从零搭建 Agent Harness 系列(三)极简工具与物理交互原则
之前的博客我们已经通过ReAct的架构为Agent赋予了一个大脑,但是只有大脑是不够的,也就是说现在的Agent只能做token的预测,但是还需要一些感官,能够将现实世界中与完成任务有关的各种信息整理成token,以及能够将token重新变成能够影现实世界的操作,这些操作就是我们这篇博客的重点——tool
我们将亲手用 Go 语言构建一个强扩展、高内聚的 Tool Registry.
架构设计:为什么需要 Tool Registry?
在 Harness(驾驭工程)的理念中,Main Loop 永远是“瞎子”和“聋子”。它不应该知道 bash 命令怎么调用,也不应该知道 read_file 需要什么参数格式。它只负责维护上下文,并将模型吐出来的 JSON 字符串丢给执行层。
因此,Tool Registry 扮演了一个极其关键的“集线器(Hub)”和“路由器(Router)”的角色。它的核心职责有三:
动态挂载(Register):允许开发者在引擎启动时,随时随地向系统插拔新的工具实现(在 Go 中,其本质上是实现了特定 Go 接口的结构体)。
描述暴露(Expose Schema):在每次向大模型发起推理前,Registry 负责把当前所有已挂载工具的名称、描述以及 JSON Schema 打包成列表,交给 Provider 翻译给大模型听。
路由分发与执行(Dispatch & Execute):当大模型决定调用某个工具,并吐出一串 JSON 参数(ToolCall)时,Registry 负责找到对应的 Go 函数,把 JSON 丢给它执行,最后将结果封装成统一的 ToolResult 返回给 Main Loop。

定义BaseTool接口
1 | // internal/tools/registry.go |
实现 Registry 的路由与分发
1 | // internal/tools/registry.go (续) |
极简工具法则与YOLO执行哲学
既然拥有了如此强大的动态注册机制,按照常规的开发惯例,下一步我们是不是应该开始疯狂地给 Agent 编写各种专用的业务工具了?比如:写一个 git_commit 工具,写一个 npm_install 工具,写一个 grep_search 工具,或者引入当下大火的 MCP(Model Context Protocol)协议,把几百个第三方 API 一股脑地挂载给模型?
如果你真的打算这么做,那么你的 Agent 离“智障”和“破产”也就不远了。今天这一讲,我们将探讨 Harness Engineering(驾驭工程)中最核心、也最反直觉的设计哲学:极简主义与 YOLO(You Only Live Once)模式。
我们将从底层逻辑剖析,为什么顶尖的开源 Coding Agent(如 OpenClaw)坚决抵制过度封装,最终只保留了几个最核心的工具。随后,我们将用 Go 语言补齐这块拼图,打造出驾驭工程中的“终极武器”——bash 工具
警惕 Context Bloat:为什么工具越多,Agent 越笨
在当前的 AI Agent 开发圈子里,有一种普遍的迷思:“只要我给模型的工具足够多,它的能力就越强。
”这导致了大量臃肿的框架和 MCP Server 的诞生。比如,一个标准的 GitHub MCP 可能包含 20 多个工具,消耗上万个 Token;一个 Playwright MCP 也会塞入几十个页面操作原语。如果你在引擎启动时加载了这些工具,会发生什么?
大模型的每一次思考(每一次 Turn 发起请求时),都必须把这些极其冗长的工具描述(JSON Schema)全部阅读一遍。这在业界被称为 Context Bloat(上下文膨胀)。
这会带来三个致命的后果:
极高的成本与延迟:仅仅为了问一句“帮我看看 main.go 的代码”,你就要向大模型发送 3 万个 Token 的前置工具描述。每次 API 请求的时间和金钱成本呈指数级上升。
注意力分散:这是最致命的。大模型的核心机制是注意力(Attention)。工具描述越多,大模型对核心任务指令的注意力就越弱。它非常容易发生幻觉(Hallucination),在几十个长得差不多的工具中调用了错误的那一个。
无尽的适配维护:你每加一个特定的专用工具(比如 search_jira_ticket),就要在 Go 引擎里维护一套繁琐的反序列化和 API 请求代码。一旦第三方接口变更,Agent 直接罢工
大道至简:图灵完备的 4 大原语
顶尖的 Harness 驾驭工程师是如何解决这个问题的?答案是:回归操作系统的本质。
其实本质上还是,还是避免提供与当前任务无关的信息,比如大量的Tool,绝大多数当前用不到,提供了就是噪音。
既然我们把 Agent 当作一个跑在本地工作区(Workspace)的工作流助手,那么它面对的环境就是操作系统的终端和文件系统。我们完全不需要为 git、grep、npm 单独写工具,因为操作系统里已经有了一个终极接口——Shell(Bash)。
在 OpenClaw / pi 的极简哲学中,仅需为大模型提供 4 个基础工具:
read:读取文件内容(获取环境信息)。
write:创建新文件或完全覆盖文件。
edit:精准的局部代码替换(外科手术式修改。由于其具备多级降级的复杂性,我们将在下一讲专门实现)。
bash:在当前工作区执行任意 Shell 命令(终极执行器)。

YOLO 哲学:放弃本地“安全剧场”
Harness 驾驭工程的实战经验告诉我们:对于在本地开发者机器上运行的 Agent,过度前置的安全校验往往是“安全剧场(Security Theater)”。
注:安全剧场(Security Theater)指一些安全措施主要停留在形式层面——例如做了很多看起来很严格的校验 / 流程,但这些手段对真实风险的降低帮助有限,或无法有效覆盖攻击的关键路径。其效果更像“展示安全姿态”,而不是实质性地提升安全性。
只要你允许 Agent 运行代码,它总能找到方法绕过静态的黑名单,比如把 rm 拆成变量拼接执行,或者写一个带有恶意逻辑的 Python 脚本再去运行它。为了防范这种小概率事件而引入极其复杂的权限控制,只会让 Agent 在日常开发中变得愚蠢且处处受限。
因此,在基础开发阶段,OpenClaw 奉行 YOLO 模式:默认全权信任,直接在工作区(WorkDir)中执行。
如果真的出了错,交给 Git 去回滚。