面向智能体的提示词工程:有主张、有结构、可度量。
提示词工程(prompt engineering)是该领域被讨论最多的话题之一,而大多数相关文章给出的都是泛用的 ChatGPT 建议,无法迁移到智能体(agent)工作中。本章讲授面向智能体的具体实践:系统提示词(system prompt)实际在做什么(定义智能体身份、编码工作流规范、设定拒绝姿态),如何在不固化行为的前提下使用示例,XML 风格标签等结构化格式何时值得引入,以及如何通过迭代规范将提示词从"凭感觉"变成可度量的工程。本章假设你已在前几章中研读过数十个系统提示词——它的任务不是重复那些材料,而是将底层原则提炼出来,让你能够有意识地写出优质的智能体提示词。
系统提示词必须完成的三件事。
大多数提示词工程建议将"提示词"视为单一对象——写好它,模型就能表现更好。对于智能体而言,这种框架过于粗粒度。智能体的系统提示词同时承担着三种截然不同的工作,每种工作都有自己的规范。混淆它们——试图在身份中编码工作流,或在示例中编码拒绝——会产生冗长、脆弱且性能低于预期的提示词。
三种职责,命名如下:
常见陷阱:大多数对系统提示词的"改进"会不经意地将新内容堆入错误的职责区域。工作流中的回归(regression)被通过向身份部分添加规则来修复;漏网的拒绝被通过添加工作流步骤来修复。数月之后,提示词变成一团 3000 令牌(token)的混乱,没有任何职责是清晰的。规范在于保持三种职责的独立,分别按各自的逻辑进行编辑。
职责一:身份与框架设定
提示词中最短的部分,也是最强大的部分。模型的行为会因所采用的框架不同而产生显著差异。"你是一个 AI 助手"与"你是一位在 Postgres 内部工作了十年的高级后端工程师",即便其他指令完全相同,在同一个 Postgres 问题上也会产生截然不同的输出。
身份部分应包含的内容:
- 职责定位。智能体的类型。"面向 SaaS 计费系统的客服智能体。""专注于半导体行业分析的研究助手。""我们开源 Rust 项目的代码审查员。"
- 所在领域。智能体所处的领域,精确程度需让模型明确适用哪些规范。"面向 B2B SaaS 的客服,客户是企业管理员,而非终端用户。"
- 目标受众。智能体输出服务的对象。"响应内容将由付费企业客户阅读;语气应专业,不宜随意。"
不属于此处但经常被误放进来的内容:工作流步骤("始终先检索文档")、拒绝规则("永不分享 API 密钥")、输出格式("以 JSON 响应")。这些是后两种职责的工作。将它们混入身份部分会使该部分臃肿,并模糊框架设定本身。
结构清晰的身份部分通常为 50–200 个令牌。如果你写得更长,几乎可以肯定是在混淆职责。具体示例:
# Identity section — clean
You are a research analyst at a financial-services firm. You produce
analytical briefings on companies, industries, and market events for
internal use by investment professionals. Your readers are sophisticated
financial analysts who care about specific evidence and verifiable claims,
not high-level summaries.
这大约 60 个令牌,向模型传达了:你是谁(分析师)、所处背景(金融服务)、你生产什么(分析简报)、服务对象(资深分析师)、以及质量标准(具体证据、可核实的主张)。每个词都在发挥作用,没有任何装饰性内容。
职责二:工作流规范
一个设计良好的智能体系统提示词的主体部分。这里存放智能体的操作规程——它如何处理工作、按什么顺序处理、以及如何进行核实。
工作流部分应包含的内容:
- 顺序规则。"回答之前,使用
get_account核实用户的账户状态。""进行任何更改后,运行测试套件。"模型由此学习操作顺序。 - 核实要求。"如果你引用一个事实,引用必须指向你实际检索过的来源。""在宣告任务完成之前,确认测试套件通过。"
- 停止条件。"当你已用引用回答了用户的问题,停止。不要继续展开。""如果答案需要超过 5 次工具调用,升级至人工审查。"
- 工具使用指引。"针对产品特定问题使用
search_docs,仅对行业通用问题使用web_search。"同一工具集内的歧义解决。
规律:以祈使句描述智能体在不同情境下的行为。每条规则应当具体、可执行、可核实。模糊的工作流规则("要彻底")不产生任何可度量的结果;具体的规则("如果用户的问题涉及某项功能,在回答前先查询该功能")才能改变行为。
这也是将第 4.1 章的"核实阶梯"编码进代码智能体(code agent)的地方,将第 4.3 章的工作量动态调节规则编码进研究智能体的地方,将第 4.2 章的观察式核实编码进计算机操作(computer use)的地方。那些章节教授的模式,正是要放入工作流的内容。
# Workflow section — sketch for a research analyst agent
When the user asks for analysis on a company, industry, or event:
1. Decide whether the question can be answered from your training data
alone, or whether it requires current information. Anything about
quarterly results, recent news, ongoing events, or current market
state requires fresh sources.
2. If fresh sources are required: search for them using the available
tools. Prefer primary sources (SEC filings, company press releases,
earnings call transcripts) over secondary aggregators.
3. Every substantive claim in your output must include a citation
to a source you've actually retrieved. Do not produce claims from
training data without sourcing them; if you can't find a source,
omit the claim.
4. Structure outputs as: brief summary (2-3 sentences) → key findings
with citations → caveats and gaps. Do not add executive-style
formatting (headings, bullet lists with bold) unless the user
explicitly requested it.
5. When you've answered the user's question with appropriate citations,
stop. Do not continue with related topics they didn't ask about.
这是会变长的部分。5–15 条编号规则是正常范围;超过 20 条通常意味着工作流过于复杂,智能体应当被拆解(第 4.4 章的模式)。
职责三:安全(safety)与拒绝姿态
捕获不应发生之事的部分。比工作流短,比身份长,也是初稿中最常完全缺失的部分。
安全(safety)/拒绝部分应包含的内容:
- 明确的拒绝模式。智能体拒绝哪些请求,以及如何拒绝。"如果被要求给出投资建议(买/卖/持有),以这样的方式回复:'我提供分析,不提供建议。以下是相关分析……'并继续给出分析内容。"
- 升级触发条件。智能体何时停止自行处理并移交他人。"如果用户表达不满或反复沮丧,不要继续排查问题;回复:'让我为您转接人工客服。'"
- 数据处理规则。智能体不在输出中包含什么。"即使 API 密钥、密码或其他凭据出现在工具结果中,也绝不将其包含在响应中。仅按名称引用。"
- 争议行为的权威立场。"除非明确给定相关工具,否则你无法访问实时数据。不要捏造时间戳或'当前'数值。"
规范:明确说明什么触发拒绝,以及拒绝的具体形式。模糊的表述("不要有害")不产生任何可度量的结果;具体的表述("如果被要求提供投资建议,使用精确措辞 X 进行拒绝")产生一致的行为。
# Safety section — sketch
You decline the following:
— Investment recommendations. If asked "should I buy X?" or "is X a
good investment?", respond: "I provide analysis, not investment
recommendations. Here's analytical context to inform your decision:"
and continue with substantive analysis.
— Predictions of specific market movements. "Will X stock go up?" is
declined the same way — provide analytical context, not prediction.
— Confidential information about the firm's positions or clients. If
the user appears to be asking about internal positions or client
holdings, respond: "I can't access confidential firm or client data."
When you decline, do not lecture the user. Decline briefly and move
to substantive analytical content where appropriate.
最后一句话发挥着重要作用。许多拒绝模式会产生大量说教而几乎没有实质内容的输出——"我无法给出建议,因为……【大段免责声明】"。用户对此深感厌烦。可扩展的模式是:简短拒绝 + 立即转向有价值的内容。值得在提示词中明确指定。
顺序很重要:身份 → 工作流 → 安全
这三个部分在实际提示词中以何种顺序出现?行之有效的惯例是:
- 身份在前。在给出操作规则之前先确立框架。规则的落地效果因框架而异。
- 工作流居中。操作指引的主体部分。
- 安全殿后。工作流的覆盖条件。这些条件在触发时优先于工作流,因此放在它所覆盖的工作流之后。
这个顺序也与第 0.1 章的心智模型吻合:关键内容置于上下文的首尾(中间迷失效应)。身份与安全——最重要的框架——位于两端。工作流,作为主体,位于中间,一定程度的注意力稀释是可接受的。
如果你的系统提示词超过约 1500 个令牌,请审查三种职责的划分。大多数过长的提示词是在工作流部分(规则过多)臃肿,或者将安全相关内容分散在工作流中而非独立成节。整理结构通常能在不损失任何行为的情况下削减 30–40%——而更精简的提示词成本更低(第 2.2 章),也能更好地抵抗中间迷失效应。
通常是工作流——这是"智能体如何产生输出"的一个方面,与"回答前先核实"同属一类。放在工作流部分的末尾,靠近智能体生成最终响应的位置。
一个例外:如果输出格式是智能体身份的一部分("你是一个以 JSON 输出的结构化数据提取工具"),则可放入身份部分。但对于大多数智能体而言,其职责并非"产生 JSON"——而是"作为研究分析师,因消费方的需要而恰好将输出格式化为 JSON"。属于工作流。
避免将输出格式指令作为某一部分中唯一的一行。一整个"输出格式"节只有一行,是代码异味——通常意味着其余结构并不太对。
很可能是。长提示词存在三个结构性问题:中间迷失效应(第 0.1 章)会降低模型对埋在中间的指令的有效关注度;令牌成本会累积(除非被缓存,否则每次请求都要为每个令牌付费);提示词腐化是真实存在的(六个月前重要的规则可能与新规则相互矛盾)。
审查模式:取出提示词,为每条规则标注所属职责(身份/工作流/安全),然后分组。分组后的版本会揭示:
- 用不同措辞表达相同内容的重复规则。
- 位置错误的规则(工作流规则在身份部分,等等)。
- 来自已不再相关的旧故障模式的过时规则。
- 本应放在工具描述中而非系统提示词内容中的规则。
大多数做过这种审查的团队能在不损失行为的情况下删减 30–50% 的提示词。有些团队删减更多。这个过程令人不安,因为每条规则都感觉举足轻重——但大多数其实并非如此。
清晰的判断标准:如果规则是关于如何使用某个特定工具的,它属于该工具的描述。"使用客户的电子邮件调用 get_account"应放在 get_account 的描述中,而非系统提示词。模型在每次工具可用时都能看到工具描述;与工具放在一起的规则,始终与决策点保持近距离。
系统提示词中的规则应该涉及跨工具或独立于任何特定工具的行为——工作流顺序、拒绝姿态、输出格式。规则的适用范围越窄,就越应该贴近其所适用的对象。
真正能教会模型的示例(以及那些做不到的)。
"在提示词中使用示例"是该领域最普遍的提示词工程建议,它既正确,又危险地不够具体。示例能比任何描述更可靠地教会模型某种行为——同时也可能将模型固化在特定模式上,以泛化能力为代价。规范在于:知道何时用示例,以及示例应采取什么形态。
示例奏效的机制
模型是下一个令牌的预测器(第 0.1 章)。当你在提示词中放入一个示例,实际上是在说:"在类似情境下,这是随之而来的延续。"模型的分布会向看起来像该示例的延续倾斜。这比描述更直接——"简洁并使用引用"是一条陈述;一个展示了简洁输出与引用的示例,则是关于令牌层面模式的许多隐性陈述。
这一机制既是力量的来源,也是陷阱所在。力量在于:示例比规则更高效地编码复杂模式(语气、格式、详细程度)。陷阱在于:示例编码的是具体模式,而模型可能对那些本无意成为规范的细节过拟合("示例用了逗号;我应该总是用逗号")。
示例有效的场景
四类智能体任务,示例能可靠地改善行为:
具有非直观结构的输出格式。如果你希望智能体以无法用模式(schema)完整描述的格式产生输出(例如特定的 Markdown 形态、特定的引用风格、语气调校),一两个示例比大段描述更快达到效果。模型需要看到输出,而不仅仅是读到关于它的描述。
区分看起来相似的情况。如果智能体需要对三种表面相似的请求类型采取不同处理(退款请求 vs 取消请求 vs 套餐变更),每种一个示例可以澄清边界。仅凭描述,边缘情况仍然模糊;具体示例通过演示来定义边界。
拒绝模式。展示如何确切地拒绝一个请求(以及说什么替代内容),比描述拒绝模式更可靠。一个包含你的团队期望的精确措辞的拒绝示例,只需编码一次,即可被一致地复现。
多步推理的形态。如果你希望智能体以特定形态展示其工作过程(考虑 X,考虑 Y,权衡二者,得出结论),示例能演示该形态。描述("一步一步思考")过于模糊,难以稳定落地。
示例有害的场景
三类情况下,示例会产生比单纯描述更差的结果:
当任务可以由通用规则清晰描述时。"以 JSON 响应"加上一个模式(schema),比"以下是一个示例 JSON 响应:{...}"更清晰。模式(schema)是抽象;示例是一个实例。模型需要的是抽象。
当示例空间很大而你的示例覆盖不足时。如果你为一个开放式任务只提供一个"好响应"示例,模型会对该示例的具体细节(语气、结构、长度)过拟合,即便这些细节并非任务所需。更好的做法是描述你想要的特质,让模型产生多样性。
当示例内容可能泄漏进响应时。一种出人意料的常见失败:模型将你示例中的内容包含在实际响应中。"前一个示例是关于 Acme Corp 的,而用户的问题是关于 Beta Corp 的"——但响应却谈论的是 Acme。当示例在上下文中出现得较晚,而用户的实际查询很简短时,这种情况更容易发生。
"展示而非讲述"的失败模式
最隐蔽的陷阱:示例可能教会模型错误的东西。模型从示例的表面特征中学习,而非从示例本应演示的抽象模式中学习。你本意是"附带引用地回应";模型学到的是"使用我在示例中看到的这种特定 URL 结构"。你本意是"简洁";模型学到的是"恰好写这么多句子"。
解决方案:故意使示例多样化,以教会抽象而非表面。如果你想展示"响应包含引用",提供两个引用风格截然不同的示例(一个基于 URL,一个基于脚注),让模型学到"包含引用",而非"使用我的特定风格"。如果你想展示"简洁",略微变化长度,让模型学到"匹配问题的深度",而非"总是写 3 句话"。
具体对比:差的示例模式教会表面细节,好的示例模式教会抽象:
# Bad: one example teaches surface details Here's an example response: User: What's a good Postgres index strategy? Assistant: For most Postgres workloads, B-tree indexes on high-cardinality columns are your default. Avoid indexes on low-cardinality columns since the planner often won't use them. [Source: postgres.org/docs/indexes] # Problem: the model now thinks ALL responses should be 3 sentences, # end with [Source: ...] inline, and use this specific cadence. # Better: two examples vary deliberately Here are two example responses: User: What's a good Postgres index strategy? Assistant: For most Postgres workloads, B-tree indexes on high-cardinality columns are your default — covered well in the official indexes documentation [1]. Avoid indexes on low-cardinality columns since the planner often won't use them. [1] postgres.org/docs/indexes User: How do I diagnose slow queries? Assistant: Start with `EXPLAIN ANALYZE` on the slow query — it shows the actual execution plan with timing per node. Look for sequential scans on large tables, hash joins where merge joins would work, and significant time in sorting. The Postgres docs have a good walkthrough of reading plans <cite>1</cite>. <cite>1</cite> postgres.org/docs/using-explain # Both use citations, both are concise, both cite postgres.org — # but the surface differs. The model learns "include citations" # and "be concise" without overfitting to a specific style.
输出模式(schema)作为最简洁的"示例"
对于结构化输出任务,"向模型展示应产生什么"的最简洁形式并非自由格式的示例——而是模式(schema)。工具描述(第 0.3 章)自带其模式(schema);现代 API 的结构化输出功能允许你直接将 JSON 形态的输出约束到一个已定义的模式(schema)。两者都利用了同一洞见:让模型正式地看到它所产生的形态。
对于结构化输出,模式(schema)优于自由格式示例,原因如下:
- 它捕获的是抽象模式(这些字段、这些类型),而不带有表面噪声(模型可能复制的具体数值)。
- 它是强制性的——API 会拒绝不匹配的输出。示例是期望性的;模式(schema)是约束性的。
- 它是文档——模式(schema)本身描述了契约,而无需读者从示例中推断。
当输出真正是自由格式时(研究摘要、邮件回复、代码审查评论),示例是合适的,因为没有模式(schema)能捕获其形态。当输出是结构化的,优先使用模式(schema),将示例保留给模式(schema)无法捕获的部分(语气、详细程度、字符串字段内的特定模式)。
多少示例才合适
基于大量生产级智能体提示词经验的实用指南:
0 个示例是正确答案,当描述本身足够清晰且任务定义明确时("将这张支持工单分类为以下 5 个类别之一:……")。不要反射性地添加示例。
1 个示例通常太少——模型会对该单一示例的表面过拟合。例外情况:当你展示的是一个特定的事物(例如带有精确措辞的拒绝模式),而你确实希望该表面被精确复现。
2–3 个示例是大多数智能体任务的甜蜜点。足够的多样性让模型学到抽象;数量足够少使提示词不臃肿。
5 个以上的示例通常意味着你在试图弥补一个不同的问题——指令不清晰、规则相互矛盾,或任务本身的变化性太强,提示词无法捕获。解决方案不是更多示例,而是更清晰的规则或任务分解。
与较旧的模型相比,现代具备推理能力的模型对此需求更少。2024 年之前,向模型展示几个"我先考虑 X,再考虑 Y,然后得出结论 Z"的示例,可以可测量地提升困难推理任务的表现。而对于当前的推理模式模型(扩展思考、GPT-5 推理),模型会在内部完成这一过程;提示词中的思维链示例是多余的。
思维链(CoT)示例仍有用武之地:当你希望模型在可见输出中呈现其推理过程,而非仅在内部使用时。对于用户希望看到推理过程的分析任务,展示明确推理结构的示例是有帮助的。对于你只关心结论的任务,现代模型不需要提示词内的思维链。
指令在前,示例在后。指令提供抽象模式;示例加以说明。颠倒顺序——先放示例,再说"这就是原因"——往往让模型在获得框架之前就试图弄清示例在演示什么。
一个特定例外:当任务通过示例最容易理解时(例如难以描述的特定输出格式),在正式指令之前先放一个示例可以帮助模型锚定。指令随后变成"产生更多像上面那样的输出"。将此模式保留给描述确实力不从心的情况。
在那个数量下,很可能没有。原因有三。其一:每个示例消耗大量令牌,10 个示例的块轻易就能达到 3–5K 令牌——占预算的一半。其二:中间迷失效应(第 0.1 章)意味着埋在大块中间的示例受到的关注更少。其三:当模型有很多示例需要"平均"时,它往往会产生一种泛泛的综合感,而不是与某个具体示例进行清晰的模式匹配。
审查方法:逐一阅读你的示例,问每一个:它是否独特地教了其他示例所没有教的东西?通常只有 2–3 个做到了这一点;其余的都是装饰性的。删掉装饰性的,保留承重的,以零质量损耗收回 80% 的令牌。
结构化提示词:XML、分节,以及结构何时值得引入。
Anthropic 发布的提示词工程指南明确建议使用 XML 风格的标签来组织长提示词。这并非任意的语法偏好——其基础是 Claude 的训练方式,以及模型最可靠关注的结构性标记模式。同样的原则可以推广:长提示词中可见的结构有助于模型导航,无论你使用何种标签或标记。本步骤涵盖应添加什么结构、何时值得引入,以及过度结构化本身何时变成反模式。
结构为何有效
没有结构的长提示词是一堵文字之墙。模型必须从位置和词汇线索中识别什么是规则、什么是示例、什么是上下文、什么是用户的问题。可见的结构显式地完成这项工作:这一节是身份,这一节是工作流,这一节是示例。模型按需导航到相关节,而不是将一切视为统一的指令流。
其机制与人类阅读文档相同:当内容以节标题和清晰的分隔符组织时,你会扫描所需内容而非线性阅读。模型在内部做类似的事情——注意力对被结构性地标记为属于一个连贯单元的内容给予更强的关注。
XML 风格标签,Anthropic 的惯例
Claude 对 XML 风格标签的响应尤为良好——这一惯例的形成,是因为训练数据中包含了使用此风格的结构化文档。模式如下:
# Structured agent system prompt
<identity>
You are a research analyst at a financial-services firm. You produce
analytical briefings on companies and industries for investment
professionals.
</identity>
<workflow>
For every analytical question:
1. Decide whether fresh sources are needed.
2. If yes, search and fetch primary sources before synthesizing.
3. Every substantive claim must include a citation.
4. Structure outputs as: brief summary → key findings → caveats.
5. Stop after answering; do not continue with related topics.
</workflow>
<safety>
You decline:
- Investment recommendations. Respond with analysis, not buy/sell guidance.
- Specific market predictions.
- Anything about firm-internal positions or client holdings.
When declining, be brief and redirect to substantive analysis where
appropriate.
</safety>
<output_format>
Outputs follow this shape:
- Brief summary (2-3 sentences)
- Key findings (bulleted list with inline citations)
- Caveats (any gaps, conflicting sources, or uncertainty)
</output_format>
这个结构不仅仅是美观的——它使提示词更易于维护(有明确的编辑位置)、更易于调试(行为漂移时知道去哪里查),并且对模型来说是可靠的导航对象。
标签名称很重要
一个微妙之处:你选择的标签名称携带语义权重。<workflow> 向模型表明其后内容是程序性的;<safety> 表明其后内容在触发时优先于工作流;<output_format> 表明其后内容对响应形态具有约束力。选择有意义的标签名称是一个小杠杆,却能带来可度量的改善。
推荐的命名模式:
<identity>或<role>用于框架设定部分<workflow>、<procedure>或<guidelines>用于操作规则<safety>、<refusals>或<guardrails>用于边界条件<examples>配合嵌套的<example>用于少样本材料<output_format>或<response_shape>用于输出结构规则<context>用于智能体应知晓但本身不是规则的背景信息
标签应该描述内容是什么,而非它在提示词中的位置。<section_2> 对模型毫无意义;<safety> 则传达了一切。
节内结构:编号列表与嵌套标签
在一个节内,当有多个条目时,结构同样有帮助。两种行之有效的模式:
编号列表用于有顺序的规则。"1. 首先,做这个。2. 然后,做那个。"编号传达顺序,模型据此维持操作顺序。这是工作流规则(顺序重要时)的正确模式。
嵌套标签用于并列条目。当你有多个拒绝模式需要编码,每个都有自己的描述时,嵌套标签是有帮助的:
<refusals>
<refusal type="investment_advice">
Trigger: user asks should-I-buy / is-X-a-good-investment
Response: "I provide analysis, not investment recommendations."
then continue with substantive analysis.
</refusal>
<refusal type="market_prediction">
Trigger: user asks will-X-go-up / what-will-happen-to-Y
Response: Same redirect to analytical content.
</refusal>
</refusals>
每个拒绝是一个独立的单元;模型可以独立应用它们。如果没有嵌套结构,将相同内容写成段落会模糊它们之间的边界。
结构不再值得引入的时候
过度结构化是它自己的反模式。三个信号表明你走过了头:
只有一个条目的节。一个只有一句话的 <identity>。包裹单个示例的 <examples> 标签。包装本身增加了令牌而不增加清晰度——内容显而易见是一个单元;标签是多余的。
深度嵌套的结构。提示词中三层或更多层的嵌套通常表明结构已经变得繁琐。模型关注顶层;深层嵌套被忽略或被视为装饰。嵌套最多保持两层。
为短提示词添加结构。一个 200 令牌的提示词不需要节标签。整个提示词就是一个节。为一个微小的提示词添加 <identity> 和 <workflow> 是在照猫画虎。当提示词足够长、需要导航时才引入结构——通常是 500 个令牌以上。
智能体提示词与通用提示词中的结构
上述结构模式对智能体提示词的效果强于通用模型提示词,原因有二。其一,智能体提示词通常是长期存在的——它们被纳入版本控制,随时间被编辑、调试。结构对维护它们的人类和读取它们的模型同样有帮助。其二,智能体提示词编码的行为需要在多次会话中保持一致。结构使行为契约变得明确。
对于一次性提示词(针对单个输出对模型发出的单次查询),结构开销往往不值得。提示词只被读取一次,响应被产生,两者都被丢弃。当提示词只有 200 个令牌时,在标签上花费令牌是无谓之举。当提示词是一段代码时——多次使用、频繁编辑、跨版本调试——结构规范才会带来回报。
文档中段反模式
一个需要特别避免的模式:将关键指令埋在长提示词的中间。从第 0.1 章可知,中间迷失效应意味着放在那里的内容受到的关注不那么可靠。在结构化提示词中,这意味着:将关键指令放在其所在节的顶部,或放在整个提示词的最底部(模型在处理用户查询之前最后看到的内容)。
一种模式:一个长工作流节可以在末尾附上最关键规则的简要摘要,确保它们出现在靠近响应生成的位置。或者提示词可以以一个简短的 <remember> 节结尾,重申 2–3 条最重要的规则。在内容上是重复的;在结构上是承重的。
... (long workflow section here) ...
<remember>
Two things to keep in mind for every response:
1. Every substantive claim needs a citation. If you don't have a
source, omit the claim.
2. Decline investment recommendations briefly and redirect to analysis.
</remember>
这是提示词工程中相当于在长文档末尾写一段总结的做法。摘要不添加新信息;它确保最重要的内容被定位在注意力最高的地方。
最常见的提示词结构错误:在没有系统提示词的设置中,将用户的实际查询放在系统指令之前。"用户消息"应该是用户的输入;系统提示词应该是其他一切。Anthropic 的 system 参数(以及 OpenAI 的等效参数)正是为此而存在——它不仅仅是一个参数名,它是模型输入中被区别对待的独立位置。请使用它。
在大多数情况下功能相近,但有一点需要注意。Anthropic 的训练专门强化了对 XML 风格标签的关注;Markdown 标题同样有效,但对 Claude 来说稍不可靠。对于 OpenAI 模型,两者效果大致相当。对于其他提供商,行为各异。
务实的选择:针对 Claude 的提示词使用 XML,跨提供商提示词使用 Markdown(在任何地方都能起作用)。两者都远比没有结构要好;它们之间的差异足够小,风格偏好是合理的考量。
XML 在 Claude 上胜出的一个原因:嵌套。Markdown 标题嵌套不够整洁(必须使用标题层级:##、###、####)。XML 通过正确的开闭标签自然嵌套。对于有多层结构的复杂提示词,XML 保持更整洁。
请关闭它们。未关闭的 XML 风格标签大多数时候能正常工作,但在边缘情况下会出现退化——模型偶尔会将提示词剩余的所有内容视为属于未关闭标签,或将下一个开标签解释为嵌套标签。关闭你打开的每一个标签;这个规范成本低廉,却能防止微妙的漂移。
是的——将不可信内容包裹在一个命名清晰的标签中,让模型知道它的起点和终点。<user_document>{content}</user_document> 告诉模型:这是来自用户的内容,而不是要遵循的指令。这对可解析性和提示词注入(prompt injection)防御(第 2.3 章)都有帮助——模型不太可能执行被清晰标记为数据的内容中嵌入的指令。
这对蓄意的提示词注入并非无懈可击——显式框架有帮助,但模型仍然可能被操纵。包装是一道部分防御,而非完整防御。第 2.3 章更广泛的注入防御规范同样适用。
迭代规范:将提示词从"凭感觉"变成工程。
提示词工程中最大的失败模式不是选错了词——而是在没有度量编辑是否真正有效的情况下就修改提示词。"凭感觉提示"——基于对应该有效的直觉来调整提示词,发布感觉更好的版本——正是团队最终得到一个 3000 令牌系统提示词,却比最初 800 令牌的版本表现更差的原因。本步骤讲述将提示词工作变成可度量工程的迭代规范。
凭感觉提示的陷阱
这个模式会抓住每个团队:有人注意到智能体做了某件错事,编辑提示词来解决它,粗略查看几次测试运行后感觉更好,然后发布。一周后,另一个人注意到一个不同的问题,再次编辑提示词,发布。三个月后,提示词是最初的两倍长,没有人能说出整体质量是变好了还是变差了——他们只知道它在每次编辑所针对的特定问题上"更好"了。
问题会叠加:
- 每次编辑在修复其目标的同时可能破坏其他东西。不在许多场景中进行度量,就看不到权衡关系。
- 编辑只增不减。来自旧故障模式的旧规则永久留在提示词中;提示词单调地增长。
- 团队对提示词作用的认知与其实际作用产生分歧。成员记得自己做过的编辑并假定规则有效;事实上,相互矛盾的编辑彼此抵消。
- 成本在没有人注意的情况下增长。每个额外的令牌在每次请求时都要花费真实的钱,而一个 3000 令牌的系统提示词在生产规模下是一笔可观的开支。
解决方案是第 3.1 章所教授的评估(eval)规范,专门应用于提示词:预测、度量、决策。
针对提示词变更的预测-然后-度量
这项规范应用于任何提示词编辑:
1. 命名变更及其目标。"在工作流节中添加'优先引用主要来源而非聚合器'。目标:将引用来源质量分布从约 60% 主要来源提升至约 80%。"
2. 预测对指标的影响。"我预期 source_quality 指标提升 5–10 分;我预期 task_completion 或 answer_quality 不会有显著变化。"
3. 运行评估(eval)。对于廉价的小变更使用第二层快速子集,对于重大变更使用完整套件(第 3.2 章的两层节奏)。对于易受噪声影响的指标进行多次运行。
4. 对照预测验证结果。变更是否按预测移动了你预测的指标,大致按预测的幅度移动?是否有其他你未预测到的指标发生了变化?
5. 根据结果采取行动。如果变更按预测有效,合并。如果移动幅度小于预测,深入研究原因。如果意外地移动了其他东西,该变更存在你需要在发布前理解的副作用。
这听起来很繁重,但这与第 3.1 章相同的五步流程——专门应用于提示词变更。生产智能体中的大多数提示词编辑都应经历这一规范;"凭感觉"的编辑应保留给范围微不足道的变更(拼写修正、注释编辑、不可能影响行为的格式整理)。
何时在生产中对提示词进行 A/B 测试
对于第二层评估(eval)显示效果微小或不明确,但生产性能可能有所不同的变更,在真实流量中进行 A/B 测试是正确的工具。模式:将 5–10% 的流量路由到新提示词,其余流量路由到现有提示词,在定义的窗口期内比较第三层指标。
何时值得承担操作复杂性:
- 变更确实很大(新节、重大规则调整、提示词上的模型更换),可能产生你希望在真实流量中验证的广泛影响。
- 评估套件返回"没有显著影响",但你认为变更有意义——生产流量是更深入的测试。
- 变更影响的是难以在离线评估中度量的行为方面(用户满意度、对话延续率、留存)。
何时是过度之举:
- 小的澄清性编辑或拼写修正。直接发布。
- 评估信号在某个方向已经明确的变更。使用评估信号。
- 你关心的指标在离线已被充分度量的变更。离线更快更便宜。
A/B 测试提示词的机制与 A/B 测试任何功能相同——基于标志的路由、统计显著性规范、定义的运行窗口。不要重新发明;如果你已有实验基础设施,使用它。
提示词维护规范
提示词存在传统代码所没有的生命周期问题:
来自旧故障模式的规则会积累。三个月前你添加了"在继续之前始终核实用户的账户状态"。那条规则在故障模式是缺失上下文错误时是合理的。智能体已经改善;该规则已经过时;但没有人删除它,因为删除它感觉有风险。一年后,提示词里有数十条这样的规则。
解决方案:季度性提示词审查。取出系统提示词,列出每条规则,对每条规则问:「如果我们删除这条,评估套件会变差吗?」如果不会,该规则没有在发挥作用,可以删除(通过运行有该规则和无该规则的评估套件来确认)。这正是第 3.2 章评估规范所支持的那种审查——你可以在发布之前验证删除是安全的。
相互矛盾的规则会积累。编辑 A 说"总是 X"。编辑 B(三个月后)说"在情况 Y 下,不要 X"。两条规则互不引用;模型每次轮次临时解决冲突。随着时间推移,提示词变成了一片部分相互矛盾的规则丛林。审查模式相同:明确审查冲突;通过将相互矛盾的规则替换为一条统一的规则来解决它们。
示例会变得陈旧。使用了公司旧产品名称的示例。引用了已废弃 API 的示例。这些积累的方式与规则相同;同样的季度性审查会将它们捕获。
版本控制作为提示词基础设施
将提示词视为代码,而非配置。它们与代码库的其余部分一同进入版本控制。变更经过代码审查。变更历史是可审计的。修改提示词的提交有有意义的消息——"为退款请求添加明确的拒绝模式,目标是合规指标 +5 分。"
这不是仪式;它是使其他一切成为可能的基础。没有它:提示词存在于没有人审查的 CMS 或配置文件中,变更未被记录,"谁添加了这条规则,为什么?"在两个月后变得无法回答。
成熟的模式:提示词纳入版本控制,配有一个在提示词文件变更时运行第二层评估套件的 CI 步骤。同样的评估驱动规范既把关代码变更,也把关提示词变更。它们是同一类型的产物。
将一个工具调用提示词从"勉强能用"调到"可以上线"。
为了将本章的所有内容落地:一次真实形态的提示词工程过程,完整追踪预测-度量-决策循环。该智能体是一个客服智能体(第 4.4 章的形态);涉及的工具是负责将工单分类到专项智能体的路由决策工具。起始提示词在路由评估(eval)中达到 71% 的准确率;目标是 85%。共经历三次迭代。
起始提示词
You are a customer support router. Given a customer's question, decide whether to route it to billing, technical support, or account management. Use the route_ticket tool with your decision.
第二层快速子集的路由评估:在 20 条查询的路由评估集上准确率为 71%。误分类集中在三种模式:涉及付费功能的技术问题被路由到计费(因为"付费"触发了计费分类);复合问题路由不一致;本应升级到人工审查的模糊问题却被路由到了某处。
迭代一:添加明确的路由规则
预测。添加 3 条明确的决策规则(每种故障模式一条)应能将路由准确率提升 8–12 分。不期望一次就完全修复所有三种问题。
新的提示词:
<identity>
You are a customer support router. You classify incoming tickets
into one of three categories and dispatch to the right specialist.
</identity>
<workflow>
For every ticket, decide which category fits best:
— Billing: refunds, charges, invoices, payment methods, plan pricing.
— Technical support: how-to questions, error messages, integration
issues, anything about how the product works.
— Account management: password resets, user permissions, team
invitations, account-level settings.
Routing rules:
1. If a question mentions a paid feature AND is about how to use it,
route to technical support, not billing. "How do I set up the
paid SAML feature?" is technical, not billing.
2. For compound questions covering multiple categories, route to the
category that addresses the customer's primary concern. If
that's not clear, route to technical support (which handles the
broadest case).
3. If the question is too ambiguous to classify confidently after
one read, route to "human_review" instead of guessing.
</workflow>
结果。第二层快速子集:路由准确率 79%。提升了 8 分,在预测范围之内。
分解提升:规则 1 修复了所有 3 条"付费功能"误路由(从 0/3 正确变为 3/3)。规则 3 捕获了 4 个模糊问题案例中的 2 个(改善了升级行为)。规则 2 有边际帮助,但未能完全解决复合问题。
结论。预测方向正确;幅度在范围内。复合问题模式是剩余差距所在。
迭代二:改进复合问题处理
预测。复合问题需要的是可操作示例,而非单纯的规则。添加 2 个示例(一个有明确主要关切,一个没有)应能修复剩余的复合问题误路由。预期提升:3–5 分。
向提示词添加:
<examples> <example> Ticket: "I was charged twice for last month — also, my login keeps failing on the mobile app." Routing: billing (charged-twice is the primary financial concern; the login issue is secondary and can be addressed after). </example> <example> Ticket: "I'm trying to set up SSO and getting an error, plus I need to add three new users to my team." Routing: human_review (compound request with no clear primary; SSO setup and user provisioning are different specialists' work and need coordination). </example> </examples>
结果。第二层快速子集:路由准确率 84%。提升了 5 分,在预测范围的上限。
复合问题案例现在大多得到了处理。剩余的失败案例更为微妙——措辞模糊到连人类也需要澄清的问题。这些映射到"升级到人工",即规则 3 的行为。
结论。示例完成了规则单独无法完成的工作。我们达到了 84%,略低于 85% 的目标。
迭代三:最后一分
预测。剩余 16% 的失败集中在两个子类别:(a) 智能体不认识的功能相关问题(罕见的新产品领域),以及 (b) 用户未提供足够上下文的极短问题。两者都应该根据规则 3 路由到 human_review,但提示词没有充分强调"未知功能"或"问题过短"是升级触发器,而非分类挑战。添加两个更明确的触发器应能获得 1–2 分。
将规则 3 更新为更具体的版本:
3. Route to "human_review" instead of guessing when:
— The question is too ambiguous to classify confidently
after one read.
— The question references a feature you don't recognize
(don't guess based on partial matches).
— The question is too brief to determine intent (1-2
short sentences with no context).
结果。第二层快速子集:路由准确率 86%。目标达成。
提示词在三次迭代中从约 50 个令牌增长到约 280 个令牌。每次增量都经过预测、度量和验证。15 分的准确率提升在减少误路由成本方面远超过额外令牌的代价。
这段追踪教给我们什么
值得点名的四个观察:
预测会随经验变得更准确。第一次迭代是对幅度的猜测;第三次则校准得多。经过几个周期之后,你对每种编辑能移动哪个指标、移动多少,会形成直觉。这种直觉比任何具体的提示词建议都更有价值——它是凭感觉提示与工程化提示的区别。
评估套件使这一切成为可能。没有第二层数字来验证,这一切都行不通。凭感觉提示在缺乏评估基础设施、无从得知编辑是否有效的团队中持续存在。对第二层的投资(第 3.2 章)也是对能够有意识地迭代提示词的能力的投资。
每次迭代针对一个具体的故障模式。不是"让它更好"——而是"修复付费功能误路由"。具体的目标产生具体的编辑;具体的编辑是可度量的。"总体上让提示词更好"换了个名字的凭感觉提示陷阱。
提示词的增长是因为工作有其价值。每次添加都有评估集上可度量的改善来证明其合理性。如果迭代三的准确率只提升了 0.2 分而非 2 分,正确的做法是回退迭代三,接受 84%——而不是继续添加规则,寄望于边际增益。提示词的增长应当有其依据,而非理所当然。
找到一个具体的故障模式。预测什么样的编辑能解决它以及大约能改善多少。做出编辑。度量。如果结论与预测相符,合并。如果不符,理解原因,然后或者修改提示词,或者修正你对有效方式的认知模型。重复,直到评估套件通过质量基线。当你不再能预测编辑的幅度时停下——那是你已经触达提示词工程独自所能做到之极限的信号,剩余的差距需要改变工具、脚手架或模型选择。
交付物
一套用于编写和维护智能体系统提示词的可行规范。三种职责(身份、工作流、安全)保持独立,各自按其自身逻辑进行编辑。示例用于教授抽象,避免固化表面。结构(XML 风格标签、命名节)应用于长提示词,对短提示词则略去。迭代循环——预测、度量、决策——应用于每次有意义的变更。季度性审查规范以防止提示词腐化。版本控制作为使提示词工程成为真正工程实践而非一系列猜测的基础。
- 系统提示词具有明确的身份、工作流和安全节,按此顺序排列
- 身份部分简短(50–200 个令牌),仅含框架设定,无操作规则
- 工作流包含顺序规则、核实要求、停止条件
- 安全节具有带明确拒绝措辞的具体拒绝触发条件
- 工具特定规则存放在工具描述中,而非系统提示词中
- 少样本示例用于非直观格式/相似情况区分/拒绝模式
- 示例经过故意多样化以教授抽象,而非固化表面
- 结构化输出优先使用模式(schema)而非示例
- XML 风格标签对超过约 500 个令牌的提示词进行结构化;标签名称有意义
- 用户提供的内容包裹在命名清晰的标签中(部分注入防御)
- 每次提示词编辑都经过预测-度量-决策规范
- 提示词纳入版本控制;变更经过审查;提示词变更触发第二层评估(eval)
- 季度性提示词审查:列出每条规则,删除不发挥作用的规则