梦境循环(下):多 source 怎么并行、预算怎么不爆
上节课讲了梦境循环「整体在干什么」。但当你真的建了一个多 source 的 brain(比如 investing/work/tech 三个来源),问题就具体了:这一轮循环是三个 source 排队跑,还是各跑各的?会不会 A 来源的笔记被算进 B 的来源预算?预算烧爆了怎么办?
这一课讲梦境循环的「作用域(scope)」——它怎么在多个来源之间既并行又不串、既独立又共享。
一、per-source 扇出:每个来源自己跑一轮
gbrain 不是把一个 brain 当一团整体去跑循环,而是按来源(source)扇出——每个 source 各自独立跑一轮自己的阶段1。比如你有 5 个 source,循环就扇出成 5 路,各自抽取、嵌入、连图谱。一个来源卡住或失败,不影响其他来源继续。文档实测 5 个来源的联邦 brain 并行刷新大约 5 分钟2。
对使用者意味着:你往 investing 里猛加了一百篇笔记,当晚只有 investing 这一路的循环工作量变大,work 和 tech 不受影响。隔离是默认的。
二、但有些阶段必须全局走
并行不是无条件的。文档明确:per-source 锁允许两路循环并发,但若干阶段仍在每个循环里全局走 brain——嵌入(embed)、孤儿清理(orphans)、净化(purge)、符号边解析(resolve_symbol_edges)、观点评分(grade_takes)、校准档案(calibration_profile)这几个是全局的3。代码用 NON_GLOBAL_PHASES / GLOBAL_PHASES / LAST_GLOBAL_AT_KEY 严格区分哪些 per-source、哪些全局。
为什么有的要全局?比如「净化」要清理全 brain 过期的东西,按 source 各自清会漏;「嵌入」全局统一算向量避免重复。一个建筑师会记下:能并行的尽量 per-source 隔离,但跨 source 才正确的事必须全局串行——这个边界划错了要么串数据、要么漏活。
三、预算双封顶:既按 source 又按总额
循环会烧大模型(LLM)和向量化(embedding)的钱。gbrain 用两套预算闸住4:
- 每来源上限:比如抽取原子笔记
extract_atoms默认每 source 每次 $0.30;你可以用配置键cycle.propose_takes.budget_usd之类给某阶段设封顶。 - 全 brain 总额:一个「脑级预算追踪器」贯穿所有 per-source 调用,任何一路烧到总额剩余不足时,自动把该路的单 source 上限压到「剩余总额」以内——保证不会某一路把整月额度一口气花光4。
而且预算是硬停的:超了就干净停下,不崩、不丢进度、下次接着跑。对一个 7×24 自动跑的系统,这种「钱烧完了就停、绝不偷偷透支」的纪律,比「跑得快」重要得多。
四、一个使用者真正要关心的
你几乎不用懂上面这些。你只要知道两件事:(1)多 source 是隔离并行、互不影响;(2)预算有上限、烧完就停、不会偷偷爆账单。 真正要调的,是 gbrain.yml 里给某阶段设的 budget_usd 封顶值,以及来源数量——来源越多、并行刷新越久,但单来源隔离保证不会互相拖垮。
五、这一课带走的
- 梦境循环按 source 扇出,每来源独立跑一轮,5 来源联邦约 5 分钟并行刷新。
- 嵌入/孤儿清理/净化/符号边/观点评分/校准 这几个阶段仍全局走 brain,不能 per-source。
- 预算双封顶:每 source 有上限,全 brain 还有总额,任一触顶硬停不崩。
- 使用者无感,只知道「多来源互不干扰、钱不会偷偷烧爆」。
练习题
梦境循环在多 source brain 里怎么跑?
下列哪些阶段仍全局走 brain(非 per-source)?
预算控制机制是?
某来源预算烧到全 brain 总额剩余不足时?
参考出处
Footnotes
-
代码
src/commands/autopilot-fanout.ts(v0.38 per-source autopilot dispatch;取代 v0.36「每 tick 一个 cycle job」,改为枚举listSources后 per-source 扇出)。 ↩ -
文档
docs/architecture/dream-cycle.md(per-source 扇出;5-source 联邦 brain 并行刷新约 5 分钟;fanoutMax默认 1)。 ↩ -
代码
src/core/cycle/(若干 phase 仍全局走 brain:embed/orphans/purge/resolve_symbol_edges/grade_takes/calibration_profile;用NON_GLOBAL_PHASES/GLOBAL_PHASES/LAST_GLOBAL_AT_KEY区分 per-source 与全局阶段)。 ↩ -
代码
src/core/cycle/budget-meter.ts(brain-wide BudgetTracker 贯穿所有 per-source 调用;budget_usd入参);src/core/cycle/extract-atoms.ts(每 source 每次 $0.30,keycycle.extract_atoms.budget_usd);src/core/cycle/base-phase.ts(阶段预算键如cycle.propose_takes.budget_usd);per-source 上限与 brain-wide 总额取 min 双封顶。 ↩ ↩2