
很多 AI 应用最初只有一段提示词。
用户提出问题,模型生成答案。只要任务不复杂,这套方式已经够用。但当我们让模型读取几十个文件、调用工具、修改代码,再连续工作几十轮时,问题就不再是“提示词写得好不好”了。
模型可能忘记目标,可能在错误方案上反复尝试,也可能写完代码却没有运行测试。要处理这些问题,AI 应用的工程重心会依次经过三个阶段:提示词工程、上下文工程和 Harness 工程。
它们分别回答三个问题:
怎样把任务说清楚?
模型这一轮需要看到什么?
怎样让任务可靠地执行到底?
1. 提示词工程:先把任务交代清楚
提示词工程处理的是人与模型之间的表达问题。
例如,让模型判断一条商品评价的情感,最简单的提示词可能是:
分析下面这条评价。
这句话没有说明分类范围,也没有规定输出格式。模型可能写一段解释,也可能给出几个模棱两可的标签。更清楚的写法是:
判断下面这条商品评价的情感倾向。
分类范围:
– 正面
– 中性
– 负面
评价内容:
包装破损,客服两天都没有回复。
只输出分类结果。
后一版并没有使用什么神奇技巧,只是把任务、范围和格式交代清楚了。
一段实用的提示词通常会包含四类内容:
- 要完成的任务;
- 理解任务所需的背景;
- 必要时提供一两个示例;
- 输出格式和边界。
少样本示例、角色设定、任务拆解、结构化输出都属于提示词工程。它们适合处理分类、翻译、摘要、信息提取等短任务。
麻烦出现在任务变长之后。
假设模型要分析一个代码仓库。第一次调用时,它需要了解目录结构;找到相关模块后,它需要读取具体文件;修改代码前,还要知道项目的测试方式。把整个仓库和全部日志都塞进一段提示词,成本很高,效果也未必好。
这时,问题已经从“怎么说”变成了“给模型看什么”。
2. 上下文工程:管理模型眼前的信息

模型每次生成内容时,只能依据当前上下文。这里的上下文远不止用户输入,还包括系统指令、历史消息、工具说明、检索结果、任务状态和运行日志。
可以把它写成:
当前上下文 =
系统规则
+ 用户请求
+ 相关知识
+ 可用工具
+ 历史记录
+ 当前任务状态
上下文工程的工作,是在每一轮调用前重新组织这些信息。
重点不在“多”,而在“刚好够用”。上下文过短,模型缺少依据;上下文过长,关键内容又容易被埋没。工具返回的几百行日志、已经过期的计划和重复出现的代码片段,都会消耗注意力和 Token。
先看地图,再进房间
分析大型代码库时,一次加载所有文件并不合适。更实用的过程是:
查看目录结构
↓
确定相关模块
↓
搜索类名或函数名
↓
读取几个具体文件
↓
补充测试与调用关系
模型先看到“地图”,再决定进入哪个“房间”。这就是渐进式披露。
知识库问答也采用类似思路。系统不会把整个资料库交给模型,而是先根据问题进行检索,再选出几段真正相关的内容。
历史记录不能只增不减
Agent 每执行一步,都会产生新的消息、工具结果和判断。如果这些内容全部保留,上下文很快就会变成一份杂乱的流水账。
比较稳妥的做法是分层保存:
- 当前步骤保留必要的原始信息;
- 已完成步骤压缩成简短结论;
- 任务状态单独记录;
- 完整日志放在上下文窗口之外,需要时再查询。
假设 Agent 已经检查了 20 个文件,真正需要留在当前上下文里的,通常不是 20 次读取结果,而是这样的摘要:
已确认:
1. 用户鉴权入口位于 auth/middleware.py。
2. Token 过期判断使用本地时间,可能受时区影响。
3. tests/test_auth.py 中没有覆盖跨时区场景。
下一步:
补充失败用例,再修改过期时间判断。
信息少了,但任务脉络更清楚。
不过,即使上下文整理得很好,系统仍然可能出问题。模型调用工具失败后怎么办?连续三次执行同一条命令怎么办?它说“修改完成”时,谁来确认测试真的通过了?
这些属于运行过程的问题,需要 Harness 来处理。
3. Harness 工程:给模型配一套运行系统
Harness 是模型外部的执行框架。模型负责判断下一步做什么,Harness 负责把这个判断变成一次受控的行动。
一个能长期运行的 Agent,通常需要下面这些部件:
| 执行循环 | 接收模型决策,调用工具,再把结果交还给模型 |
| 工具系统 | 管理文件读写、搜索、命令行和外部服务 |
| 任务状态 | 记录哪些工作已经完成,哪些仍在等待 |
| 记忆管理 | 保存、压缩并按需恢复历史信息 |
| 验证机制 | 用测试和检查项判断结果是否合格 |
| 重试机制 | 工具失败或验证不通过时继续处理 |
| 权限控制 | 在执行高风险操作前进行限制或确认 |
| 沙箱 | 隔离模型生成的不可信代码 |
| 运行日志 | 记录每一步操作,方便恢复和排查问题 |
提示词只能要求模型“修改后记得运行测试”。Harness 可以把测试设为完成任务前必须经过的一道检查。
两者的差别很实际。
只有提示词时,模型可能声称修改已经完成。加入 Harness 后,系统会读取测试结果:通过则结束,失败就把错误信息送回执行流程。判断依据从模型的自我评价变成了外部证据。 
4. miniMaster 如何组织一次任务
miniMaster 使用 Planner、Executor 和 Validator 三种角色处理任务。
用户提出任务
↓
Planner 拆解任务
↓
Executor 调用工具执行
↓
Validator 检查结果
↓
通过 未通过
↓ ↓
交付结果 返回修改

Planner:管方向
Planner 负责拆分任务和安排顺序。
用户提出“分析项目的记忆系统”时,Planner 不会立即生成最终答案。它会先确定需要检查哪些内容,比如:
执行过程中如果发现任务太大,Planner 还可以继续拆分。某条路径多次失败时,它也可以调整计划。
Executor:做具体工作
Executor 根据当前任务调用工具。它可能先搜索 memory 相关文件,再读取初始化代码,随后追踪对象如何传入 Planner、Executor 和 Validator。
它的工作成果不只是最后一段文字,还包括文件位置、搜索结果、运行日志和阶段性结论。这些内容会成为后续验证的依据。
Validator:检查有没有真的做完
Executor 说“已经完成”,不代表任务真的完成了。
Validator 会按照验收条件检查:
- 用户问到的对象是否全部解释;
- 结论能否在代码中找到依据;
- 是否遗漏跨重启持久化问题;
- 输出内容是否与实际实现一致。
如果证据不足,任务会回到执行阶段。Planner 也可以根据失败原因重新拆分任务。
把这三种职责分开,并不意味着必须调用三个不同的模型。重点是不要让同一轮判断同时承担计划、执行和自我验收。否则,模型很容易接受自己刚刚得出的结论。
5. 三种工程分别管什么
| 提示词工程 | 模型是否理解任务 | 明确指令、示例、格式约束 |
| 上下文工程 | 模型是否拿到了合适的信息 | 检索、筛选、压缩、分层记忆 |
| Harness 工程 | 任务能否稳定执行并通过验收 | 状态管理、工具调度、验证、重试和权限控制 |
三者并不是三个互相排斥的方案。
一个 Harness 仍然需要为不同角色准备提示词,也需要决定每一轮提供哪些上下文。区别在于,它还管理模型调用之外的事情:任务什么时候开始,工具怎样执行,错误如何处理,结果由谁检查。 
6. 开发时怎样判断问题出在哪里
遇到问题时,可以先看它发生在哪一层。
如果模型经常误解要求,或者输出格式不稳定,先检查提示词。任务目标、输入范围和完成标准可能没有写清楚。
如果模型找不到信息,或者总被无关日志带偏,问题多半出在上下文。此时应检查检索结果、历史消息和工具返回值。
如果模型知道该做什么,却在执行中重复操作、丢失进度,或者未经测试就宣布完成,则需要调整 Harness。增加提示词通常治不好这类问题。
真正可用的 Agent,很少依靠一段“万能提示词”。它需要清楚的任务说明,也需要干净的上下文,还要有一套能记录进度、约束行为和检查结果的运行机制。模型只是其中负责判断的一部分。



