Harness Engineering 从零理解到动手实践

Harness Engineering = 给 AI Agent 设计"缰绳 + 马鞍 + 跑道护栏 + 反馈镜子"的工程方法。

它不是优化模型本身,而是构建一整套让 Agent 跑得稳、跑得久、不跑偏 的运行控制系统。


先说结论

如果只用一句话解释 Harness Engineering:

它是在模型之外,给 Agent 搭建一整套"可读、可控、可验证、可恢复"的运行环境。

它关心的重点不是:

  • 模型参数多不多
  • Prompt 写得花不花
  • 换哪个底座更强

而是:

  • Agent 为什么会半路跑偏?
  • 为什么会"嘴上说做完了,实际没做"?
  • 为什么长任务越跑越乱?
  • 为什么接了很多工具以后,系统反而更不稳定?
  • 怎么让同样的错误别反复发生?

这就是 Harness Engineering 想解决的问题。

说明:本文主要从 AI coding / agent 工程实践语境讨论 Harness Engineering,强调其工程含义,不追求术语的唯一标准定义。


一、为什么会需要 Harness Engineering?

1.1 一个人人都能秒懂的场景

想象你雇了一个天才实习生:

  • 打字极快
  • 精力无限
  • 什么都懂一点
  • 永远不抱怨加班

听起来很美好。 但真实工作里,你很快会发现它有这些毛病:

症状 具体表现
偷懒 多步骤任务做到一半,就说"已完成",其实只做了前几步
迷失 长任务里忘了初始目标,来回试已经失败过的方法
自我感觉太好 让它评估自己写的代码,常常会说"没问题",哪怕明显有 bug
上下文混乱 对话一长、信息一多,就开始草草收尾
无视规矩 团队有明确规范,它仍按自己熟悉的风格乱写

这些问题很多时候不是因为模型不够聪明 ,而是因为它缺少一套外部约束反馈系统

在一些长任务开发实验里,研究者就观察到类似现象: 当上下文越来越长、接近窗口上限时,模型往往不是更认真地把任务收尾,而是更容易出现"仓促结束"、"提前停止"这类行为。这个问题本质上不是智商问题,而是运行环境设计问题


1.2 从"怎么问"到"怎么搭环境"

过去两三年里,AI 工程实践的关注重点,大致经历了一个逐层外扩的过程:

阶段 核心问题 设计对象 类比
Prompt Engineering "该怎么问?" 发给模型的指令文本 告诉厨师"中火煎 3 分钟"
Context Engineering "该让模型看到什么?" 模型推理时可见的上下文 给厨师备好食材、菜谱和注意事项
Harness Engineering "整个运行环境怎么设计?" Agent 外部的约束、反馈、验证和执行系统 设计整个厨房的动线、安全规范、质检流程

可以粗略理解成一种逐层扩展的关系:

  • Prompt 是最内层
  • Context 更外一层
  • Harness 再往外,扩展到整套运行控制环境

也就是说:

Prompt 解决"说什么",Context 解决"给什么",Harness 解决"整个系统怎么让它稳定做成"。


二、Harness Engineering 到底是什么?

2.1 更准确的隐喻:马具,不只是接口层

"Harness" 这个词本身就很有意思。 它原本更接近:

  • 缰绳
  • 马鞍
  • 挽具
  • 驾驭装置

所以 Harness Engineering 最贴切的隐喻不是"给模型装饰一下",而是:

给一匹力量很大、速度很快、但方向感不稳定的马,配上一整套能驾驭它的东西。

LLM / Agent 很像这种"烈马":

  • 能力很强
  • 自主性更强
  • 但并不天然可靠
  • 不天然遵守你的项目规则
  • 不天然知道什么时候该停、什么时候该验证、什么时候该求助

Harness 的价值,就是让它的能力真正可驾驭。一个很有启发性的技术类比是:

模型像 CPU,上下文窗口像 RAM,而 Harness 更像围绕 Agent 的运行控制层。

这个类比不是严格定义,但很好理解:

  • 模型负责推理
  • 上下文提供工作记忆
  • Harness 负责组织流程、约束行为、保存状态、校验结果、处理异常

2.2 一个更稳妥的定义

如果用工程语言来定义:

Harness Engineering 是围绕 AI Agent 构建的一整套约束、上下文管理、反馈回路与执行控制机制,目的是让模型在明确边界内,稳定、可靠、可追踪地完成复杂任务。

它关心的核心是:

  • 怎么组织任务
  • 怎么限制行为
  • 怎么管理上下文
  • 怎么验证结果
  • 怎么处理中途失败
  • 怎么让同类错误别反复发生

一句更大白话的话就是:

Harness 不是让模型更聪明,而是让模型真正能上生产。


2.3 它不是什么

这点很重要。Harness 很容易和别的概念混在一起。

容易混淆的概念 它主要做什么 和 Harness 的区别
MLOps 模型训练、部署、版本、推理基础设施 Harness 更关注 Agent 的执行控制
AI Gateway 统一接入、鉴权、限流、路由 那是请求入口,Harness 更偏任务运行层
Prompt Engineering 优化单次提问措辞 Harness 关注整套执行环境
Agent 框架 / 编排框架 提供工具、节点、流程积木 框架是工具,Harness 更像方法论 + 工程体系

简单说:

MLOps 管模型生命周期,平台工程管底座,Harness 管 Agent 在真实任务里怎么被组织、约束、验证和兜底。


三、Harness Engineering 的三根支柱

为了便于理解,可以把 Harness 的重点归纳成三类能力:

  • 读得懂
  • 管得住
  • 学得会

也就是:

  1. 可读性
  2. 防御机制
  3. 反馈回路

支柱一:可读性------让 Agent 读得懂你的系统

Agent 在每次会话开始时,其实对你的项目几乎一无所知。 你不明确告诉它:

  • 这个项目是什么技术栈
  • 代码目录怎么分
  • 哪些规则不能碰
  • 改完代码要跑什么命令
  • 什么算完成

它就会按自己的"默认世界观"来做事。这就是为什么越来越多团队开始使用类似 AGENTS.md 这样的文件。

什么是 AGENTS.md

可以把它理解成:

给 Agent 看的项目说明书。

如果 README 是给人看的, 那 AGENTS.md 就是专门给 AI Agent 看的。

一个简单例子:

markdown 复制代码
# AGENTS.md

## 项目概览
这是一个 Next.js 14 + TypeScript 全栈项目,使用 App Router。

## 技术栈
- 框架:Next.js 14(App Router,不要用 Pages Router)
- 语言:TypeScript(严格模式)
- 样式:Tailwind CSS(不要用 CSS Modules)
- 数据库:Prisma + PostgreSQL
- 测试:Vitest + Testing Library

## 开发命令
- 安装依赖:`pnpm install`
- 开发服务器:`pnpm dev`
- 运行测试:`pnpm test`
- 类型检查:`pnpm typecheck`
- 代码检查:`pnpm lint`

## 代码规范
- 组件使用函数式组件 + Hooks,禁止 Class 组件
- 文件命名:kebab-case
- 不允许 any 类型

## 架构约束
- 所有 API 路由放在 app/api/ 下
- 业务逻辑放在 lib/ 下
- 环境变量通过 env.ts 统一管理,禁止硬编码

## 验证方式
改完代码后必须执行:
1. `pnpm typecheck`
2. `pnpm lint`
3. `pnpm test`

一个关键点:不是信息越多越好

很多人第一次做这件事,容易犯一个错: 把所有文档、所有规则、所有历史都一股脑塞给模型。实际经验通常刚好相反:

全量灌输不如渐进披露。

更好的做法是:

  • AGENTS.md 只保留最关键规则
  • 详细设计和规范放到 docs/
  • 让 Agent 按需查阅,而不是一次塞满

如果是 monorepo,也可以分层放:

text 复制代码
项目根目录/AGENTS.md
├── packages/
│   ├── web/AGENTS.md
│   └── api/AGENTS.md

这样 Agent 在不同子目录下读取到的规则更精准。


支柱二:防御机制------让 Agent 跑在轨道里,而不是靠自觉

Harness 的一个核心认知是:

软约束不够,关键流程必须有硬约束。

什么叫软约束?

  • "请先做计划再执行"
  • "请不要跳过测试"
  • "请遵守团队规范"

这些写在 Prompt 里有用,但不可靠。 因为模型会忘、会忽略、会在压力下跳过。

什么叫硬约束?

  • 没计划就不允许进入下一阶段
  • 改了文件必须先跑测试
  • 没验证通过就不能宣称完成
  • 某些目录根本不允许写入

这类约束一旦写进执行层,Agent 就绕不过去。


例子一:状态机锁定执行阶段

复杂任务最好不要一口气跑到底,而是显式分阶段:

  • research
  • plan
  • execute
  • verify

示意代码如下:

python 复制代码
from enum import Enum

class AgentPhase(Enum):
    RESEARCH = "research"
    PLAN = "plan"
    EXECUTE = "execute"
    VERIFY = "verify"

class PhaseStateMachine:
    ALLOWED_TRANSITIONS = {
        AgentPhase.RESEARCH: [AgentPhase.PLAN],
        AgentPhase.PLAN: [AgentPhase.EXECUTE, AgentPhase.RESEARCH],
        AgentPhase.EXECUTE: [AgentPhase.VERIFY],
        AgentPhase.VERIFY: [AgentPhase.EXECUTE, AgentPhase.PLAN],
    }

    PHASE_PERMISSIONS = {
        AgentPhase.RESEARCH: ["read_file", "search_code", "list_files"],
        AgentPhase.PLAN: ["read_file", "create_plan"],
        AgentPhase.EXECUTE: ["read_file", "write_file", "run_command"],
        AgentPhase.VERIFY: ["run_tests", "run_lint", "run_typecheck"],
    }

这样做的好处不是"显得高级",而是:

  • 任务进度清晰
  • 可以局部重试
  • 可以强制先想后做
  • 可以阻止 Agent 一上来就乱改

例子二:防"嘴上完成,实际上没做"

很多 Agent 最大的问题不是不会做,而是会"提前宣布胜利"。所以需要在执行层检查:

  • 你说完成了,有没有真实工具调用记录?
  • 你改了代码,有没有跑测试?
  • 你说创建成功了,外部系统里真的存在吗?

示意逻辑:

python 复制代码
class ToolCallValidator:
    def validate_completion(self, agent_output, tool_call_log):
        if agent_output.claims_done and not tool_call_log.has_calls:
            return ForcedAction(
                action="retry",
                reason="你声称任务已完成,但没有工具调用记录。"
            )

        if tool_call_log.has_file_writes and not tool_call_log.has_test_runs:
            return ForcedAction(
                action="run_tests",
                reason="检测到文件修改但未运行测试。"
            )

例子三:防止反复撞墙

Agent 还很容易出现一个问题: 已经失败两三次了,还在重复同样的动作。这时候就需要循环失败检测:

python 复制代码
class LoopDetector:
    def __init__(self, max_retries=3):
        self.failure_log = []
        self.max_retries = max_retries

    def record_failure(self, action: str, error: str):
        self.failure_log.append({"action": action, "error": error})

    def should_break(self, proposed_action: str) -> bool:
        same_failures = [
            f for f in self.failure_log
            if f["action"] == proposed_action
        ]
        return len(same_failures) >= self.max_retries

这和传统后端里的熔断器思路很像:

  • 连续失败
  • 自动打断
  • 强制换路径

例子四:权限边界

只要 Agent 能写文件、调 API、执行命令,就必须有权限边界。

python 复制代码
class PermissionBoundary:
    FORBIDDEN_PATHS = [".env", "secrets/", "config/production/", ".git/"]

    def check_file_access(self, file_path: str, operation: str):
        for forbidden in self.FORBIDDEN_PATHS:
            if file_path.startswith(forbidden):
                raise PermissionDeniedError(
                    f"禁止{operation}文件:{file_path}"
                )

不要把"别碰生产配置""别动密钥"这种话只写在提示词里。 真正高风险的地方,要靠代码层拦住。


支柱三:反馈回路------让 Agent 在犯错后越来越稳

Harness 不是只负责"挡错",还要负责"吃一堑长一智"。

一个非常关键的经验是:

生成和评估最好分开。

因为 Agent 自己评自己,往往容易"放水"。


方法一:自动化验证

最基础的一层反馈回路就是:

  • 写完代码
  • 自动跑 typecheck
  • 自动跑 lint
  • 自动跑测试
  • 不过就打回

示意代码:

python 复制代码
class FeedbackLoop:
    def run_verification(self, changed_files: list[str]):
        results = []

        type_result = self.run_command("pnpm typecheck")
        results.append(("typecheck", type_result))

        lint_result = self.run_command("pnpm lint")
        results.append(("lint", lint_result))

        test_result = self.run_command("pnpm test")
        results.append(("test", test_result))

        return VerifyResult(
            passed=all(r.success for _, r in results),
            details=[
                {
                    "check": name,
                    "passed": r.success,
                    "output": r.stdout[-500:],
                    "errors": r.stderr[-500:] if not r.success else None
                }
                for name, r in results
            ]
        )

这一步看起来很普通,但它是 Harness 最低成本、最高收益的能力之一。


方法二:把执行和评审拆开

更进一步,可以让一个 Agent 负责执行,另一个 Agent 负责审查。流程大概像这样:

text 复制代码
Agent A:写代码 / 做实现
    ↓
Agent B:按标准评审 / 找问题
    ↓
Agent A:根据反馈修复
    ↓
再次验证

示意代码:

python 复制代码
async def dual_agent_review(task, executor, reviewer):
    MAX_ROUNDS = 3

    for _ in range(MAX_ROUNDS):
        result = await executor.execute(task)
        review = await reviewer.review(
            task_description=task.description,
            code_diff=result.diff,
            review_criteria=[
                "是否完成所有要求?",
                "是否有 bug?",
                "是否遵循规范?",
                "是否存在安全隐患?",
            ]
        )

        if review.is_good_enough():
            return result

        task = task.with_feedback(review.comments)

    return EscalateToHuman(result, review)

它不一定非要上"多智能体架构"那么重, 哪怕只是换一个独立会话来审查,效果通常都比"自己写自己夸"要好。


方法三:错误经验持久化

Harness 最宝贵的一点是:

每一次错误,都应该变成下一次的系统改进。

比如维护一份经验文件:

markdown 复制代码
# .harness/lessons-learned.md

## 2026-03-20: Prisma 迁移必须在测试前执行
- 问题:修改 schema 后没跑 migrate
- 修复:在验证步骤中加入 migrate 检查
- 状态:已纳入硬约束

## 2026-03-18: 不要在 middleware 中直接 throw
- 问题:导致页面白屏
- 修复:补充框架约束说明
- 状态:已写入 AGENTS.md

形成一个闭环:

text 复制代码
Agent 犯错
→ 分析根因
→ 更新文档 / 约束 / 验证
→ 下次自动带上
→ 同类错误减少

这才是 Harness 真正的"工程化"。


四、怎么从零搭一个最小可用的 Harness?

如果你今天就想开始,不需要一上来搞复杂平台。 先做一个最小可用版本就够了。


第一步:写一个 AGENTS.md

先别追求完美,先把最关键的三类信息写清楚:

  • WHAT:项目是什么、技术栈是什么
  • HOW:常用命令、开发流程、验证方式
  • RULES:哪些规范必须遵守、哪些目录禁止改

这是让 Agent"读得懂系统"的第一步。


第二步:加一条硬约束

比如最简单也最值回票价的一条:

只要改了业务代码,就必须跑测试。

如果你自己写 Agent 运行层,可以这么做:

python 复制代码
def post_edit_guard(agent, edited_files):
    src_files = [f for f in edited_files if f.startswith("src/")]
    if not src_files:
        return

    result = agent.execute("pnpm test --run")
    if not result.success:
        agent.feedback(f"测试失败:\n{result.stderr}\n请修复后重新运行。")
        return RetrySignal()

这一条就能消灭很多"我已经做完了但其实没验证"的问题。


第三步:引入反馈回路

最小版本就是:

text 复制代码
Agent 写代码
→ 自动 lint + test
→ 失败则反馈
→ Agent 修复
→ 再验证
→ 直到通过或升级人工

很多团队光做到这一步,稳定性就会明显提升。


第四步:处理长任务的上下文问题

长任务里,一个常见坑是:

  • 会话越来越长
  • 上下文越来越脏
  • 模型越来越不愿意认真收尾

这时与其无限压缩上下文,不如考虑结构化交接 + 新会话继续。示意代码:

python 复制代码
class ContextManager:
    MAX_CONTEXT_UTILIZATION = 0.6

    async def run_with_reset(self, agent, task):
        subtasks = self.decompose_task(task)

        for subtask in subtasks:
            if agent.context_utilization > self.MAX_CONTEXT_UTILIZATION:
                handoff_doc = await agent.generate_handoff(
                    prompt="总结:1.已完成 2.当前进度 3.下一步 4.注意事项"
                )
                agent = agent.fresh_session()
                agent.load_context(handoff_doc)

            await agent.execute(subtask)

核心思路是:

不要让一个会话死扛到底,而是让任务可交接、可重置、可续跑。


第五步:形成持续改进飞轮

当 Agent 出错时,不要只骂模型不行。

更有价值的问题是:

  • 是不是缺信息?
  • 是不是缺约束?
  • 是不是缺验证?
  • 是不是缺回退机制?

然后把它变成系统改进:

text 复制代码
Agent 犯错
→ 归因
→ 补文档 / 补约束 / 补验证 / 补权限
→ 记录经验
→ 下次同类问题更少

这就是 Harness Engineering 最核心的工作方式。


五、一个完整执行时序长什么样?

假设 Agent 收到一个任务:

"修复 src/login.tsx 中的登录 bug"

整个过程可能像这样:

text 复制代码
1. Harness 启动新会话,加载 AGENTS.md,初始化状态为 RESEARCH
2. Agent 请求读取 login.tsx
3. Harness 检查:RESEARCH 阶段允许 read_file,放行
4. Agent 想直接改代码
5. Harness 检查:RESEARCH 阶段不允许 write_file,拒绝
6. Agent 转而请求进入 PLAN 阶段
7. Harness 校验状态迁移合法,允许进入 PLAN
8. Agent 生成修复计划
9. Harness 允许 create_plan
10. Agent 请求进入 EXECUTE
11. Harness 允许状态迁移
12. Agent 修改 login.tsx
13. Harness 记录到文件修改事件
14. Harness 自动触发验证守卫
15. Harness 强制进入 VERIFY,运行 typecheck / lint / test
16. 若全部通过,则任务完成;否则把错误反馈给 Agent 重试

这里会看到一个很关键的分工:

  • Agent 负责推理和执行
  • Harness 负责约束和裁判

Agent 不一定知道状态机代码长什么样, 但它会真实感受到:哪些动作被允许,哪些动作会被拦下,什么才算完成。


六、真实工程实践给了我们什么启发?

关于 Harness Engineering,最近一批公开分享有一个共同结论:

很多时候,Agent 的瓶颈不只在模型能力,更在运行环境设计。

从这些实践里,至少能提炼出几条一致经验:


1)项目说明必须对 Agent 友好

如果项目结构复杂、规范隐含、命令分散、禁区不明确, Agent 很容易走错路。所以"让项目可被 Agent 读取"本身就是第一层工程能力。


2)关键流程必须靠硬约束,不要只靠提示词提醒

尤其是这些事:

  • 改代码后必须验证
  • 高风险目录禁止写
  • 任务必须分阶段
  • 不能跳过测试直接宣布完成

只写在 Prompt 里,远远不够。


3)验证层越扎实,Agent 越能被放心放权

Agent 真正能承担更多执行工作,不是因为"它看起来很聪明", 而是因为外面有足够厚的验证层:

  • 类型检查
  • 测试
  • Lint
  • 安全扫描
  • 代码评审
  • 人工兜底

这和传统工程里"自动化程度越高,越需要可靠门禁"是一个道理。


4)同一个模型,在不同 Harness 下表现差异会很大

这是很多团队越来越清楚感受到的一点:

底层模型一样,Harness 不一样,最终产出质量可能差很多。

也就是说,Harness 不是"附属包装",而是会直接影响 Agent 的可用性、稳定性和上限。


5)Harness 不是一劳永逸,而是跟模型一起演化

模型变强后,有些外层补丁会变得多余; 但新的能力边界出现后,又会催生新的约束和验证需求。所以 Harness 不是"搭完收工",而是一个持续迭代的系统:

text 复制代码
模型变强
→ 某些旧约束变冗余
→ 拆掉不必要的部分
→ 暴露新的问题边界
→ 新增新的 Harness 机制
→ 继续演化

这很像一套随着 Agent 能力变化而不断重构的"运行控制层"。


七、给后端工程师的对标翻译

如果你是后端 / Go / 平台工程背景,可以这样理解:

Harness 概念 后端里更像什么
AGENTS.md README + 开发规范 + contributor guide
状态机约束 工作流引擎 / Saga / Temporal
权限边界 RBAC + 沙箱 + ACL
工具调用验证 中间件 / AOP / 网关后置校验
自动验证回路 CI/CD + 质量门禁
多 Agent 评审 Code Review / 审批流
上下文重置 无状态服务 + 会话持久化
循环失败检测 熔断器 / 重试策略
Harness 整体 面向 Agent 的执行控制系统

所以对后端工程师来说,Harness 不是一个玄学词。它更像:

工作流引擎 + 状态机 + 工具沙箱 + 验证器 + 补偿机制 + 可观测执行框架

只不过这里被管理的"执行者",不再是固定代码,而是 LLM / Agent。


八、今天就能开始做的 5 件事

不用等平台团队,不用等架构升级,今天就能做。

序号 行动 耗时 效果
1 写一个最小版 AGENTS.md 10 分钟 Agent 不再总按默认习惯乱来
2 加一条硬约束:改完代码必须跑测试 30 分钟 大幅减少"宣称完成但没验证"
3 把执行和评审拆开 每次多 5 分钟 更容易发现自我评估遗漏的问题
4 记录 Agent 的典型错误 持续 同类问题不必一错再错
5 让人审计划,不是盯每一行代码 改变协作方式 更接近高效的人机分工

九、一句话收束:Harness 的本质到底是什么?

Harness Engineering 最值得记住的一点是:

模型已经足够强了,接下来的竞争,越来越多是在"谁更会设计它的运行环境"。

前几年我们在研究:

  • 怎么和模型说话
  • 怎么给模型更多上下文

而现在,越来越多团队开始研究:

  • 怎么让模型在工程系统里稳定跑起来
  • 怎么让它别跑偏
  • 怎么让它犯过的错别再犯
  • 怎么让它从"能演示"变成"能交付"

所以如果非要用一句最短的话来定义它:

Harness Engineering,不是让模型更聪明,而是让模型真正可驾驭、可上线、可交付。


参考阅读

下面列的是本文写作时参考过的公开讨论方向。由于相关概念仍在快速演化,建议优先阅读各团队的一手原文与官方仓库。

一手资料方向

  • Mitchell Hashimoto 关于 AI adoption / harness engineering 的博客讨论
  • OpenAI 关于 Codex / Agent-first / Harness Engineering 的公开文章
  • Anthropic 关于长任务应用开发中的 harness 设计文章
  • AGENTS.md 相关官方仓库与社区规范

二手解读方向

  • Martin Fowler / Thoughtworks 相关分析文章
  • LangChain 团队关于 agent harness 改进的技术分享
  • 中文社区对 Harness Engineering、Context Engineering、AGENTS.md 的工程解读文章
相关推荐
不吃辣4904 分钟前
vibe coding | 如何做一个 AI 音乐生成工具?
java·人工智能·后端·ai·ai编程
文人sec7 分钟前
从接口压测到全链路质量保障:AI智能客服系统的软件测试实践
人工智能
声讯电子8 分钟前
实测A-59F音频模组:降噪稳、不啸叫、通话清晰
人工智能·语音识别·ai降噪·usb接口·回音消除
神奇霸王龙13 分钟前
2026旗舰六阶段MCP流水线实战指南
人工智能·ai·ai作画·prompt·aigc·mcp
山河不见老15 分钟前
【Cursor 、Qoder安装问题】Cursor 、Qoder安装卡在“正在准备安装”问题排查及解决
人工智能·windows·编辑器
新知图书15 分钟前
2.3 开发工作流
人工智能·agent·ai agent·智能体
tuanxiang18 分钟前
用免费 AI 改写工具处理批量文案的踩坑记录,附完整降噪脚本
人工智能
小邓的技术笔记18 分钟前
DeepSeek 大模型落地应用与场景实战指南
大数据·人工智能
石榴24 分钟前
从 Codex + Obsidian 到本地 RAG:我的私人知识库实践
人工智能
QZSJTR29 分钟前
技术解析|从SEO到GEO:生成式搜索时代实体企业数字化适配方案
人工智能