尧图精选

系统提示词样本库拆解:system_prompts_leaks 提示工程实践

🕒 发布时间:2026/9/18 3:11:47 📁 来源:尧图网络
1. 先把 system_prompts_leaks 这个标题拆开看第一次看到system_prompts_leaks这个仓库名很多人的第一反应是这又是个蹭热度的东西。但只要你在提示工程这条路上认真走过半年以上就会明白它真正解决的是一个非常实际的问题我们平时写 prompt 全靠拍脑袋而大模型产品背后的系统提示词system prompt长什么样几乎没人能完整看到。system_prompts_leaks这个项目做的事情其实很朴素——它把各家大模型产品对外暴露出来的系统提示词收集、整理、归档到一起形成一份可以横向对比的样本库。热搜词system_prompts之所以一直有热度本质上不是因为大家猎奇而是因为系统提示词是当前阶段最接近官方提示工程答案的公开材料。它不像网上流传的提示词大全那样东拼西凑而是从真实产品里出来的、经过实际流量验证的文本。我在做完几个基于大模型的对话产品之后越来越确信一件事提示词的质量差距80% 不在辞藻而在结构。而系统提示词恰恰是结构最讲究的一类 prompt。它要同时处理身份定义、能力边界、工具调用、格式约束、安全兜底这五件事还要保证在不同用户、不同输入下都稳定输出。这种东西你自己从零设计可能要迭代几十个版本而直接看别人整理好的样本你能在几小时里把业界大概长什么样这件事摸清楚。这篇文章面向三类人一是刚接触提示工程、还没写过超过两百字 prompt 的新手二是已经在做对话类产品、需要系统性优化提示词的开发者三是对大模型行为机制感兴趣、想搞清楚为什么模型会这样回答的研究型读者。不管你在哪一档读完之后你应该能独立完成三件事看懂一份系统提示词的骨架、自己搭一个提示词分析的小工作流、以及避开抄提示词时最容易踩的那几个坑。下面我不打算按仓库介绍—文件列表—使用方法这种流水账来写而是按我自己真正会用到它的顺序来讲先讲清楚一份系统提示词内部的模块划分再讲这些样本里反复出现的写法模式然后是我自己搭的一套本地分析流程最后是踩过的坑。2. 一份系统提示词到底由哪几块拼成很多人以为系统提示词就是你是一个专业的助手请用友好、专业的语气回答这么一句话。看完system_prompts_leaks里那些真实样本之后你会发现产品级系统提示词的复杂度和这段话不在一个数量级。一个成熟产品的系统提示词通常在两千到上万字符之间而且内部是有明确分区的。我把它归纳成五个模块下面逐个拆。2.1 身份定义块决定模型站在谁的角度说话身份定义块通常出现在提示词最开头作用是给模型一个稳定的自我认知。它的写法有个演进过程早期就是一句You are a helpful assistant.后来变成带公司信息、带职责描述的段落再后来会细化到你不代表公司发表法律意见你不知道未来发生的事这类边界声明。为什么这个块要放最前面因为大模型的注意力在长上下文里是会被稀释的越靠前、越反复出现的内容对最终输出的锚定作用越强。我实测过一个很明显的现象把身份定义从开头挪到中间模型在长对话里忘掉自己是谁的概率会明显上升。所以如果你自己写系统提示词身份定义放最前面并且在结尾再简短复述一次是个成本极低但收益很高的做法。这里有个容易忽略的细节身份定义不只是你是谁还隐含了你的知识截止到哪、你的信息来源是什么、你在不确定时怎么办。很多样本里会专门写一段类似如果用户询问你没有把握的信息你应该说明这一点而不是猜测的话。这段话看起来像废话但它直接决定了模型会不会一本正经地胡说。我自己在做知识问答类产品时光加这一句用户投诉答非所问的比例就降下来一截。2.2 能力清单与工具规则告诉模型你能干什么、怎么干第二个模块是能力清单。如果这个产品支持联网、支持调函数、支持读文件那么系统提示词里一定会有一大段描述这些能力的文本。这部分的技术含量最高因为它涉及工具调用的触发条件和参数约束。举个典型的写法逻辑样本里常见的形式是这样的先列出有哪些工具每个工具一句话说明用途然后写什么时候该用、什么时候不该用最后写调用格式和失败处理。关键在于中间那层什么时候不该用——很多新手写工具提示词只写你可以调用搜索工具结果模型会在一句简单的常识问答上也去联网搜索既慢又浪费。我自己总结的一条经验是在工具规则里负面约束的价值往往高于正面描述。比如当用户问的是通用常识、数学计算、或你已经确定答案的内容时不要调用搜索这种话比你可以在需要时调用搜索有用得多。system_prompts_leaks里那些经过大规模验证的样本几乎都有这类负面清单这不是巧合是被真实流量教育出来的结果。2.3 输出格式约束让模型的回答长得可控第三个模块是格式约束。这部分直接决定了你拿到的是 Markdown、纯文本、JSON 还是带特定标签的结构化内容。如果你在做的是后端对接场景格式约束的重要性甚至高于内容质量——格式错了下游解析直接崩。样本里的格式约束写法大致分三档。最轻的是风格描述比如回答简洁避免冗长中间档是结构描述比如先给结论再给理由最后给例子最重的是严格格式比如必须输出合法的 JSON不要加任何解释文字不要用代码块包裹。这三档的约束力完全不同用哪档取决于你的下游怎么消费输出。注意格式约束写得越严格模型的自由发挥空间就越小创造力也会被压制。如果你的场景是创意写作别把格式卡太死如果是数据抽取那就往死里卡。这里有个实操技巧是我反复验证过的把格式要求写成模板 反例比只写模板效果好得多。比如你只写输出如下 JSON{...}模型有时会在 JSON 前后加一句好的这是结果。但如果你补一句不要输出 JSON 以外的任何字符包括不要用 json 包裹这个问题的消失率非常高。原理很简单——反例给了模型一个明确的禁区而模板只给了目标。2.4 安全与拒答策略产品能不能上线的隐形门槛第四个模块是安全兜底。这部分在开源样本里经常被简化但在商业产品的系统提示词里篇幅往往不小。它主要处理三类情况用户请求超出产品能力范围、用户请求涉及不当内容、用户试图让模型偏离既定角色。拒答策略的写法很有讲究。粗暴的拒绝一切敏感问题会导致模型过度拒答用户问个正常问题也被挡而只写注意安全又等于没写。样本里比较成熟的做法是分层处理明确列出坚决不做的少数几类明确列出可以做但要加说明的中间地带剩下默认正常处理。这种分层逻辑其实和写业务代码里的参数校验是一个思路——边界清晰避免全盘否决。2.5 上下文与变量占位让提示词活起来最后一个模块容易被忽视就是变量占位。真实产品的系统提示词不是静态文本里面会嵌入当前时间、用户昵称、用户所在地、订阅等级、历史偏好等动态信息。这些东西在样本里通常以占位符形式出现比如{current_date}、{user_name}这类标记。为什么要单独拎出来讲因为很多人抄系统提示词时直接把这些占位符也一起抄进去了结果模型看到{user_name}这种字面量输出就变得很奇怪。这部分我在后面的避坑章节还会细说。理解占位符的意义在于你要能区分哪些文本是固定指令哪些是运行时注入抄的时候只抄前者后者要根据自己的业务自己实现。3. 样本里反复出现的几种写法模式把几十份系统提示词并排放在一起看你会发现一些明显重复出现的套路。这些套路不是谁规定的而是大家在实际调优中收敛出来的结果。我把最值得学的三种挑出来讲。3.1 分节结构化用标题把长提示词切成块第一种模式是分节。几乎所有的长系统提示词都会用某种标记来分节常见的是 Markdown 标题、大写关键词、或者自定义的分隔符。比如样本里经常出现这种写法## Role You are ... ## Capabilities You can ... ## Guidelines - ... - ... ## Output Format ...这种写法的好处是让模型能快速定位到现在这段在讲什么。类比一下这就像给一本书加目录——模型读长文本时目录能帮它建立结构感。我自己做过一个对照实验同样内容的提示词一份分成五节一份揉成一大段在需要模型严格遵守多项约束的任务上分节版本的遵循率明显更高。但这里有个坑分节标记本身如果太花哨比如用一堆特殊符号、用很长的分隔线反而会干扰模型。我一般建议用最朴素的 Markdown 二级标题或者全大写的短词别搞创意。3.2 条件分支写法把如果……就……写清楚第二种模式是条件分支。产品级提示词里大量使用If the user asks X, then do Y这种句式。原因很直白真实用户的输入千奇百怪你不可能给每种情况都写一条独立规则只能靠条件分支来覆盖。条件分支写得好不好有个很实用的判断标准看它有没有覆盖边界情况。新手写的分支往往只覆盖正常路径比如如果用户要翻译就翻译而成熟样本会写如果用户要翻译先判断是否已经是目标语言如果是则直接告知不要重复翻译。这种对边界的处理正是从真实投诉里长出来的经验。3.3 变量占位与模板化把可变部分抽出去第三种模式是模板化。这个前面提过这里从怎么用的角度再说细一点。模板化的核心思想是把不会变的部分固化把会变的部分参数化。这样做的好处有两个一是提示词可以版本管理改一处生效全局二是可以针对不同用户群体注入不同参数实现个性化而不需要维护多份提示词。实际操作中我通常会把系统提示词存成模板文件用最简单的字符串替换来注入变量。不一定要上复杂的模板引擎str.replace或者格式化字符串就够用了。真正要注意的是转义和安全——如果注入的是用户可控内容一定要防止用户内容里包含能改变指令的文本。这点很多人在做原型时不在意上线后就容易出问题。4. 我自己的提示词分析工作流光看不练没用。我用system_prompts_leaks这类样本库时不会一份份读过去而是搭了一套小流程让机器先帮我做粗筛我再人工看重点。下面完整讲一遍这套流程你可以直接照搬。4.1 第一步数据整理与统一格式收集到的样本来源不同格式很乱——有的是纯 txt有的是 json有的还带元信息。第一步就是统一成一种结构。我一般用 jsonl每行一个 JSON 对象字段就四个name产品名、content提示词正文、source来源标记、collected_at收集时间。import json import os from datetime import datetime records [] for fname in os.listdir(raw_prompts): if not fname.endswith(.txt): continue with open(os.path.join(raw_prompts, fname), r, encodingutf-8) as f: text f.read().strip() records.append({ name: os.path.splitext(fname)[0], content: text, source: local_archive, collected_at: datetime.now().strftime(%Y-%m-%d), }) with open(prompts.jsonl, w, encodingutf-8) as f: for r in records: f.write(json.dumps(r, ensure_asciiFalse) \n)这一步看着简单但它决定了后面所有分析能不能自动化。我之前图省事直接在原始文件上做统计结果因为编码和换行符不一致统计出来的字符数全是错的白白浪费时间。4.2 第二步结构化统计找到共性统一格式之后先做一轮轻量的统计分析目的是找到样本之间的共性。我关注的指标有三个字符长度分布、章节数量分布、高频指令词分布。import json import re from collections import Counter with open(prompts.jsonl, r, encodingutf-8) as f: data [json.loads(line) for line in f] lengths [len(d[content]) for d in data] section_counts [len(re.findall(r^#{1,3} , d[content], re.M)) for d in data] instr_words Counter() for d in data: for w in [must, should, never, always, avoid, do not]: instr_words[w] len(re.findall(rf\b{w}\b, d[content], re.I)) print(样本数:, len(data)) print(长度中位数:, sorted(lengths)[len(lengths)//2]) print(平均章节数:, sum(section_counts) / len(section_counts)) print(高频指令词:, instr_words.most_common())跑完这些统计你会得到一些很有意思的结论。比如我这边跑下来发现长度中位数大概在三千多字符章节数普遍在 4 到 8 之间。这说明什么说明产品级系统提示词不是越长越好而是够用就好结构清晰比堆砌内容更重要。而高频指令词里should和never的量级直接反映了各家的约束风格松紧。4.3 第三步按模块切分建立对比表统计只是粗筛真正有价值的是把每份提示词按前面讲的五个模块切开然后横着比。这一步我没找到能完全自动化的办法因为分节方式各家不同硬写规则容易误切。我的做法是半自动先用关键词定位大概位置再人工确认最后填进一张对比表。模块常见出现位置典型长度占比我主要看什么身份定义开头 10%10%~15%边界声明的表述方式能力与工具中前段20%~35%负面约束的多少和具体程度输出格式中后段10%~20%是否给了反例安全兜底后段5%~15%分层拒答还是全盘拒答变量占位分散不定哪些字段被参数化这张表是我用得最频繁的工具。每次要设计一个新场景的提示词我会先翻一遍表看看同类场景别人是怎么分模块的然后照着这个比例关系搭自己的骨架。4.4 第四步抽象出可复用的模板骨架做完对比最后一件事是把共性抽象成一个自己的模板骨架。别直接抄某一份而是取长补短。我现在的通用骨架大概是这样## Role [身份 知识边界 不确定时的处理原则] ## Capabilities 你可以[正向能力清单] 你不应该[负面约束清单] ## Workflow 1. [第一步该做什么] 2. [判断条件分支] 3. [输出前自检] ## Output Format [模板 反例] ## Safety [分层拒答策略]这个骨架我自己用了大半年覆盖了问答、写作、数据抽取三类场景改的主要是各段的具体内容结构基本不用动。这就是分析样本库的最大价值——它不是给你答案而是给你一个已经被验证过的结构。5. 抄提示词最容易踩的几个坑讲完怎么写必须讲讲哪几种写法会翻车。这些坑我基本都亲自踩过写出来帮你省时间。5.1 占位符原样抄进去这是最高频的错误。你把某份样本复制过来里面带着{user_name}、{{current_date}}这类占位符如果你的程序没有对应的替换逻辑模型就会看到一串花括号。更糟的是如果用户输入里碰巧也有类似结构模型可能会把它误当成指令。我一般的处理原则是抄任何提示词之前先全文搜一遍花括号和{{ }}把每一个都确认清楚是固定文本还是变量。固定文本的转义处理掉变量的补上自己的替换逻辑。别嫌麻烦这一步省下来后面排查 bug 的时间十倍都补不回来。5.2 直接照搬语气描述第二个坑是照搬语气。样本里经常有You are friendly, warm, and professional这种话你直接抄过来但你的产品定位可能是严肃的专业咨询结果模型语气软绵绵反而显得不专业。语气描述这东西和产品调性强绑定不能跨场景复用。我的建议是别抄语气形容词抄行为描述。比如与其写友好热情不如写用户提出问题后先确认理解再给答案遇到不确定的信息主动说明。行为描述是可执行、可验证的语气形容词不是。5.3 忽略版本与时间差异第三个坑是忽略时间。大模型的能力和产品形态都在快速变化一份半年前的提示词可能在今天的环境里表现完全不同。有的写法是针对当时某个具体的模型行为做的补丁模型升级后这个补丁不仅没用还可能反作用。所以我在整理样本时一定会记录收集时间并且在使用前做一轮小规模回归测试。具体做法是准备十个左右的典型输入分别跑新旧提示词对比输出。只有当新版本在大部分用例上不劣于旧版本才正式替换。这套流程听着重但比上线后被用户投诉要轻得多。6. 常见问题排查速查表最后把经常被问到的问题整理成一张表都是我实际被问过、也实际解决过的。现象可能原因排查动作模型忽略格式要求格式约束放在太靠后或没给反例把格式段前移补一句不要输出额外内容长对话后角色漂移身份定义只出现一次在提示词结尾复述一次身份与边界工具被过度调用缺少负面使用条件补充以下情况不要调用工具清单输出前后多出客套话约束里没禁止明确写不要以好的开头不要加总结换行结构被压平格式要求与模型默认行为冲突用显式标记如\n说明或标签强化变量没生效占位符未替换或转义错误打印最终拼好的提示词肉眼检查一遍提示排查这类问题时最高效的调试手段是把最终拼装好的系统提示词完整打印出来。我见过太多人对着模板文件调半天结果问题出在拼装环节模板本身没毛病。还有个小技巧分享一下当你拿不准某个约束该不该加时先去掉它跑一轮再单独加它跑一轮对比两次输出。很多约束其实是冗余的去掉之后模型表现没变化那就说明它占位置但不产生价值应该删掉给更重要的规则腾空间。提示词的空间不是无限的尤其在上下文窗口有限或者按 token 计费的场景里每一句都该有存在理由。7. 我在实际使用中的几点体会做了这么多轮提示词的拆解和重构我最深的一个体会是系统提示词这个东西看一百份不如自己重写一份。你光是读样本会觉得哦原来是这样但真正动手把自己的场景套进那个骨架里你会发现每一段都有无数个具体决策要做——边界声明写多细、负面清单列几条、格式约束卡多严。这些决策做多了你对模型行为的直觉才真正建立起来。另一个体会是关于抄这件事的边界。把公开样本当作学习素材研究它的结构、写法、约束思路这完全没问题也是提升效率的正道。但直接拿别人的完整提示词去跑自己的商业产品风险很大一是那些文本可能和你产品的价值观、合规要求不完全一致二是它针对的是别人的模型行为和用户群体迁移过来未必成立。我的做法一直是看结构、自己写内容这样既省力又安全。最后一个建议给你的提示词建版本管理。哪怕就用最简单的 Git把每次调整和对应的效果变化记下来。三个月后你回头看会发现自己踩过的坑、验证过的写法都在里面这份记录比任何网上的提示词大全都值钱因为它是针对你自己场景的。system_prompts_leaks这类样本库能给你的是横向参考而真正让产品跑起来的永远是你自己在纵向迭代中积累下来的那套经验。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →