dsh-data-domain-knowledge 0.1.0-alpha.1 → 0.1.0-alpha.11
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.
- package/README.md +340 -182
- package/cordis.patch.yml +61 -39
- package/eval/README.md +2 -2
- package/eval/datasets/diagnosis-cases/cases.md +899 -0
- package/eval/evaluate-retrieval.mjs +1 -1
- package/lib/client.js +10857 -5251
- package/lib/doc-page.js +7767 -0
- package/lib/pages.js +22693 -0
- package/lib/types/axis-contract.d.ts +9 -0
- package/lib/types/axis-contract.d.ts.map +1 -0
- package/lib/types/axis-contract.js +35 -0
- package/lib/types/axis-contract.js.map +1 -0
- package/lib/types/axis-registry.d.ts +324 -0
- package/lib/types/axis-registry.d.ts.map +1 -0
- package/lib/types/axis-registry.js +858 -0
- package/lib/types/axis-registry.js.map +1 -0
- package/lib/types/card-organize.d.ts +312 -0
- package/lib/types/card-organize.d.ts.map +1 -0
- package/lib/types/card-organize.js +610 -0
- package/lib/types/card-organize.js.map +1 -0
- package/lib/types/config-schema.d.ts +6 -8
- package/lib/types/config-schema.d.ts.map +1 -1
- package/lib/types/config-schema.js +5 -7
- package/lib/types/config-schema.js.map +1 -1
- package/lib/types/convert/host.d.ts +6 -5
- package/lib/types/convert/host.d.ts.map +1 -1
- package/lib/types/convert/host.js +97 -45
- package/lib/types/convert/host.js.map +1 -1
- package/lib/types/convert/ingest.d.ts +20 -22
- package/lib/types/convert/ingest.d.ts.map +1 -1
- package/lib/types/convert/ingest.js +162 -50
- package/lib/types/convert/ingest.js.map +1 -1
- package/lib/types/convert/settings-schema.d.ts +2 -2
- package/lib/types/convert/settings-schema.d.ts.map +1 -1
- package/lib/types/convert/settings-schema.js +2 -2
- package/lib/types/convert/settings-schema.js.map +1 -1
- package/lib/types/convert/types.d.ts +2 -2
- package/lib/types/convert/types.d.ts.map +1 -1
- package/lib/types/convert/types.js +2 -2
- package/lib/types/convert/types.js.map +1 -1
- package/lib/types/diagnosis/cards.d.ts +34 -15
- package/lib/types/diagnosis/cards.d.ts.map +1 -1
- package/lib/types/diagnosis/cards.js +148 -59
- package/lib/types/diagnosis/cards.js.map +1 -1
- package/lib/types/diagnosis/run.d.ts +57 -0
- package/lib/types/diagnosis/run.d.ts.map +1 -0
- package/lib/types/diagnosis/run.js +245 -0
- package/lib/types/diagnosis/run.js.map +1 -0
- package/lib/types/diagnosis/schema.d.ts +26 -3
- package/lib/types/diagnosis/schema.d.ts.map +1 -1
- package/lib/types/diagnosis/schema.js +64 -25
- package/lib/types/diagnosis/schema.js.map +1 -1
- package/lib/types/diagnosis/seed-source.d.ts +8 -2
- package/lib/types/diagnosis/seed-source.d.ts.map +1 -1
- package/lib/types/diagnosis/seed-source.js +20 -5
- package/lib/types/diagnosis/seed-source.js.map +1 -1
- package/lib/types/diagnosis/seed.d.ts +32 -42
- package/lib/types/diagnosis/seed.d.ts.map +1 -1
- package/lib/types/diagnosis/seed.js +187 -51
- package/lib/types/diagnosis/seed.js.map +1 -1
- package/lib/types/diagnosis/store.d.ts +107 -27
- package/lib/types/diagnosis/store.d.ts.map +1 -1
- package/lib/types/diagnosis/store.js +339 -173
- package/lib/types/diagnosis/store.js.map +1 -1
- package/lib/types/diagnosis/types.d.ts +206 -16
- package/lib/types/diagnosis/types.d.ts.map +1 -1
- package/lib/types/diagnosis/types.js +1 -1
- package/lib/types/diagnosis/types.js.map +1 -1
- package/lib/types/document-page.d.ts +39 -0
- package/lib/types/document-page.d.ts.map +1 -0
- package/lib/types/document-page.js +43 -0
- package/lib/types/document-page.js.map +1 -0
- package/lib/types/events.d.ts +60 -0
- package/lib/types/events.d.ts.map +1 -0
- package/lib/types/events.js +2 -0
- package/lib/types/events.js.map +1 -0
- package/lib/types/extract-contract.d.ts +21 -0
- package/lib/types/extract-contract.d.ts.map +1 -0
- package/lib/types/extract-contract.js +130 -0
- package/lib/types/extract-contract.js.map +1 -0
- package/lib/types/extract-model.d.ts +70 -27
- package/lib/types/extract-model.d.ts.map +1 -1
- package/lib/types/extract-model.js +229 -97
- package/lib/types/extract-model.js.map +1 -1
- package/lib/types/extract.d.ts +16 -0
- package/lib/types/extract.d.ts.map +1 -1
- package/lib/types/extract.js +20 -3
- package/lib/types/extract.js.map +1 -1
- package/lib/types/extraction-runs.d.ts +97 -0
- package/lib/types/extraction-runs.d.ts.map +1 -0
- package/lib/types/extraction-runs.js +169 -0
- package/lib/types/extraction-runs.js.map +1 -0
- package/lib/types/fs-atomic.d.ts +11 -0
- package/lib/types/fs-atomic.d.ts.map +1 -0
- package/lib/types/fs-atomic.js +40 -0
- package/lib/types/fs-atomic.js.map +1 -0
- package/lib/types/fts.d.ts +2 -3
- package/lib/types/fts.d.ts.map +1 -1
- package/lib/types/index.d.ts +6 -10
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1396 -320
- package/lib/types/index.js.map +1 -1
- package/lib/types/intent/engine.d.ts +22 -8
- package/lib/types/intent/engine.d.ts.map +1 -1
- package/lib/types/intent/engine.js +71 -84
- package/lib/types/intent/engine.js.map +1 -1
- package/lib/types/intent/host.d.ts +8 -25
- package/lib/types/intent/host.d.ts.map +1 -1
- package/lib/types/intent/host.js +74 -216
- package/lib/types/intent/host.js.map +1 -1
- package/lib/types/intent/preset-tools.d.ts +2 -2
- package/lib/types/intent/preset-tools.js +3 -3
- package/lib/types/intent/scope.d.ts +27 -0
- package/lib/types/intent/scope.d.ts.map +1 -0
- package/lib/types/intent/scope.js +114 -0
- package/lib/types/intent/scope.js.map +1 -0
- package/lib/types/intent/store.d.ts +16 -58
- package/lib/types/intent/store.d.ts.map +1 -1
- package/lib/types/intent/store.js +202 -102
- package/lib/types/intent/store.js.map +1 -1
- package/lib/types/intent/tools.d.ts +7 -12
- package/lib/types/intent/tools.d.ts.map +1 -1
- package/lib/types/intent/tools.js +25 -34
- package/lib/types/intent/tools.js.map +1 -1
- package/lib/types/intent/types.d.ts +18 -37
- package/lib/types/intent/types.d.ts.map +1 -1
- package/lib/types/intent/types.js +3 -9
- package/lib/types/intent/types.js.map +1 -1
- package/lib/types/knowledge-bases.d.ts +26 -121
- package/lib/types/knowledge-bases.d.ts.map +1 -1
- package/lib/types/knowledge-bases.js +60 -686
- package/lib/types/knowledge-bases.js.map +1 -1
- package/lib/types/knowledge.d.ts +550 -0
- package/lib/types/knowledge.d.ts.map +1 -0
- package/lib/types/knowledge.js +1213 -0
- package/lib/types/knowledge.js.map +1 -0
- package/lib/types/layout.d.ts +108 -34
- package/lib/types/layout.d.ts.map +1 -1
- package/lib/types/layout.js +116 -37
- package/lib/types/layout.js.map +1 -1
- package/lib/types/migrate.d.ts +12 -1
- package/lib/types/migrate.d.ts.map +1 -1
- package/lib/types/migrate.js +130 -6
- package/lib/types/migrate.js.map +1 -1
- package/lib/types/model-text.d.ts +101 -0
- package/lib/types/model-text.d.ts.map +1 -0
- package/lib/types/model-text.js +79 -0
- package/lib/types/model-text.js.map +1 -0
- package/lib/types/oplog.d.ts +98 -0
- package/lib/types/oplog.d.ts.map +1 -0
- package/lib/types/oplog.js +178 -0
- package/lib/types/oplog.js.map +1 -0
- package/lib/types/organize-contract.d.ts +18 -0
- package/lib/types/organize-contract.d.ts.map +1 -0
- package/lib/types/organize-contract.js +75 -0
- package/lib/types/organize-contract.js.map +1 -0
- package/lib/types/present.d.ts +236 -0
- package/lib/types/present.d.ts.map +1 -0
- package/lib/types/present.js +254 -0
- package/lib/types/present.js.map +1 -0
- package/lib/types/query-analysis.d.ts +49 -0
- package/lib/types/query-analysis.d.ts.map +1 -0
- package/lib/types/query-analysis.js +159 -0
- package/lib/types/query-analysis.js.map +1 -0
- package/lib/types/recall-rank.d.ts +41 -4
- package/lib/types/recall-rank.d.ts.map +1 -1
- package/lib/types/recall-rank.js +46 -6
- package/lib/types/recall-rank.js.map +1 -1
- package/lib/types/runtime.d.ts +1604 -123
- package/lib/types/runtime.d.ts.map +1 -1
- package/lib/types/runtime.js +7537 -1030
- package/lib/types/runtime.js.map +1 -1
- package/lib/types/settings-schema.d.ts +25 -29
- package/lib/types/settings-schema.d.ts.map +1 -1
- package/lib/types/settings-schema.js +51 -48
- package/lib/types/settings-schema.js.map +1 -1
- package/lib/types/settings-volatile.d.ts +3 -3
- package/lib/types/settings-volatile.js +3 -3
- package/lib/types/source-images.d.ts +151 -0
- package/lib/types/source-images.d.ts.map +1 -0
- package/lib/types/source-images.js +344 -0
- package/lib/types/source-images.js.map +1 -0
- package/lib/types/store/derived.d.ts +145 -0
- package/lib/types/store/derived.d.ts.map +1 -0
- package/lib/types/store/derived.js +295 -0
- package/lib/types/store/derived.js.map +1 -0
- package/lib/types/store/knowledge-db.d.ts +412 -0
- package/lib/types/store/knowledge-db.d.ts.map +1 -0
- package/lib/types/store/knowledge-db.js +1288 -0
- package/lib/types/store/knowledge-db.js.map +1 -0
- package/lib/types/store/migrate.d.ts +172 -0
- package/lib/types/store/migrate.d.ts.map +1 -0
- package/lib/types/store/migrate.js +498 -0
- package/lib/types/store/migrate.js.map +1 -0
- package/lib/types/store/views.d.ts +118 -0
- package/lib/types/store/views.d.ts.map +1 -0
- package/lib/types/store/views.js +237 -0
- package/lib/types/store/views.js.map +1 -0
- package/lib/types/types.d.ts +664 -231
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/types.js +55 -293
- package/lib/types/types.js.map +1 -1
- package/lib/types/wiki-finalize.d.ts +157 -0
- package/lib/types/wiki-finalize.d.ts.map +1 -0
- package/lib/types/wiki-finalize.js +295 -0
- package/lib/types/wiki-finalize.js.map +1 -0
- package/lib/types/wiki-materialize.d.ts +88 -0
- package/lib/types/wiki-materialize.d.ts.map +1 -0
- package/lib/types/wiki-materialize.js +197 -0
- package/lib/types/wiki-materialize.js.map +1 -0
- package/lib/types/wiki-trial-types.d.ts +378 -0
- package/lib/types/wiki-trial-types.d.ts.map +1 -0
- package/lib/types/wiki-trial-types.js +18 -0
- package/lib/types/wiki-trial-types.js.map +1 -0
- package/lib/types/wiki-trial.d.ts +276 -0
- package/lib/types/wiki-trial.d.ts.map +1 -0
- package/lib/types/wiki-trial.js +1319 -0
- package/lib/types/wiki-trial.js.map +1 -0
- package/lib/types/wiki-types.d.ts +23 -17
- package/lib/types/wiki-types.d.ts.map +1 -1
- package/lib/types/wiki-types.js +65 -92
- package/lib/types/wiki-types.js.map +1 -1
- package/package.json +36 -26
- package/preset/tita-data-agent/agent.cordis.yml +54 -31
- package/scripts/doctor.mjs +5 -9
- package/scripts/e2e-pipeline.mjs +0 -3
- package/scripts/setup-embedding.sh +4 -3
- package/src/axis-contract.ts +35 -0
- package/src/axis-registry.ts +1003 -0
- package/src/card-organize.ts +777 -0
- package/src/client/AgentPresetCard.tsx +11 -20
- package/src/client/AttributionEventGuide.tsx +176 -0
- package/src/client/AxisMatrix.tsx +389 -0
- package/src/client/AxisRegistrySection.tsx +434 -0
- package/src/client/CompileDialogs.tsx +272 -0
- package/src/client/DeleteDocumentDialog.tsx +229 -0
- package/src/client/DirectoryPicker.tsx +23 -89
- package/src/client/DrawerSection.tsx +18 -0
- package/src/client/ExpansionGraph.tsx +251 -0
- package/src/client/ExtractionTasksPage.tsx +189 -0
- package/src/client/GuideArchitectureCanvas.tsx +470 -0
- package/src/client/ImportFilesDialog.tsx +331 -0
- package/src/client/InfoHint.tsx +61 -13
- package/src/client/{IntentLogicTab.tsx → IntentLogic.tsx} +35 -28
- package/src/client/IntentTab.tsx +226 -600
- package/src/client/KnowledgeBaseTab.tsx +2130 -754
- package/src/client/KnowledgeLayerSection.tsx +629 -0
- package/src/client/KnowledgePanel.tsx +151 -58
- package/src/client/KnowledgeStepRail.tsx +20 -12
- package/src/client/KnowledgeToolRow.tsx +504 -0
- package/src/client/ListPager.tsx +81 -0
- package/src/client/NodeSettings.tsx +132 -111
- package/src/client/OperationLogTab.tsx +295 -0
- package/src/client/PreviewSections.tsx +617 -46
- package/src/client/RecallPanel.tsx +687 -151
- package/src/client/RelatedGraph.tsx +221 -0
- package/src/client/TabGuide.tsx +414 -0
- package/src/client/TrialReportView.tsx +581 -0
- package/src/client/TypeDefinitionDrawer.tsx +141 -185
- package/src/client/WikiCardPreview.tsx +290 -0
- package/src/client/WikiCardReview.tsx +255 -0
- package/src/client/WikiCardRow.tsx +121 -0
- package/src/client/WikiFlowPanel.tsx +577 -0
- package/src/client/WikiTrialRun.tsx +216 -0
- package/src/client/agent-preset.ts +3 -3
- package/src/client/arch/AgentArchitectureGraph.tsx +32 -16
- package/src/client/arch/NodeLogicPanel.tsx +8 -5
- package/src/client/arch/ProblemDetailPanel.tsx +2 -2
- package/src/client/arch/model.ts +312 -43
- package/src/client/architecture.css +25 -10
- package/src/client/architecture.tsx +138 -109
- package/src/client/asset-images.ts +152 -0
- package/src/client/attribution/AttributionGraph.tsx +486 -35
- package/src/client/attribution/AttributionTab.tsx +585 -109
- package/src/client/attribution/CaseView.tsx +11 -16
- package/src/client/attribution/EventView.tsx +98 -0
- package/src/client/attribution/GraphStage.tsx +26 -19
- package/src/client/attribution/RunView.tsx +29 -11
- package/src/client/attribution/StageChrome.tsx +314 -143
- package/src/client/attribution/ViewSwitch.tsx +2 -2
- package/src/client/attribution/graph-options.ts +613 -48
- package/src/client/attribution/model.ts +560 -31
- package/src/client/axis-lookup.ts +74 -0
- package/src/client/config-scope.ts +2 -2
- package/src/client/convert/ConvertPanel.tsx +17 -28
- package/src/client/doc-page.css +134 -0
- package/src/client/doc-page.tsx +239 -0
- package/src/client/graph/edges.ts +42 -0
- package/src/client/graph/expansion.ts +71 -0
- package/src/client/graph/layout.ts +112 -99
- package/src/client/graph/related.ts +235 -0
- package/src/client/index.ts +71 -8
- package/src/client/ledger.tsx +436 -0
- package/src/client/pages.css +589 -0
- package/src/client/pages.tsx +261 -0
- package/src/client/panel-state.ts +105 -0
- package/src/client/preview-citations.ts +145 -0
- package/src/client/problem-domains.ts +4 -4
- package/src/client/request.ts +36 -0
- package/src/client/styles.css +2138 -184
- package/src/client/useFitScale.ts +19 -6
- package/src/client/wiki-trial.ts +423 -0
- package/src/config-schema.ts +6 -10
- package/src/convert/host.ts +100 -47
- package/src/convert/ingest.ts +184 -68
- package/src/convert/settings-schema.ts +2 -2
- package/src/convert/types.ts +2 -2
- package/src/diagnosis/cards.ts +162 -61
- package/src/diagnosis/run.ts +251 -0
- package/src/diagnosis/schema.ts +68 -27
- package/src/diagnosis/seed-source.ts +21 -7
- package/src/diagnosis/seed.ts +187 -85
- package/src/diagnosis/store.ts +355 -180
- package/src/diagnosis/types.ts +206 -16
- package/src/document-page.ts +51 -0
- package/src/events.ts +45 -0
- package/src/extract-contract.ts +134 -0
- package/src/extract-model.ts +265 -99
- package/src/extract.ts +36 -4
- package/src/extraction-runs.ts +216 -0
- package/src/fs-atomic.ts +40 -0
- package/src/fts.ts +2 -2
- package/src/index.ts +1383 -309
- package/src/intent/README.md +28 -50
- package/src/intent/engine.ts +70 -82
- package/src/intent/host.ts +77 -223
- package/src/intent/preset-tools.ts +3 -3
- package/src/intent/scope.ts +124 -0
- package/src/intent/store.ts +180 -105
- package/src/intent/tools.ts +26 -42
- package/src/intent/types.ts +19 -35
- package/src/knowledge-bases.ts +81 -688
- package/src/knowledge.ts +1524 -0
- package/src/layout.ts +119 -38
- package/src/migrate.ts +120 -6
- package/src/model-text.ts +133 -0
- package/src/oplog.ts +214 -0
- package/src/organize-contract.ts +76 -0
- package/src/present.ts +366 -0
- package/src/python/embedding_worker.py +17 -2
- package/src/query-analysis.ts +195 -0
- package/src/recall-rank.ts +63 -8
- package/src/runtime.ts +8032 -1119
- package/src/settings-schema.ts +17 -14
- package/src/settings-volatile.ts +3 -3
- package/src/source-images.ts +381 -0
- package/src/store/derived.ts +316 -0
- package/src/store/knowledge-db.ts +1469 -0
- package/src/store/migrate.ts +590 -0
- package/src/store/views.ts +313 -0
- package/src/types.ts +685 -478
- package/src/wiki-finalize.ts +339 -0
- package/src/wiki-materialize.ts +243 -0
- package/src/wiki-trial-types.ts +368 -0
- package/src/wiki-trial.ts +1464 -0
- package/src/wiki-types.ts +67 -102
- package/lib/types/intent/settings-schema.d.ts +0 -59
- package/lib/types/intent/settings-schema.d.ts.map +0 -1
- package/lib/types/intent/settings-schema.js +0 -57
- package/lib/types/intent/settings-schema.js.map +0 -1
- package/src/client/KnowledgeGraphView.tsx +0 -306
- package/src/client/WikiFlowCard.tsx +0 -226
- package/src/client/WikiTypeEditor.tsx +0 -332
- package/src/client/graph.css +0 -113
- package/src/intent/settings-schema.ts +0 -63
package/README.md
CHANGED
|
@@ -1,107 +1,216 @@
|
|
|
1
1
|
# dsh-data-domain-knowledge
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
本地知识库插件:一个知识库是一个目录,里面四样东西。`knowledge.db` 保存 **SourceRaw**
|
|
4
|
+
(原始可追溯文档)、按主题聚合可双向链接的 wiki 卡片,以及**两者的每一个版本**;
|
|
5
|
+
`derived.db` 输出可检索的 **wikiNotes**、wiki
|
|
5
6
|
知识图谱和向量索引,`<agentRoot>/memory/<库 id>` 保存版本快照、访问审计与反馈。默认使用本地 WeMM Python backend:从 WeMM
|
|
6
7
|
原生 2048 维向量按 MRL 截取 1024 维,先做 binary/Hamming 粗筛,再用 int8 点积精算余弦
|
|
7
8
|
(这是**向量路内部的粗排 → 精算**,与 stage 4 的 cross-encoder **重排**不是一回事);
|
|
8
9
|
模型不可用时明确降级到 FTS,不会伪造向量结果。Markdown 中的
|
|
9
10
|
本地图片会与正文一起交给 WeMM,因此图片不是独立知识类型。
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Tita Agent 的固定数据根目录是 `$DSH_HOME/tita-agent`(默认 `~/.dsh/tita-agent`)。
|
|
13
|
+
设置面板只展示这个目录并提供「打开目录」,不允许切换根路径;知识库、意图记录、记忆、
|
|
14
|
+
模型和 Python 环境都从这里派生。
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
## 承载范围(五个视图)
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
| --- | --- | --- | --- |
|
|
17
|
-
| `overview` | Agent 概览 | `src/index.ts` | 各设置的挂载节点 |
|
|
18
|
-
| `intent` | 意图 | `src/intent/`(0020 自 `data-domain-intent` 并入);配置与留痕落 `<agentRoot>/intent/` | `intent_*` 工具名、`/intent/*` 路由、`tita-data-agent-intent` 设置、`titaDataAgentIntent` 服务 |
|
|
19
|
-
| `knowledge` | 知识库 | `src/runtime.ts` + `src/knowledge-bases.ts` + `src/convert/`(0018 并入) | `recall_knowledge` 等工具名、`/knowledge/*` 与 `/convert` 路由、`tita-data-agent-knowledge` / `-convert` 设置 |
|
|
20
|
-
| `memory` | 记忆 | `src/runtime.ts` 的 `memoryPath()`(版本快照、`feedback.ndjson`、`access-audit.ndjson`),根在 `<agentRoot>/memory/<库 id>` | 磁盘目录布局 |
|
|
21
|
-
| `eval` | 评测 | `eval/evaluate-retrieval.mjs`(开发期能力,不注册运行时入口) | 问题集格式 |
|
|
22
|
-
|
|
23
|
-
**架构原理:插件的数量应当等于用户入口的数量,而不是概念的数量;而插件的名字应当指向主干概念,不指向子域。**
|
|
24
|
-
意图/知识库/记忆/评测是四个概念,但它们共享同一条流水线(记录意图 → 录入来源 → 编译知识 →
|
|
25
|
-
沉淀记忆 → 评测质量)和同一个入口(面板的五个 Tab)。0020 之前,「意图」Tab 已经长在本插件里、
|
|
26
|
-
宿主实现却在第二个挂载单元里——**声明的信息架构与代码布局不一致**,这才是要修的东西。
|
|
27
|
-
|
|
28
|
-
意图的**配置与留痕**落在 `<agentRoot>/intent/`(0033):`registry.json` 是分类 / act 词表的
|
|
29
|
-
真源(面板的「意图配置」直接读写这个文件,不再写宿主的 settings 文档),`records.ndjson`
|
|
30
|
-
是每轮一条记录的 append-only 留痕(按 `sessionKey#turn` 读时取最后一条,所以内存里
|
|
31
|
-
「一轮一条」的语义不变)。读接口 `/intent/store` 与 `/intent/overview` 读的是**留痕**:
|
|
32
|
-
引擎内存里那份有 600 秒 TTL,重启或隔一段时间回来不该让面板上的历史凭空消失。
|
|
18
|
+
侧边栏 `TitaAgent` 面板的五个视图就是本插件的全部范围:
|
|
33
19
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
| 视图 | 面板标签 | 冻结契约 |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| `overview` | Agent 概览 | 各设置的挂载节点 |
|
|
23
|
+
| `intent` | 意图 | `intent_record` / `intent_store_view`、`/intent/*` 路由、`titaDataAgentIntent` 服务;会话审计留痕落 `<agentRoot>/intent/` |
|
|
24
|
+
| `knowledge` | 知识库 | `recall_knowledge` 等工具名、`/knowledge/*` 与 `/convert` 路由、`tita-data-agent-knowledge` / `-convert` 设置 |
|
|
25
|
+
| `memory` | 记忆 | 抽取轨迹、轴 / Knowledge 真源、处理日志、`feedback.ndjson`、`access-audit.ndjson`,根在 `<agentRoot>/memory/<库 id>`;磁盘目录布局 |
|
|
26
|
+
| `eval` | 评测 | 问题集格式(开发期能力,不注册运行时入口) |
|
|
27
|
+
|
|
28
|
+
意图的**会话审计留痕**落在 `<agentRoot>/intent/`:`intent.db` 保存当前记录与追加历史
|
|
29
|
+
(按 `sessionKey#turn` 读取时取当前版本,所以内存里「一轮一条」的语义不变)。
|
|
30
|
+
分类与 act 是代码内置的固定契约,不提供编辑入口。读接口 `/intent/store` 与 `/intent/overview` 读的是**留痕**:
|
|
31
|
+
引擎内存里那份有 600 秒 TTL,重启或隔一段时间回来不该让面板上的历史凭空消失。
|
|
37
32
|
|
|
38
33
|
## 五段链路
|
|
39
34
|
|
|
40
35
|
| 段 | 名称 | 产物 | 关键配置 |
|
|
41
36
|
| --- | --- | --- | --- |
|
|
42
|
-
| 1 | SourceRaw | 原始可追溯文档:`
|
|
43
|
-
| 2 | 编译 Compile | wiki:`
|
|
44
|
-
| 3 | 构建 Build | wikiNotes → 向量索引;wiki → `
|
|
45
|
-
| 4 | 召回 Recall |
|
|
37
|
+
| 1 | SourceRaw | 原始可追溯文档:`knowledge.db` 的 `source` + `blob` | `allowSourceTruth` / `rootDir` |
|
|
38
|
+
| 2 | 编译 Compile | wiki:`knowledge.db` 的 `card`(**按 wiki 类型 schema 抽实体,直接入库**);wikiNotes:`derived.db` 的 `wiki_notes.json` | `extractCandidates` / `extractWithModel` / `wikiTypes` |
|
|
39
|
+
| 3 | 构建 Build | wikiNotes → 向量索引;wiki → `derived.db` 的 `knowledge_graph.json` | `embeddingProvider` / `embeddingModel` / `python` |
|
|
40
|
+
| 4 | 召回 Recall | 多路(坐标 + 关键词 + 向量)召回 wikiNotes,取 `recallTopK`(默认 10),再解析父级 wiki 与该 wiki 的 1 跳知识图谱 | `recallTopK` |
|
|
46
41
|
| 5 | 重排 Rerank | BERT cross-encoder 对候选 wikiNotes 精排,取 `contextTopN`(默认 5)组成 `context` | `contextTopN` / `rerankProvider` / `rerankModel` |
|
|
47
42
|
|
|
48
|
-
>
|
|
49
|
-
>
|
|
50
|
-
>
|
|
43
|
+
> 第 4、5 段在**界面上是同一栏**(知识库 → 召回重排)。它们在流水线上仍是两步,
|
|
44
|
+
> 但「跑一次真实召回长什么样」是一个问题,分两栏会让用户先跑召回、再切到重排才能
|
|
45
|
+
> 看到同一次运行的全貌。
|
|
46
|
+
|
|
47
|
+
## Knowledge / Wiki Card 的存储约束
|
|
48
|
+
|
|
49
|
+
这套存储的边界固定如下,不因检索策略变化而把所有内容塞进同一张表:
|
|
50
|
+
|
|
51
|
+
| 层 | 真源 | 说明 |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| Knowledge | `knowledge` + `knowledge_sources` | 原子事实、坐标、来源、状态;不保存 Card 的排版 |
|
|
54
|
+
| Wiki Card | `card` + `blob` + `revision` | 面向阅读和召回组装的正文;正文中的 Markdown 标题是 Section 真源 |
|
|
55
|
+
| Knowledge 落位 | `card_knowledge` | 记录 Knowledge 在某张 Card 中的 Section 和顺序;这是关联索引,不是 Knowledge 属性 |
|
|
56
|
+
| Wiki Note / FTS / Vector / Graph | 派生文件 | 可以从 Card 和 Knowledge 重新构建,不是真实知识来源 |
|
|
57
|
+
|
|
58
|
+
### 状态语义
|
|
59
|
+
|
|
60
|
+
Knowledge 的状态回答“这条事实现在能否被当作事实使用”,Card 的 status/review 回答“这张卡的内容是否被审核、是否适合展示”。两者不互相替代:
|
|
61
|
+
|
|
62
|
+
- `candidate`:已进入真源但还没有人工或规则确认;可以召回,但必须标注“待确认”。
|
|
63
|
+
- `active`:当前可作为正常事实使用。
|
|
64
|
+
- `disputed`:存在相反来源;两条知识都保留,召回时必须显式提示。
|
|
65
|
+
- `deprecated`:历史上成立或曾被采用,但当前不应作为首选事实;仍保留用于追溯。
|
|
66
|
+
|
|
67
|
+
### 身份与 Scope
|
|
68
|
+
|
|
69
|
+
Knowledge ID 只在一个 `knowledge.db` 内有意义。相同文本在同一个知识库内,即使来自不同来源或不同 Coordinate,也沿用同一个 ID;Coordinate 是归类和落位信息,不是当前的判重键。不同知识库是不同 Scope,不会因为 ID 算法相同而自动合并。
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
> `add_source` / `query_source_truth`、HTTP `/knowledge/sources`、设置键 `allowSourceTruth`
|
|
54
|
-
> 与错误码 `SOURCE_TRUTH_DISABLED` 作为兼容名保留,语义等同 SourceRaw。
|
|
55
|
-
> 本轮的「编译 / 构建」仍是同一次 `rebuild()`:编译的**按主题聚合**由 Agent 完成,
|
|
56
|
-
> **wiki↔wiki 双向链接**与**分阶段重建**是设计目标,图谱当前只有 `supported_by` 溯源边。
|
|
71
|
+
这意味着当前实现适用于“一个知识库对应一个业务范围”的模型。未来如果一个库需要混合多个租户、环境或有效期,再把 Scope 纳入判重策略。
|
|
57
72
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
### Knowledge 类型
|
|
74
|
+
|
|
75
|
+
当前不把 `Fact` / `Rule` / `Procedure` / `Constraint` 加成 Knowledge 的正式列。类型暂作为抽取或 Card metadata 的扩展信息,只有当不同类型需要不同的召回、验证或执行策略时,才升级为结构化字段。
|
|
76
|
+
|
|
77
|
+
## Knowledge、Wiki Card、Wiki Note 的生命周期
|
|
78
|
+
|
|
79
|
+
三者不是三个并列的知识真源,而是同一条知识链上的三个层次:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
SourceRaw → Knowledge → Wiki Card → Wiki Note → FTS / Vector / Rerank
|
|
83
|
+
事实真源 阅读组织视图 检索派生片段
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- Knowledge 是不可由 Card 反向重建的事实记录。抽取、来源追加、合并、冲突裁决和状态变化都发生在这里。
|
|
87
|
+
- Wiki Card 是 Knowledge 的组织视图。Card 正文、摘要、Section 和阅读顺序可以重新编排;重新编排不应修改 Knowledge。
|
|
88
|
+
- Wiki Note 是 Card 的检索切片。它没有独立的业务生命周期,`status` 只是父 Card 状态的快照;Card 变化后重新编译 Wiki Note,索引随之重建。
|
|
89
|
+
|
|
90
|
+
状态也按层分开:Knowledge 使用 `candidate / active / disputed / deprecated`,Card 使用 `unreviewed / draft / reviewed / active / deprecated / problem`。同名状态不表示同一件事:Knowledge 的 `active` 是事实可采用,Card 的 `active` 是页面可展示。
|
|
91
|
+
|
|
92
|
+
因此,删除来源、合并 Knowledge、修改 Card 或重建检索索引时,都必须沿着这条依赖方向处理,不能直接把 Wiki Note 当成可编辑知识,也不能用 Card review 代替 Knowledge 验证。
|
|
93
|
+
|
|
94
|
+
- 知识库设置集中在侧边抽屉:数据位置、向量模型、检索与上下文。召回固定使用多路径融合;
|
|
95
|
+
低频设备、阈值和模型细节收在高级设置中。Agent 系统提示词常显,并链接到 preset 真源目录。
|
|
96
|
+
- **编译直接入库(0044)**:`rebuild_knowledge` 的 Pass 0 对指纹变了的来源做实体抽取,
|
|
97
|
+
按 `entityType:entityId` / `title` / `metadata.aliases` 三重索引判重 —— 命中已有卡片就把
|
|
98
|
+
新正文**追加**进去(不覆盖、不丢弃),没命中就新建。缺必填小节 / 字段的卡片**照常入库**,
|
|
99
|
+
问题写进 `metadata.schema_issues`,面板显示成「待补」。**没有任何确认门**:卡片一写盘就进
|
|
100
|
+
wikiNotes、向量与图谱,立刻可召回。
|
|
101
|
+
- **正文只读,备注可加**:卡片正文由编译产出,人改不了(手工写正文返回
|
|
102
|
+
`WIKI_CARD_IMMUTABLE`)。人的判断落在 front matter 的 `annotations` 上
|
|
103
|
+
(`kind: 'anomaly'` 表示异常点),**编译不会覆盖它**。review(`review_wiki_card`)在入库
|
|
104
|
+
之后做,它把卡片评分抬到 `REVIEWED_SCORE_FLOOR`,让它在召回时排前面一点(倍率 0.85–1.2);
|
|
105
|
+
同时把生命周期从 `unreviewed` / `draft` 推进到 `reviewed`(撤销时只退回这一档,
|
|
106
|
+
不动 `active` / `deprecated` / `problem` —— 那些是人另外做过的决定)。
|
|
107
|
+
标注异常点会把有效评分压到 `ANOMALY_SCORE`,但卡片**照样召回得到**,只是排在后面。
|
|
108
|
+
|
|
109
|
+
**合并按小节折进去**:同一实体被第二份文档命中时,新正文并进相同标签的小节里,
|
|
110
|
+
每个小节只出现一次;原来还是占位(「(文档未说明)」)的小节被真内容替换。
|
|
111
|
+
两份正文里只要有一份没有 `##` 结构(规则路径切出来的原文),退回整段拼接。
|
|
112
|
+
- **批量导入只编译一次**(0045):`import_sources` 收一组来源(一次最多 50 份),逐份写入、
|
|
113
|
+
**整批只编译一次**,逐条汇报成败 —— 第 7 份坏了不会让前 6 份白写。十份文档不再是十次审批、
|
|
114
|
+
十次往返、十次抽取。它与 `POST /knowledge/import` 落到同一个运行时方法 `runtime.importSources`,
|
|
115
|
+
与单份的 `add_source` 只差「一次多少份」。
|
|
116
|
+
- **对话流里有专用卡片**(0045):`import_sources` / `recall_knowledge` / `rebuild_knowledge` /
|
|
117
|
+
`add_source` / `propose_wiki_cards` 各自带 `presentationMeta`,浏览器半按**工具名**注册
|
|
118
|
+
`tool.call.toolview`,于是对话里显示的是「导入 3 份来源并编译 · 写入 3 份 · 新建 2 张卡」
|
|
119
|
+
与可展开的命中列表(名次、分数、`entityType:entityId`、review 评分),而不是一坨 JSON。
|
|
120
|
+
meta 随会话日志落盘,所以**回放与当时看到的一致**。
|
|
121
|
+
- **来源里的图跟着文字进卡片**(0047):抽取那一段交给模型的是文字,模型不会把图带回来,
|
|
122
|
+
所以图由编译**单独**落位 —— 拿「图前最近那一段话」去各张卡片正文里比对(12 字滑窗,
|
|
123
|
+
容忍改写与「(参见图表12)」这类图号指引),命中就插在那段话后面;锚点对不上时退回
|
|
124
|
+
「图所在的来源小节」整节比对(还要至少命中 3 个滑窗),落点在正文里再用 4 字滑窗分高下;
|
|
125
|
+
两档都不够就**不挂** —— 宁可少一张图,也不把图挂到一张讲别的事的卡上,没落位的张数如实
|
|
126
|
+
进 `warnings`。收尾的署名图 / 二维码(图后没有正文且锚点很短)故意不挂。每张 wikiNote
|
|
127
|
+
只带**自己那一节**的图,因为多模态编码只吃每条的**第一张**图。图不参与抽取指纹,所以
|
|
128
|
+
0047 之前编好的库重编时,来源虽然被指纹跳过,图仍然会被补上。
|
|
129
|
+
- **图片引用有三种写法,解析只认「真实存在的那个」**(0047):`01_source_raw/_assets/…`
|
|
130
|
+
(规范形,知识库根相对)、`_assets/…`(转换内核早期写进 SourceRaw 的形式)、
|
|
131
|
+
`../../01_source_raw/_assets/…`(`cardHints` 给手工建卡的形式)。文档的资产清单与卡片的
|
|
132
|
+
`imagePaths` 走同一个 `assetRefCandidates`(根目录 → `01_source_raw/` → 文件自己的目录),
|
|
133
|
+
否则同一张图在文档里找得到、在卡片里找不到。派生字段(图片路径、溯源链)变了也算
|
|
134
|
+
「语料变了」,否则增量编译的空操作会把刷新结果丢掉。
|
|
135
|
+
- **SourceRaw 的 front matter 是 OKF v0.2 形状**(0048):`title`、`description`、
|
|
136
|
+
`resource`(底层资产地址)、`tags`、
|
|
137
|
+
`generated: {by, at}`(`by` = 谁解析的,`at` = **采集时间** —— OKF 里没有「抓取时间」
|
|
138
|
+
这个概念)、`sources: [{id, resource, title, author, last_modified}]`(对网页就是那个页面
|
|
139
|
+
本身:地址、标题、作者、发布时间)。`source_id` / `external_id` / `created_at` /
|
|
140
|
+
`updated_at` / `metadata` / `lineage` 是我们的扩展键(OKF 明确允许,且要求消费者容忍
|
|
141
|
+
未知键)。
|
|
142
|
+
规范:<https://github.com/GoogleCloudPlatform/open-knowledge-format>(v0.2)。
|
|
143
|
+
- **召回组装按「卡片」而不是按「片段」**(0050):R1–R3 不变(多路召回 + RRF + 对候选池重排,
|
|
144
|
+
召回与重排的对象都是 wikiNotes),R4 改成四步 —— ① 取 notes 对应的 wiki 去重,一张卡片的等级
|
|
145
|
+
取它名下 note 的**最高重排分**,命中的小节挂在同一条上;② **在这之后**做 wiki → wiki 的
|
|
146
|
+
1 跳扩展(图上的 `relates_to` 边 + 共同来源,上限 20 张);③ 按 `contextMaxChars`
|
|
147
|
+
(默认 20000,`0` = 不限)装箱:命中的 note 正文优先,扩展卡片先给标题 + 摘要 + 来路,
|
|
148
|
+
有余量才给正文;④ 装不下的落**系统临时目录**(`<os.tmpdir()>/dsh-knowledge-recall/<库>/<recallId>.md`),
|
|
149
|
+
上下文里留一行绝对路径 —— Agent 用自己的文件读取能力去取,读不到就调大
|
|
150
|
+
`context_max_chars` 重新召回。响应里 `budget` 是这次的真实账,`expansion` 是 1 跳扩展的结果。
|
|
151
|
+
- **召回栏是一条三步的步骤轨**(0050):召回(找)→ 重排(排)→ 扩展(展),箭头相连,每一步
|
|
152
|
+
带自己的真实计数(`关键词 12 · 向量 9` / `保留 5 · 丢 7` / `3 张 + 2 张`),没跑过时写「未运行」。
|
|
153
|
+
第一步的路由标签可点(点一下只看关键词或向量那一路的候选与分数);第二步列出**全部**候选的
|
|
154
|
+
逐条 logit 与 sigmoid,被丢弃的置灰并写明「低于阈值 0.2」;第三步分两块(命中的卡片 / 1 跳扩展,
|
|
155
|
+
含被预算挡住的),末尾写「最终 N 个 wiki 进上下文」。旋钮跟着步骤走:路线与召回 topK 在第一步,
|
|
156
|
+
上下文 topN 在第三步。这份「面板账本」只在 HTTP 的 `detail=true` 上返回,工具调用不带它。
|
|
157
|
+
- **编译的收尾段产出三样东西**(0049),都不调模型:
|
|
158
|
+
①**索引页** `derived.db` 的 `wiki-index.md` —— 按类型分组列出库里现有的卡片(链接 + 状态 +
|
|
159
|
+
待补数),末尾单列断链。它刻意不写生成时间与版本号:写了它每次重建都变一个字节,而增量
|
|
160
|
+
编译要靠「索引页变了没有」判断这一轮要不要真的落盘。落在派生库而不是卡片那一层,
|
|
161
|
+
因为后者每一份 `.md` 都会被当成一张卡片读进卡片清单。
|
|
162
|
+
②**相关卡片** —— 写进卡片正文末尾一块(块首带 `<!-- compiled:related -->`,整块替换而不是
|
|
163
|
+
追加)。关系来源有两个:来源文档里写明的关系(双向都记),以及「同一份来源」(补前面没覆盖
|
|
164
|
+
到的,每张卡片上限 8 条)。**它不进召回单元**:相关块是导航不是知识,切进去会让
|
|
165
|
+
「毛利率怎么算」同时命中所有提到毛利率的卡片。
|
|
166
|
+
③**断链检查** —— 正文里 `[[类型/名称]]` 指向不存在的卡片时,写成 `metadata.schema_issues` 里
|
|
167
|
+
`level: 'reference'` 的问题(卡片抽屉上那枚「引用」徽标终于有了内容),同时进 `lintCards()`
|
|
168
|
+
的待补清单。判据与判重同一套(类型 + entityId / 标题 / 别名)。
|
|
169
|
+
- **工具返回值必须能被 JSON 装下**(0046):`envelopeSuccess` / `envelopeFailure` 统一过一遍
|
|
170
|
+
`jsonSafe()`。原因很具体:`rebuild_knowledge` 只重建 wiki 时报告里的 `vectorQuantization` /
|
|
171
|
+
`embeddingDimension` 是 `undefined` —— 卡片、`wiki_notes`、图谱、FTS 全都已经落盘,调用方
|
|
172
|
+
收到的却是 `value is not lossless JSON`。工具返回值要原样进会话日志,而 HTTP 那条路是
|
|
173
|
+
`JSON.stringify`,同一个 `undefined` 在那里无声无息,所以这个错只在工具调用上现形。
|
|
61
174
|
- 编译期一条 wiki 至少产出一条 note;正文按 `##`/`###` 分节且超过 800 字符时按节切分,
|
|
62
175
|
首条 note 的 `unitId` 保持 `<entityType>:<entityId>`,后续为 `<entityType>:<entityId>#<n>`,
|
|
63
|
-
每条 note 都带 `wikiId` 指回父级 wiki
|
|
176
|
+
每条 note 都带 `wikiId` 指回父级 wiki。
|
|
64
177
|
- `recall_knowledge` 返回 `hits`(重排后的 wikiNotes)、`context`(`{ note, wiki, graph }[]`)、
|
|
65
178
|
`wiki`、`graph`、`routes`、`recallMode`、`rerank`、`recallTopK`、`contextTopN`;入参 `top_k`
|
|
66
|
-
|
|
179
|
+
控制召回条数,`top_n` 控制进入上下文的条数,`mode` 覆盖默认召回路线,
|
|
67
180
|
`rerank: false` 可单次关闭重排。
|
|
68
181
|
- `rerankProvider` 默认 `bert-python`,模型默认 `BAAI/bge-reranker-base`
|
|
69
|
-
(存在 `~/.tita-
|
|
182
|
+
(存在 `~/.dsh/tita-agent/resource/models/bge-reranker-base` 时优先用本地目录)。重排在独立
|
|
70
183
|
Python worker 进程中进行,模型缺失或超时时按融合分数返回并在 `warnings` 说明,
|
|
71
184
|
不会反复重试;`rerankProvider: 'none'` 完全跳过重排。
|
|
72
185
|
|
|
73
186
|
## 本地启用 WeMM
|
|
74
187
|
|
|
75
|
-
在 Apple Silicon
|
|
188
|
+
在 Apple Silicon 上执行一次(在插件包目录内):
|
|
76
189
|
|
|
77
190
|
```bash
|
|
78
|
-
|
|
191
|
+
bash scripts/setup-embedding.sh
|
|
79
192
|
```
|
|
80
193
|
|
|
81
|
-
脚本会把 Python 环境放到 `~/.tita-
|
|
82
|
-
`~/.tita-
|
|
83
|
-
|
|
84
|
-
Tita Data Agent → Agent 概览 →「构建」节点的设置中确认:
|
|
194
|
+
脚本会把 Python 环境放到 `~/.dsh/tita-agent/resource/python`,把量化模型放到
|
|
195
|
+
`~/.dsh/tita-agent/resource/models/WeMM-Embedding-2B-Quantized`。新配置会自动发现这两个路径;
|
|
196
|
+
设置位于 Tita Data Agent → Agent 概览 →「构建」节点:
|
|
85
197
|
|
|
86
198
|
- Provider:`WeMM Python(本地)`
|
|
87
|
-
- Python:`~/.tita-
|
|
88
|
-
- Model:`~/.tita-
|
|
199
|
+
- Python:`~/.dsh/tita-agent/resource/python/bin/python`
|
|
200
|
+
- Model:`~/.dsh/tita-agent/resource/models/WeMM-Embedding-2B-Quantized`
|
|
89
201
|
- 维度:`1024`
|
|
90
202
|
- 设备:`自动(优先 MPS)`
|
|
91
203
|
|
|
92
|
-
知识库默认保存在 `~/.tita-
|
|
93
|
-
|
|
94
|
-
`03_compiled` 会生成 `wiki_notes.json`、`knowledge_graph.json`、
|
|
95
|
-
`vector-manifest.json`、`vectors.binary` 和 `vectors.int8`。未修改的 wikiNote
|
|
204
|
+
知识库默认保存在 `~/.dsh/tita-agent/domain_knowledge/<库 id>`。点击「编译」后,
|
|
205
|
+
编译结果写入 `derived.db`。未修改的 wikiNote
|
|
96
206
|
会复用已有向量,只有新增或变更的 note 重新编码;编码与重排各自使用常驻 Python
|
|
97
207
|
worker(同一份 `src/python/embedding_worker.py`),避免每个请求重复加载模型。
|
|
98
208
|
|
|
99
209
|
BERT 重排默认使用 `BAAI/bge-reranker-base`;如需完全离线,可把模型放到
|
|
100
|
-
`~/.tita-
|
|
210
|
+
`~/.dsh/tita-agent/resource/models/bge-reranker-base`(会被自动发现),或设置
|
|
101
211
|
`DSH_RERANK_MODEL` / 在设置里填写本地路径。未安装时召回会降级到融合分数并给出警告。
|
|
102
212
|
**目录必须含分词器**(`tokenizer.json` 或 `sentencepiece.bpe.model`)——只有权重时模型会
|
|
103
|
-
加载成功但给所有输入同一个分(`RERANK_TOKENIZER_DEGENERATE
|
|
104
|
-
`docs/0024-本地模型运行时.md`。
|
|
213
|
+
加载成功但给所有输入同一个分(`RERANK_TOKENIZER_DEGENERATE`)。
|
|
105
214
|
|
|
106
215
|
知识写入、编译、SourceRaw 读取和召回支持统一的
|
|
107
216
|
`sessionId/turnId/intentId/taskId/subtaskId/runId/traceId/domain` lineage。卡片把
|
|
@@ -112,158 +221,146 @@ BERT 重排默认使用 `BAAI/bge-reranker-base`;如需完全离线,可把
|
|
|
112
221
|
可以通过工具 `check_knowledge_embeddings` 或 `GET /knowledge/embedding/health`
|
|
113
222
|
查看 provider、模型、设备、索引条数和最后一次错误。
|
|
114
223
|
|
|
115
|
-
## 格式转换(convert
|
|
116
|
-
|
|
117
|
-
多格式转换的 **DSH 宿主层**自 0018 起就在本插件里:不再是第二个挂载插件,而是本插件的一个
|
|
118
|
-
子模块(`src/convert/`),共用同一次挂载、同一个侧边栏 Tab、同一套 runtime。
|
|
224
|
+
## 格式转换(convert)
|
|
119
225
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
└─ @firecrawl/anydoc MIT / Rust / 预编译绑定:doc docx ppt pptx xls xlsx odt ods odp rtf epub csv 文本层 PDF
|
|
128
|
-
```
|
|
226
|
+
多格式转换是本插件的一个子模块(`src/convert/`),与知识库共用同一次挂载、同一个
|
|
227
|
+
侧边栏 Tab、同一套 runtime。解析由可选内核 `dsh-convert-core` 完成(内核不挂载,可独立
|
|
228
|
+
运行),底层是 `@firecrawl/anydoc`(MIT / Rust / 预编译绑定),支持 doc、docx、ppt、
|
|
229
|
+
pptx、xls、xlsx、odt、ods、odp、rtf、epub、csv 与文本层 PDF;另有本地音视频/图片
|
|
230
|
+
(`iddoc`)、扫描件轻量 OCR(`scanned`:`.pdf` 报 `needsOcr` 时**自动兜底**)与
|
|
231
|
+
网页 / 微信公众号文章(`web`:收另存到本机的 `.html/.htm` 页面,从 `og:url` / `canonical`
|
|
232
|
+
把原始地址找回来;内核不联网,`kind=url` 已从契约删除)。
|
|
129
233
|
|
|
130
234
|
| 项 | 值 |
|
|
131
235
|
| --- | --- |
|
|
132
236
|
| 工具 | `convert_capabilities` / `convert_source` / `convert_task` / `convert_ingest`(后两个写操作需本轮审批) |
|
|
133
237
|
| 路由 | `/convert/**`(含内核 Vue3 控制台) |
|
|
134
238
|
| 设置命名空间 | `tita-data-agent-convert`(冻结契约,由本插件安装) |
|
|
135
|
-
| 交付目录 |
|
|
239
|
+
| 交付目录 | `<工作区>/output/<YYYY-MM-DD>/<中文名>/`(`index.md` / `assets/` / `manifest.json`);叶子名取文档标题,同名让路 `-2` |
|
|
136
240
|
|
|
137
|
-
**依赖是可选的。** `dsh-convert-core` 声明在 `optionalDependencies
|
|
138
|
-
|
|
241
|
+
**依赖是可选的。** `dsh-convert-core` 声明在 `optionalDependencies`,首次调用时才加载。
|
|
242
|
+
平台没有 anydoc 预编译绑定、或用户显式不装时,
|
|
139
243
|
`convert_*` 与 `/convert` 面板返回 `DEPENDENCY_MISSING` 并给出安装建议,**knowledge 本体
|
|
140
|
-
(`add_source` / 编译 /
|
|
244
|
+
(`add_source` / 编译 / 召回)照常可用**。
|
|
141
245
|
|
|
142
|
-
|
|
143
|
-
`POST /knowledge/sources` 回环。少了一次 JSON 序列化,也因此没有旧的 ~1.2 MB body 上限。
|
|
144
|
-
单条 SourceRaw **没有字符数上限**:`maxSourceBytes` 在 0029 撤掉了(先撤面板上的字段,
|
|
145
|
-
后来连运行层那道闸门一起撤 —— 只撤面板等于留一个用户改不了、也找不到的硬上限)。
|
|
246
|
+
**单条 SourceRaw 没有字符数上限**:`maxSourceBytes` 已撤除。
|
|
146
247
|
真正的边界是转换内核的 `maxInputBytes`(管入口大小)与嵌入分批(管模型输入)。
|
|
147
248
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
1. 内核不 import knowledge,产物只写 `convert-out/`;
|
|
151
|
-
2. 转换代码写知识库只能经 `ingest.ts` 的 `IngestTarget.addSource`,别处不许直接落 `01_source_truth`;
|
|
152
|
-
3. 0017 的网页 / 视频 / OCR 应做成**可选适配器包**注册进内核,不要继续往本插件里塞 ffmpeg / whisper。
|
|
153
|
-
|
|
154
|
-
## 多知识库与文档(0021)
|
|
249
|
+
## 多知识库与文档
|
|
155
250
|
|
|
156
251
|
一个**知识库 = 独立配置 + 独立内容**(产品参照 WeKnora)。注册表持久化在
|
|
157
|
-
`<
|
|
158
|
-
默认库 id 固定为 `default`,其 `rootDir`
|
|
159
|
-
`defaultKnowledgeRoot()`);**不传 `kb` 的旧接口与旧工具一律作用于默认库,行为不变**。
|
|
252
|
+
`<agentRoot>/resource/knowledge-bases.json`。
|
|
253
|
+
默认库 id 固定为 `default`,其 `rootDir` 固定为 `<agentRoot>/domain_knowledge/default`。
|
|
160
254
|
|
|
161
255
|
```ts
|
|
162
|
-
interface KnowledgeBase { id; name; description; rootDir; isDefault;
|
|
256
|
+
interface KnowledgeBase { id; name; description; rootDir; isDefault; wikiTypes; createdAt; updatedAt; sourceCount; cardCount; noteCount; buildVersion }
|
|
163
257
|
```
|
|
164
258
|
|
|
165
|
-
`sourceCount` / `cardCount` / `noteCount` / `buildVersion`
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
`await refresh()`。
|
|
259
|
+
`sourceCount` / `cardCount` / `noteCount` / `buildVersion` 都是
|
|
260
|
+
**计算字段**,由真实 runtime 重新统计并缓存进同一个 JSON,
|
|
261
|
+
HTTP `GET /knowledge/bases` 在返回前先刷新。
|
|
169
262
|
|
|
170
|
-
|
|
263
|
+
**Agent 数据根目录包含以下内容**:
|
|
171
264
|
|
|
172
265
|
| 段 | 装什么 | 删掉的后果 |
|
|
173
266
|
| --- | --- | --- |
|
|
174
267
|
| `domain_knowledge/` | 知识树,按知识库 id 分叉 | 丢数据 |
|
|
175
|
-
| `memory/<知识库 id>/` |
|
|
176
|
-
| `intent/` | `
|
|
268
|
+
| `memory/<知识库 id>/` | 抽取轨迹、轴 / Knowledge 真源、处理日志、反馈与访问审计(append-only) | 丢历史,不可重建 |
|
|
269
|
+
| `intent/` | `intent.db`(当前记录 + 审计历史) | 丢审计流 |
|
|
177
270
|
| `output/` | 交付物,二级按日期分桶 | 什么都不损失 |
|
|
178
271
|
| `tmp/` | 运行期临时文件,二级按日期分桶 | 只影响未完成的任务 |
|
|
179
272
|
| `resource/` | 模型、Python 环境、`knowledge-bases.json` | 失去语义检索(嵌入/重排不可用) |
|
|
180
273
|
|
|
181
|
-
|
|
182
|
-
|
|
274
|
+
**记忆与意图为什么与知识树平级**:记忆装的是**关于这个 Agent 的动作留痕**(抽取轨迹、
|
|
275
|
+
轴与 Knowledge 真源、处理日志、审计流水),不是关于知识的断言;留在知识树里会让「备份知识树」
|
|
183
276
|
被迫连审计一起备份,也让「知识树有哪几段」这个问题混进一个横切层。意图则是**会话级**的
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
知识、记忆、意图三段都是可以直接备份、直接 diff 的用户文件。
|
|
277
|
+
(同一句话在哪个知识库下说,理解方式不该变),所以它不分库。这样知识、记忆、意图三段
|
|
278
|
+
都是可以直接备份、直接 diff 的用户文件。
|
|
187
279
|
|
|
188
|
-
|
|
189
|
-
它从建出来起就是空目录)与 `04_memory`(0032 搬去 `memory/`)都已不在。
|
|
280
|
+
每个知识库的数据根目录为 `<agentRoot>/domain_knowledge/<知识库 id>/`:
|
|
190
281
|
|
|
191
|
-
|
|
|
282
|
+
| 文件或目录 | 内容 | 删除影响 |
|
|
192
283
|
| --- | --- | --- |
|
|
193
|
-
| `
|
|
194
|
-
| `
|
|
195
|
-
| `
|
|
196
|
-
| `05_diagnosis/` | 智能归因图谱 | 可重建 |
|
|
197
|
-
|
|
198
|
-
`00_schema` 撤掉的依据:它从建出来那天起就是一个**空目录**。分类注册表与 Wiki 类型
|
|
199
|
-
注册表一直住在 `<agentRoot>/resource/knowledge-bases.json`(那是配置,跟着根路径走);
|
|
200
|
-
`00_schema` 里没有一行代码写过东西。「磁盘上有一个文件夹」本身是一种承诺,空着就是
|
|
201
|
-
误导。`ensureLayout` 会在启动时把空的 `00_schema` 删掉 —— **非空则保留**:那就不属于
|
|
202
|
-
「没用的空文件夹」了,删掉别人的文件比留一个空目录危险得多。
|
|
203
|
-
|
|
204
|
-
`01_source_truth` 按分类分目录(而不是平铺)的理由与 `02_wiki` 一致:分类是每份来源的
|
|
205
|
-
必备元数据(frontmatter 的 `source_type`),提到目录名上之后「按分类找东西」在文件系统
|
|
206
|
-
层面直接成立,不依赖界面。平铺在真实使用里会先变成垃圾场 —— 几十份来源混在一层,`ls`
|
|
207
|
-
读不出「我的指标口径在哪」。启动时一次性把平铺的文档搬进分类目录;读路径不依赖这个层级
|
|
208
|
-
(`sourceIndex` 递归扫全段建 slug → path 索引),所以旧布局、新布局与两者并存的中间态
|
|
209
|
-
都能读。**改分类 = 换目录**:`add_source` 用同一 `sourceId` 配新 `sourceType` 时,旧目录
|
|
210
|
-
里那份会被删掉,不会留下孤儿。
|
|
211
|
-
|
|
212
|
-
`resource/` 是 0029 新增的:模型与虚拟环境原来住在 `~/.tita-data-agent`,现在搬进
|
|
213
|
-
根路径 —— 「这个 Agent 的全部磁盘足迹」因此是一个目录,备份 / 迁移 / 整个删掉都只
|
|
214
|
-
需要认一个路径。启动时一次性搬迁(先 `rename`,跨卷**不自动复制**,因为可能有几个
|
|
215
|
-
GB);旧的 `TITA_DATA_AGENT_HOME` 留在解析链上作为兜底,所以搬与没搬都能跑。
|
|
216
|
-
搬迁**按条目合并**:`resource/models/` 里已经有用户自己放的模型时,仍会把旧的嵌入模型
|
|
217
|
-
搬进来,只跳过同名的那个 —— 否则「目标目录存在」会让另一样东西永远搬不过来。
|
|
284
|
+
| `knowledge.db` | SourceRaw、Knowledge、Wiki Card 与版本记录 | 丢失知识真源 |
|
|
285
|
+
| `derived.db` | wikiNotes、知识图谱、检索索引 | 可重新编译 |
|
|
286
|
+
| `assets/` | 来源图片与附件 | 丢失对应素材 |
|
|
218
287
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
的顺序解析。设置面板用占位符显示解析后的真实路径,并在**家当不在 `resource/` 下时
|
|
222
|
-
逐条告警**(「还在旧位置、重启会搬」和「根本不是路径、迁移搬不了」要做的事不同)。
|
|
288
|
+
`resource/` 保存模型、Python 环境与 `knowledge-bases.json`。
|
|
289
|
+
如果资源目录没有本地 Python 或模型,就使用 `python3` 或 Hugging Face 模型名。
|
|
223
290
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
> `src/settings-schema.ts` 的模块注释与 `tests/settings-schema.test.mjs`。
|
|
291
|
+
配置里 `python` / `embeddingModel` / `rerankModel` 三个字段的**默认值改成了空串 =
|
|
292
|
+
自动**:按 `<agentRoot>/resource/…` → 兜底名(`python3` / HF 模型名)的顺序解析。
|
|
293
|
+
设置面板用占位符显示解析后的真实路径,并在**资源不是当前 `resource/` 下的本地路径时
|
|
294
|
+
逐条告警**。
|
|
229
295
|
|
|
230
|
-
|
|
231
|
-
否则把模型搬一次就让整个索引判成「配置不匹配」而作废。
|
|
296
|
+
向量清单里记的模型名是 `local:<模型目录名>` —— **身份与位置解耦**。
|
|
232
297
|
|
|
233
|
-
|
|
298
|
+
**「文件类型 → 解析引擎」那张规则表已撤。** 它唯一被读的地方是浏览器决定
|
|
234
299
|
「这份文件直读还是送转换内核」,而那个判断现在只看扩展名本身(`DIRECT_READ_EXT`);
|
|
235
300
|
真正决定用哪个适配器的是**转换内核自己的格式表**(`ANYDOC/SCANNED/IDDOC/TEXT_EXTENSIONS`),
|
|
236
301
|
它从来不读这张表 —— 也就是说「把 .docx 设成直读文本」这类配置**改了不生效**。撤掉
|
|
237
302
|
之后:上传选择框的 `accept` 问内核要(`/convert/api/capabilities`),文件类型筛选项
|
|
238
303
|
和计数从**这一库真实的文档**推导。两边都不可能再与内核漂移。
|
|
239
304
|
|
|
240
|
-
**文档扩展名 `ext`
|
|
305
|
+
**文档扩展名 `ext` 的推导是有损的**:优先取
|
|
241
306
|
`metadata.source_path` 的 basename 扩展名;否则 `source_format === 'markdown'` → `.md`,
|
|
242
|
-
`'office'` → `.docx`,其余 → `.` + `source_format`;都没有 → `.md
|
|
243
|
-
`
|
|
307
|
+
`'office'` → `.docx`,其余 → `.` + `source_format`;都没有 → `.md`。只有来源写了
|
|
308
|
+
`source_path` 时才精确。
|
|
244
309
|
|
|
245
|
-
文档的 `parser`
|
|
246
|
-
`
|
|
247
|
-
(`add_source`、浏览器直读文本)是 `direct` —— 没有解析器。
|
|
248
|
-
猜一个引擎名(`.pdf` → `anydoc`),那是在陈述一件没有发生过的事。
|
|
310
|
+
文档的 `parser` 字段说的是**谁解析了这份文档**:经转换内核进来的会写
|
|
311
|
+
`metadata.parser`(如 `anydoc@1/pdf`),直接写进来的
|
|
312
|
+
(`add_source`、浏览器直读文本)是 `direct` —— 没有解析器。
|
|
249
313
|
|
|
250
314
|
### HTTP API
|
|
251
315
|
|
|
252
316
|
```text
|
|
253
317
|
GET /knowledge/bases → { bases, defaultBaseId }
|
|
254
318
|
POST /knowledge/bases { name, description?, rootDir? } → { base }
|
|
255
|
-
|
|
319
|
+
GET /knowledge/models?kb=:id → DSH 编译模型目录与当前默认模型状态
|
|
320
|
+
PATCH /knowledge/bases/:id { name?, description?, extractionNote?, compileModel? } → { base }
|
|
256
321
|
DELETE /knowledge/bases/:id → { deleted: true }
|
|
257
|
-
GET /knowledge/documents?kb=&query=&
|
|
258
|
-
GET /knowledge/
|
|
322
|
+
GET /knowledge/documents?kb=&query=&limit=&offset= → { documents, total }
|
|
323
|
+
GET /knowledge/events?kb= → { events }
|
|
324
|
+
GET /knowledge/documents/:docId?kb= → { document }(正文截前 4000 字符)
|
|
325
|
+
GET /knowledge/documents/:docId/content?kb=&offset=&limit= → { text, offset, nextOffset, totalChars, eof }
|
|
326
|
+
GET /knowledge/documents/:docId/view?kb= → 独立整页(HTML,读全文)
|
|
259
327
|
GET /knowledge/documents/:docId/versions?kb= → { versions }
|
|
328
|
+
GET /knowledge/documents/:docId/delete-impact?kb= → { knowledge, cards, extractionRuns }(只读,删除前查账)
|
|
260
329
|
POST /knowledge/documents/:docId/revert?kb= { versionId } → { document }
|
|
261
|
-
DELETE /knowledge/documents/:docId?kb= → { deleted: true }
|
|
330
|
+
DELETE /knowledge/documents/:docId?kb= → { deleted: true }(级联:知识、卡片、抽取轨迹)
|
|
262
331
|
GET /knowledge/assets/:kb/* → 知识库根目录下的文件流
|
|
332
|
+
GET /knowledge/doc-page.js → 独立整页的脚本(构建产物)
|
|
333
|
+
GET /knowledge/pages/trial?kb= → 抽取试跑(HTML 整页)
|
|
334
|
+
GET /knowledge/pages/help/:topic → 说明整页(compile / intent)
|
|
335
|
+
GET /knowledge/pages.js → 通用整页的脚本(构建产物)
|
|
336
|
+
POST /knowledge/import { kb, sources[], compile? } → { written[], failed[], attempted, compile|null }
|
|
337
|
+
POST /knowledge/card-annotate { kb, entity_id, kind?, note?, remove_id? } → { entityId, annotations, reviewScore }
|
|
338
|
+
POST /knowledge/card-review { kb, entity_id, action } → { entityId, review, reviewScore, status }
|
|
339
|
+
POST /diagnosis/run { kb, record } → { sourceId, entityId }
|
|
263
340
|
```
|
|
264
341
|
|
|
265
|
-
|
|
266
|
-
|
|
342
|
+
**0044:入库之后才 review,不再是「确认之后才入库」。** 编译(Pass 0)与
|
|
343
|
+
`propose_wiki_cards` 都**直接写 `02_wiki`**,卡片立刻进编译、进图、能被召回。
|
|
344
|
+
人在面板上做的是 `POST /knowledge/card-review`(review 抬分 / 撤销)与
|
|
345
|
+
`POST /knowledge/card-annotate`(加备注 / 标异常点)—— 两个动作都可逆,
|
|
346
|
+
而且都作用在**已经存在于库里的卡片**上。原来的提议队列
|
|
347
|
+
(`/knowledge/card-proposals*`、`write_knowledge_card`、`list_card_proposals`)已随确认门
|
|
348
|
+
一起退役;`memory/<库 id>/card-proposals/` 不再被写入。
|
|
349
|
+
|
|
350
|
+
**为什么撤回那道门**:它把知识挡在了门外。抽到的实体停在待办队列里等人一条条点,而人
|
|
351
|
+
不会点 —— 表现就是「文档导进去了,wiki 是空的」。review 的价值不需要靠排队实现:
|
|
352
|
+
「这张卡片对不对」可以在它已经能召回之后回答,而「没 review 就不许进来」等于把
|
|
353
|
+
「暂时没人看的正确知识」和「错误知识」一起丢掉。要否掉一条知识就把它标成 `problem`
|
|
354
|
+
或 `deprecated`,那会留痕、也能撤回。
|
|
355
|
+
|
|
356
|
+
**原文预览只发前 4000 个字符。** `GET /knowledge/documents/:docId` 返回的 `content` 是
|
|
357
|
+
截断过的,全文长度在 `contentChars`、是否截断在 `contentTruncated`。理由是抽屉只有
|
|
358
|
+
380px 宽,读不完一份几十万字的文档 —— 而把整份正文发过去正是「打开弹层要等半天」的
|
|
359
|
+
成因。要读全文走 `.../view` 那个独立整页:它按 `offset`/`limit` **一页一段**地取
|
|
360
|
+
(默认 20000 字符一页,切点对齐空行),所以任何一次响应都不与文档大小成正比。
|
|
361
|
+
|
|
362
|
+
`/knowledge/stats`、`/knowledge/search`、`/knowledge/rebuild`、`/knowledge/export`、
|
|
363
|
+
`/knowledge/cards`、`/knowledge/sources`、`/knowledge/graph`、`/knowledge/embedding/health` 与全部
|
|
267
364
|
`*_knowledge*` 工具都接受**可选** `kb`(query 或 body 字段)。`docId` 含 `:`
|
|
268
365
|
(如 `document:ab12…`),必须 URL 编码。
|
|
269
366
|
|
|
@@ -271,9 +368,6 @@ GET /knowledge/assets/:kb/* → 知识库
|
|
|
271
368
|
|
|
272
369
|
| 操作 | 条件 | 错误码 | HTTP |
|
|
273
370
|
| --- | --- | --- | --- |
|
|
274
|
-
| `DELETE /knowledge/bases/:id/source-types/:typeId` | 内置分类 | `SOURCE_TYPE_BUILTIN_LOCKED` | 409 |
|
|
275
|
-
| `DELETE /knowledge/bases/:id/source-types/:typeId` | 该分类下还有来源 | `SOURCE_TYPE_IN_USE` | 409 |
|
|
276
|
-
| `PATCH /knowledge/bases/:id`(`sourceTypes` 丢掉在用分类) | 该分类下还有来源 | `SOURCE_TYPE_IN_USE` | 409 |
|
|
277
371
|
| `DELETE /knowledge/bases/:id` | 目标库是默认库 | `BASE_IS_DEFAULT` | 409 |
|
|
278
372
|
| `DELETE /knowledge/bases/:id` | 库里还有文档 | `BASE_IN_USE` | 409 |
|
|
279
373
|
|
|
@@ -281,19 +375,87 @@ GET /knowledge/assets/:kb/* → 知识库
|
|
|
281
375
|
同时给出 envelope 的 `error.code` 与顶层 `code`/`message`。删除知识库只删注册表条目,
|
|
282
376
|
**不删磁盘内容**(删文档用 `DELETE /knowledge/documents/:docId`)。
|
|
283
377
|
|
|
378
|
+
### 抽取的参考:已有坐标进提示词(0068)
|
|
379
|
+
|
|
380
|
+
抽取提示词里**带上了库里已有的坐标**(名字 + 别名 + 定义 + 人写的指导),模型据此**指认**
|
|
381
|
+
「原文讲的这个东西就是已有的某一个」,而不是每份文档都造一套新名字:
|
|
382
|
+
|
|
383
|
+
```jsonc
|
|
384
|
+
// 模型输出的 objects / actions / scenes 每一项
|
|
385
|
+
{ "name": "坑位点击", "definition": "一句话说清它指什么", "existing": "通天塔坑位click" }
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
三条要点:
|
|
389
|
+
|
|
390
|
+
- **模型的话是提案**。`existing` 要换成实体 id 才交给注册表,而换不到(查不到 / 不同轴 /
|
|
391
|
+
已被并)就退回机械解析 + 新建 —— 与卡片层 `existing_id` 同一条纪律。
|
|
392
|
+
- **定义有主**。模型只在新建时写、或给一个还没有定义的实体补一次;人改过之后
|
|
393
|
+
(`description_source = human`)模型一个字都改不了。
|
|
394
|
+
- **截断不静默**。每类最多下发 200 条,超了在提示词里明说「还有 N 个没列出来」,报告里
|
|
395
|
+
写「下发 40 / 共 312」。模型看不到某条坐标时会把「清单里没有」读成「库里没有」。
|
|
396
|
+
|
|
397
|
+
坐标清单进的是**用户提示词**(system 是缓存前缀,不许带库内数据)。每库还有一条
|
|
398
|
+
**坐标提取备注**(`knowledge-bases.json` 的 `extractionNote`),逐字进提示词 ——
|
|
399
|
+
它是用户唯一能「指挥模型怎么认坐标」的地方,抽取规则本身不可编辑。
|
|
400
|
+
|
|
401
|
+
### 坐标即卡片身份(0069)
|
|
402
|
+
|
|
403
|
+
```text
|
|
404
|
+
Document ──▶ Knowledge × N ──▶ 坐标 (对象 × 动作 × 场景) ──▶ Wiki Card(唯一)──▶ 章节是检索单元
|
|
405
|
+
索引 组织与交付视图 知识是证据层
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
> **一个坐标最多一张卡**,这件事由 `knowledge.db` 的 `card.coordinate_key` **主键**兜着,
|
|
409
|
+
> 不是靠约定。`entity_id` 是版本历史和关联表使用的稳定别名。
|
|
410
|
+
|
|
411
|
+
四条要点:
|
|
412
|
+
|
|
413
|
+
- **卡片上记着它的坐标**(`card.object_id / action_id / scene_id` + front matter 的
|
|
414
|
+
`coordinate`)。坐标在这一层是**轴实体 id**,卡名只是显示。
|
|
415
|
+
- **判重的顺序是「先坐标,再认领,最后新建」**。如果按坐标未命中,就检查已有卡片能否认领,
|
|
416
|
+
最后才新建卡片。
|
|
417
|
+
- **不同坐标可以使用同一个卡名**。撞名会返回 warning。
|
|
418
|
+
- **落位落库**(`card_knowledge`,0063 §4.5):`section` / `ordinal` 是**关联**的属性。
|
|
419
|
+
召回命中**章节**之后,按这一节取它落位的知识(含四档状态与出处引文)。
|
|
420
|
+
|
|
421
|
+
**坐标不替代图。** 图是**从 Knowledge 派生的可选关系索引**,回答的是「通天塔依赖哪些表」
|
|
422
|
+
这类任意关系与反向关系;坐标回答的是「这条知识关于什么」。见
|
|
423
|
+
[docs/current/14](../../docs/current/14-智能归因.md) §7.3。
|
|
424
|
+
|
|
284
425
|
### 版本存储与回滚语义
|
|
285
426
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
`
|
|
291
|
-
|
|
427
|
+
**版本住在 `knowledge.db` 的 `revision` 表里**(0062 v2)。一次写入 = 一行 `revision`
|
|
428
|
+
(身份是 `(entity_kind, entity_id, version)`)+ 一行 `blob`(正文按 sha256 内容寻址)。
|
|
429
|
+
正文完全相同的重复写入**不产生新版本**,只更新 front matter 那类记账字段。
|
|
430
|
+
`listVersions` / `cardVersions` 返回新→旧,并把当前 head 标成 `isCurrent: true`;
|
|
431
|
+
`versionId` 就是**整数版本号的字符串形式**。
|
|
432
|
+
|
|
433
|
+
**回滚 = 用历史版本的正文重新写一次**:回滚前会把当时的 head 再记一版,所以历史只增不减,
|
|
434
|
+
**回滚本身也可回滚**。回滚到当前版本是 no-op。
|
|
435
|
+
|
|
436
|
+
### 起编译的语义(0066)
|
|
437
|
+
|
|
438
|
+
`POST /knowledge/rebuild` **立即返回** `202 { runId, queued }` —— 它只回答「这一趟的编号
|
|
439
|
+
是什么」与「前面还有没有人在跑」。编译在后台跑完,结论写进
|
|
440
|
+
`GET /knowledge/compile-progress` 的记录里:
|
|
441
|
+
|
|
442
|
+
```jsonc
|
|
443
|
+
{ "progress": { "runId": "rebuild_…", "startedAt": "…", "finishedAt": "…",
|
|
444
|
+
"steps": [ /* 四段 */ ], "outcome": "索引 v21:…",
|
|
445
|
+
"report": { /* RebuildReport */ } } }
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
`?runId=<编号>` 指名要哪一趟;不给编号时给**正在跑**的那一趟(没有在跑就给最近结束的那一趟)。
|
|
449
|
+
已结束的记录按编号留 8 条,所以后面那一趟开始跑**不会**抹掉上一趟的结论。
|
|
450
|
+
|
|
451
|
+
**为什么结论不走那条 POST 的响应**:编译是分钟量级的,而一条 HTTP 请求活不了那么久。实机上
|
|
452
|
+
312 秒的编译在 300 秒被切断,面板于是把「请求死了」读成「没有编译」—— 而编译 11 秒后就成功了。
|
|
453
|
+
结论因此落在**与任何一条请求都无关**的记录里。
|
|
292
454
|
|
|
293
|
-
|
|
294
|
-
|
|
455
|
+
`rebuild_knowledge` 工具**仍然是同步的**(`runtime.rebuild()`):工具调用不是浏览器请求,
|
|
456
|
+
等得起,要的就是「跑完了,结论是什么」。同一时刻只有一次编译在跑,后来的排队。
|
|
295
457
|
|
|
296
|
-
###
|
|
458
|
+
### 召回链路(两路 + 图谱 boost)
|
|
297
459
|
|
|
298
460
|
```text
|
|
299
461
|
query → R0 分词 → R1 两路各自超采并过阈值(候选池 50)
|
|
@@ -303,22 +465,21 @@ query → R0 分词 → R1 两路各自超采并过阈值(候选池 50)
|
|
|
303
465
|
→ R5 弃答(insufficientEvidence)
|
|
304
466
|
```
|
|
305
467
|
|
|
306
|
-
- **R0
|
|
307
|
-
的口径切开。
|
|
308
|
-
实测 `排查`→6 命中、`怎么排查指标异常`→**0**。
|
|
468
|
+
- **R0 分词**:中文按**单字 + 相邻双字**切分(不用词典),ASCII 按 `unicode61`
|
|
469
|
+
的口径切开。
|
|
309
470
|
- **R1 关键词路**:SQLite FTS5 + **BM25**(`node:sqlite`,零新依赖;不可用时如实降级)。
|
|
310
471
|
中文之所以不用内置 tokenizer:`unicode61` 不切中文,`trigram` 要求查询 ≥3 字符且会把
|
|
311
472
|
整句变成互相 AND 的三字窗口。分数按本次最高分归一到 0..1,再过 `keywordThreshold`;
|
|
312
473
|
另有**多字词覆盖率**门槛(只数双字词与 ASCII 词,单字在中文里不是证据)。
|
|
313
474
|
- **R1 向量路**:**编码器健康门**(两段无关文本必须余弦 < 0.99,否则整路停用)→
|
|
314
|
-
查询编码一次 → binary/Hamming 预筛 → int8 精算**原始余弦**(`dot / 127
|
|
315
|
-
|
|
316
|
-
- **R2 融合**:**RRF**(`k=60`,关键词 0.3 / 向量 0.7
|
|
317
|
-
|
|
475
|
+
查询编码一次 → binary/Hamming 预筛 → int8 精算**原始余弦**(`dot / 127²`)→
|
|
476
|
+
`vectorThreshold`。
|
|
477
|
+
- **R2 融合**:**RRF**(`k=60`,关键词 0.3 / 向量 0.7)——只吃**名次**,所以各路分数
|
|
478
|
+
量纲不同这件事不再影响排序。
|
|
318
479
|
- **R2 图谱**:**boost,不是第三路**。它给已经在候选池里的条目加一个 RRF 项,**不能自己
|
|
319
480
|
制造候选**。代价是「只提到某份来源、没提到任何卡片正文」的查询没有第二条路 ——
|
|
320
481
|
由关键词索引收录 **note 的溯源身份**(sourceRefs + 来源标题)来补偿。
|
|
321
|
-
- **R3
|
|
482
|
+
- **R3 重排**:作用在**候选池**上(不是已截断的 topK),
|
|
322
483
|
低于 `rerankThreshold` 的一律丢弃并报出丢了几条。阈值与 WeKnora 同刻度(**原始 logit**)。
|
|
323
484
|
worker 用 `predict_raw()`(`activation_fn=Identity`)返回 logit —— `CrossEncoder.predict`
|
|
324
485
|
对 `num_labels == 1` 默认套 sigmoid,直接拿返回值比 0.2 会让阈值永远不生效;展示用的
|
|
@@ -331,8 +492,7 @@ query → R0 分词 → R1 两路各自超采并过阈值(候选池 50)
|
|
|
331
492
|
并标注判据强度(`rerank-threshold` / `vector-threshold` / `relative-only` / `not-needed`)。
|
|
332
493
|
宁可说「没有」,也不凑满 topN 让模型编。
|
|
333
494
|
- **降级不谎报**:`routes` 只列**通过健康门且真的跑起来**的路;每一路的状态、候选数、
|
|
334
|
-
最高分、阈值与降级原因都在 `diagnostics.routes` 里。
|
|
335
|
-
`routes: ["fts","vector","graph"]`,是这次要修的核心问题之一。
|
|
495
|
+
最高分、阈值与降级原因都在 `diagnostics.routes` 里。
|
|
336
496
|
- `mode: 'graph'` 与 `hybrid` **同义**(图谱不能制造候选,「只靠图谱」不成立)。
|
|
337
497
|
- 阈值初值:`keywordThreshold 0.3` / `rerankThreshold 0.2` 沿用 WeKnora 的出厂值;
|
|
338
498
|
**`vectorThreshold` 是 0.5,不是它的 0.15** —— 那个数是它自己 embedding 模型的刻度,
|
|
@@ -344,14 +504,12 @@ query → R0 分词 → R1 两路各自超采并过阈值(候选池 50)
|
|
|
344
504
|
余弦 < 0.99),重排器查分词器词表(`vocab_size ≥ 1000` 且探针句有非 `<unk>` 条目,否则
|
|
345
505
|
`RERANK_TOKENIZER_DEGENERATE`)。原因是「能加载」不等于「可用」:本地快照缺分词器文件时,
|
|
346
506
|
重排器照样加载、照样出分(实测三条无关文本 `0.999 / 0.998 / 0.9994`),只有探针能发现。
|
|
347
|
-
修法与运维见 `docs/0024-本地模型运行时.md`。
|
|
348
507
|
- **编码器指纹** `ENCODER_FINGERPRINT` 写在向量清单里:同一个模型换了「怎么调它」也必须让
|
|
349
|
-
已有向量作废,否则 `rebuild all` 会按 contentHash
|
|
350
|
-
修好编码器后构建仍报 `reused: 44`,修复等于没发生)。
|
|
508
|
+
已有向量作废,否则 `rebuild all` 会按 contentHash 把旧向量原样复用。
|
|
351
509
|
|
|
352
510
|
`listDocuments()` / `readDocument(docId)` / `listVersions(docId)` /
|
|
353
|
-
`revertDocument(docId, versionId)` / `deleteDocument(docId)`
|
|
354
|
-
|
|
511
|
+
`revertDocument(docId, versionId)` / `deleteDocument(docId)` 是文档接口;
|
|
512
|
+
详情页的 `assets[].url` 即 `/knowledge/assets/<kbId>/<rel>`。
|
|
355
513
|
|
|
356
514
|
## 评测
|
|
357
515
|
|