JavaGuide - Harness Engineering
HarnessEngineering
Harness Engineering:六层检查框架、上下文管理与工程实践
Harness
一个很有名的公式将 Agent 概括为:Agent = Model + Harness。
其中 Model、LLM 虽然是 Agent 的决策中枢,却完全没有任何活动能力,堪称“缸中之脑”,它既没有记忆能力,无法选择上下文,也无法使用工具,甚至无法感知到外界,只能处理输入的文本。
而 Harness 就是为了补足裸露 LLM 的缺陷而被创造出来的产物。LLM 没有记忆?不能用工具?不能感知外界?没关系,由我们人类为 LLM 创造一个沙箱环境,只要能完成工作,它需要什么,我们就给它什么,一切以 LLM 的判断为准,我们只做后勤工作,换言之,我们要做一个全盘支持 LLM 运作的环境。
然而,我认为 Harness 还应当再次分层,将其分为 Runtime 和 Capacity 。前者为 Agent Loop 的运行时环境,包括工具系统、记忆系统、上下文管理系统、Agent Loop 感知反馈循环等,将之组成为一套独立的软件系统,缺少任何一个组件就无法使 Runtime 可靠运行的基础设施;而后者则是用于增强 Agent 的组件,例如 skill、知识库等研究如何让 LLM 更有效更精确完成任务的研究,虽然缺少也不会导致 Agent 停摆,但加上就有可能使 Agent 效果更好。
我的判断是,Capacity 中的一部分,例如 Skill,或类似于基于 Skill 构建 规划-执行-审查-纠错 Workflow 的做法,会随着 LLM 基础能力提升而触碰到边际效应,它们都有一个特点:以人类的视角去指导 LLM,以人类的智慧补足 LLM 缺失的智能。
这个判断其实已经被侧面映证过了一次,就是前面提到构建 Workflow 的做法,这种实践盛行于 2026年4月,基于 Claude Code 等 Agent 应用,使用 gstack、superpowers 等 skill 库编排各种工作流,特别是 规划-执行-审查-纠错,我们当时的想法是:为 LLM 构造一个无法出错、完全按照我们的编排执行的环境,就是 Harness Engineering。然而,这套做法在仅仅一段时间后就被摒弃了,有人认为是因为太 heavy 了,然而根本原因则是 LLM 在几个月内的成长速度完全超出想象,以至于我们引以为豪的工作流,基础模型自己就能构建了,甚至能够随着任务的不同而构建更加适合任务的工作流,我们不断地加砝码反而拖累了 Agent 的性能,或者说我们设想中的通用工作流本身就是一厢情愿。
综上,我认为当前 Harness 的重心要放在 Runtime 上,全世界工程能力最强的 deepseek 团队,更是直接将他们的 Agent 命名为 Deepseek Harness,Harness 实际上更向 Agent Loop Runtime 的概念靠拢。
Harness Engineering & Prompt Engineering & Context Engineering
三者并不处在同一维度,因此严格来说无法进行相互比较。
| 层级 | 解决的问题 | 关注点 | 典型工作 |
|---|---|---|---|
| Prompt Engineering | 怎么把指令说清楚 | 让模型理解意图,减少局部歧义 | 系统提示词设计、Few-shot 示例、思维链引导 |
| Context Engineering | 该给 Agent 看什么 | 在合适时机给模型提供正确且必要的信息 | 上下文管理、RAG、记忆注入、Token 优化 |
| Harness Engineering | 系统怎么持续执行、纠偏、观测和恢复 | 长链路任务中的持续正确、偏差修正、故障恢复 | 文件系统、沙箱、约束执行、反馈回路、观测 |
现在来看,从 Prompt Engineering 到 Harness Engineering 已经是不断被包含与发扬的关系:Prompt Engineering 重点关注提示词的写法与模型执行效果间的关系;Context Engineering 肯定了 Prompt Engineering 的研究重心,同时向外将研究扩展为如何有意识地控制、修订喂给模型的输入,这是基于各种外部存储信息变得逐渐重要的考量;而 Harness Engineering 则将 Context Engineering 容纳为自己的一个大子类,并连同其记忆系统、工具系统、Loop Runtime 等与模型一起构建一个可以的 Agent 软件系统。
Harness 的组成
我们按照逻辑功能划分:
记忆系统:从 session 每轮对话中沉淀出长期 & 短期记忆持久化;同时还应提供较为准确的检索机制。(由外部知识获取&文件系统共同构成)
执行环境:为 LLM 提供 bash,以及各种语言的编译运行环境等(实则只需要计算机系统环境变量有就行了,在 Tool 里加入 bash 等工具 LLM 就可以自行完成)
外部知识获取:接入 MCP 服务、Websearch 功能等。
文件系统:操作文件,git 版本控制(除了直接进行任务,另一个重要职责还有维护 Note)。
验证闭环:验证任务完成效果,重试机制等。
上下文管理:重中之重,直接依赖记忆系统、外部知识获取、文件系统的功能,对上下文进行构建和管理。
Harness 系统分层
上文中,是以为 LLM 赋予能力的不同划分的,Harness 作为一个软件系统,从按照层级可以划分:
| 层级 | 名称 | 解决什么问题 | 关键设计 |
|---|---|---|---|
| L1 | 信息边界层 | Agent 该知道什么、不该知道什么 | 定义角色与目标,裁剪无关信息,结构化组织任务状态 |
| L2 | 工具系统层 | Agent 怎么和外部世界交互 | 选择工具、控制调用时机、提炼工具结果并反馈 |
| L3 | 执行编排层 | 多步骤任务怎么串起来 | 让模型按“理解目标、判断信息、分析、生成、检查”的轨道推进 |
| L4 | 记忆与状态层 | 长任务中间结果怎么管理 | 独立管理当前任务状态、中间产物和长期记忆,避免状态混在一起 |
| L5 | 评估与观测层 | Agent 怎么知道自己做对了没有 | 建立独立于生成过程的验证机制 |
| L6 | 约束、校验与恢复层 | 出错了怎么办 | 预设规则拦截错误,失败时提供重试、回滚或降级 |
当前 Harness 实践仍然存在的问题
棕地项目如何改造?棕地项目指的是,基于一套已有代码的项目,通过改造、新增来构建项目的方式,这种项目的共性是基座项目一般技术老旧,甚至存在致命漏洞等问题,
测试验证中,通常是 Agent 完成测试、验证、重试的全部闭环,过程中是否会发生 Agent 对自己的结果过于自信?而即便由另外的 Agent 实例来评价,也仍然像是 “用同一双眼睛检查自己的作业”。而如果悲观地认为 Agent 验证闭环完全不可信,又会陷入人工大量判断的窘境。所以测试闭环环节,Agent 与人工评审之间的边界有待解决。
AI 生成代码的可维护性几何?LLM 经常性推翻自己的旧有结论,使用重写而非拓展的形式改造代码,长期来看不利于维护。
Harness 本身应该轻量级还是重量级?可以分场景而言,场景特定且不通用的场景,Harness 产品可以高度定制;而通用场景,则尽量做薄以尽可能减少对 LLM 本身的限制。
单 Agent vs. 多 Agent?
工具调用的可用性问题
如何保证工具调用的结果是正确的、无冗余的、
案例分析:OpenAI
Agents.md
老生常谈的问题,这个文件不应该放入太多内容,而且要尽量保证文字精简,不包含任何歧义。
工具与约束
If it cannot be enforced mechanically, agents will deviate。如果 Agent 的工作不能用机械性的流程规定,那么它就会跑偏。当然,这里说的不是探索性任务。
而且,约束不能只停留在文档中,执行失败时采用工具报警,警告 AI 比让 AI 自己验证好
知识库也分权威&不权威
例如 Slack,或者 Google Doc 的知识,其可信度无法保证, Agent 的执行就要打折扣。
类似于这种问题,引申出一个很重要的原则:知识要分层,权威知识库保证知识一定权威,非权威知识库的知识 Agent 不能全盘接受。
OpenAI 的做法是,将权威的团队知识放到 git 仓库里,Agent 有什么问题去仓库找答案。而为什么使用 git?实际上是看上了它的版本控制能力,知识也并非全程有效,权威知识来源里的知识只能保证在当下权威,无法保证未来是否权威。
清理熵
人类编写的代码都不能保证百分之百有价值,更遑论 Agent 生成的代码,OpenAI 也花费大量时间精力去清理代码,一开始由人类工程师手动清理,后来则让后台 Agent 定时扫描清除。
另外,Agent 也会定时扫描 git 中的权威知识,定时清理,这也尽可能避免了权威知识被污染。
案例分析:Anthropic
GAN 架构
即: Planner(规划者)→ Generator(执行者)⇄ Evaluator(评估者)
模型升级时需要重新验证 Harness 机制
Anthropic 称,当模型上下文占用超过 40% 时,会陷入上下文焦虑,执行效果会大打折扣。Anthropic 对此的做法是,保留上下文关键信息,使用结构化 note 进行保存,然后清空 session 的 context 占用,使用 note 填充然后重新开始执行。
然而,我们有理由认为,上下文焦虑并不是一个普遍的问题,在 sonnet4.5 上问题明显,但是在 opus4.5 上几乎不存在了,而其他模型的焦虑程度、焦虑窗口都不一致,所以我们可以认为没有必要在设计 Agent 时为模型的失败埋单。
而 claude code 高度精细的 auto_compaction 机制已经可以避免很多问题了;而在模型日益吸收 harness/capacity 后变得越来越强大的情况下,原本为了应对上下文焦虑的 reset 机制也已经去除了。
这个案例也很好说明了,为什么模型升级后,Harness 的某些机制要重新验证:因为 cc、codex 这类 harness 适配 LLM 的 Agent,机制只是针对某些特定版本模型生效的。
