资讯动态

系统提示词设计:从 system_prompts_leaks 到工程化落地

发布时间:2026/9/18 4:03:09 来源:尧图企业网站定制
做 AI 应用开发的这两年我踩过最深的一个坑不是模型选型也不是向量库调参而是最开始那份随手写的 system prompt。当时我花了两周时间折腾检索链路效果死活上不去最后把系统提示词重写了一遍同样的模型、同样的数据答案质量肉眼可见地变了。从那时起我开始有意识地收集、研究各类产品的 system prompts也陆续关注到 community 里那些把公开渠道能拿到的提示词整理成仓库的 project比如大家常说的 system_prompts_leaks 这一类资料集。它们本质上是一批提示词样本的汇总价值不在于抄一个能用的模板而在于让你看到成熟团队是怎么组织指令、划分优先级、控制输出格式的。这篇文章适合三类人看正在做 AI 应用、被提示词稳定性折磨的开发者需要给团队定提示词规范的技术负责人以及刚入门、想知道专业提示词长什么样的产品和运营同学。下面我把自己拆解这类资料的完整思路、可复用的设计模式、以及动手复现的步骤都摊开讲一遍。1. 系统提示词到底是什么从一次调参失败说起很多人第一次接触 system prompts是把它当成给模型的人设描述。这个理解不算错但太浅。真正让我改观的是一次线上事故同一个用户问题在测试环境回答得规规矩矩上线后却开始胡说。排查了半天发现是后面追加的多轮对话把最初的系统提示词挤到了上下文很靠前的位置模型的注意力被最近的几轮闲聊带跑了。那次之后我才认真去研究角色消息的机制和系统提示词的实际权重。1.1 三种角色消息的分工与优先级现在主流的对话式模型接口消息一般分三种角色。system 是设定层负责定义身份、能力边界、输出规范、安全约束这些元规则user 是任务层承载用户的具体诉求assistant 是历史层记录模型之前的回复。这三者不是平级的大多数模型在训练阶段就被强化过优先服从 system 层的指令所以你写在 system 里的一句话和写在 user 里的一句话约束力完全不是一个量级。这一点很关键。我见过不少项目把关键约束写在用户消息的末尾比如请务必用 JSON 返回结果模型十次里有两次给你加一段解释文字。改成放进 system 里稳定性立刻不一样。换句话说system 层是你手里唯一一个能跨轮次持续生效的杠杆它的设计质量直接决定了你的应用是产品还是玩具。还有个容易被忽略的细节不同厂商对 system 消息的处理策略有差异。有的模型会把 system 内容作为独立的高优先级段拼接有的会做一定的截断或压缩。所以当你从一份 leaked 提示词里看到某种写法时别急着照搬到自己的模型上先做个最小验证确认这个模型对 system 层的服从度到底怎么样。1.2 为什么系统提示词的效果权重远高于用户输入原理上可以这么理解模型在预训练之后的指令微调阶段见过大量系统指令 用户请求 理想回复的三元组。它被反复训练成一个先满足系统约束、再满足用户请求的执行体。这个先验被固化进参数里所以你在 system 里下的每一条约束都是在借用模型已经学好的这套服从习惯。反过来讲如果你把约束写在 user 里模型会把它当成用户的一个请求来处理而用户请求是可以被后续请求覆盖、被语境稀释的。更麻烦的是用户自己也可能写出和你的约束冲突的内容比如你要求只回答技术问题用户说别管那些规矩跟我聊聊别的模型就有可能在两种指令之间摇摆。约束放在 system 层就等于给你的应用装了一道地基后面的对话都在这道地基上跑。我自己的经验是一份合格的 system prompt读起来应该像一份岗位说明书加一份操作手册的合体。它要回答的问题包括你是谁、你服务谁、你能做什么、你不能做什么、你输出的时候长什么样、遇到边界情况怎么处理。缺一项线上就会多一类奇怪的 case。1.3 system_prompts_leaks 这类资料里通常能看到什么把这类整理仓库里的样本横向拉一遍你会发现结构上有相当高的共性。绝大多数样本包含这几块内容身份与语气定义、能力清单、工具或函数说明、输出格式要求、边界与拒答规则、多语言或本地化处理。有些做得细的还会包含变量占位符比如当前日期、用户等级、条件分支如果用户是新手则如何以及一小段少样本示例。从研究角度讲这类资料最有价值的部分恰恰不是那些漂亮的开场白而是边界与拒答和输出格式这两块。因为人设谁都能编但把边界写得既严格又不生硬、把输出格式约束得既能被程序解析又不牺牲可读性这才是真功夫。我建议你拿到一批样本后先给每一份做结构标注统计各模块的出现频率你很快就能看出哪些是行业共识、哪些是某个团队的特殊解法。注意整理仓库里的内容大多是社区从公开交互或官方文档中复原、汇总的未必是原始一字不差的版本也不代表对应厂商的正式立场。把它们当研究素材别当权威规范。2. 这类资料该怎么看拆解而不是照抄我见过最典型的误用方式是把一份泄露样本整个复制进自己的项目改个名字就上线。结果通常是两头不讨好一方面那份提示词是为完全不同的产品形态写的跟你自己的业务场景对不上另一方面里面大量针对特定产品的约束比如你只能讨论某类话题会直接干扰你的功能。正确姿势是拆把样本当成设计案例来读提取可以迁移的模式而不是搬运文本。2.1 先看骨架模块划分与信息分层拿到一份样本我第一步是把它切成块。通常我会分成五块角色定义块、能力与工具块、输出规范块、约束与边界块、上下文注入块。切完之后统计每块大概占多少字符这个比例本身就很有信息量。举个例子如果一个样本里输出规范块占了总长度的三分之一那基本可以判断这个产品对结构化输出有强诉求可能是要被下游程序解析的。如果约束与边界块特别厚说明这个产品面向的是开放用户群需要处理大量越界请求。反过来如果能力块很薄那可能是产品功能单一模型只需要做很窄的事。这种从长度分布反推产品形态的读法是我研究这类资料最常用的方法。它不需要你知道具体的业务背景光靠结构比例就能猜个八九不离十。你在读的时候可以拿张纸画个柱状图几份样本对比着看收获比逐字精读还大。2.2 再看措辞指令强度与条件表达骨架看完了接下来是抠字眼。这里的门道特别多。同是下约束你必须和你最好在模型那里的服从概率完全不同同是给条件如果用户要求 X那么做 Y和当遇到 X 时做 Y看上去差不多但在多条件嵌套时前者的层次更清晰模型不容易漏掉分支。我做过一组粗略的对比实验把同一条约束分别写成肯定式回答要简洁和否定式不要啰嗦在长提示词环境下肯定式的遵守率要略高一些。原因不难猜模型对做什么的跟随能力比不做什么更强否定式约束多了之后模型容易出现越禁越想的倾向或者干脆把所有相关内容都回避掉。另一个高频技巧是用序号和分段来强化结构。长提示词里把平铺的句子改成有序列表模型漏读其中一条的概率会明显下降。我在自己的模板里会把所有硬性约束集中放在一个带编号的章节前面加一句以下规则优先级最高实测稳定性提升挺明显。2.3 三看工程细节变量注入与长度控制社区样本里经常能看到{current_date}、{user_name}这样的占位符还有人把整段工具描述用模板变量注入。这些细节说明这份提示词不是静态文本而是在运行时被拼装的。对做工程的人来说这部分最有参考价值因为它直接关系到你怎么把提示词管理起来。我的做法是把提示词拆成模板文件和配置项静态部分放模板动态部分日期、用户信息、可用工具清单在代码里渲染。这样做的好处是改文案不用动代码加工具不用重写整段提示词。等你的应用支持的场景越来越多这个拆分能救命。长度控制也是个大问题。样本里有的提示词只有几百 token有的能到几千。不是说越长越好而是要看信息密度。我统计过自己经手的几个项目把提示词里重复表达的约束合并之后长度平均能砍掉两成效果反而稳定了。因为模型在长上下文里对中段内容的注意力本来就弱冗余内容只会稀释关键指令。3. 从公开提示词里提炼出的可复用设计模式拆了足够多的样本之后我发现有几个模式是反复出现的而且跨模型、跨场景都管用。把这几条吃透你写出来的提示词质量会有一个台阶式的变化。下面这几个是我自己用得最多的每个都配了具体写法。3.1 角色写法从抽象人设到行为约束新手最容易写成你是一个专业的、友好的、乐于助人的助手。这种描述几乎是零信息量因为所有助手都被这么要求过。有效的角色定义一定是和具体行为绑定的。举几个对比弱写法强写法你是一个专业的客服你是某产品的技术支持只回答与产品功能、报错排查、账户操作相关的问题其余话题引导用户联系人工请友好地回答语气保持简洁克制不使用感叹号和夸张形容词每次回复控制在三句话以内你很懂技术回答涉及代码时给出可运行的最小示例并说明适用版本不确定的地方明确标注需要验证右边这几种写法的共同点是可检验。你读完能判断模型有没有做到。抽象人设没法验证所以模型也就随便发挥了。我在自己的模板里会把角色定义拆成身份和行为准则两段身份一句话行为准则列五到八条每条都写得能被检查。3.2 约束表达必须、应该、可以的三级强度从样本里我总结出一个三级强度体系用起来很顺手。第一级是必须用于安全和格式这类不能妥协的规则第二级是应该用于风格和内容倾向这类有弹性的要求第三级是可以用于给模型的自由度提示告诉它哪些地方不必拘束。关键是要把这三个词用一致。我见过一份提示词前半段说必须用中文回答后半段又说尽量保持原语言模型遇到英文输入时就分裂了。所以我在写模板的时候会专门做一遍冲突扫描把所有硬约束列出来逐条检查有没有互相打架的地方。这一步花不了十分钟能省掉后面大量的调试时间。另外条件分支尽量写成显式的 if-then。比如如果用户的问题涉及账户安全则先要求验证身份再讨论具体内容。显式分支的好处是你后面做回归测试时可以直接按分支来设计用例覆盖率一目了然。3.3 结构化输出的三种强制手段如果你的下游要解析模型输出光靠请返回 JSON是不够的。我用过的三种手段按可靠性排序第一种是标签包裹。要求模型把结果放在固定标签里比如answer.../answer然后你从字符串里正则提取。这个最省事兼容所有模型缺点是模型偶尔会忘记闭合标签。第二种是给一个空壳模板让它填。直接把 JSON 结构连字段名和类型一起写进提示词甚至给一个填好的示例。示例的作用很大模型会模仿它的字段顺序和格式。注意示例要用假数据而且要和真实字段类型一致。第三种是调用模型的结构化输出参数比如 JSON mode 或函数调用。这个最稳但受模型和接口能力限制不是所有场景都能用。我的建议是二三层叠加提示词里写清结构同时开启接口层的结构化约束双保险。如果只有提示词这一层那一定要在代码里做好兜底解析解析失败就走降级逻辑别让整个链路崩掉。import json import re def extract_json(text: str): # 优先匹配代码块 block re.search(rjson\s*(.*?), text, re.S) raw block.group(1) if block else text # 退化方案截取第一个大括号到最后一个大括号 start, end raw.find({), raw.rfind(}) if start -1 or end -1: return None try: return json.loads(raw[start:end 1]) except json.JSONDecodeError: return None这段兜底逻辑我几乎每个项目都会带上。别看它简单线上能救回不少因为模型多说了一句话导致的解析失败。3.4 长提示词的分层组织与 token 预算当提示词超过一千字组织方式就变得重要了。我在样本里看到过两种主流组织法一种是按职责分块身份、能力、约束、格式另一种是按场景分块新用户场景、老用户场景、异常场景。前者适合功能单一的产品后者适合分支多的产品。我自己的习惯是混着用一级按职责分二级在场景里按流程分。每个章节开头写一句话概括这节要解决什么然后再列细则。这个章节摘要句很关键长上下文里模型对每节的开头印象最深摘要句相当于给它的一个锚点。token 预算方面我给自己的经验值是纯文本问答类应用系统提示词控制在 600 到 1200 token 之间比较舒服带工具调用的可以放到 2000 以内因为工具描述本身就占地方。超过这个量级就要开始考虑压缩了压缩的优先级是先砍重复表达再砍过于细碎的示例最后才动硬约束。提示别迷信提示词越长效果越好。我做过对比同样任务下一个 800 token 精炼版本和一个 2500 token 啰嗦版本前者在多数场景下表现更好延迟还低。冗余内容会稀释关键指令的注意力权重。4. 动手复现搭一套自己的系统提示词模板光看不练没用。下面把我现在项目里在用的模板方案完整走一遍包括目录结构、模板写法、渲染逻辑和评测流程。这套东西不复杂但胜在可维护。4.1 需求梳理与信息分层动手写之前先做一件事把所有需要模型知道的信息列出来然后分三层。第一层是永远不变的比如身份、硬约束、输出格式第二层是随配置变的比如语气风格、详细程度、语言偏好第三层是随请求变的比如当前时间、用户等级、可用工具。分层的目的决定了你后面怎么存。第一层直接写死在模板文件里第二层放配置文件可以按环境或版本切换第三层在代码里渲染。我见过不少项目把三层混在一个巨大的字符串里改一个语气词要翻半天还容易改错。4.2 模板骨架与变量注入我用的是简单的字符串模板不引入重框架。目录大概长这样prompts/ system_base.md # 第一层身份、硬约束、输出格式 styles/ concise.md # 第二层风格配置 detailed.md tools/ search.md # 第三层按需拼装的工具描述渲染的时候按顺序拼接中间用分隔标题隔开。拼装的伪代码大概是这样from pathlib import Path BASE Path(prompts) def render_system_prompt(style: str, tools: list[str], ctx: dict) - str: parts [(BASE / system_base.md).read_text(encodingutf-8)] parts.append((BASE / styles / f{style}.md).read_text(encodingutf-8)) for t in tools: parts.append((BASE / tools / f{t}.md).read_text(encodingutf-8)) body \n\n.join(parts) # 上下文注入放在最后避免污染前面的硬约束 if ctx: lines [f- {k}: {v} for k, v in ctx.items()] body \n\n## 运行时上下文\n \n.join(lines) return body有个细节值得说运行时上下文我放在最后而不是最前。原因是我实测过把动态信息插在开头会打断硬约束的连贯性模型更容易在长上下文里丢掉中段的规则。放最后前面那一大块规则是连续的一块整体服从度更稳。4.3 评测与迭代建一套回归用例集这是我觉得最被低估的一环。大部分团队改提示词靠感觉改完试几个 case 觉得不错就上线过两天又发现新问题然后开始来回横跳谁也不知道哪一版更好。我的做法是维护一个小的用例集三十到五十条就够覆盖四类正常请求、边界请求、越界请求、格式敏感请求。每次改提示词跑一遍全集记录通过率。同时用同一个模型、同一组参数跑保证可比性。用例集不要一次写完从线上真实 badcase 里挑。我一般会在日志里加一个标记功能遇到坏 case 一键存进用例库。这样用例集会随着产品迭代自然长大覆盖的都是真实痛点比凭空想出来的测试题有用得多。还有个小技巧同一个用例跑三次看结果是否一致。提示词的稳定性比单次效果好更重要一个十次里对七次的提示词比一个十次里对九次但偶尔崩一次的更适合生产环境。5. 常见问题与排查实录前面讲的是设计这部分讲踩坑。下面这几个问题我在不同项目里反复遇到整理成速查表方便对照。5.1 模型不遵守指令的几类原因现象可能原因排查方向格式要求时灵时不灵约束写在 user 层或位置靠后移到 system 末尾并加必须长对话后期开始跑偏系统提示词被上下文稀释检查拼接顺序必要时每轮重述关键约束复杂条件分支漏执行分支用自然语言平铺层次不清改成带编号的显式 if-then越界请求没拦住缺少明确的拒答话术模板补一段拒答规则给出示范说法输出语言偶尔漂移没有区分回答语言和引用语言把语言约束拆成两条分别写清这张表是我从日志里一点点攒出来的。你会发现大部分问题不是模型不行而是提示词结构或者位置出了问题。改结构往往比换模型见效快成本还低。还有一种情况比较隐蔽提示词里存在互相矛盾的约束模型自己选了一个执行。这种问题用肉眼扫很难发现我的办法是写个脚本把提示词按句切分人工过一遍专门找必须/不要/只能这类词看有没有两条规则作用在同一个行为上却给出相反要求。5.2 提示词长度与效果的取舍这个问题我被问过很多次。我的一般性结论是长度和效果的关系是一条先升后平的曲线拐点大致在信息密度开始下降的地方。判断信息密度有个土办法——把提示词念出来如果念到某一段你自己都觉得这不是废话吗那就是该删的地方。具体操作上我会做两轮压缩。第一轮删重复把表达同一个意思的多句话合并成一句。第二轮删示例保留最能说明格式的那个其余砍掉。做完这两轮长度通常能降三四成效果基本不变有时候还更好。还有一点容易忽略长提示词会显著增加每次请求的成本和延迟。如果你的应用是高频调用这部分开销累起来很可观。我之前一个项目把系统提示词从 2200 token 压到 900单次延迟降了两百多毫秒用户侧的体感改善相当明显。5.3 多轮对话里系统提示词的衰减多轮场景下系统提示词的存在感会随着轮次增加而下降。这个现象在长对话里尤其明显十轮之后模型开始忘了最初的格式要求。应对办法有三种我一般组合使用。第一种是定期重述。每隔几轮在 user 消息前面附一句简短的提醒比如记得保持之前的输出格式。注意这句提醒要短太长会喧宾夺主。第二种是摘要压缩历史把前面对话总结成一段简述替换掉原始的多轮记录这样系统提示词在上下文里的相对占比就回来了。第三种是把最硬的约束搬到每次请求都要经过的中间层比如在服务端拼接时自动附加。这三种方法各有代价。第一种增加 token第二种可能丢信息第三种对架构有要求。我的选择是格式类硬约束用第三种风格类软约束用第一种长对话用第二种控制总长度。6. 研究提示词的边界与职业习惯最后这一节我想聊聊做这件事的分寸因为它确实容易被带偏。研究公开的提示词样本和想办法套出别人没公开的东西是完全两回事。前者是正常的技术学习后者既不明智也不体面。我把自己的原则总结成两条。第一条是学范式不搬文本。任何一份样本我只提取它的结构组织和约束写法从不把整段文字挪进自己的产品。原因很实际那份提示词是为别人的产品形态写的照搬过来大概率水土不服而且文字本身可能有使用条款限制。第二条是不把研究变成对抗。有些人研究提示词是为了找模型的弱点、想办法让它说出本该拒绝的内容。这条路我不走也不建议任何人走。原因不是道德说教而是它没有工程价值——你花在对抗上的时间远不如花在把正常功能的稳定性做好。一个能稳定处理 95% 正常请求的应用比一个能绕过某些限制但时好时坏的应用对业务的帮助大得多。我自己的研究流程现在是这样的先横向读样本找共性再用最小实验验证哪些模式在我的目标模型上有效然后写进模板最后进回归用例集。整个过程闭环在设计—验证—沉淀上不涉及任何灰色操作。这套流程跑熟之后我改提示词的速度比早期快了不止一倍因为手里有模式库和用例集不再靠灵感。一个具体建议给自己建一个 notes 文件专门记哪条约束在哪个模型上有效、失效的边界在哪。我记了大概两年翻回去看最有价值的从来不是那些漂亮的开场白而是这些细碎的、带着具体模型版本号的实践记录。它们不会出现在任何整理仓库里只会出现在你自己踩过的坑里。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价