5

工具系统

Agent 的双手 — 43+ 个内置工具

工具是怎么工作的?

每个工具都遵循一个统一的模式: 1. 名字(Name):工具的唯一标识,比如 Read、Bash、Grep 2. 描述(Description):告诉 LLM 这个工具能做什么 3. 参数定义(Parameters):工具需要什么输入 4. 执行逻辑(Execute):真正做事的代码 5. 返回结果(Result):操作的输出 LLM 会根据工具的名字和描述来决定使用哪个工具,然后传入参数,工具执行后返回结果。

工具的基本结构

openharness/tools/base.py
1class BaseTool(ABC):
2 """所有工具的基类"""
3
4 @property
5 def name(self) -> str:
6 """工具名称,如 'Read', 'Bash'"""
7 ...
8
9 @property
10 def description(self) -> str:
11 """工具描述,LLM 通过这个了解工具能力"""
12 ...
13
14 def get_input_schema(self) -> dict:
15 """参数定义,用 JSON Schema 格式"""
16 ...
17
18 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 命令并返回输出

Shell
WebFetch只读

获取网页内容

搜索
WebSearch只读

在互联网上搜索信息

搜索
ToolSearch只读

搜索可用的延迟加载工具

搜索
Agent

启动子 Agent 处理复杂任务

Agent
SendMessage

向已启动的 Agent 发送消息

Agent
TaskCreate

创建新的后台任务

任务
TaskGet只读

获取任务状态和详情

任务
TaskList只读

列出所有任务

任务
TaskUpdate

更新任务状态

任务
TaskStop

停止运行中的任务

任务
MCPTool

调用 MCP 服务器上的工具

MCP
ListMcpResources只读

列出 MCP 资源

MCP
ReadMcpResource只读

读取 MCP 资源内容

MCP
EnterPlanMode只读

进入规划模式(只读探索)

工作流
ExitPlanMode

退出规划模式

工作流
EnterWorktree

进入独立的 Git 工作树

工作流
ExitWorktree

退出 Git 工作树

工作流
Skill只读

加载并执行技能(领域知识)

元工具
AskUserQuestion只读

向用户提问以获取信息

元工具
CronCreate

创建定时任务

调度
CronList只读

列出定时任务

调度
CronDelete

删除定时任务

调度

工具注册表模式

openharness/tools/registry.py
1class ToolRegistry:
2 """工具注册表 —— 统一管理所有工具"""
3
4 def register(self, tool: BaseTool):
5 """注册一个新工具"""
6 self._tools[tool.name] = tool
7
8 def get_tool(self, name: str) -> BaseTool:
9 """按名称获取工具"""
10 return self._tools[name]
11
12 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 使用「注册表模式」来管理工具?