dsh-data-domain-knowledge 0.1.0-alpha.12 → 0.1.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/README.md +97 -57
  2. package/cordis.patch.yml +21 -17
  3. package/eval/benchmark-extraction-format.mjs +20 -0
  4. package/lib/client.js +2886 -3855
  5. package/lib/doc-page.js +1 -1
  6. package/lib/pages.js +1299 -1660
  7. package/lib/types/axis-registry.d.ts +6 -0
  8. package/lib/types/axis-registry.d.ts.map +1 -1
  9. package/lib/types/axis-registry.js +45 -0
  10. package/lib/types/axis-registry.js.map +1 -1
  11. package/lib/types/diagnosis/cards.d.ts +7 -3
  12. package/lib/types/diagnosis/cards.d.ts.map +1 -1
  13. package/lib/types/diagnosis/cards.js +13 -8
  14. package/lib/types/diagnosis/cards.js.map +1 -1
  15. package/lib/types/diagnosis/run.d.ts +4 -13
  16. package/lib/types/diagnosis/run.d.ts.map +1 -1
  17. package/lib/types/diagnosis/run.js +26 -16
  18. package/lib/types/diagnosis/run.js.map +1 -1
  19. package/lib/types/diagnosis/schema.js +2 -2
  20. package/lib/types/diagnosis/schema.js.map +1 -1
  21. package/lib/types/diagnosis/seed-source.d.ts +1 -1
  22. package/lib/types/diagnosis/seed-source.d.ts.map +1 -1
  23. package/lib/types/diagnosis/seed-source.js +5 -4
  24. package/lib/types/diagnosis/seed-source.js.map +1 -1
  25. package/lib/types/diagnosis/seed.d.ts +4 -4
  26. package/lib/types/diagnosis/seed.d.ts.map +1 -1
  27. package/lib/types/diagnosis/seed.js +6 -8
  28. package/lib/types/diagnosis/seed.js.map +1 -1
  29. package/lib/types/diagnosis/store.d.ts +8 -16
  30. package/lib/types/diagnosis/store.d.ts.map +1 -1
  31. package/lib/types/diagnosis/store.js +41 -66
  32. package/lib/types/diagnosis/store.js.map +1 -1
  33. package/lib/types/diagnosis/types.d.ts +10 -16
  34. package/lib/types/diagnosis/types.d.ts.map +1 -1
  35. package/lib/types/diagnosis/types.js.map +1 -1
  36. package/lib/types/environment/install.d.ts +2 -1
  37. package/lib/types/environment/install.d.ts.map +1 -1
  38. package/lib/types/environment/install.js +20 -11
  39. package/lib/types/environment/install.js.map +1 -1
  40. package/lib/types/environment/manifest.d.ts +203 -12
  41. package/lib/types/environment/manifest.d.ts.map +1 -1
  42. package/lib/types/environment/manifest.js +23 -21
  43. package/lib/types/environment/manifest.js.map +1 -1
  44. package/lib/types/environment/model-catalog.d.ts +191 -0
  45. package/lib/types/environment/model-catalog.d.ts.map +1 -0
  46. package/lib/types/environment/model-catalog.js +91 -0
  47. package/lib/types/environment/model-catalog.js.map +1 -0
  48. package/lib/types/environment/selection.d.ts +9 -0
  49. package/lib/types/environment/selection.d.ts.map +1 -0
  50. package/lib/types/environment/selection.js +29 -0
  51. package/lib/types/environment/selection.js.map +1 -0
  52. package/lib/types/environment/service.d.ts +5 -4
  53. package/lib/types/environment/service.d.ts.map +1 -1
  54. package/lib/types/environment/service.js +142 -53
  55. package/lib/types/environment/service.js.map +1 -1
  56. package/lib/types/environment/types.d.ts +16 -1
  57. package/lib/types/environment/types.d.ts.map +1 -1
  58. package/lib/types/events.d.ts +2 -0
  59. package/lib/types/events.d.ts.map +1 -1
  60. package/lib/types/events.js +13 -0
  61. package/lib/types/events.js.map +1 -1
  62. package/lib/types/extract-contract.d.ts +1 -1
  63. package/lib/types/extract-contract.d.ts.map +1 -1
  64. package/lib/types/extract-contract.js +34 -31
  65. package/lib/types/extract-contract.js.map +1 -1
  66. package/lib/types/extract-model.d.ts +2 -0
  67. package/lib/types/extract-model.d.ts.map +1 -1
  68. package/lib/types/extract-model.js.map +1 -1
  69. package/lib/types/extract-table-contract.d.ts +3 -0
  70. package/lib/types/extract-table-contract.d.ts.map +1 -0
  71. package/lib/types/extract-table-contract.js +30 -0
  72. package/lib/types/extract-table-contract.js.map +1 -0
  73. package/lib/types/extract-table.d.ts +8 -0
  74. package/lib/types/extract-table.d.ts.map +1 -0
  75. package/lib/types/extract-table.js +151 -0
  76. package/lib/types/extract-table.js.map +1 -0
  77. package/lib/types/extraction-runs.d.ts +3 -0
  78. package/lib/types/extraction-runs.d.ts.map +1 -1
  79. package/lib/types/extraction-runs.js +6 -0
  80. package/lib/types/extraction-runs.js.map +1 -1
  81. package/lib/types/images.d.ts +26 -0
  82. package/lib/types/images.d.ts.map +1 -0
  83. package/lib/types/images.js +196 -0
  84. package/lib/types/images.js.map +1 -0
  85. package/lib/types/index.d.ts.map +1 -1
  86. package/lib/types/index.js +220 -46
  87. package/lib/types/index.js.map +1 -1
  88. package/lib/types/intent/scope.d.ts.map +1 -1
  89. package/lib/types/intent/scope.js +1 -0
  90. package/lib/types/intent/scope.js.map +1 -1
  91. package/lib/types/knowledge-bases.d.ts.map +1 -1
  92. package/lib/types/knowledge-bases.js +3 -2
  93. package/lib/types/knowledge-bases.js.map +1 -1
  94. package/lib/types/knowledge.d.ts +3 -0
  95. package/lib/types/knowledge.d.ts.map +1 -1
  96. package/lib/types/knowledge.js +12 -3
  97. package/lib/types/knowledge.js.map +1 -1
  98. package/lib/types/layout.d.ts +2 -0
  99. package/lib/types/layout.d.ts.map +1 -1
  100. package/lib/types/layout.js +2 -0
  101. package/lib/types/layout.js.map +1 -1
  102. package/lib/types/model-text.d.ts +1 -1
  103. package/lib/types/model-text.d.ts.map +1 -1
  104. package/lib/types/model-text.js +5 -4
  105. package/lib/types/model-text.js.map +1 -1
  106. package/lib/types/pipeline/engine.d.ts +57 -0
  107. package/lib/types/pipeline/engine.d.ts.map +1 -0
  108. package/lib/types/pipeline/engine.js +268 -0
  109. package/lib/types/pipeline/engine.js.map +1 -0
  110. package/lib/types/pipeline/store.d.ts +56 -0
  111. package/lib/types/pipeline/store.d.ts.map +1 -0
  112. package/lib/types/pipeline/store.js +115 -0
  113. package/lib/types/pipeline/store.js.map +1 -0
  114. package/lib/types/pipeline/types.d.ts +82 -0
  115. package/lib/types/pipeline/types.d.ts.map +1 -0
  116. package/lib/types/pipeline/types.js +5 -0
  117. package/lib/types/pipeline/types.js.map +1 -0
  118. package/lib/types/present.d.ts +2 -0
  119. package/lib/types/present.d.ts.map +1 -1
  120. package/lib/types/present.js +9 -4
  121. package/lib/types/present.js.map +1 -1
  122. package/lib/types/runtime.d.ts +29 -4
  123. package/lib/types/runtime.d.ts.map +1 -1
  124. package/lib/types/runtime.js +462 -128
  125. package/lib/types/runtime.js.map +1 -1
  126. package/lib/types/source-evidence.d.ts.map +1 -1
  127. package/lib/types/source-evidence.js +2 -0
  128. package/lib/types/source-evidence.js.map +1 -1
  129. package/lib/types/store/axis-references.js +3 -3
  130. package/lib/types/store/axis-references.js.map +1 -1
  131. package/lib/types/store/migrate.d.ts.map +1 -1
  132. package/lib/types/store/migrate.js +6 -5
  133. package/lib/types/store/migrate.js.map +1 -1
  134. package/lib/types/types.d.ts +4 -5
  135. package/lib/types/types.d.ts.map +1 -1
  136. package/lib/types/types.js +3 -4
  137. package/lib/types/types.js.map +1 -1
  138. package/lib/types/wiki-materialize.d.ts.map +1 -1
  139. package/lib/types/wiki-materialize.js +3 -15
  140. package/lib/types/wiki-materialize.js.map +1 -1
  141. package/lib/types/wiki-trial-types.d.ts +3 -0
  142. package/lib/types/wiki-trial-types.d.ts.map +1 -1
  143. package/lib/types/wiki-trial.d.ts +2 -0
  144. package/lib/types/wiki-trial.d.ts.map +1 -1
  145. package/lib/types/wiki-trial.js +31 -7
  146. package/lib/types/wiki-trial.js.map +1 -1
  147. package/package.json +6 -3
  148. package/preset/tita-data-agent/agent.cordis.yml +21 -17
  149. package/python/prepare-models.py +1 -1
  150. package/scripts/setup-embedding.sh +11 -2
  151. package/src/axis-registry.ts +38 -0
  152. package/src/client/AttributionEventGuide.tsx +10 -9
  153. package/src/client/EnvironmentSetup.tsx +76 -10
  154. package/src/client/ExtractionTasksPage.tsx +129 -176
  155. package/src/client/KnowledgeBaseTab.tsx +31 -76
  156. package/src/client/NodeSettings.tsx +2 -3
  157. package/src/client/PipelineNotice.tsx +26 -0
  158. package/src/client/TabGuide.tsx +4 -4
  159. package/src/client/TypeDefinitionDrawer.tsx +23 -8
  160. package/src/client/WikiCardPreview.tsx +43 -10
  161. package/src/client/WikiFlowPanel.tsx +4 -4
  162. package/src/client/architecture.tsx +1 -1
  163. package/src/client/attribution/AttributionTab.tsx +6 -6
  164. package/src/client/attribution/CaseView.tsx +3 -1
  165. package/src/client/attribution/EventView.tsx +14 -4
  166. package/src/client/attribution/RunView.tsx +2 -2
  167. package/src/client/attribution/graph-options.ts +2 -2
  168. package/src/client/pages.tsx +2 -2
  169. package/src/diagnosis/cards.ts +13 -8
  170. package/src/diagnosis/run.ts +27 -17
  171. package/src/diagnosis/schema.ts +2 -2
  172. package/src/diagnosis/seed-source.ts +5 -4
  173. package/src/diagnosis/seed.ts +6 -8
  174. package/src/diagnosis/store.ts +47 -68
  175. package/src/diagnosis/types.ts +10 -16
  176. package/src/environment/install.ts +22 -10
  177. package/src/environment/manifest.ts +25 -22
  178. package/src/environment/model-catalog.ts +105 -0
  179. package/src/environment/selection.ts +29 -0
  180. package/src/environment/service.ts +122 -46
  181. package/src/environment/types.ts +11 -1
  182. package/src/events.ts +12 -0
  183. package/src/extract-contract.ts +6 -3
  184. package/src/extract-model.ts +2 -0
  185. package/src/extract-table-contract.ts +29 -0
  186. package/src/extract-table.ts +126 -0
  187. package/src/extraction-runs.ts +6 -0
  188. package/src/images.ts +203 -0
  189. package/src/index.ts +185 -48
  190. package/src/intent/scope.ts +1 -0
  191. package/src/knowledge-bases.ts +3 -2
  192. package/src/knowledge.ts +13 -3
  193. package/src/layout.ts +2 -0
  194. package/src/model-text.ts +5 -3
  195. package/src/pipeline/engine.ts +238 -0
  196. package/src/pipeline/store.ts +119 -0
  197. package/src/pipeline/types.ts +74 -0
  198. package/src/present.ts +10 -4
  199. package/src/runtime.ts +418 -126
  200. package/src/source-evidence.ts +1 -0
  201. package/src/store/axis-references.ts +3 -3
  202. package/src/store/migrate.ts +5 -5
  203. package/src/types.ts +7 -9
  204. package/src/wiki-materialize.ts +3 -14
  205. package/src/wiki-trial-types.ts +3 -0
  206. package/src/wiki-trial.ts +26 -7
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # dsh-data-domain-knowledge
2
2
 
3
- 本地知识库插件:一个知识库是一个目录,里面四样东西。`knowledge.db` 保存 **SourceRaw**
4
- (原始可追溯文档)、按主题聚合可双向链接的 wiki 卡片,以及**两者的每一个版本**;
5
- `derived.db` 输出可检索的 **wikiNotes**、wiki
6
- 知识图谱和向量索引,`<agentRoot>/memory/<库 id>` 保存操作日志、抽取轨迹、访问审计与反馈。
3
+ 本地知识库插件:一个知识库对应一个目录。`knowledge.db` 保存 **SourceRaw**
4
+ (原始可追溯文档)、轴、Knowledge、Event、wiki 卡片、版本与阶段检查点;
5
+ `derived.db` 保存可重建的 **wikiNotes**、知识图谱和向量索引,`assets/` 保存图片与附件。
6
+ 知识库目录外的 `<agentRoot>/memory/<库 id>` 保存任务与正式输出、抽取轨迹、操作日志、访问审计与反馈。
7
7
  默认使用本地 Python 推理:`BAAI/bge-small-zh-v1.5` 生成 512 维文本向量,
8
8
  `BAAI/bge-reranker-base` 对召回候选做交叉编码重排。部署入口必须完成环境自检,
9
- 索引必须匹配当前模型;不满足时提示准备环境或重新编译。
9
+ 索引必须匹配当前模型;不满足时提示准备环境或构建检索索引。
10
10
  需要图片语义检索时,可配置 WeMM 多模态模型与匹配维度,Markdown 中的本地图片
11
11
  会与正文一起交给模型。图片不作为独立知识类型。
12
12
 
@@ -16,10 +16,11 @@ Tita Agent 的固定数据根目录是 `$DSH_HOME/tita-agent`(默认 `~/.dsh/t
16
16
 
17
17
  ## 首次运行环境准备
18
18
 
19
- Python、向量模型、重排模型是部署必需项。打开 Tita 设置 → 环境准备 → 一键安装 / 修复。
20
- 系统使用 uv 安装专属 Python 环境,下载固定 revision 的 `BAAI/bge-small-zh-v1.5`
21
- (512 维)和 `BAAI/bge-reranker-base`,然后运行真实推理自检。阶段、错误和下载日志
22
- 可查看;下载失败可以重试。未就绪时阻止编译和知识召回,来源与历史内容仍可保存、读取。
19
+ 向量模型和重排模型在 Tita 设置 → 环境准备中选择,再安装 / 修复。
20
+ 系统用 DSH 自带的 Python 3.12 创建专属依赖环境,不另行下载 Python;再下载所选模型,
21
+ 默认是 `BAAI/bge-small-zh-v1.5`(512 维)和 `BAAI/bge-reranker-base`,然后运行真实推理自检。阶段、错误和下载日志
22
+ 可查看;下载失败可以重试。就绪检查按所用能力执行:抽取、归一和物化只需要 LLM;构建向量索引需要向量模型;召回按启用的向量和重排能力检查。来源与历史内容仍可保存、读取。
23
+ 自检不单独检查 `sentencepiece`;依赖安装失败会显示安装错误,模型真实推理失败会显示对应模型的错误。
23
24
 
24
25
  命令行入口:
25
26
 
@@ -29,8 +30,8 @@ pnpm --filter dsh-data-domain-knowledge environment:check
29
30
  pnpm --filter dsh-data-domain-knowledge doctor
30
31
  ```
31
32
 
32
- 自检失败时命令返回非零退出码。安装不修改系统 Python,也不隐式运行 npm postinstall
33
- 模型下载。已有知识在准备完成后需重新编译;宿主无需重启。自定义路径保留,使用默认
33
+ 自检失败时命令返回非零退出码。依赖装在 Tita 专属虚拟环境中,不修改系统 Python,也不隐式运行 npm postinstall
34
+ 模型下载。已有卡片在准备完成后需构建检索索引,文档无需重新抽取;宿主无需重启。自定义路径保留,使用默认
34
35
  资源时把高级设置中的路径恢复为空,并使用匹配的向量维度。
35
36
  细节见 [运行环境准备与自检](../../docs/current/16-知识运行环境准备与自检.md)。
36
37
 
@@ -51,19 +52,49 @@ pnpm --filter dsh-data-domain-knowledge doctor
51
52
  分类与 act 是代码内置的固定契约,不提供编辑入口。读接口 `/intent/store` 与 `/intent/overview` 读的是**留痕**:
52
53
  引擎内存里那份有 600 秒 TTL,重启或隔一段时间回来不该让面板上的历史凭空消失。
53
54
 
54
- ## 五段链路
55
+ ## 独立运行知识链路
55
56
 
56
- | 段 | 名称 | 产物 | 关键配置 |
57
- | --- | --- | --- | --- |
58
- | 1 | SourceRaw | 原始可追溯文档:`knowledge.db` 的 `source` + `blob` | `allowSourceTruth` / `rootDir` |
59
- | 2 | 编译 Compile | wiki:`knowledge.db` 的 `card`(**按 wiki 类型 schema 抽实体,直接入库**);wikiNotes:`derived.db` 的 `wiki_notes.json` | `extractCandidates` / `extractWithModel` / `wikiTypes` |
60
- | 3 | 构建 Build | wikiNotes → 向量索引;wiki → `derived.db` 的 `knowledge_graph.json` | `embeddingProvider` / `embeddingModel` / `python` |
61
- | 4 | 召回 Recall | 多路(坐标 + 关键词 + 向量)召回 wikiNotes,取 `recallTopK`(默认 10),再解析父级 wiki 与该 wiki 的 1 跳知识图谱 | `recallTopK` |
62
- | 5 | 重排 Rerank | BERT cross-encoder 对候选 wikiNotes 精排,取 `contextTopN`(默认 5)组成 `context` | `contextTopN` / `rerankProvider` / `rerankModel` |
57
+ 导入默认只保存来源。打开「知识处理」页面,按需运行以下阶段。也可以选择「全链路运行」。
58
+
59
+ | 阶段 | 输入 → 产物 | 模型与复用 |
60
+ | --- | --- | --- |
61
+ | 入库 | 文档 → SourceRaw 与版本 | 不调用模型;`import_sources` 默认 `compile: false` |
62
+ | 抽取 Knowledge / Event | 指定来源版本 → 原始 mention、引文与抽取检查点 | 本库所选 LLM;默认表格输出,兼容历史 JSON;未变化来源复用 |
63
+ | 归一合并 | 保存的抽取返回 → canonical 轴、Knowledge、Event | 精确查注册表;必要时模型补判;不重新抽取文档 |
64
+ | 物化 WikiCard | Knowledge 完整坐标分组 → 卡片与章节;Event 只建立同坐标引用 | 可选模型组织;Event 不进入卡片正文,也不单独生成 WikiCard |
65
+ | 构建检索索引 | 已保存卡片 → Wiki Note、FTS、向量与图谱 | 使用所选向量模型;事务发布一份检索快照 |
66
+ | 召回与重排 | Query → 多路候选 → RRF / 图谱加权 → 重排 → Context | 候选池先于最终截断;单个候选也经过重排阈值;停用卡片不召回 |
67
+
68
+ 向量、重排模型在环境准备中按列表选择;安装并通过实际推理后启用。选择托管模型会替换高级设置中的自定义模型路径,自检失败会恢复。更换向量模型只需重建索引,不需要重新抽取。
69
+
70
+ 本库「编译设置」支持选择 LLM 与模型声明的思考强度。任务入队时保存实际路由、强度、抽取备注与卡片组织设置;修改设置作用于后续任务。
71
+
72
+ ### 运行接口
73
+
74
+ - `run_knowledge_pipeline`:`stage` 为 `extract`、`normalize`、`materialize`、`build` 或 `all`。`source_ids` 限定文档,`group_keys` 限定完整卡片分组。`force` 显式强制当前阶段。
75
+ - `get_knowledge_pipeline`:不传 `task_id` 返回阶段待办与任务历史;传任务 ID 与 `after` 游标读取状态和正式输出。刷新后可补读。
76
+ - `get_knowledge_events`:按召回 WikiCard 的 `metadata.event_refs` 读取对应 Event,不把整库事件加入每次召回。
77
+ - `GET/POST /knowledge/pipeline`:阶段状态 / 创建后台任务。`GET /knowledge/pipeline-tasks` 分页读历史,`GET/POST /knowledge/pipeline-task` 读输出 / 暂停、继续、停止、重新运行。
78
+ - `import_sources` 显式 `compile: true` 对本批写入的来源运行完整链路。`rebuild_knowledge` 仅重建已保存卡片的检索产物;正式抽取使用独立阶段接口。
79
+ - 抽取试跑仅保存审计报告;预览实体解析使用隔离副本,不写正式 Knowledge 或实体注册表。
80
+
81
+ 旧 `runtime.rebuild` 保留兼容的规则抽取兜底。当前 HTTP / 工具重建默认只构建已保存卡片的检索产物;独立阶段的模型失败会明确失败,不自动切换到规则抽取。
63
82
 
64
- > 第 4、5 段在**界面上是同一栏**(知识库 → 召回重排)。它们在流水线上仍是两步,
65
- > 但「跑一次真实召回长什么样」是一个问题,分两栏会让用户先跑召回、再切到重排才能
66
- > 看到同一次运行的全貌。
83
+ ### 增量、失败与证据
84
+
85
+ 抽取指纹包括文档正文、标题、抽取契约、备注、LLM 路由与强度;卡片模板与无关实体更新不会强制重抽。归一、物化分别维护自己的依赖指纹。
86
+
87
+ 归一时先在内存副本解析实体。提交前核验来源版本和实体注册表;在短事务中提交实体、Knowledge、Event 和归一检查点。重新归一会撤回该来源旧版本的有效贡献,并保留出处历史。其他来源支撑的同一事实继续有效。Event 根据明确身份归并,文本相似不触发跨文档合并。
88
+
89
+ 来源已变化或新抽取尚未归一时,涉及的卡片分组显示「先归一来源」。物化按唯一坐标分组计数;不按 Knowledge 条数估算卡片数。Event 与 Knowledge 同层独立保存;WikiCard 只由 Knowledge 生成,并保存同坐标 Event 的引用。物化失败保留旧卡片。归一与物化不会提前更新已发布检索索引;构建成功后统一发布。删除与停用仍立即限制召回可见性。
90
+
91
+ 任务状态与输出写入既有抽取审计库。暂停、停止在当前文档或卡片边界生效。服务重启把未结束任务标记为中断,已完成检查点保留;重新运行默认复用成功项。实时预览每份来源最多 4 MB,完整模型返回保存在报告中;页面显示最近输出。
92
+
93
+ **目录边界的原理:** `src/pipeline/` 只承接阶段契约、持久检查点和任务编排;领域归一、成卡与检索继续调用现有运行时。业务检查点仍在 `knowledge.db`,任务审计仍在原有记忆库,索引仍在 `derived.db`。不新增一套业务真源,也不把不可重建的模型返回放进可清理的派生层。
94
+
95
+ ### 表格格式基准
96
+
97
+ 运行 `pnpm bench:extraction-format`。脚本使用同一份中文语义载荷,以 `o200k_base` 比较 TOON 与紧凑 JSON 的输出 token;不代表具体模型账单或抽取准确率。示例中,12 条知识减少 43.8%,40 条减少 51.6%;单条增加 6.9%,因为固定表头有开销。实际效果取决于字段长度、引文重复率和模型 tokenizer。
67
98
 
68
99
  ## Knowledge / Wiki Card 的存储约束
69
100
 
@@ -72,8 +103,10 @@ pnpm --filter dsh-data-domain-knowledge doctor
72
103
  | 层 | 真源 | 说明 |
73
104
  | --- | --- | --- |
74
105
  | Knowledge | `knowledge` + `knowledge_sources` | 原子事实、坐标、来源、状态;不保存 Card 的排版 |
106
+ | Event | `event` | 一次事件、时间线、结果、证据与来源;独立于 WikiCard 保存 |
75
107
  | Wiki Card | `card` + `blob` + `revision` | 面向阅读和召回组装的正文;正文中的 Markdown 标题是 Section 真源 |
76
108
  | Knowledge 落位 | `card_knowledge` | 记录 Knowledge 在某张 Card 中的 Section 和顺序;这是关联索引,不是 Knowledge 属性 |
109
+ | Event 引用 | `card_event` | 连接同坐标的 WikiCard 与 Event;引用更新不改卡片正文或检索文本 |
77
110
  | Wiki Note / FTS / Vector / Graph | `derived.db` | 可以从 Card 和 Knowledge 重新构建;编译结果在同一事务发布 |
78
111
 
79
112
  ### 状态语义
@@ -119,14 +152,20 @@ Notes、FTS、向量、图和 manifest 在 `derived.db` 中通过一次事务发
119
152
 
120
153
  ## Knowledge、Wiki Card、Wiki Note 的生命周期
121
154
 
122
- 三者不是三个并列的知识真源,而是同一条知识链上的三个层次:
155
+ 这条链路包含原始证据、并列的 Knowledge / Event 事实、知识组织卡片和检索派生片段:
123
156
 
124
157
  ```text
125
- SourceRaw → Knowledge → Wiki Card → Wiki Note → FTS / Vector / Rerank
126
- 事实真源 阅读组织视图 检索派生片段
158
+ SourceRaw → 抽取 → { Knowledge, Event }
159
+ │ │
160
+ ↓ │ card_event
161
+ WikiCard ←────┘
162
+ │
163
+ ↓
164
+ WikiNote → FTS / Vector / Rerank
127
165
  ```
128
166
 
129
- - Knowledge 是不可由 Card 反向重建的事实记录。抽取、来源追加、合并、冲突裁决和状态变化都发生在这里。
167
+ - Knowledge 是不可由 Card 反向重建的事实记录。归一、来源追加、合并、冲突裁决和状态变化都发生在这里;抽取阶段只保存原始返回与检查点。
168
+ - Event 与 Knowledge 是并列事实,分别保留事件时间线和可复用判断。WikiCard 只组织 Knowledge;它按坐标引用 Event,不复制 Event 正文。
130
169
  - Wiki Card 是 Knowledge 的组织视图。Card 正文、摘要、Section 和阅读顺序可以重新编排;重新编排不应修改 Knowledge。
131
170
  - Wiki Note 是 Card 的检索切片。它没有独立的业务生命周期,`status` 只是父 Card 状态的快照;Card 变化后重新编译 Wiki Note,索引随之重建。
132
171
 
@@ -136,11 +175,7 @@ SourceRaw → Knowledge → Wiki Card → Wiki Note → FTS / Vector / Rerank
136
175
 
137
176
  - 知识库设置集中在侧边抽屉:数据位置、向量模型、检索与上下文。召回固定使用多路径融合;
138
177
  低频设备、阈值和模型细节收在高级设置中。Agent 系统提示词常显,并链接到 preset 真源目录。
139
- - **编译直接入库(0044)**:`rebuild_knowledge` 的 Pass 0 对指纹变了的来源做实体抽取,
140
- 按 `entityType:entityId` / `title` / `metadata.aliases` 三重索引判重 —— 命中已有卡片就把
141
- 新正文**追加**进去(不覆盖、不丢弃),没命中就新建。缺必填小节 / 字段的卡片**照常入库**,
142
- 问题写进 `metadata.schema_issues`,面板显示成「待补」。**没有任何确认门**:卡片一写盘就进
143
- wikiNotes、向量与图谱,立刻可召回。
178
+ - **知识处理分开运行**:抽取只保存检查点,归一写入事实,物化按坐标产出卡片。只有构建检索索引后,新卡片才进入正式召回。任务失败保留已完成项,可查看输出和报告后重新运行。
144
179
  - **正文只读,备注可加**:卡片正文由编译产出,人改不了(手工写正文返回
145
180
  `WIKI_CARD_IMMUTABLE`)。人的判断落在 front matter 的 `annotations` 上
146
181
  (`kind: 'anomaly'` 表示异常点),**编译不会覆盖它**。review(`review_wiki_card`)在入库
@@ -149,16 +184,11 @@ SourceRaw → Knowledge → Wiki Card → Wiki Note → FTS / Vector / Rerank
149
184
  不动 `active` / `deprecated` / `problem` —— 那些是人另外做过的决定)。
150
185
  标注异常点会把有效评分压到 `ANOMALY_SCORE`,但卡片**照样召回得到**,只是排在后面。
151
186
 
152
- **合并按小节折进去**:同一实体被第二份文档命中时,新正文并进相同标签的小节里,
153
- 每个小节只出现一次;原来还是占位(「(文档未说明)」)的小节被真内容替换。
154
- 两份正文里只要有一份没有 `##` 结构(规则路径切出来的原文),退回整段拼接。
155
- - **批量导入只编译一次**(0045):`import_sources` 收一组来源(一次最多 50 份),逐份写入、
156
- **整批只编译一次**,逐条汇报成败 —— 第 7 份坏了不会让前 6 份白写。十份文档不再是十次审批、
157
- 十次往返、十次抽取。它与 `POST /knowledge/import` 落到同一个运行时方法 `runtime.importSources`,
158
- 与单份的 `add_source` 只差「一次多少份」。
187
+ - **物化整组重算**:同一坐标的有效 Knowledge 一起组织,沿用卡片 ID、review 和备注;Event 只更新关联引用。只重试物化时不会再次抽取文档。
188
+ - **批量导入只入库**:逐份保存、逐条报告导入失败;显式 `compile: true` 才运行本批来源的全链路。
159
189
  - **对话流里有专用卡片**(0045):`import_sources` / `recall_knowledge` / `rebuild_knowledge` /
160
190
  `add_source` / `propose_wiki_cards` 各自带 `presentationMeta`,浏览器半按**工具名**注册
161
- `tool.call.toolview`,于是对话里显示的是「导入 3 份来源并编译 · 写入 3 份 · 新建 2 张卡」
191
+ `tool.call.toolview`,显式编译或回放旧记录时,对话里可显示「导入 3 份来源并编译 · 写入 3 份 · 新建 2 张卡」
162
192
  与可展开的命中列表(名次、分数、`entityType:entityId`、review 评分),而不是一坨 JSON。
163
193
  meta 随会话日志落盘,所以**回放与当时看到的一致**。
164
194
  - **来源里的图跟着文字进卡片**(0047):抽取那一段交给模型的是文字,模型不会把图带回来,
@@ -169,17 +199,18 @@ SourceRaw → Knowledge → Wiki Card → Wiki Note → FTS / Vector / Rerank
169
199
  进 `warnings`。收尾的署名图 / 二维码(图后没有正文且锚点很短)故意不挂。每张 wikiNote
170
200
  只带**自己那一节**的图,因为多模态编码只吃每条的**第一张**图。图不参与抽取指纹,所以
171
201
  0047 之前编好的库重编时,来源虽然被指纹跳过,图仍然会被补上。
172
- - **图片引用有三种写法,解析只认「真实存在的那个」**(0047):`01_source_raw/_assets/…`
173
- (规范形,知识库根相对)、`_assets/…`(转换内核早期写进 SourceRaw 的形式)、
202
+ - **旧图片引用兼容三种写法,解析只认「真实存在的那个」**(0047 历史):`01_source_raw/_assets/…`
203
+ (当时的知识库根相对规范形)、`_assets/…`(转换内核早期写进 SourceRaw 的形式)、
174
204
  `../../01_source_raw/_assets/…`(`cardHints` 给手工建卡的形式)。文档的资产清单与卡片的
175
205
  `imagePaths` 走同一个 `assetRefCandidates`(根目录 → `01_source_raw/` → 文件自己的目录),
176
206
  否则同一张图在文档里找得到、在卡片里找不到。派生字段(图片路径、溯源链)变了也算
177
- 「语料变了」,否则增量编译的空操作会把刷新结果丢掉。
207
+ 「语料变了」,否则增量编译的空操作会把刷新结果丢掉。当前新资产写入 `assets/`,
208
+ 上述旧路径不定义新的知识库目录结构。
178
209
  - **SourceRaw 的 front matter 是 OKF v0.2 形状**(0048):`title`、`description`、
179
210
  `resource`(底层资产地址)、`tags`、
180
211
  `generated: {by, at}`(`by` = 谁解析的,`at` = **采集时间** —— OKF 里没有「抓取时间」
181
212
  这个概念)、`sources: [{id, resource, title, author, last_modified}]`(对网页就是那个页面
182
- 本身:地址、标题、作者、发布时间)。`source_id` / `external_id` / `created_at` /
213
+ 本身:地址、标题、作者、发布时间)。`created_at` /
183
214
  `updated_at` / `metadata` / `lineage` 是我们的扩展键(OKF 明确允许,且要求消费者容忍
184
215
  未知键)。
185
216
  规范:<https://github.com/GoogleCloudPlatform/open-knowledge-format>(v0.2)。
@@ -228,30 +259,33 @@ SourceRaw → Knowledge → Wiki Card → Wiki Note → FTS / Vector / Rerank
228
259
 
229
260
  ## 本地启用 WeMM
230
261
 
231
- 在 Apple Silicon 上执行一次(在插件包目录内):
262
+ 推荐使用「环境准备」面板选择 WeMM 量化版或腾讯 BF16 版。面板会安装所选模型并自动
263
+ 设置匹配的维度。也可在 Apple Silicon 上执行旧版辅助脚本(在插件包目录内):
232
264
 
233
265
  ```bash
234
266
  bash scripts/setup-embedding.sh
235
267
  ```
236
268
 
237
- 脚本会把 Python 环境放到 `~/.dsh/tita-agent/resource/python`,把量化模型放到
269
+ 脚本会用 `DSH_PYTHON`(未设置时为系统 `python3`)建立隔离依赖环境,把模型放到
238
270
  `~/.dsh/tita-agent/resource/models/WeMM-Embedding-2B-Quantized`。新配置会自动发现这两个路径;
239
- 设置位于 Tita Data Agent → Agent 概览 →「构建」节点:
271
+ 当前脚本安装的是 `ewin-reg` 社区维护的 INT4 / FP8 量化版,不是腾讯官方发行,模型卡将许可标为 `other`。
272
+ 它的输出维度为 2048。设置位于 Tita Data Agent → Agent 概览 →「构建」节点:
240
273
 
241
274
  - Provider:`WeMM Python(本地)`
242
275
  - Python:`~/.dsh/tita-agent/resource/python/bin/python`
243
276
  - Model:`~/.dsh/tita-agent/resource/models/WeMM-Embedding-2B-Quantized`
244
- - 维度:`1024`
277
+ - 维度:`2048`
245
278
  - 设备:`自动(优先 MPS)`
246
279
 
247
- 知识库默认保存在 `~/.dsh/tita-agent/domain_knowledge/<库 id>`。点击「编译」后,
248
- 编译结果写入 `derived.db`。未修改的 wikiNote
280
+ 知识库默认保存在 `~/.dsh/tita-agent/domain_knowledge/<库 id>`。运行「构建检索索引」后,
281
+ 检索产物写入 `derived.db`。未修改的 wikiNote
249
282
  会复用已有向量,只有新增或变更的 note 重新编码;编码与重排各自使用常驻 Python
250
- worker(同一份 `src/python/embedding_worker.py`),避免每个请求重复加载模型。
283
+ worker(同一份 `src/python/embedding_worker.py`),避免每个请求重复加载模型。换向量模型后重建索引,不重抽文档。
251
284
 
252
285
  BERT 重排默认使用 `BAAI/bge-reranker-base`;如需完全离线,可把模型放到
253
286
  `~/.dsh/tita-agent/resource/models/bge-reranker-base`(会被自动发现),或设置
254
- `DSH_RERANK_MODEL` / 在设置里填写本地路径。未安装时召回会降级到融合分数并给出警告。
287
+ `DSH_RERANK_MODEL` / 在设置里填写本地路径。启用重排的召回按该能力的自检结果放行;
288
+ 未就绪时先准备环境,显式停用重排则使用融合分数。
255
289
  **目录必须含分词器**(`tokenizer.json` 或 `sentencepiece.bpe.model`)——只有权重时模型会
256
290
  加载成功但给所有输入同一个分(`RERANK_TOKENIZER_DEGENERATE`)。
257
291
 
@@ -308,14 +342,14 @@ HTTP `GET /knowledge/bases` 在返回前先刷新。
308
342
  | 段 | 装什么 | 删掉的后果 |
309
343
  | --- | --- | --- |
310
344
  | `domain_knowledge/` | 知识树,按知识库 id 分叉 | 丢数据 |
311
- | `memory/<知识库 id>/` | 抽取轨迹、轴 / Knowledge 真源、处理日志、反馈与访问审计(append-only) | 丢历史,不可重建 |
345
+ | `memory/<知识库 id>/` | 任务与正式输出、抽取轨迹、处理日志、反馈与访问审计 | 丢历史,不可重建 |
312
346
  | `intent/` | `intent.db`(当前记录 + 审计历史) | 丢审计流 |
313
347
  | `output/` | 交付物,二级按日期分桶 | 什么都不损失 |
314
348
  | `tmp/` | 运行期临时文件,二级按日期分桶 | 只影响未完成的任务 |
315
349
  | `resource/` | 模型、Python 环境、`knowledge-bases.json` | 失去语义检索(嵌入/重排不可用) |
316
350
 
317
- **记忆与意图为什么与知识树平级**:记忆装的是**关于这个 Agent 的动作留痕**(抽取轨迹、
318
- 轴与 Knowledge 真源、处理日志、审计流水),不是关于知识的断言;留在知识树里会让「备份知识树」
351
+ **记忆与意图为什么与知识树平级**:记忆装的是**关于这个 Agent 的动作留痕**(任务、正式输出、
352
+ 抽取轨迹、处理日志、审计流水),知识断言及其阶段检查点保存在 `knowledge.db`。把动作留痕放进知识树,会让「备份知识树」
319
353
  被迫连审计一起备份,也让「知识树有哪几段」这个问题混进一个横切层。意图则是**会话级**的
320
354
  (同一句话在哪个知识库下说,理解方式不该变),所以它不分库。这样知识、记忆、意图三段
321
355
  都是可以直接备份、直接 diff 的用户文件。
@@ -324,10 +358,15 @@ HTTP `GET /knowledge/bases` 在返回前先刷新。
324
358
 
325
359
  | 文件或目录 | 内容 | 删除影响 |
326
360
  | --- | --- | --- |
327
- | `knowledge.db` | SourceRaw、Knowledge、Wiki Card 与版本记录 | 丢失知识真源 |
361
+ | `knowledge.db` | SourceRaw、轴、Knowledge、Event、Wiki Card、版本记录与阶段检查点 | 丢失知识真源 |
328
362
  | `derived.db` | wikiNotes、知识图谱、检索索引 | 可重新编译 |
329
363
  | `assets/` | 来源图片与附件 | 丢失对应素材 |
330
364
 
365
+ 知识库提供 `images.publish` 工具作为本地图床。它接收宿主本地 `file_path` 或 Base64 图片,按
366
+ `assets/<SHA-256 前 12 位>/<文件名>` 写入当前知识库,并返回 `/knowledge/assets/<kb>/<路径>` 地址
367
+ 和 Markdown 图片引用。独立图床图片不要求来源或卡片引用,也不会被孤儿清理误删。工具会校验图片格式和 MIME,
368
+ 单张图片上限为 20 MiB;写入不需要用户审批。
369
+
331
370
  `resource/` 保存模型、Python 环境与 `knowledge-bases.json`。
332
371
  如果资源目录没有本地 Python 或模型,就使用 `python3` 或 Hugging Face 模型名。
333
372
 
@@ -382,8 +421,9 @@ POST /knowledge/card-review { kb, entity_id, action } → { entityI
382
421
  POST /diagnosis/run { kb, record } → { sourceId, entityId }
383
422
  ```
384
423
 
385
- **0044:入库之后才 review,不再是「确认之后才入库」。** 编译(Pass 0)与
386
- `propose_wiki_cards` 都**直接写 `02_wiki`**,卡片立刻进编译、进图、能被召回。
424
+ **0044:入库之后才 review,不再是「确认之后才入库」(历史演进)。** 当时编译(Pass 0)与
425
+ `propose_wiki_cards` 直接写 `02_wiki`,随后进入编译与召回。当前卡片保存在 `knowledge.db`,
426
+ 新物化的卡片在构建检索索引后进入正式召回;review 仍作用于已经入库的卡片。
387
427
  人在面板上做的是 `POST /knowledge/card-review`(review 抬分 / 撤销)与
388
428
  `POST /knowledge/card-annotate`(加备注 / 标异常点)—— 两个动作都可逆,
389
429
  而且都作用在**已经存在于库里的卡片**上。原来的提议队列
package/cordis.patch.yml CHANGED
@@ -78,10 +78,9 @@
78
78
  - **The knowledge store.** Each knowledge base is one directory holding three
79
79
  things. `knowledge.db` is the knowledge itself: SourceRaw (the original
80
80
  business documents, never rewritten, kept so a conclusion can point back at
81
- where it came from), the cards people read — one per entity, each with
82
- mandatory `source_refs`, each following a type (`concept`, `metric`, `table`,
83
- `event`, `playbook`, `case`) — and every version of both, plus who changed
84
- what and when. `derived.db` is what `recall_knowledge` actually searches:
81
+ where it came from), Knowledge facts, independent Event records, and WikiCards
82
+ that organize Knowledge and point to related Events — plus every card version
83
+ and who changed what and when. `derived.db` is what `recall_knowledge` searches:
85
84
  wikiNotes, a vector index, a knowledge graph and a keyword index; it is
86
85
  recomputed, never backed up. `assets/` holds images. There are no
87
86
  per-segment folders inside a base; use the knowledge tools, not the
@@ -113,28 +112,33 @@
113
112
  record, then continue.
114
113
  2. **Recall before you answer about this organisation.** For its own rules,
115
114
  definitions, metrics, processes or history, call `recall_knowledge` first and
116
- answer from what comes back. An empty result is a finding, not a licence to
115
+ answer from what comes back. If a relevant card has `metadata.event_refs`, read
116
+ those IDs with `get_knowledge_events` before answering about incident history.
117
+ An empty result is a finding, not a licence to
117
118
  improvise — say the store has nothing on it. The wiki layer answers "what does
118
119
  this organisation mean by X"; when you need "where exactly does it say that",
119
120
  or a card and the document behind it disagree, go read the source.
120
121
  3. **Never invent a number.** Every figure you report must come from a tool
121
122
  result in this turn, and you must say which one. "I don't have that data" is
122
123
  a correct answer; a made-up number is not.
123
- 4. **Compiling is the normal path, and it writes cards by itself.** You do not
124
- have to create wiki cards: when a source is added or changed, `rebuild_knowledge`
125
- extracts entities from it, follows each wiki type's schema (required sections and
126
- fields), checks whether the wiki already has that entity, and either appends to
127
- the existing card or creates a new one. A card with missing sections is still
128
- written — the store keeps what it knows and fills the rest in when a later
129
- document covers it. So after adding a source, rebuild; then `recall_knowledge`
130
- and answer from what comes back. **More than one document at a time: use
131
- `import_sources`** — it writes the whole batch and compiles once, in one call.
132
- Ten documents through `add_source` means ten approvals and ten compiles, and the
133
- first nine results are thrown away by the tenth.
124
+ 4. **Import and knowledge processing are separate stages.** Use `import_sources`
125
+ for a batch. By default it only stores sources; adding or changing a source
126
+ never means the user asked to extract or publish it. Report the saved sources
127
+ and pending stages. When processing is requested, use `run_knowledge_pipeline`
128
+ with `extract`, then `normalize`, then `materialize`, then `build` as needed.
129
+ Track its durable task with `get_knowledge_pipeline`; use the output cursor
130
+ to inspect model text and failures. `source_ids` limits extraction to selected
131
+ documents. Materialization selects complete coordinate groups, combines all
132
+ their current Knowledge and Events, and retains the existing card identity.
133
+ An explicit full-chain request can use stage `all` or `compile: true` during
134
+ import. Unchanged results are reused; never force extraction just to build
135
+ indexes or retry materialization. `rebuild_knowledge` rebuilds saved cards'
136
+ retrieval artifacts without extracting documents. After successful index
137
+ publication, call `recall_knowledge` and answer from returned evidence.
134
138
  5. **You can add to the wiki, but you cannot rewrite it.** Call `propose_wiki_cards`
135
139
  with the `source_id` you just wrote and cards whose `source_refs` already exist in
136
140
  the store when you already have structured cards in hand — it writes them
137
- straight into `02_wiki`, they are recalled from the next compile on. A card whose
141
+ into the card store in `knowledge.db`; they are recalled after index publication. A card whose
138
142
  refs point nowhere is rejected, and rightly so. **A card body is read-only**: it
139
143
  belongs to the compiler. When something in the store is wrong, or a card and its
140
144
  source disagree, do not rewrite it — attach an annotation with
@@ -0,0 +1,20 @@
1
+ import { encode as tokens } from 'gpt-tokenizer'
2
+ import { encodeExtractionTable, decodeExtractionTable } from '../lib/types/extract-table.js'
3
+
4
+ // Compare the same semantic payload with the same o200k_base tokenizer.
5
+ // This measures transport size, not model extraction accuracy or the provider's billing.
6
+ function payload(count) {
7
+ const quote = '经营报表核对前,需要先统一订单状态、统计周期和退款口径。'
8
+ const sources = [{ quote, heading_path: ['经营报表', '口径核验'] }]
9
+ return { subject: '经营报表', knowledge: Array.from({ length: count }, (_, index) => ({ id: `k${index+1}`, text: `第 ${index+1} 项核验:统一统计周期,并检查订单状态与退款口径。`, object: '经营报表', action: '核对', scene: '周报', section: '核验步骤', order: index+1, sources })), events: [], objects: [{ mention: '经营报表', definition: '经营指标报表', evidence: quote }], actions: [{ mention: '核对', definition: '核验报表口径', evidence: quote }], scenes: [{ mention: '周报', definition: '每周报表场景', evidence: quote }], dropped: [] }
10
+ }
11
+ const results = [1, 12, 40].map(count => {
12
+ const value = payload(count)
13
+ const table = encodeExtractionTable(value)
14
+ decodeExtractionTable(table)
15
+ const json = tokens(JSON.stringify(value)).length
16
+ const toon = tokens(table).length
17
+ return { knowledge: count, jsonTokens: json, tableTokens: toon, outputReduction: `${((1-toon/json)*100).toFixed(1)}%` }
18
+ })
19
+ console.table(results)
20
+ console.log('固定表头对小样本有额外开销;真实节省取决于行数、字段长度、引文重复率和所选模型的 tokenizer。')