后端: - 工作流推进链(D-03):advance_task/状态机/闸门走 df-nodes Node trait,conditions 条件引擎扩展 - 想法评估闭环:启发式评分+对抗评估,df-ideas/scoring + df-storage/idea_eval_repo + idea 前端打通 - 全局事件数据总线:df-ai/context+context_helpers+augmentation 跨模块解耦 - AI planner/plan_hint/intent:aichat B 路线并行多轮基础 - patch_file 加固(TD-03/04):读改写整体锁防 lost update,expected_hash 合约闭环 - 压缩超时兜底(F-15 卡死根治) - F-09 多会话并发:LlmConcurrency per-conv + streamingGuard 前端守护 + verify 脚本 - 知识注入 DRY/skills/audit 扩展 清理: - aichat 技术债(误报 allow/死导入/过时注释 30 项) - URGENT.md 删除(11 项加急全解决/迁 todo) - 文档整理(todo/待决策/待审查/ARCHITECTURE/INDEX + 总线/技术债审查新文档)
12 KiB
知识库模块
创建: 2026-06-13 | 阶段: Tier 1 已实现
概述
知识库是 DevFlow 的"共享记忆层",被动积累 AI 对话中产生的可复用经验,供后续对话注入使用。外部工具(Claude Code / CodeX / Cursor)可通过相同 IPC 接口读写,内外零差异。
实现状态
| 功能 | 状态 |
|---|---|
| candidate→published 状态机 | ✅ Tier 1 |
| 手动录入(Knowledge.vue) | ✅ Tier 1 |
| AI 自动提炼(对话完成后) | ✅ Tier 1 |
| LIKE 关键词检索 + 注入 system prompt | ✅ Tier 1 |
| 审核收件箱(人工门控) | ✅ Tier 1 |
| 向量 embedding + 混合检索 | ✅ Phase 5.5(开关控制,默认关) |
| ai_node prompt 注入 | ⬜ Tier 2 |
| MCP 对外 API | ⬜ Tier 2 |
状态机
candidate ──→ pending_review ──→ published ──→ archived
│ │ │
└────────────────┴───────────────┘
(可直接到 archived)
- AI 提炼只产 candidate,绝不自动 published(人工门控)
knowledge_archive:软删除(status=archived),不物理删除
知识类型(KnowledgeKind)
7 种:pitfall(踩坑)/ review_rule(审查规则)/ prompt_template(Prompt 模板)/ architecture_pattern(架构模式)/ diagnosis(诊断知识)/ deployment_note(部署经验)/ workflow_optimization(工作流优化)
IPC 命令(11 个)
| Command | 说明 |
|---|---|
knowledge_list(status?) |
列表,默认仅 published(library 纯已发布,F-260616-02 决策 a);显式传 status 按该状态过滤(含 archived) |
knowledge_get(id) |
单条查询 |
knowledge_search(query, kind?, limit?) |
LIKE 检索,默认 top-3,limit.clamp 上限 20(min(20)) |
knowledge_create(input) |
创建(status=candidate) |
knowledge_update_status(id, status) |
状态转换(含合法矩阵校验) |
knowledge_record_reuse(id) |
reuse_count +1 |
knowledge_list_candidates() |
待处理收件箱(candidate+pending_review,按 confidence 排序) |
knowledge_archive(id) |
软删除 |
knowledge_get_config() |
读取 KnowledgeConfig |
knowledge_save_config(config) |
保存 KnowledgeConfig |
knowledge_extract_now() |
手动触发提炼(ManualOnly 模式) |
KnowledgeConfig
pub struct KnowledgeConfig {
pub auto_extract: bool, // 提炼总开关,默认 true
pub trigger_mode: ExtractTrigger, // on_complete | manual_only(OnIdle 已下线,见 KP-2)
pub min_messages: u32, // 守卫:最少消息数,默认 4
pub auto_inject: bool, // 聊天注入开关,默认 true
pub vector_enabled: bool, // 向量检索开关,默认 false
pub embedding_provider_id: Option<String>, // 仅 openai_compat 类型
pub embedding_model: Option<String>,
}
存储:AppState.knowledge_config: Arc<Mutex<KnowledgeConfig>> 为内存真相源,并通过 SettingsRepo KV 表(key=df-knowledge-config)持久化;knowledge_save_config 落库、AppState::init reload 恢复(KP-1 已修复)。
检索与注入
LIKE 检索(默认)
search(query, kind, limit=3) → WHERE title LIKE ? OR content LIKE ? → ORDER BY reuse_count DESC
混合检索(vector_enabled=true)
三层降级链:
- 开关关 → 纯 LIKE
- embed 调用失败 → 纯 LIKE
- 正常 → 双信号排序(同时命中 LIKE+向量 cos≥0.3 > 仅 LIKE > 仅向量 cos≥0.3)
嵌入时机:知识发布时(不在 candidate 阶段浪费 embed 调用),spawn_embedding_for_knowledge fire-and-forget。
注入位置
system prompt 头部([知识库上下文] --- [技能指令] --- [原始 system prompt]),仅 auto_inject=true 时生效。
AI 自动提炼流程
run_agentic_loop正常退出 →maybe_spawn_extraction()守卫检查- 守卫:
auto_extract=true+messages.len() >= min_messages tauri::async_runtime::spawn后台执行,不 await(不阻断聊天)- 取最后 6 条 user/assistant 消息 → 构造 JSON schema prompt → LLM
complete() serde_json::from_str<Vec<ExtractedItem>>解析,失败整批丢弃(warn 不报错)- 逐条写
knowledges(status=candidate,source_ref="conv:{id}")
矛盾知识处理
不做结构层消歧,在内容和 tags 中自述限制范围。检索时两条知识都可能返回,由 LLM 上下文理解取舍。
外部工具访问(规划)
Tier 1+ 目标:MCP Shell 封装(mcp-server 转发 IPC),外部工具使用逻辑与内部零差异:
- 外部写入:走 candidate → 人工审核流程
- 外部读取:
knowledge_search/knowledge_list(published)
相关文档
- df-storage 存储层 — knowledges 表结构 + 向量工具函数
- df-ai AI 集成模块 — hybrid_search / generate_embedding / extract
- 功能决策记录 — 检索方案演进决策
已知问题(2026-06-16 审查)
来源:全量源码逐行审查(knowledge.rs / knowledge_inject.rs / knowledge_timeline.rs / stores/knowledge.ts / Knowledge.vue / agentic.rs / commands.rs / state.rs)
修复进度汇总(2026-06-21):
- ✅ 已修复:KP-1 配置持久化 / KP-2 OnIdle 下线;跨审查项 R-P1-4
build_provider统一工厂(secret::build_provider_for)、CR-28 error 通道(AiError emit 覆盖 build_provider_for Err 分支)、CR-29 审批等待态竞态(B-260615-26 guard disarm + try_continue generating 复位重检)。- 🔧 本 workflow 修复中:KP-3(try_continue 知识注入)/ KP-5(编辑生命线事件)/ KP-6(嵌入失败重试/标记)。
🔴 P0 严重
KP-1: KnowledgeConfig 不持久化 — 重启丢失全部配置 ✅ 已修复
状态:已修复(P0 设置走查-2026-06-21)。
knowledge_save_config/knowledge_get_config现读写SettingsRepoKV(key=df-knowledge-config,JSON 序列化);AppState::init增加reload_knowledge_config恢复。下方原文保留供溯源。
- 位置:
state.rs:208初始化 +knowledge.rs:knowledge_save_config - 现象:
knowledge_save_config仅写入内存Arc<Mutex<KnowledgeConfig>>,未落库。应用重启后AppState::init永远用KnowledgeConfig::default() - 影响: 用户配置的向量检索 provider、提炼参数等关闭应用后全部丢失。系统已有
app_settingsKV 表和SettingsRepo可用,但未接入 - 修复方向:
knowledge_save_config/knowledge_get_config读写SettingsRepo(key=knowledge_config,value=JSON)
KP-2: OnIdle 触发模式完全未实现 — 配置项为死代码 ✅ 已修复(下线)
状态:已修复(OnIdle 下线)。
ExtractTrigger仅保留OnComplete/ManualOnly两变体,OnIdle变体与idle_timeout_ms字段已从state.rs移除(idle_timeout_ms在src-tauri内零残留)。trigger_mode取值同步收敛。下方原文保留供溯源。
- 位置:
state.rs定义ExtractTrigger::OnIdle+idle_timeout_ms;knowledge_inject.rs:maybe_spawn_extraction - 现象:
maybe_spawn_extraction仅检查trigger_mode == OnComplete,OnIdle与ManualOnly都直接return Ok(())。idle_timeout_ms在整个src-tauri中零引用 - 影响: 用户选择
OnIdle模式后,知识提炼永远不会触发(与 ManualOnly 行为相同但无任何提示) - 修复方向: 要么实现 idle 定时器(tokio::time::interval 轮询 AiSession 最后活动时间),要么移除 OnIdle 变体并在前端隐藏该选项
KP-3: 审批恢复循环路径缺失知识注入 🔧 本 workflow 修复中
状态:本 workflow 修复中。
try_continue_agent_loop(agentic/mod.rs)现已在续跑轮重建 system prompt 时调用build_knowledge_context注入知识库上下文(参考代码 :1420-1444 区段注释)。下方原文保留供溯源。
- 位置:
agentic.rs:try_continue_agent_loopvscommands.rs:ai_chat - 现象:
ai_chat首次消息时调用build_knowledge_context注入 system prompt;try_continue_agent_loop(审批通过后恢复循环)仅调用build_system_prompt,未调用build_knowledge_context - 影响: 对话经历工具审批流程后恢复时,system prompt 中不包含任何知识库上下文,AI 在多轮工具调用场景下丢失经验注入
🟡 P1 中等
KP-4: 前端搜索只能搜到 published 知识
- 位置:
knowledge.rs:knowledge_search→KnowledgeRepo::search(底层固定WHERE status='published') - 现象: 前端搜索栏调用链
store.search()→knowledgeApi.search()→ IPC →repo.search(),底层 SQL 硬编码status='published' - 影响: 知识库 Tab 列表加载的是
list_non_archived()(含 candidate/pending_review/published),但搜索只能命中 published,导致列表显示条目数 > 可搜索条目数,体验矛盾 - 修复方向: 前端搜索走独立的
knowledge_list+ 前端过滤,或后端新增search_all_status()方法供前端使用
KP-5: 编辑操作缺失生命线事件 🔧 本 workflow 修复中
状态:本 workflow 修复中。 计划在
knowledge_timeline.rs新增EVENT_UPDATED+KnowledgeTimeline::record_updated(),并接入knowledge.rs:knowledge_update(:375-411)。下方原文保留供溯源。
- 位置:
knowledge.rs:knowledge_update - 现象:
knowledge_create有record_created,knowledge_update_status有record_status_change,但knowledge_update(编辑 title/content/tags 等)无任何 Timeline 调用 - 影响: 知识被编辑修改后,生命周期时间线中不显示编辑记录,审计追踪存在断档
- 修复方向: 新增
EVENT_UPDATED事件类型 +KnowledgeTimeline::record_updated()方法
KP-6: 嵌入生成失败无重试/标记 — 可能永久无向量索引 🔧 本 workflow 修复中
状态:本 workflow 修复中。 计划在
knowledge_inject.rs:spawn_embedding_for_knowledge(:91-118)增加失败标记/重试,配合migrations.rs(knowledges 表)embedding IS NULL补偿。下方原文保留供溯源。
- 位置:
knowledge_inject.rs:spawn_embedding_for_knowledge - 现象: 发布时 fire-and-forget 生成嵌入,失败只
warn log,无重试机制、无失败标记 - 影响: provider 临时不可用(网络抖动/API 限流)时该知识永远不会获得向量嵌入,即使后续 provider 恢复。混合检索中该条目向量信号永久缺失
- 修复方向: 可选方案:(a) 定期补偿任务扫描
published AND embedding IS NULL;(b) 前端详情页显示嵌入状态并提供"重新生成"按钮
KP-7: 前端 updateStatus 后仅本地移除 — 不刷新列表
- 位置:
stores/knowledge.ts:updateStatus - 现象: 发布/拒绝/归档操作后仅
filter移除本地数组中的条目,不重新loadList()/loadCandidates() - 影响: 状态变化后需手动刷新才能看到最新列表。若其他路径(如 AI 提炼)并发写入候选列表,本地状态会进一步偏离
🟢 P2 低优先级
KP-8: 搜索后分类筛选状态丢失
- 位置:
Knowledge.vue:onSearchInput - 现象: 搜索框清空时触发
store.loadList(),但不恢复之前的activeKind分类筛选状态
KP-9: knowledge_search limit 硬限 3 条
- 位置:
knowledge.rs:knowledge_search→.min(3) - 现象: 即使传入
limit=10也只返回最多 3 条。Tier 1 内部合理,但 Tier 2 MCP 对外开放后可能受限
KP-10: 矛盾知识无消歧机制
- 位置: 模块设计层面(文档已记录此决策)
- 现象: 两条矛盾知识可能同时返回,完全依赖 LLM 上下文理解取舍。当前 top-3 限制降低了冲突概率,但随知识积累会逐渐显现