Skip to content

DCBrain 动态规划大脑

DCBrain(Dynamic Compiling Brain)是 TFRobot 的高阶推理引擎。它在"仿生机器人"中扮演大脑皮层的角色——接收用户问题后,自主规划解决方案、调度思维链执行、验证结果质量,并在必要时反复迭代,直至问题被充分解决。与单条 Chain 只关注"如何执行一个具体任务"不同,DCBrain 关注的是"面对一个开放式问题,应该做什么、按什么顺序做、做完之后够不够好"。

设计理念

单条 Chain 擅长在确定的流程中完成特定任务,但现实问题往往需要多步骤、多工具的协同解决。DCBrain 的设计目标是:

  1. 动态规划:面对用户的开放式问题,由 LLM 自主分析并生成可执行的计划脚本(tf_plan),而非依赖硬编码流程
  2. 迭代收敛:计划执行后,通过独立的验证 LLM 判断是否已充分解决问题,不充分则携带建议重新规划
  3. DSL 驱动:计划脚本使用类 Python 语法编写,由内置的 TFChainInterpreter 解释执行,兼顾表达力与安全性
  4. 容错与止损:通过 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 可以从 initplanningrunning 触发——计划赶不上变化,随时可调整
  • abort 从任何状态均可触发——及时止损
  • init 从任何状态均可触发——永远可以重来

tf_plan 脚本

DCBrain 的核心产出是由 LLM 生成的 tf_plan 脚本。它使用类 Python 语法,支持:

  • 调用已有 Chain:像调用函数一样 result = my_chain(input_text="...")
  • 动态构建 Chainchain = __construct_chain(output_schema={...}, tags=[...])
  • 流程控制if-elseforwhile、函数定义
  • 变量与表达式:标准 Python 数据类型和运算

不允许使用 try-catchimportwith 语句,以保证脚本在沙箱解释器中的安全执行。

三层 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
    1. 验证 Token 用量
    2. 构建 plan_chain(清空 LLM prompt 后重新设置 planning_prompt、MemoPrompt、KnowledgePrompt)
    3. 运行 plan_chain,生成结果
    4. 如结果包含 ```tf_plan 代码块,提取脚本内容设置为 current_plan
    5. 如不包含脚本,则将 LLM 的直接回复作为 final_result(简单问题直接回答)

4. running 阶段

  • condition_exec_plan:检查是否存在未执行的计划(有 plan 且无 result)
  • on_enter_running
    1. 使用 Lark 解析 tf_plan 脚本为 AST
    2. 构建 TFChainInterpreter,注入 spec_chains、工具、上下文
    3. 执行 AST,将执行结果设置为 current_result
    4. 捕获可恢复异常(TFLLMInterruptTFInterpreterErrorTFChainError),存入 interpreter_err 供后续决策

5. 验证与收敛

  • condition_succeed
    1. 如执行过程中有异常(interpreter_err),直接返回 False,触发重规划
    2. 否则,构建 validate_chain,将 plan + result + 用户输入 交给 Validate LLM 判断
    3. is_solved=True,设置 final_result,进入 succeeded
    4. 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 避免重复犯错。

  • 写入时机failedaborted 状态进入时;condition_succeed 验证不通过时
  • 清空时机succeeded 状态进入时
  • 作用域:按 conversation_id 隔离,不同会话互不干扰

动态 Chain 构建

当 LLM 在 tf_plan 中调用 __construct_chain() 时,DCBrain 会:

  1. 清空 default_llm 的所有 prompt
  2. 根据参数设置 response_format 和 JSON 示例引导 prompt
  3. 构建新的 Chain 实例
  4. 如有 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_chainsdefault_llmmemory 都会注册到 Neural
  • 执行阶段的工具调用可以通过 Neural 信号系统分发
  • 用户新输入可以通过 Neural 信号获取

与 TFChainInterpreter 的关系

TFChainInterpreter 是 DCBrain 的"执行引擎"。它接收 Lark 解析后的 AST,在沙箱环境中解释执行 tf_plan 脚本。解释器将 spec_chains 包装为可调用函数,并处理工具执行、错误恢复和结果追踪。