Skip to content

Hour 1: Agent 核心与对话循环


一、阅读路径

核心文件

文件行数职责
run_agent.py5550AIAgent 类的定义,入口转发
agent/conversation_loop.py4561真正核心逻辑
model_tools.py~1100工具注册和调用
tools/registry.py~500工具执行器

转发模式

run_agent.py 中的 AIAgent 是一个转发器

python
# run_agent.py:429
class AIAgent:
    def __init__(self, ...):
        from agent import agent_init
        agent_init.init_agent(self, ...)  # 转发

    def run_conversation(self, ...):
        from agent.conversation_loop import run_conversation
        return run_conversation(self, ...)  # 转发

二、核心循环

while 循环入口(第 589 行)

python
while (api_call_count < agent.max_iterations and agent.iteration_budget.remaining > 0) or agent._budget_grace_call:

循环条件解析:

条件含义
api_call_count < agent.max_iterations未超过最大迭代次数(默认90)
agent.iteration_budget.remaining > 0预算还有剩余
agent._budget_grace_call宽限调用(预算耗尽后最后一次机会)

while 循环内部流程

循环开始 (第 589 行)


┌─────────────────────────────┐
│ 1. new_turn()             │
│    重置检查点去重计数器     │
└─────────────────────────────┘


┌─────────────────────────────┐
│ 2. 检查中断请求             │
│    _interrupt_requested?    │
└─────────────────────────────┘


┌─────────────────────────────┐
│ 3. api_call_count++        │
│    消耗迭代预算             │
└─────────────────────────────┘


┌─────────────────────────────┐
│ 4. 宽限调用处理             │
│    _budget_grace_call      │
└─────────────────────────────┘


┌─────────────────────────────┐
│ 5. step_callback           │
│    通知网关钩子             │
└─────────────────────────────┘


    ... (准备消息、调用 API、处理响应)

三、LLM API 调用链

conversation_loop.py:589  while 循环


conversation_loop.py:1138  _perform_api_call()


hermes_cli/middleware.py   run_llm_execution_middleware()


agent/chat_completion_helpers.py:125  interruptible_api_call()


agent/chat_completion_helpers.py:239  client.chat.completions.create()
         ↑ 实际调用

四、消息格式

Hermes 使用 OpenAI 格式:

python
{"role": "system", "content": "..."}
{"role": "user", "content": "..."}
{"role": "assistant", "content": "...", "tool_calls": [...]}
{"role": "tool", "tool_call_id": "...", "content": "..."}

reasoning 内容存储在 assistant_msg["reasoning"] 中。


五、会话状态管理

SessionDB (hermes_state.py)

  • SQLite 存储(FTS5 全文搜索)
  • 每个会话独立数据库文件
  • 支持消息历史和搜索

状态清理

循环结束后清理:

  • 消息历史写入 SessionDB
  • 检查点计数器重置

六、循环结束条件

条件结果
assistant_message.tool_calls 存在执行工具,继续循环
无 tool_calls返回文本响应,退出循环
达到 max_iterations退出循环
预算耗尽退出循环
_interrupt_requested退出循环

七、验证代码

python
# 验证工具数量
from model_tools import get_tool_definitions
tools = get_tool_definitions()
print(f"Total tools: {len(tools)}")

# 验证工具注册表
from tools.registry import registry
print(f"Registry dispatch works: {registry.get_entry('terminal') is not None}")

# 验证 handle_function_call
from model_tools import handle_function_call
result = handle_function_call("noop", {"message": "test"})
print(f"Noop tool result: {result}")

八、关键文件位置

功能文件:行号
while 循环入口conversation_loop.py:589
API 调用conversation_loop.py:1138
工具执行入口run_agent.py:5170
工具注册model_tools.py:876
registry dispatchtools/registry.py:390

总结

Hour 1 核心理解:

  • Agent = while 循环 + LLM API 调用 + 工具执行
  • run_conversation() 是入口
  • 循环条件:api_call_count < max_iterations AND iteration_budget.remaining > 0
  • 循环结束:break → 文本响应,或达到最大迭代

基于 VitePress 重建