Skip to content

提示词优化:应该如何写好 Agent 的 Prompt?

已经对于 Agent 有了一些了解,那么面临的下一个问题,也是最显而易见的问题是:提示词(System Prompt)要如何写?同时我们要怎么去优化它?

这篇文章的标题可能有一点“危言耸听”。坦白说,我至今也不知道要如何才能把一个 Prompt 写得完美。但在 Agent 出现的短短时间里,业界通过大量试错,确实沉淀出了一些能落地的最佳实践。

在这篇笔记里,我尝试总结一下 Agent 提示词的“核心骨架”和一些避坑指南。

1. 核心澄清:是谁决定了 Agent 的“模式”?

Section titled “1. 核心澄清:是谁决定了 Agent 的“模式”?”

在正式开始写 Prompt 之前,我必须先澄清一个在开发中非常关键的概念。

我们可能听说过 工作流 (Workflow)、单智能体 (Single Agent) 和 多智能体 (Multi-Agent)。很多初学者以为,只要我在 Prompt 里写一句“你是一个自主智能体”,LLM 就会自动变成 Agent。

Agent 的模式,实际上是由宿主程序(Host Program)的代码逻辑决定的,而不是 Prompt 决定的。

  • Workflow:宿主代码写的是 Step A -> Step B -> Step C 的线性逻辑。
  • Agent:宿主代码写的是一个 While (True) 的死循环,把控制权交给 LLM。
  • Multi-Agent:宿主代码写的是一个复杂的状态机 (State Machine) 或路由逻辑。

这就是为什么我们在 Dify 或 Coze (扣子) 新建项目时,平台强制要求你先选择应用类型(是“聊天助手”还是“工作流”)。

  • 当你选了“工作流”,平台就在后台生成了一套线性的代码骨架,你的 Prompt 只需要关注每个节点的具体任务。
  • 当你选了“Agent”,平台才会在后台启动那个关键的循环引擎 (Loop),此时你的 Prompt 才需要包含“思考-行动”的 ReAct 逻辑。

结论:架构决定 Prompt。 只有在宿主代码提供了“循环”和“工具调用能力”的前提下,下面讨论的 Agent Prompt 结构才有意义。


在开始写结构之前,先聊聊格式。

目前主流的提示词格式其实是 Markdown(使用 # 号分级)。

  • 优点:结构清晰,可读性强,且对 GPT-4、DeepSeek、Llama 等主流模型非常友好。
  • 注:如果你使用的是 Claude 系列模型,或者需要处理极长的上下文(防止模型把指令和数据搞混),使用 XML 标签(如 <role>, <context>)通常效果更好。

但在大多数通用场景下,Markdown 足矣。

一个鲁棒的 Agent System Prompt,通常可以拆解为以下 6 个核心模块:

不仅要定义“你是谁”,更要定义 “你的目标是什么”。

  • 边界清晰:你是什么领域的专家?资深程度如何?
  • 风格设定:你的说话方式是严谨的、幽默的,还是简洁的?

3.2 宪法/约束定义 (Constitution & Constraints)

Section titled “3.2 宪法/约束定义 (Constitution & Constraints)”

这就像是机器人的“底层法则”。告诉它 **“绝对不能做”**的事情。

  • 安全边界:例如“禁止删除数据库”、“禁止输出用户隐私”。
  • 技术边界:例如“只使用 Python 3.10 语法”、“只生成 JSON 格式”。

显式地告诉 LLM,有哪些工具(Tools)可以调用,以及调用的协议格式。

  • 注意:在实际开发中,这部分通常是一个动态变量。由 Agent 程序(如 MCP Client)自动把工具的 JSON Schema 转换成文本,注入到 Prompt 里,不需要手动写死。

这是 Agent 的灵魂。你需要强制模型遵守某种思考框架,比如 ReAct (Reason + Act)。

  • 循环指令:明确告诉它,在回答之前必须经历:思考 (Thinking) -> 行动 (Action) -> 观察 (Observation) -> 反思 (Reflection) 的循环。
  • 禁止跳步:强调“在没有观察到工具结果之前,不要编造答案”。

3.5 输出格式与结束条件 (Output & Finish Criteria)

Section titled “3.5 输出格式与结束条件 (Output & Finish Criteria)”

告诉 Agent 如何“交卷”。

  • 结束标志:如何确定任务完成了?(例如:当收集到所有信息后,调用 finish 工具)。
  • 格式要求:最终输出是 Markdown 报表,还是纯 JSON 数据?还要评估 LLM 的输出是否符合预期。

这是动态注入的部分,相当于 Agent 的“短期记忆”。

  • 内容:当前时间、用户信息、之前的对话历史(History)。
  • 来源:通常由 Memory 模块管理,在每次 API 调用前动态拼接在 System Prompt 的末尾。

4. 一个标准的 Prompt 模板 (Markdown 版)

Section titled “4. 一个标准的 Prompt 模板 (Markdown 版)”

把上面的结构拼起来,大概长这样:

# Role
你是一个资深的数据分析 Agent。你的目标是帮助用户查询数据库,分析数据趋势,并生成可视化的报告。
# Constraints
- 禁止伪造数据,所有数据必须来自数据库查询。
- 在执行高危操作(如 DELETE, DROP)前,必须先获得用户的显式批准。
- 如果工具报错,不要立刻放弃,尝试分析错误原因并修正参数后重试。
# Tools
你拥有以下工具。在调用前,请务必阅读工具的参数说明:
1. `query_database`: 执行 SQL 查询。
2. `generate_chart`: 根据数据生成图表。
# Reasoning Protocol
在回答用户问题时,请严格遵守以下 "ReAct" 流程:
1. **Thinking**: 分析用户意图,决定下一步行动。
2. **Action**: 生成工具调用指令(JSON)。
3. **Observation**: 观察工具返回的结果。
4. **Reflection**: 反思结果是否解决了问题,如果没有,重复步骤 1。
# Output Format
请按照以下格式输出你的思考过程:
- **Thought**: [你的思考]
- **Command**: [工具调用代码]
- **Final Answer**: [最终给用户的回复]

5. 优化 Agent Prompt 的 5 个实战建议

Section titled “5. 优化 Agent Prompt 的 5 个实战建议”

关于 Function Call 的描述(Description),需要像写法律条文一样精确。

  • 不仅要描述工具的作用,更要详细描述输入参数的格式(比如日期是 ‘YYYY-MM-DD’)和边界情况(如果查不到返回什么)。

Agent 最容易挂的地方就是工具报错。

  • 需要在 Prompt 里明确:“如果工具调用失败,或者结果为空,请不要直接把报错扔给用户。”
  • 处理逻辑:要求它分析错误原因,尝试修改参数(Self-Correction),或者换一个工具重试。

你告诉它“不要做 X”,它反而容易关注到 X。

  • Bad:不要使用复杂的 SQL。
  • Good:请仅使用基础的 SELECT 和 WHERE 语句。

5.4 使用动态提示词 (Dynamic Prompting)

Section titled “5.4 使用动态提示词 (Dynamic Prompting)”

不要把 Prompt 写成死字符串。在 PydanticAI 或 LangChain 中,Prompt 本质上就是一个 Python 的 f-string。

  • 利用这一点,根据用户的不同属性(如{user_role})或当前场景,动态拼装不同的 Prompt,让 Agent 显得更有“情商”。

5.5 善用少样本提示 (Few-Shot Prompting)

Section titled “5.5 善用少样本提示 (Few-Shot Prompting)”

如果你的指令很复杂,给它一个例子(Example)胜过说一千句废话。

  • 在 Prompt 里直接给出一个 <example>:
    • User: “查下天气”
    • Thought: “用户想查天气,我需要调用 get_weather…”
    • Tool: get_weather(“Beijing”)
  • 这能极大地提高 Agent 遵循复杂逻辑的成功率。

5.6 进阶心法:上下文工程 (Context Engineering)

Section titled “5.6 进阶心法:上下文工程 (Context Engineering)”

最近看到关于 CLAUDE.md 的最佳实践,让我意识到 Prompt 优化不仅仅是写好指令,更是管理好上下文。

  • 渐进式披露 (Progressive Disclosure):不要试图把几万字的开发文档一次性塞进 Prompt。更好的做法是给 Agent 一份 “索引列表”(比如:docs/api.md - API 接口说明),让 Agent 在需要时自己决定去读取哪个文件。
  • 少即是多:有研究表明,即便是最强的模型,能稳定遵循的指令上限也就是 150-200 条。所以,保持 Prompt 简练(建议控制在 60 行以内),只保留最核心的业务逻辑。

不要在 Prompt 里写诸如“代码末尾必须加分号”、“使用单引号”这种格式规范。

  • 原因:这会浪费宝贵的上下文窗口,且分散模型的注意力。
  • 解法:这种确定性的工作,应该交给外部工具(如 Linter、Formatters)在代码生成后自动处理。让 AI 专注逻辑,让工具专注规范。

总结

写 Agent 的 Prompt,其实就是在用自然语言编写 “业务逻辑”。它像是一份写给 AI 看的、逻辑严密的员工手册。而这份手册能否生效,前提是你选择了一个正确的“宿主程序架构”(Dify/Coze 里的应用类型)。