什么是“harness”?

LLM 只生成文本、无法执行任何操作;harness 提供工具、调用语法、解析执行器与结果回传,把文本变成行动。

THEO - T3.GG(@THEO)教程 · 已翻译 · 约 8 分钟
阅览室 · AI 最佳实践#harness#Code#工具#MCP#agent原文

说实话:我写这篇文章是因为我厌倦了反复解释这件事,而且似乎没有任何一个资源能真正讲清楚 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 课程吧。我在那里会把这一切讲得深入得多 :)

也去看看 T3 Code。它是开源的,所以你可以让你的 agent 解释它的工作原理,从而深入得多

已读完 · 本文由熊猫易读翻译重排