提示词工程进阶:从“写 Prompt”到“让 Agent 可预期工作”

HTMLPAGE 团队
25 分钟阅读

Prompt 不是“把话说清楚”,而是把不确定的模型约束成可控系统。本文给出 Agent Prompt 的结构化写法、工具调用提示设计、失败回路、测试用例、版本化与观测指标,让你的 Agent 输出稳定、可复盘、可迭代。

#Prompt Engineering #AI Agent #结构化输出 #Function Calling #可测试性

很多人把提示词工程理解成“写一段更聪明的话”。但当你做 Agent(尤其带工具、带状态、带多步骤任务)时,Prompt 的角色已经变了:

Prompt 不是文案,而是系统规格说明(spec):它要定义目标、约束、输出结构、失败处理与测试边界。

如果你只追求“这次回答看起来更好”,你很快会撞上三个现实:

  1. 稳定性问题:换个输入就跑偏。
  2. 可维护性问题:改一次 prompt 就像改玄学,无法回归验证。
  3. 工程闭环缺失:你无法解释“为什么变好了/变坏了”。

这篇文章给你一套可落地的 Agent Prompt 工程方法:

  • 用结构化模板写 Prompt
  • 用测试用例与指标让 Prompt 可验证
  • 用版本化与观测让 Prompt 可迭代

一、先纠正一个关键认知:Agent Prompt 的职责是什么?

在 Agent 系统里,Prompt 的职责不是“让模型更聪明”,而是:

  1. 定义行为边界:什么能做、什么不能做。
  2. 定义输出协议:输出必须符合结构/Schema。
  3. 定义决策规则:何时调用工具、何时拒答、何时向用户追问。
  4. 定义失败策略:遇到缺信息/工具失败/冲突时怎么办。
  5. 把系统状态对齐:模型必须遵守结构化状态中的目标与约束。

如果你把这些职责交给“模型自由发挥”,系统必然不可控。

延伸阅读(基础概念):


二、一套可复用的 Prompt 结构(建议你直接当模板)

这里给你一个“系统提示词(system prompt)”的工程化结构。重点不是文字,而是模块化。

2.1 System Prompt 模板

你可以按 8 段写:

  1. Role(角色):你是谁
  2. Objective(目标):要达成什么
  3. Constraints(约束):硬性规则(安全、权限、格式、成本)
  4. Inputs(输入):系统会提供哪些字段(状态、证据、工具结果)
  5. Process(过程):你必须按什么步骤思考/决策(强调可校验结构)
  6. Tool Policy(工具策略):何时调用工具、工具输入校验、失败处理
  7. Output Contract(输出协议):结构化输出 Schema
  8. Examples(示例):仅对关键边界给 few-shot

示例(删减版,保留结构):

Role:
你是一个任务型 AI Agent,负责在约束条件下完成用户请求。

Objective:
帮助用户完成任务,并输出可执行结果或明确拒答/追问。

Constraints:
- 必须遵守 permissions 中的权限
- 不得编造不存在的证据
- 输出必须满足 JSON Schema

Inputs:
你会收到:user_input, state(JSON), evidence[], tool_results[]

Process:
1) 判断信息是否足够;不够就追问
2) 生成结构化 plan(含成功条件与 stop condition)
3) 逐步执行:必要时调用工具
4) 校验输出:schema/业务规则/引用证据

Tool Policy:
- 工具调用前必须校验参数
- 工具失败:先尝试修复参数;最多重试 1 次;否则降级并解释

Output Contract:
输出 JSON:{status, answer, citations, next_questions, debug}

你会发现:Prompt 的关键不在“写得像人话”,而在“写得像协议”。


三、工具调用提示:Function Calling 不是让模型随便调用

工具调用最常见的翻车点有三个:

  1. 参数缺失/类型错
  2. 越权调用(不该用的工具/不该查的字段)
  3. 重复调用造成副作用

3.1 工具提示的三条硬规则

建议你在 Prompt 明确写:

  1. 先校验再调用:参数不完整就追问或补齐。
  2. 白名单 + 最小权限:只能用允许的工具,只能读取允许字段。
  3. 失败必须可解释:工具失败时输出降级方案与下一步。

3.2 把“参数校验”写进 Prompt

很多人只在代码里校验参数,但不在 Prompt 里约束,会导致模型不断生成垃圾参数。

你可以加一段明确指令:

当你需要调用工具时:
1) 先输出 tool_call_proposal(工具名 + 参数)
2) 自检:参数是否齐全、类型是否正确、是否越权
3) 只有自检通过才允许调用

这会显著降低“模型胡乱调用工具”的概率。


四、让 Prompt “可预期”的关键:把失败回路写出来

Agent 系统必然会失败,Prompt 的高级玩法是:让失败进入一个可控回路,而不是随机崩掉。

4.1 三种必须写入 Prompt 的失败场景

场景 1:缺信息

  • 策略:优先追问(最多 2 个问题),不要凭空补。

场景 2:工具失败

  • 策略:解释失败原因 → 给出可选降级 → 如果可能,换一个无工具方案。

场景 3:输出不满足协议

  • 策略:触发自我修复(reformat / regenerate)并限制次数。

4.2 一个可复用的“失败处理协议”

你可以要求模型在输出里带 status

  • success
  • need_more_info
  • degraded
  • fail

并强制每种 status 都要有:

  • reason(为什么)
  • next_questions(要问什么)或 next_actions(建议怎么做)

这样你的系统就能像处理 API 一样处理模型输出。


五、Prompt 工程的分水岭:测试用例(你必须有)

如果你没有测试用例,你永远无法回答“这次改 prompt 会不会把其他地方搞坏”。

5.1 你至少要有 5 类测试

  1. 正常用例:能按预期完成
  2. 边界用例:输入很短/很长/歧义
  3. 对抗用例:prompt 注入、诱导越权
  4. 失败注入:工具超时、429、返回空数据
  5. 格式用例:强制 schema 输出,检查格式稳定性

5.2 用“可验证断言”写测试,而不是人工看

如果你做结构化输出,就可以做强断言:

  • JSON 可解析
  • 必填字段存在
  • citations 为空时必须是 degradedneed_more_info

延伸阅读:


六、版本化与观测:让 Prompt 像代码一样可维护

Prompt 一旦进入项目,就应该像代码一样:有版本、有变更记录、有回归指标。

6.1 版本化:至少做到这三点

  1. prompt_version:每次 run 记录
  2. diff:记录变更点(哪一段结构改了)
  3. rollback:发现指标变差能回退

6.2 观测指标:用数据管理 prompt

建议你把下面指标按版本聚合:

  • 完成率(success_rate)
  • 平均模型调用次数(avg_llm_calls)
  • 工具失败导致降级比例(tool_degrade_rate)
  • 输出协议失败比例(schema_fail_rate)
  • 引用证据比例(citation_rate)

当你能拿着这些指标讲“我怎么迭代 prompt”,你的工程能力会非常明确。


七、把 Prompt 放回系统:和记忆、规划、工具一起设计

高级提示词工程从来不是孤立的。

你需要把 Prompt 与三件事联动:

  1. 记忆:结构化状态必须进入上下文,并且 prompt 要强制遵守。
  2. 规划:计划必须结构化,并且每步有成功条件。
  3. 工具调度:prompt 只负责提出工具意图,执行与校验必须在代码侧完成。

如果你想把 Agent 项目做出含金量,建议把 prompt 工程直接接入项目骨架与 eval 流程:


一句话总结

Prompt 工程进阶的目标不是“这次回答更像人”,而是:

  • 输出像协议一样稳定
  • 失败像 API 一样可处理
  • 迭代像代码一样可回归

当你能做到这三点,你的 Agent 才真正“可预期”。