核心架构概览

Hermes Agent 是一个基于工具调用的 AI 代理框架,核心由 run_agent.py 中的 AIAgent 类实现,约 9200 行代码,负责从提示词组装到工具调度再到故障转移的完整生命周期管理。

三种 API 模式

支持三种 API 执行模式,通过优先级解析:

  1. chat_completions - OpenAI 兼容端点(OpenRouter、自定义服务等)
  2. codex_responses - OpenAI Codex/Responses API
  3. anthropic_messages - 原生 Anthropic Messages API

解析顺序: 显式参数 → 提供商检测 → Base URL 启发式 → 默认值


Agent Loop 核心流程

入口函数

两个主要接口:

# 简单接口 - 返回最终响应字符串
response = agent.chat("Fix the bug in main.py")

# 完整接口 - 返回字典(消息、元数据、使用统计)
result = agent.run_conversation(
    user_message="Fix the bug",
    conversation_history=None,
    task_id="task_abc123"
)

Turn 生命周期(每次迭代)

run_conversation() 方法的执行流程:

1. 生成 task_id(如未提供)
2. 添加用户消息到对话历史
3. 构建或复用缓存的系统提示词
4. 检查预压缩(上下文 > 50%)
5. 构建 API 消息格式
   - chat_completions: OpenAI 格式
   - codex_responses: Responses API 输入项
   - anthropic_messages: 通过适配器转换
6. 注入临时提示层(预算警告、上下文压力)
7. 应用提示词缓存标记(Anthropic)
8. 执行可中断的 API 调用
9. 解析响应:
   - 有 tool_calls → 执行工具 → 追加结果 → 回到步骤 5
   - 文本响应 → 持久化会话 → 刷新内存 → 返回

核心组件

1. 提示词构建 (agent/prompt_builder.py)

  • 身份和平台提示
  • 技能索引注入
  • 上下文文件(AGENTS.md、.cursorrules、SOUL.md)
  • 威胁模式扫描(防止提示注入)

2. 上下文压缩 (agent/context_compressor.py)

触发条件:

  • 预检:对话超过模型上下文窗口的 50%
  • 网关自动压缩:超过 85%

压缩算法:

1. 修剪旧的工具结果(无 LLM 调用)
2. 保护头部消息(系统提示 + 首次交互)
3. 保护尾部消息(按 token 预算,最近 ~20K tokens)
4. 使用辅助模型总结中间轮次
5. 后续压缩时迭代更新之前的摘要

3. 工具执行系统

工具调度 (model_tools.py)

串行 vs 并发执行:

  • 单个工具 → 主线程直接执行
  • 多个工具 → ThreadPoolExecutor 并发执行
    • 例外:交互式工具(如 clarify)强制串行

执行流程:

for each tool_call in response.tool_calls:
    1. 从 tools/registry.py 解析处理器
    2. 触发 pre_tool_call 插件钩子
    3. 检查危险命令(tools/approval.py)
       - 危险 → 调用 approval_callback → 等待用户确认
    4. 执行处理器(带 args + task_id)
    5. 触发 post_tool_call 插件钩子
    6. 追加 {"role": "tool", "content": result} 到历史

Agent 级工具拦截(不经过 registry):

  • todo - 读写代理本地任务状态
  • memory - 写入持久化内存文件
  • session_search - 查询会话历史
  • delegate_task - 生成子代理

4. 回调系统

回调 触发时机 用途
tool_progress_callback 工具执行前后 CLI 旋转器、网关进度消息
thinking_callback 模型开始/停止思考 CLI “thinking…” 指示器
reasoning_callback 模型返回推理内容 CLI 推理显示、网关推理块
clarify_callback clarify 工具调用 CLI 输入提示、网关交互消息
step_callback 每个完整代理轮次后 网关步骤追踪、ACP 进度
stream_delta_callback 每个流式 token CLI 流式显示
status_callback 状态变化 ACP 状态更新

关键机制

1. 可中断 API 调用

┌──────────────────────┐     ┌──────────────┐
│  主线程               │     │  API 线程     │
│  等待:               │────▶│  HTTP POST   │
│  - 响应就绪          │     │  到提供商     │
│  - 中断事件          │     └──────────────┘
│  - 超时              │
└──────────────────────┘

中断时(用户发送新消息、/stop 命令、信号):

  • API 线程被放弃(响应丢弃)
  • 代理可处理新输入或干净关闭
  • 无部分响应注入到对话历史

2. 消息格式与交替规则

所有消息使用 OpenAI 兼容格式:

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

严格交替规则:

  • 系统消息后:User → Assistant → User → Assistant → …
  • 工具调用时:Assistant (with tool_calls) → Tool → Tool → … → Assistant
  • 绝不两个连续的 assistant 消息
  • 绝不两个连续的 user 消息
  • 只有 tool 角色可以有连续条目(并行工具结果)

3. 预算和故障转移

迭代预算 (IterationBudget)
  • 默认:90 次迭代(可通过 agent.max_turns 配置)
  • 父子代理共享预算
  • 两级压力警告:
    • 70%+:附加 [BUDGET: Iteration X/Y...]
    • 90%+:附加 [BUDGET WARNING: Only N left. Provide final response NOW.]
    • 100%:停止并返回工作摘要
故障转移模型

主模型失败时(429、5xx、401/403):

  1. 检查配置中的 fallback_providers 列表
  2. 按顺序尝试每个备用
  3. 成功后继续使用新提供商
  4. 401/403 时在失败前尝试凭证刷新

错误分类 (agent/error_classifier.py):

  • rate_limit - 立即切换备用
  • context_overflow - 压缩后重试
  • payload_too_large - 压缩后重试
  • long_context_tier - 降低上下文限制
  • thinking_signature - 清除推理块重试

4. 会话持久化

每轮后:

  • 消息保存到会话存储(SQLite via hermes_state.py
  • 内存变更刷新到 MEMORY.md / USER.md
  • 会话可通过 /resumehermes chat --resume 恢复

错误处理与重试

多层重试机制

  1. API 调用级(最多 3 次):

    • 无效响应 → 指数退避重试
    • 速率限制 → 立即切换备用
  2. 上下文错误(最多 3 次压缩尝试):

    • 413 payload too large → 压缩 → 重试
    • context overflow → 降低上下文限制 → 压缩 → 重试
  3. 特殊重试:

    • 无效工具名 → 返回错误给模型自纠正(最多 3 次)
    • 无效 JSON 参数 → 重试或注入恢复工具结果
    • 不完整 REASONING_SCRATCHPAD → 重试(最多 2 次)
    • 空响应 → 重试(最多 3 次)→ 尝试备用

核心文件清单

文件 用途
run_agent.py AIAgent 类 - 完整代理循环(~9200 行)
agent/prompt_builder.py 系统提示词组装
agent/context_compressor.py 默认引擎 - 有损压缩算法
agent/prompt_caching.py Anthropic 提示词缓存标记
agent/auxiliary_client.py 辅助 LLM 客户端(视觉、总结)
model_tools.py 工具模式集合、handle_function_call() 调度
tools/registry.py 工具注册表
hermes_state.py 会话存储(SQLite)

架构图

Agent Loop 核心循环

有 tool_calls

文本响应

中断

错误

速率限制

上下文溢出

其他错误

用户消息

初始化会话

构建系统提示词

需要压缩?

上下文压缩

构建 API 消息

执行 API 调用

解析响应

执行工具

追加工具结果

预算耗尽?

返回工作摘要

持久化会话

刷新内存

返回最终响应

处理中断

返回中断状态

错误处理

切换备用提供商

重试?

返回错误

工具执行流程

无效

有效

无效 JSON

有效

拒绝

批准

工具调用

验证工具名

返回错误给模型

验证参数

重试或恢复

危险命令?

请求用户批准

用户决定

返回取消

执行工具

触发插件钩子

追加结果到历史

继续?

完成

上下文压缩流程

触发压缩

修剪旧工具结果

保护头部消息

保护尾部消息

中间有内容?

LLM 总结中间轮次

创建摘要消息

替换原消息

生成新会话 ID

持久化新会话

完成


总结

Hermes Agent 的 Loop 架构是一个高度模块化、容错性强的系统:

  1. 模块化设计:提示词构建、上下文压缩、工具执行各自独立
  2. 多层容错:API 重试、上下文压缩、提供商故障转移、凭证池轮换
  3. 资源管理:迭代预算、上下文压力警告、自动压缩
  4. 可扩展性:插件钩子系统、回调表面、可插拔上下文引擎
  5. 平台适配:支持三种 API 模式、多种消息格式、流式与非流式

核心循环是一个 观察-思考-行动 的迭代过程,通过工具调用实现复杂任务的自动化执行,同时具备完善的错误恢复和资源管理机制。


Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐