🐳 导读 为什么现在需要Harness
📄 一句话概括

模型的本事只有一样——【预测下一个 Token】;可用户要的是【把活干完】。这两件事之间隔着的一整层,就叫 Harness。DSH 把它写成一句话:Model + Harness = Agent。

📝 本节和前面几节的关系

这是全书第 1 篇,导读的第 1 节,也是整本书的地基:模型和 Agent 不是一回事。后面第 1 章分【产品与 Runtime】、第 3 章讲插件、第 6 章拆 Agent 一轮工作,全都是在给这一篇里说的【模型之外那一层】补细节。

一、模型的输出,只有一种东西:Token

不管多大的模型,它一次只做一件事:接着前面的内容,猜下一个 Token。 然后把猜出来的这个 Token 接到后面,再猜下一个。就这样一个一个接下去。

这意味着它在【出生】时就不具备几样东西:

所以严格说,模型是一个把文字变成文字的东西,不是一个能干活的东西。

二、但用户说的【干活】,是七件事

换到用户这一侧,同样一个任务——【找出仓库里没写测试的函数,补上测试并跑通】—— 里面实际发生了七件事:

  1. 理解要干什么(这是模型的长项)
  2. 知道有哪些文件
  3. 打开文件读内容
  4. 修改文件
  5. 跑测试
  6. 看测试结果,决定下一步
  7. 记住前面做过什么

七件事里,模型只包了第一件。剩下六件,一件它都做不了—— 不是做得不好,是它根本没有手。

三、中间那一层,就是 Harness

Harness 这个词本义是马具、挽具——套在马身上、让马能拉车的那一套东西。 马有力气,但光有马拉不动车;得有人给它套上挽具、再接上车。

DSH 把这件事写成了一句等式:

Model + Harness = Agent

读法是:模型负责想,Harness 负责其余一切。 那个【其余一切】里装着:工具(让它能读文件、跑命令)、 会话存储(让它记得上一轮)、沙箱(决定命令能在哪儿跑)、 Agent 循环(一轮一轮地把结果送回去),还有界面(让人能看、能插手)。

这也解释了为什么 DSH 的口号是【一切皆插件】—— 上面列的每一样,在 DSH 里都是一个可以单独装卸的插件。

四、为什么这个区分对你很重要

分清【模型】和【Harness】之后,很多以前觉得玄的事就有解释了:

一句话记住:马跑得快不快是模型的事,车拉不拉得动是 Harness 的事。

五、动手 Demo:数一数七件事里模型包了几件

把上面那七件事列出来,按【谁在做】分一下类:

tasks = [
    ("理解要干什么", "模型", "不缺"),
    ("知道有哪些文件", "工具", "缺:看不见磁盘"),
    ("打开文件读内容", "工具", "缺:读不到正文"),
    ("修改文件", "工具", "缺:写不动磁盘"),
    ("跑测试", "工具", "缺:跑不了命令"),
    ("看结果再决定", "Agent 循环", "缺:没人送回去"),
    ("记住前面做过什么", "会话存储", "缺:下一轮就忘"),
]
n = sum(1 for _, who, _ in tasks if who == "模型")
print("七件事里,模型自己包了 %d 件,占 %.0f%%" % (n, n / len(tasks) * 100))
print("剩下 %d 件由 Harness 提供" % (len(tasks) - n))

实跑输出:

--------------------------------------------------------------------
一次任务的活,到底是谁在干
--------------------------------------------------------------------
  用户要的是【把活干完】,模型给的只是一串 Token。中间差的那一截,
  就是 Harness 要补的部分——DSH 把这句话写成了一个等式:

        Model + Harness = Agent
        (模型负责推理,其余一切都归 Harness)

  拿一个具体任务看:找出仓库里没写测试的函数,补上测试并跑通。
  这个任务里其实发生了七件事:

  工作环节               谁在做         只有模型时缺什么
  -----------------------------------------------------------
  理解要干什么           模型           不缺,这是模型的强项
  知道有哪些文件         工具           缺:模型看不见磁盘
  打开文件读内容         工具           缺:模型读不到正文
  修改文件               工具           缺:模型写不动磁盘
  跑测试                 工具           缺:模型没法执行命令
  看结果再决定下一步     Agent 循环     缺:没人把结果送回去
  记住前面做过什么       会话存储       缺:下一轮就忘了
  -----------------------------------------------------------

  七件事里,模型只包了第一件。剩下六件都要 Harness 提供。
  按这个分工,Harness 要提供的是一整套能力:

  能力           解决什么                   在 DSH 里是插件
  ---------------------------------------------------------------
  模型适配       连上哪个模型、怎么调       是
  工具注册表     有哪些工具、谁能用         是
  会话存储       这轮记得住上一轮           是
  沙箱           命令在哪儿跑、能碰什么     是
  Agent 循环     一轮一轮地推进             是
  界面           人怎么看、怎么插手         是(连 UI 都是插件)
  ---------------------------------------------------------------

  算一笔账:模型真正【生成】的东西,在一个任务里占多少?

  示意算例(按一次中型代码任务估):
    模型自己写出来的内容       约 1.2 万 Token
    工具返回、被读进上下文的内容 约 50 万 Token
    差额倍率 = 50 / 1.2 ≈ 42 倍

  也就是说,任务里流动的内容有九成以上不是模型生成的,
  而是 Harness 从外面搬进来、再送回去的。
  这解释了为什么同一句话交给同一个模型,换个 Harness 效果就变了——
  模型没变,但它看到的东西、能做的事、被怎么催着往前走,全变了。

这七行就是一本 Agent 教材的目录。左边那列工作,右边那列【缺什么】—— DSH 的每一类插件,都是在补右边某一格的窟窿。 所以后面看插件名的时候,你可以随时回到这张表来对号。

30 秒实验

  1. 打开你现在用的 AI 对话工具,问它一个需要看你本地文件的问题,看它会不会说【我读不到你的文件】。
  2. 回想最近一次让 AI【帮我改个东西】,数一下它实际做了几步——那几步里哪几步是工具在干活。
  3. 把同一句提示词分别丢给你手上两个不同的 AI 工具,看结果差在哪:是模型差,还是给它的信息差。

常见误区

  1. 错误:Harness 就是那个聊天界面。——纠正:界面只是 Harness 最外面的一层。Harness 里还装着工具、会话、沙箱、循环这些看不见的东西。
  2. 错误:模型够强就够了,Harness 无所谓。——纠正:七件工作里模型只包一件,给它看什么、让它做什么、怎么催它往下走,全在 Harness 手里。
  3. 错误:模型只会生成 Token,所以它其实什么也做不了。——纠正:正因为只会生成 Token,Harness 才有事可做——把 Token 翻译成动作,再把动作的结果翻译回 Token。
自测三问(点开对答案) 1. 模型在一次任务里,自己包了哪几件事? —— 只有【理解要干什么】这一件。列文件、读、写、执行、记住、推进,全部由 Harness 提供。 2. Harness 这个词本义是什么? —— 马具、挽具。模型是马,Harness 是把它套上、让它能拉车的那一套东西。 3. 为什么同一句话、同一个模型,换个工具结果就变了? —— 因为模型看到的内容、能做的事、被推进的节奏全变了——**变的是马具,不是马**。

相关笔记