# 产品内知识库沉淀系统开发文档 ## 1. 背景 当前项目是一个 DeerFlow 定制化离线部署系统,包含: - 前端:`frontend-web/`,Vite + React 19 + TypeScript。 - 后端:`offline-backend-20260512/backend/`,FastAPI Gateway + LangGraph agent runtime。 - 现有能力:对话线程、工具搜索、引用来源、Markdown 渲染、外部知识库 iframe 页面。 本需求希望将“每次问答、搜索、工具调用、生成报告”等高价值内容自动或手动沉淀为产品内知识库,并在后续问答中可被检索和召回。 本方案以 `ar9av/obsidian-wiki` 为底层知识组织规范:优先复用它的 vault 目录结构、Markdown frontmatter、`index.md`、`log.md`、`hot.md`、`.manifest.json`、wikilink、`wiki-capture`、`wiki-query`、`wiki-export`、`graph-colorize` 等原生技能/页面产物。产品侧负责把这些能力封装成后端 API 和 React 页面。 ## 2. 目标 实现一套产品内知识库系统: 1. 支持从单次对话线程沉淀知识。 2. 支持从搜索结果、工具调用结果沉淀知识。 3. 支持自动抽取摘要、标签、实体、来源、关键结论。 4. 支持知识列表、详情、搜索、编辑、删除。 5. 支持保存 Obsidian 兼容 Markdown 文件。 6. 支持后续问答时召回相关知识,并显示引用来源。 7. 首版支持知识图谱页面,后续可增强实体关系抽取、自动去重、知识合并。 ## 3. 首版交付范围 首版必须实现: - 产品内知识库页面:列表、详情、搜索、编辑、删除/归档。 - 产品内 Markdown 编辑体验:支持编辑正文、预览 Markdown、编辑标题/标签/状态/来源信息。 - 当前对话沉淀:在聊天线程页面点击“保存到知识库”,生成 obsidian-wiki 兼容 Markdown 笔记。 - 历史线程批量入库:提供后台接口和前端入口,可批量扫描已有线程并沉淀为知识库内容。 - 搜索和工具结果沉淀:保存 query、结果标题、摘要、URL、工具名等来源信息。 - 全局共享知识库:所有用户共用同一套 vault 和数据库索引,不按用户隔离。 - 审计记录:写入、更新、删除记录 `created_by` / `updated_by`,用于追踪操作来源。 - Obsidian 兼容 vault:后端自行维护 `index.md`、`log.md`、`hot.md`、`.manifest.json`、wikilinks 和 frontmatter。 - 图谱页面:后端自行生成 `wiki-export/graph.html` 和 `graph.json`,前端直接 iframe 展示 `graph.html`。 - 不安装、不调用 `obsidian-wiki` CLI。 - 知识库功能由新增 `knowledge` 模块独立实现。 首版暂缓实现: - 精确复刻 Obsidian 桌面端所有交互细节。 - 图数据库服务。首版图谱用 Markdown wikilinks + `graph.json` / `graph.html` 实现,不额外引入图数据库中间件。 - 向量 RAG 自动注入。首版先完成知识沉淀、管理、关键词搜索和图谱,向量召回后续增强。 ## 4. 总体架构 数据流: ```text 用户问答 / 搜索 / 工具调用 / 生成文档 ↓ Knowledge Event 采集 ↓ Obsidian Wiki Adapter 按 obsidian-wiki 原生技能规范抽取、分类、写入 vault ↓ 三类存储 1. Markdown Vault:obsidian-wiki 原生目录、frontmatter、wikilinks 2. 数据库:产品检索、列表、来源映射、创建/修改审计 3. 向量索引:语义检索和 RAG 召回 ↓ 前端知识库页面 列表、搜索、详情、来源、编辑、图谱 ↓ 后续问答自动召回相关知识 ``` 推荐新增后端模块: ```text offline-backend-20260512/backend/app/gateway/routers/knowledge.py offline-backend-20260512/backend/packages/harness/deerflow/knowledge/ ``` 推荐新增前端模块: ```text frontend-web/src/core/knowledge/ frontend-web/src/pages/KnowledgeBasePage.tsx frontend-web/src/components/knowledge/ ``` ## 4.1 obsidian-wiki 原生复用策略 必须优先复用 `obsidian-wiki` 的原生约定,而不是另起一套知识库格式。 ### 4.1.1 复用对象 从 `ar9av/obsidian-wiki` 复用以下内容: - `.skills/wiki-capture/SKILL.md` - 用作“对话沉淀为知识笔记”的抽取和写作模板。 - 关键要求:写成 declarative knowledge,不保存聊天流水账。 - `.skills/wiki-query/SKILL.md` - 用作知识检索策略参考。 - 关键要求:先读 `hot.md` / `index.md` / frontmatter,再逐步升级到正文。 - `.skills/wiki-export/SKILL.md` - 用作知识图谱导出规范。 - 复用输出:`wiki-export/graph.json`、`graph.graphml`、`cypher.txt`、`graph.html`。 - `.skills/graph-colorize/SKILL.md` - 后续用于 Obsidian graph 配色。 - `.skills/wiki-status/SKILL.md` - 后续用于知识库状态、孤立页面、delta 分析。 - `.skills/cross-linker/SKILL.md` - 后续用于自动补充 wikilinks。 - `.skills/wiki-dedup/SKILL.md` - 后续用于重复知识合并。 - vault 文件: - `index.md` - `log.md` - `hot.md` - `.manifest.json` - `_insights.md` - `_meta/taxonomy.md` ### 4.1.2 产品封装原则 产品后端新增 `ObsidianWikiAdapter`,负责: - 初始化 vault。 - 调用或模拟 `wiki-capture` 的写入流程。 - 写入 `index.md`、`log.md`、`hot.md`。 - 维护 `.manifest.json`。 - 按 `wiki-export` 规范生成 `wiki-export/graph.html/json`。 - 将 vault 页面同步到产品数据库索引。 前端不直接依赖 obsidian-wiki 技能文件。前端只调用 `/api/knowledge/*`。 ### 4.1.3 调用方式优先级 优先级如下: 1. 运行时不使用 `obsidian-wiki` CLI。 2. 后端内置 obsidian-wiki 兼容实现,输出必须兼容 obsidian-wiki vault。 3. 后端自行初始化 vault、写入 Markdown、维护 `index.md` / `log.md` / `hot.md` / `.manifest.json`。 4. 后端自行按 `wiki-export` 规范生成 `wiki-export/graph.html` / `graph.json`。 5. 对 `wiki-export/graph.html` 这类原生产物,优先直接作为静态页面 iframe 到产品内。 6. 对 Markdown 笔记列表、详情、编辑,使用产品自研 React 页面读取同一个 vault。 ## 5. 与现有系统的关系 可复用现有能力: - `app/gateway/routers/threads.py` - `GET /api/threads/{thread_id}/state` 可读取线程 messages。 - `GET /api/threads/{thread_id}/reference-batches` 可读取工具搜索/引用来源。 - 前端 Markdown 能力 - `frontend-web/src/strategy-components/MarkdownRenderer.tsx` - `frontend-web/src/core/threads/export.ts` - 现有知识库入口 - `frontend-web/src/strategy-components/components/resource-management/KnowledgeBaseResourceManagement.tsx` - 当前是 iframe,后续可替换为原生知识库管理页面。 必须复用/兼容的外部项目能力: - `git-clone/obsidian-wiki/.skills/wiki-capture/SKILL.md` - `git-clone/obsidian-wiki/.skills/wiki-query/SKILL.md` - `git-clone/obsidian-wiki/.skills/wiki-export/SKILL.md` - `git-clone/obsidian-wiki/.skills/wiki-status/SKILL.md` - `git-clone/obsidian-wiki/.skills/wiki-dedup/SKILL.md` - `git-clone/obsidian-wiki/.skills/cross-linker/SKILL.md` ## 6. 分阶段实现 ### 阶段一:首版完整交付 目标:交付可用的产品内共享知识库。用户可以手动沉淀当前对话,也可以批量沉淀历史线程;所有知识写入同一套 obsidian-wiki 兼容 vault,并在产品内完成浏览、搜索、编辑、删除和图谱查看。 范围: - 新增知识笔记数据库表。 - 新增 `ObsidianWikiAdapter`。 - 新增 obsidian-wiki 兼容 Markdown vault 写入能力。 - 初始化并维护 `index.md`、`log.md`、`hot.md`、`.manifest.json`。 - 新增 `POST /api/knowledge/ingest/thread/{thread_id}`。 - 新增 `POST /api/knowledge/ingest/threads/batch`,支持批量扫描并沉淀历史线程。 - 新增 `POST /api/knowledge/ingest/search`,支持搜索和工具结果来源沉淀。 - 新增 `GET /api/knowledge/notes`。 - 新增 `GET /api/knowledge/notes/{note_id}`。 - 新增 `PUT /api/knowledge/notes/{note_id}`。 - 新增 `DELETE /api/knowledge/notes/{note_id}`。 - 新增 `POST /api/knowledge/search`,首版支持关键词/frontmatter/Markdown 内容检索。 - 新增 `POST /api/knowledge/export/graph`,生成 `wiki-export/graph.html` 和 `graph.json`。 - 前端新增“保存到知识库”按钮。 - 前端新增“批量导入历史线程”入口。 - 前端新增知识库列表、详情、编辑、搜索、删除/归档页面。 - 前端新增图谱页面,iframe 展示 `wiki-export/graph.html`。 - 知识库全局共享,不按用户隔离。 阶段一暂缓: - 向量检索。 - 自动合并重复知识。 - agent 回答前的向量 RAG 自动注入。 ### 阶段二:向量检索和 RAG 召回 目标:用户后续提问时,自动检索知识库并注入 agent 上下文。 范围: - 先实现 obsidian-wiki 原生 `wiki-query` 风格的分层检索: - `hot.md` - `index.md` - frontmatter - 相关正文片段 - 新增 Markdown 分块。 - 新增 embedding 生成与索引。 - 新增 `POST /api/knowledge/search`。 - 在 agent 调用前执行知识召回。 - 回答中展示引用的知识笔记和来源。 ### 阶段三:自动沉淀和知识治理 目标:聊天完成后自动判断是否值得沉淀,并支持去重、合并、编辑审核。 范围: - 后台任务队列。 - 价值判断:是否值得入库。 - 重复检测。 - 版本记录。 - 合并建议。 - 敏感信息过滤。 - 审核状态:draft、approved、archived。 ### 阶段四:图谱增强 目标:在首版 `graph.html` / `graph.json` 基础上增强实体、关系和交互能力。 范围: - 优先复用 obsidian-wiki `wiki-export` 输出。 - 直接生成/服务 `wiki-export/graph.html` 作为第一版图谱页面。 - 读取 `wiki-export/graph.json` 给产品自研图谱组件使用。 - 后续再做实体抽取、关系抽取和自定义图谱。 - `GET /api/knowledge/graph`。 - 前端图谱页面。 ## 7. 数据库设计 首版可使用当前项目已有数据库体系。字段名建议使用 snake_case。 ### 7.1 knowledge_notes 知识笔记主表。 ```sql CREATE TABLE knowledge_notes ( id VARCHAR(64) PRIMARY KEY, title VARCHAR(512) NOT NULL, summary TEXT, content_md LONGTEXT NOT NULL, vault_path VARCHAR(1024), source_type VARCHAR(64) NOT NULL, source_id VARCHAR(256), status VARCHAR(32) NOT NULL DEFAULT 'approved', confidence FLOAT DEFAULT 0, created_by VARCHAR(128), updated_by VARCHAR(128), created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` `source_type` 可选: - `thread` - `search` - `tool` - `file` - `manual` - `report` `status` 可选: - `draft` - `approved` - `archived` ### 7.2 knowledge_sources 知识来源表。 ```sql CREATE TABLE knowledge_sources ( id VARCHAR(64) PRIMARY KEY, note_id VARCHAR(64) NOT NULL, source_type VARCHAR(64) NOT NULL, thread_id VARCHAR(128), message_id VARCHAR(128), tool_name VARCHAR(128), title VARCHAR(512), url TEXT, snippet TEXT, raw_json LONGTEXT, created_by VARCHAR(128), created_at DATETIME NOT NULL ); ``` ### 7.3 knowledge_tags ```sql CREATE TABLE knowledge_tags ( id VARCHAR(64) PRIMARY KEY, name VARCHAR(128) NOT NULL, created_at DATETIME NOT NULL ); ``` ### 7.4 knowledge_note_tags ```sql CREATE TABLE knowledge_note_tags ( note_id VARCHAR(64) NOT NULL, tag_id VARCHAR(64) NOT NULL, PRIMARY KEY (note_id, tag_id) ); ``` ### 7.5 knowledge_entities 阶段五使用。 ```sql CREATE TABLE knowledge_entities ( id VARCHAR(64) PRIMARY KEY, name VARCHAR(256) NOT NULL, entity_type VARCHAR(64), created_at DATETIME NOT NULL ); ``` ### 7.6 knowledge_relations 阶段五使用。 ```sql CREATE TABLE knowledge_relations ( id VARCHAR(64) PRIMARY KEY, from_note_id VARCHAR(64), to_note_id VARCHAR(64), from_entity_id VARCHAR(64), to_entity_id VARCHAR(64), relation_type VARCHAR(128) NOT NULL, weight FLOAT DEFAULT 1, created_at DATETIME NOT NULL ); ``` ### 7.7 knowledge_embeddings 阶段三使用。如果使用外部向量库,此表只保存索引映射。 ```sql CREATE TABLE knowledge_embeddings ( id VARCHAR(64) PRIMARY KEY, note_id VARCHAR(64) NOT NULL, chunk_index INT NOT NULL, content TEXT NOT NULL, vector_id VARCHAR(256), created_at DATETIME NOT NULL ); ``` ## 8. Markdown Vault 设计 默认存储路径: ```text offline-backend-20260512/backend/data/knowledge/obsidian-vault/ ``` 也可以通过配置项指定: ```yaml knowledge: enabled: true provider: obsidian_wiki vault_dir: data/knowledge/obsidian-vault auto_ingest_enabled: false max_thread_messages: 80 ``` 必须兼容 obsidian-wiki 原生结构: ```text vault/ index.md log.md hot.md .manifest.json _meta/ taxonomy.md concepts/ entities/ skills/ references/ synthesis/ journal/ projects/ deerflow/ concepts/ references/ synthesis/ journal/ wiki-export/ graph.json graph.graphml cypher.txt graph.html ``` 页面分类遵循 `wiki-capture`: - `synthesis`:多步骤分析、方案、结论。 - `concepts`:概念、框架、模型。 - `references`:外部来源、搜索结果、文章资料。 - `synthesis` decision 类型:架构或设计决策。 - `journal`:完整会话摘要。 - `projects//...`:项目相关知识优先进入项目空间。 Markdown frontmatter 必须优先兼容 `wiki-capture`: ```markdown --- title: >- 知识标题 category: synthesis tags: [deerflow, knowledge-base, agent] sources: - conversation:2026-06-08 - thread:thread_id - message:message_id created: 2026-06-08T15:30:00+08:00 updated: 2026-06-08T15:30:00+08:00 summary: >- 一到两句话说明这页知识保存了什么。 provenance: extracted: 0.7 inferred: 0.2 ambiguous: 0.1 base_confidence: 0.82 lifecycle: draft lifecycle_changed: 2026-06-08 relationships: - target: "[[concepts/knowledge-graph]]" type: uses --- # 知识标题 ## Context 问题背景或触发场景。 ## Finding / Decision 沉淀后的知识本体。不要写成“用户问了什么,AI 回答了什么”的聊天摘要。 ## Reasoning 为什么成立、取舍是什么、不确定性在哪里。推断内容使用 `^[inferred]` 标记。 ## Implications 后续使用建议、风险、下一步。 ## Related - [[concepts/knowledge-graph]] - [[projects/deerflow/synthesis/product-knowledge-base]] ``` 写入任何页面后必须同步: - `index.md`:加入页面索引。 - `log.md`:追加 `CAPTURE` / `INGEST` / `QUERY` / `EXPORT` 记录。 - `hot.md`:更新近期活动摘要。 - `.manifest.json`:记录 source、hash、vault path、更新时间,用于去重和 delta。 ## 9. 后端接口设计 统一前缀: ```text /api/knowledge ``` ### 9.1 从线程沉淀知识 ```http POST /api/knowledge/ingest/thread/{thread_id} ``` 请求: ```json { "mode": "summary", "title": "", "status": "approved", "tags": ["DeerFlow"], "include_sources": true } ``` 字段说明: - `mode`: `summary` 或 `full` - `title`: 可选,空时自动生成 - `status`: `draft` 或 `approved` - `tags`: 用户手动附加标签 - `include_sources`: 是否解析工具/搜索来源 响应: ```json { "note": { "id": "kb_xxx", "title": "多智能体任务调度方案", "summary": "...", "source_type": "thread", "source_id": "thread_id", "vault_path": "threads/2026/06/xxx.md", "created_at": "2026-06-08T15:30:00+08:00" } } ``` ### 9.2 批量沉淀历史线程 ```http POST /api/knowledge/ingest/threads/batch ``` 请求: ```json { "limit": 100, "offset": 0, "status": "approved", "include_sources": true, "skip_existing": true } ``` 字段说明: - `limit`: 本次最多处理多少个线程。 - `offset`: 线程分页偏移。 - `status`: 生成知识的默认状态。 - `include_sources`: 是否解析工具/搜索来源。 - `skip_existing`: 是否根据 `.manifest.json` / source hash 跳过已沉淀线程。 响应: ```json { "ok": true, "processed": 80, "created": 52, "skipped": 28, "failed": 0, "items": [ { "thread_id": "thread_id", "note_id": "kb_xxx", "status": "created" } ] } ``` ### 9.3 从搜索结果沉淀知识 ```http POST /api/knowledge/ingest/search ``` 请求: ```json { "query": "LangGraph checkpoint", "results": [ { "title": "Example", "url": "https://example.com", "snippet": "..." } ], "thread_id": "optional_thread_id", "message_id": "optional_message_id" } ``` ### 9.4 手动创建知识 ```http POST /api/knowledge/notes ``` 请求: ```json { "title": "知识标题", "content_md": "# 知识标题\n\n正文", "tags": ["业务"], "status": "approved" } ``` ### 9.5 知识列表 ```http GET /api/knowledge/notes?keyword=&tag=&source_type=&status=&limit=20&offset=0 ``` 响应: ```json { "items": [ { "id": "kb_xxx", "title": "知识标题", "summary": "摘要", "tags": ["DeerFlow"], "source_type": "thread", "source_id": "thread_id", "updated_at": "2026-06-08T15:30:00+08:00" } ], "total": 1 } ``` ### 9.6 知识详情 ```http GET /api/knowledge/notes/{note_id} ``` 响应: ```json { "id": "kb_xxx", "title": "知识标题", "summary": "摘要", "content_md": "# 知识标题...", "tags": ["DeerFlow"], "sources": [ { "id": "src_xxx", "source_type": "thread", "thread_id": "thread_id", "message_id": "message_id", "title": "来源标题", "url": "https://example.com", "snippet": "..." } ] } ``` ### 9.7 更新知识 ```http PUT /api/knowledge/notes/{note_id} ``` 请求: ```json { "title": "新标题", "content_md": "# 新内容", "tags": ["新标签"], "status": "approved" } ``` ### 9.8 删除知识 ```http DELETE /api/knowledge/notes/{note_id} ``` 建议默认软删除:设置 `status = archived`。 ### 9.9 知识搜索 阶段三实现。 ```http POST /api/knowledge/search ``` 请求: ```json { "query": "如何做多智能体调度", "mode": "hybrid", "limit": 8 } ``` `mode` 可选: - `keyword` - `vector` - `hybrid` 响应: ```json { "items": [ { "note_id": "kb_xxx", "chunk_id": "chunk_xxx", "title": "多智能体任务调度方案", "snippet": "相关片段", "score": 0.87, "sources": [] } ] } ``` ### 9.10 知识图谱 阶段五实现。 ```http GET /api/knowledge/graph?keyword=&limit=100 ``` 响应: ```json { "nodes": [ { "id": "kb_xxx", "type": "note", "label": "知识标题" } ], "edges": [ { "id": "rel_xxx", "source": "kb_a", "target": "kb_b", "label": "related", "weight": 1 } ] } ``` ### 9.11 Export Obsidian Wiki Graph First implementation should reuse obsidian-wiki `wiki-export` compatible output. ```http POST /api/knowledge/export/graph ``` Response: ```json { "ok": true, "files": { "graph_json": "/api/knowledge/export/files/graph.json", "graph_html": "/api/knowledge/export/files/graph.html", "graph_graphml": "/api/knowledge/export/files/graph.graphml", "cypher": "/api/knowledge/export/files/cypher.txt" }, "stats": { "nodes": 12, "edges": 18 } } ``` ### 9.12 Serve Obsidian Wiki Export Files ```http GET /api/knowledge/export/files/{filename} ``` Allowed files: - `graph.json` - `graph.graphml` - `cypher.txt` - `graph.html` Frontend graph page first version: ```text iframe src="/api/knowledge/export/files/graph.html" ``` ## 10. 后端服务设计 建议拆分: ```text deerflow/knowledge/ __init__.py models.py repository.py obsidian_adapter.py skill_templates.py markdown_vault.py extractor.py sources.py manifest.py exporter.py chunking.py embeddings.py search.py ``` 职责: - `models.py` - Pydantic/领域模型。 - `repository.py` - 数据库读写。 - 不直接调用 LLM。 - `obsidian_adapter.py` - 核心适配器。 - 对外提供 `capture_thread`、`capture_search`、`list_notes`、`read_note`、`update_note`、`export_graph`。 - 输出必须兼容 obsidian-wiki vault。 - `skill_templates.py` - 读取或内置 `wiki-capture`、`wiki-query`、`wiki-export` 的关键模板。 - 后端 LLM 抽取 prompt 应以这些技能为准。 - `markdown_vault.py` - 负责生成 obsidian-wiki 兼容 frontmatter。 - 负责安全文件名。 - 负责写入/更新 Markdown 文件。 - 负责 wikilink 解析和基础 frontmatter 解析。 - `extractor.py` - 负责从 thread/search/tool 中抽取知识。 - 首版可用规则生成摘要,正式版可调用 LLM。 - LLM 输出必须映射为 `wiki-capture` 的类型:synthesis、concept、source、decision、session。 - `sources.py` - 负责归一化来源。 - 复用 `threads.py` 里的 reference normalize 逻辑时,建议抽公共函数,避免复制大段代码。 - `manifest.py` - 读写 `.manifest.json`。 - 记录 source hash,避免重复沉淀。 - `exporter.py` - 内置实现 obsidian-wiki `wiki-export` 等价逻辑。 - 生成 `wiki-export/graph.json` 和 `wiki-export/graph.html`。 - 前端图谱优先 iframe `graph.html`。 - `chunking.py` - Markdown 分块。 - `embeddings.py` - embedding 生成和索引写入。 - `search.py` - 关键词、向量、混合搜索。 ## 11. 知识抽取策略 抽取策略必须优先遵循 obsidian-wiki 的 `wiki-capture`: - 保存知识本体,不保存聊天流水账。 - 使用 declarative knowledge,不写“用户问了什么,AI 回答了什么”。 - 明确分类为 `synthesis`、`concept`、`source`、`decision`、`session`。 - 项目相关内容写入 `projects//...`。 - 推断内容使用 `^[inferred]`。 - 不确定或冲突内容使用 `^[ambiguous]`。 - 每篇笔记尽量包含至少 2 个 `[[wikilinks]]`。 从线程抽取时,只保留高价值内容: - 用户明确提问。 - 助手最终回答。 - 工具搜索结果。 - 被引用的来源。 - 生成的结论、方案、计划、代码设计。 过滤: - 空消息。 - 纯寒暄。 - 中间推理内容。 - 重复 token 流。 - 错误堆栈中无价值的噪声。 - 过长原文全文。 首版规则: 1. 读取 thread state 的 `messages`。 2. 按 human 消息切分 turn。 3. 找每个 turn 的最后一个有正文的 ai 消息。 4. 拼成沉淀上下文。 5. 自动生成标题: - 优先使用 thread title。 - 没有 title 时使用第一条用户问题的前 40 字。 6. 自动生成 summary: - 首版可截取或简单规则总结。 - 正式版用 LLM 生成结构化 JSON。 LLM 抽取推荐输出: ```json { "title": "知识标题", "summary": "摘要", "key_points": ["要点一", "要点二"], "actions": ["建议一"], "tags": ["标签"], "entities": [ {"name": "LangGraph", "type": "technology"} ], "relations": [ {"from": "LangGraph", "to": "checkpoint", "type": "uses"} ], "confidence": 0.82, "should_ingest": true, "reason": "包含可复用架构决策" } ``` ## 12. 前端页面设计 ### 12.1 路由 新增路由建议: ```text /page/knowledge /page/knowledge/:noteId ``` 如果必须放在工作台内,可放: ```text /page/workspace/knowledge ``` ### 12.2 页面结构 知识库主页面: ```text 顶部工具栏 - 搜索框 - 来源类型筛选 - 标签筛选 - 新建知识按钮 左侧/主区域 - 知识列表 - 标题 - 摘要 - 标签 - 来源类型 - 更新时间 右侧/详情区域 - Markdown 内容 - 来源列表 - 编辑按钮 - 删除/归档按钮 ``` ### 12.3 对话页入口 在聊天线程页面增加按钮: ```text 保存到知识库 ``` 交互: 1. 用户点击按钮。 2. 弹窗展示: - 标题输入框。 - 标签输入。 - 状态:草稿/正式。 - 是否包含搜索来源。 3. 调用 `POST /api/knowledge/ingest/thread/{thread_id}`。 4. 成功后 toast 提示。 5. 可点击进入知识详情。 ### 12.4 知识详情页 功能: - Markdown 渲染。 - 显示 frontmatter 中的标签、来源、更新时间。 - 来源区支持跳转: - thread 来源跳回原对话。 - url 来源打开外链。 - 编辑模式: - 标题。 - Markdown 内容。 - 标签。 - 状态。 ## 13. RAG 召回接入 阶段二再做,不建议首版强行接入。 召回策略优先复用 obsidian-wiki `wiki-query` 的分层检索,而不是直接上向量库: 1. 读取 `hot.md`,获取近期知识上下文。 2. 读取 `index.md`,用标题、摘要、标签筛候选页面。 3. 扫描 frontmatter:`title`、`tags`、`aliases`、`summary`、`tier`。 4. 只读取候选页面相关片段。 5. 必要时才读取全文。 6. 向量检索作为增强,不作为首个唯一检索方式。 推荐接入点: 1. 用户发送问题。 2. 后端进入 agent 运行前。 3. 调用 `KnowledgeSearchService.search(query, limit=5)`。 4. 将搜索结果转换为系统上下文: ```text 以下是产品知识库中与本问题相关的资料。回答时优先参考,若使用其中信息,请在回答中标注来源。 [知识 1] 标题 摘要/片段 来源:note_id / url ``` 注意: - 不要注入过多内容,建议限制 3-5 条。 - 每条只注入 snippet,不要注入整篇 Markdown。 - 必须携带来源 id,方便前端引用展示。 - 知识库为全局共享,检索所有已批准的公共知识。 ## 14. 权限与安全 必须实现: - 知识库为全局共享,不按用户隔离。 - 所有用户读取同一套 vault 和知识索引。 - 写入、更新、删除操作记录 `created_by` / `updated_by`,用于审计。 - Markdown 文件路径必须防止路径穿越。 - 文件名必须 sanitize。 - 删除默认软删除。 建议实现: - 自动沉淀前做敏感信息检测。 - 对 token、密钥、手机号、身份证等内容做脱敏。 - 提供“不要沉淀本次对话”的用户开关。 ## 15. 配置项 建议在 `config.yaml` 中新增: ```yaml knowledge: enabled: true provider: obsidian_wiki vault_dir: data/knowledge/obsidian-vault project_name: deerflow auto_ingest_enabled: false auto_ingest_min_chars: 300 max_thread_messages: 80 max_source_items: 20 export: enabled: true graph_html_enabled: true graph_json_enabled: true rag_enabled: false rag_limit: 5 query: use_hot_md: true use_index_md: true use_frontmatter_scan: true embedding: enabled: false provider: local model: "" ``` ## 16. 验收标准 阶段一验收: - 可以从一个已有 thread 生成知识笔记。 - 可以批量扫描历史线程并生成知识笔记。 - 搜索结果/工具结果能作为 sources 保存。 - 数据库中存在 `knowledge_notes` 记录。 - vault 中生成 Markdown 文件。 - `index.md`、`log.md`、`hot.md`、`.manifest.json` 会同步更新。 - 前端可以看到知识列表。 - 前端可以查看知识详情。 - 前端可以编辑标题、标签、状态和 Markdown 正文。 - 前端可以关键词搜索知识。 - 前端可以删除/归档知识。 - 前端可以打开图谱页面,iframe 展示 `wiki-export/graph.html`。 - 所有用户都能看到已批准的全局知识。 - 删除知识后列表不再显示。 阶段二验收: - `POST /api/knowledge/search` 能返回相关知识。 - agent 回答能使用知识库内容。 - 回答中能显示知识来源。 阶段三验收: - 可配置自动沉淀开关。 - 自动沉淀不会保存明显无价值寒暄。 - 重复内容不会无限新增。 - 用户可编辑和归档自动沉淀的知识。 ## 17. 推荐开发顺序 1. 创建后端数据模型和 repository。 2. 创建 `ObsidianWikiAdapter`,初始化 obsidian-wiki 兼容 vault。 3. 创建 Markdown vault 写入工具,同步 `index.md`、`log.md`、`hot.md`、`.manifest.json`。 4. 实现 `POST /api/knowledge/ingest/thread/{thread_id}`。 5. 实现 `POST /api/knowledge/ingest/threads/batch`。 6. 实现 `POST /api/knowledge/ingest/search`。 7. 实现 `GET /api/knowledge/notes` 和详情接口。 8. 实现 `PUT /api/knowledge/notes/{note_id}` 和 `DELETE /api/knowledge/notes/{note_id}`。 9. 实现 `POST /api/knowledge/search` 的关键词/frontmatter/Markdown 内容检索。 10. 增加 `POST /api/knowledge/export/graph`,生成并服务 `wiki-export/graph.html`。 11. 前端创建 `core/knowledge/api.ts`。 12. 前端实现知识列表、详情、编辑、搜索、图谱页面。 13. 对话页增加“保存到知识库”按钮。 14. 前端增加“批量导入历史线程”入口。 15. 补充基础测试。 16. 再进入向量 RAG、自动沉淀、自动合并阶段。 ## 18. 测试建议 后端测试: - 从 thread state 生成知识。 - 批量历史线程入库。 - 搜索/工具来源入库。 - 空 thread 返回合理错误。 - 任意可读取的 thread 都可沉淀到全局知识库;需要按现有 thread 权限判断是否可读取来源。 - Markdown 文件路径安全。 - 知识列表分页正确。 - 更新知识同步更新 vault 文件。 - 删除知识为软删除。 前端测试: - 知识列表加载态、空态、错误态。 - 搜索和筛选。 - 详情 Markdown 渲染。 - 知识编辑和保存。 - 图谱 iframe 页面。 - 批量导入历史线程入口。 - 保存到知识库弹窗。 - 保存成功后跳转详情。 手动测试: 1. 新建一轮对话。 2. 点击保存到知识库。 3. 打开知识库页面。 4. 查看生成的知识笔记。 5. 编辑标题和内容。 6. 批量导入历史线程。 7. 打开图谱页面。 8. 删除或归档知识。 ## 19. 给开发模型的任务提示词 可将下面提示词交给其他模型: ```text 请基于 frontend-web/docs/product-knowledge-base-dev.md 实现阶段一:首版完整交付。 要求: 1. 后端新增 /api/knowledge 相关接口。 2. 从 /api/threads/{thread_id}/state 读取 messages,生成知识笔记。 3. 新增独立 knowledge 模块,知识库相关能力都在该模块内实现。 4. 新增 ObsidianWikiAdapter,复用 ar9av/obsidian-wiki 的原生规范和技能思路。 5. 将知识元数据写入数据库,将 content_md 写入 obsidian-wiki 兼容 Markdown vault。 6. 写入后必须同步 index.md、log.md、hot.md、.manifest.json。 7. Markdown frontmatter 和正文结构参考 obsidian-wiki 的 wiki-capture 技能。 8. 前端新增知识库列表、详情、编辑、搜索、图谱页面。 9. 在聊天线程页面增加“保存到知识库”入口。 10. 增加批量导入历史线程入口。 11. 知识库为全局共享,不做 user_id 隔离;写入时记录 created_by / updated_by 作为审计。 12. 图谱第一版生成并服务 wiki-export 兼容的 graph.html/json。 13. 首版实现关键词/frontmatter/Markdown 内容搜索;向量 RAG 后续增强。 14. 遵循当前项目已有 FastAPI、SQLAlchemy、React、TanStack Query、UI 组件风格。 15. 完成后运行后端相关测试和前端 typecheck/build。 ``` ## 20. 风险与注意事项 - 知识库模块独立实现,相关能力都收敛在新增 `knowledge` 模块内。 - 不要另起一套与 obsidian-wiki 不兼容的 Markdown 结构。 - 不要忽略 `index.md`、`log.md`、`hot.md`、`.manifest.json`,这些是 obsidian-wiki 的关键原生资产。 - 不要让前端直接读服务器 Markdown 文件,应通过 API。 - 不要同步阻塞聊天流式响应,自动沉淀应后台执行。 - 不要保存完整工具 raw_json 到前端展示,详情页只展示必要字段。 - 不要把所有搜索结果无脑入库,应先关联来源,再由知识笔记引用。 - 首版不额外引入图数据库中间件,图谱优先使用 `wiki-export/graph.html` 和 `graph.json`。