第 2 讲:Agent 对话循环——从用户输入到 LLM 响应的完整链路

Hermes Agent 源码解析 · 第 2 讲

Hermes Agent 源码解析 第 2 讲:Agent 对话循环——从用户输入到 LLM 响应的完整链路 基于 v0.16.0 源码 · 2026-06-15 一、对话循环:Agent 的心脏 第 1 讲我们建立了全局架构地图。这一讲深入 Hermes 最核心、最复杂的代码区域—— 对话循环 (Conversation Loop),逐层拆解从用户输入到 LLM 响应的完整链路。 📦 源码仓库 https://github.com/NousResearch/hermes-agent 本讲核心文件: agent/conversation_loop.py (4,252 行) 二、对话循环的入口与架构 1. AIAgent 的转发器模式 AIAgent 的 __init__ 是一个转发器——它接受 ~70 个参数,全部委托给 agent.agent_init.init_agent() 。同样, run_conversation() 也委托给 agent/conversation_loop.py : 📄 run_agent.py (第 415-488 行) def __init__(self, base_url=None, api_key=None, provider=None, max_iterations=90, tool_delay=1.0, ...): """Forwarder — see ``agent.agent_init.init_agent``.""" from agent.agent_init import init_agent init_agent(self, base_url=base_url, api_key=api_key, ...) def run_conversation(self, user_message, system_message=None, ...): """Thin forwarder — see ``agent.conversation_loop.run_conversation``.""" from agent.conversation_loop import run_conversation return run_conversation(self, user_message, system_message, ...) 设计意图: 5400 行的 run_agent.py 被拆解为 agent/ 子模块,每个模块职责单一。对话循环独立为 4252 行的 conversation_loop.py ,但仍通过 agent 参数(而非类方法)访问状态——这是一种"结构化的过程式"风格。 2. 对话循环的三阶段架构 一次完整的对话(turn)分为三个阶段: ┌─────────────────────────────────────────────────────────┐ │ run_conversation() │ │ │ │ ┌─ 阶段 1: Turn Prologue (build_turn_context) ──────┐ │ │ │ • 用户消息清洗 (surrogate sanitization) │ │ │ │ • System prompt 恢复/重建 │ │ │ │ • 迭代预算重置 (IterationBudget) │ │ │ │ • 上下文预压缩 (preflight compression) │ │ │ │ • 插件钩子: pre_llm_call │ │ │ │ • 外部记忆预取 (memory prefetch) │ │ │ │ • 返回 TurnContext dataclass │ │ │ └────────────────────────────────────────────────────┘ │ │ ↓ │ │ ┌─ 阶段 2: 主循环 (while loop) ─────────────────────┐ │ │ │ • 中断检查 (interrupt_requested) │ │ │ │ • 预算检查 (IterationBudget.consume()) │ │ │ │ • API 请求构建 + Anthropic cache 注入 │ │ │ │ •…

阅读全文:Hermes Agent 源码解析 第 2 讲