
2026年2月,LangChain发布了他们coding agent在Terminal Bench 2.0上的最新成绩:从52.8%提升到66.5%,排名从Top 30之外冲进Top 5。底层模型固定为gpt-5.2-codex,权重一个字节没改。他们改变的是包裹在模型周围的那套系统——系统提示词、工具定义、中间件逻辑、验证循环、上下文组装策略。
另一组数据更极端:同一个模型,仅改变文件编辑界面的调用格式,编码基准分数从6.7%跃升至68.3%。marmelab对246个仓库的审计显示,同一模型在8种不同Harness下运行相同的25个任务,成功率从68%到88%不等。
这些数字指向同一个结论:模型能力正在商品化,而围绕模型构建的工程系统——Harness——正在成为决定Agent可靠性与交付质量的分水岭。
要理解Harness Engineering的定位,需要先区分三个经常被混为一谈的概念。
Prompt Engineering解决的是“如何把指令表达清楚”——让模型理解意图,减少局部歧义。典型工作是System Prompt设计、Few-shot示例、思维链引导。Context Engineering解决的是“应该给Agent看什么”——在正确的时间向模型提供正确且必要的信息,包括RAG、记忆注入、Token优化。
Harness Engineering解决的是一个更系统性的问题:长链路任务中,系统如何持续执行、纠正偏差、观测与恢复。它管理的是模型之外的一切:文件系统与沙箱环境、工具调用接口、编排逻辑与中间件、反馈循环与约束机制、可观测性与评估体系。
一个操作性定义来自Mitchell Hashimoto:“每当Agent犯了一个错误,你就花时间设计一个解决方案,使得Agent在未来不会再犯同样的错误”。这一定义将Harness Engineering从“系统设计”具体化为“持续迭代的错误处理闭环”——每一类失败都应该被固化为一条结构化的约束,而非依赖于在提示词中反复叮嘱。
成熟的Harness通常具有清晰的分层设计。从工程实践的角度,可以拆解为六个核心层次。
第一层:上下文管理层。 核心问题是“如何让模型在有限的窗口里,看到此刻应该看到的东西”。长上下文存在“Lost in the Middle”效应——模型在中间段的注意力明显下降;成本随Token数量线性增长;无关信息会干扰模型聚焦。工程解决方案包括动态组装上下文(每轮根据当前任务检索相关文件和历史决策)、上下文压缩(接近上限时自动摘要早期对话)、分层加载(核心指令常驻、工作记忆按需加载、长期记忆按查询拉取)。
第二层:工具与执行层。 工具名、参数schema、描述文案,每一个字都会影响模型的调用准确率。执行沙箱隔离代码执行和Shell命令。工具执行结果需要以模型能理解的结构化方式回传——成功/失败、错误信息、输出摘要。
第三层:编排与规划层。 这是Agent从“单轮问答”升级为“多步任务执行”的关键。ReAct循环(Reason→Act→Observe→再思考)是最经典的单Agent循环。Plan-and-Execute模式先生成完整计划再逐步执行,支持中途重规划。更复杂的场景需要子代理委派——主Agent将独立的多步骤任务交给子Agent,子Agent的工作不污染主Agent的上下文。
第四层:状态与记忆层。 长周期任务需要跨会话的状态持久化。工程实践包括基于文件的记忆系统(如MEMORY.md)、向量检索的长期记忆、以及会话日志的仅追加设计以便恢复和回放。
第五层:验证与反馈层。 这是Harness Engineering区别于简单工具调用的核心。验证循环的核心思想是“让AI验证自己的输出,而不是直接交付”。基于规则的验证包括测试、linter、类型检查器;基于模型的验证使用另一个LLM作为评判者;自验证则要求Agent在执行过程中内置检查点,防止死循环与静默失败。一个值得注意的设计模式是:在Agent的query()循环中,只有少数步骤是“调用模型”,其余步骤全是验证和修复逻辑。
第六层:安全、约束与失败恢复层。 权限模型、危险操作拦截、失败重试与升级策略、预算管理。核心原则是“约束应该在模型之外强制执行”——提示词层面的防御可以被自适应攻击绕过,而运行时级别的约束(如沙箱、权限白名单、操作审批)才是可靠的。
以下是一个简化的Harness实现骨架,展示了上下文管理、子代理委派和验证循环的核心逻辑。代码使用Python伪代码风格,重点在于结构而非具体API。
from dataclasses import dataclass, field
from typing import Callable
import json
@dataclass
class HarnessState:
"""Harness维护的全局状态,跨越Agent的多次调用"""
todos: list[dict] = field(default_factory=list)
files: dict[str, str] = field(default_factory=dict) # 虚拟文件系统
token_budget: int = 128_000
tokens_used: int = 0
verification_log: list[dict] = field(default_factory=list)
class Harness:
"""
Harness = 模型之外的一切。
它不负责'想',负责让'想'的结果变得可控、可验证、可恢复。
"""
def __init__(self, model_client, tools: dict, system_prompt: str,
compaction_threshold: float = 0.4):
self.model = model_client
self.tools = tools
self.system_prompt = system_prompt
self.state = HarnessState()
# 上下文使用率超过40%时触发压缩——这是Smart Zone的上限
self.compaction_threshold = compaction_threshold
# ---------- 上下文管理 ----------
def _assemble_context(self, task: str, history: list[dict]) -> list[dict]:
"""
动态组装上下文:不是把历史全塞进去,而是根据当前任务
决定'此刻应该看到什么'。
"""
messages = [{"role": "system", "content": self.system_prompt}]
# 常驻:当前TODO列表(精简版)
active_todos = [
{"id": t["id"], "status": t["status"], "desc": t["desc"][:80]}
for t in self.state.todos if t["status"] != "completed"
]
if active_todos:
messages.append({
"role": "system",
"content": f"当前任务清单:\n{json.dumps(active_todos, ensure_ascii=False)}"
})
# 按需:与当前任务相关的文件内容
relevant_files = self._retrieve_relevant_files(task)
if relevant_files:
messages.append({
"role": "system",
"content": f"相关文件:\n{relevant_files}"
})
# 历史:最近N轮对话(经过压缩的)
messages.extend(history[-6:])
return messages
def _maybe_compact(self, history: list[dict]) -> list[dict]:
"""
上下文使用率接近阈值时,压缩早期对话为摘要。
这是防止'Lost in the Middle'和成本爆炸的关键机制。
"""
usage = self.state.tokens_used / self.state.token_budget
if usage < self.compaction_threshold or len(history) < 10:
return history
# 保留最近4轮完整对话,其余压缩为摘要
recent = history[-4:]
older = history[:-4]
summary = self._summarize(older) # 调用模型生成摘要
compressed = [{"role": "system", "content": f"[历史摘要] {summary}"}]
compressed.extend(recent)
self.state.tokens_used = self._estimate_tokens(compressed)
return compressed
# ---------- 子代理委派 ----------
def delegate(self, sub_task: str, sub_agent_prompt: str) -> str:
"""
将独立的多步骤任务交给子代理执行。
关键设计:子代理的中间过程不进入主Agent的上下文,
只有最终结果返回。这防止了上下文污染。
"""
sub_history = []
sub_context = [
{"role": "system", "content": sub_agent_prompt},
{"role": "user", "content": sub_task}
]
for _ in range(15): # 子代理有自己的步数上限
response = self.model.chat(sub_context)
if response.tool_calls:
result = self._execute_tool(response.tool_calls[0])
sub_context.append({"role": "tool", "content": result})
else:
# 子代理给出最终答案
return response.content
return "[子代理达到步数上限,未完成任务]"
# ---------- 验证循环 ----------
def verify(self, action: str, result: str) -> dict:
"""
验证循环:不让Agent的声明直接成为最终状态。
每一类关键操作都有对应的验证规则。
"""
checks = []
# 规则1:文件操作后验证文件是否真的存在且非空
if action.startswith("write_file"):
path = action.split(":")[1].strip()
content = self.state.files.get(path, "")
checks.append({
"name": "file_exists",
"passed": bool(content),
"detail": f"{path} {'已写入' if content else '为空或不存在'}"
})
# 规则2:代码执行后验证是否返回了预期信号
if action == "run_tests":
checks.append({
"name": "tests_passed",
"passed": "FAIL" not in result.upper(),
"detail": result[:200]
})
# 规则3:任何声明'完成'的操作必须通过至少一项独立验证
if "完成" in result or "done" in result.lower():
checks.append({
"name": "independent_verification",
"passed": self._cross_check(),
"detail": "需要至少一项独立验证确认完成声明"
})
all_passed = all(c["passed"] for c in checks)
self.state.verification_log.append({
"action": action, "checks": checks, "passed": all_passed
})
return {"passed": all_passed, "checks": checks}
# ---------- 主循环 ----------
def run(self, task: str, max_steps: int = 30):
"""
Agent Harness的主循环。
注意:循环中的大部分步骤不是'调用模型',而是
上下文组装、压缩、工具执行、验证和状态更新。
"""
history = [{"role": "user", "content": task}]
self.state.todos = self._initial_plan(task)
for step in range(max_steps):
# 1. 组装上下文(不是全量历史)
context = self._assemble_context(task, history)
# 2. 调用模型(这是循环中唯一'调用模型'的步骤)
response = self.model.chat(context)
# 3. 如果有工具调用,执行并验证
if response.tool_calls:
for tc in response.tool_calls:
result = self._execute_tool(tc)
verification = self.verify(tc.name, result)
if not verification["passed"]:
# 验证失败 → 将失败信息注入下一轮上下文
failure_msg = (
f"操作 {tc.name} 的验证未通过:\n"
f"{json.dumps(verification['checks'], ensure_ascii=False)}\n"
f"请分析原因并修正。"
)
history.append({"role": "system", "content": failure_msg})
else:
history.append({"role": "tool", "content": result})
else:
# 模型给出最终回答
history.append({"role": "assistant", "content": response.content})
break
# 4. 更新状态,必要时压缩上下文
self._update_todos(response)
history = self._maybe_compact(history)
return self._final_report()
def _execute_tool(self, tool_call) -> str:
tool_fn = self.tools.get(tool_call.name)
if not tool_fn:
return f"未知工具:{tool_call.name}"
try:
return str(tool_fn(**tool_call.args))
except Exception as e:
return f"执行失败:{type(e).__name__}: {e}"
def _summarize(self, messages):
# 实际实现会调用模型生成结构化摘要
return "[早期对话已压缩]"
def _estimate_tokens(self, messages):
return sum(len(m.get("content", "")) // 3 for m in messages)
def _retrieve_relevant_files(self, task):
return ""
def _initial_plan(self, task):
return []
def _update_todos(self, response):
pass
def _cross_check(self):
return True
def _final_report(self):
return {
"todos": self.state.todos,
"verification_log": self.state.verification_log
}这段代码展示的核心模式是:Harness循环中,大部分步骤是确定性的工程逻辑,只有少数步骤是“让模型想” 。_assemble_context、_maybe_compact、verify、_update_todos 都是确定性代码。模型的价值在于处理chat()返回中那些需要判断的部分,而Harness的价值在于确保这些判断不会失控。
Harness Engineering的崛起有扎实的实验证据支撑,但它并非万能方案。几个关键局限需要被诚实面对。
验证器质量是瓶颈。 企业Harness实践调研指出,“验收能力是当前最主要的落地瓶颈”。如果验证器本身不够可靠——比如用来判断“代码是否正确”的测试用例覆盖不全——Harness就无法有效拦截错误。验证器的质量上限,决定了Harness的可靠性上限。
Harness改进可能被模型内化。 翁荔在万字长文中指出,“许多Harness层的改进最终会被内化为模型能力,就像提示词技巧被指令微调吸收一样”。这意味着今天精心设计的某些Harness机制,明天可能因为模型能力的提升而变得多余。Harness Engineering的长期价值,更可能在于那些无法被内化的部分:与外部系统的接口、人类监督的嵌入方式、以及组织层面的约束策略。
架构边界仍在快速变化。 2026年的Harness仍不属于成熟的软件基础设施市场,“核心组件正在稳定,但架构边界、指标体系、治理责任和最佳实践仍在快速变化”。没有人能确定当前的六层或三层划分是最终形态。
对人类判断力的要求没有降低。 当一个系统足够可靠时,人类容易过度信任它,从而放松审查。Harness Engineering的一个隐性风险是:它可能通过生产“看起来可靠”的系统,反而加剧了自动化偏见和信任校准错误。
Harness Engineering的核心洞察可以浓缩为一句话:当你不是在造模型时,你造的就是Harness。模型提供概率性的智能,Harness提供确定性的工程控制。前者的能力在快速提升,后者的设计质量——在模型能力水平给定的情况下——决定了Agent在实际交付中能走多远。
对于工程团队而言,这意味着能力建设的重心需要从“如何写出更好的提示词”转向“如何设计更可靠的约束、验证和恢复机制”。提示词仍然重要,但它是Harness的输入之一,而不是Harness本身。当一个Agent在第三步正确调用了工具、在第七步验证了输出、在第十二步从一次失败中恢复了执行,背后起作用的是一套被精心设计的工程系统,而非一段更长的提示词。
这套系统不会因为下一个模型的发布而过时——至少那些与外部世界交互的接口、人类监督的嵌入点、以及失败恢复的策略,不会。它们解决的是概率性引擎与确定性交付之间的根本张力,而这个张力不会因为模型变聪明就自动消失。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。