.. _part1:
第一部分:基础概念
====================
什么是 AI Agent?
-------------------
定义
~~~~~~
AI Agent 是一个能够**自主感知环境、制定决策、执行动作,并根据反馈调整行为**
的软件系统。它与传统软件的核心区别在于:传统软件的行为由程序员预先编码,
而 Agent 的行为由大语言模型(LLM)在运行时动态决定。
但这一定义过于抽象。让我们通过对比来精确理解。
与聊天机器人的区别
^^^^^^^^^^^^^^^^^^^^
聊天机器人(Chatbot)是一个**单轮或固定多轮** 的对话系统:
.. code-block:: text
用户 → LLM → 回复
用户发送一条消息,LLM 返回一条回复,交互结束。即使像 ChatGPT 这样的
多轮对话系统,其核心模式也是"用户提问,模型回答"。模型不会主动采取行动。
Agent 则引入了**行动能力** :
.. code-block:: text
用户 → LLM → 思考 → 选择工具 → 执行 → 观察结果 → 继续思考 → ... → 回复
关键区别在于 Agent 拥有一个**循环** :它可以反复调用工具、观察结果、
调整策略,直到任务完成或预算耗尽。这个循环赋予了 Agent 处理复杂、
多步骤任务的能力。
与 RAG 管线的区别
^^^^^^^^^^^^^^^^^^^
检索增强生成(RAG)管线是一个**增强输入** 的系统:
.. code-block:: text
用户查询 → 检索相关文档 → [文档 + 查询] → LLM → 回复
RAG 增强了 LLM 的知识,但没有给它行动能力。RAG 系统不会"决定"要去检索——
检索是管线中固定的步骤。RAG 系统也不会在检索失败时尝试另一种检索策略。
Agent 则可以**自主决定** 何时检索、检索什么、以及检索结果不满意时如何调整。
这种决策能力是 Agent 区别于所有"管线式"LLM 应用的核心特征。
一个精确的工作定义
^^^^^^^^^^^^^^^^^^^^
综合以上对比,我们可以给出一个更精确的工作定义:
**AI Agent = LLM + 工具 + 循环 + 状态**
- **LLM** :作为"大脑",负责理解输入、制定计划、选择行动
- **工具** :作为"手和脚",让 Agent 能够影响外部世界
- **循环** :observe → think → act → observe 的迭代能力
- **状态** :跨迭代的记忆与上下文管理
Hermes Agent 完美地体现了这四个要素:
.. list-table::
:header-rows: 1
:widths: 20 30 50
* - 要素
- 抽象概念
- Hermes 实现
* - LLM
- 推理与决策
- ``AIAgent._interruptible_streaming_api_call()`` ,支持 OpenAI/Anthropic/Bedrock
* - 工具
- 行动能力
- ``model_tools.handle_function_call()`` → ``registry.dispatch()``
* - 循环
- 自主迭代
- ``run_conversation()`` 中的 ``while`` 主循环
* - 状态
- 记忆与上下文
- SQLite 会话数据库、Memory Store、消息历史
基础循环:Observe → Think → Act → Observe
----------------------------------------------
所有 Agent 架构,无论多么复杂,都可以归结为一个基本循环:
.. mermaid::
:name: observe-think-act-loop
:caption: Observe-Think-Act 基础循环
sequenceDiagram
autonumber
participant U as 用户/环境
participant A as Agent (LLM)
participant T as 工具集
U->>A: 输入 (Observe)
loop 直到任务完成或预算耗尽
A->>A: 思考与规划 (Think)
alt 需要使用工具
A->>T: 调用工具 (Act)
T-->>A: 返回结果 (Observe)
else 任务完成
A-->>U: 最终回复
end
end
这个循环看似简单,但真实的生产实现中隐藏着大量复杂性:
**Observe(观察)的复杂性:**
- 流式接收 LLM 输出时如何处理部分 JSON(工具调用的参数是不完整的)
- 如何统一不同提供商(OpenAI choices vs Anthropic content blocks vs Bedrock)的响应格式
- 如何在流式输出中检测工具调用与纯文本的边界
**Think(思考)的复杂性:**
- 如何将系统提示词、用户输入、工具结果、记忆上下文组合成有效的 prompt
- 当思考过程被输出 token 上限截断时如何处理
- 如何在不破坏 prompt 缓存的前提下注入动态上下文
**Act(行动)的复杂性:**
- 如何决定工具的并行执行还是顺序执行
- 如何处理模型幻觉出的不存在的工具名
- 如何处理工具参数的 JSON 解析错误
- 如何在执行过程中响应中断请求
Agent 架构的演进
------------------
ReAct (2022)
~~~~~~~~~~~~~~
ReAct(Reasoning + Acting)是由 Yao 等人在 2022 年提出的 Agent 架构范式。
其核心思想是让 LLM 在每个步骤中先进行**推理** (Thought),然后选择**行动** (Action),
最后观察**结果** (Observation)。
.. code-block:: text
Thought: 我需要查找北京今天的天气
Action: weather_query(city="北京")
Observation: 晴,25°C
Thought: 我已经得到了答案
Answer: 北京今天是晴天,25°C
ReAct 的贡献在于将推理和行动交织在一起,而不是先完成所有推理再执行所有行动。
这使得 Agent 能够根据中间结果动态调整策略。
Hermes 在 ``run_conversation()`` 的主循环中实现了 ReAct 模式:
每次 API 调用对应一个 "Thought",工具调用对应 "Action",工具结果对应 "Observation"。
Reflexion (2023)
~~~~~~~~~~~~~~~~~~
Reflexion 在 ReAct 的基础上增加了**自我反思** 能力。当 Agent 完成一个任务后,
它会回顾自己的执行轨迹,评估哪些步骤有效、哪些无效,并将这些反思保存下来
供未来的任务参考。
Hermes 的记忆系统(``memory_tool``)和技能系统(``skill_manage``)实现了
类似的反思机制。当对话结束时,Agent 会在后台线程中回顾对话内容,
自动将值得记住的信息保存到长期存储中(``run_agent.py:2458`` ,
``_spawn_background_review`` 方法)。
Toolformer (2023)
~~~~~~~~~~~~~~~~~~~
Toolformer 展示了 LLM 可以通过微调学会**自主决定何时调用工具** 。
在 Agent 架构中,这一思想的工程实现是 function calling API——
模型不是通过微调,而是通过 API 协议来获得工具调用能力。
Hermes 通过 OpenAI Chat Completions API 的 ``tools`` 参数、
Anthropic Messages API 的 ``tool_use`` content block、
以及 AWS Bedrock 的 ``toolConfig`` 来实现跨提供商的工具调用。
AutoGPT (2023)
~~~~~~~~~~~~~~~~
AutoGPT 是第一个引起广泛关注的自主 Agent 项目。它的核心创新是让 GPT-4
自主分解任务、设定子目标、并迭代执行。AutoGPT 暴露了一个关键问题:
**无限的自主迭代会导致失控。** Agent 可能陷入循环,不断调用工具却永远无法完成任务。
Hermes 通过 ``IterationBudget`` 类(``run_agent.py:170``)解决了这一问题:
每个 Agent 实例有固定的迭代预算,耗尽后触发一次"宽限调用"让模型完成总结,
然后强制退出循环。
为什么要工具、记忆和规划?
----------------------------
工具:Agent 的手脚
~~~~~~~~~~~~~~~~~~~~
没有工具的 LLM 只能生成文本。工具赋予了 Agent 影响外部世界的能力。
Hermes 提供了丰富的工具集:
.. list-table::
:header-rows: 1
:widths: 20 40 40
* - 工具类别
- 具体工具
- 能力
* - 文件操作
- read_file, write_file, patch, search_files
- 读写和搜索本地文件
* - 终端执行
- terminal
- 执行 shell 命令
* - 网络访问
- web_search, web_extract
- 搜索和提取网页内容
* - 浏览器
- browser_navigate, browser_click, ...
- 无头浏览器自动化
* - 代码执行
- execute_code
- 沙箱中的代码执行
* - 记忆
- memory, todo, session_search
- 长期和短期记忆管理
* - 视觉
- vision_analyze, image_generate
- 图像理解与生成
**关键设计原则:** 工具通过自注册模式加入系统。每个工具文件(如 ``tools/terminal_tool.py``)
在模块加载时调用 ``registry.register()`` 将自己注册到全局工具注册中心。
这意味着添加新工具只需创建一个新文件并调用注册函数,无需修改核心调度代码。
记忆:Agent 的经验
~~~~~~~~~~~~~~~~~~~~
记忆系统让 Agent 能够跨越单次对话的限制,积累和利用长期知识。
Hermes 实现了两层记忆:
- **短期记忆(会话级):** 通过 ``messages`` 列表中的对话历史实现。
每次工具调用的结果都作为 tool 角色消息添加到历史中。
- **长期记忆(跨会话):** 通过 ``memory_tool`` 实现。
Agent 可以保存用户的偏好、项目信息、工作习惯等到持久化存储中,
并在后续会话中通过系统提示词注入这些记忆。
``run_agent.py`` 中 ``_memory_manager.on_turn_start()`` 在每轮对话开始时
预取长期记忆,并通过 ``build_memory_context_block()`` 注入到用户消息中。
规划:Agent 的大脑
~~~~~~~~~~~~~~~~~~~~
规划能力是 Agent 区别于简单工具调用的关键。一个没有规划能力的 Agent
只会对每条消息做即时反应;有规划能力的 Agent 能够分解复杂任务、
设定中间目标、并根据执行结果调整计划。
Hermes 的规划通过以下机制实现:
- **系统提示词引导:** 通过 ``TOOL_USE_ENFORCEMENT_GUIDANCE`` 等提示词片段
引导模型进行结构化规划
- **Todo 工具:** 让 Agent 显式地创建和管理任务列表
- **子代理委派:** 通过 ``delegate_task`` 工具将子任务分配给专门的子 Agent
- **迭代预算:** ``IterationBudget`` 确保 Agent 有足够的迭代空间来完成复杂任务
通用 Agent 架构模式
---------------------
综合以上分析,我们可以绘制出通用 Agent 的架构模式:
.. mermaid::
:name: agent-architecture-overview
:caption: 通用 Agent 架构全景
flowchart TB
classDef start fill:#dbeafe,stroke:#3b82f6,color:#1e3a8a
classDef success fill:#dcfce7,stroke:#16a34a,color:#166534
classDef warn fill:#fef9c3,stroke:#ca8a04,color:#854d0e
classDef info fill:#f1f5f9,stroke:#64748b,color:#334155
subgraph UI["用户接口层"]
direction LR
CLI["CLI / TUI"]
GW["网关 RPC"]
BOT["Bot 集成"]
end
subgraph CORE["Agent 核心"]
LOOP["主循环
run_conversation()"]
BUDGET["迭代预算
IterationBudget"]
end
subgraph LLM["LLM 适配层"]
direction LR
OPENAI["OpenAI
Chat Completions"]
CODEX["Codex
Responses API"]
ANTHRO["Anthropic
Messages API"]
BEDROCK["AWS Bedrock
Converse API"]
end
subgraph TOOLLAYER["工具层"]
direction LR
REG["工具注册中心
registry"]
TOOLS["工具实现
terminal / file / web / ..."]
MCP["MCP 工具"]
PLUGINS["插件工具"]
end
subgraph STATE["状态层"]
direction LR
SESSION["会话存储
SQLite"]
MEMORY["长期记忆
MemoryStore"]
COMPRESS["上下文压缩
ContextCompressor"]
TRAJ["轨迹保存
trajectory"]
end
CLI --> LOOP
GW --> LOOP
BOT --> LOOP
LOOP --> BUDGET
LOOP --> OPENAI
LOOP --> CODEX
LOOP --> ANTHRO
LOOP --> BEDROCK
LOOP --> REG
REG --> TOOLS
REG --> MCP
REG --> PLUGINS
LOOP --> SESSION
LOOP --> MEMORY
LOOP --> COMPRESS
LOOP --> TRAJ
class CLI,GW,BOT start
class LOOP,BUDGET success
class OPENAI,CODEX,ANTHRO,BEDROCK info
class REG,TOOLS,MCP,PLUGINS warn
class SESSION,MEMORY,COMPRESS,TRAJ info
Hermes 如何映射到这些概念
---------------------------
以下是 Hermes 核心模块与 Agent 概念的精确映射:
.. list-table::
:header-rows: 1
:widths: 25 25 50
* - Agent 概念
- Hermes 模块
- 关键实现细节
* - 主循环
- ``run_agent.py`` :: ``run_conversation()``
- ``while`` 循环,每次迭代对应一次 LLM 调用,支持流式和非流式两种模式
* - LLM 适配
- ``run_agent.py`` :: ``api_mode``
- 四种 API 模式:``chat_completions`` 、``codex_responses`` 、``anthropic_messages`` 、``bedrock_converse``
* - 工具调度
- ``model_tools.py`` :: ``handle_function_call()``
- 先检查 Agent 级拦截工具(todo/memory/session_search),再分发到注册中心
* - 错误恢复
- ``agent/error_classifier.py`` :: ``classify_api_error()``
- 14 种错误类型,自动选择凭证轮换/压缩/回退等恢复策略
* - 上下文管理
- ``agent/context_compressor.py``
- 头尾保护 + 中间摘要,使用辅助模型生成摘要
* - 会话持久化
- ``run_agent.py`` :: ``_persist_session()``
- JSON 日志 + SQLite 双重存储,确保任何退出路径都不丢失数据
* - 子代理
- ``tools/delegate_tool.py``
- 父子共享 ``IterationBudget`` ,子代理有独立的迭代上限
在下一章中,我们将深入 ``run_agent.py`` 的 ``run_conversation()`` 方法,
逐行分析这个 2000+ 行的方法如何实现上述所有功能。
这是本书最核心、最详细的章节——请确保你已经准备好了。