跳转至

第 5 章 Prompt 作为控制层

当很多人第一次接触 Agent 时,最容易把 Prompt 理解成“写给模型的一段提示词”。这种理解不能说错,但过于浅。对于一个真正可用的 Agent 系统来说,Prompt 的职责远不只是“让模型说得更像人”或者“让回答更漂亮”,它更像是系统对模型施加控制的一种接口。

如果把 Agent 看成一个任务控制系统,那么 Prompt 的位置就不应该被理解为营销文案或写作技巧,而应该被理解为控制协议的一部分。它决定模型如何理解自己的角色、如何识别任务目标、如何遵守输出约束、如何看待工具调用、如何在不确定情况下选择下一步动作。

因此,本章讨论的重点不是“Prompt Engineering 的花式技巧”,而是一个更工程化的问题:Prompt 在 Agent 里究竟负责什么,不应该负责什么,以及怎样设计才更稳定。

5.1 System Prompt 的职责边界

在大多数 Agent 系统里,最核心的一层 Prompt 通常是 System Prompt。它定义的不是一次具体任务的内容,而是模型在整个运行周期中应遵循的角色与行为边界。

一个合格的 System Prompt 至少应该回答以下问题:

  • 这个 Agent 的角色是什么。
  • 它应该以什么目标函数来行动。
  • 它有哪些硬约束不能违反。
  • 它在什么情况下应该使用工具。
  • 它在什么情况下必须停止、澄清或请求人工确认。
  • 它的输出需要满足什么结构或风格要求。

换句话说,System Prompt 关心的是“行为协议”,而不是“事实内容”。例如,一个排障 Agent 的 System Prompt 应该强调先收集证据再下结论、在高风险动作前必须确认、不可编造不存在的诊断结果;而不是在里面塞大量业务知识或具体故障样例。后者更适合进入知识系统、示例库或动态上下文,而不应长期固化在 System Prompt 中。

这也是很多 Agent 系统一开始就会踩的坑:把所有东西都往 System Prompt 里堆,结果既有行为规则,又有业务知识,又有用户历史偏好,还有临时任务说明。这样做的短期效果可能是“模型一开始看起来很懂”,但长期代价通常非常明显:

  • Prompt 变得冗长且难维护。
  • 不同信息的生命周期混在一起。
  • 知识更新必须改系统提示。
  • 调试时很难判断问题到底来自规则、事实还是上下文冲突。

因此,System Prompt 的核心职责应该被严格限制在“定义角色、目标、边界和协议”上。只要把这个边界守住,后续系统在动态装配任务上下文、知识片段和工具说明时才不会失控。

工程提示

如果一个 System Prompt 长得像一份知识库汇总,那它大概率已经承担了不属于自己的职责。

5.2 指令设计中的约束、目标与风格

Prompt 作为控制层,最重要的不是“说得礼貌”,而是把约束、目标和风格区分清楚。

目标告诉模型,它最终在追求什么。例如“优先完成任务闭环”“以可验证信息为依据回答”“在信息不足时先澄清再行动”。没有明确目标时,模型往往会退回最通用的语言生成习惯,也就是优先输出一个看起来完整、流畅、像答案的内容,而不是优先推进任务。

约束则告诉模型,哪些事情绝对不能做,或者哪些条件不满足时必须停下来。比如:

  • 不得编造工具调用结果。
  • 未经确认不得执行高风险写操作。
  • 检索不到证据时必须明确说明不确定性。
  • 输出必须符合固定 JSON 结构。

风格则是最次要但仍然有必要的一层。它解决的是表达方式问题,例如“简洁、正式、解释先于结论”“先给结论,再给依据”“引用时保留来源标识”等。风格不能替代目标,也不能替代约束。如果一个系统只写风格,不写行为边界,那么模型通常仍然会在关键时刻做出不可控决策。

工程上,一个很有用的原则是:Prompt 中的内容应该按优先级组织,而不是按作者想到什么就写什么。通常来说,更合理的顺序是:

  1. 角色定义。
  2. 任务目标。
  3. 硬约束。
  4. 行为策略。
  5. 输出格式。
  6. 表达风格。

这个顺序背后的逻辑很简单:先定义“你是谁”和“你要干什么”,再定义“你不能做什么”,然后才是“你通常应该怎么做”和“你最后怎么说出来”。顺序混乱并不一定总会失败,但它会让 Prompt 的维护者也失去结构感,最终演化成难以修改的长文本。

工程提示

当 Prompt 开始失控时,先检查是不是把“表达风格”写得比“任务边界”还重了。

5.3 Few-shot、规则注入与动态 Prompt

System Prompt 只解决了稳定规则的问题,但 Agent 在运行过程中面对的任务和环境是动态变化的,因此 Prompt 通常还需要具备更灵活的装配机制。常见的三种补充方式是 Few-shot、规则注入和动态 Prompt。

Few-shot 的价值在于提供行为示例。与其抽象地说“请先澄清信息不足的情况”,不如给模型一个一问一答样例,让它看到在何种输入下应如何处理。Few-shot 非常适合传达以下类型的信息:

  • 输出格式样例。
  • 工具调用前后的行为模式。
  • 高风险场景下的停机与澄清方式。
  • 某类任务的推理结构偏好。

但 Few-shot 的问题也很明显:示例越多,上下文越长;示例越具体,迁移性越弱;示例质量不高时,模型还会过拟合到错误模式。因此 Few-shot 应该被视为“行为演示”,而不是“样本越多越稳”的堆砌策略。

规则注入则是在 System Prompt 之外,为某类任务或某个运行阶段临时添加控制规则。例如:

  • 进入审批阶段后,禁止写操作。
  • 进入代码修复阶段后,回答必须引用受影响文件。
  • 进入多 Agent 协调阶段后,输出必须为结构化任务分派结果。

这种方式的优势在于,它能把“阶段性规则”从全局 Prompt 中剥离出来,避免系统级规则被局部需求污染。

动态 Prompt 则更进一步,它强调上下文是在运行时根据当前任务、用户、状态和工具环境实时生成的。动态 Prompt 的组成可能包括:

  • 当前任务目标。
  • 本轮上下文摘要。
  • 检索到的知识片段。
  • 已完成动作和中间状态。
  • 当前允许使用的工具描述。
  • 针对本轮的输出要求。

这意味着 Prompt 在 Agent 系统里不是一个固定字符串,而更像一个被程序动态构建的“控制包”。系统设计者真正要做的,不只是写一段好文案,而是设计一个稳定的 Prompt 生成机制。

5.4 Prompt 失效的常见原因

很多团队在做 Agent 时,遇到问题的第一反应是“再调一下 Prompt”。但如果不先识别失效原因,反复加字通常只会让问题更复杂。

Prompt 失效最常见的原因之一,是职责混乱。行为规则、知识内容、临时任务说明和历史状态被无差别堆在一起,模型很难稳定区分哪些是长期约束,哪些只是当前参考信息。

第二个常见原因是上下文竞争。当用户输入、系统规则、工具说明和知识片段同时过长时,模型注意力会被稀释。结果不是它完全没看到某条规则,而是它在权重竞争中没有稳定优先使用那条规则。

第三个原因是规则冲突。例如一边要求“尽量自主完成任务”,另一边又要求“任何不确定时必须先确认”;一边要求“回答简洁”,另一边又要求“给出完整推理过程”。规则不是越多越好,彼此打架的规则只会让系统不可预测。

第四个原因是系统把本应在程序层解决的问题推给了 Prompt。比如希望 Prompt 保证幂等、权限隔离、工具白名单、格式严格校验或长任务恢复。Prompt 可以辅助这些行为,但不能替代系统控制。

第五个原因是示例污染。低质量 Few-shot、过时的历史上下文、错误的记忆片段,都可能让模型学到错误行为。很多人以为 Prompt 问题就是文字问题,实际上它经常是“输入供应链”问题。

面对失效,正确姿势通常不是一味追加文字,而是先定位问题属于哪一层:

  • 是规则没写清,还是写了但被淹没。
  • 是知识缺失,还是知识应该放在检索层而不是 Prompt 里。
  • 是行为约束不够,还是程序层根本没做校验。
  • 是样例有帮助,还是样例本身在制造偏差。

工程提示

多数“Prompt 不稳定”问题,本质上不是文案不够优雅,而是控制层、上下文层和执行层的职责没有分开。

5.5 Prompt 与系统控制的边界

Prompt 很重要,但它不是系统的万能控制器。任何成熟 Agent 架构都必须清楚一个边界:Prompt 负责影响模型行为,程序负责保证系统约束。

例如以下这些事情,不能只靠 Prompt:

  • 工具权限控制。
  • 风险动作审批。
  • 输出格式强校验。
  • 超时、重试和熔断。
  • 幂等处理。
  • 状态持久化与恢复。

Prompt 可以告诉模型“不要这么做”,但真正的系统约束必须能在模型不听话时依然生效。这一点非常关键,因为生产环境里不能把安全和稳定性寄托在“模型大概率会配合”上。

更准确地说,Prompt 更适合处理的是“软控制”:

  • 行为偏好。
  • 推理习惯。
  • 表达规范。
  • 工具使用倾向。
  • 不确定性表述方式。

而程序层更适合处理的是“硬控制”:

  • 白名单与黑名单。
  • 阶段门禁。
  • 结构校验。
  • 权限检查。
  • 执行终止。

只有把软控制和硬控制分开,Prompt 才会真正成为控制层的一部分,而不是被误用成唯一控制手段。

5.6 Prompt 的工程化管理

当 Agent 系统开始增长,Prompt 不再只是某个开发者本地调的一段长文本,而会变成需要被版本化、评测化和模块化管理的工程资产。

首先,Prompt 应该具备版本管理。每一次关键修改都应该能够关联到行为变化和评测结果,否则团队很快就会失去对系统行为演化的认知。

其次,Prompt 应该模块化。全局角色定义、任务模板、工具说明、阶段规则、输出要求和 Few-shot 示例,最好不要混在一个无法拆分的文本块里,而应该被组织成可组合的片段。这样既方便替换,也方便针对不同任务类型进行差异化装配。

再次,Prompt 应该可评测。修改 Prompt 不是写作行为,而是系统行为变更。任何重要改动都应该经过离线样例回归、关键场景对比或人工评审,否则系统就会进入“谁改了谁也说不清效果”的状态。

最后,Prompt 应该可观测。至少要能知道本轮到底给了模型哪些规则、哪些知识片段、哪些工具说明,以及模型最终受哪些因素影响做出了动作选择。看不见实际输入的 Prompt 调试,几乎等于盲修。

从这个意义上说,Prompt Engineering 真正成熟的标志,不是提示词写得多花,而是 Prompt 已经被当成系统配置和行为控制资产来管理。

5.7 本章小结

在 Agent 系统里,Prompt 的价值不在于“让模型更会说话”,而在于它为模型提供了角色定义、行为边界、任务目标和动作策略。Prompt 是控制层的一部分,但它只适合负责软控制,而不适合承担程序级硬约束。

一个成熟的 Prompt 设计,应该明确区分规则、知识、记忆和状态的边界,并通过 System Prompt、Few-shot、规则注入和动态装配共同构成控制协议。只有当 Prompt 被放回系统设计语境中去理解,它才不会沦为“哪里不对就再加一句”的补丁机制。

下一章会继续讨论控制层中的另一个核心问题:当任务开始变复杂时,Agent 究竟应不应该先做规划,以及不同 Planning 机制各自适合什么样的任务。