@sparkelf/dsh-knowledge-base 0.1.5 → 0.1.21

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 (59) hide show
  1. package/README.md +129 -2
  2. package/SKILL.md +86 -18
  3. package/lib/client.js +14765 -9662
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +8082 -258
  6. package/lib/types/api.d.ts +36 -1
  7. package/lib/types/client/KnowledgeCreateDialog.d.ts +25 -0
  8. package/lib/types/client/KnowledgeFileTree.d.ts +143 -0
  9. package/lib/types/client/KnowledgeHome.d.ts +58 -0
  10. package/lib/types/client/KnowledgeListing.d.ts +7 -0
  11. package/lib/types/client/KnowledgeNewDocumentDialog.d.ts +32 -0
  12. package/lib/types/client/KnowledgeProgressPopover.d.ts +69 -0
  13. package/lib/types/client/KnowledgeSettings.d.ts +4 -3
  14. package/lib/types/client/KnowledgeTemplates.d.ts +4 -0
  15. package/lib/types/client/VectorSettingsGroup.d.ts +17 -0
  16. package/lib/types/client/WorkflowMenuIcon.d.ts +22 -0
  17. package/lib/types/client/extractionHistory.d.ts +43 -0
  18. package/lib/types/client/index.d.ts +32 -14
  19. package/lib/types/client/listingFilter.d.ts +58 -0
  20. package/lib/types/client/locales.d.ts +123 -0
  21. package/lib/types/client/openInSidebar.d.ts +2 -2
  22. package/lib/types/client/progressRules.d.ts +198 -17
  23. package/lib/types/client/sanitizeExplorerTabs.d.ts +20 -0
  24. package/lib/types/client/settingsGate.d.ts +65 -0
  25. package/lib/types/client/uploadTransport.d.ts +65 -0
  26. package/lib/types/client/useTreeSort.d.ts +72 -0
  27. package/lib/types/client/workflows/WorkflowPlaza.d.ts +146 -0
  28. package/lib/types/client/workflows/cron.d.ts +125 -0
  29. package/lib/types/client/workflows/dedupe.d.ts +70 -0
  30. package/lib/types/client/workflows/deps.d.ts +101 -0
  31. package/lib/types/client/workflows/modelChoice.d.ts +106 -0
  32. package/lib/types/client/workflows/published.d.ts +43 -0
  33. package/lib/types/client/workflows/registry.d.ts +98 -0
  34. package/lib/types/client/workflows/subscribe.d.ts +179 -0
  35. package/lib/types/embeddings.d.ts +62 -0
  36. package/lib/types/externalChange.d.ts +25 -0
  37. package/lib/types/extract.d.ts +32 -0
  38. package/lib/types/extractionQueue.d.ts +23 -2
  39. package/lib/types/ftsIndex.d.ts +497 -0
  40. package/lib/types/index.d.ts +266 -8
  41. package/lib/types/initialize.d.ts +105 -0
  42. package/lib/types/knowledgeTools.d.ts +239 -0
  43. package/lib/types/localStoragePath.d.ts +6 -0
  44. package/lib/types/localStorageSettings.d.ts +33 -0
  45. package/lib/types/managementTools.d.ts +184 -0
  46. package/lib/types/outlineGuard.d.ts +119 -0
  47. package/lib/types/outlineText.d.ts +134 -0
  48. package/lib/types/protocol.d.ts +34 -0
  49. package/lib/types/scopeAliases.d.ts +20 -0
  50. package/lib/types/vectorIndex.d.ts +113 -0
  51. package/lib/types/views.d.ts +33 -1
  52. package/lib/types/workflowPublish.d.ts +114 -0
  53. package/package.json +7 -7
  54. package/skills/kb-summarize/SKILL.md +158 -0
  55. package/skills/kb-summarize/i18n/zh.json +10 -0
  56. package/skills/kb-vectorize/SKILL.md +57 -0
  57. package/skills/kb-vectorize/i18n/zh.json +10 -0
  58. package//344/270/207/347/233/270AI/344/275/277/347/224/250/346/225/231/347/250/213.html +294 -0
  59. package/lib/types/client/KnowledgeProgressPanel.d.ts +0 -53
package/README.md CHANGED
@@ -1,7 +1,134 @@
1
1
  # @sparkelf/dsh-knowledge-base
2
2
 
3
- DataOps-backed knowledge base for DeepSeek Harness: a left-sidebar destination,
4
- Settings configuration, and index tooling over a mounted NAS view.
3
+ DeepSeek-Harness knowledge base: a left-sidebar destination, Settings configuration, and
4
+ index tooling over a mounted directory. Runs standalone or against a DataOps backend.
5
+
6
+
7
+ ## 两种部署形态
8
+
9
+ 同一个包,一份代码,由**有没有配置 `baseUrl`** 决定跑哪种形态。这不是一个运行期开关,
10
+ 而是部署事实:`baseUrl` 为空就是个人版。
11
+
12
+ ### 个人版(`baseUrl` 未配置)
13
+
14
+ 一个操作者,一个本地目录,**没有任何 DataOps 依赖**。
15
+
16
+ **能做:**
17
+ - 新建 / 编辑 / 重命名 / 复制 / 移动 / 删除文档与目录
18
+ - 上传文件并自动提取 Markdown(MinerU 地址取本插件 `mineruBaseUrl`,或按 `mineruPort` 推导)
19
+ - 目录浏览、全文搜索、预览
20
+ - 收藏、置顶、视图模式、回收站、审计记录——都是本地文件,不依赖后端
21
+ - 模板的读写
22
+
23
+ **不能做(因为没有可询问的权威):**
24
+ - **没有成员与账号体系**:不知道「我是谁」,只有一个固定的 `local` 身份
25
+ - **没有权限控制**:路径不按用户隔离;唯一的限制是「不能越出知识根目录」
26
+ - **没有共享配置**:没有管理员可以下发地址,MinerU 地址要自己填
27
+ - **没有授权与共享**:不能把文档授权给别人,也看不到别人的共享
28
+ - **没有成员目录**:无法列出用户 / 角色 / 部门作为授权对象
29
+ - **没有组织树**:视图只有一个平铺层级
30
+ - **不读取共享 OCR 地址**:不调用 `GET /api/ocr/config`,只用本插件自己的配置
31
+
32
+ **边界仍然存在:** 所有路径都相对知识根目录,`..`、绝对路径、NUL 字节一律拒绝并给出原因
33
+ (`checkLocalPath`)。「没有权限体系」不等于「没有边界」。
34
+
35
+ ### 团队版(`baseUrl` 已配置)
36
+
37
+ 装到 DataOps 工作区里的形态,行为与之前一致:账号、按路径授权的读写、共享 MinerU 地址、
38
+ 成员目录、共享配置、按用户隔离的视图(`/nas/kb/views/<userId>` 符号链接到 `mountPoint`)。
39
+
40
+ 路径校验、上传、提取、搜索、预览这些核心链路两种形态共用同一份实现——区别只是权限判据
41
+ 从「问后端」变成「查本地边界」。
42
+
43
+ ## 本地验证一个个人版
44
+
45
+ 个人版不依赖任何后端,所以可以直接起一个临时 profile 验证四条链路:
46
+
47
+ ```bash
48
+ mkdir -p ~/.dsh/profiles/kb-personal/plugins
49
+ cd ~/.dsh/profiles/kb-personal
50
+ # package.json 的 dsh.profile.bundles 里放 @deepseek-ai/dsh-base + dsh-web-app + 本插件
51
+ # cordis.patch.yml 里放 baseUrl: '' 和两个根目录(见下)
52
+ ~/.dsh/.../bin.js --profile kb-personal --port 6688 --no-open
53
+ ```
54
+
55
+ **`mountPoint` 必须等于 `actualRoot`。** 团队版靠 `pointMountAtView` 把两者用符号链接接起来;
56
+ 个人版没有视图层,列表读 `mountPoint`、写入落 `actualRoot`,写成两个目录就会表现为
57
+ 「上传成功了但文件不见了」。
58
+
59
+ ### 验证端口不要用 Chrome 的保留端口
60
+
61
+ **6666、6667 这类端口 Chrome 会拒绝加载**(`ERR_UNSAFE_PORT`,浏览器硬限制,与本插件无关),
62
+ 表现为 Playwright / 浏览器连不上而 curl 正常:
63
+
64
+ ```
65
+ page.goto: net::ERR_UNSAFE_PORT at http://127.0.0.1:6666/?token=...
66
+ ```
67
+
68
+ 选 6688 这类端口做本地验证。另外**起服务前先 `curl` 一次目标端口**再判断是否占用——
69
+ `ss` 显示空闲不代表绑定会成功(连续起停会有瞬时的绑定失败)。
70
+
71
+
72
+ ## 引用契约
73
+
74
+ `kb_search` 的每个命中、`kb_chunk_get` 的每个响应都带一个稳定 token:
75
+
76
+ ```
77
+ kb://doc/<docId>/chunk/<key>
78
+ ```
79
+
80
+ `key` 是内容寻址的 `chunk_key`(16 位十六进制),旧索引里可能是数字 chunk id。模型回答时
81
+ **原样引用这个 token**,不要写 `:193`、`第N块`、`path:line`,也不要写 `.docx.md`/`.pdf.md`
82
+ 派生路径。`kb_chunk_get` 接受完整 token,或 `docId` + `chunkId`(数字 id 或 chunk_key)。
83
+
84
+ `@sparkelf/dsh-kb-citation` 负责把 token 渲染成 `文件名:第N块`:点击后打开原始
85
+ `.docx/.pdf/.xlsx`,滚动到该 chunk 的首个命中页,并**每页只画 1 个 union 框**。source 面板、
86
+ 正文、GenUI 三处共用同一解析与标签逻辑;旧 `.docx.md:line` 链接仅作兼容 fallback,新回答
87
+ 不应再产生。
88
+
89
+ ### 目录索引(INDEX.md)与 `kb_outline`
90
+
91
+ 每篇文档建立 FTS 索引时会同步生成一份**导航结构**:目录(章/节/条)和章节行,
92
+ 但**默认不生成摘要**。摘要是在用户明确要求时,由 agent 执行 `kb-summarize` 技能阅读原文后
93
+ 调用 `kb_outline_save` 写入的。
94
+
95
+ - 文件:`<indexDir>/md/<docId>.INDEX.md`(默认 `/nas/kb/index/md/<docId>.INDEX.md`),
96
+ 与 `kb-index.sqlite` 同级,**不写入源文件目录**,也不进入任何用户的可见视图。
97
+ - 上传/抽取后:`kb_docs.summary` 为空,`kb_outline` 返回 `summaryStatus: "missing"` +
98
+ `hint: "调用 kb-summarize 技能生成摘要"`;目录和 `kb_sections` 已可用。
99
+ - 显式生成:`kb_outline` 拿 `toc`/`sectionId`/`chunkIds` → 逐章 `kb_chunk_get` 读原文 →
100
+ agent 生成 doc/section summary + keyFacts → `kb_outline_save` 校验并落库。
101
+ - 校验:摘要与 keyFacts 中的数字、比例、金额、条款号、责任主体必须能在对应 source chunks
102
+ 原文中找到(严格归一化);不匹配返回 `rejected[]`,**不写任何半成品**。
103
+ - 存储:`kb_docs.summary` / `toc_json` / `summary_version` / `summary_kind`;章节行写入
104
+ `kb_sections`;摘要与一级/全部章节摘要写入 `kb_summary_chunks` + `kb_summary_fts`
105
+ (独立 FTS 表,不影响 `kb_chunks_fts`)。
106
+ - 兼容:0.1.9 的抽取式摘要保留为 `summary_kind='extractive'`;`outline.autoGenerate=true`
107
+ 可恢复旧的自动抽取式行为(默认 `false`)。显式保存后整篇文档覆盖为 `summary_kind='llm'`。
108
+ - 重建条件:源文件 hash 或 `CHUNKER_VERSION` 变化会重建目录结构并使旧摘要失效;旧索引升级时只补
109
+ outline 行,**不重分块、不换 chunk id**,已有 citation token 仍然有效。
110
+
111
+ `kb_outline(docId | kb://doc/<docId>/chunk/<key>)` 返回
112
+ `{docId,path,summary,summaryKind,summaryStatus,toc,sections,indexPath}`,不返回整章全文。
113
+ `summaryStatus` 为 `missing` 时摘要为空,不应伪造;`kb_search` 命中在索引有摘要时附带
114
+ `sectionId/sectionPath/sectionSummary/docSummary`;摘要类结果永远不带 `citation`,只用于导航。
115
+ 引用仍只能使用原文 chunk 的 `kb://doc/<docId>/chunk/<key>` token。
116
+
117
+ `kb-summarize` 作为第二个 bundled skill 注册在同一个 skill provider 下;`list()` 同时返回
118
+ `knowledge-base` 与 `kb-summarize` 两个 candidate。
119
+
120
+ ### 分块与 bbox 契约
121
+
122
+ - `kb_chunk_boxes` 按提取块(段落/表格行/OCR block)逐条保存 provenance,供排查与
123
+ 重新聚合使用,**不是**前端绘制粒度。
124
+ - `POST /knowledge-base/api/chunk`、`/api/resolve` 与 `kb_search` 的 `boxes` 字段均为
125
+ **每页 1 个 union**;`kb_chunk_unions` 缓存该结果,旧索引没有缓存时由 API 现算。
126
+ - 分块以结构优先:`第X章/第X节`、`第X条`、Markdown/`一、` 标题、表格行都会开启新 chunk,
127
+ 章标题/条标题不会被并入上一块;`(一)` 等条内列表可以合并,但不得跨章。430 字只是软目标,
128
+ 上限 800 字只用于切分超长段落。`CHUNKER_VERSION` 变化会触发重建。
129
+ - 重建后旧 `chunk_key` 通过 `kb_chunk_key_aliases` 按文本重叠率(≥20%,短块要求完全一致)
130
+ 重映射;内容已被改写/删除的旧 token 解析为 404,引用侧显示「引用已失效」,不会落到相邻块。
131
+
5
132
 
6
133
  ## MinerU 部署(`scripts/deploy-mineru.mjs`)
7
134
 
package/SKILL.md CHANGED
@@ -15,39 +15,107 @@ description: "Read and change the shared knowledge base: browse, search, create,
15
15
 
16
16
  **新建文档前先想清楚它属于哪一层。** 放错层的后果是可见范围错了,而移动文档需要写权限——用户可能没有那个权限去纠正。
17
17
 
18
- ## 一、查(读与检索)
18
+ ## 一、查(Agentic RAG:先检索,再验证,最后引用)
19
+
20
+ 知识库检索不是“背答案”,也不是一上来 `cat` 大文件。按下面的顺序工作:
21
+
22
+ 1. **先判断问题形态,再选入口**:
23
+ - **精确事实/单点条款**:直接从 `kb_search(query, topK=10)` 开始。FTS5 + BM25 是主召回与排序路径,支持中文/英文,先按调用者身份和可见范围过滤。不要先查“知识库状态/索引状态”,没有 `kb_status` 工具;状态只由 UI 使用。
24
+ - **广泛/比较/区别/全面/是否类问题**(“有什么区别”“全面梳理”“是否允许”“分别有哪些”):先用 `kb_outline(docId | citationToken)` 拿目录(章/节/条)和已有摘要;如果 `summaryStatus` 是 `missing`,按需显式执行 `kb-summarize` 技能生成摘要,再 `kb_search` / `kb_chunk_get` 读相关章节原文。用户点名了文档或给了 `kb://` token 时直接 `kb_outline`;不知道 docId 时先 `kb_search` 找到文档,再 `kb_outline` 展开,避免只看命中 chunk 就下结论。
25
+ - **摘要只是导航,不是引用**:`kb_outline` 的 `summary`、`kb_search` 的 `sectionSummary` / `docSummary` / `relatedSections` 可能是旧 extractive 或显式生成的 llm 摘要,但**都不是引用来源**;引用必须使用原文 chunk 的 `citation` token。
26
+ 2. **比较、门槛、比例、金额、日期类问题必须先发 2 个 query 变体,再合并结果**(不要只发一条长句):
27
+ - 变体 A(精确术语):把问题里的制度术语直接拼起来,例如“普通决议 特别决议 三分之二 过半数”“董事会 表决 通过 比例”。
28
+ - 变体 B(实体+动作):例如“董事会 会议 召开 通知 工作日”“三重一大 重大项目 金额 门槛”。
29
+ - 数字/单位同时试常见写法:`5万元` / `50000元`、`3000元` / `3千`。
30
+ - 两个 query 的 hits 按 `citation` 去重合并(不要按 `path + line`);优先保留同时命中两边的 chunk,再按分数取 topK。
31
+ - **多词 query 返回 0 时不要放弃**:`kb_search` 会自动 relaxation(按 token 逐词搜、去重合并),结果里的 `relaxed: true` / `queries` 会告诉你实际查了哪些词。
32
+ - 如果 relaxation 后仍不足,最多再发 **2 轮**拆词/同义词(如 `普通决议`、`特别决议`、`三分之二`、`过半数`);**禁止用 `ls` 逐目录翻找答案**,目录列表只用于确认路径/找 `.md` 副本,不是检索手段。
33
+ - 2 轮仍无证据就明确说“资料未提供/知识库没有找到”,不能无限换词,也不能凭记忆补答案。
34
+ 3. **这些查询优先(或并行)用 `rg` 在 `/workspace/kb` 视图内精确搜索**:查询含 regex 元字符、引号字面量、反引号标识符、错误码、路径、`file:line`,或只有 1–2 个汉字。挂载隔离已保证 agent 只能看到自己的 view,普通 `rg` 就是权限内的,不需要额外封装安全工具。
35
+ 4. **`kb_search` 0 结果、top score 偏低,或 snippet 不足以回答** → 用 `rg` 做精确/验证兜底。
36
+ 5. **`rg` 命中很多(>30 行)** → 回到 `kb_search` 收敛排序,或加 `--glob` / 更精确 pattern,不要直接读几十个文件。
37
+ 6. **引用只用 `citation` token**:`summary` / `sectionSummary` / `docSummary` / `relatedSections` 都不是引用来源,只能用来决定“读哪一章”;每条 hit 都带 `citation: kb://doc/<docId>/chunk/<key>`(`?terms=` 只是查看器高亮提示)。回答里**原样写 `kb://doc/<docId>/chunk/<key>` 这段**(写成行内代码,省略 `?terms=`/`&highlight=` 后缀),**不要**自己写 `:193`、`第N块`、`path:line`,也不要写 `.docx.md`/`.xlsx.md`/`.pdf.md` 这类派生路径。查看器会把 token 渲染成 `文件名:第N块`,点击会打开原文件并定位到该 chunk 的 bbox;正文只需要写条文号(如“第十五条”),位置交给 token。
38
+ 7. **看到 `kb://doc/<docId>/chunk/<key>` token,必须先调 `kb_chunk_get`**:可以传 `docId` + `chunkId`,也可以直接传 `citation: "kb://..."`;`chunkId` 支持数字 id 或 16 位 chunk_key。返回原文 `path`、`quote`、`heading/paragraphText`、`sheet/cell`、`page/boxes`、`chunkOrdinal`、`snippet`。**禁止**用 bash/sqlite3 查 `.dataops`、`kb-index.sqlite` 或任何内部索引来解析 token;工具不可用就明确说“当前无法解析该引用”,不要逆向内部存储。
39
+ 8. **需要核对原文时**用通用 `read` 工具读 `/workspace/kb/<view相对路径>`(例:hit `global/制度.md` → `read /workspace/kb/global/制度.md`),但**引用仍然用 hit 的 `citation` token**;不要从 `read` 输出抄行号再拼 `path:line`。二进制文件用 `ls -l` / `stat` 看大小,不要用 `read`。
40
+ 9. **引用必须选“包含该 claim”的 chunk**:引用前逐个核对 citation chunk 是否同时包含 claim 的实体、条款号/数字/单位;不得用同文档但不含该 claim 的相邻 chunk 凑引用。多个候选时选重叠最高且能覆盖 claim 的 chunk;没有任何 chunk 覆盖时,明确说“资料未提供”,不要编引用。PDF/扫描件的低 confidence 框带 `approximate:true`,回答里说明“近似定位”。
41
+ 10. **整题最多 3 轮检索**(含 relaxation):仍无证据就明确说“知识库里没有找到”,不要凭记忆补答案。
42
+
43
+ ### 主检索:kb_search
19
44
 
20
- ### 浏览与读取
45
+ ```
46
+ kb_search(query="差旅住宿标准", topK=10)
47
+ kb_search(query="reimbursement policy", topK=10)
48
+ ```
21
49
 
22
- 用户界面里看到的就是这份视图,你也可以直接读同一批文件:
50
+ 返回 `citation/path/chunkOrdinal/snippet/score`(PDF/扫描件另有 `page/boxes`);先看 snippet 是否直接回答,再决定是否 `rg` 精确验证或用通用 `read` 读 `/workspace/kb/<path>` 全文。回答里引用时只用 `citation` token。
23
51
 
24
- ```bash
25
- ls /workspace/kb/global/
26
- cat /workspace/kb/global/规范.md
52
+ ### 导航:kb_outline
53
+
54
+ 广泛、比较、区别类问题先展开文档结构,再读原文:
55
+
56
+ ```
57
+ kb_outline(docId=49)
58
+ kb_outline(citation="kb://doc/49/chunk/e63b7f9eda2d86cb")
59
+ ```
60
+
61
+ 返回 `docId/path/summary/summaryKind/summaryStatus/toc/sections/indexPath`:
62
+
63
+ - `toc`:章/节/条目录,含 `sectionId`、`title`、`level`、`chunkIds`。
64
+ - `sections`:每节摘要 + `keyFacts`(门槛/比例/主体/例外)+ `sourceChunkIds`;**不返回整章全文**。
65
+ - `summaryKind`:`none`(尚未生成)/ `extractive`(0.1.9 旧抽取式)/ `llm`(`kb-summarize` 生成)。
66
+ - `summaryStatus`:`missing` 时摘要为空,返回 `hint: "调用 kb-summarize 技能生成摘要"`;`ready` 才可用摘要导航。
67
+ - `indexPath`:`/nas/kb/index/md/<docId>.INDEX.md`,内容与返回值一致,可按需 `read`。
68
+ - **上传/抽取不会自动生成摘要**。索引只自动建立目录/章节结构;摘要由 `kb-summarize` 技能显式读取原文后生成,并用 `kb_outline_save` 落库。旧 extractive 摘要会保留,显式保存后覆盖为 `llm`。
69
+ - 源文件 hash 变化会让旧 llm 摘要失效并在下次同步时清空,需要重新执行技能;chunk id 不变时已有 citation token 继续有效。
70
+ - 摘要只用于定位章节;回答里的每个数字、主体、例外仍须回到原文 chunk 核对,引用只用原文 token。
71
+
72
+ #### 显式生成/更新摘要:kb-summarize
73
+
74
+ 当用户明确要求摘要,或 `kb_outline` 返回 `summaryStatus: "missing"` 且问题需要整体理解时,执行 `kb-summarize` 技能(见其 SKILL.md)。流程是:
75
+
76
+ 1. `kb_outline(docId)` 拿 `toc` / `sections` / `chunkIds`;
77
+ 2. 逐章 `kb_chunk_get(docId, chunkId)` 读原文;
78
+ 3. 由你(当前 agent)生成 doc summary、section summaries、keyFacts;
79
+ 4. `kb_outline_save(docId, summary, sections)` 落库;数字/比例/条款号/主体不匹配会被拒绝,不会写半成品;
80
+ 5. 再 `kb_outline` 确认 `summaryKind: "llm"`、`summaryStatus: "ready"`。
81
+
82
+ 不要为了生成摘要而在插件外直接改 `/nas/kb/index`、SQLite 或 INDEX.md。
83
+
84
+ ### 引用写法
85
+
86
+ ```text
87
+ ✅ `kb://doc/49/chunk/e63b7f9eda2d86cb`
88
+ ❌ `[董事会议事规则](kb/global/0911董事会议事规则(试行).docx.md:193)`
89
+ ❌ `董事会议事规则.docx:第9块`
90
+ ❌ `董事会议事规则.docx:193`
27
91
  ```
28
92
 
29
- 三层都要看的时候:
93
+ token 是唯一稳定的引用标识;文件名、第N块、行号都由查看器从 token 解析,模型不要手写。
94
+
95
+ ### 精确兜底:rg(在视图内)
30
96
 
31
97
  ```bash
32
- find /workspace/kb -name "*.md" -not -path "*/.*" | head -50
98
+ rg -n "错误码|file:line|反引号标识符" /workspace/kb --glob "*.md" | head -30
99
+ rg -n "差旅" /workspace/kb --glob "**/*.md" | head -30
33
100
  ```
34
101
 
35
- ### 用 grep 全文检索
102
+ **限制**:图片里的文字搜不到;扫描件 PDF 没有 `.md` 副本时 rg 搜不到;`.doc/.xls/.ppt` 老格式可能丢表格结构。搜不到时先确认旁边有 `.md` 文本副本。
36
103
 
37
- **这是知识库最重要的用法**:所有上传的文档在上传时都会自动生成一份 `.md` 文本副本(同名加 `.md`,例如 `报告.docx` 旁边有 `报告.docx.md`),所以 grep 能直接搜到 Word 和 PDF 里的正文:
104
+ ### 浏览与读取
38
105
 
39
106
  ```bash
40
- grep -rl "关键字" /workspace/kb --include="*.md"
41
- grep -rn "关键字" /workspace/kb --include="*.md" | head -20
107
+ ls /workspace/kb/global/
108
+ cat /workspace/kb/global/规范.md
42
109
  ```
43
110
 
44
- 搜到了原文,再决定要不要读整个文件。不要一上来就 `cat` 大文件。
111
+ 根目录用 `ls /workspace/kb` 即返回 global/department/personal 三个桶;搜索框/HTTP search 由 KB 页面使用,AI 侧主检索仍是 `kb_search`。
45
112
 
46
113
  ### 搜索的局限
47
114
 
48
- - 图片里的文字搜不到(解析不覆盖 OCR)
49
- - 扫描件 PDF 只有 MinerU 能读出文字,读不出时该文件没有 `.md` 副本
50
- - `.doc`/`.xls`/`.ppt` 老格式靠 LibreOffice 转换,可能丢失表格结构
115
+ - FTS5 trigram 对 1–2 个汉字可能没有命中,此时按策略用 `rg`。
116
+ - 解析是异步的:上传后立刻搜可能还没有 `.md` 副本;看进度面板的“解析→分块→写索引→完成/失败”。
117
+ - 索引在 companion 的 `/nas/kb/index`,不在 agent view;**不要尝试直接读索引文件**,它是实现细节。唯一例外是 `kb_outline` 返回的 `indexPath`(`/nas/kb/index/md/<docId>.INDEX.md`),它是给 agent 读的导航副本;不要把它当原文引用。
118
+ - 刚上传/刚解析的文档只有目录结构,`summaryStatus` 为 `missing`;需要摘要时显式执行 `kb-summarize`,不要期待 `kb_outline` 自动补摘要。
51
119
 
52
120
  ## 二、增(新建与上传)
53
121
 
@@ -133,8 +201,8 @@ rm /workspace/kb/personal/废弃草稿.md
133
201
  | 把文档写到 `/workspace/kb/` 根下 | 脱离三个桶,权限与可见性都不受控 | 先选层,再写进对应文件夹 |
134
202
  | 用 `rm *.md` 清理 | 知识库不是临时目录 | 明确指定单个路径 |
135
203
  | 假设 `department/` 里是自己部门的文件 | 目录名是桶名,具体部门在数据层区分 | 以实际列出的内容为准 |
136
- | 上传后立刻 grep 搜正文 | 解析是异步完成的,且只对可解析格式生效 | 确认旁边有 `.md` 副本再搜 |
137
- | 读不到文件就去翻 `/nas/kb` 原始库 | 那是权威存储,绕过视图等于绕过权限 | 尊重当前视图的可见范围 |
204
+ | 上传后立刻检索正文 | 解析是异步完成的,且只对可解析格式生效 | 看进度面板确认“写 FTS5 索引”完成,或确认旁边有 `.md` 副本 |
205
+ | 读不到文件就去翻 `/nas/kb` 原始库或索引 | 那是 companion 权威存储/索引,绕过视图等于绕过权限 | 尊重当前视图的可见范围 |
138
206
 
139
207
  ## 七、给用户写操作前的自检
140
208