
什么是“harness”?
LLM 只生成文本、无法执行任何操作;harness 提供工具、调用语法、解析执行器与结果回传,把文本变成行动。
说实话:我写这篇文章是因为我厌倦了反复解释这件事,而且似乎没有任何一个资源能真正讲清楚 harness 到底是什么。
读完本文,你应该会掌握关于 harness 是什么、它如何运作的一切必要知识。
人类使用界面
一般来说,人类并不是通过写代码来使用计算机的。他们使用的是某种形式的界面,无论是终端、网站还是应用。
从理论上讲,人类完全可以为想完成的每项任务编写独特的 Python 或 JS 代码。但我们并没有让他们这么做,而是通过按钮、快捷键、命令等方式让他们访问这些代码。
界面的例子:Chrome、Claude Code、ChatGPT App(前身为 Codex)
同样值得注意的是,人类通常看不到底层的代码。人类只看到界面。
LLM 使用 harness
默认情况下,LLM 能做的只有生成文本。要让语言模型做更多事情,它就需要工具。如今大多数 LLM 都经过训练,能够使用诸如“read_file”(用于访问你电脑上的文件)、“edit_file”(用于修改这些文件)、“bash”(用于运行命令)和“search”(用于在网上查找数据)之类的工具。
不过,LLM 仍然只是发送文本!它无法像人类那样点击按钮。因此,我们需要一种供 LLM 使用的自定义文本格式,用来表示“你应该运行某些代码”。假设我们给 LLM 一种调用工具的格式,例如:
<read_file name="README.md">
现在 LLM 知道它可以按这种格式回复了。但这仍然只是文本,它什么也做不了!就像在电脑关机时敲键盘或移动鼠标一样。
必须有某个东西来解释这些回复,然后根据 LLM 回复的内容运行相应的代码。
要让 LLM 真正做事,它需要:
- 能够做事的工具(read_file、edit_file、bash、search 等)
- 一种通过文本调用这些工具的特殊语法
- 一个解析消息、识别该语法并运行代码的系统
- 一种将工具返回的响应回传给 LLM 的方法
- 一份可用工具列表,并附带各工具的使用说明
这就是 harness。
Claude Code 不就是一个 harness 吗?
算是吧。
Claude Code 包含两部分:界面和 harness
当你在终端运行 “claude” 时,打开的是 Claude TUI。当你进入 Claude 桌面应用的 “code” 标签页时,打开的是 Claude Code GUI。这两者都不是 harness。
在底层,Claude Code 使用 Anthropic Agent SDK 与智能体交互。ChatGPT 也是如此,由 ChatGPT/Codex 应用与 Codex App Server(内置于 CLI 中)交互。

我理解人们为什么会困惑:Claude Code 和 Codex 都把 harness 直接内置到了各自的应用中。
不过,你也可以把同样的 harness 内置到其他应用中!例如:
- Grok Bot 使用了 Cursor 的 harness
- T3 Code 使用了 Anthropic Agents SDK 和 Codex App Server
- OpenClaw 使用了 Pi
harness 是一个独立的组件,很少甚至几乎不会直接暴露给使用这些应用的人类。
工具归谁所有?
让我们把执行框架想象成一座厨房。
厨房里有各式各样的工具。锅、平底锅、刀具、锅铲、搅拌机等等。
没有哪座厨房能备齐每位厨师所需的一切。
优秀的执行框架正是基于这一前提构建的,允许用户自带工具。
需要明确的是:大多数重要工具都由执行框架直接提供。Codex 和 Claude Code 都内置了大量工具,而 Pi 等其他执行框架则要精简得多。
情况从这里开始变得复杂,所以让我再画一张图。

橙色方框代表“Claude Code 内置的内容”(确切地说是 agents sdk)。
你可以添加许多自定义工具,比如 TypeScript 插件,为你的 LLM 提供一些检查代码的工具;或者 CUA 插件,让智能体能够控制你的电脑。
注意“工具平面”与人类/LLM 层之间的那条线。无论是人类还是 LLM,都无法看到或触及这些工具。我们无从得知它们是否存在。执行框架正是将它们暴露出来的东西——既暴露给 LLM,也暴露给界面(我们正是通过界面看到它们)。
MCP 让事情变得稍微复杂一些
MCP(Model Context Protocol,模型上下文协议)是一项标准,旨在让 harness 更容易访问外部资源。简单来说:工具是“在这里运行代码来完成某件事”,而 MCP 是“向别处发起 API 请求来完成某件事”。
工具直接提供代码。MCP 让代码存在于别处,但 LLM 仍然可以通过 MCP 发起请求来完成事情。
MCP 最常见的用途是向 LLM 暴露数据。想让 ChatGPT 翻看你的邮件?用 MCP。想让 Claude 查看你网站的分析数据?用 MCP。
Chrome 扩展有点像工具。它们可以改变网站的工作方式,实现方式是让代码在你的电脑上、在 Chrome 中运行。
MCP 更像网站。你不需要安装任何东西,只需要知道 URL。拿到 URL 之后,你(应该)就能获得使用它所需的全部信息 :)
把这些放在一起,大致是这样的:

……等等,T3 Code 怎么也在里面?让我解释一下。

T3 Code 向 LLM 暴露自定义功能,用来做 harness 本身做不到的事情。例如,我们允许使用 Claude Code 的线程在 Codex 中派生子代理。其他工具也这么做,比如 Herdr、Orca 和 Superset 就是一些例子。
那么,为什么把它以 MCP 的形式暴露出来?这难道只是为了省去自己造 harness 的某种廉价伎俩吗?
回想一下前面这句话:
工具直接提供代码。MCP 让代码存在于别处,但 LLM 仍然可以通过 MCP 发起请求来完成事情。
T3 Code 有大量代码来实现诸如多 harness 子代理之类的酷炫功能。从技术上讲,我们本可以把 T3 Code 最酷的功能全部重建成一组插件,分别适配 Claude Code、Codex、Antigravity、Pi、Cursor、Muse……
或者,我们可以把所有代码都留在 T3 Code 本身,只暴露一个简单的 MCP 服务器供 LLM 使用 :)
回到厨房的例子,MCP 几乎就像食谱。它们是做某件事的方法,但它们并不是事情本身。
T3 Code 是在给厨房提供一本食谱。它完全不改变厨房的运作方式。如果厨师们决定想看看我们的食谱,那太好了!他们也可以完全无视它,什么都不会改变。
……那么,什么是 agent?
你知道我有多自豪吗——我一路写到这里,居然没有一遍又一遍地说 Agent 却不给它下定义?这可不容易,哈哈。
tl;dr —— Agent 就是 harness 和 LLM 结合之后的产物。
LLM 只是生成文本,它们本身什么也不做。Harness 只是厨房,它们做不出任何菜。LLM 和 harness 的组合创造出一个“Agent”。
不同的“Agent”往往只是不同的 harness 配置,比如自定义工具、指令、MCP 服务器等等。
T3 Code 是 harness 吗?
不是。如果你不带上一个 harness,T3 Code 就无法工作。
回到厨房的例子:
- 厨师 = LLM
- 厨房 = harness
- T3 Code = 餐厅
T3 Code 是一家餐厅,你想带什么厨房来都行。我们有自己的拿手食谱,并且会把那本食谱提供给每个厨房,但除非你让厨师去看,否则厨师是不会翻开它的 :)
想深入了解的读者……
如果你喜欢这种自上而下的讲解方式,就让你的老板掏钱买我下周推出的 Mega.dev 课程吧。我在那里会把这一切讲得深入得多 :)