Architecture cn
Jianmu 采用严格的三层分层架构设计,从底层的事件驱动运行时引擎,到中层的节点组合与行为树编排,再到上层可插拔的能力模块,形成一条清晰的依赖链:运行时引擎负责驱动执行,节点组合负责编排逻辑,能力模块负责提供具体功能。理解这三层的边界和协作方式,是深入掌握 Jianmu 全部子系统的基础。
三层架构全景¶
在深入各层之前,先用一张图建立全局视角:
graph TB
subgraph 配置层["配置层 (jianmu.yaml / .env)"]
CONFIG[Config Loader]
end
subgraph 运行时引擎层["运行时引擎层 (Engine)"]
AGENT[Agent / AgentTeam 外观]
RUNNER[ReactiveRunner 事件驱动调度器]
SM[StateManager 类型化状态]
CTX[RunContext 依赖容器]
INTERACT[InteractionController 挂起/恢复]
EVENTS[RuntimeEventBus 事件总线]
end
subgraph 节点组合层["节点组合层 (Node)"]
direction TB
PRESETS[预设模式: ReAct / Plan-Execute]
BUILTIN[内置节点: LLM / Tool / Skill / Swarm]
COMPOSITES[组合节点: Sequence / Selector / LoopUntilSuccess]
BASE[基类: AsyncNode / Node / JianmuNodeMixin]
PRESETS --> BUILTIN
PRESETS --> COMPOSITES
BUILTIN --> BASE
COMPOSITES --> BASE
end
subgraph 能力模块层["能力模块层 (Capability)"]
MODEL[Model 模型接入]
TOOL[Tool 工具系统]
SKILL[Skill 技能系统]
GUARD[Guard 防护审批]
EXEC[Execution 执行沙箱]
MEMORY[Memory 记忆系统]
SWARM[Swarm 多Agent]
MCP[MCP 外部协议]
RAG[RAG 知识检索]
TELE[Telemetry 遥测]
end
CONFIG --> AGENT
AGENT --> RUNNER
RUNNER --> SM
RUNNER --> CTX
RUNNER --> INTERACT
RUNNER --> EVENTS
RUNNER --> BASE
PRESETS --> MODEL
PRESETS --> TOOL
PRESETS --> GUARD
BUILTIN --> MODEL
BUILTIN --> TOOL
BUILTIN --> SKILL
BUILTIN --> SWARM
BUILTIN --> GUARD
BUILTIN --> EXEC
BUILTIN --> MEMORY
箭头方向表示依赖关系:运行时引擎驱动节点执行,节点在运行时消费能力模块提供的服务。配置层横切所有层级,提供全局参数默认值。
第一层:运行时引擎 (Runtime Engine)¶
运行时引擎是 Jianmu 的执行心脏,负责将行为树从初始状态驱动到终态(SUCCESS 或 FAILURE)。核心组件包括:
ReactiveRunner —— 事件驱动的 tick 调度器¶
ReactiveRunner 是整个框架最底层的执行驱动器。它绑定一棵 py_trees 行为树、一个 StateManager 状态管理器、以及一个可选的 RunContext 依赖容器。在初始化阶段,Runner 遍历整棵树的所有节点,通过 inject_runtime_deps() 向每个 Jianmu 原生节点注入运行时依赖(RunContext、StateManager、wake_up 回调)。
Runner 提供三个核心执行入口:
| 入口 | 语义 | 适用场景 |
|---|---|---|
tick_once() |
执行一次同步 tick | 最低层 API,交互式单步调试 |
step() |
一次异步 tick + step 级状态处理 | TUI / Studio 等交互应用 |
run() |
驱动树直到终态 | 标准 Agent 执行 |
Runner 内部使用 asyncio.Event 机制实现事件驱动的唤醒:当状态变化或异步节点完成时,通过 wake_up 回调触发 tick 信号,Runner 收到信号后执行下一轮 tick。这种设计避免了忙轮询(busy-wait),实现高效的异步调度。
StateManager —— 类型化状态管理¶
StateManager 是线程安全的状态容器,基于 Pydantic Schema 提供编译时类型校验和运行时状态合并。它支持三种关键机制:
- Reducer 合并:通过
Annotated标注自定义合并函数,实现增量更新而非全量覆盖 - Ephemeral 字段:通过
Ephemeral("step"|"run"|"call")标注临时字段,在指定粒度自动重置 - Change Listener:状态变更时通知订阅者(如 Runner),触发行为树重新 tick
class AgentState(BaseModel):
task: str = ""
final_answer: Annotated[str | None, Ephemeral("run")] = None
scratchpad: Annotated[list[str], Ephemeral("step")] = []
RunContext 与依赖注入¶
RunContext 是运行时依赖容器,承载不应序列化到状态中的共享服务对象:模型客户端、审批管理器、沙箱句柄、约束配置等。InjectPayload 将 RunContext、StateManager 和 wake_up 回调统一打包,由 Runner 注入每个节点。
@dataclass
class RunContext:
model_client: Any = None
approval_manager: Optional[ApprovalManager] = None
sandbox: Optional[Any] = None
constraints: Optional[Constraints] = None
runtime: Optional[Any] = None
prompt_runtime: Optional[PromptRuntimeContext] = None
runtime_event_bus: Optional[RuntimeEventBus] = None
InteractionController —— 挂起与恢复¶
运行时引擎内置完整的挂起/恢复协议,支持三种挂起类别:审批等待(REQUIRE_APPROVAL)、用户输入等待(REQUIRE_USER_INPUT)、外部执行等待(REQUIRE_EXTERNAL_EXECUTION)。挂起记录(SuspensionRecord)序列化到状态中,支持跨进程恢复。
RuntimeEventBus —— 运行时事件总线¶
RuntimeEventBus 是线程安全的内存事件总线,发布 RuntimeEvent 事件(如 reply.started、tool.call.completed、execution.failed)。上层应用(TUI、Studio)通过订阅这些事件实现 UI 实时更新。
Agent 与 AgentTeam 外观¶
Agent 和 AgentTeam 是面向用户的外观类,封装了 Runner 的构造、配置默认值解析、以及 Checkpoint 检查点接线。用户通常不直接操作 ReactiveRunner,而是通过 Agent 外观来运行单 Agent,通过 AgentTeam 来编排多 Agent 协作。
| 外观类 | 封装对象 | 用途 |
|---|---|---|
Agent |
ReactiveRunner + StateManager + Checkpointer | 单 Agent 执行 |
AgentTeam |
AgentRuntime + 角色注册 + 工具提供者 | 多 Agent Swarm 协作 |
第二层:节点组合 (Node Composition)¶
节点层是行为树编排的构建块,处于运行时引擎和能力模块之间的桥梁位置。节点从引擎层接收注入的依赖(RunContext、StateManager),在 tick 时调用能力模块的服务。
基类体系¶
Jianmu 的节点基类建立在 py_trees 之上,形成了清晰的继承层次:
| Jianmu 类 | py_trees 等价 | 说明 |
|---|---|---|
Node / Behaviour |
py_trees.behaviour.Behaviour |
同步节点基类 |
AsyncNode / AsyncBehaviour |
自定义扩展 | 异步节点基类,支持 update_async() |
Decorator |
py_trees.decorators.Decorator |
装饰器节点基类 |
JianmuNodeMixin 混入类为所有节点提供统一的端口绑定(port binding)和状态读写能力。每个节点可以声明输入端口(从状态读取数据)和输出端口(将结果写回状态),通过 bind(inputs=..., outputs=...) 完成端口到状态字段的映射。
内置节点分类¶
内置节点按功能域分为六类:
| 类别 | 节点 | 功能 |
|---|---|---|
| LLM | AgentLLMNode、SimpleLLMNode |
模型推理:上下文构建、模型调用、流式输出 |
| 工具 | ToolExecutor、ToolNode |
工具执行:LLM 工具调用解析、Guard 检查、沙箱运行 |
| 技能 | SkillNode |
技能加载与执行 |
| Swarm | SpawnAgent、SendMessage、WaitMessage |
多 Agent 通信原语 |
| 条件 | StateCondition |
基于状态断言的分支控制 |
| 工具 | Log、Wait、Timeout、EvaluationNode |
辅助节点 |
每个内置节点在 update_async() 中实现核心逻辑,通过 read_port() / write_port() 与状态交互,通过 self.ctx 访问能力模块。
预设模式:节点组合的模板¶
预设模式是将内置节点按最佳实践组装成可复用的子树。两种核心预设:
ReAct 预设 (create_react_node):组装 AgentLLMNode → ToolExecutor → StateCondition 的循环体,包裹在 LoopUntilSuccess 中,并附加 Token 预算检查的 abort 钩子。这是工具使用型 Agent 的默认模式。
Plan-Execute 预设 (create_plan_execute_node):实现规划 → 执行 → 审查的三阶段流水线,每个阶段由独立的 LLM 节点驱动。
# ReAct 预设的内部结构
loop_body = Sequence(children=[
AgentLLMNode(...), # LLM 推理 + 工具调用
ToolExecutor(...), # 执行工具调用
StateCondition(...), # 检查 done 标志
])
root = LoopUntilSuccess(child=loop_body, max_iterations=10)
自定义节点¶
Jianmu 提供两种自定义节点方式:
@node装饰器:最快的函数转节点方式,函数接收当前状态,返回状态更新字典- 继承
AsyncNode:重写update_async()实现完整的异步逻辑
@node
def my_node(state):
return {"result": process(state.task)}
class MyAsyncNode(AsyncNode):
async def update_async(self):
result = await some_io()
self.write_port("output", result)
return Status.SUCCESS
组合节点与行为树原语¶
Jianmu 通过 jianmu.tree 模块重导出 py_trees 的全部组合原语:Sequence(顺序执行)、Selector(优先选择)、Parallel(并行执行)及其装饰器(Inverter、SuccessIsFailure 等)。此外提供 Jianmu 特有的 LoopUntilSuccess,支持带 abort 条件的重试循环。
第三层:能力模块 (Capability Modules)¶
能力模块层是 Jianmu 最丰富的子系统集合,采用 Protocol 协议驱动设计——每个模块定义抽象接口,支持多种实现,用户可自由替换。各模块之间保持松耦合,通过 RunContext 在运行时组装。
模块全景表¶
| 模块 | 目录 | 核心抽象 | 关键实现 |
|---|---|---|---|
| 模型接入 | jianmu/model/ |
ModelProviderProtocol |
ModelClient → OpenAI Provider / LiteLLM Provider |
| 工具系统 | jianmu/tool/ |
Tool 基类 |
@tool 装饰器、ToolSet、ToolProvider、内建工具集 |
| 技能系统 | jianmu/skill/ |
SkillRecord、SkillLoader |
SkillsCatalog(工作空间覆盖内置)、行为树技能 / Prompt 技能 |
| Guard 防护 | jianmu/guard/ |
CheckerProtocol、GuardProtocol |
GuardEnforcer + 四类检查器(ToolPolicy、RateLimit、Budget、Confirm) |
| 执行沙箱 | jianmu/execution/ |
SandboxRunnerProtocol |
ToolRunner → LocalSandbox / DockerSandbox |
| 记忆系统 | jianmu/memory/ |
CheckpointerProtocol、ContextBuilderProtocol |
FileCheckpointer、ContextBuilder、Mem0 长期记忆 |
| 消息系统 | jianmu/message/ |
Message |
StateMessageStore、消息编码/保留策略 |
| Swarm 多Agent | jianmu/swarm/ |
AgentRole、AgentRuntimeProtocol |
AgentRuntime(邮箱路由、事件总线、生命周期)、AgentTeam 外观 |
| MCP 集成 | jianmu/mcp/ |
- | MCPClient、MCPToolProvider、MCP Server |
| RAG 检索 | jianmu/rag/ |
- | Embedder、Retriever、Reranker、KnowledgeBase 流水线 |
| 遥测系统 | jianmu/telemetry/ |
- | TelemetryHub、多 Sink 输出、Span 追踪 |
模型接入模块¶
ModelClient 是统一的模型调用外观,封装了 provider 解析(按凭证可用性自动选择 OpenAI 或 LiteLLM)、重试与 fallback 策略、流式输出、以及遥测埋点。调用路径为:
工具系统模块¶
Tool 抽象基类定义了工具的执行契约:run() 方法实现核心逻辑,execute() 方法提供统一的调用路径(支持注入参数、沙箱委托)。ToolSet 聚合多个工具并生成 LLM function-calling schema。ToolProvider 协议支持动态工具发现(如 Swarm 工具、MCP 工具)。
Guard 防护模块¶
GuardEnforcer 组合多个检查器形成防护链,按序评估每个工具调用。检查器链默认包含:ToolPolicyChecker(白名单/黑名单)→ RateLimitChecker(频率限制)→ BudgetChecker(Token 预算)→ ConfirmChecker(人工审批)。遇到 DENY 立即阻断,CONFIRM 暂缓并等待审批。
执行沙箱模块¶
ToolRunner 是工具执行的外观,根据配置选择 LocalSandbox(直接在当前进程执行)或 DockerSandbox(在隔离容器中执行)。每次执行发出 execution.started → execution.completed / execution.failed 生命周期事件。
Swarm 多 Agent 模块¶
AgentRuntime 是多 Agent 运行时的核心实现,管理 Agent 主机的生命周期(spawn / kill / pause / resume / preempt),提供邮箱路由(SendMessage / WaitMessage 通信原语)、事件总线和快照持久化。AgentTeam 外观封装了 AgentRuntime 的构造和默认值解析。
层级间的数据流¶
整个架构的运行时数据流清晰分层:
sequenceDiagram
participant U as 用户代码
participant A as Agent 外观
participant R as ReactiveRunner
participant N as 行为树节点
participant S as StateManager
participant C as 能力模块
U->>A: agent.run(input_data)
A->>R: runner.run(input)
R->>S: merge input_data
loop 事件驱动 tick 循环
R->>R: tick_signal.wait()
R->>N: tree.tick() → update_async()
N->>S: read_port() 读取状态
N->>C: 调用能力模块 (model_client.invoke / tool.execute)
C-->>N: 返回结果
N->>S: write_port() 写入状态
S-->>R: wake_up() 通知状态变化
R->>R: tick_signal.set()
end
R-->>A: RunResult
A-->>U: 最终结果
配置层的横切作用¶
配置系统(jianmu/config/)横切所有三层,由 jianmu.yaml、.env 和代码默认值三重来源合并,通过 get_config() 全局访问。JianmuConfig 包含模型默认值、运行时参数(max_fps、checkpoint 间隔)、路径配置、Prompt 模板、LLM 超参数默认值等。运行时引擎和节点在初始化时从配置中读取默认参数,允许用户在调用时显式覆盖。
阅读建议¶
本文建立了 Jianmu 三层架构的全局视图。建议按以下顺序深入各子系统:
- 行为树执行内核:深入理解
AsyncBehaviour如何扩展py_trees,以及JianmuNodeMixin的端口绑定机制 - 类型化状态管理:深入 StateManager 的 Reducer 合并、Ephemeral 字段和线程安全设计
- ReactiveRunner:深入事件驱动调度、挂起恢复协议和 Checkpoint 机制
- Agent 与 AgentTeam 外观模式:理解外观模式如何简化运行时组装
- 节点体系全景:深入节点系统的完整设计
能力模块各专题则可以在需要时分别查阅,详见导航目录中的"运行时能力模块"和"扩展与集成"分组。