跳到主要内容

03 · Co-STORM:人机圆桌讨论 + 动态思维导图

Co-STORM 把 STORM 从“无人自动写稿”升级成“人能随时插话的协同知识探索”。两个新东西:一套轮次管理策略(谁该说话)和一张动态思维导图(信息怎么组织)。

1. 它解决什么新问题

STORM-Wiki 是“一键出稿”,人无法干预方向。Co-STORM(EMNLP 2024)面向人机协同的信息探索:人可以观察这场讨论,也可以插一句话把讨论引向自己关心的点。

为降低人“看长对话”的认知负担,Co-STORM 维护一张动态更新的思维导图:把零散信息组织成层级概念结构,作为“人和系统共享的概念空间”(见 dataclass.py:291-306KnowledgeBase 文档串,引用 Co-STORM 论文 §3.2)。

2. 三类参与者 + 轮次管理

圆桌上有三类“说话人”:

角色干什么代码
CoStormExpert(专家)某个视角的专家,做 RAG 作答或追问collaborative_storm/modules/co_storm_agents.py CoStormExpert
Moderator(主持人)用“检索到但还没被用过”的信息抛出新角度问题co_storm_agents.py Moderator
Human / SimulatedUser(人类/模拟用户)观察或主动插话引导方向co_storm_agents.py SimulatedUser

谁该下一个说话?DiscourseManager.get_next_turn_policy(collaborative_storm/engine.py:461-502)决定,返回一个 TurnPolicySpec(engine.py:293-316,带 4 个标志:是否重组知识库/是否更新专家列表/是否润色发言/由哪个 agent 发言)。怎么读这套优先级(从上到下,命中即定):

get_next_turn_policy(conversation_history):
├─ simulate_user? → 由模拟用户发言
├─ rag_only_baseline_mode? → 纯 RAG agent(消融基线)
├─ next_turn_moderator_override? → 主持人(warm start 后强制先由主持人开场)
├─ 连续 N 轮没人提问了? → 主持人抛新问题 + 标记“重组知识库”
└─ 否则 → 专家轮流发言(experts.pop(0) 再 append 回队尾)

“连续 N 轮没提问就让主持人介入”靠 _should_generate_question(engine.py:408-423):它倒着数连续的“非提问”轮次,达到 moderator_override_N_consecutive_answering_turn(默认 3)就触发。这保证讨论不会一直在答、不开新方向。

专家列表是动态的: 当上一轮是“提问”时,should_update_experts_list 为真,系统会据这轮内容用 GenerateExpertModule 重新生成一批对口专家(engine.py:446-453)。

3. 一步对话:CoStormRunner.step

人或系统的每一次推进都走 CoStormRunner.step(collaborative_storm/engine.py:661-761)。怎么读这条主线:

step(user_utterance):
├─ 若 user_utterance 非空: # 人插话
│ 直接作为 "Guest / Original Question" 入历史,返回
└─ 否则: # 系统自动推进一轮
① get_next_turn_policy(...) 选出本轮 agent
② agent.generate_utterance(kb, history) 生成发言(专家会做 RAG)
③ should_update_experts_list? 据发言刷新专家名单
④ knowledge_base.update_from_conv_turn 把本轮引用的信息插进思维导图
⑤ should_reorganize_knowledge_base? reorganize() 重组导图

专家发言 CoStormExpert.generate_utterance(co_storm_agents.py:78-107)三步:先取知识库摘要当上下文 → 用 CoStormExpertUtteranceGenerationModule 规划动作并 RAG 作答 → 再润色成更口语化的圆桌发言。RAG 作答的底层是 AnswerQuestionModule(grounded_question_answering.py:50-163),和 STORM 的专家同源:拆查询→检索→带 [1][2] 作答→抽取被引用的源。

4. 思维导图:信息怎么被 LLM “导航”归位

这是 Co-STORM 最巧的地方。导图是 KnowledgeBase(dataclass.py:291-849),一棵 KnowledgeNode 树;每个节点挂着一组信息的 citation_uuid(dataclass.py:86-119)。

新信息往哪挂? 不是简单按相似度塞,而是让 LLM 在树里逐层导航InsertInformationModule(collaborative_storm/modules/information_insertion_module.py:53-313)有两条路径:

  1. 先用嵌入排序候选 + LLM 选一个(choose_candidate_from_embedding_ranking,information_insertion_module.py:175-211):把所有节点路径编码,按与“问题+查询”的 cosine 相似度排序,取 top-N 给 InsertInformationCandidateChoice 让 LLM 选最佳;选不出再走第二条。
  2. 逐层导航(layer-by-layer)(layer_by_layer_navigation_placement,information_insertion_module.py:108-147):从根开始,每层让 InsertInformation(information_insertion_module.py:16-30)在三个动作里选一个:
LLM 在当前节点的选择(InsertInformation 的 prompt 约定):
- insert → 就挂在当前节点
- step: 子节点名 → 下钻到该子节点继续判断
- create: 新节点名 → 新建子节点并挂进去(需 allow_create_new_node)

关键细节:allow_create_new_node=True(结构会变)时改用顺序插入,因为每次插入都可能改变树结构、不能并发;只读结构时才并发多线程(information_insertion_module.py:278-313)。插入本身带线程锁(dataclass.py:697 with self._lock),并给每条信息分配全局唯一的 citation_uuid

5. 导图重组:长出子主题、剪掉空枝

随着信息变多,某些节点会“太胖”。KnowledgeBase.reorganize(dataclass.py:828-846)做两件事(对应论文“自顶向下扩展 + 自底向上清理”):

reorganize():
① trim_empty_leaf_nodes() 剪掉没内容的叶子
② merge_single_child_nodes() 单孩子节点与孩子合并(去掉冗余层)
③ expand_node_module(kb) 给“信息超过阈值”的节点长出子主题
④ 再 trim + merge 清理

节点扩展 ExpandNodeModule(information_insertion_module.py:334-425):找到第一个内容数 ≥ node_expansion_trigger_count(默认 10)的节点,用 ExpandSection 让 LLM 起一组子主题名,建子节点后把该节点原有信息清空、重新逐条 insert 到子节点下(_expand_node,information_insertion_module.py:391-413)。这样“胖节点”就被拆成了更细的子结构。

6. Warm Start 与报告生成

Warm Start(engine.py:582-640): 正式讨论前,Co-STORM 先跑一个“迷你 STORM”——多视角模拟对话采集背景信息,初始化思维导图,并生成首版报告 + 一段引人入胜的开场对话,让用户“跟上系统已知的东西”。完成后设 next_turn_moderator_override=True,保证讨论由主持人开场。

报告生成(generate_reportKnowledgeBase.to_report,engine.py:642-656 / dataclass.py:848-849): 和 STORM 论文同范式——把思维导图的节点当章节名,逐节生成报告。所以那张导图既是“给人看的概念地图”,也是“报告的目录”。

7. 这章带走什么

Co-STORM 的两个新原语值得记住:(1) 用显式的轮次策略(谁说话/何时主持人介入/何时换专家)把多 agent + 人协调成一场有节奏的讨论;(2) 用“LLM 逐层导航 + 嵌入候选”把每条信息可解释地归进一棵会自我重组的思维导图。 工程上更难、但也是它相对 STORM 的核心增量。