上篇解剖上下文窗口时留了一个尾巴:窗口里这么多内容,到底哪一块对模型行为的塑造力最强?答案朴素得近乎无聊——系统提示(system prompt)。用户消息一轮一换,工具结果用完即弃,检索片段随问题变化,只有系统提示从第一轮到第一千轮始终在场。它每轮都占预算、每轮都参与注意力分配,是上下文里最值得精心设计的一块不动产。
本文把系统提示从"写提示词的技巧"里拆出来,按软件工程的标准对待:先讲清它的定位,再给出五层信息架构模板,然后逐个讨论规则预算、指令冲突、示例放置与结构化输出,最后完整重构一个真实尺寸的系统提示。全文按"定位 → 架构 → 约束与冲突 → 示例与格式 → 工程化 → 实战 → 总结"组织。
1、常驻上下文的操作系统
很多人把系统提示当成"加强版提示词":写一段角色设定,堆几句要求,扔进 system 字段就完事。这个理解会让系统提示越写越长、越改越乱。更准确的类比是操作系统配置文件:用户消息是一次性的命令行输入,工具结果是磁盘上的临时文件,而系统提示像 /etc 下的配置——进程启动即加载、全程生效,任何一行改动都影响之后的每一次调用。
按这个类比,一个生产级系统提示要回答四个问题,对应四层内容:
- 角色:你是谁、为谁服务、在什么环境里工作
- 能力边界:可以做什么、明确不做什么
- 输出协议:回复的结构、格式与机器可解析约定
- 安全规则:哪些红线行为不可触碰
四层缺一层都有典型故障:缺角色则人设漂移,缺边界则越权调用工具,缺协议则下游解析器天天崩,缺安全规则则把防线交给运气。Anthropic 的提示词工程最佳实践反复强调的也是这件事:系统提示的首要职责不是"激发模型潜力",而是定义接口契约。
既然是接口契约,就值得像设计数据库 schema 一样对待:结构稳定、语义唯一、每次变更走评审。后文全部围绕这个观念展开。
2、五层信息架构模板
四层是职责视角,落到文本上还需要可复用的骨架。大量生产系统验证过的排列是五层,从上到下依次为身份层、能力层、规则层、格式层、示例层。
顺序有两个讲究。第一,从稳定到易变:身份几乎永不变,示例偶尔更换,把稳定的放前面。系统提示还天然占住上下文的最前端——Lost in the Middle 论文的研究显示,长上下文中段的信息利用率明显低于首尾,头部是最稳的位置。第二,从抽象到具体:先说"你是谁",再框"你能做什么",然后才是"怎么做"的限制与"做成什么样"的格式,示例最后兜底。
骨架模板如下,采用 XML 标签结构:
<identity>
你是 Acme 的企业客服助手,服务已认证的企业版用户。
环境:生产环境,多轮会话,必要时转接人工。
</identity>
<capabilities>
你可以:查询订单状态、发起退款(500 元以内自动通过)、转人工。
你不可以:修改账户密码、承诺赔偿金额、透露内部定价。
</capabilities>
<rules>
1. 涉及资金操作,先复述用户意图并获得确认。
2. 不确定时明说"我不确定",禁止编造政策条款。
3. 用户情绪激动时,先致歉再处理事务。
</rules>
<output_format>
每次回复不超过 5 条要点;金额保留两位小数并注明币种。
</output_format>
<examples>
<example user="退款到哪一步了?">订单 R-1024 的退款已于昨日原路发起,预计 3 个工作日到账。</example>
</examples>
解读:五层之间用 XML 标签显式分隔,模型对标签结构的遵从度高于纯自然语言分段;能力层用"可以/不可以"两栏对举,规则层编号管理,出问题时可以精确引用"违反了规则 2"。每层只写自己的事,重复职责是后面几节要清理的头号异味。
3、约束的 token 经济
系统提示里的每一条规则都是常驻开销:它占据每一轮的输入预算,参与每一轮的注意力分配,还摊薄其他规则的权重。规则不是免费的,而且边际收益递减得很快。
Google 在 2025 年发布的 IFScale 基准(How Many Instructions Can LLMs Follow at Once?)专门测了这件事:让模型写商业报告时同时遵守 N 条关键词指令。结果是头部模型在 10 条指令时遵从率还能维持在 95% 以上,指令数量加到几十上百条后,所有受测模型都出现明显下滑。
这不是模型"不努力",而是注意力分配的数学问题:每条规则都要在生成前被检索、比较、应用,规则越多,单条被漏掉的概率越大。堆几十条规则的系统提示,实际效果接近把规则表摇匀了随机抽几条执行。生产上的克制原则:
- 硬规则控制在 10 条以内,编号管理
- 每条规则必须可判定,能写出对应验收用例
- 写不进 10 条的,降级为格式层描述或交给示例演示
- "希望活泼一点"这类无法判定的期望,直接删掉
判断一条规则该不该留,最好的问题是:模型违反它时,我能在评测里写一条断言抓住吗?写不出断言的规则,多半也写不出效果。
4、指令冲突检测清单
比规则过多更危险的是规则互相矛盾。两条规则冲突时,模型没有内建的仲裁机制,实际听谁的由位置、具体程度、措辞强度甚至示例的暗示共同决定——同一个系统提示在不同轮次可能选出不同的赢家,表现为"时灵时不灵"的玄学故障。
常见冲突模式可以整理成一张清单,每次重构系统提示时逐项过一遍:
- 同维度反向要求:"回答要详细全面"与"尽量简短"
- 泛化规则与具体规则打架:"绝不透露内部信息"与"用户是内部员工所以都可以说"
- 格式条款重复且不一致:规则层说"用表格",示例层全是段落
- 风格约束互相拉扯:"语气活泼"与"保持严肃专业"
- 示例与条文矛盾:条文禁止编造,示例里却有臆造数字
其中最后一条最隐蔽也最致命:示例的权重高于条文。模型对"照着样子做"的执行力远强于对抽象禁令的执行力,一条违规示例能无声地废掉三条规则。所以冲突检测必须扫到示例层,不能只读规则段落。
5、示例放置与缓存权衡
few-shot 示例放哪里,是一道典型的缓存与灵活性权衡题,选项只有两个:写进 system prompt,或在每轮拼装时动态注入。
| 放置方式 | 缓存表现 | 灵活性 |
|---|---|---|
| 写进 system | 前缀稳定,多轮摊薄成本 | 差,换例即改常驻层 |
| 动态拼装 | 命不中缓存,每轮全价 | 高,按场景挑选示例 |
写进 system 的收益来自 prompt caching:Claude 的缓存文档给出的账本是,缓存写入按 1.25 倍输入价计费(1 小时档 2 倍),命中读取只按 0.1 倍计费,最小可缓存长度在千 token 量级(Opus/Sonnet 为 1024,Haiku 为 2048)。多轮会话里,几千 token 的系统提示从第二轮起几乎只付一折,示例跟着前缀一起享受这个折扣。代价是不灵活:换示例就要改常驻前缀,前缀一变缓存全失效,下一轮重新付写入成本。
生产上的折中是"稳定前缀 + 易变尾部",把拼装函数写成这样:
SYSTEM = load_prompt("support_agent", version="3.2.1") # 常驻前缀
def build_messages(case: dict) -> list:
examples = pick_examples(case["topic"], k=2) # 每轮动态选例
return [
{"role": "system", "content": SYSTEM}, # 缓存命中区
{"role": "user", "content": render(case, examples)}, # 易变区
]
解读:通用示例(体现格式与风格的定式)进 system 吃缓存,场景专属示例(某类问题的解法)放 user 消息尾部按需注入。分界线只有一条:这条示例多久变一次?越少变的越靠前。
6、结构化输出协议
当下游消费者是代码而不是人眼,格式条款就成了系统提示里最重要的部分。结构化输出的完整方法论——约束解码、函数调用、输出评测——在《AI Agent 开发》系列第 4 篇展开过,这里只关心它在常驻提示里的位置与维护。
位置上,格式条款属于五层骨架的格式层,且必须单一权威来源:字段结构只定义一次,规则层不复述字段细节,示例层只展示填充效果。多处重复定义是格式漂移的头号来源——改了 JSON Schema 忘了改示例,模型就会在两个版本之间随机摇摆。提示条款与配套 schema 如下:
<output_format>
严格输出 JSON,结构遵守 data_analysis.schema.json:
summary 不超过 80 字;change 为环比百分比,保留 1 位小数;
无法计算的字段返回 null,禁止填 0 或删除字段。
</output_format>
字段结构单独放在 schema 文件里维护:
{
"type": "object",
"required": ["summary", "rows", "confidence"],
"properties": {
"summary": {"type": "string", "maxLength": 80},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": ["dimension", "value", "change"],
"properties": {
"dimension": {"type": "string"},
"value": {"type": "number"},
"change": {"type": "number"}
}
}
},
"confidence": {"enum": ["high", "medium", "low"]}
}
}
解读:schema 是机器侧的真相,提示条款只写行为约束(null 策略、小数位数),字段结构一律引用 schema,由构建脚本在打包时注入前缀。更彻底的做法是 schema 驱动——以 JSON Schema 为源,脚本生成提示条款与解析器校验代码,改一处、三处同步。做不到自动生成时,至少把 schema 纳入评审范围,与系统提示同仓库同变更单。
7、系统提示版本化管理
系统提示当代码管,就该享受代码的待遇:版本控制、评审、灰度发布,一样不能少。反面案例俯拾皆是——提示词散落在代码字符串、聊天记录和某人的备忘录里,线上行为"上周还好好的",谁也说不清中间改了什么。
第一步是入库:每个系统提示一个文件、一个版本号,变更走 PR,评审重点是第 4 节的冲突清单与第 3 节的规则预算。第二步是灰度:提示词没有编译期保护,一行措辞变化可能让某个场景集体翻车,必须像后端服务一样按流量百分比放量。一个轻量的提示词注册表可以这样写:
prompts:
support_agent:
version: 3.2.1
file: prompts/support_agent.md
rollout:
canary: 5 # 5% 流量先走 3.2.1
stable: 3.2.0
data_analyst:
version: 1.4.0
file: prompts/data_analyst.md
eval_set: evals/data_analyst.jsonl # 过评测门禁才能发布
解读:注册表把"哪个版本在线上、灰度到多少、用哪个评测集验收"变成显式声明,load_prompt(name, version) 按表加载,回滚就是把 stable 指针挪回去。一个现成的参照是 Claude 自己:官方文档专门维护着Claude 产品系统提示的发布记录,每次措辞调整都有版本可查——头部厂商也是这么管的。
8、实战重构数据分析助手
理论凑齐了,动手把一团乱麻重构成五层骨架。素材是真实项目里出现过的一个"数据分析助手"系统提示,做了脱敏改写。
8.1、重构前
原始版本全文如下:
你是一个数据分析助手,要专业但要友好,回答要详细全面,但也尽量简短。
用户是运营同事,会问各种数据问题,你要尽力回答,
不确定的时候也要给出你的 best guess,不要让用户失望。
如果数据不够,可以编一些合理的数字把报告补充完整。
输出用 markdown,重要的话用表格,图表可以用 mermaid 也可以只描述。
不要提你是 AI。回答要有深度但不要太长,语气活泼一点但保持专业。
涉及敏感数据要小心,但用户都是内部员工所以基本都可以说。
拿前几节的清单逐项扫描,问题排成一排:第 1 句自带"详细 vs 简短"的正面冲突,"活泼 vs 专业"又是一对反向拉扯;"给出 best guess"与负责任的分析精神相悖,下一句更是直接授权编造数字;"敏感但都可以说"让安全规则形同虚设;格式层给了 mermaid 与文字描述两个选项却没有判定条件,下游只能靠猜。
8.2、重构后
重构版按五层重排,硬规则压到 3 条:
<identity>
你是电商平台的数据分析助手,服务运营团队,用户均为内部员工。
数据范围:近 90 天的订单、流量与转化漏斗。
</identity>
<capabilities>
可做:指标计算、同环比归因、异常波动定位、生成图表配置。
不做:预测性结论、跨行业建议、涉及单个用户身份的分析。
</capabilities>
<rules>
1. 数据缺失时明确指出缺口,禁止用估计值填充。
2. 关键数字标注口径:统计周期与过滤条件。
3. 置信度不足时,结论前加"初步判断"并说明依据。
</rules>
<output_format>
第一行一句话结论;随后最多 5 条要点;对比数据用 markdown 表格。
无法计算的字段填 null 并加脚注,禁止填 0。
</output_format>
<examples>
<example user="上周转化率为什么跌了?">初步判断:移动端支付页流失率上升 2.3 个百分点(近 7 天对比前 7 天,全量订单口径)……</example>
</examples>
对照着看变化:冲突全部消失——"简短"落进格式层的硬性条数,"详细"体现在要点的信息密度;"编数字"被规则 1 显式禁止,示例同步演示了标注口径的正确姿势;安全边界从一句含糊的"小心"变成能力层的三条"不做"。散落全文的十几条隐含要求收敛为 3 条可判定规则,总 token 少了约三分之一,遵从率反而上升——问题大多不出在写得少,而出在写得乱。
9、总结
系统提示是上下文里唯一永远在场的组件,值得用工程标准对待。全文主线可以压缩成五句话:把它当操作系统的配置而不是高级提示词;用身份、能力、规则、格式、示例五层组织信息;硬规则克制在 10 条以内,因为每条都是常驻预算;用冲突清单扫描条文与示例,记住示例的权重高于条文;示例按变更频率分层放置,格式条款保持单一权威来源,整个文件走 git、评审与灰度。
留三道练习:
- 数一数你线上 system prompt 的硬规则条数,挑出互相冲突的两条
- 把其中一条无法判定的规则,改写成可验收的断言形式
- 为它建一个提示词注册表条目,设计 5% 灰度发布流程
对于正在维护生产 Agent 的团队,建议本周先做第一道练习——大多数系统提示的问题,在数完规则条数的那一刻就已经暴露了。

