Jean's Blog

一个专注软件测试开发技术的个人博客

0%

Harness Engineering:驾驭工程介绍

介绍

Harness Engineering(本文译作“驾驭工程”)是 2025—2026 年间在 Agent 工程讨论中快速流行的术语。它不是一套已有统一标准的独立学科,而是一组围绕大语言模型(LLM)和智能体(Agent)的工程实践:通过工具、权限、状态、上下文、验证、预算和可观测性,让模型能够更稳定地执行真实任务。

本文使用便于理解的简化公式:Agent 系统 ≈ Model + Harness。模型提供推理与生成能力,Harness 提供执行环境和工程约束;具体产品通常还包含业务逻辑、数据与用户界面。

词源隐喻(精准易懂)

  • 野马:LLM / 大模型,能力强但不可控、易失控;
  • 马具(Harness):驾驭系统,含规则、工具、校验、流程;
  • 骑手:工程师,负责设计系统、设定目标;
  • 千里马:AI Agent(模型 + Harness),安全可靠的生产力工具。

Agent = Model + Harness核心公式拆解

Agent 由模型与 Harness 组成的结构示意图

核心观点:大模型 Model 只是中间的计算引擎,光靠大模型本身不等于 Agent;外围整套 Harness 组件,才把普通大模型变成能自主干活的智能 Agent。

组成部分 类比 核心作用 关键描述
Model 引擎 决定 Agent 的能力上限 生成、推理、代码理解等核心能力都在模型权重里,但 “引擎再强,没有底盘和刹车,跑不过 100 公里就失败”
Harness 底盘 + 刹车 + 方向盘 保住 Agent 的运行下限,让上限真正落地 包含循环刹车、状态持久化、工具编排、上下文管理、验证闭环,是让模型能稳定持续运行的工程系统

Harness核心组件说明

组件 名称 作用通俗解释
Tools 工具集 给模型可以调用的外部能力:读写文件、执行命令、访问 API、查询数据库等,让模型能动手做事
Memory 记忆 短期 / 长期记忆,保存历史对话、任务记录、技能、用户偏好,Agent 能记住过去发生的事
Hooks 钩子 生命周期回调,任务前后做拦截、校验、告警、日志、质量检查,相当于 “安全阀门和监控”
Context 上下文管理器 负责整理、压缩、投喂上下文窗口,管理输入输出,解决上下文长度溢出问题
Permissions 权限管控 定义 Agent 能干什么、不能干什么,文件读写、命令执行的权限隔离,做安全风控

三种运行形态对比:差异主要在执行环境

下面比较的是典型默认形态,不是对具体产品能力的永久承诺。ChatGPT、Claude Code 等产品持续更新,连接器、沙箱和本地权限也会因套餐、配置及授权方式而不同。

维度 对话式模型 带沙箱的数据分析环境 本地编码 Agent
生成与解释代码 支持 支持 支持
执行代码 通常不能直接执行,取决于产品工具 可在隔离沙箱中执行 可在授权的本地或远程工作区执行
访问项目文件 仅限用户上传或连接的数据 主要访问沙箱文件 可访问用户授权的仓库或目录
调用开发工具 通常有限 以沙箱内工具为主 可编排 shell、Git、测试和构建工具
长任务可靠性 依赖会话和产品能力 受沙箱、上下文与会话限制 可通过检查点、验证和权限机制增强

真正拉开差距的,不只是底层模型,而是模型外部的执行系统:它是否能够访问正确的文件、调用工具、保存状态、限制风险,并用测试验证结果。因而,更严谨的比较应尽量控制模型、任务集、工具权限和预算等变量,而不能仅凭产品名称判断。

为什么说 Harness 才是 Agent 落地的关键?

  1. Model 决定 “能跑多快”,Harness 决定 “能跑多久”

很多人误以为 “模型越强,Agent 越好用”,但实际落地中,没有完善的 Harness,再强的模型也像没有底盘的引擎 —— 跑两步就失控、出错、崩溃,根本没法完成长任务。

  1. Harness 是让模型 “听话” 的约束与保障

它就像方向盘和刹车,帮模型:

  • 控方向:通过上下文管理、工具编排,让模型始终朝着目标前进,不跑偏;
  • 控风险:通过验证闭环、状态持久化,及时纠错、防崩溃,避免 “脱缰”;
  • 控流程:通过循环刹车(重试 / 校验机制),让模型的每一步都在可控范围内。

Harness 的真实效果

下面是一组可量化案例,用于说明 Harness 设计可能显著影响任务结果:

同模型仅改 Harness,Terminal Bench 2.0 通过率从 52.8% → 66.5%,提升了 13.7 个百分点(LangChain 2026-02-17)

这意味着:在该实验设置下,Harness 调整带来了 13.7 个百分点的绝对提升;若按相对增幅计算,约为 25.9%。两种口径不能混用。

这也印证了使用F1 类比:“引擎差一点,但底盘调校好了,能跑满整个赛季二十几个大奖赛。”

对 AI Agent 来说,模型与 Harness 都会影响结果。更好的 Harness 可以提高稳定性,但不能弥补模型能力、任务定义或数据质量上的所有不足。

Harness Engineering 公开案例与数据

数据 出处 含义
同模型仅改 harness,Terminal Bench 2.0 从 52.8% → 66.5%,+13.7pp,排名 Top 30 → Top 5(测试模型:gpt-5.2-codex;同一任务集 Terminal Bench 2.0;测试时间 2026-02-17) LangChain 博客
2026-02-17,作者 Vivek Trivedy:
Improving DeepAgents with Harness Engineering
说明 Harness 可以作为独立工程变量进行评测
OpenAI 内测产品:5 个月、约 100 万行代码(原文 “on the order of a million”)、约 1500 个 PR(原文 “roughly 1,500”)、全程零人工编码、开发时间约为传统方式的 1/10(原文 “on the order of ten times faster”;博文注明此为团队内部估算,非严格对照实验) OpenAI 工程团队博文
2026-02-11:
Harness engineering: leveraging Codex in an agent-first world
展示了 OpenAI 团队内部 Agent-first 开发实践的规模
Manus 团队 6 个月内重构 harness 5 次,每次都是删掉过时的复杂逻辑 Phil Schmid 博文
2026-01-05:
The importance of Agent Harness in 2026
提示 Harness 需要随模型和任务持续迭代
2026-04-02 Birgitta Böckeler在 martinfowler.com 发表 “Harness engineering for coding agent users”,Martin Fowler 系博客正式纳入 martinfowler.com:
Harness engineering for coding agent users
说明该术语已进入更广泛的软件工程讨论

Model 是 Agent 的上限潜力,Harness 是 Agent 的下限保障。没有 Harness 的模型只是 “裸奔的引擎”,加上 Harness,才是能稳定跑完比赛的 “可用赛车”。

AI 工程关注点的三层扩展

flowchart LR
    A["关注点一
Prompt Engineering
提示词工程
- 表达目标与约束
- 优化单次模型调用"] --> B["关注点二
Context Engineering
上下文工程
- 选择模型当前可见信息
- 管理历史、检索与工具结果"] B --> C["关注点三
Harness Engineering
驾驭工程
- 管理长任务执行
- 权限、状态、验证与预算"] style A fill:#e6f2ff,stroke:#3399ff,stroke-width:2px style B fill:#e6f9e6,stroke:#339966,stroke-width:2px style C fill:#fff2e6,stroke:#cc6633,stroke-width:2px

Prompt Engineering(提示词工程)

主要场景:表达单次调用的目标、约束和输出格式

核心目标:解决「单次调用的指令表达」问题

  • 优化单次调用指令:通过清晰、结构化的提示词(如角色设定、示例、约束),让模型单次输出符合预期
  • 精准表达意图:解决模型理解偏差、答非所问的问题,是早期和大模型交互的核心手段

本质

是 “教模型听懂话” 的基础工程,核心是优化单轮输入的语言表达,但对多轮对话、外部信息依赖的场景能力有限。


Context Engineering(上下文工程)

主要场景:为模型选择、组织和压缩当前任务所需的信息

核心目标:解决「多轮对话中的信息完整性与可见性」问题

  • 提供模型 “当前可见信息”:不仅包含用户的新指令,还会把历史对话、外部检索的知识、工具调用结果等信息,整理成模型能 “看到” 的上下文
  • 包含历史对话、检索、工具:比如 RAG(检索增强生成)、Agent 工具调用,本质都是通过上下文工程,让模型在多轮交互中始终掌握关键信息,保证回答的连贯性与准确性

本质

是“管理模型视野”的工程。它通常会复用提示词工程,但两者并不是严格的上下级标准;上下文工程进一步关注多轮、多信息源场景下的信息选择、组织和压缩。


Harness Engineering(驾驭工程)

主要场景:让模型在工具调用和长任务中保持可控、可恢复、可验证

核心目标:解决「AI 系统长期运行的稳定性与可控性」问题

  • 系统性约束与治理:为长期运行的 AI Agent / 系统建立规则边界、权限控制、目标对齐机制,避免模型在长流程中偏离任务目标
  • 持续观测、纠偏、收敛:在 AI 长时间运行的过程中,实时监控行为与输出,发现偏差时自动调整提示词、上下文或流程,让系统始终收敛到预期目标

本质

是“约束和治理 AI 系统”的工程。它会同时运用提示词与上下文工程,并增加长任务所需的执行控制、状态恢复、权限、验证和可观测性。

关键总结

  1. 协同关系:三类工程关注点不是严格的代际标准,也不是简单替代关系:
    • 提示词工程是基础
    • 上下文工程解决信息选择、组织与压缩问题
    • 驾驭工程解决长时运行的执行、治理与验证问题
  2. 场景扩展:从单次调用到多轮交互,再到长任务系统,工程关注点逐渐增加
  3. 核心变化:交互的重心从 “怎么说清楚一句话”,变成了 “怎么管好一个持续运行的系统”

三代工程的包含关系与术语边界

Prompt Engineering、Context Engineering、Harness Engineering 之间到底是什么关系;Agent、Scaffolding、Framework、Runtime 这四个词各自和 Harness 的边界在哪里;以及 LangChain 本身是什么——是 Framework、Runtime,还是一个 Harness?

三类工程:相互协作而非简单替代

这三类术语描述的是不同关注点,而不是由标准组织定义的严格代际。实际系统通常同时使用三者:提示词表达目标,上下文工程准备模型当前可见的信息,Harness Engineering 管理工具、状态、权限、预算与验证。

提示词工程关注如何清晰表达目标;上下文工程关注给模型哪些信息,包括 RAG、工具 schema、对话历史和缓存策略;驾驭工程关注多轮工具调用与长任务执行,包括循环终止、状态持久化、权限、验证和子任务隔离。

下次再看到”上下文工程取代提示词工程”或”驾驭工程取代上下文工程”这种标题,你可以直接关掉。作者没有理解同心圆。

为了让”包含而非替代”不只停留在图示,我们把它落到一个真实产品上走一遍——以 Claude Code 处理”写登录功能”这个任务为例:当它启动时,Prompt Engineering 层在工作——system prompt 里写着”你是编程助手、使用 Anthropic 推荐的指令工程范式”;同时 Context Engineering 层也在工作——它会读取你项目目录里的 CLAUDE.md、把已有 tool 的 schema 注入 context、监测并压缩过长的 tool 输出;同时 Harness Engineering 层在工作——它用 max_iterations 硬刹车兜底循环、用 progress 文件持续保存进度、用 compaction 阈值触发 context 清理。一次 Claude Code 会话同时运行着三代工程的所有机制,没有哪一层被”替代”,只有层层叠加。这是包含关系最朴素的验证——同一个产品可以同时被三代工程的任意一代观察,都能看到对应机制在工作\。

术语边界:Agent / Scaffolding / Framework / Runtime vs Harness

把身边几个高频术语一次性捋清楚,每个术语用”是什么 / 解决什么 / 与 Harness 区别”三连定位。在看表之前先认识两个后面反复出现的名字:LangGraph 是 LangChain 2024 年推出的状态机运行时(checkpoint / interrupt / 状态持久化),DeepAgents 是 LangChain 在 LangGraph 之上提供的 Agent Harness,集成规划、文件工具、子 Agent 和长期记忆等能力。

术语边界对照

术语 是什么 解决什么 与 Harness 的关系
Agent 一个”会用工具完成任务”的软件实体(概念层) 让 LLM 具备行动能力,不只是回答 Agent 是目标,Harness 是让目标能持续运行的工程系统
Scaffolding prompt 到达模型前的组装层(含 prompt template / few-shot 拼接 / tool schema 注入) 让 LLM 的输入更可控 Scaffolding 是 Harness 的一部分(偏 context 装配层)
Framework 提供类库和抽象的开发工具包(LangChain / LlamaIndex 等) 让你不用从零写 LLM 调用链 Framework 是积木,Harness 是用积木搭出来的整车
Runtime 负责执行 Agent 逻辑的运行时引擎(如 LangGraph) 让 agent 的状态机在工业环境可运行 Runtime 是发动机,Harness 是发动机 + 底盘 + 传动

这里需要特别留意一个陷阱——“scaffolding” 在学术文献里比 harness 宽泛很多,甚至会覆盖到 prompt template 和微调数据。

【常见误区】把 scaffolding 当 harness 的同义词 后果:很多博客把 ‘prompt scaffolding’ 和 ‘harness’ 混用,让读者低估 harness 的工程复杂度 —— 以为做好 prompt 组装就等于做好了 harness,脱离 runtime 执行层的循环刹车、进度续传、验证闭环等关键机制。

正确做法:按本课的三代工程同心圆图定位 ——scaffolding 只是 context 装配层的一个子集,是 harness 的一部分,一个面向长任务的 Harness 通常还应覆盖运行控制、状态、权限和验证。

排查方法:看一个系统被宣称是 harness 时,检查它是否包含:(a) 循环终止刹车、(b) 跨 session 进度持久化、(c) 真机功能验证 。这三项是实用检查点,但不是行业认证标准。

驾驭工程的拐点

Karpathy 的判断:Agent 从“不可用”走向“勉强可用”

Karpathy 在 2026 年初讨论 Agent 时写道:在 2025 年 12 月之前,Agent 基本不可用;随后它们开始“勉强可用”,于是 Harness Engineering 才真正成为值得投入的工程问题。这里的日期是 2025 年 12 月,并非 2024 年 12 月;这段表述也不应归到 2025 年 6 月的 YC 演讲。

这是一种趋势判断,而不是由某个 SWE-bench 百分比定义的行业分界线。基准成绩会受到模型版本、脚手架、工具权限、预算和评测实现影响,因此不能把“60%—90%”写成公认的黄金区间。更稳妥的结论是:当模型具备一定的工具使用与代码修改能力后,外围系统的质量开始成为可测量的重要变量。

节点时间轴:术语怎么一步步被命名的

下面按公开文章整理一条代表性传播时间线。由于“harness”早已用于软件测试与模型评测,且公开检索无法证明某篇文章是绝对首用,因此这里不再做“术语发明者”或“完整历史”的断言。

驾驭工程术语演化 8 节点时间轴

# 日期 事件 作者 / 出处
1 2025-09-23 博文 “The Claude Code SDK and the Birth of HaaS(Harness-as-a-Service,把 harness 封装为服务形态)” 较早系统讨论 “Agent Harness” 与 HaaS Vivek Trivedy(独立 AI 博客作者,vtrivedy.com)
2 2025-10-25 博文 Agent Frameworks, Runtimes, and Harnesses - oh my! 明确引用并传播该术语,并自认 “I didn’t come up with it” 并链接 Trivedy Harrison Chase(LangChain 博客)
3 2025-11-26 官方首篇系统化博文 Effective Harnesses for Long-Running Agents Anthropic,作者 Justin Young
4 2026-01-05 博文 The importance of Agent Harness in 2026,提出 Bitter Lesson(Rich Sutton 2019 经典,简单通用方法最终胜过复杂领域知识)三原则(Start Simple / Build to Delete / Harness is the Dataset) Phil Schmid(Hugging Face 技术博主,philschmid.de)
5 2026-02-11 官方博文 Harness engineering: leveraging Codex in an agent-first world,用生产实证定型术语 OpenAI 工程团队
6 2026-02-17 博文 Improving DeepAgents with Harness Engineering,报告 Harness 调整带来 +13.7 个百分点的结果变化 Vivek Trivedy @ LangChain
7 2026-02-18 博文 A Guide to Which AI to Use in the Agentic Era,用三分框架把概念推向大众 Ethan Mollick(Wharton 商学院教授,AI 大众传播者,oneusefulthing.org)
8 2026-03-24 博文 Harness Design for Long-Running Application Development,提出 GAN(生成对抗网络,”生成者 vs 鉴别者”对抗思路)启发的 Planner-Generator-Evaluator 三角色架构 Anthropic,作者 Prithvi Rajasekaran

从这条时间线可以看到:2025 年下半年到 2026 年上半年,社区文章、框架厂商和模型厂商都开始更集中地讨论 Agent 外围系统。但这说明的是术语快速传播,并不等于一门学科已经在六个月内完成定型。

还有一个细节:Anthropic 在 6 个月里一口气发了两篇官方博文(2025-11-26 和 2026-03-24),前一篇讲”机制是什么”,后一篇讲”架构怎么设计”。这个节奏说明什么?说明 Anthropic 把驾驭工程当成严肃的工程学科在持续投资,不是一次博客营销。

实证数据收束:两个决定性证据

回到“Agent 开始勉强可用”的判断:模型能力与 Harness 设计都会影响结果。下面两组数据说明 Harness 已经成为可测量的工程变量,但它们不能证明模型选型不再重要。

  • 证据一(LangChain 2026-02-17):同模型、同 benchmark、只改 harness,Terminal Bench 2.0 从 52.8% → 66.5%,+13.7 个百分点。当你用这一条去反驳”这是 feedback control 换皮”的人,对方没得反驳——该结果来自具体框架与评测设置,不能直接外推到所有 Agent。

  • 证据二(OpenAI 2026-02-11):一个内测产品,5 个月、约 100 万行代码(原文 “on the order of a million”)约 1500 个 PR(原文 “roughly 1,500”)、全程零人工编码、开发时间约为传统方式的 1/10。这是 OpenAI 团队公开的内部实践数据,能说明其工程规模,但不等同于独立第三方对照实验。

这两条证据合起来的教学结论:模型能力决定可完成任务的范围,Harness 影响执行过程能否稳定、可控并通过验证。两者共同决定系统是否适合上线——我们现在学驾驭工程,不是跟风,是踩在学科刚立起来的最佳时间点上。

naive agent (裸奔智能体)的八种失效方式

示例代码展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# Project :agent-evolve
# File :naive_agent_demo.py
# Author :jinglv
# Date :2026/8/3 10:37
# Software:PyCharm
"""
naive_agent_demo.py
教学示意:简陋工具调用Naive Agent循环
故意保留全部8个故障点,禁止直接用于生产环境
演进定位:Naive Agent + Function Call(初级工具智能体,存在大量工程缺陷)
"""
import json
import logging
import os
import subprocess

from dotenv import load_dotenv
from openai import OpenAI

# ====================== 日志配置 ======================
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(levelname)s | %(message)s",
datefmt="%H:%M:%S"
)
logger = logging.getLogger("NaiveAgent")


# 简易终端颜色常量
class Color:
RED = "\033[91m"
GREEN = "\033[92m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
RESET = "\033[0m"


# 加载.env
load_dotenv()

# -------------------------- 配置区 --------------------------
# 优先读取环境变量
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
DEEPSEEK_BASE_URL = os.getenv("DEEPSEEK_BASE_URL")
DEEPSEEK_MODEL_NAME = os.getenv("DEEPSEEK_MODEL_NAME")

# 初始化DeepSeek客户端(OpenAI兼容SDK)
client = OpenAI(
api_key=DEEPSEEK_API_KEY,
base_url=DEEPSEEK_BASE_URL
)

# OpenAI 标准工具Schema
TOOLS = [
{
"type": "function",
"function": {
"name": "read_file",
"description": "读取文件内容",
"parameters": {
"type": "object",
"properties": {"path": {"type": "string"}},
"required": ["path"]
}
}
},
{
"type": "function",
"function": {
"name": "write_file",
"description": "写入/覆盖文件内容",
"parameters": {
"type": "object",
"properties": {
"path": {"type": "string"},
"content": {"type": "string"}
},
"required": ["path", "content"]
}
}
},
{
"type": "function",
"function": {
"name": "run_pytest",
"description": "运行 pytest 自动化测试",
"parameters": {"type": "object", "properties": {}}
}
}
]


# -------------------------- 工具函数实现(存在缺陷) --------------------------
def read_file(path: str) -> str:
"""故障点④:文件不存在/权限不足直接抛异常,上层捕获后统一返回空字符串"""
logger.info(f"{Color.BLUE}[工具调用] read_file path={path}{Color.RESET}")
with open(path, "r", encoding="utf-8") as f:
return f.read()


def write_file(path: str, content: str) -> str:
"""故障点⑥:无路径白名单、无权限校验,可覆盖系统任意文件,高危操作"""
logger.info(f"{Color.BLUE}[工具调用] write_file path={path}{Color.RESET}")
with open(path, "w", encoding="utf-8") as f:
f.write(content)
return "write done"


def run_pytest() -> str:
"""故障点④:只返回标准输出stdout,丢弃返回码,智能体无法识别测试失败"""
logger.info(f"{Color.BLUE}[工具调用] run_pytest{Color.RESET}")
result = subprocess.run(
["pytest"],
capture_output=True,
text=True,
encoding="utf-8"
)
# ⚠️故障点④日志提示:丢弃returncode
logger.warning(f"{Color.YELLOW}⚠️故障点④:pytest进程返回码被丢弃,无法判断测试成功与否{Color.RESET}")
return result.stdout


# -------------------------- Agent主循环(8处故障集中区域) --------------------------
def naive_agent(task: str):
iter_count = 0
messages = [
# 故障点③:system prompt 会在循环内持续变更,破坏上下文一致性
{"role": "system", "content": "你是编程助手。完成任务后停止。[session_iter=0]"},
{"role": "user", "content": task},
]
logger.info(f"{Color.GREEN}===== 启动Naive Agent ====={Color.RESET}")
logger.info(f"目标任务:{task}")

# 故障点①:while True 无限循环,没有最大迭代保护;模型持续调用工具时会死循环、持续扣费
logger.warning(f"{Color.RED}⚠️故障点①:使用while True无限循环,无迭代上限,存在死循环风险{Color.RESET}")
while True:
logger.info(f"\n========== 第 {iter_count} 轮思考 ==========")
# 故障点③:每轮迭代修改system提示词,破坏上下文稳定,影响模型输出一致性
messages[0]["content"] = f"你是编程助手。完成任务后停止。[session_iter={iter_count}]"
logger.warning(f"{Color.YELLOW}⚠️故障点③:本轮更新system prompt,上下文基线持续变动{Color.RESET}")

# 请求DeepSeek模型
logger.info("向DeepSeek发起LLM请求...")
response = client.chat.completions.create(
model=DEEPSEEK_MODEL_NAME,
messages=messages,
tools=TOOLS
)
msg = response.choices[0].message
logger.info(f"LLM返回:是否调用工具 = {msg.tool_calls is not None}")

# 故障点②:消息持续追加,无窗口截断、无消息摘要,极易触发上下文溢出、token暴涨
messages.append(msg)
logger.warning(
f"{Color.YELLOW}⚠️故障点②:消息列表持续追加,未做截断,上下文持续膨胀,当前消息总数:{len(messages)}{Color.RESET}")

if msg.tool_calls:
for tool_call in msg.tool_calls:
args = json.loads(tool_call.function.arguments)
tool_name = tool_call.function.name
logger.info(f"准备执行工具:{tool_name} 参数={json.dumps(args, ensure_ascii=False)}")

try:
# 故障点⑥:缺少调用参数校验、路径沙箱、安全拦截,直接执行工具
logger.warning(f"{Color.RED}⚠️故障点⑥:无沙箱/路径白名单校验,直接执行工具{Color.RESET}")
tool_mapping = {
"read_file": read_file,
"write_file": write_file,
"run_pytest": run_pytest
}
tool_func = tool_mapping[tool_name]
tool_result = tool_func(**args)
except Exception as e:
# 故障点④:所有异常统一吞掉,返回空字符串,模型无法感知错误
logger.error(
f"{Color.RED}⚠️故障点④:捕获异常静默处理!异常信息:{str(e)},返回空字符串给LLM{Color.RESET}")
tool_result = ""

logger.info(f"工具返回结果长度:{len(tool_result)}")
# 将工具返回结果加入对话上下文
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": tool_result
})
else:
# 故障点⑦:仅依靠模型自己判断任务完成,没有独立外部校验器
# 故障点⑤:任务终止后不持久化会话、中间状态,中断无法恢复
logger.warning(f"{Color.YELLOW}⚠️故障点⑦:依靠模型自判任务完成,无独立校验器{Color.RESET}")
logger.warning(f"{Color.YELLOW}⚠️故障点⑤:退出前不保存会话状态,无法断点续跑{Color.RESET}")
print(f"\n{Color.GREEN}Agent 判断任务完成,退出循环{Color.RESET}")
break

iter_count += 1


if __name__ == "__main__":
# 故障点⑧:没有token限额、费用预算控制,极端场景持续消耗API额度
logger.warning(f"{Color.RED}⚠️故障点⑧:未设置Token上限、调用成本预算控制{Color.RESET}")
task_desc = "读取 test_calculator.py,修复失败的测试代码,运行 pytest 确认全部用例通过"
naive_agent(task_desc)

这段代码是一个诚实的 “tool-calling 教科书实现”——核心代码100 行左右完成了所有”必要的事”:调 LLM、解析 tool_calls、执行工具、把结果塞回 messages、下一轮。这一段代码写的过于朴素,暴露了很多问题。

测试代码 test_calculator.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# test_calculator.py
"""计算器模块(包含故意制造的bug)"""

def add(a, b):
# Bug:本该 a + b,错误写成 a - b
return a - b

def mul(a, b):
return a * b


# pytest 测试用例
def test_add():
assert add(2, 3) == 5

def test_mul():
assert mul(3, 4) == 12

我们进行执行,可以完整的看下,执行的结果:

  1. 初始直接执行测试,可以看到测试失败 pytest test_calculator.py -v
  2. 运行 Agent 脚本 python naive_agent_demo.py

Naive Agent 运行失败日志示例

Naive Agent 长循环与错误输出示例

注意,脚本都在同一目录下!

其中的八大故障模式

失效模式 典型现场表现 直接后果 对应你代码中的位置
循环失控 while True 无终止条件 / 无独立的终止验证 API 额度耗尽、服务器资源被占满,任务停不下来 代码中用了 SAFE_MAX_ITER_FOR_CLASSROOM 做课堂保护,去掉就是典型的 while True
Context 溢出 messages 列表被无限追加,无裁剪 / 归档 / 淘汰逻辑 超出模型上下文窗口报错;token 消耗指数级上升,费用失控 messages.append(msg) 每次循环都追加消息,上下文越攒越大
Cache Miss(缓存失效) 每次循环修改 system prompt 等固定前缀,导致缓存不命中 请求延迟翻倍、token 费用翻倍,无法享受模型缓存优化 messages[0]["content"] = f"...[session_iter={i}]" 每次迭代都修改 system prompt
Tool 错误吞 工具调用异常被 try-except 吞掉 / 工具执行的返回码被丢弃 Agent 完全感知不到错误,在错误状态上继续操作,越跑越偏 except Exception: result = ""run_pytest() 只返回 stdout、丢弃 returncode
状态丢失 无进度文件 / 状态快照,所有状态仅存在内存中 会话崩溃 / 关闭后进度全丢,任务无法续跑 主循环结束后没有任何持久化逻辑,退出即丢状态
缺权限闸 无危险命令拦截、无路径白名单,高危操作(rm -rf // 覆盖核心文件)直接执行 数据损毁、生产事故,甚至服务器被破坏 write_file 可覆盖任意路径文件,无任何安全校验 / 权限控制
缺自动化评审 完全依赖 Agent 自评 “任务完成”,无独立的第三方评估器 任务没完成 / 结果错误,但 Agent 认为自己做完了,问题被带到交付环节 else: break 仅靠模型说 “完成了” 就退出,没有独立验证
成本失控 无 token 预算、调用次数上限、费用告警机制 长任务无限消耗 API,直接耗尽月度预算,产生巨额账单 代码中无 token 计数、预算检查的任何逻辑

这 8 个点,本质上就是驾驭工程(Harness Engineering)要解决的核心问题清单

  • 循环失控、Context 溢出、成本失控 → 资源与成本治理
  • Cache Miss → 性能优化与成本控制
  • Tool 错误吞、缺权限闸 → 工具调用安全与可靠性
  • 状态丢失 → 任务可恢复性
  • 缺自动化评审 → 结果质量校验

所有成熟的 Agent 框架,本质上都是在给 naive agent 补上这些 “短板”,让它能稳定、安全、可控地运行。

naive agent (裸奔智能体)失效时间线

flowchart LR
    A[任务启动] --> B[第1轮]
    B --> C[第2轮]
    C --> D[第3轮+]
    D --> E[Session运行中]
    E --> F[任务完成/会话结束]

    %% 标注各阶段故障
    B -->|循环失控| B
    B -->|Cache Miss| C
    C -->|Tool错误吞| C
    D -->|Context溢出| D
    E -->|缺权限闸| E
    E -->|成本失控| F
    F -->|状态丢失| F
    F -->|缺自动化评审| F
失效模式 核心描述 风险发生阶段 直接后果
循环失控 while True 无终止验证,模型一直认为任务没完成,无限循环调用 API 第 1 轮就可能触发 API 额度被耗尽,任务永远停不下来
Context 溢出 messages 列表被无限追加,轮次越多 prompt 越长 第 3 轮后快速恶化 超出模型上下文窗口报错,Token 费用失控
Cache Miss system prompt 每轮被改写,前缀不稳定导致缓存全部失效 每轮循环都会触发 请求延迟翻倍、Token 费用翻倍
Tool 错误吞 except 捕获异常后返回空字符串,Agent 误以为工具调用成功 第 2 轮开始常见 在错误的基础上继续操作,任务越跑越偏
状态丢失 无进度文件,关闭窗口后所有进度清零 Session 结束时触发 长任务无法跨天续跑,一切努力白费
缺权限闸 无权限控制,rm -rf/sudo 高危命令可直接执行 任意时刻都可能触发 数据损毁、生产事故,甚至服务器被破坏
缺自动化评审 Agent 自评 “任务完成” 就退出,无独立 Evaluator 把关 任务完成时触发 问题没解决就交付,事后返工成本极高
成本失控 无 Token 预算控制,循环跑多久 API 烧多少 全程累积 长任务直接耗尽月度 API 预算,产生巨额账单

Harness Engineering应对机制

序号 方案名称 核心实现 解决的失效模式 关键细节
1 Agent Loop 四相循环 Gather → Action → Verify → Iterate + max_iterations 硬刹车 循环失控 给 Agent 加上明确的终止条件和最大轮次限制,从源头避免无限循环。
2 Tool Use 工具编排 Schema 契约化调用,工具失败返回结构化错误,而非空字符串 Tool 错误吞 工具调用失败时,返回带错误码 / 原因的结构化数据,让 Agent 能感知错误、重试或调整。
3 Progress Tracking 进度追踪 claude-progress.txt + git commit 持久化进度快照 状态丢失 把每一步进度保存到文件 / 版本控制中,会话关闭后可续跑,长任务不怕中断。
4 Context Management 上下文管理 Token 监控 + 阈值压缩 / 重置 + 固定前缀 Context 溢出、Cache Miss 控制上下文长度,超出阈值时做压缩 / 归档;同时保持 system prompt 等前缀稳定,确保缓存命中。
5 Feature List 任务拆解 JSON 任务清单 + 单次只做一件事,从源头切细上下文 Context 溢出 把大任务拆成原子步骤,避免一次性把所有信息都塞进上下文,从源头控制 prompt 长度。
6 Verification Loop 验证闭环 Playwright/pytest 真机验证,不依赖 LLM 自评 缺自动化评审 用自动化测试工具(pytest、浏览器自动化)验证任务结果,而不是靠 Agent 自己说 “完成了”。
7 Subagents 子代理分治 独立 context 隔离子任务,主 Agent 不被中间过程污染 Context 溢出、循环失控 把复杂子任务交给独立子 Agent 处理,每个子 Agent 有自己的上下文,避免主循环被污染或失控。
8 Generator-Evaluator 生成 - 评估对抗 Planner + Generator + Evaluator 三角色分离,类似 GAN 缺自动化评审 引入独立的 “评估者” 角色,和生成者对抗,自动检查结果是否符合预期,避免自评偏差。

方案的出处与背景

大部分方案都标注了 Claude Agent SDK / Anthropic 和对应的日期,说明这些都是 Anthropic 官方推出的成熟实践,不是凭空想出来的 “最佳实践”。

和驾驭工程(Harness Engineering)的关系

这 8 个方案,合起来就是驾驭工程的核心组成部分:

  • 循环控制、成本控制 → 资源治理
  • 上下文管理、子代理分治 → 信息治理
  • 工具编排、验证闭环 → 可靠性治理
  • 进度追踪 → 任务可恢复性治理
flowchart LR
    subgraph 前置防护
        A[Feature List 任务拆解] --> B[Agent Loop 四相循环 + max_iterations]
        C[Progress Tracking 进度快照] --> B
    end

    subgraph 运行中防护
        B --> D[Gather]
        D --> E[Action]
        E --> F[Verify]
        F --> G[Iterate]

        E -->|使用| H[Tool Use 工具编排(结构化错误)]
        B -->|持续控制| I[Context Management 上下文压缩/缓存优化]
        B -->|分治| J[Subagents 子代理隔离]
    end

    subgraph 结果验证
        G --> K[Verification Loop 真机验证]
        K --> L[Generator-Evaluator 对抗评估]
    end

LangChain 三层架构:Framework、Runtime、Harness 同一家

接下来用 LangChain 这个你最熟悉的例子把上面四个术语同时落地。LangChain 创始人 Harrison Chase 在 2025-10-25 博文 Agent Frameworks, Runtimes, and Harnesses - oh my! 里把产品线切成了三层。

在看表之前先做个小铺垫:如果你用过 LangChain 的 LCEL 或 AgentExecutor,你已经在用 Framework 层;LangGraph 是 LangChain 2024 年推出的状态机引擎,把一次对话升级为可暂停、可恢复的有状态工作流(这就是表里提到的 checkpoint / interrupt);DeepAgents 则在 LangGraph 之上组合规划、文件工具、子 Agent 和长期记忆等能力。如果这三者的区别暂时记不住不用慌——我们在第八章生态地图里会再次见到它们,到时候再回过头看这张表会更清晰。顺便补一个生态定位:LangChain 在整体 AI 技术栈中位于 Framework+Runtime+Harness 层,上游是 LLM API(OpenAI / Anthropic / 国产模型),下游是应用(ChatBot / IDE / CLI)。

LangChain 三层产品架构

LangChain 对应产品 角色 类比
Framework langchain-core / integrations 提供 LLM / tool / retriever 的抽象基类 积木
Runtime LangGraph 提供状态机 / checkpoint / interrupt 的执行引擎 发动机
Harness DeepAgents 把 LangGraph 组装成”能跑长任务”的完整系统 整车

看到这张表,我们就理解了LangChain 为什么持续从早期 AgentExecutor 扩展到 LangGraph 和 DeepAgents:AgentExecutor 属于较早的 Agent 执行抽象;DeepAgents 则在 LangGraph 运行时之上提供更完整的 Agent Harness。Harrison Chase 在那篇博文里说得很直白:大多数工程师需要的不是 runtime,是一个能直接跑的 harness,LangChain 要把 harness 这一层也做完。

到这里我们手里已经有了 Agent = Model + Harness 公式、三类工程协作关系、四个术语边界、LangChain 三层落地——这是本课所有后续内容的”字典基底”。接下来我们要做一件更决定性的事:把一个没有 harness 保护的 naive agent 拉出来现场复现失效,让你亲眼看到缺了 harness 的 agent 到底有多脆弱。