AI 工具

Duck.ai 粘贴前敏感信息自检:本地 Prompt Guard

粘贴进 Duck.ai 前的敏感信息自检:密码/Key/身份证号等模式命中则拒绝——官方明确匿名≠可随意输入敏感信息。

BINBHO · 图文教程

粘贴进 Duck.ai 前的敏感信息自检:密码/Key/身份证号等模式命中则拒绝——官方明确匿名≠可随意输入敏感信息。

先看清成品

  • 礼貌邮件样例 ok。
  • 含密码+身份证样例 hits≥2。
  • 1 项 pytest 通过。

合规提醒:Duck.ai 没有官方公开聊天 REST API。本系列不教网页逆向、不自动化登录、不绕过额度。A 篇使用 DuckDuckGo 官方 Instant Answer API;B/C 为本地账本与粘贴前自检。匿名化不等于可输入身份证/密码;对话仍会发往模型提供方处理。Instant Answer 需署名且非商用须遵守官方条款。

运行说明:Instant Answer 无需 Key;A 篇 mock + 对 api.duckduckgo.com 实测可返回 Abstract。未调用任何非官方 Duck.ai 聊天端点。B/C 纯本地。2026-10-23(Asia/Shanghai)pytest 通过。

做完之后你会得到什么?

成果 说明
duckai_prompt_guard.py 自检
样例 txt ok/bad
test_119c.py 测试

需要准备哪些环境?

项目 说明
Python 3.10+

关键事实

事实 来源
对话内容仍发往模型提供方 官方帮助页
勿输入身份证号、密码等 教程页提醒
本工具纯本地正则,无上传 实现

文件结构

119-duck-ai-C-src/
├── duckai_prompt_guard.py
├── sample_ok.txt
├── sample_bad.txt
└── test_119c.py

第 1 步:自检

#!/usr/bin/env python3
"""Duck.ai 粘贴前敏感信息自检。

官方强调:匿名化不等于可随意输入身份证号/密码等;对话仍会发往模型提供方处理。
本工具只做本地正则提示,不上传任何内容。
"""
from __future__ import annotations
import argparse, json, re, sys
from pathlib import Path

PATTERNS = [
    ("password_like", re.compile(r"(?i)(password|passwd|密码)\s*[:=]\s*\S+")),
    ("api_key_like", re.compile(r"(?i)\b(sk-[A-Za-z0-9]{16,}|AKIA[0-9A-Z]{16})\b")),
    ("cn_id_like", re.compile(r"\b\d{17}[\dXx]\b")),
    ("bank_card_like", re.compile(r"\b\d{16,19}\b")),
    ("email_password_pair", re.compile(r"(?i)[\w.+-]+@[\w-]+\.[\w.-]+.{0,20}(password|密码)")),
]


def check(text: str) -> dict:
    hits = []
    for name, rx in PATTERNS:
        if rx.search(text):
            hits.append(name)
    reasons = [f"possible {h}" for h in hits]
    if len(text) > 8000:
        reasons.append("prompt very long; prefer splitting non-sensitive context")
    return {"ok": not reasons, "reasons": reasons, "hits": hits}


def main(argv=None) -> int:
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument("text_file")
    args = ap.parse_args(argv)
    r = check(Path(args.text_file).read_text())
    print(json.dumps(r, ensure_ascii=False, indent=2))
    return 0 if r["ok"] else 1


if __name__ == "__main__":
    raise SystemExit(main())

第 2 步:测试

import json, subprocess, sys
from pathlib import Path
HERE = Path(__file__).resolve().parent

def test_guard():
    ok = subprocess.run([sys.executable, str(HERE/"duckai_prompt_guard.py"), str(HERE/"sample_ok.txt")],
                        capture_output=True, text=True, check=True)
    assert json.loads(ok.stdout)["ok"] is True
    bad = subprocess.run([sys.executable, str(HERE/"duckai_prompt_guard.py"), str(HERE/"sample_bad.txt")],
                         capture_output=True, text=True)
    assert bad.returncode == 1
    assert len(json.loads(bad.stdout)["hits"]) >= 2

第 3 步:运行

.                                                                        [100%]
1 passed in 0.05s
{
  "ok": true,
  "reasons": [],
  "hits": []
}
{
  "ok": false,
  "reasons": [
    "possible password_like",
    "possible cn_id_like",
    "possible bank_card_like"
  ],
  "hits": [
    "password_like",
    "cn_id_like",
    "bank_card_like"
  ]
}

怎么检查结果?

  • ok → exit 0。
  • bad → hits ≥ 2。

调试示例

「已经匿名了所以可以贴 Key」。 不行。上游模型提供方仍会看到明文;删掉敏感段再问。

常见问题

现象 原因 处理
误报银行卡 长数字可能命中 人工复核
企业机密 同样不要贴 用私有部署模型
Plus/Pro 更多模型与额度 见帮助页,不编造价格

模板规则

  • 先 guard 再粘贴。
  • 命中即改写。
  • 日志勿保存原文敏感段。

项目资源

用途 地址
帮助说明 https://duckduckgo.com/duckduckgo-help-pages/duckai/
隐私政策 https://duckduckgo.com/privacy
Duck.ai https://duck.ai

隐私产品也救不了你主动粘贴的密码。