很多人第一次接触 Agent,会把它理解成“一个更会调用工具的聊天机器人”。这个理解并不算错,但还不够完整。
Agent 真正发生变化的地方,不只是模型变大了,也不只是 Prompt 写得更长了,而是我们开始用工程方法设计一套完整的工作系统:让模型知道该知道的内容,能够调用合适的能力,知道如何判断结果,并且在出错后继续修复。
如果把这条演进路线压缩成三句话,可以这样理解:
- Prompt Engineering:把需求讲清楚,告诉模型应该怎么做。
- Context Engineering:把当前任务需要的信息准备好,决定模型此刻能看到什么。
- Harness Engineering:把工具、验证、状态和任务流程组织起来,让 Agent 能持续把事情做完。
这三个概念不是互相替代的关系,而是一层一层向外扩展的工程边界。
一、Prompt Engineering:先解决“怎么说”
大语言模型的基本工作方式,可以粗略理解为:根据已经看到的内容,预测接下来最合理的内容。
这意味着模型即使具备很强的语言和推理能力,也不会自动知道你的目标、约束和验收标准。你只说一句“帮我写篇文章”,模型并不知道文章是给谁看的、要解决什么问题、应该多长、采用什么格式,更不知道哪些内容不能出现。
一个更有效的 Prompt,通常会把下面几件事说清楚:
| 要素 | 需要回答的问题 |
|---|---|
| 角色 | 你希望模型以什么身份工作? |
| 目标 | 最终要交付什么结果? |
| 背景 | 模型必须了解哪些上下文? |
| 约束 | 哪些事情不能做,或必须遵守? |
| 输出格式 | 结果应该是表格、代码、清单还是文章? |
| 验收标准 | 怎样才算完成? |
例如,“帮我分析接口性能”可以改成:
1 | 你是一名后端性能工程师。 |
这段 Prompt 并没有让模型“变聪明”,但它减少了任务歧义,让输出更稳定、更容易检查。
所以,Prompt Engineering 解决的核心问题是:
模型有能力,但不知道我们想让它朝哪个方向工作。
二、Context Engineering:再解决“知道什么”
当任务变复杂以后,问题通常不再是 Prompt 写得不够好,而是模型根本没有足够的信息。
让模型修改一个真实代码仓库时,可能需要同时参考:
- 当前需求和历史讨论;
- 相关代码文件与目录结构;
- 项目约定、接口文档和数据库结构;
- 最近一次构建失败日志;
- 用户在本次任务中的选择;
- 前面已经执行过的命令及其结果。
这些内容共同组成模型本轮推理看到的 Context。Prompt 只是 Context 的一部分。
一次完整的上下文可能长这样:
1 | System instructions |
Context Engineering 关注的不是“把所有信息都塞进去”,而是三个更实际的问题:
1. 选择信息
上下文越多不一定越好。无关内容会稀释重点,过长的历史还可能让模型遗漏真正重要的约束。
更好的做法是围绕当前任务筛选信息:先确定任务目标,再只加载与目标相关的文件、规范和历史结论。
2. 组织信息
同一批资料,组织方式不同,模型的理解效果也会不同。可以用标题、分隔符、来源标记和时间标记把不同类型的信息分开,让模型知道哪些是规则、哪些是事实、哪些是待验证的推断。
3. 控制信息的新鲜度
代码、日志和任务状态会变化。昨天检索到的结果,可能已经不能代表当前状态。因此,Context 不仅要“相关”,还要尽量“新鲜”。
可以把 Context Engineering 理解成:
为模型准备一张与当前任务匹配的工作台。
三、Harness Engineering:最后解决“如何持续完成”
如果说 Prompt 是一张说明书,Context 是工作台上的资料,那么 Harness 就是整套工作环境。
它负责把模型和真实世界连接起来,包括:
- 文件读写;
- Terminal 和脚本执行;
- 浏览器或外部 API;
- 编译、Lint、测试和运行环境;
- 任务拆解、状态记录与进度管理;
- 权限边界、超时、重试和错误处理。
一个 Agent 的价值,不在于它第一次回答得多漂亮,而在于它能否形成这样的闭环:
1 | 理解需求 |
这也是 Agent 和普通聊天的分界线。聊天通常在“生成回答”处结束;Harness 则把“执行、检查、修复、再执行”变成系统的一部分。
四、三个 Engineering 的边界
把三者放在一起,可以得到一张简单的分层图:
1 | ┌────────────────────────────────────────────┐ |
| 层次 | 主要问题 | 典型产物 |
|---|---|---|
| Prompt | 怎样把任务说明白? | 指令、示例、输出模板 |
| Context | 模型现在应该知道什么? | 检索结果、代码片段、记忆、日志 |
| Harness | 模型怎样持续把事情做完? | 工具链、状态机、验证器、重试策略 |
当输出不稳定时,先检查 Prompt 是否清楚;当模型答非所问时,检查 Context 是否缺资料或混入噪声;当模型会回答却不会交付时,检查 Harness 是否缺少工具和验证闭环。
五、用一个代码修改任务看完整流程
假设需求是:“给服务增加一个限流配置,并保证原有接口行为不变。”
只使用 Prompt,模型可能会直接修改一个看起来相关的文件。但一个更可靠的 Agent 流程应该是:
- 理解:读取项目结构、服务入口和现有配置方式。
- 规划:列出需要修改的文件,以及不应触碰的模块。
- 执行:编辑配置、实现限流逻辑并补充测试。
- 验证:运行格式检查、单元测试和一条真实启动命令。
- 修复:根据失败日志定位问题,而不是凭感觉重写。
- 交付:说明修改了什么、验证了什么、还剩哪些限制。
这个过程中,Prompt 规定做事方式,Context 提供项目事实,Harness 提供读取文件、执行命令和运行测试的能力。三者缺一不可。
六、如何开始搭建自己的 Harness
不必一开始就做一个复杂的多 Agent 平台。一个可用的最小 Harness,可以先具备四类能力:
1. 可控的工具
每个工具都应该说明输入、输出、失败方式和权限范围。工具越明确,模型越容易正确使用,也越容易在失败后恢复。
2. 可观察的执行过程
保留命令、参数、返回码和关键输出。没有执行记录,就很难判断 Agent 是没做、做错,还是验证步骤本身失效。
3. 可重复的验证
把“做对了吗”变成可以重复执行的检查,例如编译、Lint、单元测试、接口探活和快照对比。
4. 有边界的重试
重试应该由错误类型和剩余预算驱动。对于语法错误可以自动修复;对于权限不足、需求矛盾或外部服务不可用,则应该停下来说明原因。
可以用下面的清单评估一个 Agent 工作流:
- 它是否能读取完成任务所需的最小信息?
- 它是否能调用完成任务所需的工具?
- 它是否知道成功标准?
- 它是否能从错误输出中恢复?
- 它是否会保留进度,而不是每次从头开始?
- 它是否能在无法继续时给出清晰的阻塞原因?
七、结语:我们工程化的对象变了
Prompt Engineering 关注的是“让 AI 回答得更好”;Context Engineering 关注的是“让 AI 在正确的信息上思考”;Harness Engineering 关注的是“让 AI 在一个可验证的工作系统里持续行动”。
这条路线背后,是 AI 使用方式的变化:从一次性的问答,走向有目标、有工具、有状态、有反馈的任务执行。
所以,Agent 工程的关键问题不再只是:
我应该写一句什么 Prompt?
而是:
我应该如何设计一套系统,让模型知道该知道的、能够做该做的,并且能证明自己做对了?
下一步可以继续拆解 Agent 的能力边界:Tool 是能力,MCP 是连接能力的协议,Skill 则是一套可以复用的做事方法。理解这三者,才能进一步看懂 Agent 是怎样长出“手和脚”的。