dsh-pii-anonymizer:在 Agent 環路上對發往模型的文本做確定性 PII 脫敏

前言

在 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。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜