System Prompt 到底放什么?我把 Anthropic 那套约束拆了三层
上周给一个做法律 AI 的客户 review 线上代码,看到他 system prompt 里塞了足足 850 个字。开头是”你是一个专业、严谨、客观、富有同理心且极其注重细节的法律助手”,后面跟了两段职业操守、三段风格要求,还夹了一条”请确保你的回答准确无误”。
user 那边呢?就一句:”请帮我分析这份合同的风险点。”然后把合同全文贴上去。
我看完大概沉默了十秒。这不是一个 prompt,这是一份岗位说明书。
我先讲一下 system 和 user 的职责边界
这事其实 Anthropic 在官方文档里讲得挺清楚,但被大部分中文教程带偏了。中文圈子里流行的说法是”system 放人设,user 放问题”,听起来没毛病,但太笼统。
我现在理解的边界是这样:
system 管的是”约束”——不管这次来什么请求,这些规则都成立。比如你是什么角色、不能做什么、输出什么格式、用哪种语气、失败时怎么兜底。这些东西一旦写进 system,Claude 会把它当成整个会话的”重力场”。
user 管的是”指令”——这一次我具体要你干什么。输入数据、本次任务目标、这次特殊的限制。
所以”请确保你的回答准确无误”这种话放 system 是浪费 token。它对所有任务都成立,说了等于没说。Claude 又不会因为你没说就故意瞎编。
那个客户一开始不服气,说你看 OpenAI 官方示例里也会写”你要准确”。我说那是他们 GPT 的风格,Claude 对这种”空话”敏感度很高,你写多了它反而会把实际约束稀释掉。
我拆的三层模型
在他项目上我重写了一版,就砍到 320 字,结构长这样:
第一层是身份(Identity)。两三句说清你是谁、服务谁、核心任务。不要形容词堆叠。”你是一名为中国中小企业服务的合同审阅助手,用户通常是没有法务团队的创业者”——这一句比”专业严谨富有同理心”信息量大十倍。因为它锚定了读者画像。
第二层是规则(Rules)。必须做什么、绝对不能做什么、边界在哪。我一般用无序列表直接列出来,每条不超过 15 字。比如:
- 不提供具体诉讼策略
- 不引用未经查证的法条编号
- 发现高风险条款必须用
<alert>标签标出 - 无法判断时直接说”建议咨询律师”,不要硬答
这层最怕的是写得像宪法——“应当秉持公正原则”这种话 Claude 看了会礼貌性点头然后该怎么错还怎么错。要具体、要可执行、要像红线。
第三层是示例(Examples)。1-2 个微型 in/out 对,展示典型场景的风格和格式。如果你的任务有固定输出结构,这一层几乎是救命的。不过示例别写太长,system 里的示例主要是”锚定风格”,不是”穷举用例”。穷举用例的活儿交给 user 里的 few-shot 做更合适,这个我在另一篇讲 few-shot 设计的文章里会细说。
客户那版为什么会失败
回头看他原来那 850 字,问题不是”写得不好”,是”层次混乱”。身份、规则、示例、自我吹捧全糊在一块儿。
Claude 这种大模型处理长 system 的时候,有个我观察到的规律:越靠前的内容权重越高,越具体的内容越容易被执行,越形容词化的内容越容易被忽略。
他原 prompt 开头那三行全是形容词,Claude 大致相当于收到一个”请你表现得很牛逼”的模糊信号。到第 400 字左右才出现”不要编造法条”这种硬约束——但这时候注意力已经被稀释了。
我重写后把身份压到两句、规则上提到前置位、形容词几乎全删。实测在同一批 200 个合同分析 case 上,合格率从 71% 涨到 88%。”合格”的标准是他们自己的 QA 团队打分,不是我定的。
Claude 到底多”听”system
这事我顺手测过。同一条硬约束,放 system 里和放 user 里,执行率差多少?
我拿一个简单规则:”输出必须是 JSON,不要任何解释文字”,跑了 100 次相同的抽取任务。
- 只写在 user 里:73 次合规
- 只写在 system 里:91 次合规
- 两边都写:96 次合规
差距挺明显的。Claude 对 system 的”服从度”确实更高,这也是为什么我倾向把格式约束、输出结构这类”每次都一样”的东西往 system 放。想稳住 JSON 输出还有一套组合拳,我在让 Claude 稳定吐 JSON 的 5 个套路里专门写了。
顺便提一句,如果你在用 CLAUDE.md 做项目级配置,那个文件本质上就是个持久化的 system 增强,相关的写法我在Claude Code 项目配置那篇里有更细的讨论。
一些容易踩的坑
坑一:把可能变化的东西写进 system。比如”今天是 2026 年 4 月 20 日”——明天就过期了。这种应该放 user 或者动态注入。
坑二:system 里塞大段背景资料。知识性内容该放 user 或者用 RAG。system 主要承载规则,不是知识库。放多了既浪费缓存命中率,又让模型分心。prompt caching 的机制我在另一篇深入讲过。
坑三:用 markdown 标题装饰 system。# 身份 ## 规则 这种写法不是不行,但 Claude 对 XML 标签更敏感,用 <identity> <rules> <examples> 这种语义标签效果更稳。为什么 Claude 特别吃 XML,这篇专门讨论过。
坑四:规则互相矛盾没察觉。比如一边说”回答要简洁”一边说”要引用具体法条并解释”。Claude 遇到矛盾约束时倾向挑软的执行,结果就是两头不讨好。写完规则自己过一遍,看有没有打架的。
我现在的 system 模板
给一个脱敏后的骨架,你可以照着改:
1 | <identity> |
基本上 200-400 字解决战斗。想加东西先问自己:”这条规则是不是每次都成立?”不是就挪去 user。
写 prompt 这事最怕的就是”越写越长、越长越虚”。砍到只剩骨头,反而是最快出效果的办法。
延伸阅读
想把 Claude 的 XML 能力用到极致,看 为什么 Claude 特别吃 XML 标签。想搞清楚 system 和持久化配置的边界,去 CLAUDE.md 项目配置那篇。要让输出稳定,别错过 让 Claude 稳定吐 JSON 的 5 个套路。
- 标题: System Prompt 到底放什么?我把 Anthropic 那套约束拆了三层
- 作者: Claude 中文知识站
- 创建于 : 2026-04-18 10:20:00
- 更新于 : 2026-04-19 14:40:00
- 链接: https://claude.cocoloop.cn/posts/prompt-system-role-placement/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。