- 无人值守长任务设计定稿,含效率与可观测补遗 - u-relay wire 协议规格与五项评估结论 - 新能力引入评估纪律五项清单 - todo 销账与狗粮短板分析登记
91 lines
6.6 KiB
Markdown
91 lines
6.6 KiB
Markdown
# 跨会话召回最小闭环 · 设计(2026-10-04)
|
||
|
||
> ✅ 拍板通过(2026-10-04,3/3 按建议:B1 mention 唯一才启用/B2 软排序/B3 新增 scoped 方法;见 [拍板集](../滚动规范/拍板集-2026-10-04.md))
|
||
|
||
> 来源:todo.md「P1 跨会话召回最小闭环(项目级记忆+会话结束提炼进知识库,source_project 已有字段未用)」。
|
||
> 勘察结论(2026-10-04 现场核实,以源码为准):
|
||
> - 会话内自动提炼链已存在:`knowledge_inject.rs` `extract_knowledge_from_conversation`(user/assistant 过滤+`KNOWLEDGE_EXTRACT_WINDOW` 窗口+JSON 提炼+candidate 批量插入)+ `EXTRACT_WATERMARKS` 水位防重 + `conv(cid).knowledge_extracted` 哨兵 + `trigger_extraction_now` 手动强制。
|
||
> - `source_project` 字段在**主仓存储层零使用**:仅 `idea_repo.rs` 列定义/INSERT/UPDATE 贯通,`idea_repo.rs:949` 注释自证「source_project/source_ref 等元字段未被使用却仍随每行读出」。检索侧 `search_keywords`(idea_repo.rs:699)无项目过滤。
|
||
> - 注入点:`knowledge_inject.rs:622 inject_knowledge_into_prompt`(`search_keywords(keywords, include_candidates, limit)`,无项目维度)。
|
||
> - 会话→项目关联:`ai_conversations` 表**无 project_id 列**(V4 仅补 archived、V33 pending_approvals、V44 origin、V45 boundary_json);项目归属当前只能靠会话内 mention/`boundary_json`/`@项目` enrichment 间接推断。
|
||
> - candidate→published 机制已通(自动晋升 + knowledge_promote 工具 + V43 存量迁移 854 条),**跨会话可见性**只欠「published 参与检索注入」+「项目维度过滤」两环。
|
||
|
||
## 1. 目标与非目标
|
||
|
||
**目标(最小闭环)**:
|
||
1. 会话结束(AiCompleted 收敛点)自动触发提炼时,把当前会话**归属项目**写入产出知识的 `source_project`;
|
||
2. 知识注入(`inject_knowledge_into_prompt`)按**当前项目优先**:同项目知识加权/前置,跨项目知识仍可召回但不淹没;
|
||
3. 形成闭环:会话 A 的踩坑 → candidate → 晋升 published → 会话 B(同项目)注入时优先命中。
|
||
|
||
**非目标(本期不做)**:
|
||
- 不做会话↔项目的强绑定 schema 变更(不加 `ai_conversations.project_id` 列)——归属用**弱推断**(见 §3.1),避免迁移风险;
|
||
- 不动 candidate 晋升策略(C3 已拍板项);
|
||
- 不做向量检索(embedding 现状 1033 条全 NULL,另线);
|
||
- 不做 UI 变更(Knowledge 页项目筛选留后续)。
|
||
|
||
## 2. 核心取舍:项目归属从哪来
|
||
|
||
会话本身不存 project_id。归属来源三选,按可靠性排序:
|
||
|
||
| 来源 | 可靠性 | 实现成本 | 结论 |
|
||
|---|---|---|---|
|
||
| a. `boundary_json`(V45 无人值守边界)含项目路径 | 高(显式绑定) | 低(已落库) | ✅ 首选:有则用 |
|
||
| b. 会话消息中的 `@项目` enrichment / mention 记录 | 中(用户显式引用过) | 中(解析消息) | ✅ 次选:回退 |
|
||
| c. `ai_conversations` 加 project_id 列 | 高但侵入 schema | 高(迁移+全链) | ❌ 本期不做 |
|
||
|
||
**设计决策 D1(建议拍板)**:归属采用 a→b 两级弱推断,都不命中则 `source_project = NULL`(全局知识,不过滤)。这样零 schema 变更,且与「无人值守长任务」边界模型(boundary 已带项目上下文)天然对齐。
|
||
|
||
**提炼函数签名扩展**(knowledge_inject.rs 内,不新建文件):
|
||
|
||
```
|
||
async fn resolve_source_project(db, conv_id) -> Option<String>
|
||
// 1. 读 ai_conversations.boundary_json → 解析 project_path → 反查 projects 表 path 匹配 → id
|
||
// 2. 回退:读最近 N 条消息找 "[项目:xxx]" enrichment 标记 → 反查 → id
|
||
// 3. 皆无 → None
|
||
```
|
||
|
||
候选插入处(`extract_knowledge_from_conversation` 内 INSERT 前)把 `source_project = resolve_source_project(...)` 赋上。
|
||
|
||
## 3. 注入侧:项目维度过滤
|
||
|
||
**设计决策 D2**:注入不做硬过滤(`WHERE source_project = ?` 会把同问题跨项目通用知识挡死),改**软排序**——SQL 层 `search_keywords` 增加可选 `project_id` 参数:
|
||
|
||
```
|
||
ORDER BY (CASE WHEN source_project = ?1 THEN 0 ELSE 1 END), reuse_count DESC, ...
|
||
```
|
||
|
||
- 同项目知识排前(limit 截断时优先保留);
|
||
- `source_project IS NULL`(全局知识)视为第二档但优于异项目:`(CASE WHEN source_project = ?1 THEN 0 WHEN source_project IS NULL THEN 1 ELSE 2 END)`;
|
||
- `inject_knowledge_into_prompt` 调用前同样走 `resolve_source_project`(此时是当前活跃会话)取 project_id 传入;
|
||
- `knowledge_search` 工具(LLM 显式调用)暂不加项目参数——LLM 不知道当前 project_id,靠注入侧自动带。
|
||
|
||
**接口改动面**:
|
||
- `df-storage/crud/idea_repo.rs`:`search_keywords(&keywords, include_candidates, limit)` → 增参 `project_id: Option<&str>`(或新方法 `search_keywords_scoped`,保旧签名给 MCP 等外部调用方,内部转调);
|
||
- `knowledge_inject.rs` 两个调用点(:423 检索、:622 注入前置);
|
||
- `knowledge.rs` 工具(tools/knowledge.rs)不动。
|
||
|
||
## 4. 闭环验证与防劣化
|
||
|
||
| 风险 | 对策 |
|
||
|---|---|
|
||
| 提炼重复(每会话产相似 candidate 洪水) | 已有水位+哨兵;新增:插入前按 `title` 相似度(`search_keywords` 查同 title 命中即跳过或 `reuse_count+1`)——复用现有检索,零新机制 |
|
||
| 弱推断错误归属(张冠李戴) | 只在高置信(boundary 显式路径)时写 source_project;mention 回退可拍板是否启用(D1-b) |
|
||
| 注入 token 膨胀 | limit 不变,软排序只改顺序不增量 |
|
||
| 存量 967 条 candidate/907 published 无 source_project | 不回填(NULL=全局,行为正确);增量自然带项目 |
|
||
|
||
**验收**:
|
||
1. 新会话提及某项目 → 完成后提炼的 candidate `source_project` 非空且指向该项目;
|
||
2. 同项目新会话注入时该知识(晋升后)排在异项目知识前;
|
||
3. 无项目会话(source_project=NULL)注入行为与现状逐字一致(回归门);
|
||
4. `cargo test -p df-storage -p df-ai` 全绿 + search_keywords 新旧签名编译兼容。
|
||
|
||
## 5. 拍板点(3 项)
|
||
|
||
- **拍板1(D1-b)**:mention 回退推断是否启用?建议启用但仅当会话中项目 mention ≥1 次且唯一(多项目 mention 不猜,置 NULL)。
|
||
- **拍板2(D2)**:注入软排序 vs 硬过滤?建议软排序(理由见 §3)。
|
||
- **拍板3**:`search_keywords` 改签名(breaking,内部 crate)vs 新增 scoped 方法?建议**新方法**(df-mcp 等外部链路零影响)。
|
||
|
||
## 6. 工作量估算
|
||
|
||
约 1 天:resolve_source_project(2h)+ search_keywords_scoped + 两调用点接线(3h)+ 去重跳过(1h)+ 单测(2h)。
|