目前项目只完成了30%左右,欢迎大家一起来pr,另外我建了一个QQ群:1103861504,可以一起来讨论AI写小说问题。俺基本上一天16个小时都在线,有问必回。(QAQ,加个群来讨论吧,作者单机好久了🤣)。

笔记17:编排画布深化——从顺序发言到动态编排

一、当前实现的问题

当前编排画布已实现:拖拽专家到画布 → 连线定义顺序 → 按顺序逐轮发言。

但这是”固定流水线”,缺少真正工作流画布应有的灵活度。

用户反馈暴露了以下几个层次的问题:

二、循环控制:不应只有轮次

2.1 当前

while round < max_rounds:
    for expert in order:
        expert.speak()

只在会议创建时设一个 max_rounds,发动机引擎只管数圈。

2.2 应该是

while not should_exit():
    expert = determine_who_speaks_now()
    expert.speak()
    # 人/agent 可以随时终止或重开

退出条件多元化:

退出条件 触发者 场景
达到专家发言总次数 系统 “每人说够3次就停”
用户手动终止 讨论已充分
全自动模式下 agent 判定 自动化 agent 共识达成、产出质量达标
讨论质量太差,重开 人/agent “这次方向歪了”

轮次不再是核心概念。核心概念是发言权分配——谁在什么时候说话。

三、发言权分配:点名与@提及

3.1 当前

固定顺序:A → B → C → A → B → C…

3.2 应该是

三种发言模式共存

模式 触发 行为
用户点名 人在输入框写 @剧情架构师 指定专家立刻发言
专家@提及 专家输出中包含 @人物设计师 正则检测,系统自动让被点名者发言
默认顺序 没人点名 按画布连线顺序继续

3.3 @提及的实现

专家 prompt 中增加指令:

如果你想请另一位专家回应你的观点,在发言末尾加上 @专家名。
例如:@人物设计师 请确认主角行为是否符合人设。

后端正则 @(\S+) 检测,匹配到已注册专家名,则下一发言者为该专家。

3.4 容器

画布上用户可以拖一个”容器”把多个专家框在一起。容器内所有专家共享一个群聊窗口。

右键容器 → 属性面板:

容器名称: [卷纲编排小组    ]
并发方式: [串行 ▾]         选项: 串行 / 并行
发言方式: [顺序循环 ▾]     选项: 顺序循环 / 提及驱动
重复次数: [3]             (1 = 不循环)

── 提及驱动退出条件(发言方式=提及驱动时生效)──
退出方式: [手动 ▾]         选项: 手动 / 全部赞同 / 多数赞同 / 门禁专家
赞同比例: [0.6]           (多数赞同时需达到的比例)
门禁专家: [--- ▾]          (选择容器内一位专家担任)
最大发言: [20]             (0 = 不限)

并发方式:一次几个人说话。串行默认,并行允许 @多人同时回应。

发言方式:谁决定下一个人说话:

  • 顺序循环:按容器内部连线顺序走完一圈再一圈。这是当前默认行为。
  • 提及驱动:没有固定发言顺序。专家通过 @提及点名下一个说话的人——A @了 B,B 说;B @了 C,C 说。没人点名时引擎按最近的活跃度选择一个专家发言。这种模式下专家之间互相 @ 形成讨论网络,而不是死板的 ABCD→ABCD。

提及驱动的退出条件:因为没有固定轮次边界,必须约定什么时候停:

  • 手动:用户点击停止(半自动模式下适用)
  • 全部赞同:所有专家在发言中明确表达”讨论已充分,可以结束”
  • 多数赞同:达到指定比例(如 0.6 = 60% 的专家)同意退出
  • 门禁专家:指定一位专家负责裁决。该专家发言中若包含”会议结束”等关键词则退出
  • 最大发言:无论如何,达到发言次数上限自动停止(兜底)

上下文深度:群聊越长,历史越长。用户可以同时启用两种限制——以先触达的为准:

  • 按楼层:只读最近 N 层发言(一层 = 所有专家各说一次)。适合控制逻辑连贯性。
  • 按 token:约 N token 的最近历史。适合控制成本。
  • 两项都启:哪个先到用哪个。例如 3 层 + 100K token,实际取更小者。
  • 都不启:全量历史。

总结师不再内置:之前作为容器属性开关,但用户完全可以自己从工具箱拖一个”讨论总结师”专家进容器里。拖进去就是群聊的一员,按连线顺序发言时自动做总结。比内置开关更灵活——用户可以决定总结师的位置(在谁前面/后面),也可以配多个。

3.5 容器的输入输出引脚

容器对外暴露一个输入端口和一个输出端口——输入上游数据,输出整个群聊的完整记录。

┌─────────────── 容器: 卷纲编排 ───────────────┐
│                                               │
│  ┌──────────┐    ┌──────────┐                 │
│  │ 资深作者  │───→│ 读者代表  │                 │
│  └──────────┘    └──────────┘                 │
│       │               │                       │
│       └───────┬───────┘                       │
│               ▼                               │
│  ┌──────────┐    ┌──────────┐                 │
│  │ 资深作者  │───→│ 讨论总结师 │ ← 用户自己拖的  │
│  └──────────┘    └──────────┘                 │
│                                               │
└──────────────────┬────────────────────────────┘
                   │
                   ▼ 输出: 群聊全文
            ┌──────────┐
            │ 讨论总结师 │  ← 容器外部还可再接一个
            └──────────┘

类比电路设计中的”模块封装”。

四、世界书 Agent:被动查询 → 主动节点

4.1 当前

世界书仅作为 L2 专家会议的被动数据源——读一下,灌进 prompt。

4.2 应该是

世界书作为可连线的画布节点

┌──────────┐       ┌──────────────┐
│ 剧情架构师│       │ 世界书 Agent  │
│          │←─────→│              │
│          │ 查询  │ - 查询设定    │
│          │       │ - 冲突检测    │
│          │ 更新  │ - 提取变化    │
│          │──────→│ - 归档旧条目  │
└──────────┘       └──────────────┘

双箭头连接的含义

  • 左箭头:专家发言时,可以选择查询世界书(自动在发言前注入相关条目)
  • 右箭头:专家发言后,可以选择触发世界书更新(提取新信息、检测冲突)

4.3 触发时机配置

每个专家节点在右侧配置面板中可以设置:

配置项 选项 效果
世界书查询 关闭 / 手动(发言前点按钮)/ 自动 自动在 prompt 前插入相关条目
世界书更新 关闭 / 每次发言后 / 每 N 次后 / 本循环结束后 触发 agent 提取变化
RAG 查询 同上 检索历史/技法参考注入 prompt

配置完成后专家节点显示对应图标(📖 有世界书查询 / 🔄 有自动更新 / 🔍 有 RAG)。

4.4 RAG 同理

  • RAG-历史回顾:查询”之前类似场景是怎么写的”
  • RAG-技法参考:查询”打脸场景的经典写法”

两者作为独立的检索节点连接专家节点。

五、拆得更细:专家池扩充

五个默认专家(资深作者、读者代表、剧情架构师、人物设计师、网络编辑)是”角色视角”的分法,但缺少”工序”视角的专家。

新增专家 职责 使用场景
章节拆分师 将卷纲拆为具体章节号及概要 L1.5 → L2 之间的工序
讨论总结师 定期总结群聊中多位专家的发言,提炼共识、标注分歧、确保讨论不偏离格式 群聊模式下,多位专家同时发言时避免信息散乱
世界书管理员 查询/更新世界书(可手动/自动触发) 所有需要吃设定的专家
RAG 检索员 查询历史/技法(可手动/自动触发) 需要参考旧文或技法的专家

章节拆分师本质上是”从卷纲到章纲的翻译器”——把”卷二写秘境探索”拆成”第31章发现入口、第32章遭遇守门兽、第33章…“。这一步之前由 L1.5 跳到 L2 隐式完成,现在显式化为一个专家节点。

六、浮动工具栏

画布上方增加一个浮动工具栏,包含:

图标 功能
🔲 拖入容器(框选专家分组,可配置重复次数实现循环)
📖 世界书 Agent 节点
🔍 RAG Agent 节点
自定义专家(快捷创建)
💾 保存设计
📂 加载设计

类似电路设计软件(Altium、KiCad)的元件工具栏。

七、数据模型变化

7.1 节点类型扩展

当前:只有 expert 节点
扩展后:
  - expert     (专家)
  - worldbook  (世界书 agent)
  - rag        (RAG agent)
  - container  (容器:框选专家分组 + 配置重复次数实现循环)

7.2 边类型

当前:只有 speak_order(发言顺序)
扩展后:
  - speak_order (谁先谁后)
  - query       (专家 → 世界书/RAG:发言前查询)
  - update      (专家 → 世界书:发言后更新)
  - data_flow   (通用数据流)

7.3 容器节点配置

{
  "id": "container_1",
  "type": "container",
  "config": {
    "name": "卷纲编排小组",
    "concurrency": "serial",
    "speaking_mode": "ordered",
    "repeat": 3,
    "context_layers": 3,
    "context_tokens": null,
    "exit_mode": "manual",
    "exit_ratio": 0.6,
    "exit_gatekeeper": null,
    "exit_max_speeches": 20,
    "worldbook_bindings": [],
    "rag_bindings": []
  },
  "children": ["node_1", "node_2", "node_3"],
  "edges": [
    {"source": "node_1", "target": "node_2"},
    {"source": "node_2", "target": "node_3"}
  ]
}
  • speaking_mode"ordered" (顺序循环,按内部连线)/ "mention_driven" (提及驱动,专家互相 @)
  • exit_mode"manual" / "consensus" (全部赞同)/ "ratio" (多数赞同)/ "gatekeeper" (门禁专家)
  • exit_ratio: 0~1,多数赞同模式下需要达到的比例
  • exit_gatekeeper: 门禁模式下负责裁决的 expert_id
  • exit_max_speeches: 提及驱动模式下的发言次数兜底上限
  • worldbook_bindings: 绑定的世界书实例名称列表
  • rag_bindings: 绑定的 RAG 实例名称列表

容器对外暴露一个输入端口(接收上游产出的数据,如 L1 愿景)和一个输出端口(输出整个群聊的原始内容 + 内部总结师产出的每轮摘要)。可与画布上的其他节点连线。

7.4 专家节点配置

{
  "id": "node_1",
  "type": "expert",
  "expert_id": "plot_architect_v1",
  "config": {
    "role": "main",
    "granularity": "chapter",
    "triggers": {
      "worldbook_query": "auto",    // off | manual | auto
      "worldbook_update": "after_cycle", // off | every | after_n | after_cycle
      "rag_history": "auto",
      "rag_technique": "off"
    }
  }
}

八、会议引擎改造

当前:
  for round in max_rounds:
      for expert in order:
          expert.speak()
          if semi_auto: wait_user()

改造后:
  while not should_exit(state):
      next_expert = determine_speaker(state)
      if next_expert has auto_worldbook_query:
          inject_worldbook_entries(next_expert)
      if next_expert has auto_rag:
          inject_rag_results(next_expert)
      output = next_expert.speak()
      detect_mentions = regex_match(output, r'@(\S+)')
      if detect_mentions:
          # 若容器并发方式为串行,被点名的多位专家依次发言
          # 若容器并发方式为并行,唤起 send_parallel(detect_mentions) 同时发言
          state.force_next = resolve_mention(detect_mentions[0], state.current_container)
      state.expert_speak_count[next_expert] += 1
      if next_expert has auto_worldbook_update:
          schedule_worldbook_update(output)
      if semi_auto: wait_user()
      if user_called_expert:
          state.force_next = user_called_expert
      # 容器循环:当前容器内专家走完一轮,检查是否已达到 repeat 次数
      if state.current_container and container_round_complete(state):
          if state.container_round < container.repeat:
              state.container_round += 1
              continue  # 从头开始下一轮
          else:
              exit_container(state)  # 退出容器,继续画布后续节点
      # 循环结束时
      for scheduled in state.pending_worldbook_updates:
          run_worldbook_agent(scheduled)

九、世界书与 RAG 实例化

9.1 现状

世界书和 RAG 目前是会议级全局变量——一个项目只有一套世界书、一个 RAG 检索器。启动时加载,专家发言前统一注入文本。问题是:

  • 用户看不到世界书和 RAG 的工作过程(查询日志、更新记录、检索结果)
  • 无法为不同容器/专家绑定不同的世界书(比如 L1.5 卷纲编排用一个轻量世界书,L4 正文生成用另一个带全文历史的世界书)
  • RAG 同理——历史回顾和技法参考是两种检索需求,但目前混在一起

9.2 设计方向

世界书和 RAG 成为独立的可管理页面,类似文档库有自己的管理视图。用户可以在页面中查看运行日志、手动增减条目、调整索引。

支持多个实例。每个实例有唯一名称,在画布上作为独立节点,容器或专家通过名称绑定。

── 世界书管理 ──                ── RAG管理 ──
  worldbook:                      rag:
    核心设定 (核心层)                历史回顾 (已写章节)
    全文历史 (归档层)                技法参考 (映射规则)
    角色追踪 (活跃层)                自定义知识库
    + 新建...

9.3 绑定方式

容器和专家节点配置中增加绑定字段:

容器配置:
  ┌─────────────────────────┐
  │ 世界书绑定: [核心设定 ▾]  │  下拉选择已注册的世界书实例
  │            [+添加]       │
  │ RAG绑定:   [历史回顾 ▾]  │
  │            [+添加]       │
  └─────────────────────────┘

数据模型更新(容器节点):

{
  "config": {
    "worldbook_bindings": ["核心设定", "角色追踪"],
    "rag_bindings": ["历史回顾"]
  }
}

专家节点同样支持——某个专家可以绑特定的世界书(比如人物设计师只关注角色追踪)。

9.4 唯一名称约束

专家、容器、世界书实例、RAG 实例的名称在同一项目内必须唯一——这样才能在绑定下拉框中精确指定:

项目内命名空间:
  专家:  资深作者、读者代表、剧情架构师...
  容器:  卷纲编排小组、章纲设计1、章纲设计2...
  世界书: 核心设定、全文历史、角色追踪...
  RAG:   历史回顾、技法参考、自定义知识库...

各自独立命名空间,但同类内部不重名。

9.5 接口预留

# 世界书实例管理(CRUD + 查询日志)
GET    /api/projects/{id}/worldbooks                    列表所有实例
POST   /api/projects/{id}/worldbooks                    创建实例 {name, description}
GET    /api/projects/{id}/worldbooks/{name}             获取实例详情(条目 + 日志)
PUT    /api/projects/{id}/worldbooks/{name}             更新实例配置
DELETE /api/projects/{id}/worldbooks/{name}             删除实例
GET    /api/projects/{id}/worldbooks/{name}/log         查询日志
POST   /api/projects/{id}/worldbooks/{name}/query       手动查询

# RAG 实例管理(CRUD + 检索日志)
GET    /api/projects/{id}/rags                          列表所有实例
POST   /api/projects/{id}/rags                          创建实例 {name, description, type: history/technique/custom}
GET    /api/projects/{id}/rags/{name}                   获取实例详情
PUT    /api/projects/{id}/rags/{name}                   更新实例配置
DELETE /api/projects/{id}/rags/{name}                   删除实例
POST   /api/projects/{id}/rags/{name}/search            手动检索
POST   /api/projects/{id}/rags/{name}/index             索引文档
GET    /api/projects/{id}/rags/{name}/log               检索日志

9.6 实施优先级

世界书和 RAG 的具体实现(触发器配置、自动查询时机、冲突检测细节等)留待后续单独讨论。当前阶段先确定:

  1. 世界书和 RAG 为独立管理页面
  2. 支持多实例,名称唯一
  3. 容器/专家通过名称绑定
  4. 接口按上述预留

十、管道模式(Pipeline Mode)

10.1 设计思路

将会议模式(圆桌讨论)改为管道模式(DAG 数据流):

L1 愿景 .md
    │
    ▼
资深作者(节点1)           ← 接收上游 .md,处理后产出
    │
    ▼
读者代表(节点2)           ← 接收节点1产出,处理
    │
    ▼
最终 .md

若有容器(群聊模式):.md 进入容器,内部专家按规则轮流处理,输出全文。

管道按画布边的拓扑排序逐层执行——同层可并行,上层完成才进入下层。每个节点的输出自动注入下一节点的 custom_prompt 中。

10.2 已实现

  • MeetingEngine.run_pipeline():DAG 拓扑排序 + 逐节点处理
  • 前端 pipeline: true 参数
  • SSE 事件:pipeline_start → level_start → expert_speak(含 node_id) → level_complete → pipeline_complete
  • 前端聊天标签按专家/容器独立显示
  • BroadcastChannel 消息广播(弹窗接收)

10.3 已知问题(待解决)

  1. 管道在第一个节点完成 AI 回复后直接中止,不进入第二个节点。DAG 构建验证正确(两节点带边确认产生 [node_1] → [node_2] 两层),怀疑是 SSE 流或 human_feedback 交互在管道模式下未正确适配
  2. 节点的 input_text 注入方式:目前通过 custom_prompt 传入,专家 prompt 模板需要确认正确引用
  3. Vue Flow 容器尺寸警告:运行时画布最小高度已设 min-height:200px,偶发警告不影响功能

10.4 后续方向

  • 容器节点在管道模式下的数据流入流出
  • 管道模式与中断模式的交互(是否在管道中也需要 per-node 暂停)
  • 管道产出的 .md 文件自动存档到文档库

十一、实施优先级

优先级 内容 理由
P0 灵活退出(总次数/手动) 代替死板的 max_rounds
P0 @提及点名 核心互动机制
P0 容器节点 + 属性配置 分组/循环/并发/提及驱动
P0 管道模式调试 管道 DAG 执行到第一节点后中止,待修复
P1 世界书/RAG 独立页面 + 多实例 数据支撑的核心
P1 容器/专家绑定世界书+RAG 按需组合
P1 浮动工具栏 节点类型多了需要面板
P2 章节拆分师专家 新 expert 类型
P3 世界书/RAG 触发器细节 等单独讨论

创建时间:2026-05-01 状态:管道模式已实现但存在执行中断 bug,待下次修复

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐