AI辅助网文创作理论研究笔记(十七):编排画布深化——从顺序发言到动态编排
目前项目只完成了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_idexit_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 的具体实现(触发器配置、自动查询时机、冲突检测细节等)留待后续单独讨论。当前阶段先确定:
- 世界书和 RAG 为独立管理页面
- 支持多实例,名称唯一
- 容器/专家通过名称绑定
- 接口按上述预留
十、管道模式(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 已知问题(待解决)
- 管道在第一个节点完成 AI 回复后直接中止,不进入第二个节点。DAG 构建验证正确(两节点带边确认产生
[node_1] → [node_2]两层),怀疑是 SSE 流或human_feedback交互在管道模式下未正确适配 - 节点的
input_text注入方式:目前通过custom_prompt传入,专家 prompt 模板需要确认正确引用 - 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,待下次修复
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)