Cherry Studio 知识库(Knowledge)功能全解:从摄取管道到 Concept ID 智能体工具
发布时间:2026/9/12 5:07:57
分类:文化教育
浏览:1234
功能全解:从摄取管道到 Concept ID 智能体工具)
Cherry Studio 知识库Knowledge功能全解从摄取管道到 Concept ID 智能体工具【免费下载链接】cherry-studioAI productivity studio with smart chat, autonomous agents, and 300 assistants. Unified access to frontier LLMs项目地址: https://gitcode.com/GitHub_Trending/ch/cherry-studio本篇文章以 Cherry Studio 开源仓库中 src/main/features/knowledge/README.md 为骨架深入剖析其按知识库隔离的私有知识库per-base knowledge library的完整实现文件/目录/URL/笔记如何被摄取、转换为 Markdown、分块与向量化并持久化进每个知识库专属的index.sqlitebetter-sqlite3 sqlite-vec进而为混合向量/BM25 检索与以 Concept ID 寻址的智能体工具kb_search/kb_read/kb_tree/kb_manage提供能力。读完本文你将掌握该知识库模块的目录结构、四阶段摄取管道、五类持久化任务与状态机、并发与崩溃恢复语义以及从检索到智能体工具的完整调用链。总览一个库即一个可检索的私有资料中心Cherry Studio 的知识库功能遵循per-base按知识库实例的设计原则。每个知识库负责摄取输入源本地文件、目录、URL 网页、用户笔记统一转化为 Markdown 文本通过pipeline/readers/下的多种 readerpdf/docx/epub 等分块并向量化通过pipeline/indexing/的 splitter、chunker 与 embedding/rerank 封装持久化到独立的索引库每个知识库在磁盘上拥有专属的index.sqlite基于 better-sqlite3 sqlite-vec提供混合向量/BM25 检索。检索结果既面向界面层的普通搜索也面向智能体层以Concept ID即 material 在库内的相对路径见 OKF §2寻址的kb_search/kb_read/kb_tree/kb_manage四个智能体工具让 Agent 可以精确定位、精读、浏览与增删改某个知识库内的文档。从源码结构看整个功能被严格分为两条边界pipeline/只负责输入 → 预处理 → 索引 → 持久化四阶段的纯管道执行ingestion/与tasks/负责编排决定入队哪些任务、更新 item 状态pipeline/下的代码绝不自行入队任务或修改 item 状态。这一管道与编排分离的架构是理解整个模块的关键。四阶段摄取管道Pipelinepipeline/按阶段顺序定义了完整的摄取管道README 用一张 ASCII 架构图概括了数据流向input preprocess index persist ┌──────────────┐ ┌────────────────┐ ┌───────────────┐ ┌───────────────┐ pipeline/ │ sources/ │ ─── │ readers/ │ ── │ indexing/ │ ── │ vectorstore/ │ │ expand dirs, │ │ file → md text │ │ chunk, embed, │ │ index.sqlite │ │ url/note │ │ (pdf, docx, …) │ │ rerank │ │ (per base) │ │ snapshots │ └────────────────┘ └───────────────┘ └───────────────┘ └──────────────┘ heavy conversions (MinerU/PaddleOCR/…) run out-of-process via FileProcessingService, polled by a knowledge job各阶段职责与实现位置如下1. 输入阶段pipeline/sources/负责把用户的原始输入变成可处理形态directory.ts目录展开将文件夹递归展开为子 itemurl.tsURL 抓取经 Jina reader。源码中fetchKnowledgeWebPage通过WebSearchService.fetchUrlsUnprocessed({ providerId: jina, urls: [...] })抓取网页并置于一个并发上限为 3、每分钟最多 10 次的限流队列中见 url.ts单次抓取默认超时 30 秒urlSnapshot.ts/noteSnapshot.tsURL 与笔记的快照捕获snapshot把抓取到的 Markdown 或笔记正文落盘为库内文件okfFrontmatter.ts为快照生成 OKF frontmatter知识库文件的元数据头sourcePlanning.ts源计划判定某个 item 下一步是直接索引还是需要文件处理转换。2. 预处理阶段pipeline/readers/将各类源文件统一转换为 Markdown 文本产出Document[]。入口是 KnowledgeReader.tsfile走KnowledgeFileReader内部按扩展名分发到 AnydocReader.ts、DocReader.ts、EpubReader.ts、DraftsExportReader.ts 等url/note走KnowledgeSnapshotReader读取快照。重型的格式转换MinerU、PaddleOCR 等不在主进程内同步执行而是通过FileProcessingService在进程外运行再由一个知识库任务轮询其结果——这正是图中heavy conversions run out-of-process的含义也解释了knowledge.check-file-processing-result任务存在的必要性。3. 索引阶段pipeline/indexing/splitter.ts保留偏移量的结构化分块器offset-preserving splitter保证source.slice(start, end) chunk.text这一不变量成立chunk.ts将多个Document按文档边界拼接为一个规范contentText并生成带charStart/charEnd偏移的分块embed.ts/rerank.tsAiService的 embedding 与 rerank 封装tokenLimit.ts/localEmbeddingTokenLimit.ts嵌入令牌上限控制含本地嵌入模型场景。4. 持久化阶段pipeline/vectorstore/KnowledgeVectorStoreService.ts每个知识库index.sqlite的生命周期管理按 baseId 缓存打开的 store见 KnowledgeVectorStoreService.tsindexStore/同步的 better-sqlite3 驱动BetterSqlite3Driver.ts、BetterSqlite3VectorIndex.ts与引擎无关的KnowledgeIndexStorevectorCleanup.ts向量删除与索引空间回收delete 后按需 VACUUM 归还磁盘空间。目录地图每个子目录的职责README 给出了完整的目录职责表结合源码进一步确认目录职责源码印证KnowledgeService.ts生命周期门面注册全部任务处理器、启动时执行恢复、把每个公共方法委托给对应模块并创建共享的按知识库互斥锁KeyedMutex。自身不含任何领域逻辑见 KnowledgeService.ts 中Injectable与onInit注册五个 handler 的代码base/按库领域生命周期管理KnowledgeBaseAdminService——带回滚的创建、删除、恢复失败库守护baseGuards.ts孤儿库产物检查orphanBaseArtifacts.tsingestion/写侧编排准入检查、item 创建、添加冲突处理addConflicts.ts、任务入队、子树清理subtreePurge.ts、启动恢复statusCleanup.tspipeline/sources/输入阶段见上文pipeline/readers/预处理阶段file → markdown/textDocument[]pipeline/indexing/索引阶段保留偏移的分块器 分块器 AiServiceembedding/rerank 封装pipeline/vectorstore/持久化阶段每库index.sqlite生命周期、store 本身indexStore/同步 better-sqlite3 驱动、向量删除与索引空间回收vectorCleanup.tsquery/读侧 Concept ID 工具面库发现与带可见性过滤的混合检索KnowledgeQueryServiceConcept ID 读/grep/树浏览以及kb_manage的删除/刷新写操作委托给ingestion/的KnowledgeConceptServicetasks/任务处理器管道执行者prepareItem.ts是 prepare-root 专用的私有辅助负责把目录根展开成子 itempathStorage.tsraw/路径分配无冲突命名、预留、库文件路径解析items.ts/types.ts共享 item 词汇类型别名、谓词、源探测、material 路径推导品牌化 idbranded ids、队列名、幂等键关于存储布局pathStorage.ts 明确了每个知识库的物理结构{baseDir}/ raw/ # 复制的文件、URL/笔记快照material 根relativePath 相对此目录 .cherry/index.sqlite # 派生的检索索引控制目录其中relativePath一律以 POSIX 风格存储且assertSafeKnowledgeRelativePath会拒绝绝对路径、越界路径..以及任何.cherry/前缀的保留路径——这是防止路径穿越把raw/之外或整库文件删掉的边界守卫。持久化任务Jobs与状态机所有任务运行在每库队列base.{baseId}上幂等键防止重复入队。幂等键的构造集中在 types.ts删除与重建子树键基于排序后的根 item id 列表索引键基于baseId itemId parentJobId文件处理轮询键还包含pollRound。任务作用由谁入队knowledge.prepare-root把目录根展开为子 item再为叶子入队索引任务ingestion添加时、reindex 处理器knowledge.index-documents读 → 分块 → 嵌入 → 在一个 store 事务内rebuildMaterialingestion、prepare-root、fp-checkknowledge.check-file-processing-result轮询 FileProcessingService 任务每轮延迟 5 秒成功则入队索引ingestion需要转换的文件knowledge.delete-subtree取消活动任务 → 删除向量 → 删除文件 → 删除行ingestion删除时、启动恢复knowledge.reindex-subtree校验源 → 重新获取源 → 删除向量 → 重置状态 → 重新入队索引ingestion重建索引时恢复recovery语义索引类任务与knowledge.reindex-subtree声明recovery: abandon——应用重启永远不会静默恢复它们因为那会无意中再次消耗付费的 embedding API取而代之的是启动恢复boot recovery把被中断的 item 停放到failed状态。只有knowledge.delete-subtree使用recovery: retry。在 indexDocumentsJobHandler.ts 中可以看到索引任务的具体配置recovery: abandon、默认并发 5、重试策略为指数退避最多 3 次、基延迟 1s、最大 30s、超时 30 分钟。同时KnowledgeService.onAllReady会调用ingestionService.recoverDeletingItems()与recoverInterruptedItems()把因崩溃停在deleting的根分组重新入队清理任务把因索引中断停在活动态reading/embedding/processing等的 item 标记为failed错误码indexing_interrupted避免界面出现永不结束的进度。Item 状态流preparing目录/ processing → completed | failed任意状态 → deleting → 行删除reading/embedding是索引任务运行期间向外暴露的瞬时子阶段见 types.ts 中KnowledgeProgressDetail的 stage 定义。完整的状态枚举定义在 src/shared/data/types/knowledge.tsidle、preparing、processing、reading、embedding、completed、failed、deleting。重建Reindex先重新获取源再重建README 强调了一条无类型例外的唯一规则Reindex re-acquires, then rebuilds.文件把用户的原始文件重新复制覆盖到它的raw/副本若知识库配置了文档处理器则重新处理目录重新扫描其原始文件夹URL重新抓取网页笔记从data.content数据库中的笔记正文重写快照——笔记的正文本身才是源raw/*.md文件只是派生的导出物。因此源必须仍然存在准入门classifyKnowledgeItemReacquireSource见 items.ts会拒绝源已消失的 reindex而不是静默地从陈旧副本重建。assertSubtreesCanReindex会在入队前一次性校验所有选定根的源状态与子树状态整棵子树必须全部处于completed或failed且根源可读并区分确实缺失应删除后重新添加与暂时无法验证如瞬时权限错误应重试而非销毁两种情形见 KnowledgeIngestionService.ts。与 reindex 相对恢复restore问的是另一个问题它从当前库向外复制因此一个原始文件已删除的文件项依然能正常恢复——classifyKnowledgeItemRestoreSource探测的是本库的raw/副本而非原始路径。并发模型应用级 KeyedMutex而非 SQLite 保护知识库的写并发依赖核心组件KeyedMutex通过runExclusive获取它是一个应用级互斥锁用于串行化跨越主数据库、索引库与文件系统三方的多步业务不变量例如 add 的读冲突 → 建行序列。明确的两点边界它不是用来保护 SQLite 本身的——每库驱动是同步的单条语句天然原子handler只在变更区段持有锁绝不跨越慢速 I/O抓取、读取、嵌入持锁。KnowledgeService门面创建这把共享锁并把它注入base/、ingestion/与各任务 handler见 KnowledgeService.ts。崩溃安全不依赖这把内存锁它只串行化当前进程内的并发而来自持久化任务 持久化 item 状态 JobManager 启动恢复 幂等清理。从参考文档 docs/references/knowledge/workflow-architecture.md 可以看到完整的调用链API / user action - KnowledgeIngestionService # 决定下一步工作流 - JobManager # 持久化任务 - Knowledge job handlers # 执行一个持久化阶段 - KeyedMutex.runExclusive # 串行化同库变更 - SQLite / index store / knowledge-owned files (raw/)三个责任方各司其职KnowledgeIngestionService决定下一步KeyedMutex.runExclusive串行化同库变更与清理任务 handler 只执行当前阶段并回调工作流服务进入下一步。handler 不自行决定某个 item 是根、嵌套容器、直接叶子还是文件处理候选。入口操作与守卫语义KnowledgeService对外暴露的公共操作对应 KnowledgeService.ts包括createBase/deleteBase/restoreBase、addItems/deleteItems/reindexItems、enableEmbeddingModel、search、listItemChunks、readConcept/grepConcept/deleteConcepts/refreshConcepts/getOrganizationTree等。addItems 的三种冲突策略addItems在准入阶段处理根名冲突默认renamerename默认保留全部输入冲突时自动分配无冲突的_N后缀名detect检测到根名冲突时什么都不写返回冲突列表让 UI 询问用户replace批次内后者胜出在取锁之前先取消冲突根的进行中任务否则会死锁在锁内清除冲突根再导入替换物。详见 KnowledgeIngestionService.ts 的addItems实现。入队失败时已完成调度的 item 保持不动未完成调度的 item 被标记为failed并重抛错误——避免行停留在preparing/processing却没有持久化任务推进它的卡死状态。deleteItems可回滚的删除意图deleteItems先把选中子树折叠为最外层根然后在锁内的单个数据库事务中把根子树标记为deleting并同事务入队knowledge.delete-subtree幂等键knowledge:{baseId}:{sortedRootIds}:delete。若入队失败整个事务回滚行保留原状态且对用户仍然可见——不存在可供启动恢复继续的已提交删除意图。删除清理失败时不会把 item 转为failed因为deleting是从默认列表/搜索/RAG 读取中隐藏内容的状态转为failed可能让未删完的陈旧块重新可搜索。reindexItems仅接受终态子树reindexItems不是取消原语。只有当整棵选中子树全部处于completed或failed时才允许重建idle、preparing、processing、reading、embedding与deleting一律拒绝。删除才是任何时候都可用、且唯一允许抢占活动工作的操作。reindex-subtree任务内部还有两处针对deleting的二次检查任务入口与锁内覆盖入队后删除抢先的竞态窗口。完整对比可查阅 docs/references/knowledge/operation-guards.md 的审查清单表failed base 放行策略、根折叠、前置状态守卫、入队失败补偿各不相同。读侧检索混合向量/BM25KnowledgeQueryService.search是检索入口KnowledgeQueryService.ts执行流程拒绝 failed 库与无搜索令牌的查询实时推导检索模式有 embedding 模型且已完成→hybrid否则 →bm25。这是每次调用即时计算的固定运行时策略而非存储的偏好永远不会与库配置漂移混合模式下先嵌入查询embedKnowledgeQuery以超额抓取的方式调用索引库搜索候选上限 topK × 5超额因子硬顶 200 条先让 BM25 车道search_text_fts对短 CJK 词元有 LIKE 回退与暴力向量扫描的结果用RRF倒数排名融合常数 K60融合用可见性过滤同库 completed见 visibility.ts 的loadVisibleItems丢弃缺失、异库、未完成的命中再裁剪到documentCount ?? 10条配置了rerankModelId时先重排再裁剪重排器看到的是完整超额候选集仅对scoreKind relevance的结果应用threshold过滤BM25/混合的ranking分数直接通过见 search.ts赋予rank。每个搜索结果携带conceptIdmaterial 相对路径与标题方便命中后直接用kb_read跟进。实现边界上需要留意当前检索对embedding行做直接扫描 标量余弦距离排序sqlite-vec 的vec_distance_cosine没有 ANN 近似索引因此单库检索成本随向量行数近似线性增长——这是精确实现边界而非索引化 ANN 的扩展性承诺。Concept ID 与智能体工具面Concept ID material 相对路径OKF §2是kb_read/kb_manage的寻址原语先在索引库中解析再对照可见的knowledge_item重新校验身份同库且completed防止一个相对路径触达其他库或已删除 item 的内容。工具层位于 src/main/ai/tools/knowledgeLookup.ts被 AI SDK 内置工具与 Claude Code 进程内 MCP 桥共享工具操作kb_list分页浏览范围内的库或返回某个库的逻辑 item 树带 depth 的前序 DFS 节点列表叶子携带可读conceptIdkb_search在显式范围内的库中检索返回带引用的块与 Concept IDkb_read读取有界文档切片默认单次上限 20,000 字符truncated/totalChars支持分页或以正则 grep 单篇文档kb_manage在用户批准后添加源、删除 Concept ID、刷新/重建 Concept IDKnowledgeConceptService是这些工具的读/写实现KnowledgeConceptService.ts其关键实现细节readConcept按[charStart, charEnd)切片默认上限CONCEPT_READ_MAX_CHARS 20,000grepConcept逐行扫描正则单行上限 2,000 字符防止灾难性回溯模式如(a)$冻结主进程事件循环默认返回最多 50 个匹配硬顶 200每个匹配带行号、字符偏移与 60 字符上下文getOrganizationTree基于knowledge_item.groupId层级构建逻辑组织树目录为文件夹、file/url/note 为叶子节点上限 1,000与扁平的物理raw/布局解耦deleteConcepts/refreshConcepts批量解析 Concept ID解析不到的放进notFound而不拖垮整批applied/notFound返回给 Agent 以便重查 id。测试覆盖如何验证这套实现仓库为该模块配备了与管道阶段一一对应的测试可用于深入理解与验证行为管道测试pipeline/indexing/testssplitter/chunk/embed/rerank/tokenLimit、pipeline/readers/testsAnydocReader/EpubReader 等、pipeline/sources/testsdirectory/url/noteSnapshot/okfFrontmatter向量库测试pipeline/vectorstore/indexStore/testsBetterSqlite3 驱动、RRF 融合、搜索、哈希、向量 blob、schema任务测试tasks/tests五个 handler 各自的单测与jobHandlerTestUtils集成与单元测试tests/KnowledgeService.integration.test.ts、tests/pathStorage.test.ts含 Windows 变体 pathStorage.win32.test.ts专门验证反斜杠路径穿越防护。参考文档索引围绕该模块仓库还维护了一套深度参考文档可作为继续阅读的入口docs/references/knowledge/README.md知识库领域入口索引以下全部文档docs/references/knowledge/knowledge-service.md当前后端形态——服务拆分、IPC 表面、存储边界、搜索流程、恢复式迁移库与智能体工具面docs/references/knowledge/workflow-architecture.md工作流模型——调度、持久化 JobManager 任务、每库互斥锁、崩溃语义docs/references/knowledge/operation-guards.mdaddItems/deleteItems/reindexItems/enableEmbeddingModel的守卫与恢复语义、审查清单。通过本文你应当已经掌握 Cherry Studio 知识库模块的完整图景四阶段管道只做纯转换编排交给ingestion/与tasks/所有写操作在应用级KeyedMutex内完成并配以幂等键重启永不静默恢复索引保护付费 embedding API而 Concept ID 这把相对路径即寻址原语的钥匙把知识库的检索能力无缝接入了 Agent 工具层。【免费下载链接】cherry-studioAI productivity studio with smart chat, autonomous agents, and 300 assistants. Unified access to frontier LLMs项目地址: https://gitcode.com/GitHub_Trending/ch/cherry-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考