第 5 章
工具系统
Agent 的双手 — 43+ 个内置工具
🎯
像手机上的 App
你的手机本身只是一块屏幕和处理器,是 App 赋予了它各种能力:相机 App 让它能拍照,地图 App 让它能导航,支付 App 让它能付款。OpenHarness 的工具系统也是一样 —— 每个工具就是一个「App」,赋予 Agent 一种特定的能力。
工具是怎么工作的?
每个工具都遵循一个统一的模式:
1. 名字(Name):工具的唯一标识,比如 Read、Bash、Grep
2. 描述(Description):告诉 LLM 这个工具能做什么
3. 参数定义(Parameters):工具需要什么输入
4. 执行逻辑(Execute):真正做事的代码
5. 返回结果(Result):操作的输出
LLM 会根据工具的名字和描述来决定使用哪个工具,然后传入参数,工具执行后返回结果。
工具的基本结构
openharness/tools/base.py
1class BaseTool(ABC):2 """所有工具的基类"""34 @property5 def name(self) -> str:6 """工具名称,如 'Read', 'Bash'"""7 ...89 @property10 def description(self) -> str:11 """工具描述,LLM 通过这个了解工具能力"""12 ...1314 def get_input_schema(self) -> dict:15 """参数定义,用 JSON Schema 格式"""16 ...1718 async def execute(self, params, context) -> ToolResult:19 """执行工具,返回结果"""20 ...
在 OpenHarness 中,每个工具都继承自 BaseTool:
工具的分类
OpenHarness 的 43+ 个工具可以分为以下几大类:
📁 文件操作(6 个)
Read、Write、Edit、Glob、Grep、NotebookEdit
这是最常用的一类工具,让 Agent 能读写和搜索文件。
💻 Shell(1 个)
Bash —— 执行任意 Shell 命令,是最强大也最需要权限控制的工具。
🔍 搜索(3 个)
WebFetch、WebSearch、ToolSearch
让 Agent 能从互联网获取信息。
🤖 Agent 协作(2 个)
Agent、SendMessage
让一个 Agent 启动子 Agent 来处理复杂子任务。
📋 任务管理(5 个)
TaskCreate、TaskGet、TaskList、TaskUpdate、TaskStop
管理后台异步任务。
🌐 MCP(3 个)
MCPTool、ListMcpResources、ReadMcpResource
通过标准协议连接外部工具。
🔄 工作流(4 个)
EnterPlanMode、ExitPlanMode、EnterWorktree、ExitWorktree
控制 Agent 的工作模式。
🔧 工具浏览器 — OpenHarness 的 29+ 个内置工具
Read只读
读取文件内容
文件Write
写入文件
文件Edit
精确替换文件中的字符串
文件Glob只读
按文件名模式搜索文件
文件Grep只读
按内容搜索文件(基于 ripgrep)
文件NotebookEdit
编辑 Jupyter Notebook 单元格
文件Bash
执行 Shell 命令并返回输出
ShellWebFetch只读
获取网页内容
搜索WebSearch只读
在互联网上搜索信息
搜索ToolSearch只读
搜索可用的延迟加载工具
搜索Agent
启动子 Agent 处理复杂任务
AgentSendMessage
向已启动的 Agent 发送消息
AgentTaskCreate
创建新的后台任务
任务TaskGet只读
获取任务状态和详情
任务TaskList只读
列出所有任务
任务TaskUpdate
更新任务状态
任务TaskStop
停止运行中的任务
任务MCPTool
调用 MCP 服务器上的工具
MCPListMcpResources只读
列出 MCP 资源
MCPReadMcpResource只读
读取 MCP 资源内容
MCPEnterPlanMode只读
进入规划模式(只读探索)
工作流ExitPlanMode
退出规划模式
工作流EnterWorktree
进入独立的 Git 工作树
工作流ExitWorktree
退出 Git 工作树
工作流Skill只读
加载并执行技能(领域知识)
元工具AskUserQuestion只读
向用户提问以获取信息
元工具CronCreate
创建定时任务
调度CronList只读
列出定时任务
调度CronDelete
删除定时任务
调度工具注册表模式
openharness/tools/registry.py
1class ToolRegistry:2 """工具注册表 —— 统一管理所有工具"""34 def register(self, tool: BaseTool):5 """注册一个新工具"""6 self._tools[tool.name] = tool78 def get_tool(self, name: str) -> BaseTool:9 """按名称获取工具"""10 return self._tools[name]1112 def get_tool_schemas(self) -> list[dict]:13 """获取所有工具的 JSON Schema(给 LLM 看的)"""14 return [tool.to_json_schema() for tool in self._tools.values()]
所有工具通过一个「注册表」统一管理:
ToolResult —— 工具的返回值
每个工具执行后都会返回一个 ToolResult,它有两个关键字段:
• output:工具的输出内容(比如文件内容、命令输出)
• is_error:是否出错
重要的是,工具的错误不会导致程序崩溃。错误信息会被当作结果返回给 LLM,LLM 会看到错误并尝试修正。这就像一个人做错了事会自我纠正一样。
📌 关键要点
统一接口 + 注册表 = 无限扩展
OpenHarness 工具系统的精妙之处在于:每个工具都遵循相同的接口(BaseTool),通过注册表统一管理。这意味着添加新工具不需要修改引擎代码 —— 只需要写一个新类、注册进去即可。这就是为什么 OpenHarness 能支持 43+ 个工具而代码依然简洁。
🧠 检验理解
当工具执行出错时,OpenHarness 会怎么处理?
🧠 检验理解
为什么 OpenHarness 使用「注册表模式」来管理工具?