驾驭 Harness 工程思维:Agent = Model + Harness,模型负责思考,Harness 负责管控
工程参考书:《HARNESS 工程:从上下文管理到 Agent 系统构建》(邢云阳 著,人民邮电出版社 2026-05,ISBN 9787115697950)。
本文 6 大工程主题(边界设计、编排流程、上下文管理、工具封装、任务调度与状态机、可观测性)逐一落地,
每个主题给出通俗解释、可运行示例与 arXiv 前沿依据(全部 urllib 实拉核验,见文末核验回执)。
0. 先讲人话:为什么"会写提示词"不等于"会做 Agent"
写提示词,是给模型写"话术";做 Agent,是在模型外面造一辆车。
模型是发动机,负责思考(理解、推理、生成);而 Harness 是底盘、方向盘、仪表盘和刹车,负责管控:决定车往哪开(编排)、油箱怎么分配(上下文)、什么时候点刹车(安全)、出了故障怎么处理(重试降级)。
一句话公式:
Agent = Model + Harness
- Model(模型):只负责"想"。
- Harness(工程):负责"管控、编排、记忆、安全"。
邢云阳在《HARNESS 工程》里把这条主线讲得很清楚:第 1–2 章是上下文工程与五大能力(意图识别、计划、反思、CodeAct 行动、人机协作),第 6–7 章直接讲怎么复现 Claude Code 核心特性、构建 OpenClaw 类产品——为什么要专门用两章讲"复现一个产品"?因为真正难的从来不是模型调用,而是把模型装进一套可靠的工程系统。
本文就把这套工程思维拆成六块,每一块都能上手。
1. Harness 全景:模型想,Harness 管
先给一张总图,后面每一节都是图里的一个方块:
工程思维的本质,是把"玄学"变成"确定性":每个环节都要有明确的输入、明确的输出、明确的失败路径。模型可能给出不可预测的回答,但 Harness 的每个闸门必须是确定性的。
2. 设计边界:先画圈,再谈能力
2.1 边界是什么
边界 = 这个 Agent 能做什么、不能做什么、什么时候必须停下来问人。没有边界的 Agent 就像一个没有红绿灯的十字路口,能力越强越危险。
边界至少分三层:
| 层 | 管什么 | 典型手段 |
|---|---|---|
| 意图层 | 用户的请求该不该接 | 意图识别(小模型微调 + 大模型兜底,见书第 2.1 节) |
| 权限层 | 能调用哪些工具、动哪些资源 | 工具白名单、读/写/执行分级 |
| 失败层 | 超时、超预算、超出能力时怎么办 | 最大步数、超时上限、人工接管(Human-in-the-loop) |
2.2 意图识别:先判"接不接"
[自撰示例] 一个简单的意图闸门,小模型先分类、大模型兜底:
def route(intent: str, text: str) -> str:
# 1. 小模型快速分类:query / tool / refuse / escalate
label = small_model.classify(text)
# 2. 高置信直接放行
if label.confidence > 0.9:
return label
# 3. 低置信交大模型兜底(书第2.1节:小模型微调+大模型兜底)
return big_model.judge(f"请判断该请求意图: {text}")
意图识别做不好,后面所有编排都是空转。先画圈,再谈能力。
3. 编排流程:把大任务拆成可管理的子任务
3.1 拆:复杂任务 → 子任务
复杂任务的第一件事是拆。Plan-and-Solve(arXiv:2305.04091)提出"先规划、再求解"的两阶段提示;更进一步,Tree of Thoughts(2305.10601)把一条推理链拆成"树",Graph of Thoughts(2308.09687)允许子任务之间任意连边、合并、回溯——编排越复杂,越接近真实工程。
3.2 选模式:每个子任务用什么"打法"
书第 2 章给出五种核心模式,正好对应不同子任务:
| 子任务类型 | 用哪种模式 | 论文锚点 |
|---|---|---|
| 先想清楚再干 | 计划模式 | Plan-and-Solve 2305.04091 |
| 干完检查一遍 | 反思模式 | Reflexion 2303.11366、Self-Refine 2303.17651 |
| 要调外部能力 | 工具模式 | Toolformer 2302.04761、SWE-agent 2405.15793 |
| 要执行代码 | CodeAct 模式 | 书第 2.4 节(代码即工具) |
| 拿不准就问你 | 人机协作模式 | 书第 2.5 节 |
3.3 传:子 Agent 之间怎么递信息
- AutoGen(2308.08155):让多个 Agent 互相对话,把中间结果当"消息"传递。
- MetaGPT(2308.00352):给每个 Agent 分配角色(产品、架构、开发),按角色产出文档作为交接物——像真实公司一样靠"工件"协作。
3.4 败:失败后重试 or 降级
- 重试:Reflexion(2303.11366)把失败原因写成"反思笔记",下次带着笔记重来;CRITIC(2305.11738)让模型调用工具来批判自己(如用编译器/搜索验证答案)。
- 降级:换更简单的模型、换更稳的提示、或直接交给人工。IHBench(2606.19595)专门评测 Agent 被打断后能否恢复——重试/降级能力本身就该被量化。
[自撰示例] 一个编排器的骨架:
def orchestrate(task: str):
subtasks = planner.split(task) # 拆
results = {}
for st in subtasks:
mode = pick_mode(st) # 选模式
results[st.id] = run_subagent(st, mode)
if not verify(results[st.id]): # 校验
results[st.id] = retry(st, max_times=2) # 重试
if not results[st.id]:
results[st.id] = degrade(st) # 降级
return aggregate(results) # 汇聚
4. 上下文管理:Agent 的记忆与注意力预算
4.1 为什么"上下文"是工程问题
上下文是 Agent 唯一的"工作记忆",但它有三个硬伤:
- 会丢:Lost in the Middle(2307.03172)证明,模型对长上下文中间位置的信息利用最差——重要信息要放在开头或结尾。
- 会满:窗口有限,对话一长就溢出。
- 会贵:token 即成本,塞太多又慢又贵。
书中第 1.2 节给出了"上下文构建的四大模块与核心管理策略"的框架(详见原书),本文给一套可落地的分层实践:
4.2 三条核心策略
- 分层:短期(本轮对话)→ 工作记忆(任务中间态)→ 长期记忆(向量库/文件/数据库)。MemGPT(2310.08560)把上下文当成"操作系统内存",不够就分页换出——长期记忆放"磁盘",需要时再换入。
- 压缩:LLMLingua(2310.05736)用小型语言模型压缩 prompt,提速降本。实践中可把历史对话滚动摘要,而不是全量保留。
- 调度:每次调用前问一句"这次真正需要哪些信息",而不是把整个记忆库都塞进去。
经验法则:能检索的不常驻,能摘要的不全文,能外置的不进窗。 上下文越干净,模型发挥越稳定。
5. 工具调用封装:把"能力"变成可调用的接口
5.1 工具 = Agent 的手脚
Toolformer(2302.04761)证明模型可以自学何时调用工具、调用什么工具。但工程上,工具怎么"露给"模型,决定了成功率——SWE-agent(2405.15793)的核心洞察是:Agent 的界面设计(Agent-Computer Interface)直接决定任务成败。给模型一个烂工具界面,再强的模型也白搭。
5.2 封装五要点
| 要点 | 说明 |
|---|---|
| 签名清晰 | 函数名 + 参数名要"人话",模型才好理解 |
| Schema 化 | 给出 JSON Schema,让模型生成结构化参数 |
| 输入校验 | 参数进工具前先校验,防止模型幻觉参数 |
| 输出解析 | 返回结构统一,附带错误码而非自然语言报错 |
| 超时重试 | 工具调用加超时,失败自动重试或换路 |
[自撰示例] 一个带 schema + 重试的工具装饰器:
@tool(
name="search_stock",
schema={"symbol": "str", "days": "int"},
retry=2, timeout=10
)
def search_stock(symbol: str, days: int) -> dict:
# 校验 + 调用 + 统一返回 {ok, data, error}
...
书第 2.4 节讲的 CodeAct(代码即工具)更进一步:与其让模型填 JSON,不如让模型直接写代码执行——表达力强得多,这也是 Claude Code 类产品能"干活"的关键之一。
6. 任务调度与状态机:让 Agent 变成确定性的机器
6.1 为什么需要状态机
LLM 的输出天生不可预测,但工程系统必须可预测。解法是:用确定性的状态机把模型"包"起来——模型只在状态机允许的转移里行动。
一个最小状态集合:
| 状态 | 含义 |
|---|---|
| idle | 空闲,等任务 |
| running | 正在思考/生成 |
| tool_call | 正在调工具 |
| wait_human | 等待人工确认 |
| done | 成功完成 |
| failed | 失败 |
| degraded | 已降级兜底 |
[自撰示例] 状态转移表驱动:
TRANSITIONS = {
"idle": ["running"],
"running": ["tool_call", "wait_human", "done", "failed"],
"tool_call": ["running", "failed"], # 工具失败回到运行态重试
"wait_human": ["running", "done"], # 人工确认后继续或结束
"failed": ["running", "degraded"], # 重试 or 降级
}
def step(state: str, event: str) -> str:
nxt = TRANSITIONS[state]
assert event in nxt, f"非法转移: {state} -> {event}" # 非法转移直接拦下
return event
失败策略上,用指数退避控制重试节奏,连续失败 N 次熔断切降级,防止 Agent 在同一个坑里无限打转。
前沿锚点:Code as Agent Harness(2605.18747)把"代码即 Harness"作为系统范式;CUGA FLO(2606.27188)把遗留业务流程升级为 Agentic 流程;Architectural Implications of Agentic AI Workflows(2608.04458)讨论这类架构的工程代价。确定性外壳 + 模型内核,是 2026 年 Harness 工程的主旋律。
7. 可观测性:看不见的 Agent 无法改进
7.1 记录什么
可观测性 = 给 Agent 装"黑匣子"。每个关键节点至少记录:
- 输入输出(模型层)
- 工具调用(参数、返回、耗时、错误)
- 每一步的 token 消耗、耗时
- 状态机转移路径
- 失败原因、重试/降级动作
[自撰示例] 结构化 trace:
{
"trace_id": "t-1024",
"steps": [
{"step": 1, "state": "running", "model": "deepseek-r1",
"tokens": 812, "ms": 430},
{"step": 2, "state": "tool_call", "tool": "search_stock",
"ok": true, "ms": 210},
{"step": 3, "state": "failed", "reason": "schema_error",
"retry": 1}
],
"final": "done"
}
7.2 为什么可观测性决定上限
- 归因难:Agent 长程任务里,"到底哪一步导致了最终成败"很难说清。TRACE(2607.13988)把回合级信用归因变成可计算方法——而它的输入,正是你记录的每一步 trace。
- 证据链:From Agent Traces to Trust(2606.04990)系统梳理了 LLM Agent 的执行溯源(execution provenance)——可观测性不只是排障,更是建立信任、支撑合规的基础设施。
- 闭环:trace → 评估 → 改进 Harness(换编排、换模式、换工具),形成飞轮:
落地建议:结构化日志 + trace ID 贯穿 + 回放工具 + 回归测试集。没有回放和回归集,可观测性只是"事后诸葛亮";有了它们,才能"事前避坑"。
8. arXiv 前沿论文表(全部 urllib 实拉核验)
| 论文 | 作者 | arXiv | 年份/会议 | 与本文关系 | 链接 |
|---|---|---|---|---|---|
| A Survey of Context Engineering for Large Language Models | Mei L. et al. | 2507.13334 | 2025 | 上下文工程综述;支撑第 4 节 | 链接 |
| Lost in the Middle: How Language Models Use Long Contexts | Liu N. et al. | 2307.03172 | 2023 | 长上下文中间信息易丢失;支撑 4.1 | 链接 |
| MemGPT: Towards LLMs as Operating Systems | Packer C. et al. | 2310.08560 | 2023 | 上下文分页管理;支撑 4.2 分层 | 链接 |
| LLMLingua: Compressing Prompts for Accelerated Inference | Jiang H. et al. | 2310.05736 | 2023 | Prompt 压缩;支撑 4.2 压缩 | 链接 |
| Plan-and-Solve Prompting | Wang L. et al. | 2305.04091 | 2023 | 先规划再求解;支撑 3.1 拆解 | 链接 |
| Tree of Thoughts: Deliberate Problem Solving with LLMs | Yao S. et al. | 2305.10601 | 2023 | 树状搜索式推理;支撑 3.1 | 链接 |
| Graph of Thoughts: Solving Elaborate Problems with LLMs | Besta M. et al. | 2308.09687 | 2023 | 图式编排与回溯;支撑 3.1 | 链接 |
| AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation | Wu Q. et al. | 2308.08155 | 2023 | 多 Agent 对话式协作;支撑 3.3 传递 | 链接 |
| MetaGPT: Meta Programming for A Multi-Agent Collaborative Framework | Hong S. et al. | 2308.00352 | 2023 | 角色化多 Agent 协作;支撑 3.3 | 链接 |
| Toolformer: Language Models Can Teach Themselves to Use Tools | Schick T. et al. | 2302.04761 | 2023 | 模型自学工具调用;支撑 5.1 | 链接 |
| SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering | Yang J. et al. | 2405.15793 | 2024 | Agent 界面设计决定成败;支撑 5.1 | 链接 |
| Reflexion: Language Agents with Verbal Reinforcement Learning | Shinn N. et al. | 2303.11366 | 2023 | 反思笔记式重试;支撑 3.4 | 链接 |
| Self-Refine: Iterative Refinement with Self-Feedback | Madaan A. et al. | 2303.17651 | 2023 | 迭代自修;支撑 3.4 重试 | 链接 |
| CRITIC: LLMs Can Self-Correct with Tool-Interactive Critiquing | Gou Z. et al. | 2305.11738 | 2023 | 调用工具批判自己;支撑 3.4 | 链接 |
| IHBench: Evaluating Post-Interruption Recovery in Voice Agents | Salimi A. et al. | 2606.19595 | 2026 | 打断后恢复能力评测;支撑 3.4 降级 | 链接 |
| From Agent Traces to Trust: A Survey of Evidence Tracing and Execution Provenance in LLM Agents | Wang Y. et al. | 2606.04990 | 2026 | 执行溯源综述;支撑第 7 节 | 链接 |
| TRACE: Turn-level Reward Assignment via Credit Estimation for Long-Horizon Agents | Tao L. et al. | 2607.13988 | 2026 | 回合级信用归因;支撑 7.2 | 链接 |
| Code as Agent Harness | Ning X. et al. | 2605.18747 | 2026 | 代码即 Harness 范式;支撑第 6 节 | 链接 |
| CHILL-Harness: Counterfactual Harness Learning for Efficient Reasoning in Long-Horizon Agents | Fu J. et al. | 2607.25825 | 2026 | 反事实 Harness 学习;支撑第 6–7 节 | 链接 |
另参考(非 arXiv):《HARNESS 工程:从上下文管理到 Agent 系统构建》(邢云阳 著,人民邮电出版社 2026-05,ISBN 9787115697950)——上下文工程五大能力与 Harness 工程落地的主线来源。
9. 思考题
- 你的 Agent 失败后,该重试还是降级?判定依据是什么(成本、成功率、用户等待时长)?
- 上下文窗口越来越大(百万级),为什么 MemGPT 式的分层管理依然必要?"塞得下"和"用得好"是一回事吗?
- 可观测性数据收集了,怎么把它变成下一次执行的改进?你的闭环断在哪一环(是没记录,还是没评估,还是没回灌)?
- 状态机的"确定性外壳"和模型"自由发挥",边界画在哪?太死会笨,太活会失控,你怎么找平衡?
附Harness学习路径
学习路径可以分成三层,从“会用”到“用好”再到“能设计”:
第一层:会用 Harness(1-2 周)
-把四种预设模式(标准、代码、极简、创造)都跑一遍,感受每种模式下的工具可用范围、思考深度差异
-学会用 / 命令调用对话压缩、目标设定、计划模式、Skills
-学会看 Trajectory 视图,理解模型每一步在做什么、花了多少 Token
-学会配置工作区、管理 Agent 预设、安装社区 Skill
第二层:用好 Harness(1-2 个月)
-学会为不同任务选择合适的模式和思考深度
-学会编写有效的系统提示词和 Skill 定义(SKILL.md 格式),让模型在特定任务上表现更稳定
-学会设计权限边界:哪些目录可读写、哪些命令需确认、哪些操作直接禁止
-学会用 Git 配合 Harness,建立“模型改代码→人工审查→合并”的工作流
-学会分析 Trajectory 日志,定位模型在哪里“栽跟头”、哪个环节成本最高
第三层:能设计 Harness(长期)
-理解 Harness 的插件系统(基于 Cordis),能自己写插件扩展能力
-理解上下文工程的核心原则:什么信息该放进上下文、什么时候该压缩、如何用外部记忆(文件、数据库)解决长任务中的“失忆”问题
-理解多智能体编排的模式:主 Agent 分配任务、子 Agent 执行并汇报、结果汇总与校验
-理解微调与 Harness 的配合:哪些问题靠 Harness 的工程手段解决,哪些问题必须靠微调模型本身来解决

652

被折叠的 条评论
为什么被折叠?



