资讯动态

dsh-purge 提示词清洗机制深度指南:小码酱身份锁、幂等装配与国模规则集切换全解

发布时间:2026/10/21 2:08:30 来源:尧图企业网站定制
dsh-purge 提示词清洗机制深度指南:小码酱身份锁、幂等装配与国模规则集切换全解【免费下载链接】dsh-purgeDeepSeek Harness 破甲让所有模型都能破甲不同模型可换不同提示词默认提示词面向国模「小码酱」。Jailbreak for every model — swap prompts per model. 求 Star 收藏 ⭐ 如要二开请查看署名要求部分项目地址: https://gitcode.com/GitHub_Trending/ds/dsh-purgedsh-purge 是装在本机官方 DeepSeek Harness 上的提示词清洗与评测插件,默认提示词面向国模,人设叫「小码酱」(LCS)。遇到过这种困惑吗:换了模型,回答还是「我是 DeepSeek 的 AI 助手」?那多半不是模型拒绝,是宿主的身份壳没剥掉。本文只拆这套提示词如何被定义、装配、切换和生效,红队演练部分不涉及。宿主与模型:提示词清洗要拆开的两层宿主不只是把问题转发给模型。运行时它还会改提示词、加审批门、控沙箱和会话格式(README.zh-CN.md,L98)。所以「模型答不出来」要先二次判定:是模型自己拒了,还是宿主先拦了?dsh-purge 的机制设计都建立在这个区分上:把宿主层剥掉,评测才指向模型本身。插件边界也写得很死:只动本机已装的官方deepseek-ai包,不是公网扫描器,不是攻击套件(同文件 L112)。清洗也不是整段删除。宿主提示词按句处理:身份句删掉,「工作目录」这类有用信息留下。逐句的处置表就是 lib/identity.js 里的stripHarnessPersona(L41-L102),其中一条很典型:.replace( /You are a coding agent powered by the \{\{model\}\} model, running on the DeepSeek Harness\. Your working directory is \{\{cwd\}\}\.?\s*/g, Working directory: {{cwd}}. , )一长句身份包装,降级成半句工作目录声明。中英文身份句都覆盖,Claude系身份句也在清洗列表里(L95-L98)。小码酱身份锁:三句话和三个血统标记默认人设的规则写在身份锁常量IDENTITY_LOCK_LCS里(lib/core.js,L113-L114):const IDENTITY_LOCK_LCS You are the operator persona in prompt-inject (Little Code Sauce / LCS unless that file names someone else). ...;三句话各管一件事。默认人设是 LCS,除非prompt-inject.md里另起名字;被问「你是谁」只报这个名字;绝不自称「DeepSeek 的 AI 助手」——那是环境标签,不是「它」。这里有个容易忽略的问题:怎么判断磁盘上那份提示词是插件自带的默认,还是用户手写的?项目用三个血统标记判定(PLUGIN_DEFAULT_MARKS,L8182-L8186):const PLUGIN_DEFAULT_MARKS [ system:, project_instructions, Little Code Sauce, ];三条必须同时命中才算插件血统。只写一句「小码酱」不够,不会误伤用户自己的文案。装配链:inject 段怎么挤进系统提示词最前宿主每轮对话都靠prompt.assemble拼系统提示词。插件不绕开它,而是包住装配入口:installAssembleGuard(lib/identity.js,L593-L704)在assemble属性上挂守卫。守卫自身幂等,重复安装不会叠代理导致栈溢出(注释引了 #82 / PR #83,L624-L629)。原生 assemble 返回分段列表后,rewritePromptAssembly(L706-L771)做整体改写,尾段流水线是关键:const body overlayOfficialIdentity(sanitizeAssemblySections(sections)); const folded foldInjectIntoPersona(body, injectText); // ... const outSections ensureFullInject([...withoutCapDup, ...tail], injectText);overlayOfficialIdentity把官方身份段置空、只留工作目录句(L218-L252);foldInjectIntoPersona把注入正文写进persona-prefix段开头,并赋GLOBAL_PROMPT_ORDER -100000(L4)——最小的排序值,保证排在系统提示词最前。这是版本演化来的:早期实现把 inject 放尾部(order 1e61)压官方段,后来改为前置折叠,对照见 docs/注入方式改造方案-1.1.34化.md 的差异表(L52-L58)。分段命名也在打架。宿主内部会把dsh-purge前缀的段挪到最前,所以能力协议段特意起名dshpg-capabilities,避免被提前到 inject 之前(lib/capability-protocol.js,L7-L11)。幂等去重:841 字符雪球的教训每轮都跑装配,有一个经典坑:替换产物若以前一轮文本为前缀,每次应用就叠一层。项目修过 issue #38——提示词补丁每次 apply 增长约 841 字符,永不收敛(release-notes.md,L733-L739)。现在的防线是拼接前先查正文:if (prior.includes(inject)) return { ...section, order: GLOBAL_PROMPT_ORDER, interpolate: false }; return { ...section, text: prior ? ${inject}\n\n${prior} : inject, order: GLOBAL_PROMPT_ORDER, interpolate: false, };正文里已有 inject 就只保留排序值,不加字符(L170-L176)。末尾的ensureFullInject同样先做全文匹配(L112-L128)。配套有npm run test:idempotence回归,保证多轮会话后身份句恰好出现一次。提示词两条线:系统注入与规则集分道走系统注入只有一个文件:$DSH_HOME/prompt-inject.md。读取顺序在resolveInjectText里写死(lib/rules.js,L243-L257):const disk readPromptInjectFileSync(home); if (normalizeOverride(disk)) { const source hashOverride(disk) defaultOverrideHash() ? default : prompt; return { text: disk, source, ruleId: null }; }磁盘文件优先;为空时回退到本进程提示词框的未落盘草稿,再回退加密槽默认。source标记default或prompt,面板能显示当前用的是哪一份。第二条线是「规则集」,也就是口号里「不同模型换不同提示词」的落点。注意规则集根本不进系统注入链——源码注释直接写明(L239-L242):只改工作区指令文件AGENTS.md/CLAUDE.md。activateRule(L266-L284)做两件事:先把原件备份为target.dsh-purge-rule.bak,再把选中的规则正文原子写入目标文件。每套规则集就是$DSH_HOME/rules/下的两个文件:id.md(正文)和id.json(名称与目标),启用哪套记在rules/state.json。切换模型 把不同id.md写进同一个AGENTS.md。工作区指令是模型最先读的层,换一套话术成本只是一次文件写;系统注入里的小码酱保持不动。默认提示词的分发:AES-256-GCM 加密槽默认提示词源码是lib/default-prompt-inject.md,但发布包里没有这个明文文件。构建时 scripts/embed-default-prompt.mjs 调sealSlot加密后写入 lib/asset-table.js:export function sealSlot(text) { const mask randomBytes(16).toString(base64); const iv randomBytes(12); const cipher createCipheriv(aes-256-gcm, mixKey(mask), iv); const packed deflateSync(Buffer.from(String(text ?? ), utf8), { level: 9 });密钥不是写死的:SHA-256 混入插件名等常量再加 16 字节随机掩码(lib/table-key.js,L11-L13)。密文还按 96 字符切块成字符串数组,grep不出连续明文。运行时openSlot解密还原(lib/table-read.js,L6-L18)。读默认提示词的入口是defaultOverrideText(lib/core.js,L8121-L8125)——每次现解密槽,不做进程内缓存。这个「不缓存」是为下一个坑准备的。落盘与生效:三态文件、应用重启与还原边界点应用时,installOverride(L8316-L8345)决定是否把默认写入prompt-inject.md:if (!force normalizeOverride(disk) isKeepableUserOverride(dshHome, disk)) { await markOverrideCustomized(dshHome, true, disk); return exists; }用户改过就原样保留;没改过才刷成当前槽。判定依据是$DSH_HOME/dsh-purge/override-state.json里的四个字段:customized、explicitSave、hash、seedHash(L8131-L8164)。这里有个项目自己记录的坑:重新加密后defaultOverrideHash()必然变化,磁盘上还是上一版默认。直接拿「磁盘 vs 新默认」比,会把「插件自己写的旧默认」误判成用户手改,之后每次 apply 都拒绝更新——「改了默认却不生效」的根因就在此(L8166-L8173 注释)。解法是overrideTextIsOurs(L8174-L8179):先比对哈希是否等于上次落盘记录,再谈和内置默认比。生效是固定三步:应用 → 自动重启 → 新开会话。应用只写文件,当前进程还跑旧代码,重启后新开一轮,注入才进会话(README.zh-CN.md,L40)。只点应用不重启,看起来就像没生效。操作入口在会话标题旁的dsh-purge按钮→「清洗」页,或聊天命令/purge apply、/purge edit、/rules use id(L433-L434)。还原和卸载的边界同样明确:宿主文件先备份为.dshpurge.bak再改,「还原」用备份覆盖回去并删除备份;prompt-inject.md是用户文件,还原时保留;「卸载」先还原、再删注入文件、规则库和插件本身(L576-L580)。重复应用幂等,宿主原文对不上时标记跳过、不乱改(L609)。把这套机制连起来看,其实是三个克制的选择:身份是可被用户覆盖的默认,注入段以最小排序值抢占最前且严格幂等,按模型换提示词则下沉到工作区层、切换成本只是一次文件写。默认提示词加密落盘防误改,用户自定义由四字段三态文件保护;宿主层和模型层分开之后,「默认策略该不该收紧」才有了可评测、可还原、可切换的判断依据。⚠️ 使用边界:dsh-purge 仅作用于你自己本机已安装的官方 Harness,面向本机、离线靶标或已书面授权的受控评测,任何未授权攻击或违法用途由使用者独立承担法律责任。【免费下载链接】dsh-purgeDeepSeek Harness 破甲让所有模型都能破甲不同模型可换不同提示词默认提示词面向国模「小码酱」。Jailbreak for every model — swap prompts per model. 求 Star 收藏 ⭐ 如要二开请查看署名要求部分项目地址: https://gitcode.com/GitHub_Trending/ds/dsh-purge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价 →
↑