logo

提示词工程进阶 (Prompting for Agents)

做普通聊天机器人时,Prompt 写得“顺口”一点通常就够了。但一旦进入 Agent 场景,Prompt 就不只是文案问题了,它更像一份运行说明书。你不是在教模型怎么聊天,而是在约束它怎么判断、怎么调用工具、怎么输出结果。

很多 Agent 不稳定,最后排查下来并不是模型太弱,而是 Prompt 太松。该明确的没明确,该禁止的没禁止,该结构化的还停留在自然语言层面。

[PROMPT_LAB_BANNER]


1. Agent Prompt 和普通 Chat Prompt 不是一回事

普通 Chat Prompt 更关心回答质量,比如解释清不清楚、语气好不好、内容够不够完整。

Agent Prompt 关心的重点不一样,它更在乎:

  • 会不会选对工具
  • 会不会漏步骤
  • 输出能不能被程序稳定解析
  • 遇到边界情况时会不会乱猜

所以两者看起来都叫 Prompt,实际上承担的职责差很多。

维度Chat PromptAgent Prompt
目标生成好答案驱动正确动作和流程
容错空间较高较低
输出要求人能看懂就行人和程序都要能消费
失败后果回答不够好调错工具、走错流程、污染状态

如果是做 Agent,建议你从一开始就把 Prompt 当成“系统接口”的一部分,而不是把它当成补充说明。


2. 先解决一个核心问题:模型到底什么时候该动手

很多 Agent 的不稳定,根源都在这里。

如果 Prompt 太松,模型可能会:

  • 还没想清楚就直接调工具
  • 明明缺信息,却先编一个答案
  • 工具结果出来后,不会根据 observation 调整动作
  • 本来该停下确认,却继续擅自往前做

这也是 ReAct 这类模式一直有生命力的原因。它不是因为名字高级,而是因为它强迫模型把“想”和“做”分开。

ReAct 的价值,不是格式,而是节奏

ReAct 里最有价值的部分,不是 ThoughtAction 这些单词本身,而是它把执行过程拆成了:

  1. 先判断当前信息够不够
  2. 不够就调用工具
  3. 拿到 observation 再决定下一步
  4. 最后再给结论

一个简化后的模板可以是这样:

# Role
你是一个能够使用工具的 AI 助手。

# Tools
- google_search: 搜索互联网信息
- calculator: 进行数学计算

# Rules
- 在信息不足时,不要直接回答
- 每次调用工具前,先说明目的
- 工具结果和原始假设冲突时,以工具结果为准

# Output Format
Question:
Thought:
Action:
Action Input:
Observation:
Final Answer:

这个结构最适合那种“需要边查边做”的任务,比如检索、计算、排错、自动化流程执行。

不过也别机械套模板。不是每个 Agent 都需要把所有 Thought 明文打出来。有些场景只需要内部推理,然后对外暴露结构化动作就够了。


3. 结构化输出不是加分项,是稳定性的底线

如果你的系统后面要接程序逻辑、数据库写入、前端渲染、任务编排,那就不要让模型随意输出“好的,结果如下”这种自由文本。

最稳的思路永远是:

  • 输入分区明确
  • 输出格式固定
  • 程序只信结构,不信语气

XML / 标签分区

把不同类型的信息分开,是很实用的一步。特别是当你要把用户输入、外部文档、系统指令同时塞给模型时,如果不做分区,很容易互相污染。

例如:

<documents>
  <doc id="1">...</doc>
  <doc id="2">...</doc>
</documents>

<instructions>
  只根据 <documents> 中的内容回答。
</instructions>

这种写法的好处,不是“看起来高级”,而是边界更清楚。后面排查 Prompt Injection 或上下文串味时,也更容易定位问题。

JSON 输出

如果下游程序需要解析结果,尽量让模型直接输出 JSON,而不是让后端再从一堆自然语言里抠字段。

例如:

interface Response {
  reasoning: string;
  plan: string[];
  command?: string;
}

然后在 Prompt 里明确要求:

  • 必须返回合法 JSON
  • 不要输出额外解释
  • 字段缺失时返回 null 或空数组,而不是省略

这些细节听起来琐碎,但在实际系统里非常重要。很多“模型偶发出错”,本质上就是协议没写死。


4. Persona 真正的作用,是划清边界

很多人写 Persona 时,喜欢写“你是一个专业、友好、知识渊博的 AI 助手”。这类描述几乎没有工程价值。

对 Agent 来说,一个好的 Persona 更像权限声明,而不是文学设定。

坏例子:

你是一个有帮助的助手。

好一点的例子:

你是一个 Python 安全审查 Agent。你只负责识别安全风险,不负责重构业务逻辑。如果发现 SQL 注入或命令注入风险,必须标记为高危;如果证据不足,明确写出不确定性,不允许臆测。

这种 Persona 的关键在于它回答了几个工程问题:

  • 你负责什么
  • 你不负责什么
  • 什么情况下必须保守
  • 输出应该长什么样

如果这些边界不写清楚,模型会默认自己什么都能做,最后就很容易越权。


5. Prompt 最难的部分,其实是维护

真正上线以后,你会发现 Prompt 工程最痛苦的阶段不是“写出来”,而是“改不坏”。

Agent Prompt 往往会越来越长,因为你会不断往里补:

  • 新规则
  • 新边界情况
  • 新 few-shot 示例
  • 新工具约束

写到后面,如果没有结构,很快就会变成一坨没人敢动的长字符串。

所以我更建议这样维护:

模块化

把 Prompt 拆成几个稳定模块,比如:

  • role
  • context
  • tools
  • rules
  • examples
  • output_format

这样改动时,你知道自己改的是哪一层,而不是每次都重写整段系统提示词。

版本化

Prompt 应该像代码一样进版本控制。改完以后,最好记录:

  • 改了什么规则
  • 为什么改
  • 想修复什么失败案例

否则过几周以后,你很难知道某一条限制到底是不是还能删。

用失败样本反推 Prompt

这是很实用的一条。不要凭感觉加规则,优先看真实失败案例。

例如:

  • 模型老是调用错工具
  • 明明检索不到资料,却硬答
  • 输出 JSON 时夹带解释文字

这时候应该针对失败模式补规则,而不是泛泛地再加一句“请更严谨一点”。后者通常没什么用。


6. 一些在实战里很管用的小原则

下面这些不是理论名词,但在 Agent 项目里经常救命。

把禁止项写明

不要只告诉模型“该做什么”,还要告诉它“绝对不能做什么”。

比如:

  • 不要在证据不足时猜测
  • 不要伪造命令执行结果
  • 不要在未获得确认时执行破坏性操作

禁止项越清楚,系统越稳。

给模型判停条件

有些 Agent 会无限尝试,不停调工具,直到把 token 用完。你要明确告诉它:

  • 什么情况下应该继续
  • 什么情况下应该向用户提问
  • 什么情况下应该停止并报告失败

这比一味强调“尽力完成任务”更有用。

Few-shot 要贴近真实错误

示例当然重要,但别只放那种过于完美的 happy path。真正有价值的示例,通常是:

  • 信息不足时如何拒答
  • 工具失败时如何回退
  • 结果冲突时如何处理

这些更接近真实线上情况。


小结

Agent Prompt 的核心不是“写得漂亮”,而是让模型在复杂流程里不乱来。

如果只记几个重点,我会选这几条:

  1. 先把思考、动作、结果分开。
  2. 让输入输出都尽量结构化。
  3. 把角色边界和禁止项写死。
  4. 用真实失败案例持续修 Prompt。

做到这里,Prompt 才更像系统设计的一部分,而不只是聊天技巧的延伸。

AI Agent 开发实战手册
AI Engineer

AI Agent 开发实战手册

从 0 到 1 掌握 AI Agent 开发:涵盖自主计划、工具调用、MCP 协议与多智能体编排实战。

AI Agent 开发实战手册提示词工程进阶

提示词工程进阶 (Prompting for Agents)

做普通聊天机器人时,Prompt 写得“顺口”一点通常就够了。但一旦进入 Agent 场景,Prompt 就不只是文案问题了,它更像一份运行说明书。你不是在教模型怎么聊天,而是在约束它怎么判断、怎么调用工具、怎么输出结果。

很多 Agent 不稳定,最后排查下来并不是模型太弱,而是 Prompt 太松。该明确的没明确,该禁止的没禁止,该结构化的还停留在自然语言层面。

Prompt Lab

把这章的知识,直接变成实战能力

进入交互式实验室,用真实任务练 Prompt,10 分钟快速上手。

进入 Prompt Lab →

#1. Agent Prompt 和普通 Chat Prompt 不是一回事

普通 Chat Prompt 更关心回答质量,比如解释清不清楚、语气好不好、内容够不够完整。

Agent Prompt 关心的重点不一样,它更在乎:

  • 会不会选对工具
  • 会不会漏步骤
  • 输出能不能被程序稳定解析
  • 遇到边界情况时会不会乱猜

所以两者看起来都叫 Prompt,实际上承担的职责差很多。

维度Chat PromptAgent Prompt
目标生成好答案驱动正确动作和流程
容错空间较高较低
输出要求人能看懂就行人和程序都要能消费
失败后果回答不够好调错工具、走错流程、污染状态

如果是做 Agent,建议你从一开始就把 Prompt 当成“系统接口”的一部分,而不是把它当成补充说明。


#2. 先解决一个核心问题:模型到底什么时候该动手

很多 Agent 的不稳定,根源都在这里。

如果 Prompt 太松,模型可能会:

  • 还没想清楚就直接调工具
  • 明明缺信息,却先编一个答案
  • 工具结果出来后,不会根据 observation 调整动作
  • 本来该停下确认,却继续擅自往前做

这也是 ReAct 这类模式一直有生命力的原因。它不是因为名字高级,而是因为它强迫模型把“想”和“做”分开。

#ReAct 的价值,不是格式,而是节奏

ReAct 里最有价值的部分,不是 ThoughtAction 这些单词本身,而是它把执行过程拆成了:

  1. 先判断当前信息够不够
  2. 不够就调用工具
  3. 拿到 observation 再决定下一步
  4. 最后再给结论

一个简化后的模板可以是这样:

markdown
# Role 你是一个能够使用工具的 AI 助手。 # Tools - google_search: 搜索互联网信息 - calculator: 进行数学计算 # Rules - 在信息不足时,不要直接回答 - 每次调用工具前,先说明目的 - 工具结果和原始假设冲突时,以工具结果为准 # Output Format Question: Thought: Action: Action Input: Observation: Final Answer:

这个结构最适合那种“需要边查边做”的任务,比如检索、计算、排错、自动化流程执行。

不过也别机械套模板。不是每个 Agent 都需要把所有 Thought 明文打出来。有些场景只需要内部推理,然后对外暴露结构化动作就够了。


#3. 结构化输出不是加分项,是稳定性的底线

如果你的系统后面要接程序逻辑、数据库写入、前端渲染、任务编排,那就不要让模型随意输出“好的,结果如下”这种自由文本。

最稳的思路永远是:

  • 输入分区明确
  • 输出格式固定
  • 程序只信结构,不信语气

#XML / 标签分区

把不同类型的信息分开,是很实用的一步。特别是当你要把用户输入、外部文档、系统指令同时塞给模型时,如果不做分区,很容易互相污染。

例如:

xml
<documents> <doc id="1">...</doc> <doc id="2">...</doc> </documents> <instructions> 只根据 <documents> 中的内容回答。 </instructions>

这种写法的好处,不是“看起来高级”,而是边界更清楚。后面排查 Prompt Injection 或上下文串味时,也更容易定位问题。

#JSON 输出

如果下游程序需要解析结果,尽量让模型直接输出 JSON,而不是让后端再从一堆自然语言里抠字段。

例如:

typescript
interface Response { reasoning: string; plan: string[]; command?: string; }

然后在 Prompt 里明确要求:

  • 必须返回合法 JSON
  • 不要输出额外解释
  • 字段缺失时返回 null 或空数组,而不是省略

这些细节听起来琐碎,但在实际系统里非常重要。很多“模型偶发出错”,本质上就是协议没写死。


#4. Persona 真正的作用,是划清边界

很多人写 Persona 时,喜欢写“你是一个专业、友好、知识渊博的 AI 助手”。这类描述几乎没有工程价值。

对 Agent 来说,一个好的 Persona 更像权限声明,而不是文学设定。

坏例子:

你是一个有帮助的助手。

好一点的例子:

你是一个 Python 安全审查 Agent。你只负责识别安全风险,不负责重构业务逻辑。如果发现 SQL 注入或命令注入风险,必须标记为高危;如果证据不足,明确写出不确定性,不允许臆测。

这种 Persona 的关键在于它回答了几个工程问题:

  • 你负责什么
  • 你不负责什么
  • 什么情况下必须保守
  • 输出应该长什么样

如果这些边界不写清楚,模型会默认自己什么都能做,最后就很容易越权。


#5. Prompt 最难的部分,其实是维护

真正上线以后,你会发现 Prompt 工程最痛苦的阶段不是“写出来”,而是“改不坏”。

Agent Prompt 往往会越来越长,因为你会不断往里补:

  • 新规则
  • 新边界情况
  • 新 few-shot 示例
  • 新工具约束

写到后面,如果没有结构,很快就会变成一坨没人敢动的长字符串。

所以我更建议这样维护:

#模块化

把 Prompt 拆成几个稳定模块,比如:

  • role
  • context
  • tools
  • rules
  • examples
  • output_format

这样改动时,你知道自己改的是哪一层,而不是每次都重写整段系统提示词。

#版本化

Prompt 应该像代码一样进版本控制。改完以后,最好记录:

  • 改了什么规则
  • 为什么改
  • 想修复什么失败案例

否则过几周以后,你很难知道某一条限制到底是不是还能删。

#用失败样本反推 Prompt

这是很实用的一条。不要凭感觉加规则,优先看真实失败案例。

例如:

  • 模型老是调用错工具
  • 明明检索不到资料,却硬答
  • 输出 JSON 时夹带解释文字

这时候应该针对失败模式补规则,而不是泛泛地再加一句“请更严谨一点”。后者通常没什么用。


#6. 一些在实战里很管用的小原则

下面这些不是理论名词,但在 Agent 项目里经常救命。

#把禁止项写明

不要只告诉模型“该做什么”,还要告诉它“绝对不能做什么”。

比如:

  • 不要在证据不足时猜测
  • 不要伪造命令执行结果
  • 不要在未获得确认时执行破坏性操作

禁止项越清楚,系统越稳。

#给模型判停条件

有些 Agent 会无限尝试,不停调工具,直到把 token 用完。你要明确告诉它:

  • 什么情况下应该继续
  • 什么情况下应该向用户提问
  • 什么情况下应该停止并报告失败

这比一味强调“尽力完成任务”更有用。

#Few-shot 要贴近真实错误

示例当然重要,但别只放那种过于完美的 happy path。真正有价值的示例,通常是:

  • 信息不足时如何拒答
  • 工具失败时如何回退
  • 结果冲突时如何处理

这些更接近真实线上情况。


#小结

Agent Prompt 的核心不是“写得漂亮”,而是让模型在复杂流程里不乱来。

如果只记几个重点,我会选这几条:

  1. 先把思考、动作、结果分开。
  2. 让输入输出都尽量结构化。
  3. 把角色边界和禁止项写死。
  4. 用真实失败案例持续修 Prompt。

做到这里,Prompt 才更像系统设计的一部分,而不只是聊天技巧的延伸。

常见问题

开发 AI Agent 需要掌握哪些编程语言?
首选 Python 或 TypeScript。Python 是 AI 生态的基石,而 TypeScript 在开发 MCP Server 和网页端交互时效率极高。借助 Cursor 等 AI 原生编辑器,编程门槛已大幅降低。
MCP 协议目前支持哪些模型?
MCP 是开放协议,目前对 Claude 3.5 系列支持最完美。通过 MCP Proxy,GPT-4o 和 Gemini 也可以间接访问 MCP Server 数据源。
AI Agent 会导致程序员失业吗?
不会,但会改变程序员的工作内容。未来的开发者将从“写代码”转向“管理 Agent 团队”,重点在于系统架构设计、复杂逻辑校验和 Agent 的提示词优化。