AndKinoko/DSH-Search-Citation-Auditor
Audit citation sources in AI responses – extract URLs from the reply, score and rank them by threat level, and output a detailed report. Domains on your blocklist will be genuinely blocked – web tools such as web_search and web_fetch will directly refuse to access them. The blocklist is fully maintained by you.
Project Overview项目介绍
Citation Auditor is a DeepSeek Harness function plugin that extracts URLs from AI replies, normalizes them to registered domains (PSL), and scores them 0–100 with a report. It offers whitelist, simple, and standard audit modes. A user-maintained blocklist causes web tools like web_search and web_fetch to be refused at the tools/pre-execute stage, genuinely preventing the model from visiting those domains. Use it to audit citations and block untrusted sources. Caveat: only DSH-registered web tools are intercepted; shell channels like pwsh and curl fall outside its scope.
Citation Auditor 是 DeepSeek Harness 函数插件,从 AI 回复中提取 URL,按注册域(PSL 归一化)以 0–100 威胁分排序出报表。提供白名单、简单、普通三种审计模式。维护用户自管的拦截名单后,web_search/web_fetch 等 Web 工具会在 pre-execute 阶段直接拒绝调用该域名。适用审计模型引用来源。提示:仅拦截 DSH 注册的 web 工具,shell 通道(pwsh、curl)不在拦截范围。
请帮我了解并安装插件:【DSH-Search-Citation-Auditor】【https://github.com/AndKinoko/DSH-Search-Citation-Auditor】
Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。
Or use CLI install (for developers)或使用命令行安装(适合开发者)
CLI Install命令行安装
dsh plugin --profile web add github:AndKinoko/DSH-Search-Citation-Auditor
把 AndKinoko/DSH-Search-Citation-Auditor 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
Citation Auditor
审查 AI 回复里的引用来源:把回复中的 URL 提取出来,按威胁度打分排序,输出报表;拦截名单里的域名会按拦截策略处置(allow=仅提醒 / ask=需确认 / deny=直接拒绝 web_search / web_fetch 等 web 工具,默认直接拦截)。名单完全归用户维护,处置权在你手上。
Cordis 函数插件,可被 DeepSeek Harness 直接加载。业务内核(scanner / scorer / report)是纯函数,脱离 dsh 也能复用。
工作效果
打分机制(v0.3 起多信号可配,阈值见下方“高级阈值”,欢迎提 issue 讨论权重)
| 模式 | 打分函数 | 判断维度 | 核心规则 | 典型分值 |
|---|---|---|---|---|
| whitelist | scoreWhitelist | 纯名单二元判定 | 命中白名单 → trusted;否则一律 critical | 0 / 100 |
| simple | scoreSimple | 域名注册年龄 | 注册于分界年(默认 2023,可配)前 → trusted;此年及以后 → critical;查不到年龄 → critical(treatAsNew) | 0 / 100 |
| normal | scoreNormal | 多信号累加 | TLD 拦截+TLD 可信度分级、连字符/数字、域名长度、注册年龄、年龄可验证性、URL 结构信号(IP 直连、userinfo/@ 混淆、短链、追踪参数、深路径、超长查询、非标准端口)分别累加,同域多 URL 各信号只计一次 | 0–100 |
拦截成功的效果如图
工作方式
扫描文本 → 提取 URL → PSL 解析注册域(eTLD+1)→ 0–100 打分 → 出报表。
三种模式:
- 白名单模式:名单内绿,名单外全红。最严。
- 简单模式:分界年(默认 2023,可配)前注册的可信,之后标红。
- 普通模式:多信号综合评分(TLD、连字符/数字个数、域名长度、注册年龄、URL 结构信号)。
命中拦截名单的域名直接标红,不参与评分;精确域名与 .xyz/.shop 这类 TLD 条目都受当前模式的拦截名单开关控制(开关关闭 = 该模式完全不应用名单)。域名匹配统一按注册域:en.wikipedia.org → wikipedia.org。年龄查不到时只记"可疑"(ageQuery 未启用或查询失败),只有确认是新域名才从严标红。
真实拦截:拦截名单(含 .shop 这类 TLD 条目)会在 tools/pre-execute 阶段按拦截策略处置 web 工具(web_search / web_fetch 等):deny(默认)命中即拒绝调用并告知模型原因——加入名单后模型就访问不了该网页了;ask 命中时需确认后才访问;allow 仅在报表标红,不阻止访问。策略经设置页 / 悬浮窗 / citation_manage policy 切换,即时生效。只拦 web 工具;pwsh/curl 等 shell 通道属沙箱层,不在拦截范围。名单增删(界面按钮或直接改 blocklist.json)即时生效,无需重启。
向 dsh 注册两个工具:
| 工具 | 作用 |
|---|---|
citation_audit |
审计一段文本,返回结构化结果(含逐域处置动作 action)+ 纯文本报表 |
citation_manage |
查状态、启停、切模式、增删名单、切拦截策略(policy + action)、测试年龄片段 |
Web 界面
- 设置页卡片:三种模式单选、各模式拦截名单开关、白名单免查加速、插件总开关、拦截策略三档(仅提醒/需确认/直接拦截)、高级阈值(年份分界线与各项加分,可展开)、年龄片段 [编辑JS代码] 与 [测试](固定 wikipedia.org)。名单旁的 [查看/编辑] 用系统默认程序打开对应 JSON,改完即生效。
- 悬浮窗设置:面板内 ⚙ 同样可切拦截策略与高级阈值,与设置页同一
/settings通道落盘。 - 交互报表:会话里
citation_audit渲染成可点报表,非可信域名带 [➕ 加入拦截名单] / [➕ 加入白名单] / [忽略];拦截名单开关关闭时弹窗三选(开启并保存 / 仅保存 / 取消)。写入后按钮变灰,可再点确认移除。 - 悬浮窗:右下角可拖动球(有可疑域名时显示红色角标),点击展开最近回复的网址列表与分数;面板内含 ⚙ 设置入口和同样的名单按钮。悬浮窗按宿主实际能力取会话节点:新宿主优先订阅
uiConversation的 chat 通道(legacy.nodes),旧宿主回退会话快照自带的 nodes。
所有设置/名单读写都走插件自有的同源端点 /api/citation-auditor/*(status / audit / list / settings / test-age / open-file),直接落盘 settings.json,不依赖 harness 的 settings 服务。
年龄查询片段(唯一联网点)
一段你自己写的 JS,在 worker 线程执行,5 秒超时直接 terminate(同步死循环也拖不垮主线程)。契约:必须返回 { creationDate: <ISO 日期或毫秒> } 对象,查不到返回 undefined。先测试后启用,默认关闭。
按 TLD 分发注册局直连的 RDAP 示例(可直接粘贴进 ageQuery.js):
async (domain, fetch) => {
const tld = domain.split('.').pop();
const regs = {
com: 'https://rdap.verisign.com/com/v1/domain/',
net: 'https://rdap.verisign.com/net/v1/domain/',
org: 'https://rdap.publicinterestregistry.org/rdap/domain/',
top: 'https://rdap.centralnic.com/domain/',
xyz: 'https://rdap.centralnic.com/domain/',
};
const base = regs[tld] || 'https://rdap.org/domain/';
try {
const res = await fetch(base + domain, { signal: AbortSignal.timeout(4000) });
if (!res.ok) return undefined;
const j = await res.json();
const ev = (j.events || []).find((e) => e.eventAction === 'registration');
return ev ? { creationDate: ev.eventDate } : undefined;
} catch { return undefined; }
}
局限:RDAP 只认注册域(已按 PSL 归一化,天然满足);.cn 等部分 ccTLD 无公开 RDAP 或被网络阻断会查不到;新 gTLD(如 .top)数据不一定齐全。
数据与安全
名单、设置、年龄缓存各自存成独立 JSON 文件(默认 ~/.citation-auditor/,配置 statePath 可改),外加可编辑的 ageQuery.js。写入走临时文件 + fsync + rename 原子发布;损坏先备份为 *.corrupt-* 再处理,绝不覆盖;每次读取检查 mtime,直接改文件保存即生效。旧版单文件 state.json 首次启动自动迁移。
报表永不改写 AI 原文;全项目唯一的联网点是你的年龄查询片段。
构建与安装
npm install
npm run typecheck # tsc --noEmit
npm run test # 构建 + node:test(61 项)
或 dsh plugin --profile web add https://github.com/AndKinoko/DSH-Search-Citation-Auditor/releases/download/v0.3.0/dsh-citation-auditor-0.3.0.tgz(prepare 脚本自动构建)。配置只有一个字段:
- insert:
- id: dsh-citation-auditor
name: dsh-citation-auditor
config:
statePath: "" # 留空用 ~/.citation-auditor
client 半边要求宿主 dsh.engines.dsh >= 0.1.1-rc.1(host 工具无此门槛)。
目录结构
src/
├── index.ts # Cordis 插件入口(name/inject/Config/apply + 两个工具)
├── storage.ts # 目录化键值存储(每 key 一文件 + mtime 热重载 + 原子写)
├── routes.ts # /api/citation-auditor/* 数据端点
├── settingsSection.ts # 设置命名空间 host 半边(含策略与阈值映射)
├── webBlock.ts # pre-execute 处置(deny/ask/allow 三档)
├── client/ # 浏览器半边(设置卡片 / 交互报表 / 悬浮窗)
│ ├── constants.ts # 共享常量(颜色/模式标签/字体)
│ └── float/ # 悬浮窗子组件(FloatBall/AuditPanel/SettingsPanel/ConfirmDialog)
├── test/ # node:test 一致性测试
└── auditor/ # 业务内核(scanner/scorer/report 纯函数 + rules/cache/ageQuery)
v0.3 更新
- URL 结构信号:IP 直连、userinfo/
@混淆、短链、追踪参数、深路径、超长查询、非标准端口分别加分,同域多 URL 只计一次。含@的 URL 会完整提取并归属@后的真实主机(此前会被截断)。 - 拦截策略三档:
allow仅提醒 /ask需确认 /deny直接拦截(默认),命中名单的 verdict 自带action。 - 高级阈值 UI:设置页与悬浮窗均可调年份分界线与各项加分,其余 scoring 键直接改
settings.json即生效。
License
MIT,见 LICENSE。
Minglink/dsh-infinite-gen-4
toby-bridges/api-relay-audit
howmp/dsh-pentest
SeaOf0/dsh-redteam-model
saya-ch/dsh-mobile
liguobao/ds-harness-remote
zhu1090093659/dsh-trading
PerryLink/dsh-auto-review