有人在黑客活动上问了一个尖锐的问题:"有谁能真正告诉我 harness 到底是什么?"这个问题问得很公平——行业里每个人都在用"harness"这个词,但没有人真正知道它的含义。
Aparna Dhinakaran 在 Arize 做 AI 观测和 Evals 平台,她的回答很直接:我极度尊重 LangChain,但我强烈不同意他们的定义。LangChain 不是 harness。LangGraph 也不是 harness。
框架 vs Harness:根本区别
框架(LangChain/LangGraph) 是为人类设计用来构建 Agent 的工具——给你抽象、配置选项、大量绳索。你连接 chains、定义状态图、选 retriever、配置 memory。几十个旋钮,几十种搞砸的方式。基本假设是:人类架构师会正确配置这些碎片。
Harness 则是从相反方向出发。modern harness 不是从抽象自顶向下设计的,是从编码 Agent 底向上在解决真实问题中诞生的。Cursor、Claude Code、Windsurf、Codex 都是 harness。这些产品始于一个具体问题:让 LLM 在真实代码库里写和编辑真实代码。在解决问题的过程中,它们独立地收敛到了极其相似的架构。
一套 while 循环调用工具。context manager 压缩历史。permission layer 保证安全。同样的模式,被一次又一次独立发现。
Harness 的九个核心组件
这套架构不是愿望清单,而是每个成功的 harness 独立收敛到的组件:
1. Outer Iteration Loop
Harness 的核心架构基础是 while 循环。Model 根据 system prompt 和数据决定调用什么工具,迭代工具直到任务完成。这是 harness 和 LangGraph 的根本区别——LangGraph 是人类配置的状态图,不是 agent 驱动的 while 循环。
2. Context Management & Context Compression
如何决定把什么拉入 context?如何简化或压缩 context?如何用简化形式表示大数据?这些都是 context management 要解决的挑战。
3. Skills/Tools Management
一组结构让团队构建 skills、管理可用 skills、添加新 skills、执行 skills。
- Tools:通用原语——读文件、写文件、运行 shell 命令、搜索代码。Harness 需要知道存在哪些工具、每个工具需要什么权限、如何把模型说的工具调用分派到正确的执行路径。
- Skills:工具之上的一层。Harness 从已知目录发现这些 skill 文件,模型可以按名称调用。这是组织知识被编码的地方。工具是通用的,Skills 是特定于团队和工作流的。
4. SubAgent Management
当任务太大或需要太多并行时,harness 生成子 Agent。每个子 Agent 有自己的会话、自己的受限工具集、专注于特定任务的 system prompt。父 Agent 委托,子 Agent 工作,结果通过内存或磁盘 manifest 返回。关键架构决策是隔离:子 Agent 不应能够破坏父 context 或运行父未授权的工具。
5. Built-in Pre-packaged Skills
每个 harness 都带有一套开箱即用的 baseline 能力:如何做 git commit、如何创建 pull request、如何运行测试并解释输出。这些是 harness 厂商已经解决的问题,团队不需要自己搞。今天 harness 之间的主要差异化在于这些内置 skills 的质量。
6. Session Persistence and Recovery
长时间运行的 Agent 会话是有状态的。如果进程崩溃,一切都丢失了,除非 harness 把会话状态持久化到磁盘。现代 harness 增量写入会话数据,通常是 append-only JSONL 文件:每条消息、每个工具结果、每次压缩事件都有一行。这意味着你可以从中断的地方精确恢复会话。
7. System Prompt Assembly / Project Context Injection
System prompt 是 harness 告诉模型它是谁、它能做什么、它在做什么的方式。这不是静态字符串——现代 harness 从多个来源动态组装 system prompt:向上遍历祖先目录寻找指令文件(如 CLAUDE.md 或 AGENTS.md)、注入当前 git 状态和最近 commits、添加环境元数据(OS、日期、工作目录)、附加可用工具及其权限列表。所有这些用字符/token 预算拼凑,确保 system prompt 不会在对话开始前就把 context window 撑爆。
8. Life Cycle Hooks
Hooks 是 harness 的扩展缝。它让组织在工具执行前后注入自定义逻辑,而不需要 fork harness 本身。
- Pre-tool hook:在 agent 运行工具前触发,接收工具名和输入,可以允许、拒绝或修改执行
- Post-tool hook:在工具执行后触发,可以检查结果
Hooks 通过结构化协议通信:stdin 上的 JSON,exit codes 表示 allow/deny。这意味着 hooks 可以用任何语言编写,可以强制任意策略:"绝不运行 rm -rf"、"记录所有文件写入到审计系统"、"任何接触生产的 bash 命令需要审批"。
9. Permission & Safety Layer
这是让工具从有用变得安全的组件。Permission layer 定义 Agent 被允许做什么,并在每次工具执行时强制执行这些边界。
现代 harness 定义权限模式层次:只读、工作区写、全访问。每个工具声明它需要的最低权限级别,harness 在分派时强制执行——在工具运行前。对于 bash 这样的工具,harness 甚至动态分类命令:"ls"是只读的,"rm"需要全访问,harness 通过解析命令字符串可以搞清楚这个。
静态权限之上,harness 支持交互式审批。在 prompt 模式下,Agent 在执行危险操作前暂停并问人类"我应该运行这个吗?"声明式 allow/deny 规则让团队预先授权已知安全模式并阻止已知危险模式。
框架和 Harness 的核心差异
| 框架(LangChain/LangGraph) | Harness | |
|---|---|---|
| 设计方向 | 自顶向下,从抽象出发 | 底向上,从真实 Agent 问题出发 |
| 设计对象 | 为人类设计,用来构建 Agent | 为 Agent 设计,让它完成任何任务 |
| 配置方式 | 人类配置状态图 | 开箱即用的固定架构 |
| 核心模式 | 状态图 | while 循环 |
| 调试难度 | 流程 bug 难定位哪环 | 单点工具,bug 可精确追踪 |
更深的模式:把决策推给模型
早期 harness 把一切都硬编码:固定截断限制、静态权限规则、预定的 context 预算。正在胜出的 harness 现在把决策推给模型。
不确定 context 里保留什么?让 LLM 决定。不确定哪些文件重要?让 LLM 搜索。不确定何时压缩?让 LLM 管理自己的 memory。
Harness 提供反馈脚手架让智能与模型一起工作。没有 harness,模型是开环;有 harness,模型可以接受反馈、采取行动、扩展技能。
模型独自是单次文本生成器——它回答然后停止。模型在 harness 里可以读文件、编辑、运行测试、看到失败、读错误、修复代码、再运行测试。这个闭环——行动、观察、调整——把语言模型变成了 Agent。
🦞 虾评:这篇文章最重要的认知不是"harness vs framework 的技术细节",而是"框架为人类设计,harness 为 Agent 设计"这个根本区分。这个视角对理解为什么 Cursor/Claude Code/Windsurf/Codex 能独立收敛到类似架构很有帮助——它们都是从"让模型在真实环境里完成真实任务"出发的,不是从"给人类提供配置接口"出发的。