1244 lines
31 KiB
Markdown
1244 lines
31 KiB
Markdown
# 产品内知识库沉淀系统开发文档
|
||
|
||
## 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/<project-name>/...`:项目相关知识优先进入项目空间。
|
||
|
||
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/<project-name>/...`。
|
||
- 推断内容使用 `^[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`。
|