主题
FDS-19 · B10 跨会汇总与项目看板
打开一个项目,一屏看到这个项目所有会议汇总后的决策、风险、里程碑、待办;同一件事跨多场会议怎么一步步变化、哪个风险反复出现。看板只读项目事实库(FDS-17),不重啃录音/纪要。本章的命门:跨会"算不算同一件事"必须靠实体消歧 + 语义相似判断(谁是同一个人、哪两条说的是同一件事),不能像现在这样只看两场会开会日期挨得近——那是假的"智能"。
1. 业务说明
是什么:项目级的一张汇总看板。一个项目开了 N 场会,每场会都被前面的流水线抽过决策/风险/里程碑/待办并核实进了事实库(FDS-14→FDS-17)。B10 做的事是把这 N 场会的事实横着拼起来给人看:这个项目到今天总共定了哪些决策、还压着哪些风险、里程碑走到哪一步、待办谁欠着,以及——同一件事在多场会里是怎么演变的。
几个关键名词先用人话说清:
- 跨会汇总:不是把每场会的纪要叠在一起,而是把"散落在不同会的、其实是同一件事"的条目认出来、串成一条线。例:3 月 5 日会上提"接口联调有风险",3 月 12 日会上说"联调风险还在、已升级",3 月 26 日会上说"联调已通过"——这是同一个风险的三次状态,要串成一条演进链,而不是三条互不相干的风险。
- 实体消歧:判断不同说法指的是不是同一个对象。人:"张总 / 张三 / 老张"是同一个人;事:"对接 ERP 接口""ERP 联调""那个接口的事"可能是同一件事。消歧错了,跨会就会把两件事当一件(或把一件事拆成两件)。
- 语义相似:两句话字面不一样但意思相近的程度(靠把文本转成向量再算距离,向量越近越像)。它是判断"是不是同一件事"的主力依据之一。
- 演进链:同一事项按时间排好的状态序列(提出 → 升级 → 收敛 → 关闭),配出处,能点回每一场会的原文。
给谁、解决什么:给项目经理和管理层。现在的痛点是——想知道"这个项目所有会加起来到底定了啥、还有什么风险没了",得自己翻一场场会的纪要在脑子里对;而且同一件事在不同会里换了说法,人会对不上、系统更对不上。B10 把"项目级的账"一屏算清,并且这笔账是站内闭环:决策/风险/待办都在项目工作台里看、确认、追,不依赖任何外部平台。
不做会怎样:就是现状(见 §9)——有一个跨会聚合在跑,但它认"是不是同一件事"实际上只按两场会的开会日期挨不挨得近算,实体消歧和语义相似两条主依据都被关掉了。结果:换个说法的同一风险被拆成多条、不相干但日期接近的两件事被强行归并,看板上的"跨会智能"是近似失效的错觉。管理层据此判断项目,等于看一份对不上的账。
2. 用户操作与界面
用户主要是"看",少量是"纠错"(把系统认错的归并关系掰回来,纠错本身走站内确认,见 FDS-16)。
界面信息架构定四块,一屏内可切:
- 四象限总览:决策 / 风险 / 里程碑 / 待办,四块并排。每块是该项目全部会议汇总去重后的当前态(不是某一场会的)。风险块按严重度+是否反复排序;待办块可一键跳 FDS-18 待办面板。
- 演进时间线:点任一事项,右侧展开它的演进链——按时间排的状态点(提出/升级/收敛/关闭),每个点标来自哪场会、可点回原文出处。这是"同一件事怎么变的"的主视图。
- 反复风险高亮:单独一条带,把"在 ≥2 场会里反复出现/反复未关闭"的风险挑出来置顶标红,旁注"已反复 N 次、最近一次在某会"。这是管理层最该先看的。
- 按负责人视图:切换成以人为轴,看每个人名下跨所有会的待办/决策跟进项,谁是瓶颈一眼看出。
交互约束:看板只读事实库,用户在看板上不能直接改事实;要纠正归并(把系统串错的演进链拆开、或把该串的合上)走站内确认任务,由代码侧落库并留痕(FDS-16/17),保证可逆可追溯。
3. 数据与接口(字段级)
B10 自己不新建事实表——事实都在 FDS-17 的 project_facts。B10 新增的只有"跨会归并关系"这一层,即 FDS-17 已预留的 project_fact_links,以及一组只读取数/装配接口。
project_fact_links(跨会同一事项归并关系,FDS-17 预留,本章定义其字段):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | uuid PK | 关系 id |
| project_id | uuid, 索引 | 项目隔离边界(所有查询强制带) |
| group_key | uuid, 索引 | 同一事项的归并组标识(同组=被判定为同一件事) |
| fact_id | uuid, 索引 | 指向 project_facts.id(组里的一条) |
| kind | enum | 与 fact 同(decision/risk/milestone/action;同组必同 kind) |
| relation | enum | same(同一事项)/ evolves_from(由前一条演进而来) |
| order_no | int | 组内时间序(装演进链用,按来源会议时间定) |
| match_basis | jsonb | 判定依据快照:{entity_overlap, semantic_sim, time_proximity, decided_by}(可解释、可复核) |
| confidence | float | 归并置信(低于阈值不自动归并,转人工确认) |
| status | enum | proposed / confirmed / rejected(人纠错后置 rejected,组重算) |
| created_at / updated_at / deleted_at | ts | deleted_at 非空=软删(可逆) |
一个
group_key把"被判定为同一件事"的多条 fact 拴在一起;order_no给出时间顺序;relation=evolves_from标出"这条是上一条演进来的",装出演进链。match_basis把"凭什么判它们是一件事"的三项依据存下来可复核——这是和现状"黑箱按日期"最大的区别。
接口(acdm-backend 提供;读走 FDS-17 GET /facts/query,B10 在其上加汇总/装配):
GET /projects/{pid}/board:看板主接口。一次返四象限(各 kind 汇总去重后的当前态)+ 反复风险高亮列表 + 计数。强一致(读 FDS-17,刚写完即见)。GET /projects/{pid}/board/evolution?fact_id=…:取某事项的演进链(按group_key取同组,按order_no排,每条带source_ref供回原文)。GET /projects/{pid}/board/by-owner:按负责人聚合的跨会跟进项。POST /projects/{pid}/fact-links/recompute:对项目(或指定 kind)重算归并关系(规则/版本变、或人纠错后触发;写project_fact_links,旧关系软删留痕)。POST /fact-links/{id}/split…/merge:人工纠错入口,不直接改库,生成站内确认任务(FDS-16),确认后由代码落库并 recompute 受影响组。
与技能的契约:技能(语义关联判断/叙述,见 §5)不直连库,只通过上面接口和一个"关联候选评判"工具被调用;判不准/冲突的不自己拍板,标存疑交 FDS-16。不接飞书,通知走站内(项目工作台/待办面板)。
4. 技术实现(分步)
把一个项目所有会的事实汇总成看板,核心是正确地归并(谁和谁是同一件事) + 正确地装配(串成链/去重/排序)。分七步:
- 取数(代码):从 FDS-17
GET /facts/query按project_id拉该项目全部status=confirmed/proposed的事实,按 kind 分桶。强制带 project_id 做隔离;只读,不重啃录音。 - 生成关联候选(代码):对同 kind 的事实两两配对,算三项依据——
- 实体消歧重叠:把每条事实里出现的人/事/系统先归一到统一标识(同一个人不管叫"张总/张三"都归一个 id),再算两条的实体集合重叠率;
- 语义相似:把两条事实文本转向量算余弦相似度(意思像不像);
- 时间接近:两条来源会议的日期差(只作次要权重,绝不单独定生死)。 综合分 = 0.6×实体重叠 + 0.2×语义相似 + 0.2×时间接近(权重示意,可调),低于阈值的对直接丢,不进候选。
- 同义仲裁(技能):候选里"分数在边界、字面差得多但疑似同一件事"的(典型:换了说法的同一风险),交关联判断技能用语言理解判定"是不是同一件事";技能给判定+一句理由,不自己写库。判不准的标存疑 → FDS-16 派人确认。
- 成组与装链(代码):确认是同一事项的,分配同一
group_key写project_fact_links;组内按来源会议时间定order_no,相邻两条按"后者是否前者状态推进"标relation=evolves_from,装成演进链。match_basis存下三项依据快照(可复核)。 - 去重与取最新(代码):同组里被取代的旧态(FDS-17
supersedes_id/status=superseded)在四象限只显示当前态,历史进演进时间线;同义重复条目折叠成一条,避免看板把"换了说法的同一件事"重复罗列。 - 反复风险识别(代码):对 kind=risk 的组,统计"跨 ≥2 场不同会议出现 / 长期未关闭"的,打"反复"标并计次,喂给高亮带。这是按归并组算,不是按日期凑。
- 叙述生成(技能):看板顶部"本项目跨会概述"(几句话:定了哪些大决策、哪些风险反复、里程碑进度、谁的待办积压)由叙述技能基于已装好的结构化数据生成,只组织语言、不下与数据矛盾的结论。
- 失效联动(代码):上游纪要被改/抽取规则升级 → FDS-17 把相关事实标 superseded → 触发受影响
group_keyrecompute,看板下次读自动反映,不展示过期归并。
单向数据流:唯一真相在 FDS-17;B10 的归并关系是它的派生物,事实变→归并重算→看板更新,全程可逆、留痕。
5. 技能 or 代码
判据(沿用 FDS-04 §2:"错了会算错数据/出假结论"的→代码;"换种说法/换套判断标准"的→技能):
| 必须是技能(靠语言理解、判断标准会演进) | 必须是代码(正确性不容漂移) |
|---|---|
| 同义仲裁:边界候选"是不是同一件事"的语言判定 | 取数、project_id 隔离、强一致读 |
| 跨会概述/演进叙述:把结构化数据讲成人话 | 三项依据计算(实体重叠/语义相似/时间接近) |
| "什么算反复、什么算演进"的业务措辞口径(可版本化) | 成组/装演进链/去重/取最新/反复计次的执行 |
project_fact_links 写库、归并/纠错落库、recompute | |
| 失效联动、可逆留痛、权限校验 |
一句话边界:"是不是同一件事"的语言判断和怎么讲给人听 = 技能;把数据取出来、按公式算依据、串链、去重、写归并关系、保证可复核 = 代码。 关联的最终落库与演进链装配永远是代码,技能只产出判定与叙述,判不准就标存疑交人确认(FDS-16)——技能不自己拍板写库。
技能形态(遵 FDS-04 模板):skills/custom/meeting-cross-relate/SKILL.md,frontmatter 写 owner/version/inputs(两条候选事实文本+三项依据分)/outputs(是否同一事项+理由)/acceptance/eval;正文是业务人可读可改的判定口径("换说法的同一风险算同一件事""不同子系统的同名问题不算"),配 eval/cases.jsonl 自动测试,改动走测试+人审才生效(FDS-04 三红线)。
6. 二开归类
🟢 复用 deer-flow · 🟡 基于 deer-flow 扩展位 · 🔴 acdm-backend 从头自建
- 🟡 基于:同义仲裁与跨会叙述做成技能挂技能目录、跑在 deer-flow 引擎上(复用其技能机制/版本评审,不动内核);跨会聚合的确定性流程复用 deer-flow 已有的
meeting_aggregatorpipeline 骨架作为"取数+算依据+装配"的执行壳(它已是确定性 DAG,符合"流程固定不需 LLM 自主决策")。 - 🔴 从头自建(acdm-backend + 现有 PostgreSQL):
- 真关联执行——
project_fact_links表与归并组/演进链装配、去重取最新、反复风险识别; - 实体消歧接通(把人/事归一到统一标识,现状是空的,见 §9)与语义相似接通(文本转向量算相似,现状是被关掉的零向量);
- 看板取数/汇总接口、按负责人视图、人工纠错→站内确认→落库→recompute、失效联动。
- 真关联执行——
- 为什么 🔴 这块不能只靠现成的:现状的跨会聚合是有壳的,但消歧没接、语义没接,等于壳在转、内核是空的(详 §9 代码事实)。把"真关联"补成正确、可复核、可逆的执行,是本章 🔴 的全部重量;deer-flow 没有"按项目隔离、强一致、可复核的跨会归并"这种东西,必须自建。
- 复用项目已有"可逆存储"做归并关系的软删/回收站/留痕,不重造。
7. 与人机协同模型关系
对应模型里的项目工作台(项目级上下文/账):跨会看板就是这个项目"对外只有一笔账"的呈现面——决策/风险/里程碑/待办都从单一真相(FDS-17)来,杜绝多处数据打架。归并组/演进链是工作台上的项目级派生视图;人对归并的纠错是任务卡片(走站内确认 FDS-16,可审阅可回滚);归并/重算流程是任务流(确定性、留痕、可逆)。技能只在"判不准"处提请人确认,人始终能掰回系统的判断,符合"AI 与人共写、人最终拍板"。全程站内,不外溢到飞书等外部平台。
8. 验收(可证伪)
- 可用:打开任一有 ≥3 场会的项目,一屏出四象限,每块是全项目汇总去重后的当前态;每条可点回某场会原文出处(配 FDS-17 trace)。
- 可用:构造一个"同一风险换三种说法、分散在三场不同日期会"的样例,看板必须把它识别为一条演进链(三个状态点、按时间排、
relation=evolves_from),不拆成三条。 - 可用(关键·反证现状):构造两条"开会日期相邻但明显不同事(实体不重叠、语义不相近)"的事实,看板不得把它们归并;反之"日期隔一个月但实体重叠+语义高度相近"的两条,必须归并。即:归并判定不被日期单独决定,
match_basis里能看到三项依据各自分值。 - 好用:把某反复风险在第 4 场会标关闭,看板反复高亮带据此更新("已关闭"或移出高亮),无需人工重算整盘。
- 好用:人把系统串错的演进链拆开(走站内确认),确认后该组 recompute、留痕可查、可恢复;旧归并软删不丢。
- 可复核:随机抽 20 个归并组,
match_basis三项依据与展示一致,人能据此判断归并对错;抽 20 条演进链,时间序与原文一致。
9. 现状
有,但基本失效——现关联实际只按会议日期算,语义/实体比对被关掉,跨会"智能"是近似错觉。
读过代码,事实如下(deer-flow/backend/.../pipelines/meeting_aggregator/relate.py、embedding.py、meeting_aggregator_realtime/nodes/extract.py):
- 关联判别公式确实写成
relevance = 0.6×实体重叠 + 0.2×时间接近 + 0.2×语义相似,阈值 0.4 入归并候选——设计是对的。 - 但语义相似分量恒为 0:默认用
ZeroEmbeddingService,文本转向量返回的是零向量,余弦相似度恒等于 0(代码注释明写"公式实际退化为 0.6×实体重叠 + 0.2×时间接近")。即:语义比对被关掉(原因是 phase-B 当时火山 embedding 未开通、本地装包失败,做了接口抽象先用零向量顶着,真 embedding 留到后续——但后续没接上)。 - 且实体消歧没接通:实时抽取节点里
canonical_entity_map={}是空的(代码注释明写"本 change 不实施 cascade canonicalize,relate 直接用 entity name 字面比对");而entity_overlap在实体集合为空时返回 0。也就是说实体重叠分量在真实跑的实时链路里大概率也算不出有效值(没归一,字面不一致就不重叠)。 - 两项主依据(0.6 的实体 + 0.2 的语义)都塌掉后,公式实际只剩 0.2×时间接近(开会日期差)一项在起作用。
time_proximity = exp(-日期差/7),同日=1.0、7 天≈0.37;再乘 0.2,最大值才 0.2,够不到 0.4 阈值——意味着实时链路里跨会归并要么靠 entity 字面偶然命中、要么几乎不归并,看板呈现的"同一件事跨会串联"是近似失效的错觉。 - 后果直说:换了说法的同一风险被当成多条不同风险;不相干但日期接近的两件事可能被错连;反复风险识别失真。管理层据此看项目,等于看一份对不上的账。
本章即把这层补成"真关联":接通实体消歧、接通语义相似、把归并/演进/反复识别做成正确可复核可逆的代码执行,语言判断与叙述交技能。
10. 风险与取舍
- 风险:语义相似依赖文本转向量(embedding),而现状 embedding 服务未就绪(火山未开通/本地装包失败)。取舍:接口已抽象,先接通一个可用 embedding(火山方舟开通后用其 embedding,或本地中文 embedding 模型二选一),公式恢复三项齐全;在 embedding 真接通前,宁可少归并也不靠日期硬凑——即把阈值/权重设成"实体不重叠且语义不可得则不归并",避免重蹈"按日期假串"。
- 风险:实体消歧做错→把两个人/两件事当成一个,污染整条演进链。取舍:消歧低置信不自动归并,转技能同义仲裁,仍不确定转 FDS-16 人确认;
match_basis全程存证可复核可回退。 - 风险:归并算法把不同事强行合并(假阳)或该合不合(假阴)。取舍:宁可漏归并(假阴)不可错归并(假阳)——错归并会让管理层看到伪造的演进链,危害大于"没串起来";阈值偏保守,边界交人确认。
- 风险:每次事实变就全量重算归并→项目会议多时贵。取舍:失效只标记、recompute 按受影响
group_key局部增量,不动未变组(沿用 FDS-17 失效不立即重算的范式)。 - 风险:业务人改"什么算同一件事/反复/演进"的口径改坏。取舍:这些口径在技能正文,技能必带 eval 样例、改动走自动测试+人审才生效、可一键回退(FDS-04 三红线)。
- 取舍(范围):本期看板就是站内一屏 + 演进/高亮/按人四视图;外部 IM/PM 同步留可插拔出口位,本期不实现不依赖(全局约束〇)。