ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

系统提示词工程:从system_prompts_leaks到本地对照库

系统提示词工程:从system_prompts_leaks到本地对照库 做AI应用这两年我硬盘里攒得最多的东西不是模型权重也不是训练数据而是一堆整理好的系统提示词。system prompts这层东西说白了就是把一个通用大模型捏成某个具体角色的那层胶水——同一颗底座模型套上不同的系统提示词出来的效果能差出十万八千里。所以当system_prompts_leaks这类合集项目在圈子里传开的时候我第一反应不是猎奇而是把它当成一份免费的、活的提示工程教材来读。这篇文章就是我读了几百份样本之后关于怎么采集、怎么整理、怎么对比、能学到什么、哪里会踩坑的一次完整复盘适合正在做AI产品、写提示词、或者单纯想搞懂大厂产品是怎么设计角色的人参考。不管你是刚接触提示工程的新手还是已经写过几百行提示词的老手这里面的整理思路和避坑经验应该都用得上。严格讲system_prompts_leaks这类项目的核心价值不在于泄露这个噱头而在于它把原本散落在各个角落、格式五花八门的系统提示词统一收拢成了一可比对、可检索、可版本追踪的语料库。这件事本身就很有工程含量采集只是第一步清洗、去重、标注来源、追踪版本变化每一步都有坑。下面我按自己实际整理的经验从项目定位、结构拆解、采集流程、可复用套路、问题排查到自建对照库一层层讲清楚。1. 这个项目到底在做什么1.1 系统提示词是什么为什么值得被反复研究系统提示词system prompt是大模型对话接口里优先级最高的一段文本通常由产品方预设用户看不到、也改不了。它的作用是给模型设定身份、能力边界、语气风格、输出格式和一系列约束规则。你可以把它理解成给一个刚入职的员工发的《岗位说明书》告诉他你是谁、你负责什么、遇到什么情况该拒绝、回答要写成什么样子。为什么值得研究因为它是产品感的来源。一个AI助手是活泼还是严肃是先反问还是直接答是给长文还是给要点是主动调用工具还是等你指令——这些体验差异八成以上是靠系统提示词调出来的而不是靠换模型。我做过一组对照测试同一套业务问题只换系统提示词里的语气和格式约束用户满意度问卷的差异能到20个百分点以上。所以对一个做AI产品的团队来说读懂竞品的系统提示词本质上是在读它的产品设计文档。system_prompts_leaks这类合集之所以有生命力就是因为它把这种产品设计文档规模化地展示了出来。你不需要自己去一个个产品里试探直接横向对比几十份样本就能看出哪些写法是行业共识哪些是某家的独门技巧。1.2 这类合集项目的内容组织方式我翻过的几个同类项目组织方式大同小异基本是按产品/厂商分目录 单文件存原始文本 一份索引表的三层结构。目录层面通常按厂商或产品名切分比如anthropic/、openai/、google/这种单文件里放的是原样文本尽量不改动顶多在文件头加几行注释说明采集时间和来源索引表则记录产品名、版本、采集日期、文件路径、字段完整度。这种结构看起来朴素但非常合理。原因有三点一是保留原始文本方便做diff任何改动都可能引入偏差二是按厂商分目录符合阅读时的对比习惯你想看两家头部产品在拒绝策略上的差异直接开两个文件对照就行三是索引表提供了元数据层检索和统计都靠它。提示如果你打算自己复刻一套强烈建议把原始文本和你的分析笔记彻底分开存放。混在一起写三个月后你自己都分不清哪句是原文、哪句是你加的批注。我见过一些新手整理版本把原文和分析写在同一个文件里还用高亮标记改动结果diff工具直接失效版本追踪全废。这个坑我踩过后来老老实实做了raw/和notes/两个目录raw/只读、只追加notes/随便写。1.3 预期的读者和使用场景分别是什么这类项目的受众其实挺分层的。第一层是做提示工程的产品同学他们的诉求是抄作业想看别人怎么处理长上下文、怎么做多轮澄清、怎么兜底拒答第二层是做AI安全评估的研究者他们的诉求是横向统计哪些约束被反复强调、哪些风险场景被显式覆盖第三层是纯好奇的技术爱好者想搞明白自己每天用的AI助手背后到底被下了什么指令。不同受众对同一份语料的用法完全不同所以一个好的合集项目不会只堆原文还会提供一些基础的分析视角比如标注出每份提示词里的角色定义段、约束段、格式段、工具段让不同需求的人各取所需。我在自己维护的小库里就做了这样的分段标注后面第6章会讲具体怎么做。2. 系统提示词的骨架从典型样本看结构2.1 一份完整系统提示词的通用骨架翻了几十份之后我发现结构再花哨的提示词基本都能拆进这七个模块里身份定义你是谁、由谁开发、定位是什么。能力清单能做什么、知识截止时间、是否联网、是否支持多模态。行为准则语气、风格、主动程度、追问策略。约束与边界不能做什么、什么情况下拒绝、拒绝时怎么表达。输出格式markdown 还是纯文本、长度偏好、列表还是段落。工具约定如何调用外部工具、参数怎么传、失败怎么回退。上下文管理长对话怎么压缩、历史信息怎么取舍。这七块不是每份都齐全但顺序上高度一致几乎都是先立身份再划能力再定风格最后加约束和格式。这个顺序有它的道理——大模型的注意力对开头和结尾更敏感把最重要的身份信息放开头把最容易违反的约束和格式放结尾是被反复验证过的排版策略。注意这不是玄学是有实测支撑的。业界常说的中间遗忘现象指的是长上下文里位于中段的信息更容易被忽略。所以放中间的内容通常是不那么关键但需要存在的细节比如工具参数的完整说明。2.2 不同场景下的写法差异对比同样是系统提示词面向消费者的对话助手、面向开发者的代码助手、面向企业的客服机器人写法差异非常大。我整理了一张对照表用我实际读到的样本特征来总结维度通用对话助手代码助手企业客服机器人身份定义长度中通常三五句短一句话带过长含企业名、业务范围能力清单强调知识边界与时效强调语言与框架支持强调可查询的业务系统语气约束非常细常带示例简略偏技术直给严格模板化禁用词列表拒绝策略分类讨论有回退话术少见多转为提示风险强约束需转人工输出格式轻约束鼓励自然表达强制代码块与语言标注结构化字段为主工具约定少中常见文件与命令工具多需对接工单与查询接口从这张表能看出一个规律越是面向不确定的开放场景语气和拒绝策略写得越细越是面向确定的任务场景格式和工具约定写得越细。这其实就是提示词设计里最核心的权衡——自由度和可控性是此消彼长的。你想让模型有创造力就少写死格式你想让模型稳定输出就多写死格式。没有绝对正确的答案只有匹不匹配场景。我见过不少团队在这上面栽跟头做一个创意文案助手却把输出格式约束得死死的结果模型写出来的东西千篇一律用户用两次就腻了。反过来做客服机器人却只写礼貌回答不写禁用词和转人工规则上线第一天就出事故。所以读这些样本时最好别只看写了什么要想为什么这个场景要这么写。2.3 长度分布与信息密度的取舍我做过一个粗略统计随手抽了四十份样本长度跨度从几百字到几千字都有中位数大概在一千五百字上下。但长度和效果没有正相关。有几份非常短的提示词七八百字效果在各自场景里反而是最好的因为它们把每一句都花在了刀刃上没有一句是废话。这背后是一个信息密度的概念。系统提示词不是越长越好因为每多一句规则模型就多一份注意力负担规则之间还可能互相冲突。我自己的经验是优先写那些不写就一定会错的规则也就是兜底性的、高风险的约束那些不写大多数时候也对的偏好性描述可以往后放甚至靠少样本示例来隐式表达。举个实际的例子与其写你要友好、要耐心、要专业、要简洁、要有同理心不如写一句回答控制在三段以内先给结论来得有效。形容词是给人类看的具体指令才是给模型看的。这个认知是我读了大量样本、又自己做了A/B测试之后才真正建立的。3. 采集与整理流程怎么做3.1 采集渠道与合规边界这一块我必须把话说在前面。我所说的采集指的是公开可获取的资料包括产品官方在文档或帮助中心公开说明的提示词设计、开发者在技术分享中主动贴出的片段、学术论文附录里附上的完整提示词、以及各类开源项目里自带的可商用提示词模板。这些东西本来就是公开的整理它们不涉及任何越界行为。有些工程手段确实能诱导模型吐出一部分系统提示词内容但这属于对产品的探测行为可能违反服务条款也会给平台带来额外的安全成本。我不建议做本文也不展开讲。做提示词研究公开语料足够多了没必要去碰这些边界。我实际维护的库里来源会逐个标注清楚比如来自某产品官方文档、来自某开发者大会分享、来自开源项目某某仓库。标注来源有三个好处一是可追溯发现错误能回溯二是可判断可信度官方来源和社区转述的权重不一样三是合规谁知道你这些东西哪来的一问就能答上来。提示如果你要把整理结果对外分享务必保留来源字段并且只放公开资料的链接不要转存他人未授权的内容。3.2 清洗、去重与版本追踪原始语料到手后别急着用先做三件事清洗、去重、建版本。清洗主要是处理格式噪声。从网页复制来的文本经常带一堆多余空行、全角半角混用、markdown 标记残留。我的做法是写个小脚本统一处理把连续空行压成一个、统一换行符、去掉不可见字符。这一步看着琐碎但不做的话后面做 diff 会满屏都是噪声根本没法看。去重比想象中复杂。简单粗暴的完全匹配去重只解决一小部分问题真正麻烦的是同一份提示词的微小变体。比如同一个产品中文版和英文版、旧版本和新版本、带工具说明和不带工具说明的版本它们相似度极高但不完全一样。我的策略是用相似度阈值做粗筛比如把相似度超过90%的归为一个家族然后人工判断哪些是真正的版本迭代、哪些只是采集时的差异。版本追踪是整个流程里最有价值也最容易被忽略的一环。同一份提示词在不同时间被采集内容有变化这个变化本身就说明了产品方的迭代方向。我给自己定的规矩是每次采集都新建文件文件名带日期绝不覆盖旧文件。然后在索引表里记一条标注变更摘要。半年下来你就能看到一份完整的演进轨迹这东西的价值远超单次快照。3.3 结构化存储与检索存成纯文本没问题但要做横向分析得有一层结构。我的做法是在原始文本之外额外维护一份结构化的元数据表用 CSV 或者 SQLite 都行字段大概长这样CREATE TABLE prompts ( id INTEGER PRIMARY KEY, product TEXT NOT NULL, lang TEXT NOT NULL, collected_at TEXT NOT NULL, source_url TEXT, raw_path TEXT NOT NULL, has_identity INTEGER DEFAULT 0, has_constraint INTEGER DEFAULT 0, has_tool INTEGER DEFAULT 0, word_count INTEGER, version_group TEXT );有了这张表你就能回答很多有意思的问题哪些产品一定会写身份定义带工具约定的样本里平均长度是多少同一产品中文版和英文版的约束条款数量差多少这些问题靠肉眼翻文件是翻不出来的必须靠结构化检索。我在实际使用中最常用的是按version_group聚合把同一产品的多个版本拉出来做时间线。第二个常用的是按has_tool过滤因为工具约定模块的写法差异最能体现产品成熟度值得单独拎出来看。4. 从提示词里能学到什么可复用的套路4.1 角色定义与能力边界的写法角色定义看起来最简单其实最容易被写坏。新手常犯的错是堆形容词你是一个专业的、友好的、知识渊博的助手。这句话对模型几乎没有任何约束力因为它不知道专业和友好在具体场景下意味着什么。我读到的成熟样本角色定义通常是身份 职责 边界三件套。身份说清是谁职责说清主要做什么边界说清不做什么。举一个我自己在用的例子你是某电商平台的售后助手主要负责订单查询、退换货流程指引和物流问题初步排查。 你不处理价格谈判、投诉升级和账号安全类问题遇到这类请求时引导用户转接人工客服。这三句话的信息量远大于一串形容词。它把能做什么和不能做什么都讲明白了模型在实际对话里就不会乱承诺。这就是我推崇的写法用动作和范围来定义角色而不是用形容词来修饰角色。还有一个细节值得注意成熟样本在写能力边界时往往会给出明确的不知道就说什么。比如如果不确定答案直接说你不确定不要编造。这一句看似简单实际能过滤掉大量幻觉。很多团队直到上线后被用户投诉才知道要加这句其实早就有现成答案摆在眼前。4.2 拒绝策略与兜底话术的写法拒绝策略是系统提示词里最考验设计功力的部分因为它要同时满足两个相互冲突的目标既要拦住不该做的事又要让用户觉得体验没有变差。我读到的样本里做得好的通常会把拒绝分成几类每类给不同的处理方式。第一类是明确违规的请求直接拒绝并简短说明原因不展开辩论第二类是超出能力范围的请求说明边界并给出替代方案比如转人工第三类是信息不足的请求不拒绝而是追问补齐信息。这三类的处理逻辑完全不同混在一起写就会导致模型要么过度拒绝、要么乱答应。注意拒绝话术最忌讳的是长篇解释。我见过一份提示词里写拒绝时要详细说明你为什么不能这么做结果模型在被拒场景下一口气输出几百字用户体验反而更差。后来改成拒绝时用一句话说明不要道歉超过一次效果立竿见影。兜底话术也是同样的思路。所谓兜底就是当模型不知道该怎么办时的默认行为。好的兜底是明确 有出路比如这个问题我无法确认建议你通过某某渠道核实而不是含糊的这个问题比较复杂。前者给了用户下一步后者只是把问题丢回给用户。4.3 格式约束与工具调用约定格式约束的核心技巧是给模板别给描述。你想让模型输出固定结构的回答最有效的办法不是描述结构而是直接给一个填空式的模板。比如请按以下格式回复 【结论】一句话结论 【依据】两到三条关键依据 【建议】下一步该做什么这种写法的好处是模型不需要理解抽象描述直接照着填就行稳定性高很多。我做过对比用描述式约束请分三部分回答分别说明结论、依据和建议和模板式约束后者在格式合规率上能高出十几个百分点。工具调用约定则更偏工程。核心要写清楚三件事什么时候该调用工具、参数怎么传、调用失败怎么办。尤其是第三点很多提示词只写了前两点结果工具超时的时候模型不知道怎么办要么干等要么瞎编。我看到的成熟做法是明确写如果工具调用失败向用户说明失败原因并询问是否重试简单一句省掉无数线上问题。还有一个小技巧把工具调用的触发条件写具体。别写需要时调用搜索工具要写当用户询问实时信息、当前日期之后的事件或你知识范围之外的事实性内容时调用搜索工具。前者全靠模型自己判断后者给了明确的判断标准。5. 常见问题与排查技巧实录5.1 整理过程中的常见问题速查表整理这类语料库踩的坑大多集中在几个固定位置。我把遇到频率最高的问题整理成表方便你对照排查现象常见原因排查与解决相似样本大量重复只做了完全匹配去重引入相似度阈值做家族聚类diff 结果全是噪声换行符与空格不统一入库前统一清洗格式找不到某条规则的来源采集时没记来源字段强制索引表填写 source_url版本演进看不出来覆盖式保存旧版丢失文件名带日期只追加不覆盖统计结果对不上元数据标注口径不一致固定标注规范并写进 README分析笔记和原文混淆两者存在同一文件拆成 raw/ 与 notes/ 两目录这张表里我个人认为最值得重视的是元数据标注口径不一致。这个问题初期不明显等语料上百份之后就会爆发因为你前后对是否包含约束的判断标准变了统计出来的趋势全是假的。解决办法很简单就是早点写一份标注规范把每个字段的定义固定下来后续所有标注都对照它。5.2 几个只有实际做过才知道的坑第一个坑是语言版本的对应关系。很多产品的中文版和英文版系统提示词并不是直接翻译关系内容差异可能相当大。我一开始以为是翻译按行对齐处理结果发现根本对不上。后来改成先各自独立整理再人工建立对应关系工作量大了不少但准确率高得多。第二个坑是时间戳的时区。看着是小事当你把几十个来源的采集时间放在一起排序时时区不统一会直接导致版本顺序错乱。我现在的规范是所有时间统一用 UTC 存展示时再转换。第三个坑是过度解读。读到的提示词只是产品方当下的一个快照不代表它的全部设计。我曾经根据某份样本推断该产品不支持多轮追问后来实际使用发现完全支持只是那份提示词不完整。所以做分析时要克制看到什么说什么别脑补。第四个坑是更新频率估计错误。有些产品的提示词几个月不变有些可能两周就迭代一次。如果你用统一频率去采集要么浪费大量时间在不变的样本上要么错过快速迭代的版本。我的做法是给每个产品维护一个活跃度标记活跃度高的提高采集频率低的降低。提示把这四个坑写进项目的 README能省掉后来者大量重复试错的时间。我现在的习惯是每踩一个坑就补一条记录积少成多这份文档比代码本身还有用。6. 自己动手搭一个本地提示词对照库6.1 目录结构与元数据设计如果你打算自己搭一套我建议从这个最小可用结构开始prompts-library/ ├── README.md ├── index.csv ├── raw/ │ ├── product-a/ │ │ ├── 2024-03-01.txt │ │ └── 2024-06-15.txt │ └── product-b/ │ └── 2024-05-20.txt ├── notes/ │ └── product-a-notes.md └── scripts/ ├── clean.py └── diff_report.py这个结构的关键在于raw/目录的组织方式按产品分目录文件名用采集日期。这样你一眼就能看出某个产品采过几次、最新一次是什么时候。index.csv作为唯一的元数据入口所有统计和检索都从它出发。元数据字段我前面给过一版你可以根据自己的关注点增减。我额外加了一个notes字段用来存一句话的变更摘要比如新增了工具调用说明。这个字段在后期做趋势分析时特别有用不用打开文件就能知道每次迭代改了什么。6.2 一段可复用的文本清洗与对比脚本清洗脚本不用复杂核心就是统一格式。下面这段我一直在用import re from pathlib import Path def clean_text(raw: str) - str: # 统一换行符 text raw.replace(\r\n, \n).replace(\r, \n) # 去掉不可见字符 text re.sub(r[\u200b-\u200f\u2028\u2029], , text) # 连续空行压成一个 text re.sub(r\n{3,}, \n\n, text) # 行尾空格清理 text \n.join(line.rstrip() for line in text.split(\n)) return text.strip() def load_clean(path: str) - str: return clean_text(Path(path).read_text(encodingutf-8))对比脚本用标准库就够重点是输出可读的差异报告别直接甩一堆符号import difflib def diff_report(old: str, new: str, label: str ) - str: old_lines old.splitlines() new_lines new.splitlines() diff difflib.unified_diff( old_lines, new_lines, fromfilef{label}-old, tofilef{label}-new, lineterm, n2 ) body \n.join(diff) return body if body else f{label}: 无变化这两个脚本加起来不到四十行但能把最耗时的机械工作自动化掉。剩下的时间就留给真正需要人脑的部分判断哪些差异是有意义的迭代哪些只是采集噪声。注意diff 报告里如果出现大量连续变动先别急着下结论说是大改版。很可能只是格式差异导致的先用清洗脚本过一遍再看。我至少有三次把格式噪声误判成版本迭代白写了半天分析。我自己现在的日常流程是这样每周固定花半小时把活跃度高的产品扫一遍有新版本就入库、清洗、打标签、跑 diff、写变更摘要。整个流程跑顺之后单份样本的处理时间大约五分钟。半年积累下来这份对照库已经成了我写新提示词时的第一参考——很多时候不是去抄而是去看看别人在同类问题上是怎么权衡的然后回到自己的场景里做判断。这个习惯比任何提示词模板都值钱。
返回列表