前言¶
在 DeepSeek Harness(DSH)裏跑智能體時,用戶輸入、系統提示、工作區說明、會話召回、工具讀文件結果等,都會進入發往模型提供商的請求。若其中帶有郵箱、電話、API Key 或銀行卡號,這些內容會離開本機。常見做法是事後審查日誌,或在 Hook 裏追加提示,但 DSH 的 Claude Code / Codex Hook 協議裏,updatedInput 被文檔標明爲「解析但不生效」,無法改寫即將發送的 prompt 與工具結果。原生 Cordis 插件則可以在 agent loop 入口把檢測到的 PII 換成佔位符,再交給上游模型。
下面介紹社區插件 dsh-pii-anonymizer(維護者 JWE24-code,分類 admin-security):在 agent loop 起點對「發往模型的一切文本」做確定性、單向的 PII 匿名化,檢測靠固定規則與校驗和,不調用模型。
這是什麼¶
dsh-pii-anonymizer 是 DSH 原生 bundle 插件(npm 包名 dsh-pii-anonymizer,當前版本 0.2.1,MIT 許可證)。它在請求離開本機前,用規則檢測結構化 PII,並替換爲形如 [[EMAIL_3f9a2c1d]] 的鍵控佔位符;本地會話日誌仍按你輸入的原樣記錄,磁盤上的文件與工具輸出內容本身不會被插件改寫。
掛載位置與改寫範圍¶
各監聽器以 prepend: true 註冊,位於對應 waterfall 最外層,在其他插件貢獻之後再改寫最終文本。
| Hook | 包 | 改寫對象 |
|---|---|---|
system-prompt/assemble |
dsh-system-prompt |
提示詞 section、runtime context、字符串型 prompt 變量 |
agent/pre-step |
dsh-agent-loop |
本步進入模型的每條消息文本塊(用戶 prompt、快照、AGENTS.md、recall、relay、技能目錄、工具附帶 context 等) |
tools/post-execute |
dsh-tools |
模型讀到的工具結果 content、塊決策反饋及附帶 context |
README 說明:外部 Hook 橋接無法實現同等覆蓋,只有原生插件能替換進入模型請求的消息、prompt 與工具結果。
檢測類型與佔位符¶
檢測是確定性的:語法或校驗和,不用 ML/NER。自由文本姓名、郵編地址等上下文相關 PII intentionally 不檢測,以避免誤報。
| 類型 | 觸發條件 | 校驗 |
|---|---|---|
API_KEY |
sk-、sk-ant-、AKIA…、ghp_… 等已知前綴 |
— |
IBAN |
CC00… 等形式 |
mod-97 |
CREDIT_CARD |
13–19 位數字(可含空格/橫線) | Luhn |
SSN |
DDD-DD-DDDD |
— |
EMAIL |
RFC 風格地址 | — |
IPV4 / IPV6 |
地址形態 | IPv4 八位範圍 |
PHONE |
7–15 位數字及常見分隔符 | 排除 ISO 日期、版本號等 |
佔位符格式爲 [[TYPE_<hash>]],<hash> 爲 HMAC-SHA256(密鑰, type + 歸一化值) 的前 8 位十六進制。同一真實值在跨會話、子 agent、重啓後佔位符一致;插件不保存「值→佔位符」映射表,單向,無法從插件側還原明文。
密鑰默認寫在 $DSH_HOME/pii-anonymizer.key(即 ~/.dsh/pii-anonymizer.key),首次使用生成 32 隨機字節、權限 0600。刪除密鑰文件會導致此後佔位符全部變化;若無法讀寫密鑰文件,會退化爲進程內密鑰,替換仍發生但跨重啓不穩定。
行爲示例¶
你在對話裏輸入帶 PII 的句子時,模型側看到的是佔位符,並可能收到一條 user 角色的通知(僅類型與數量,不含真實值或佔位符字符串)。本地 transcript 仍保留原文。README 中的示意:
you type: email a@x.com or call +31 6 1234 5678
model sees: email [[EMAIL_6c1f0a9e]] or call [[PHONE_d24b7c03]]
+ notice(PII shield: 2 item(s)...)
local log: 按你輸入的原樣
關閉通知可在配置中設置 notify: false。
覆蓋與不覆蓋¶
會改寫(面向模型的文本):用戶 prompt 與本步所有注入消息;system prompt 與 runtime context;經 tools/post-execute 的工具結果正文(含工具體返回的錯誤)。
不會改寫:本地 session log、transcript、memory 與磁盤文件中的明文;complete: true 的 system-prompt section(assemble 之後被框架恢復);工具 schema;跳過 post-execute 的少數工具結果路徑;助手回覆本身(佔位符也不會在輸出裏被還原)。未納入檢測規則的 PII(如姓名、地址)仍會原樣發出。
若工作區說明裏的 IP 等字段必須讓模型看見,可關閉部分通道:systemPrompt: false 或 toolResults: false。
安裝與啓用¶
包爲 DSH bundle:package.json 聲明 dsh.bundle.patch,cordis.patch.yml 插入 pii-anonymizer 行;profile 需在 dependencies 與 dsh.profile.bundles 中同時列出。
在 profile 目錄(如 ~/.dsh/profiles/<name>)安裝:
npm install dsh-pii-anonymizer
或在終端應用內:
/plugins add dsh-pii-anonymizer
本地 checkout 可用 node tools/register-profile.mjs ~/.dsh/profiles/tui 改 manifest(會寫 package.json.bak),並需讓 profile 能解析到包,例如:
ln -s "$PWD" ~/.dsh/profiles/node_modules/dsh-pii-anonymizer
安裝後重啓 DSH 應用加載插件;回滾可恢復對應 profile 的 package.json.bak。
運行環境要求 Node.js >= 20(見 package.json engines)。
配置¶
在 profile 的 Cordis 配置中爲插件 id pii-anonymizer 設置:
- id: pii-anonymizer
name: dsh-pii-anonymizer
config:
enabled: true # 總開關
notify: true # 本步輸入含 PII 時插入通知消息
debug: false # 僅記錄計數類 shield 事件,不記錄值
systemPrompt: true # 改寫 system prompt + runtime context
toolResults: true # 改寫工具結果 content
keyFile: '' # 空則使用 $DSH_HOME/pii-anonymizer.key
適用場景與注意¶
適合在 DSH 日常開發、調試或自動化 agent 中,降低郵箱、密鑰、卡號等結構化敏感信息進入第三方模型請求的概率,同時希望在多輪對話裏保持同一佔位符語義(例如寫入 memory 的 [[EMAIL_…]] 仍指同一地址)。
使用前請自行閱讀倉庫源碼與 MIT 許可證;插件以當前 DSH 進程權限運行,本地明文仍存在於 $DSH_HOME 與 workspace 文件中,防護邊界是「出站請求」而非全盤加密或 DLP。社區目錄 SkillHub 插件頁 與 GitHub 倉庫由社區維護,與 DeepSeek / 幻方無官方從屬關係;DSH 生態本身是「一切皆插件」,安裝第三方 bundle 前核對來源與配置是常規做法。
結尾¶
dsh-pii-anonymizer 在 agent loop 最早階段對發往模型的 prompt、上下文與工具結果做規則化 PII 替換,鍵控佔位符跨會話穩定且不可逆,補上了外部 Hook 無法改寫輸入的缺口。詳情與端到端測試說明見 GitHub:JWE24-code/dsh-pii-anonymizer,目錄索引見 SkillHub。