首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Harness Engineering:当模型能力不再是瓶颈,工程系统的设计质量才是

Harness Engineering:当模型能力不再是瓶颈,工程系统的设计质量才是

原创
作者头像
用户12502707
发布于 2026-09-29 10:25:56
发布于 2026-09-29 10:25:56
1440
举报

一个被数据反复确认的反直觉事实

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可靠性与交付质量的分水岭。

三层递进:从Prompt到Context再到Harness

要理解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:代码骨架

以下是一个简化的Harness实现骨架,展示了上下文管理、子代理委派和验证循环的核心逻辑。代码使用Python伪代码风格,重点在于结构而非具体API。

代码语言:javascript
复制
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 Engineering的崛起有扎实的实验证据支撑,但它并非万能方案。几个关键局限需要被诚实面对。

验证器质量是瓶颈。 企业Harness实践调研指出,“验收能力是当前最主要的落地瓶颈”。如果验证器本身不够可靠——比如用来判断“代码是否正确”的测试用例覆盖不全——Harness就无法有效拦截错误。验证器的质量上限,决定了Harness的可靠性上限。

Harness改进可能被模型内化。 翁荔在万字长文中指出,“许多Harness层的改进最终会被内化为模型能力,就像提示词技巧被指令微调吸收一样”。这意味着今天精心设计的某些Harness机制,明天可能因为模型能力的提升而变得多余。Harness Engineering的长期价值,更可能在于那些无法被内化的部分:与外部系统的接口、人类监督的嵌入方式、以及组织层面的约束策略。

架构边界仍在快速变化。 2026年的Harness仍不属于成熟的软件基础设施市场,“核心组件正在稳定,但架构边界、指标体系、治理责任和最佳实践仍在快速变化”。没有人能确定当前的六层或三层划分是最终形态。

对人类判断力的要求没有降低。 当一个系统足够可靠时,人类容易过度信任它,从而放松审查。Harness Engineering的一个隐性风险是:它可能通过生产“看起来可靠”的系统,反而加剧了自动化偏见和信任校准错误。

真正的能力迁移

Harness Engineering的核心洞察可以浓缩为一句话:当你不是在造模型时,你造的就是Harness。模型提供概率性的智能,Harness提供确定性的工程控制。前者的能力在快速提升,后者的设计质量——在模型能力水平给定的情况下——决定了Agent在实际交付中能走多远。

对于工程团队而言,这意味着能力建设的重心需要从“如何写出更好的提示词”转向“如何设计更可靠的约束、验证和恢复机制”。提示词仍然重要,但它是Harness的输入之一,而不是Harness本身。当一个Agent在第三步正确调用了工具、在第七步验证了输出、在第十二步从一次失败中恢复了执行,背后起作用的是一套被精心设计的工程系统,而非一段更长的提示词。

这套系统不会因为下一个模型的发布而过时——至少那些与外部世界交互的接口、人类监督的嵌入点、以及失败恢复的策略,不会。它们解决的是概率性引擎与确定性交付之间的根本张力,而这个张力不会因为模型变聪明就自动消失。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一个被数据反复确认的反直觉事实
  • 三层递进:从Prompt到Context再到Harness
  • 六层架构:从上下文管理到安全约束
  • 最小可行的Harness:代码骨架
  • 当前边界:Harness Engineering不能做什么
  • 真正的能力迁移
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档