Agent Runtime and Tools
模块概览
agent_runtime_and_tools 是整个系统的核心编排层,实现了一个基于 ReAct (Reasoning + Acting) 范式的智能代理引擎。这个模块负责协调 LLM 思考、工具调用、知识检索和响应生成的完整流程。
核心价值:它将复杂的多步骤问题分解为 "思考-行动-观察" 的迭代循环,让 AI 能够像人类研究员一样工作——先理解问题,制定计划,使用工具检索信息,反思结果,最后给出完整答案。
类比:你可以把这个模块想象成一个研究团队的指挥中心。AgentEngine 是项目经理,负责规划整体流程;Tools 是各个领域的专家(搜索专家、数据分析师、网络爬虫等);Skills 是可重用的专业方法论。整个系统协同工作,解决复杂的信息检索和分析任务。
架构总览
(ReAct 循环引擎)"] EventBus["EventBus
(事件总线)"] end subgraph "Tooling Layer" ToolRegistry["ToolRegistry
(工具注册表)"] KnowledgeTools["知识访问工具
(grep_chunks, knowledge_search, list_knowledge_chunks)"] DataTools["数据工具
(data_analysis, database_query)"] WebTools["网络工具
(web_search, web_fetch)"] ReasoningTools["推理工具
(thinking, todo_write)"] MCPTools["MCP 工具
(外部服务集成)"] end subgraph "Skills Layer" SkillsManager["SkillsManager
(技能管理器)"] SkillLoader["SkillLoader
(技能加载器)"] end subgraph "Prompt Layer" SystemPrompt["SystemPrompt
(渐进式 RAG 提示)"] PromptContext["PromptContext
(知识库上下文)"] end AgentEngine --> ToolRegistry AgentEngine --> EventBus AgentEngine --> SkillsManager AgentEngine --> SystemPrompt ToolRegistry --> KnowledgeTools ToolRegistry --> DataTools ToolRegistry --> WebTools ToolRegistry --> ReasoningTools ToolRegistry --> MCPTools SkillsManager --> SkillLoader SystemPrompt --> PromptContext
架构解读
这个模块采用了清晰的四层架构:
- 编排层(Orchestration Layer):由
AgentEngine主导,实现 ReAct 循环。它负责状态管理、流程控制和事件分发。 - 工具层(Tooling Layer):提供各种专业能力的工具集,从知识检索到数据分析,再到网络搜索。
- 技能层(Skills Layer):实现"渐进式披露"(Progressive Disclosure)模式,允许按需加载专业方法论。
- 提示层(Prompt Layer):构建动态的系统提示,注入知识库上下文、技能元数据等信息。
数据流向:用户查询 → AgentEngine(构建上下文)→ LLM 思考 → 工具调用 → 结果观察 → 下一轮思考 → 最终答案。
核心设计决策
1. ReAct 范式作为核心编排模式
选择:采用 ReAct (Reasoning + Acting) 模式,而不是简单的单次 LLM 调用。
为什么这样设计:
- 复杂问题处理:许多查询需要多步检索和推理,单次调用无法完成
- 可解释性:每一步思考和行动都可见,便于调试和理解
- 容错性:如果某一步出错,可以在下一步反思和修正
- 渐进式信息收集:可以根据中间结果调整检索策略
权衡:
- ✅ 优点:更强的问题解决能力,更透明的决策过程
- ❌ 缺点:更高的延迟(多次 LLM 调用),更多的 token 消耗
2. 工具优先的"证据优先"(Evidence-First)哲学
选择:系统被设计为从不依赖 LLM 的参数知识,所有答案必须基于检索到的证据。
为什么这样设计:
- 准确性:LLM 会产生幻觉(hallucination),检索到的文档是真实可信的
- 可追溯性:每个答案都有引用来源(chunk_id, doc_name)
- 领域适配:可以针对特定领域的知识库工作,无需重新训练模型
实现细节:
- 系统提示明确禁止使用内部知识
- 强制要求"深度阅读"(Deep Read):搜索后必须调用
list_knowledge_chunks查看完整内容 - 要求内联引用,每个事实声明必须紧跟来源
3. 渐进式 RAG(Progressive Agentic RAG)
选择:不是一次性检索所有可能相关的内容,而是采用"侦察-计划-执行"的三阶段流程。
流程:
- 初步侦察:先用
grep_chunks和knowledge_search进行试探性检索 - 深度阅读:对找到的 ID 调用
list_knowledge_chunks获取完整内容 - 战略决策:根据深度阅读结果决定是直接回答还是制定复杂计划
为什么这样设计:
- 避免信息过载:先了解信息地形,再决定深入方向
- 上下文效率:有限的上下文窗口中,只放入最相关的完整内容
- 自适应检索:可以根据初步结果调整检索策略
4. 技能系统的渐进式披露(Progressive Disclosure)
选择:技能系统采用三级披露模式:
- Level 1:只在系统提示中显示技能名称和描述(元数据)
- Level 2:当需要时,调用
read_skill加载完整指令 - Level 3:如果需要,使用
execute_skill_script运行配套脚本
为什么这样设计:
- 提示空间优化:不需要的技能不会占用宝贵的上下文
- 按需加载:只有在相关时才加载完整指令
- 可扩展性:可以添加数十个技能而不影响默认行为
5. 事件驱动的流式输出
选择:AgentEngine 不直接返回结果,而是通过 EventBus 发出事件,由外部处理器监听并流式传输给用户。
事件类型:
agent_thought:思考内容(流式)agent_tool_call:工具调用开始agent_tool_result:工具调用结果agent_final_answer:最终答案(流式)agent_complete:执行完成
为什么这样设计:
- 解耦:引擎不需要知道是 HTTP 流式、WebSocket 还是其他输出方式
- 实时性:思考过程可以实时展示给用户,降低感知延迟
- 可观测性:多个订阅者可以监听事件用于日志、监控、调试等
子模块概览
这个模块被组织成多个高内聚、低耦合的子模块:
| 子模块 | 职责 | 关键组件 |
|---|---|---|
| agent_core_orchestration_and_tooling_foundation | 核心引擎、工具注册和执行抽象 | AgentEngine, ToolRegistry, BaseTool |
| agent_skills_lifecycle_and_skill_tools | 技能的发现、加载和执行 | SkillsManager, SkillLoader, Skill |
| knowledge_access_and_corpus_navigation_tools | 知识库检索和文档浏览工具 | grep_chunks, knowledge_search, list_knowledge_chunks |
| data_and_database_introspection_tools | 数据查询和分析工具 | data_analysis, database_query, data_schema |
| web_and_mcp_connectivity_tools | 网络搜索和外部服务集成 | web_search, web_fetch, MCPTool |
| agent_reasoning_and_planning_state_tools | 推理和计划工具 | sequential_thinking, todo_write |
与其他模块的依赖关系
agent_runtime_and_tools 是一个消费者模块,它依赖系统的多个核心服务,但被设计为与具体实现解耦:
主要依赖
-
Chat Model (
chat.Chat):LLM 提供商接口,用于思考和生成- 用于:流式思考、最终答案生成、反思
- 集成点:
AgentEngine.streamThinkingToEventBus、AgentEngine.streamFinalAnswerToEventBus
-
Knowledge Services (
interfaces.KnowledgeService,interfaces.KnowledgeBaseService):知识库访问- 用于:文档检索、分块获取
- 集成点:多个知识工具(
knowledge_search,list_knowledge_chunks等)
-
Chunk Service (
interfaces.ChunkService):分块访问- 用于:获取完整分块内容
- 集成点:
list_knowledge_chunks工具
-
Web Search Service (
interfaces.WebSearchService):网络搜索- 用于:实时信息检索
- 集成点:
web_search工具
-
Event Bus (
event.EventBus):事件分发- 用于:流式输出、可观测性
- 集成点:
AgentEngine所有执行步骤
-
Context Manager (
interfaces.ContextManager):对话上下文管理- 用于:持久化对话历史
- 集成点:
AgentEngine.appendToolResults
-
Sandbox Manager (
sandbox.Manager):沙箱执行- 用于:安全执行技能脚本
- 集成点:
SkillsManager.ExecuteScript
设计原则:依赖倒置
注意所有依赖都是通过接口注入的,而不是具体实现。这使得:
- 可以轻松编写单元测试(使用 mock 实现)
- 可以替换服务实现而不影响代理逻辑
- 模块保持聚焦于自身职责,不关心服务如何实现
关键使用场景与流程
典型的 ReAct 执行流程
让我们通过一个具体例子来看系统如何工作:
用户查询:"比较 WeKnora 和 LangChain 的 RAG 实现,列出它们的优缺点"
-
初始化:
AgentEngine接收查询- 构建包含知识库信息的系统提示
- 初始化对话消息列表
-
第一轮思考(Think):
- 调用 LLM,提供工具列表
- LLM 决定:这是复杂任务,需要先搜索,再制定计划
- 流式输出思考内容给用户
-
第一轮行动(Act):
- 调用
todo_write创建研究计划:- 搜索知识库中的 WeKnora 信息
- 使用 web_search 查找 LangChain 资料
- 比较两者架构
- 标记任务 1 为 in_progress
- 调用
-
第二轮观察(Observe):
- 工具结果添加到消息历史
- 进入下一轮循环
-
第二轮思考(Think):
- LLM 看到 todo_write 结果,继续执行计划
- 决定调用
grep_chunks(["WeKnora", "RAG", "architecture"])
-
第二轮行动(Act):
- 执行
grep_chunks,找到相关文档 ID - 关键:根据系统提示的"深度阅读"规则,必须调用
list_knowledge_chunks查看完整内容
- 执行
-
第二轮观察(Observe):
list_knowledge_chunks返回完整文档内容- 添加到消息历史
...(这个循环继续,执行计划中的每个任务)...
N. 最终综合:
- 所有检索任务完成后
- LLM 综合所有收集的信息
- 流式输出最终答案,包含内联引用
- 发出 agent_complete 事件
技能使用流程
当启用技能时,流程略有不同:
-
Level 1 - 发现:
- 系统提示中包含所有可用技能的名称和描述
- LLM "看到"有一个 "产品比较分析" 技能与当前任务匹配
-
Level 2 - 加载:
- LLM 决定使用该技能,调用
read_skill(skill_name="product_comparison") - 完整的技能指令加载到对话中
- LLM 决定使用该技能,调用
-
Level 3 - 应用:
- LLM 按照技能指令进行比较分析
- 如果需要,调用
execute_skill_script运行辅助脚本 - 按照技能指定的格式输出结果
新贡献者注意事项
常见陷阱
-
跳过"深度阅读":
- ❌ 错误:搜索后直接根据摘要回答
- ✅ 正确:始终调用
list_knowledge_chunks查看完整内容 - 为什么:搜索摘要可能不完整或有误导性
-
工具名称泄露:
- ❌ 错误:在思考中说"我将使用 grep_chunks"
- ✅ 正确:说"我将搜索关键词"
- 为什么:用户不应该知道底层工具,关注要做什么而不是怎么做
-
跳过 KB 直接使用网络搜索:
- ❌ 错误:一上来就 web_search
- ✅ 正确:先 grep_chunks,再 knowledge_search,最后才 web_search
- 为什么:知识库内容更可靠、更相关,也更省钱
-
在 todo_write 中添加综合任务:
- ❌ 错误:任务包括"总结发现"、"生成最终答案"
- ✅ 正确:只包括检索任务,综合由 thinking 工具处理
- 为什么:职责分离,todo_write 跟踪检索,thinking 处理综合
扩展点
添加新工具
- 在
internal/agent/tools/创建新文件,遵循现有模式 - 实现
types.Tool接口(Name, Description, Parameters, Execute) - 在注册时添加到
ToolRegistry - 在
definitions.go的AvailableToolDefinitions中添加 UI 定义 - 在
DefaultAllowedTools中考虑是否默认启用
添加新技能
- 在技能目录创建子文件夹
- 创建
SKILL.md,包含 YAML frontmatter 和指令 - 可选:添加配套脚本和资源文件
- 技能会在启动时自动发现,无需代码更改
自定义系统提示
- 提供自定义
systemPromptTemplate给NewAgentEngine - 使用支持的占位符:
{{knowledge_bases}}、{{web_search_status}}、{{current_time}} - 占位符会在运行时自动替换
总结
agent_runtime_and_tools 模块是整个系统的大脑,它通过 ReAct 模式将 LLM 的推理能力与各种工具的执行能力结合起来。其核心设计理念——证据优先、渐进式检索、技能的按需披露——都指向一个目标:让 AI 像一个谨慎、彻底的研究员那样工作。
这个模块不是一个简单的"问答机器",而是一个研究引擎。它不会急于给出答案,而是先侦察、再计划、然后深入调查,最后基于确凿证据给出完整、可追溯的结论。