# dsh-knowledge-graph **[中文](README.md) | [English](README.en.md)** **DSH(DeepSeek Harness)Cordis 插件**:把任意一段资料正文、包含文字 / 图示 / 表格的图片——或一段 AI 会话执行轨迹——用 AI 拆解成一张**知识图**,并在**知识图与原文之间双向定位**。 > 贴原文 → AI 异步拆图 → 双向锚点定位。是 NovelStudio「资料 ⇄ 知识图」落地为独立、可复用插件的形态。 --- ## 它能做什么 - **AI 异步拆分**:输入任意正文(章节、技术文档、学习笔记…),后台任务模式调用 LLM,约 15–40 秒返回一张知识图。支持最长约 100 万字符的书级正文;`documentId` 是随机稳定的逻辑文档 UUID,`sourceId` 是全文 SHA-256 的不可变版本身份,`chunkId` 绑定 sourceId + batch + paragraph range,因此不同文档/追加版本不会因局部 `chunk-0001` 重号而覆盖。常驻模式把全文、canonical graph 与无损 checkpoint 保存在 SQLite;刷新后浏览器只凭 `documentId/runId` 恢复,只有 Host 重启遗留的 `running` 任务才允许从 checkpoint 续跑,显式 `failed/cancelled` 任务绝不自动重试。 - **图片直接生成知识图**:工作台可一次上传 1–4 张 PNG / JPEG / WebP / GIF(单张不超过 6 MiB、合计不超过 16 MiB),支持纯文字截图、示意图 / 流程图 / 架构图、统计图、公式和表格,也可同时附带说明文字。Host 先把浏览器提交的有界 base64 图片交给 DSH `attachments.saveImages()` 验证并保存,再用多模态模型生成带图片范围的 canonical 视觉转写;现有文本抽取器只消费这份转写。结果页保留原图预览与 `source.visualSource` 回链,点击图片会定位对应转写段落。视觉转写会把箭头 / 连线、分组 / 包含、对象对应、顺序和具有图例语义的颜色 / 形状编码拆成独立关系单元,知识抽取后的覆盖复核会补回被首轮遗漏的图示关系;无法准确映射到内置 relation 的关系会保留为原子 fact / claim,而不会强套错误边。视觉转写是模型产物而非像素级确定性 OCR,关键文字、数值、表格单元和连线关系仍应对照原图复核;当前图片输入用于**新建**知识图,已有图的增量追加仍使用文字。 - **8 类节点 / 12 类关系**: - 节点:`fact` 事实 · `claim` 主张 · `inference` 推论 · `concept` 概念 · `definition` 定义 · `example` 例子 · `counter_example` 反例 · `rule` 规则。 - 关系:`supports` 支持 · `example` 例子 · `counter_example` 反例 · `defines` 定义 · `infers` 推断 · `causes` 因果 · `is_a` 属于 · `contains` 包含 · `driven_by` 受驱动于 · `not_is` 不是 · `analogy` 类比说明 · `aims_at` 旨在。 - **最小语义契约**:一个节点只表达一个原子命题;作者的理论/经验概括用 `claim` 而不是 `fact`;保留“可能 / 多数 / 通常 / 必须 / 如果”等原文限定;存在更精确关系时不退化成 `supports`。 - **解释覆盖复核**:首轮抽取通过后,仅在多步机制疑似欠覆盖,或原文明示纠偏/防误推理限定、留待后文回答的信息却未进入图时,执行一次受限复核;它也可恢复被多个核心命题反复引用的稳定概念锚点。调用可选复核器前,系统会先对原文明示且同句已命名的“某方法在明确条件下行不通/失效”原子结论做确定性、只增节点的补漏;相关关系仍必须由关系编织器依据直接原文证据审定,不会因端点同段出现而自动连边。复核通常只能补缺失节点及其必要关系;对于【图示关系】段落,若箭头、连线标签、分组、对应或图例直接证明允许 relation,也可只补两个已有节点之间的遗漏边;该例外仍要求同一条 evidence quote 同时包含 relation 专用显式词、两个端点及兼容方向。复核不能重写已有图,也不会为了连通率补知识。 - **关系感知分层布局**:分层模式先对每个无向连通分量独立排层、消除重叠,再把组件矩形紧凑打包,避免无关子图共用全局层级而把直接相连节点拉远;层内排序按关系加权,以 `causes/infers` 推理链作为主路径,把例子、类比、反例、定义和概念关系放成邻近分支,并将 `supports/driven_by/aims_at` 作为有界软邻近偏好。多条边共享节点或行间通道时,箭头入口、水平通道和垂直走廊分别分轨,并为密集的水平轨道保留更高的层间通道;相邻关系标签发生碰撞时会在可读距离内确定性错位;极端拥挤且无可用位置时默认隐藏标签芯片,悬停或选中对应关系仍会显示,避免线段、标签及箭头挤在一起。新用户默认使用分层布局,已有本地布局偏好保持不变。 - **双向定位**: - 点击**图中节点** → 弹出**详情卡片**(完整内容 + 原文摘录 + 定位按钮),并平滑滚动高亮到原文对应内容单元; - 点击**原文内容单元** → 图中居中聚焦并闪烁对应节点。 - 图中节点只展示前 4 行(超出以 `…` 省略),**完整内容随时可在详情卡片中查看**; - 锚点以 AI 直接输出**内容单元编号**为主(确定性索引,长自然段会按句子边界切分成多个编号单元),quote 精确匹配与 token 重合度兜底;无法回链的节点不猜测偏移,统一进入诊断列表。 - **图渲染**:SVG 画布 + 8 类配色 / **4 种可切换布局形态**(图右上角下拉,选择记忆):**力导向**(d3-force 开源引擎内嵌零依赖:碰撞防节点重叠、边-节点排斥防箭头穿节点)、**圆形**、**放射**(中心枢纽 + BFS 环,边走**折线**:径向出线 → 外环弧 → 径向进线)、**分层**(边走**直角正交折线**:行间空通道 + 逐行避障走廊,线段保证不穿节点)/ 关系边带类型标签,且**同源边按目标角度扇形弯曲**(二次贝塞尔)/ 拖拽平移 / Ctrl+滚轮缩放 / 工具栏 `− 100% +`(50%–200% 步进 10%)/ 长按节点查看原文摘录 / 键盘可达。 - **验证与质疑知识图**:生成图后可以检查它是否忠于原文—— - **⚡ 快速体检**:本地规则即时检查(自环/悬空边、quote 能否在原文定位、段落编号与摘录位置是否一致、类型-关系语义规则、重复/疑似矛盾节点、孤立节点、覆盖统计),0 秒返回问题报告; - **🤖 AI 深度审校**:异步调用 LLM 逐节点/逐边**找茬**,所有 issue 必须以原文摘录为证据,标准档还会二次复核过滤误报; - **人工闭环**:问题按「错误 / 警告 / 建议」列出,点击问题 → 图中相关节点/边按严重度着色高亮并滚动定位原文;每条问题可**采纳修复**(改动立即应用并写入审计记录)或**忽略**;面板顶部提供**一键修复**,批量应用全部可自动修复的问题;修复记录逐条显示**旧值 → 新值**的具体差异; - **主动质疑**:节点详情卡可点「质疑此节点」,选中边后出现关系详情卡可点「质疑此关系」,也可在验证面板直接向整张图提问/质疑,AI 给出「图成立 / 质疑成立 / 证据不足 / 超出范围」判定与原文证据; - **🔎 外部事实核查原文**:把知识图中的 fact/claim/inference/rule/definition/counter_example 节点转为**可核查断言**,用 Wikipedia 等外部证据裁决原文是否可靠;面板支持**粘贴领域规则来源**(法条、制度、教材、标准),规则文本与 Wikipedia 证据共同参与裁决;判定为「支持 / 矛盾 / 部分支持 / 证据不足 / 无法核查 / 超出范围」,每条结论绑定证据链接与证据引文(引文必须能在检索结果中定位,编造引文会被自动降级);点击断言可回链图中节点与原文段落; - **追加拆分后自动标记验证/核查结果过期**,可重新验证或核查;轨迹知识图支持同样的全部验证/质疑/外部核查能力。 - **浮动工作台**:窗口可拖动、可调整大小;原文与知识图的**宽度比例**、**结果区高度**均可拖拽调整并记忆。 - **划线拆分**:**在聊天消息里**用鼠标选中任意一段文字,选区上方浮出「拆成知识图」按钮,点击即自动打开工作台并拆分所选文字;在结果页原文里划线选中可拆成子图;输入框里选中部分文字也可「拆分所选」。 - **追加拆分(增量合并)**:已有拆分结果后,输入区主按钮变为「追加拆分」——粘贴下一段/下一份资料,AI 只抽取新增内容,并自动与已有图建立**跨段关系边**(同一概念不重复建节点,直接连线到已有节点);结果原地合并、全文段落统一编号、历史记录原地更新。聊天划线选中文字时也会自动追加到当前图。 - **历史记录**:每次成功拆分自动记录(最多 20 条、同文去重、可单删 / 清空);浏览器只保存 `documentId`、标题、计数等轻量索引,回看时从 Host/SQLite 重新载入正文与 canonical graph,避免把书级正文复制进 `localStorage`。 - **章节过滤与候选审核**:结果区按章节筛选图节点和原文段落;候选实体 / 声明面板展示 evidence,可一键标记「待审核 / 已接受 / 已驳回」,状态通过 Host 同步到 SQLite(动态插件在 Host 会话中保留,失败时回退浏览器 localStorage),并可点击候选回链原文。 - **知识图消费层**:正文图与轨迹图共用「使用这张知识图」面板,可按关键词、节点类型、章节、grounding / entailment 状态做有界结构化检索,并区分**直接命中**与关系邻居;「证据问答」只使用服务端加载的 canonical graph 和已认证原文,模型只能引用 Host 预分配的 `evidenceId`,每个被接纳的回答片段都必须有节点、关系或原文段落证据。点击检索结果或 citation 可回链图与原文;节点即使位于当前 800 节点渲染窗口之外,也会先按 node ID 加载 canonical 子图再定位。 - **知识图导出**:结果工具栏可导出当前渲染图为高清 PNG 图片,也可导出完整 JSON(保留 source、chunk、evidence、验证报告和审计记录)以及节点 CSV、关系 CSV;数据导出的是完整图,不受当前章节筛选影响。轨迹知识图也支持相同导出。 - **常驻入口**:每个对话的标题右侧常驻「知识图」按钮,一键打开;运行卡片内也有启动条。 - **轨迹知识图(会话视图标签页)**:对话区新增第三个标签页「轨迹知识图」(位于 对话 / 轨迹 旁),一键把**当前会话的完整执行轨迹**(用户消息、工具调用、工具结果、AI 回复)拆成知识图——可视化这个 Agent **查到了什么事实、做出了什么推论、用了什么方法**,并在图与轨迹事件之间**双向定位**(点击节点滚动到对应事件,点击事件在图中聚焦对应节点)。结果按会话持久化到 Host/SQLite;浏览器仅保存 `documentId/revision` 引用,因此**切换标签页或刷新页面后会从 canonical state 恢复**,拆分进行中切走再切回会自动续接轮询;会话继续产生新事件后,可点 **追加新事件** 只拆解新增部分并在同一 revisioned document 上增量合并(跨事件建立关系边);轨迹事件列与图列的宽度、结果区高度均可拖拽调整并记忆。 ## 界面一览 image ``` ┌─────────────────────────────── 浮动工作台 ───────────────────────────────┐ │ ● 知识库 · 资料 ⇄ 知识图 [ × ] │ │ 知识库 │ │ 把任意资料用 AI 拆成「事实/主张/推论/概念/定义/例子/反例/规则」知识图… [历史][重新开始]│ │ [输入资料 ─────────── 收起 ▴] │ │ [原文 ⇄ 知识图] │ │ 一句话总结:… │ │ N 节点 · M 关系 · 可回链 X/Y ─────────────────────────┐ │ │ [原文段落…带类型徽标] ‖ [知识图 SVG…] [− 100% +] │ ← 可拖宽竖条 │ │ ─────────────── 可拖高横条 ──────────────── │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` 对话区「轨迹知识图」标签页: image ``` ┌────────────────────────── 轨迹 ⇄ 知识图 ──────────────────────────┐ │ 拆解本会话轨迹:用户消息 / 工具调用 / 工具结果 / AI 回复 │ │ 一句话总结:… │ │ [轨迹事件…带类型徽章] ‖ [知识图 SVG…] [− 100% +] ← 可拖宽竖条 │ │ ──────────── 可拖高横条 ──────────── │ │ (切换标签页 / 刷新页面后结果自动恢复) │ └────────────────────────────────────────────────────────────────────┘ ``` ## 安装 这是一个 **DSH 动态 Cordis 插件**:一份 Host 代码(Node 进程)+ 一份 Client 代码(浏览器),纯 JS、零依赖、无需构建。通过 DSH Web 界面的 Cordis 插件机制加载,步骤适用于任何 DSH Web 会话。 ### 0. 前置条件 - 已启动 **DSH Web**(`dsh web`)并进入任意会话; - 环境中已配置 **AI 模型提供方**(设置 → 模型,或 `agentDefaultModel`)。插件默认跟随系统当前模型;工作台与「轨迹知识图」顶部均提供模型下拉框,可手动指定拆分、追加、AI 审校、质疑与外部核查使用的模型(选择会保存在浏览器本地);未配置时会给出明确的中文错误提示。图片抽取需要支持 `image` 输入的多模态模型;模型下拉框会标注已知的「图像 / 仅文本」能力,能力未知的模型允许尝试,但提供方拒绝图片时会以 `model_image_unsupported` 明确失败。 ### 1. 获取源码 ```bash git clone https://github.com/cwbcheng/dsh-knowledge-graph.git cd dsh-knowledge-graph ``` | 文件 | 作用 | | --- | --- | | [`src/index.host.js`](src/index.host.js) | Host 半:异步 AI 拆分任务引擎(图片 admission / 多模态视觉转写、段落编号、分批、schema 校验、typed 诊断、模型路由、会话轨迹序列化)+ 知识图验证/质疑引擎 + canonical 结构化检索与 evidence-ID 证据问答 | | [`src/index.client.js`](src/index.client.js) | Client 半:浮动工作台 UI、图渲染、双向定位、共享检索/证据问答面板、验证与质疑面板、修复应用/审计、历史、宽高调节、轨迹知识图标签页 | | [`src/kg-store.mjs`](src/kg-store.mjs) | SQLite 持久化层:文档、内容块、节点、关系、证据、候选实体/声明、抽取 checkpoint 与大图有界消费查询 | ### 2. 安装(二选一) **方式 A:让 Agent 帮你安装(推荐)** 在任意会话中把下面这句话发给 Agent(把路径换成你 clone 的位置): > 请读取 `dsh-knowledge-graph` 仓库的 `src/index.host.js` 和 `src/index.client.js`,把这两个文件定义为 Cordis 插件的 Host 半和 Client 半,然后运行它。 Agent 会依次调用 `cordis_define`(定义)→ `cordis_run`(运行),并在界面上弹出**运行审批卡片**。 **方式 B:自己复制源码定义** 1. 在任意会话中发起一次 `cordis_define`(由 Agent 执行,或按你环境的 Cordis 工具流程操作); 2. **Host 半**粘贴 `src/index.host.js` 的内容,**Client 半**粘贴 `src/index.client.js` 的内容; 3. 注意粘贴的是**函数体**:去掉文件里的 `export default function hostPlugin() {` / `export default function clientPlugin() {` 这一行和文件末尾对应的 `}`,保留中间的 `return { ... };` 部分(文件头部注释可保留也可删掉)。 > 不熟悉 `cordis_define` 工具的话直接用方式 A,Agent 会自动处理好上面的取函数体步骤。 **方式 C:常驻安装(推荐,重启不丢)** 把本仓库安装为 web profile 的组合插件(与 `dsh-hud` 相同的社区插件包形态):Host 半走 `webServer` 路由、Client 半是 `__ModuleLoader__` 浏览器模块,随 `dsh web` 启动自动加载,**不需要每次重启后重新定义**,也无需审批。 ```bash # 1. 在 profile 目录添加依赖与 bundle($DSH_HOME 默认 ~/.dsh) cd ~/.dsh/profiles/web # 在 package.json 的 dependencies 中加: # "dsh-knowledge-graph": "github:cwbcheng/dsh-knowledge-graph#main" # 在 package.json 的 dsh.profile.bundles 中加: # "dsh-knowledge-graph" pnpm install # 2. 重启 dsh web(Ctrl+C 后重新 `dsh web`) ``` 重启后:对话标题右侧出现「知识图」按钮。窗口位置、筛选和历史索引等轻量 UI 状态保存在浏览器 `localStorage`;正文、图、checkpoint 与 revision 由 Host/SQLite 持久化。 | 文件 | 作用(常驻包) | | --- | --- | | [`lib/index.js`](lib/index.js) | Host 半:任务引擎 + `/api/dsh-knowledge-graph` 路由(抽取/追加、task status、`document-load`/canonical 来源成员校验 `image-load`/`document-export`、revisioned `graph-commit`、`graph-query`、`answer-graph`、安全 `resume-extract`、验证/质疑等)+ 自动 SQLite canonical graph / checkpoint 持久化 | | [`lib/client.js`](lib/client.js) | Client 半:`__ModuleLoader__` 浏览器模块(fetch RPC + 手动样式注入) | | [`cordis.patch.yml`](cordis.patch.yml) | bundle patch:向组合插入 `dsh-knowledge-graph` 行 | > `src/` 与 `lib/` 是同一插件的两种部署形态:`src/` 供动态插件(方式 A/B)使用,`lib/` 供常驻组合(方式 C)使用,逻辑保持一致。 ### 3. 批准运行 定义成功后运行会进入 **awaiting approval(等待批准)** 状态: - 插件面板(左下角 **Cordis Plugin** 按钮)会自动弹出并高亮待批准的行; - 点 **✓(单勾)**:仅授权本次运行;点 **✓✓(双勾)**:同时授权该插件后续版本的自动运行(推荐); - 批准后插件在浏览器中激活,面板状态变为 **running**。 ### 4. 验证安装 - 任意对话的**标题右侧**(对话头部操作行)出现「知识图」按钮; - 点击弹出**浮动工作台**,粘贴一段正文 → **AI 拆分**,约 15–40 秒后得到知识图; - 对话区顶部出现第三个标签页「轨迹知识图」(对话 / 轨迹 / 轨迹知识图),点击 → **拆解本会话轨迹**,约 15–40 秒后得到该会话的轨迹知识图。 ### 5. SQLite 持久化与 CLI CLI 使用 Node `node:sqlite`,当前要求 Node 22.5+;不需要额外 npm 依赖。它适合把浏览器或 Host 导出的 `KnowledgeGraphDto` 落盘,再进行候选实体 / 声明的人工审核。 ```bash # 初始化数据库 npm run kg -- init --db ./data/knowledge.sqlite # 导入抽取结果(JSON 文件可直接来自 task.result) npm run kg -- import-graph --db ./data/knowledge.sqlite --input ./graph.json # 查看候选实体或声明 npm run kg -- list-candidates --db ./data/knowledge.sqlite --kind entity --status candidate npm run kg -- list-candidates --db ./data/knowledge.sqlite --kind claim --status candidate # 接受 / 驳回候选 npm run kg -- set-candidate --db ./data/knowledge.sqlite --kind entity --id ent_xxx --status accepted npm run kg -- set-candidate --db ./data/knowledge.sqlite --kind claim --id clm_xxx --status rejected # 查看已持久化文档与 checkpoint npm run kg -- list-documents --db ./data/knowledge.sqlite npm run kg -- show-document --db ./data/knowledge.sqlite --id document_xxx npm run kg -- save-checkpoint --db ./data/knowledge.sqlite --input checkpoint.json --run-id run_xxx npm run kg -- load-checkpoint --db ./data/knowledge.sqlite --run-id run_xxx ``` 常驻包的 `lib/index.js` 会在每个成功 chunk 和任务完成时自动写入 SQLite;数据库路径由 `DSH_KG_DB` 指定,未指定时为当前工作目录的 `.dsh-knowledge-graph.sqlite`。`npm run test:kg` 会在内存 SQLite 中验证文档、chunk、evidence、候选状态变更、checkpoint 保存与恢复;`npm run test:kg-consumption` 覆盖动态 RPC / 常驻 HTTP / SQLite 检索语义、800 节点窗口之外与 600+ 常见候选之后的精确召回、relation-only 查询、上下文预算、revision fence、非法过滤器、node/edge/source citation 认证、未知及「真实但无关」evidenceId 拒绝和共享前端入口;`npm run test:kg-timeout` 使用不合作 provider 回归真实 wall-clock deadline、晚到 iterator 清理与即时取消;`npm run test:kg-image` 覆盖动态 / 常驻图片 admission、多模态 content block、文字 / 表格 / 图示转写、颜色分组与对象对应关系遗漏补漏、text-only 模型 typed 拒绝、visual provenance、canonical 来源成员校验图片读取、伪造 visual checkpoint 拒绝、转写后即时 checkpoint / runId 恢复及 SQLite 不落原始 base64;`npm run test:kg-performance` 在 10000+ 节点 / 关系图上验证 keyset 分页和有界返回;`npm run test:kg-candidates` 额外验证候选列表和状态更新。常驻包构建时会同步生成 [`lib/kg-store.mjs`](lib/kg-store.mjs)。 ### 冻结质量回归门禁 `kg:quality-regression` 固定使用 2844 字的 world-recognition 原文与 calibrated-v2 的 25 个 QA case。修复后观察基线为 24/25;默认门禁要求 trusted QA 至少 23/25(最多退化 1 case)、score 至少 92、节点至少 20。节点下限只是 catastrophic-collapse sentinel,不能替代 QA 分数。`--graph` 模式也会先校验 `graph.sourceText` 的字符数和 SHA-256;缺少原文或换了文章时返回 `frozen_source_missing` / `frozen_source_mismatch`,不会输出误导性分数。 ```bash # 检查已有 graph(不会调用模型) npm run kg:quality-regression -- --graph ./graph.json # 调用当前 DSH Host 做真实抽取,再检查并保存结果 npm run kg:quality-regression -- \ --base-url http://127.0.0.1:3080 \ --provider codex-proxy \ --model gpt-5.6-sol \ --output ./quality-run.json ``` CI 也可以设置 `DSH_KG_QA_BASE_URL`、`DSH_KG_QA_PROVIDER`、`DSH_KG_QA_MODEL` 后直接运行 `npm run kg:quality-regression`。门禁同时校验冻结原文的字符数与 SHA-256,防止通过改评测原文或 QA 尺子掩盖回归。 ## 更新插件 - **动态安装(方式 A/B)**:仓库有更新后重复方式 A——让 Agent 重新读取两个源文件并 `cordis_define`(在同一个插件下追加新 Package),再 `cordis_run`(update 模式)切换到新版本;若你之前点了双勾,新版本会自动运行。 - **常驻安装(方式 C)**:更新后重新 `pnpm install`(拉取最新 `#main`)并重启 `dsh web` 即可。 ## 卸载插件 - **动态安装**:打开 **Cordis Plugin** 面板 → 在插件行点击 **停止(Stop)** 暂停使用;需要彻底删除定义时使用 `cordis_undefine`。 - **常驻安装**:从 profile 的 `package.json` 移除依赖与 bundles 条目,`pnpm install` 后重启。 窗口布局、历史索引等轻量 UI 数据保存在浏览器 `localStorage`;书级正文、canonical graph、checkpoint 与 graph revision 在常驻模式保存在 Host/SQLite。卸载前如需长期保留知识内容,请保留对应 SQLite 数据库或先导出 JSON/CSV。 ## 注意事项 - 动态插件运行在 DSH **进程内**:进程重启后插件会消失,需要重新安装(方式 A 或改用常驻方式 C,历史数据仍保留在浏览器里);常驻插件随服务启动自动加载,不受重启影响; - Host 半依赖可用的 LLM(见前置条件);AI 调用只发生在你自己的 DSH 环境内,是否外传取决于你配置的模型提供方。图片抽取会把已由 DSH 附件服务接纳的原图发送给所选多模态模型,敏感图片请先确认提供方的数据政策; - 本项目**不含**付费 / 配额功能:拆分、历史、双向定位全部在本地完成。 ## 使用 1. 点击对话标题右侧的「知识图」按钮,打开浮动工作台; 2. 在「输入资料」粘贴正文,或点 **上传图片** 选择包含文字、图示或表格的图片(可同时输入说明文字、可选填标题);选择支持图片的模型后点 **AI 拆分 / 图片生成知识图**。图片生成后,原文栏顶部会显示可点击的原图画廊与视觉转写风险提示(输入区可收起;结果区高度、原文/图宽度比例均可拖拽调整并记忆); 3. 摘要 / 图出现后,**点图中节点查看详情卡片(完整内容)并定位原文**,或**点原文段落聚焦图中节点**; 4. 在 **「使用这张知识图」** 面板切换「结构化检索 / 证据问答」:按关键词、类型、章节找节点,或直接向 canonical graph 提问;点击结果/citation 可回链节点、关系与原文证据; 5. 点 **⚡ 快速体检** 立即拿到确定性问题报告,或点 **🤖 AI 深度审校** 让 LLM 以原文为证据逐节点找茬;点 **🔎 外部事实核查** 则用外部证据核查原文本身;点击问题/断言行高亮图中相关节点/边并定位原文,**采纳修复**或**忽略**;在节点详情卡「质疑此节点」、选中边后「质疑此关系」,或在验证面板底部直接向整张图提问/质疑; 6. 在「章节与候选审核」面板选择章节,只查看该章节的图和原文;对候选实体 / 声明点「已接受」或「已驳回」,点击候选卡可回链原文证据; 7. 想继续扩展图:在输入区粘贴下一段资料,点 **追加拆分**(或直接选中聊天消息里的文字自动追加)——新增节点与已有节点自动建立跨段关系,全文段落统一编号,历史记录原地更新;此前验证结果会自动标记为过期,可重新验证; 8. 用「历史」回看之前的拆分(自动保存最近 20 条,可单删 / 清空);任务进行中关窗或刷新,重开窗口会自动恢复轮询; 9. 对话区切换到「轨迹知识图」标签页,点 **拆解本会话轨迹** 生成会话轨迹知识图;轨迹图也提供相同的结构化检索与证据问答入口;点击轨迹事件在图中聚焦节点,点击节点查看完整内容并滚动到对应事件;结果在切换标签页 / 刷新后自动恢复,拖拽中间竖条调两列宽度、拖拽下方横条调结果区高度。 ## 知识图消费层 ### 前端使用 生成正文知识图或轨迹知识图后,下方会出现共享的 **「使用这张知识图」** 面板: 1. **结构化检索**:输入关键词,并可叠加节点类型与章节筛选;返回列表只表示直接命中,关系邻居保留在响应子图中作为上下文,不会伪装成直接命中。 2. **证据问答**:输入自然语言问题,Host 先做有界节点召回、最多两跳关系扩展和原文段落 fallback,再调用当前选择的模型;`answered`、`insufficient`、`out_of_scope` 都是成功的语义结果。 3. 点击检索结果或回答 citation 会同时聚焦节点与原文。若目标节点不在当前 800 节点窗口,Client 会调用 `document-load({ query: nodeId })` 加载该节点及其邻居后再定位,而不是把“当前没渲染”误判为“图中不存在”。 4. 面板的错误、任务轮询与取消状态独立于抽取/验证面板,不会覆盖父工作台的错误提示。 ### `graph-query`:有界结构化检索 动态插件调用 `host.call('graph-query', body)`;常驻包调用 `POST /api/dsh-knowledge-graph/graph-query`。公开请求以 logical document 为边界: ```json { "documentId": "document_xxx", "expectedRevision": 4, "query": "断点恢复", "nodeIds": [], "types": ["fact", "rule"], "relations": ["supports", "causes"], "sectionIds": ["section-2"], "groundingStatuses": ["grounded"], "entailmentStatuses": ["verified", "uncertain", "unverified"], "limit": 20, "hops": 1, "direction": "both", "maxNodes": 80, "maxEdges": 240 } ``` - `nodeIds / types / sectionIds / groundingStatuses / entailmentStatuses` 是 hard filter;非法枚举返回 typed `invalid_input`,不会静默丢弃后退为全图查询。 - `relations` 限制返回/扩展的关系类型;`direction` 为 `both | in | out`。`relations` 也可单独作为 selector:Host/SQLite 会先从匹配关系的端点播种直接候选,而不是从文档开头任取节点。 - `matches` 只包含直接命中;`graph.nodes/edges` 还可包含 0–2 跳邻居。直接命中的原文单元优先于邻居证据进入预算,预算截断量通过 `metrics.sourceRefsOmitted` 暴露。 - 响应包含 `documentId`、`revision`、`matches`、有界 `graph`、可回链 `sourceUnits` 和 `metrics`,不返回完整 `sourceText`。动态与常驻模式都对公开 node/edge/evidence 做字段与长度投影,`sourceUnits` 不再重复携带 quote 数组,并对聚合上下文设置硬 envelope;`metrics.contextChars/contextBudget` 可用于观测。 - 当前硬上限:查询 600 字、直接命中 40、节点 160、关系 480、跳数 2、原文单元 80、原文文本 24000 字;graph context 另有约 384000 字 envelope。调用者给出更小的 `maxNodes/maxEdges` 时也会严格遵守。 - 常驻模式在 SQLite 中一次查询就完成候选排名、关系扩展、精确 `document_units` 回填和可选 source fallback,不再先查 SQLite、再把结果交给 Host 做第二次检索/重组。词汇候选和 source fallback 使用 keyset 分页,避免随页码增长的 `OFFSET` 重扫;`queryId` 包含全部规范化 selector 与有效预算。 - `expectedRevision` 与 canonical revision 不一致时返回 `revision_conflict`,避免把旧 UI 状态与新图混用。抽取、重新抽取、追加与 checkpoint 恢复也会记录启动时 revision,并在发布 canonical replacement 时执行同样 fencing。 ### `answer-graph`:canonical graph + 原文证据问答 `answer-graph` 是异步任务,复用既有 `task-status` / `task-cancel`: ```json { "documentId": "document_xxx", "expectedRevision": 4, "question": "为什么检查点能够支持断点续跑?", "types": [], "sectionIds": [], "hops": 1, "model": { "provider": "...", "model": "..." } } ``` 启动响应: ```json { "taskId": "kg_xxx" } ``` 任务完成后的核心结果: ```json { "status": "answered", "answer": "由 Host 拼接的已接纳回答", "parts": [ { "id": "part-1", "text": "一个独立回答命题", "evidenceIds": ["ev3"] } ], "citations": [ { "id": "ev3", "targetKind": "node", "targetId": "n12", "nodeId": "n12", "paragraph": 8, "quote": "canonical 原文逐字摘录", "groundingStatus": "grounded", "entailmentStatus": "unverified" } ] } ``` 安全与可信边界: - 图片请求在 Client 与 Host 双侧限制为最多 4 张、单张 6 MiB、合计 16 MiB,并只接受 PNG / JPEG / WebP / GIF。Host 在任务发布前解码 canonical base64 并调用 DSH `attachments.saveImages()`;之后任务、checkpoint、canonical graph、`task-status` 与 SQLite 都只保留不可变 attachment ref / 元数据,**不持久化原始 base64**。 - 插件会在调用 `saveImages()` 前预检已明确声明为仅文本的模型,避免这类确定性失败写入附件。DSH 当前公开附件契约是持久化、内容寻址存储且没有插件可调用的删除 API;因此能力未知的模型、模型超时或视觉 schema 失败发生在 admission 之后时,底层附件的保留周期由所配置的 DSH attachment backend 决定。对敏感图片应同时遵循该 backend 的留存 / 清理策略。 - `image-load` 不接受任意 attachment id:它先按 `documentId`(及可选 expected revision)加载 canonical source,再确认 `imageId` 确实属于 `source.visualSource.images`,最后才读取有界图片字节。公开 graph 可包含 attachment ref 以保留证据来源,但不直接包含像素字节。 - 图片证据的可回链文本来自模型生成的 immutable 视觉转写。Host 仍会对节点 quote 与该 canonical 转写做确定性认证,但这只能证明节点忠于“转写”,不能证明转写忠于像素;UI 因此同时展示原图、图片段落范围和风险提示,要求人工复核关键证据。 - `image-load` 与其他 canonical document API 一样依赖 DSH Web 的同源 / 工作区信任边界;`documentId` 是高熵随机 UUID,但不是多租户授权令牌。不要把同一 DSH Web origin 暴露给互不信任的租户;Chrome 扩展的 `/dsh-kg` allowlist 不开放 `image-load`。 - 对带 `documentId` 的请求,Host/SQLite **只从服务端加载 canonical graph 与 source**;客户端提交的 `graph` / `text` 不会成为事实源。 - Host 在调用模型前,从已认证 node evidence、edge evidence 和 source paragraph fallback 中预分配最多 24 个 `evidenceId`。模型只能返回 `parts[].evidenceIds`,不能自行声明 `nodeId/paragraph/quote`。 - Host 丢弃未知 evidenceId、真实但与命题词汇无关的 evidenceId,以及没有合法证据的 `answered` part;`candidate/unverified/uncertain` 证据还要求回答显式使用“资料表述/可能/未验证”等限定措辞,`unsupported` 证据不能被包装成已证实结论。若所有 part 都被丢弃,结果自动降级为 `insufficient`。即使 part 通过准入,模型原始 `part.text` 也不会直接展示:Host 会从已认证 node/edge/source evidence 确定性渲染 part,再拼接最终 `answer`;`insufficient/out_of_scope` 也只返回 Host 固定语义文案且不返回 follow-up;`answered` 的 follow-up 由 citation target ID / paragraph 确定性生成,因此模型自由文本无法借回答或可点击追问混入结果。 - `targetKind=node | edge | source` 分别支持节点命题、关系命题和图覆盖不足时的原文段落证据。关系结论可直接引用 edge evidence,而不是只拿端点节点充当关系证明。 - `groundingStatus=grounded` 只表示 quote 可回到 canonical 原文,**不等价于外部事实已证实**;外部真实性仍应使用「外部事实核查」。`entailmentStatus` 会原样进入 citation,UI 不会把 `unverified/uncertain/unsupported` 包装成已验证事实。 - 原文中的 prompt injection 文本在问答提示中明确标记为待分析数据;输出仍经过严格 JSON 解析、evidence-ID admission、长度和数量上限。 - 每次模型调用都执行真实 wall-clock deadline,计时覆盖 `llm.stream()` 建立连接和完整异步迭代;超时以 typed `timeout` 失败,取消以 `cancelled` 结束。即使 provider 忽略 `AbortSignal` 或 `iterator.return()` 不返回,任务也会立即释放前台 busy 状态,晚到 iterator 会在进入 `next()` 前被幂等关闭,部分输出不会发布。运维/回归可用 `DSH_KG_MODEL_TIMEOUT_CAP_MS`(最小 20ms)把各调用点原有 deadline 统一下调;未设置时保留各阶段 60–360 秒的既有预算。 ## Chrome 扩展(划线拆图) 在**任意网页**上选中文字,点浮动按钮「拆成知识图」,一键调用本机 DSH 服务生成知识图(弹窗内可直接拆分、看图、回链原文)。 - 源码在仓库 `extension/` 目录,零依赖打包:`viewer.js` 由 `scripts/build-viewer.mjs` 从 `src/index.client.js` 切片生成(`d3/*.js` 为内嵌 d3 模块的独立文件——MV3 扩展页禁止 eval,popup 用 `