如何设计 Agent 场景下的 Prompt

很多人在写 Agent 场景下的 Prompt 时,第一反应往往是"继续加":多加几个角色设定,多补几条规则,多写几组示例,最好把模型可能犯的错都提前堵上。

结果呢?Prompt 确实变长了,结构看起来也更"完整"了,但实际效果却未必更好。有时候,模型反而更容易跑偏,输出也更不稳定。

问题并不一定出在"写得不够多",而是很多 Prompt 从一开始就没有被当成一个清晰的任务模板来设计。它们看似内容丰富,实际上目标混杂、边界模糊、层级混乱。模型收到的不是一个明确的任务接口,而是一大段密度很高、重点不清的说明文字。

这也是本文想讨论的问题:在 Agent 场景下,单个 Prompt 模板应该怎么设计,才能更清晰、更稳定、更容易复用。

先说明边界:本文只讨论单个 Prompt 模板,不展开工程化、系统设计、状态管理、评测体系、工作流编排等问题。也就是说,这篇文章关注的不是"如何搭建一个完整的 Agent 系统",而是"如何把 Agent 系统里的某一个 Prompt 写清楚"。


一、一个好的 Prompt 通常包含哪些部分?

如果把 Prompt 当成一句随口发给模型的话,它往往会非常不稳定;但如果把它当成一个任务模板来看,它其实有几个相对明确的组成部分。

一个好的 Prompt,不一定要很长,但通常要把以下几个问题交代清楚:

  • 模型要承担什么职责?
  • 这一次的核心任务是什么?
  • 输入是什么?
  • 应该如何处理输入?
  • 输出应该是什么样?
  • 哪些事情不能做?

这些部分并不是为了让 Prompt 看起来"专业",而是为了减少歧义,让模型更容易理解任务边界。

1. 角色 / 职责

很多人喜欢从"角色设定"开始写 Prompt,比如:

你是一位资深分析师。

你是一位经验丰富的工程师。

你是一位专业、严谨、可靠的顾问。

这类写法不是完全没用。它能帮助模型收敛语气、视角和表达方式。但是在 Agent 场景下,真正重要的通常不是"人设",而是职责

角色的作用,是让模型知道自己应该站在什么视角处理问题;职责的作用,是让模型知道自己到底要完成什么任务。

相比下面这种写法:

你是一位非常专业、逻辑严谨、经验丰富的专家。

更有效的写法往往是:

你的职责是根据用户输入,识别用户的核心意图,并从给定类别中选择最匹配的一项输出。

前者是在营造身份,后者是在限定任务。

再比如,如果你要设计一个客服工单分类 Agent,角色不应该只写成:

你是一名优秀的客服专家。

更清楚的写法是:

你的职责是阅读用户提交的工单内容,判断该工单属于"退款""物流""产品故障""账号问题"还是"其他",并只输出分类结果。

这就比单纯强调"优秀""专业""资深"更有用。

所以,写角色时不要只追求"像不像一个专家",而要优先回答这个问题:这个 Prompt 希望模型承担什么责任?

角色可以帮助收敛风格,职责才真正决定输出质量。

2. 任务目标

Prompt 里必须明确告诉模型:这一次的核心任务是什么。

这一点看似简单,实际上却是很多 Prompt 最容易出问题的地方。因为不少人会在一个 Prompt 里同时塞进多个目标:

  • 既要总结;
  • 又要判断;
  • 又要改写;
  • 又要分类;
  • 最好还能顺手解释原因;
  • 最后还要给出建议。

从人的角度看,这些任务似乎都有关联;但从模型执行的角度看,它会面临一个问题:到底哪个才是最重要的?

一个更好的做法是,让 Prompt 围绕一个清晰的核心任务展开。它可以有附加要求,但主任务必须足够明确。

常见的任务目标包括:

  • 从文本中抽取结构化信息;
  • 根据给定规则进行分类;
  • 判断输入是否满足某个条件;
  • 将已有内容改写成指定风格;
  • 把零散信息重组为固定格式;
  • 根据上下文生成一段回复。

比如,一个用于销售线索识别的 Prompt,核心任务可以是:

判断用户输入是否包含明确的购买意向,并输出意向等级。

它不应该同时承担"总结用户背景""生成销售话术""预测成交概率""补充客户画像"等多个目标。那些任务可以放到其他 Prompt 里处理,而不是全部塞进一个模板里。

任务目标越明确,模型越容易抓住重点;任务目标越发散,模型越容易平均用力,最后哪一项都做得不够稳。

3. 职责与边界

除了告诉模型"要做什么",还要告诉它"不要做什么"。

这一步非常重要。很多 Prompt 的问题并不是目标完全不清楚,而是边界没有定义

比如你让模型"分析用户需求",它可能会顺带补充很多输入中没有的信息;你让模型"生成方案",它可能会把猜测写得像事实;你让模型"整理内容",它可能会主动发挥,加入不必要的扩写。

因此,Prompt 里最好同时包含两层信息:

一层是职责,也就是它必须完成的任务;

另一层是边界,也就是它不能越过的范围。

比如:

  • 只基于输入内容作答,不补充输入之外的事实;
  • 只做信息提取,不做原因猜测;
  • 只输出结果,不展开解释;
  • 无法判断时直接说明信息不足,不强行补全;
  • 不对用户意图做过度推断;
  • 不把可能性写成确定结论。

举个例子,如果你在设计一个"会议纪要提取"Prompt,可以这样定义边界:

你只需要从会议记录中提取明确提到的事项,包括决策、负责人和截止时间。

不要根据上下文猜测未明确出现的负责人。

如果某个事项没有截止时间,输出"未提及"。

这样一来,模型就更不容易把"可能是张三负责"写成"张三负责"。

边界的价值在于,它能减少模型"自作主张"的空间。对单个 Prompt 来说,清晰的边界往往比华丽的角色设定更有用。

4. 输入定义

很多人写 Prompt 时,会花大量精力说明"应该怎么做",却很少说明"你会拿到什么"。

这会导致一个问题:模型理解了任务,却不一定理解自己正在处理什么类型的输入。

输入定义至少要让模型知道几件事:

  • 它会收到哪些输入;
  • 这些输入分别代表什么;
  • 哪些输入是必须的,哪些可能为空;
  • 输入之间是什么关系;
  • 输入格式是什么。

比如,输入到底是:

  • 一段用户对话;
  • 一段网页内容;
  • 一条客服工单;
  • 一组字段集合;
  • 一个用户问题加补充上下文;
  • 还是多轮对话历史加当前用户消息?

这些都应该说明清楚。

例如,一个用于判断用户意图的 Prompt,可以这样定义输入:

你会收到两部分输入:

  1. conversation_history:用户与系统之前的对话记录,可能为空;
  2. current_message:用户当前发送的最新消息,必须存在。

判断用户意图时,应优先依据 current_message;只有当 current_message 信息不足时,才参考 conversation_history。

这段说明解决了一个很关键的问题:模型知道当前消息和历史对话哪个更重要。

如果不说明这一点,模型可能会过度依赖历史记录,也可能只看当前消息,导致判断不一致。

输入定义清楚的本质,是在帮模型建立处理对象的边界。它知道自己面对的是什么,才更容易做出一致的判断。

5. 处理流程

处理流程不是让 Prompt 变成操作手册,而是告诉模型:应该按什么顺序理解和处理输入。

这一部分的关键,不是写得越细越好,而是写得越清楚越好。

很多 Prompt 的"复杂",就复杂在流程部分:步骤列了很多,规则写了很多,判断条件也写得很满。结果模型并没有更聪明,反而被信息淹没了。

一个更合理的处理流程,通常只需要交代清楚几类内容:

  • 先做什么判断;
  • 再处理什么信息;
  • 处理时遵循什么原则;
  • 遇到信息不足怎么办;
  • 遇到不确定时如何表达。

比如,一个信息提取类 Prompt 的处理流程可以是:

  1. 先识别输入中是否包含姓名、手机号、预约时间和服务项目;
  2. 再判断这些字段是否齐全;
  3. 最后按指定结构输出;
  4. 如果字段缺失,则明确标注缺失项,不要自行补全。

这个流程已经足够有效,不需要再把每一步拆成过细的程序式描述。

再比如,一个内容审核类 Prompt 可以这样写:

先判断文本是否涉及违规内容;

再根据规则选择最匹配的风险类型;

如果没有明显风险,输出"通过";

如果无法判断,输出"需要人工复核",不要强行给出结论。

这样的流程短,但重点清楚。

流程的作用是帮助模型抓住任务顺序,而不是让它照着"表演执行"。一旦流程写得太死、太长、太密,模型反而更容易忽略真正的任务重点。

6. 输出要求

Prompt 的输出要求,不能只停留在"请输出 JSON""请按 Markdown 格式输出"这种表层格式上。

真正有价值的输出要求,应该同时说明:

  • 输出包含哪些内容;
  • 输出使用什么结构;
  • 是否允许额外解释;
  • 信息不足时怎么表示;
  • 哪些字段必须出现;
  • 字段值应该使用什么类型或范围。

也就是说,输出要求不仅是"长什么样",也是"在什么情况下如何表达"。

例如,如果输入里某个字段缺失,是输出空值、输出"未知",还是直接说明"信息不足"?这些都应该提前定义。否则模型就会根据自己的理解随意补齐,导致结果不一致。

比如,一个结构化提取 Prompt 可以要求:

json 复制代码
{
  "name": "用户姓名,未提及时输出 null",
  "phone": "手机号,未提及时输出 null",
  "appointment_time": "预约时间,未提及时输出 null",
  "missing_fields": "缺失字段列表"
}

这样模型就知道:缺失信息不是让它去猜,而是要明确标注。

再比如,如果你只希望模型输出分类结果,就要明确说明:

只输出以下类别之一:退款、物流、产品故障、账号问题、其他。 不要输出解释,不要输出额外文本。

这类要求看起来简单,但非常关键。因为在 Agent 场景里,结构化输出往往不是为了"看起来整齐",而是为了让后续环节更容易处理。

即便不谈工程化,清楚的输出要求本身也能显著提升 Prompt 的稳定性和复用性。

7. 约束规则

约束规则是整个 Prompt 的收口部分。

前面讲的是任务是什么、怎么做、输出什么;这一部分讲的是:哪些规则必须遵守,哪些事情绝对不能做。

常见的约束规则包括:

  • 不要编造输入中不存在的信息;
  • 不要输出格式之外的内容;
  • 无法判断时不要强行给结论;
  • 不要遗漏必填字段;
  • 不要把猜测写成事实;
  • 不要因为示例中出现过某种形式,就忽略当前输入的真实内容。

这一部分最好简洁而明确。它不需要太长,但必须清楚。

因为很多模型行为上的不稳定,不是因为它"不会做",而是因为它没有被明确告知"哪些事情不能做"。

从结构上看,一个好的 Prompt 往往不是把所有内容混在一起,而是分层清楚:

先定义职责,再说明任务,再定义输入,再给出处理流程,然后约束输出,最后补充禁止事项。

结构一旦清楚,Prompt 即使不长,也会更稳定。


二、为什么 Prompt 写得越复杂,效果反而越差?

很多人对 Prompt 的直觉是:不够好,就继续加;不够稳,就继续补;模型容易犯错,就把所有注意事项都塞进去。

这个思路在少数情况下可能有帮助,但更多时候会把 Prompt 越写越重,最后出现一种典型现象:看起来更完整了,实际效果却更差了。

Prompt 不是需求文档的堆砌,也不是规则大全。它的目标不是把所有事情都说一遍,而是把最关键的任务信息组织清楚。

一旦结构失衡,复杂度上升,效果反而可能下降。

1. 角色过重,职责不清

最常见的问题之一,就是角色写得很满,职责写得很空。

比如开头先来一大段:

你是一位经验丰富、逻辑严谨、表达清晰、擅长复杂分析、拥有多年行业经验的高级专家......

看起来很完整,实际却没有回答最关键的问题:你这次到底要做什么?

角色过重的问题在于,它会占用大量篇幅去渲染身份,却没有真正收敛任务。

模型可能知道自己应该"像一个专家一样说话",但未必知道当前任务是分类、抽取、判断、总结,还是改写。

在 Agent 场景下,Prompt 最怕的不是没有气质,而是没有任务重心。

角色可以存在,但不能盖过职责。否则模型拿到的是风格提示,而不是任务模板。

2. 目标过多,重点分散

另一个常见问题是,一个 Prompt 同时想做太多事。

比如:

请准确理解用户意图,提取关键信息,进行归纳总结,判断用户需求类型,给出下一步建议,并按固定格式输出。

从人的视角看,这些任务可能彼此相关;但从模型的执行角度看,它会面临一个问题:到底哪个才是第一优先级?

目标过多的结果往往是,模型倾向于做一个平均分配式的回答。每一部分都沾一点,但没有哪部分做得特别稳。

特别是在单个 Prompt 场景下,目标太多几乎一定会带来重点分散。

比如你想判断用户是否有购买意向,那主任务就应该是"判断购买意向"。至于"生成销售回复""提取预算信息""推荐产品方案",这些可以拆成后续步骤,而不是全部压在一个 Prompt 里。

一个好的 Prompt,不是把所有想法都塞进去,而是有意识地克制。

主任务必须突出,其他要求只能为主任务服务,不能把主任务淹没。

3. 输入不清,直接要求执行

还有一类 Prompt,看起来要求很明确,但它默认模型已经知道自己在处理什么输入。

于是上来就开始要求:

  • 请先分析......
  • 请严格判断......
  • 请根据以下规则输出......

问题是,"以下"到底是什么?

输入是原始文本、用户问题、对话记录、字段对象,还是混合上下文?如果这一点没有交代清楚,模型就只能自己猜。

比如,同样是"判断用户意图",下面两种输入完全不同:

用户当前只发了一句话:"这个怎么退?"

和:

用户前面已经说过商品损坏、物流延迟、商家拒绝处理,最后又问:"这个怎么退?"

如果 Prompt 没有说明是否参考历史对话,模型的判断就可能不一致。

输入不清的 Prompt,常常给人一种"指令写得很强"的错觉,但本质上,它是在一个不稳定的输入基础上施加复杂要求。结果自然不会稳。

越是想让模型表现稳定,越要先把输入定义清楚。否则后面的所有处理要求,都会建立在一个模糊前提上。

4. 流程过细,规则过载

有些 Prompt 的思路是:既然模型不稳定,那就把每一步都写给它。

于是流程部分会变成十几条、二十几条,包含大量条件判断、细碎要求和重复提醒。

问题在于,流程过细并不等于流程更清楚。

很多时候,过细的流程只是让 Prompt 的信息密度急剧上升。模型需要同时关注太多局部细节,最后反而抓不住主线。

规则过载也会带来类似问题。

比如:

  • 一方面要求"尽可能详细";
  • 另一方面又要求"保持简洁";
  • 一方面要求"严格依据输入";
  • 另一方面又要求"必要时补充合理信息";
  • 一方面要求"不解释过程";
  • 另一方面又要求"说明判断依据"。

这些规则单独看都似乎有道理,但放在一起就会形成拉扯。

模型会遇到一个很现实的问题:到底该听哪一条?

一个好的 Prompt 流程,应该服务于任务,而不是把自己写成一个难以消化的规则集合。

模型需要的是清晰的优先级,而不是铺天盖地的细节。

5. 约束冲突,层次混乱

Prompt 里最难发现、但非常影响效果的问题,是约束之间的冲突。

这种冲突不一定是显性的。有时它表现为不同部分在说不同的话。

比如:

  • 角色设定鼓励模型"充分发挥专业能力";
  • 边界规则又要求"只基于输入内容作答";
  • 输出要求让模型"补全完整结构";
  • 约束规则又说"信息不足时不要猜测"。

每一条单独看都合理,但组合起来,模型就会遇到一个典型问题:到底该听谁的?

如果 Prompt 没有清晰层次,模型就很难分辨哪些是主规则,哪些是补充规则,哪些应该优先执行。

结果往往不是严格遵守全部要求,而是在不同要求之间做一种不稳定的折中。

所以,复杂 Prompt 的问题往往不只是"长",而是"层次不清"。

信息一旦失去组织,再多的规则都可能互相抵消。

6. 示例堆砌,干扰主任务

示例本来是帮助模型理解任务的,但示例一旦过多,就可能反过来干扰任务本身。

有些 Prompt 会塞很多组输入输出例子,希望模型"多看几个就学会了"。这在某些场景下确实有效,但如果示例太多、风格不一致、边界不统一,模型反而会开始过度模仿示例的表面形式,而忽略真正的规则。

比如,一个分类 Prompt 中给了很多示例,但有的示例输出解释,有的示例只输出类别;有的示例在信息不足时选择"其他",有的示例却强行推断类别。这样一来,示例不但没有增强稳定性,反而制造了新的不确定性。

更常见的问题是,示例把 Prompt 撑得很长。模型在阅读时需要分配更多注意力去理解这些例子,真正属于任务本体的说明反而被弱化了。

示例不是不能用,而是不应该堆砌。

少量、高质量、边界清晰的示例,往往比大量杂乱的示例更有价值。

示例的作用是辅助理解,不是成为 Prompt 的主体。

总的来说,Prompt 写得越复杂,不一定意味着设计得越精密。很多时候,它只是意味着信息开始堆积、边界开始模糊、重点开始分散。

对单个 Prompt 来说,真正重要的从来不是"写得多",而是"写得清楚"。


三、Prompt 不是万能的,Prompt 有哪些局限?

讨论 Prompt 设计时,很容易走向两个极端。

一个极端是把 Prompt 看得太轻,觉得它不过是随便说几句话;另一个极端是把 Prompt 看得太重,仿佛只要写得足够精细,模型就能像程序一样被严格控制。

这两种看法都不准确。

Prompt 确实重要。它会直接影响模型的理解方式、输出形式和行为稳定性。

但 Prompt 同时也有很清晰的能力边界。理解这些局限,反而更有助于我们写出更现实、更有效的 Prompt。

1. 不能保证严格按流程执行

哪怕 Prompt 里已经把步骤写得非常清楚,也不能保证模型每次都严格按流程执行。

根本原因在于,模型不是流程引擎,也不是脚本解释器。它不会像程序那样逐条执行指令,而是在理解整体语境的基础上,生成一个"看起来合理"的回答。

流程性的描述当然会影响它,但这种影响不是绝对控制。

所以,即使你在 Prompt 里写了:

先做 A,再做 B,最后做 C。

模型也可能在某些输入下跳过部分步骤、合并部分步骤,或者在表达时根本不显式体现这个过程。

这并不一定意味着 Prompt 完全失效,而是说明自然语言约束本身就不是强执行机制。

这也是为什么我们应该把 Prompt 理解为"引导行为",而不是"编写程序"。

2. 不能保证输出绝对稳定

很多人优化 Prompt 的目标,是希望同一类输入永远得到同样的输出风格和结构。

这种追求可以理解,但必须承认:Prompt 只能提升一致性,不能保证绝对稳定。

模型的输出本质上具有一定的不确定性。即使 Prompt 没变、输入也非常相似,输出仍然可能在措辞、展开方式、信息组织上存在差异。

有时这种差异很小,只是表达不同;有时则可能影响结果质量。

Prompt 设计可以减少这种波动,比如让输出格式更明确、任务边界更清晰、约束规则更直接。但它无法把模型变成一个完全确定的函数。

对单个 Prompt 来说,追求"更稳"是合理的,追求"绝对不变"通常并不现实。

3. 不能彻底消除幻觉

"不要编造""不要猜测""没有依据就说明不知道"这些规则当然值得写进 Prompt,它们通常也确实能改善结果。

但它们不能从根本上消灭幻觉。

原因很简单:语言模型天生就擅长补全。当信息不充分、上下文有歧义、输入本身不完整时,它很容易生成一个"看起来合理"的内容。

Prompt 可以降低这种倾向,可以让模型更保守,但无法彻底把它变成一个只会机械回显输入的系统。

比如,输入里只写了:

客户说产品坏了,想处理一下。

如果 Prompt 没有严格约束,模型可能会补出"客户要求退款""产品存在质量问题""需要安排售后检测"等内容。可事实上,输入中并没有明确说客户要退款,也没有说明产品一定存在质量问题。

所以,面对幻觉问题时,比较现实的态度不是"用更强的 Prompt 彻底解决它",而是承认 Prompt 只能压低风险,不能彻底消除风险。

一个好的 Prompt 可以让模型在信息不足时更愿意停下来,但不能保证它永远不补全。

4. 不同模型结果会有差异

同一个 Prompt,放在不同模型上,效果很可能不一样。

这一点非常常见,但又常常被低估。

有的模型更擅长遵循格式要求,有的模型更擅长理解复杂指令;有的模型在面对长 Prompt 时更容易抓住重点,有的模型则可能在示例较多时表现更好。

也就是说,Prompt 的效果从来不是脱离模型本身独立存在的。

一个在模型 A 上表现很好的 Prompt,不一定原样放到模型 B 上也同样稳定。

Prompt 设计当然有共通原则,但最终效果仍然会受到模型能力、指令遵循习惯和上下文处理方式的影响。

因此,写 Prompt 时最好不要抱着一种"通吃所有模型"的想法。

更合理的认识是:Prompt 是和具体模型共同构成结果的。二者不是完全可分离的关系。


写在最后

Agent 场景下的 Prompt 设计,说到底不是在比谁写得更长、规则更多、措辞更"专业",而是在比谁能把一个任务讲得更清楚。

一个好的单个 Prompt,通常会把几件事情说明白:

它的职责是什么,任务目标是什么,输入是什么,应该如何处理,输出要长什么样,以及有哪些明确约束。

它不一定很长,但结构清楚;它不一定面面俱到,但重点明确。

反过来,很多看起来很"复杂"的 Prompt 之所以效果不好,并不是因为信息不够,而是因为信息太乱。

角色太重、目标太多、流程太细、规则打架、示例堆砌,这些都会让模型离主任务越来越远。

同时也要承认,Prompt 不是万能的。

它能改善结果,但不能保证绝对正确; 它能提升一致性,但不能消除不确定性; 它能帮助模型更接近预期,但不能把模型变成一个严格可控的程序。

所以,写 Prompt 最重要的能力,不是不断往里加要求,而是不断减少歧义

当一个 Prompt 能够把任务、边界、流程和输出都交代清楚时,它通常就已经比那些堆满规则的大段说明更有价值了。

相关推荐
starrysky8101 小时前
Hermes Gateway重启慢到让人砸键盘:从journalctl到cProfile,三层根因逐层拆解实录
程序员·angular.js
GitCode官方1 小时前
开源鸿蒙跨平台直播|Flutter 鸿蒙化进阶:三方库适配与性能调优实战
flutter·华为·开源·harmonyos·atomgit
码途漫谈1 小时前
Harness:让 Claude Code 先组队,再开工
开源·ai编程
冬奇Lab2 小时前
每日一个开源项目 第124篇:last30days —— 洞察最近30天:跨越信息茧房的 AI Agent 搜索引擎
人工智能·搜索引擎·开源
天丁o2 小时前
开源教程:用飞书长连接把本地 Codex CLI 接入机器人,支持进度心跳和可见过程
机器人·开源·飞书
alwaysrun2 小时前
C++之灵活易用的YAML解析库yaml-cpp
c++·后端·程序员
RuoyiOffice2 小时前
2026 企业定制开发选型:从零开发、低代码、SaaS 与 RuoYi Office 怎么选?
spring boot·uni-app·开源·saas·oa·定制化·ruoyioffice
狗凯之家源码网2 小时前
电商代付系统从零搭建与实战指南
前端·后端·开源
咖啡星人k2 小时前
MonkeyCode 的 CI/CD 实践:开源项目如何做到每2周稳定发布
ci/cd·开源