DCBrain 动态规划大脑¶
DCBrain(Dynamic Compiling Brain)是 TFRobot 的高阶推理引擎。它在"仿生机器人"中扮演大脑皮层的角色——接收用户问题后,自主规划解决方案、调度思维链执行、验证结果质量,并在必要时反复迭代,直至问题被充分解决。与单条 Chain 只关注"如何执行一个具体任务"不同,DCBrain 关注的是"面对一个开放式问题,应该做什么、按什么顺序做、做完之后够不够好"。
设计理念¶
单条 Chain 擅长在确定的流程中完成特定任务,但现实问题往往需要多步骤、多工具的协同解决。DCBrain 的设计目标是:
- 动态规划:面对用户的开放式问题,由 LLM 自主分析并生成可执行的计划脚本(
tf_plan),而非依赖硬编码流程 - 迭代收敛:计划执行后,通过独立的验证 LLM 判断是否已充分解决问题,不充分则携带建议重新规划
- DSL 驱动:计划脚本使用类 Python 语法编写,由内置的
TFChainInterpreter解释执行,兼顾表达力与安全性 - 容错与止损:通过 Token 预算、迭代次数上限和超时时间三重保护,防止失控
这种"规划 → 执行 → 验证 → 重规划"的闭环,使 DCBrain 具备稳定的长程推理能力。
核心概念¶
状态机¶
DCBrain 基于 TFISM 有限状态机驱动,包含 6 个状态:
| 状态 | 说明 |
|---|---|
init |
初始化。从 Memory 中召回历史对话、文档、知识,填充上下文 |
planning |
规划。由 Plan LLM 结合用户输入和上下文,生成 tf_plan 脚本 |
running |
执行。由 TFChainInterpreter 解析并执行 tf_plan 脚本 |
succeeded |
成功终态。验证通过,最终结果已生成 |
failed |
失败终态。已知异常导致的可恢复失败 |
aborted |
中止终态。用户主动中止或不可恢复异常 |
状态转换规则如下:
┌──────────────────────────────┐
│ init │
└──────┬───────────────────────┘
│ plan
▼
┌──────────────┐
┌───►│ planning │◄──────────┐
│ └──┬───────┬───┘ │
│ │ │ │
│ exec_plan succeed plan (重规划)
│ │ │ │
│ ▼ ▼ │
│ ┌──────┐ ┌─────────┐ │
│ │running│ │succeeded│ │
│ └──┬───┘ └─────────┘ │
│ │ │
│ ├── succeed ──► succeeded
│ ├── fail ────► failed
│ └── plan ───────────────┘
│
└── plan (验证未通过时循环)
任何状态 ── abort ──► aborted
关键转换约束
exec_plan只能从planning触发——凡事先规划,三思而后行plan可以从init、planning、running触发——计划赶不上变化,随时可调整abort从任何状态均可触发——及时止损init从任何状态均可触发——永远可以重来
tf_plan 脚本¶
DCBrain 的核心产出是由 LLM 生成的 tf_plan 脚本。它使用类 Python 语法,支持:
- 调用已有 Chain:像调用函数一样
result = my_chain(input_text="...") - 动态构建 Chain:
chain = __construct_chain(output_schema={...}, tags=[...]) - 流程控制:
if-else、for、while、函数定义 - 变量与表达式:标准 Python 数据类型和运算
不允许使用 try-catch、import、with 语句,以保证脚本在沙箱解释器中的安全执行。
三层 LLM 架构¶
DCBrain 支持为不同阶段配置独立的 LLM:
| LLM | 用途 | 推荐模型 | 降级策略 |
|---|---|---|---|
default_plan_llm |
生成规划脚本 | Reasoning/Thinking 模型 | 降级使用 default_llm |
default_validate_llm |
验证执行结果 | Reasoning/Thinking 模型 | 降级使用 default_llm |
default_llm |
动态构建 Chain 时使用 | 通用 Chat 模型 | — |
这种分离设计允许在成本和质量之间灵活权衡:规划和验证阶段使用推理能力更强的模型,而执行阶段的动态 Chain 使用性价比更高的模型。
生命周期与状态流转¶
一次完整的 run() / async_run() 调用的执行流程如下:
1. 消息提交与上下文初始化¶
# 将用户输入提交到 Memory
self.commit_message(current_input)
# 构建 BrainContext
brain_ctx = BrainContext(current_input=current_input, tools=tools, ...)
brain_intermediate = BrainIntermediateResult(context=brain_ctx)
2. init 阶段¶
- on_enter_init:将
spec_chains的能力描述(名称、输入/输出 Schema)序列化为 JSON,注入到current_input.additional_kwargs中,供后续规划 LLM 参考
3. planning 阶段¶
- prepare_plan:从 Memory 召回历史对话(conversation)、文档(elements)和知识(knowledge),填充上下文。如有前次验证建议,也注入上下文
- condition_plan:检查规划次数是否超过
max_iterations - before_plan:如有前次 plan+result,归档到
intermediate_plans_and_results - on_enter_planning:
- 验证 Token 用量
- 构建
plan_chain(清空 LLM prompt 后重新设置 planning_prompt、MemoPrompt、KnowledgePrompt) - 运行 plan_chain,生成结果
- 如结果包含
```tf_plan代码块,提取脚本内容设置为current_plan - 如不包含脚本,则将 LLM 的直接回复作为
final_result(简单问题直接回答)
4. running 阶段¶
- condition_exec_plan:检查是否存在未执行的计划(有 plan 且无 result)
- on_enter_running:
- 使用 Lark 解析
tf_plan脚本为 AST - 构建
TFChainInterpreter,注入 spec_chains、工具、上下文 - 执行 AST,将执行结果设置为
current_result - 捕获可恢复异常(
TFLLMInterrupt、TFInterpreterError、TFChainError),存入interpreter_err供后续决策
- 使用 Lark 解析
5. 验证与收敛¶
- condition_succeed:
- 如执行过程中有异常(
interpreter_err),直接返回False,触发重规划 - 否则,构建
validate_chain,将 plan + result + 用户输入 交给 Validate LLM 判断 - 如
is_solved=True,设置final_result,进入succeeded - 如
is_solved=False,保存suggestion,回到planning重新规划
- 如执行过程中有异常(
6. 循环与终止¶
整个 plan → exec → validate 循环持续进行,直到以下任一条件满足:
- 验证通过 →
succeeded - Token 超限 →
failed - 迭代次数超限 →
failed - 超时 → 抛出
TFBrainError - 用户中止 →
aborted
配置参数¶
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
spec_chains |
dict[str, Chain \| Chains] |
专业思维链字典。key 为链名称,value 为链实例。DCBrain 会将其能力描述暴露给 Plan LLM | {} |
default_llm |
ChatLLM |
基础 LLM。用于动态构建 Chain。注意:动态构建时所有 prompt 会被清空重设 | — |
default_plan_llm |
Optional[ChatLLM] |
规划 LLM。建议使用 Reasoning 模型。未设置时降级使用 default_llm |
None |
default_validate_llm |
Optional[ChatLLM] |
验证 LLM。建议使用 Reasoning 模型。未设置时降级使用 default_llm |
None |
planning_prompt |
AdditionalInfoPrompt |
规划模板。指导 LLM 如何分析链能力并生成 tf_plan 脚本 | DEFAULT_PLANNING_TEMPLATE |
validate_prompt |
AdditionalInfoPrompt |
验证模板。指导 LLM 判断当前 plan+result 是否充分解决了用户问题 | DEFAULT_VALIDATE_TEMPLATE |
memory_chunk_size |
int \| list[int] \| tuple |
从 Memory 召回的块大小。可以是单个 int 或 4 元素列表(分别对应会话、文档、知识、关键字索引)。tuple 形式可附带长度函数 | (16384, cl100k_base_length) |
max_iterations |
int |
最大规划迭代次数。超过后触发 failed |
10 |
max_tokens |
int |
最大 Token 预算(涵盖输入与输出)。以 GPT-4-Turbo 为例,128k tokens 约需 18 元人民币 | 128,000 |
timeout |
int |
超时时间(秒)。默认 20 分钟。设为极小值(如 0)可保证仅执行一次 plan。一个 plan 开始执行后不会被超时打断 | 1200 |
运行时行为¶
上下文缓存(_contextual_plan_info)¶
DCBrain 为每个 conversation_id 维护一个长度为 10 的双端队列,记录最近未成功的 plan+result+error/suggestion。这些历史信息会在下次规划时带入上下文,帮助 LLM 避免重复犯错。
- 写入时机:
failed或aborted状态进入时;condition_succeed验证不通过时 - 清空时机:
succeeded状态进入时 - 作用域:按
conversation_id隔离,不同会话互不干扰
动态 Chain 构建¶
当 LLM 在 tf_plan 中调用 __construct_chain() 时,DCBrain 会:
- 清空
default_llm的所有 prompt - 根据参数设置 response_format 和 JSON 示例引导 prompt
- 构建新的 Chain 实例
- 如有 Neural 连接,自动注册到 Neural
Chain 仅支持纯文本或 dict 类型返回
如需返回 list/int/float 等类型,请使用字典包装,如 {"result": [1, 2, 3]} 而非直接 [1, 2, 3]。
用户新输入处理¶
当用户在 DCBrain 执行过程中发送新消息时,Chain 层会抛出 TFUserNewInputError。该异常不会被 DCBrain 内部捕获,而是穿透到调用方(如 TFRobotServer),由应用层统一处理消息切换与重启逻辑。
非协程安全¶
虽然 DCBrain 提供了 async_run() 方法,但这主要是为了释放主线程的 IO 阻塞,并不意味着可以多线程并发运行同一个 DCBrain 实例。状态机是单线程模型,并发会导致状态混乱。如需并发处理多个任务,请使用多个 DCBrain 实例。
使用建议¶
- 简单问答不需要 DCBrain:如果任务可以用单条 Chain 解决,直接使用 Chain 即可。DCBrain 适用于需要多步推理、工具组合或结果不确定性较高的场景
- 为 Plan LLM 选择推理能力强的模型:规划阶段的质量直接决定整体效果,建议使用具备 Reasoning/Thinking 能力的模型
- 合理设置 timeout:对于需要快速响应的场景,可以将 timeout 设为较小值以限制重规划次数;对于复杂任务,适当放宽
- 通过 spec_chains 预置专业能力:将常用的、确定性高的流程封装为 spec_chains,降低 LLM 自由发挥导致的不确定性
- 利用 validate_prompt 定制验证标准:默认的验证模板适用于通用场景,可以通过自定义 validate_prompt 来设定特定的完成标准
与其他模块的协作¶
与 Chain 的关系¶
DCBrain 是 Chain 的调度者。spec_chains 中的每条 Chain 都是 DCBrain 可用的"工具",DCBrain 的 LLM 负责决定何时调用哪条 Chain,以及如何组合调用结果。DCBrain 还可以通过 __construct_chain() 在运行时动态创建新的 Chain。
与 Memory 的关系¶
DCBrain 继承自 BaseBrain,天然具备 Memory 集成能力:
- init 阶段:从 Memory 召回历史对话、文档和知识
- succeeded/failed 阶段:将用户输入和 Brain 响应 commit 到 Memory
- 通过
memory_chunk_size控制召回的数据量
与 Neural 的关系¶
通过 connect_to_neural() 注册后:
spec_chains、default_llm和memory都会注册到 Neural- 执行阶段的工具调用可以通过 Neural 信号系统分发
- 用户新输入可以通过 Neural 信号获取
与 TFChainInterpreter 的关系¶
TFChainInterpreter 是 DCBrain 的"执行引擎"。它接收 Lark 解析后的 AST,在沙箱环境中解释执行 tf_plan 脚本。解释器将 spec_chains 包装为可调用函数,并处理工具执行、错误恢复和结果追踪。