主题
FDS-17 · B8 项目事实库(地基)
整个模块的地基:一个项目所有"已核实事实"的唯一真相库。做对了,"慢 / 不准 / 看不到出处 / 跨会对不上"一起解决。本章给到表结构与接口字段级。
1. 业务说明
- 是什么:一个数据库,存某项目里经校验或人确认过的事实——决策、风险、待办、里程碑、关键事实,每条带原文出处。
- 给谁/解决什么:下游(待办、跨会看板、下次开场、复盘)全部只读它,不再每次重啃录音/纪要——这是"又慢又不准"的根因被根除的地方。
- 不做会怎样:像现在一样,每个下游各自重新分析录音,结果互相对不上、慢、不可追溯。
2. 用户操作与界面
用户不直接操作事实库;它在背后被流水线写、被下游读。用户感知到的是:
- 在会议结果页/看板上看到的每条结论 → 实际是从事实库读的,可点开看出处。
- 改了纪要/业务规则 → 受影响的事实被标"待重算/待重新确认"(界面显示灰标),由人或流程处理。
3. 数据与接口(字段级)
主表 project_facts(一条 = 一个事实):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | uuid PK | 事实唯一 id |
| project_id | uuid, 索引 | 所属项目(隔离边界,所有查询强制带它) |
| meeting_id | uuid, 索引 | 来源会议 |
| kind | enum | decision/risk/action(待办)/milestone/fact |
| text | text | 标准化内容 |
| payload | jsonb | 类型特有字段(如 action: owner/due/status;risk: severity) |
| source_ref | jsonb | 出处:{file_id, char_start, char_end, speaker, ts}(回溯原文) |
| confidence | float | 抽取置信(低于阈值不直接入库,转 B7) |
| status | enum | proposed / confirmed / superseded / dropped |
| confirmed_by | uuid null | 人确认者(confirmed 时必填) |
| extract_version | text | 产出时的抽取规则版本(规则升级→失效依据) |
| content_hash | text | 上游(精修文本)指纹,上游变→失效依据 |
| version | int | 同一事实的修订序号(乐观锁) |
| supersedes_id | uuid null | 指向被它取代的旧事实(演进链) |
| created_at / updated_at / deleted_at | ts | deleted_at 非空=软删(可逆) |
辅助:project_fact_amendments(每次改动留痕:谁、何时、改前改后)、project_fact_links(跨会同一事项归并关系,B19 用)。 索引:(project_id, kind, status)、(project_id, meeting_id)、source_ref 上 GIN(按出处反查)、text 全文索引(检索;后续可加向量列)。
接口(acdm-backend 提供,技能经工具调用,不直连库):
POST /facts/commit:批量写入(事务);入参带 project_id、extract_version、content_hash、每条 source_ref;返回写入数。GET /facts/query:按 project_id + kind/status/owner/时间范围/关键词 精确查询;强一致(刚写完即可查到)。GET /facts/{id}/trace:取某条的原文出处定位(给"点回原文")。POST /facts/invalidate:把某会议/某上游 hash 关联的事实标 superseded(失效)。POST /facts/{id}/confirm…/soft-delete…/restore:人确认 / 软删 / 恢复。
4. 技术实现(分步)
- 写入:B6 校验过或 B7 确认过的条目,经
/facts/commit在一个数据库事务里批量写;每条必带 source_ref、extract_version、content_hash。 - 强一致:同步事务提交后才返回成功;下游
query立即能读到(不经任何异步摘要/缓存延迟)。 - 版本失效(对应原始需求"单向数据流+版本化"):
- 抽取规则升级 → 该规则版本下旧事实
status=superseded,触发受影响会议重抽。 - 上游精修文本变(纪要被人改)→ 比对 content_hash,不一致的事实标 superseded + 该会进重算队列。
- 抽取规则升级 → 该规则版本下旧事实
- 并发:同一事实改动用
version乐观锁(读时带 version,写时校验,不一致则拒绝并要求重读),不允许"最后写赢"丢数据。 - 隔离:所有读写接口强制 project_id;无 project_id 或越权直接拒绝(沿用项目现有权限校验)。
- 可逆:删除=软删(deleted_at),进回收站;恢复可用;物理清理走定期任务。所有写改入 amendments 留痕。
5. 技能 or 代码
全部代码(acdm-backend)。事实库是正确性、强一致、事务、隔离的载体——不允许做成技能让模型参与。技能只通过上面的接口读写。
6. 二开归类
🔴 从头自建(acdm-backend + 现有 PostgreSQL)。
- 为什么不复用 deer-flow 自带"记忆":它是把对话用模型摘成一段文字的 blob,不能按字段精确查询、写完要等异步处理不能马上读、并发会丢、按项目隔离也没接通——读了其真实实现确认不胜任。结论:个人偏好类记忆与"项目事实库"是两回事,后者必须自建。
- 复用项目已有的"可逆存储"机制做软删/回收站/留痕,不重造。
7. 与人机协同模型关系
事实库 = 模型里的项目工作台(项目级上下文/账):人配的规则、AI 产出并经确认的事实都在这里;任务卡片(待办/确认)和任务流(流水线)都围着它转。它是"单一真相",杜绝多处数据打架。
8. 验收(可证伪)
- 可用:一场会跑完,事实写入后立即能按 project_id+kind 查到;每条都能
trace到原文位置。 - 可用:并发两次改同一事实,后者因 version 不符被拒,无数据丢失。
- 好用:改纪要后,关联事实在下次读取时为 superseded 且该会进重算;软删的事实可从回收站恢复。
- 好用:随机抽 20 条,trace 出来的原文与内容一致(配合 B6)。
9. 现状
没有。当前无此库;现状是各下游重跑会议聚合、结果落在缓存/临时态、互相对不上且不可精确追溯。本章即从零建。
10. 风险与取舍
- 风险:事实库 schema 设计不当→后续改表代价大。取舍:payload 用 jsonb 容纳类型差异,核心可查字段(project/kind/status/owner/source)固定成列+索引。
- 风险:版本失效过于激进→频繁重算贵。取舍:失效只标记不立即重算,重算入队按需/批量;未变部分不动。
- 风险:向量检索一步到位过重。取舍:先全文索引拿大头,向量列后置(B19 再上)。
地基完成。接下来回到 FDS-10 起按原子业务顺序逐章(B1→…),每章读写都对接本库接口。