提示词质检员 · Prompt 体检中心
系统提示词是 Agent 的宪法。但宪法会腐烂——写着写着「绝不」变成「通常避免」,规则互相打架,安全约束悄悄消失,而这个漂移过程没有任何客观标准能发现,直到出事故。
本技能把这件事从玄学变成工程:像代码 lint 一样,在发布前拦住问题;像内审一样,在改版后检出防线变软。
何时触发
- 用户要「体检 / 质检 / lint / 审计 / 打分」一份系统提示词、人格设定、
CLAUDE.md、AGENTS.md、SKILL.md、.cursorrules、GEMINI.md - 用户描述症状:拒绝立场被磨软(refuse-relent)、规则冲突、指令没被执行、回答忽冷忽热、AI 味重
- 用户说「这个提示词帮我看看 / 优化一下 / 有没有问题」
- 用户问「这条规则是不是和那条打架」「我改完会不会破坏原来的约束」
- 提示词被改版后需要「和上一版比一比」
不适用:一次性任务提示词的措辞优化请用 boost 子命令(那是另一套 B1–B10 槽位法);本文主体面向长期运行的系统提示词。
三层架构(关键:分工不能混)
| 层 | 谁做 | 成本 | 性质 |
|---|---|---|---|
| L0 结构层 | 脚本(纯正则/计数/相似度) | ~10ms,零 token,零网络 | 确定性,可复现,可进 CI |
| L1 语义层 | 模型(读 L0 的结构化产物后复核) | 1 轮推理 | 判断,非确定性,必须标注置信度 |
| L2 修复层 | 确定性自动修 + LLM 生成-评估循环 | 按需,有成本门 | 改动,必须备份 + diff |
| D 漂移层 | 脚本(基线快照比对) | ~10ms | 确定性,本技能独有 |
| L3 有效性层 | 脚本(AUC / 混淆矩阵 / 校准表) | ~10ms,零 token | 检验"分数到底有没有用",需要标注语料 |
铁律:检查器不能是模型。 用 LLM 检查写给 LLM 的提示词会陷入循环幻觉,而且结果不可复现。所以 L0/D 永远走脚本,模型只做「读结果 -> 解释 -> 给建议」。这是 opus-mind 的核心架构决策,照搬。
工作流
Phase 1 — 定位对象,跑 L0
python scripts/clinic.py check <目标文件> \
--save-baseline \
--html <输出.html>
- 首次体检:加
--save-baseline立基线(这一步不做,后面就没有漂移可比) - 已有基线时自动做漂移对比(基线默认落在同目录
<文件名>.baseline.json) - 退出码:
0无 P0 /1有 P0 /2用法错误;--strict时 P1 也返回 1 -> 可直接挂 pre-commit
> [!] 文件路径若含中文,用引号包裹;脚本内部已强制 UTF-8。
Phase 2 — L1 语义复核(模型的工作,脚本做不了)
L0 给的是形状,不是对错。读完 L0 输出后,必须补三类脚本无能为力的判断:
- 判定命中是否为真阳性。例如
PQ004-vague命中「适当处理」——如果这段话本身就是在授权裁量,那不是缺陷。模型要逐条复核并把误报剔除,明确说「这 3 条我判断为误报,原因…」。 - 跨段落语义冲突。L0 只能用反义词典抓字面矛盾;「以客户为中心」vs「绝不透露客户信息给任何人」这类深层张力需要人来读。
- 业务合规性。同一句话在医疗 Agent 里合规、在营销 Agent 里违规。L0 不知道业务。
输出纪律:必须区分「脚本判定」与「我的判断」,不要把模型意见包装成检测结论。
Phase 3 — L2 修复(按需,opt-in)
- T1 确定性修复(安全,可自动):填充词、负面框定改写、标题归一。改前必须备份原文件。
- T2 LLM 修复(贵,需确认):走 PromptDoctor 的生成-评估循环——每次生成 5 个候选改写 -> 逐个重新体检 -> 若仍有问题就再生成 -> 最多 10 轮 -> 按「距原版距离」排序交付。多给变体而不是给一个"最佳答案",因为提示词的价值判断权在作者手里。
- 永远不覆盖用户原文。产出
.fixed副本 + 一行式 diff 摘要。
Phase 4 — 建档与漂移
python scripts/clinic.py drift <文件> # 只看漂移
python scripts/clinic.py check <文件> --save-baseline # 把当前版立为新基线
漂移层检出四类事件:承诺削弱(丢了确定性词)、承诺消失、安全条款开关失效、指标恶化(模糊词占比上升 / 醒目标记减少 / 例外条款减少)。
建议把「每次提示词改版必跑 drift」固化进工作流——见 references/drift-protocol.md。
Phase 5 — 汇报
- 给非技术同事:出 HTML 体检报告(浅色底、可归档)
- 给工程:
--json - 给用户:一句话结论 + 最该修的那 1–3 条,不要把 16 条问题平铺给用户
报告怎么说(防止变成噪音)
按危害排序说,不按检测顺序说:
- 先说结论:总分 + 等级 + 一句话主因
- 再说 P0:能构成真实安全/一致性风险的那几条,每条给「症状 -> 后果 -> 改法」
- 然后按需折叠:P2/P3 只在用户要求时展开
- 永远附诚实边界:健康分是启发式排序工具,不是发布许可;命中不等于错误
复用资源
references/rulebook.md— 完整规则目录:每条规则的判定逻辑、阈值、来源出处(I1–I11 / PQ001–PQ013 / 五类问题模型 / PromptDoctor)references/scoring.md— 评分模型:六维度权重、扣分表、等级带、为什么这样定references/drift-protocol.md— 基线协议:何时建档、CI/pre-commit 接入、漂移阈值校准方法references/evidence.md— 七份原始材料的消化结论 + 论文实证数字 + 我们没实现什么(诚实清单)references/validity-plan.md— 健康分有效性验证方案:用 How to Measure Anything 的方法论(测量=不确定性缩减、Rule of Five、校准、EVPI)回答"这个分数到底有没有用"assets/— 可直接跑通的正反对照样例(agent_v1_young.md98 分 A 级 /agent_v2_rotten.md44 分 F 级),演示「宪法腐烂」。young 样例故意保留 1 条真实 P2(I9b 硬约束落在中部),基线agent_v1_young.baseline.json由当前引擎生成,自比对漂移为 0scripts/selftest.py— 回归套件,14 个用例;PC_SABOTAGE=1可自证能失败scripts/pc_validate.py— L3 有效性验证引擎:读标注语料(JSONL)算 AUC / 混淆矩阵 / 维度对比 / 严重度校准表;--self-test用合成数据自证管线(7 用例)
铁律(违反即不算做完)
- 先跑 L0,再说话。 不许凭语感给出"这个提示词写得不错"这类结论——必须有脚本证据。
- 区分「检测」与「判断」。 脚本输出是检测,模型意见是判断,二者在报告里必须可分辨。
- 命中 ≠ 错误。 每一条都要允许人工推翻;推翻的记录要留在报告里。
- 修必先备份。 任何写入用户提示词文件的操作,先
cp出.bak。 - 样本不足要认怂。 有效词 < 30 或指令行 < 3 时不给分,直说"测不准"。宁可说测不准,也不输出看起来专业的假分数。
- 不做未经验证的断言。 偏见检测的论文自报 F1 是性别 0.93、种族 0.46、性取向 0.13——所以本技能只做"性别默认假设"的提示,一律不下结论。这条边界不许为了报告好看而放宽。
- 不改用户文件除非用户要求。 默认只读体检。
- 改完脚本必须跑
selftest.py;改了断言就必须跑PC_SABOTAGE=1证明它还能失败。 - 分数不是担保。 健康分是"不确定性的缩减量",不是安全保证。任何时候不得表述为"高分 = 安全"或"分数达标即可上线"——那是把测量当承诺。
- 注入面修复一律标为缓解措施。 Greshake et al. 原话:"目前难以想象对对抗性提示词存在万无一失的解法"。所以输出不得声称"已修复注入漏洞",只能说"已收窄注入面"。
- 对外声称"这个分数有用"之前,必须先跑 L3。 没有标注语料时只能说"待验证",不能说"已证明有效"。
已知边界(诚实清单)
- 全部 L0 检查是正则/计数/相似度,不理解语义。它是筛子,不是判官。
- 相似度用
difflib.SequenceMatcher/ 字符 4-gram Jaccard,不是语义嵌入。因此「措辞完全不同但意思重复」的冗余查不出来(PromptQC 用 80MB 嵌入模型做这件事,我们选择不引入依赖换确定性)。 - 模糊词占比、数字密度等阈值是我们自己的操作化定义,不是 opus-mind 官方实现(其归一化口径未公开)。已集中在
pc_core.py顶部常量,便于统一校准。 - 不做真实注入攻击测试。 PromptDoctor 的做法是把 42 条已知攻击串逐个注入每个 Prompt Hole 再打真实 LLM 看是否命中靶串——那需要攻击语料库 + 真实 LLM 调用。我们只做静态注入面评估(洞是否沙箱化、是否有「数据非指令」声明、是否处于首尾高危位)。
- 不做性能优化(PromptDoctor RQ3)。 那需要合成数据集 + BLEU/GLEU/cos-sim/LLM-as-judge 评估循环,属于另一个技能的体量。
- 不检查提示词与代码的一致性(提示词里写"必须输出 JSON",代码里其实解析 YAML,本工具查不出来)。
版权与署名
本技能的脚本、规则目录、评分模型、漂移协议、有效性验证方案均为原创实现。方法论与检测思路参考以下公开来源,仅引用其方法名、结论与公式级表述,包内不含任何原文摘录或成体系复述:
- PromptDoctor(arXiv:2501.12521)— Prompt Hole 定位、"生成-评估循环"改写法、偏见检测的自报 F1 与其自身局限(本技能据此对偏见只提示、不下结论)
- Lost in the Middle(arXiv:2307.03172)— 长上下文的 U 形注意力曲线与 query-aware contextualization(I9b「硬约束勿落中部」的实证依据)
- The Attack Surface of Indirect Prompt Injection(arXiv:2302.12173)— data / instruction 界限模糊的根因、各缓解措施的逐条评价与"难以想象万无一失的解法"(本技能据此把注入面修复一律标为缓解而非根治)
- PromptQC(PyPI: promptqc)— PQ001–PQ013 规则分类体系与规则码命名
- opus-mind(公开技术文章)— 11 条结构不变量 I1–I11、BOOST 槽位 B1–B10、"检查器不能是模型"的架构决策
- System Prompt Linter(在线工具)— 五类问题分类与"健康分"命名习惯
- How to Measure Anything in Cybersecurity Risk(Douglas W. Hubbard, Richard Seiersen)— 测量 = 不确定性的定量缩减、Clarification Chain、Rule of Five(93.75%)、校准与过度自信、EVPI 闸门(L3 有效性层的方法论来源)
使用许可:可免费使用、修改与二次分享,保留上述溯源与署名即可。本技能输出的是启发式排序工具,不构成任何安全或质量担保。
作者与联系方式
本 skill 由「七仔的AI工具箱」维护。欢迎就技能使用、问题反馈与二次分享交流:
- 微信公众号:七仔的AI工具箱
- 抖音号:七仔的AI工具箱
- CSDN 博客:七仔的AI工具箱
本 skill 可免费使用与二次分享;转载请注明出处「七仔的AI工具箱」。