OPENJIUWEN / AGENT CORE ARCHITECTURE

Agent Core · 四视图

Agent Core(openjiuwen) 是构建和运行智能体的 Python SDK,提供 Agent 与工作流执行、模型和工具接入、会话状态管理,并支持团队协作与能力演进。

从职责、代码依赖、异步执行和部署位置四个角度理解 Core,并对照 Studio Runtime 的服务边界。

源码快照:openjiuwen 0.1.18 · c0491a4dc222 · 2026-09-18 · 每图附 8 节解读与源码定位

逻辑视图

CAPABILITIES / COLLABORATION

先看职责分工:宿主通过 SDK 组织执行,Agent、Workflow 和 Team 复用状态与基础能力;Harness 和演进模块在其上提供更完整的任务能力。箭头表示主要调用或支撑关系,不是每次请求必须经过的流水线。

Agent Core 逻辑视图宿主通过 Runner 运行 Agent、Workflow 和 Team,三类执行复用状态与基础能力;评估和演进流程按需调用运行能力。01 / LOGICAL VIEWSDK 内的执行职责与共享支撑 · 箭头不是固定的请求流水线三类执行共同复用 · 按需调用Python 调用按需评估执行HOST宿主应用 / Studio RuntimePython API · CLI · IR 适配SDKRunner · 统一执行入口run_agent / run_workflow / run_agent_teamOPTIONAL评估与能力演进Trainer · RSI · SymphonyEXECUTIONAgent / HarnessReActAgent · DeepAgent模型 / 工具循环 · Rails · 子代理EXECUTIONWorkflow / GraphWorkflow → Pregel节点 / 分支 / 循环 · 异步图调度EXECUTIONTeam · 多智能体协作BaseTeam / TeamAgentSpecLeader / Teammate · 消息 / 任务STATE会话、上下文与恢复Session · Context · CheckpointerSHARED模型、工具与系统能力LLM · MCP · SysOperation · 检索 / 记忆ADAPTERS集成、持久化与观测Store · Sandbox · A2A · OTel主要调用按需路径共享框:由上层执行对象复用集成框:具体适配实现

先看职责分工:宿主通过 SDK 组织执行,Agent、Workflow 和 Team 复用状态与基础能力;Harness 和演进模块在其上提供更完整的任务能力。箭头表示主要调用或支撑关系,不是每次请求必须经过的流水线。

01

Core 的边界:供应用嵌入的 SDK

Agent Core 是构建和运行智能体的 Python SDK。它提供 Agent、Workflow、模型工具接入、会话状态和执行调度。业务应用、脚本、CLI 或 Studio Runtime 把这些对象装配起来,再调用 Python 方法执行任务。

Studio Runtime 在它外面增加 HTTP 接口、请求编排、IR 转换和响应适配。之前图中的 IRConverter 位于 Studio 的运行服务代码中,它将 Studio 的配置转成 Core 的 Workflow 等执行对象;Core 的 Workflow 再负责图编译与执行。这两个转换层承担不同职责。

本页分析的是当前工作树里的 Core 源码。Studio 的依赖声明指向 develop 分支,因此不能仅凭目录并列就断言某个线上 Runtime 已安装本页这一个提交。

源码依据:
pyproject.toml:5
Studio / agent-runtime/pyproject.toml:4
Studio / agent-runtime/pyproject.toml:13
Studio / agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:94
Studio / agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:980

02

Runner:统一入口与资源登记

Runnerrun_agentrun_workflowrun_agent_team 及各自的流式方法汇集到一个公共入口。它代理进程内的 GLOBAL_RUNNER,准备或复用 Session,并把调用交给具体执行对象。

Runner.resource_mgr 是资源目录:按 ID 登记或查找 Agent、Workflow、Tool、Model、Prompt、系统操作及 MCP 服务。传入对象时可以直接使用对象;传入字符串 ID 时需要先注册。Card 描述身份和输入输出,Config 控制运行行为,实际实例或工厂提供可执行实现。

这里没有 Studio 的“三种顶层 Runner 按 IR 模式分发”。调用哪个 Core API 由宿主决定,Agent 也能在执行期间再调用 Workflow 或其他能力。

源码依据:
openjiuwen/core/runner/runner.py:359
openjiuwen/core/runner/runner.py:408
openjiuwen/core/runner/runner.py:651
openjiuwen/core/runner/runner.py:682
openjiuwen/core/runner/resources_manager/resource_manager.py:194
openjiuwen/core/runner/resources_manager/resource_manager.py:300
openjiuwen/core/single_agent/schema/agent_card.py:16

03

Agent 与 Harness:决策循环和任务外层

ReActAgent 读取上下文并调用模型。如果模型产生工具调用,就通过 AbilityManager 执行,再将结果加入上下文,继续下一轮;满足结束条件、达到迭代上限或出现交互中断时离开循环。

AbilityManager 统一处理不同能力,包括普通工具、MCP 工具和工作流。工作流能力会转调 Runner.run_workflow,所以“单 Agent”也可以在内部运行复杂工作流。

DeepAgent 位于 harness 包,内部持有一个 ReActAgent,并增加任务循环、工作空间、子代理、工具权限和 Rails。它是对基础 Agent 的组合与增强,并不是把每次任务都改成另一个独立进程。

源码依据:
openjiuwen/core/single_agent/agents/react_agent.py:2739
openjiuwen/core/single_agent/agents/react_agent.py:2793
openjiuwen/core/single_agent/ability_manager.py:1078
openjiuwen/core/single_agent/ability_manager.py:1360
openjiuwen/harness/deep_agent.py:295
openjiuwen/harness/deep_agent.py:463
openjiuwen/harness/factory.py:457

04

Workflow:从组件图到可执行图

宿主通过 set_start_compadd_workflow_compadd_connection 等方法创建节点和连接,声明输入映射、分支、循环及流式连接。节点可以是模型、工具、子工作流,也可以是自定义组件。

执行时,Workflow → BaseWorkflow.compile → PregelGraph.compile → Pregel 把这些定义交给图引擎。引擎按就绪条件推进节点;同一轮中的就绪节点创建异步任务,等待本轮结果后更新通道,决定下一轮。

invoke 汇集最终结果;stream 逐段产生输出。二者共用内部流式执行链,因此“只要最终结果”不意味着另有一套同步图引擎。

源码依据:
openjiuwen/core/workflow/workflow.py:136
openjiuwen/core/workflow/workflow.py:279
openjiuwen/core/workflow/workflow.py:328
openjiuwen/core/workflow/workflow.py:501
openjiuwen/core/workflow/_workflow.py:293
openjiuwen/core/graph/graph.py:239
openjiuwen/core/graph/pregel/engine.py:99
openjiuwen/core/graph/pregel/task.py:27

05

Team:两套协作层次,共用运行基础

core.multi_agent 提供 BaseTeam、TeamCard 和基础团队模式;更高层的 agent_teams 提供 Leader / Teammate、任务与消息协调、持久会话和成员运行管理。

当前常规团队入口使用 TeamAgentSpec,由 TeamRuntimeManager.activate 决定创建、复用或恢复团队,再调用团队 Agent。相同的 Runner 公共方法以 base=True 切换到 BaseTeam 路径。两套体系不能仅因为名称接近就视为同一个实现。

团队成员可以使用本地 Harness,也能通过 harness_protocol 和 Provider 适配外部 Harness。使用哪个 Provider、是否另起进程,属于具体运行配置,不是“多智能体”这四个字自动决定的。

源码依据:
openjiuwen/core/multi_agent/__init__.py:4
openjiuwen/agent_teams/__init__.py:1
openjiuwen/core/runner/team_runner.py:151
openjiuwen/core/runner/team_runner.py:862
openjiuwen/agent_teams/runtime/manager.py:115
openjiuwen/harness_providers/factory.py:35

06

共享状态:Session、Context 和 Checkpoint

Session 管一段执行的身份与状态,Context 管喂给模型的上下文,Checkpoint 管可恢复数据。三者相关,但不等价。Agent Session 还能创建 Workflow Session,让嵌套执行有明确归属。

默认 Checkpointer 是进程内内存实现;可换成持久化后端。Pregel 恢复时读取图状态,重建通道、待执行节点和步数。长期记忆与知识检索是可选能力,不应和一次请求的临时状态混为一谈。

流式输出由 Session 的流写入与读取设施连接执行方和消费方。SDK 交付的是 Python 对象和异步迭代器;变成 SSE、WebSocket 或产品中的消息,还需要宿主的协议适配。

源码依据:
openjiuwen/core/session/agent.py:33
openjiuwen/core/session/agent.py:236
openjiuwen/core/context_engine/__init__.py:1
openjiuwen/core/session/checkpointer/checkpointer.py:108
openjiuwen/core/graph/pregel/engine.py:39
openjiuwen/core/session/checkpointer/persistence.py:725
openjiuwen/core/memory/__init__.py:1
openjiuwen/core/retrieval/__init__.py:1

07

基础能力与外部集成

foundation 提供模型、工具、提示词和存储等基础抽象;sys_operation 提供本地或沙箱系统操作;检索、记忆、回调和安全能力支撑上层执行。图中将这些合并成共享支撑框,避免把每个适配器画成一个服务。

extensions 则放具体集成,例如 Redis Checkpointer、Pulsar、A2A、对象或向量存储、沙箱与可观测性。Harness 的 Rails 可以在模型调用、工具调用等事件上施加行为约束;资源可用、工具被暴露、工具获准执行,是不同环节。

模型端点、MCP 服务器和远程存储在进程之外,SDK 中的客户端只是连接它们的适配代码。安装 Core 不会自动把这些外部服务一并部署好。

源码依据:
openjiuwen/core/runner/resources_manager/resource_manager.py:543
openjiuwen/core/runner/resources_manager/resource_manager.py:734
openjiuwen/core/runner/resources_manager/resource_manager.py:964
openjiuwen/core/foundation/llm/__init__.py:1
openjiuwen/core/sys_operation/__init__.py:1
openjiuwen/harness_providers/factory.py:83
pyproject.toml:105

08

评估与演进:围绕执行闭环扩展

agent_evolving 将数据、执行轨迹、评估器、优化器和 Trainer 组织为训练或经验更新过程。dev_tools 提供开发调优工具;这些流程会利用执行结果,但不是每次普通 Agent 请求都必须启动的阶段。

rsi 面向 Harness 及程序、论文等产物的迭代改进;auto_harness 当前已是迁移到 RSI 后的兼容导出。symphony 提供能力指纹、评估、关系图、编排与运行时演进接口,其职责是组织能力资产。

把整张图串起来:宿主先装配资源和执行对象,通过 Runner 发起任务;执行对象使用共享状态与模型工具能力,产出结果和轨迹;需要调优时,再把这些证据交给评估与演进流程。

源码依据:
openjiuwen/agent_evolving/trainer/trainer.py:34
openjiuwen/agent_evolving/trainer/trainer.py:145
openjiuwen/agent_evolving/__init__.py:1
openjiuwen/dev_tools/tune/trainer/trainer.py:1
openjiuwen/rsi/__init__.py:1
openjiuwen/auto_harness/__init__.py:3
openjiuwen/symphony/__init__.py:10
openjiuwen/symphony/runtime.py:43

开发视图

PACKAGE DEPENDENCIES

再看代码归属:仓库名是 agent-core,安装包名是 openjiuwen,core 只是其中一个子包。图中挑出 9 个依赖单元,下面的模块表补全其余目录;箭头由使用方指向被依赖方,徽标仅统计图中入边。

Agent Core 开发视图代码包按依赖分层,Harness 与 Runner 共同使用 Agent,Agent 能力又延迟回调 Runner;图外模块在正文补全。02 / DEVELOPMENT VIEW包级依赖的主要骨架 · 9 个聚合单元,不是完整 import 图CYCLE · 能力回调PACKAGE0 inagent_teams团队 Spec / 生命周期 / 成员PACKAGE1 inharness_providers原生与第三方 Harness 适配PACKAGE0 inextensions远程协议 / 存储 / 可观测性PACKAGE2 inharnessDeepAgent / Rails / 工具 / 子代理PACKAGE1 inharness_protocolProvider 无关的契约与事件PACKAGE2 incore.runner门面 / 资源管理 / spawn / drunnerPACKAGE2 incore.single_agentReActAgent / AbilityManagerPACKAGE2 incore.workflow + graph组件定义 / Pregel 图执行PACKAGE2 in会话与基础模块session / context / foundation使用方 → 依赖方CYCLE:AbilityManager 延迟回调 RunnerN in:仅统计图内入边

再看代码归属:仓库名是 agent-core,安装包名是 openjiuwen,core 只是其中一个子包。图中挑出 9 个依赖单元,下面的模块表补全其余目录;箭头由使用方指向被依赖方,徽标仅统计图中入边。

01

仓库、安装包和服务包的关系

仓库目录叫 agent-corepyproject.toml 声明的 Python distribution 和 import 命名空间都是 openjiuwen,当前源码版本为 0.1.18,Python 要求为 >=3.11,<3.14

openjiuwen/core 包含通用执行原语;Harness、团队协作、演进和集成包与它处在同一命名空间下。Studio 的 agent-runtime 是另一个项目中的服务封装,通过依赖声明和 import 使用 Core。

因此,逻辑图中的“运行入口”对应 Python SDK 方法,而开发图中的框对应包或模块组;不能把任意一个 Python 包直接理解成一项独立部署的微服务。

源码依据:
pyproject.toml:5
Studio / agent-runtime/pyproject.toml:4
Studio / agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:94

02

core/runner:公共门面、资源目录和运行辅助

runner.py 定义 Runner 门面和全局实现,resources_manager 管理各类可执行资源,team_runner.py 接入团队生命周期;spawn 提供子进程启动与通信,drunner 放远程调用和消息队列适配。

Runner 对 Agent 和 Workflow 的主要作用是解析实例、准备会话并调用 invoke / stream。具体“下一步做什么”仍由 ReAct、图引擎或团队控制逻辑决定。

资源管理是进程级共享状态,并不是分布式注册中心。多个进程里的全局 Runner 是不同 Python 对象;跨进程复用需要远程协议或可共享的持久化设施。

源码依据:
openjiuwen/core/runner/runner.py:78
openjiuwen/core/runner/runner.py:359
openjiuwen/core/runner/runner.py:408
openjiuwen/core/runner/runner.py:682
openjiuwen/core/runner/resources_manager/resource_manager.py:68
openjiuwen/core/runner/spawn/process_manager.py:461
openjiuwen/core/runner/team_runner.py:151

03

core 的执行包与兼容边界

single_agent 包提供当前 AgentCard / Config / ReActAgent / AbilityManager API。其 legacy 子包保留旧接口;applicationcontroller 中还有供已有应用使用的控制与组合能力。画图时不能只照抄 README 中的旧示例,忽略当前导出。

workflow 负责组件与连线、输入映射、流接口和执行生命周期;graph 负责 Pregel 编译、通道、节点任务和图状态。两者是上下层关系:Workflow 表达业务流程,Graph 提供执行机制。

sessioncontext_engine 是多条执行路径共享的依赖。图里向共享模块汇合的多条箭头,表达的是复用关系,不代表组件之间必须按从左到右的顺序执行。

源码依据:
openjiuwen/core/single_agent/__init__.py:4
openjiuwen/core/single_agent/__init__.py:23
openjiuwen/core/workflow/workflow.py:98
openjiuwen/core/workflow/_workflow.py:293
openjiuwen/core/graph/graph.py:239
openjiuwen/core/graph/pregel/engine.py:25
openjiuwen/core/session/agent.py:33

04

harness:将 ReAct 组合成完整任务代理

公共构造入口是 create_deep_agent。Factory 负责解析和装配配置;DeepAgent 持有内部 ReActAgent,把工具、提示词、Rails、工作空间、子代理和任务循环组合起来。

这层增加的是长任务所需的控制行为:例如继续输入、任务循环、权限交互、子代理管理和工作空间操作。底层仍复用 Core 的模型、会话和能力执行设施。

图中“harness → core.single_agent”的箭头来自真实代码组合关系;它不是继承关系的 UML 图,也不表示 Harness 和 ReAct 必须部署在不同服务中。

源码依据:
openjiuwen/harness/factory.py:163
openjiuwen/harness/factory.py:188
openjiuwen/harness/factory.py:420
openjiuwen/harness/factory.py:457
openjiuwen/harness/deep_agent.py:295
openjiuwen/harness/deep_agent.py:463

05

协议与 Provider:把第三方 Harness 接进来

harness_protocol 定义 Provider 无关的契约与事件模型;harness_providers 提供实现、统一生命周期以及 I/O 适配。工厂当前识别 nativenative_v2claudecodecodexdsh

Provider 不会把第三方系统变成 Core 内部的 ReAct。适配器负责对齐输入、事件、交互和结果,让上层可以用共同接口驱动不同实现;具体能力仍由各 Provider 声明。

原生 Provider 使用本地 DeepAgent;第三方 SDK 通过可选依赖安装。清单中的模型、Prompt、MCP 等配置可以映射给 Provider,但本地工具、Rails 和子代理这类扩展不能被假定为跨 Provider 自动等价。

源码依据:
openjiuwen/harness_protocol/__init__.py:1
openjiuwen/harness_providers/factory.py:18
openjiuwen/harness_providers/factory.py:35
openjiuwen/harness_providers/factory.py:42
openjiuwen/harness_providers/io_adapter.py:1
pyproject.toml:129

06

两个多智能体目录如何分工

core.multi_agent 面向基础团队抽象和组合模式;顶层 agent_teams 在此之外提供更完整的协作运行系统,包括 Spec、Leader / Teammate、消息与任务管理、成员 Harness 和会话恢复。

它们通过 Runner 的团队入口接入。常规 Spec 路径按需创建 TeamRuntimeManager;BaseTeam 路径由 base=True 明确选择。开发视图将两者分别解释,避免把它们误认为一次简单目录重命名。

同样,团队成员数、Python Task 数和操作系统进程数是三种不同数量:Spec 和成员运行方式决定对象组合,进程边界要看实际 spawn 或外部 Provider 路径。

源码依据:
openjiuwen/core/multi_agent/__init__.py:4
openjiuwen/agent_teams/__init__.py:1
openjiuwen/core/runner/team_runner.py:121
openjiuwen/core/runner/team_runner.py:151
openjiuwen/core/runner/team_runner.py:862
openjiuwen/agent_teams/runtime/manager.py:104
openjiuwen/core/runner/spawn/process_manager.py:461

07

主图之外的完整模块地图

目录 / 模块组主要职责与边界
core/foundation模型、工具、提示词、存储等基础能力和抽象。
core/sessioncontext_enginekv_cache执行状态、模型上下文与 KV Cache 关联;不等同于长期记忆。
core/memoryretrieval记忆与知识检索;按场景接入。
core/sys_operationsecuritycommon系统操作、安全与通用设施;Harness 另有自己的工具权限及 Rails 层。
extensionsRedis、Pulsar、A2A、存储、沙箱、可观测性等具体适配实现。
agent_evolvingdev_tools评估、优化、经验、训练与开发调优。
rsiauto_harnessHarness / 产物递归改进;后者当前是兼容导出。
symphony能力指纹、评估、关系图、编排与运行时演进接口。

主图聚合了这些模块,省略细粒度 import 边。模块地图表达源码职责,不能据此推断所有模块都在每次请求中被加载或调用。

源码依据:
openjiuwen/core/foundation/llm/__init__.py:1
openjiuwen/core/context_engine/__init__.py:1
openjiuwen/core/memory/__init__.py:1
openjiuwen/core/retrieval/__init__.py:1
openjiuwen/core/sys_operation/__init__.py:1
openjiuwen/agent_evolving/__init__.py:1
openjiuwen/rsi/__init__.py:1
openjiuwen/auto_harness/__init__.py:3
openjiuwen/symphony/__init__.py:10

08

阅读源码时,要分清代码、文档和部署事实

这份说明以当前公共导出、调用点和实现为依据,记录源码提交与引用行号。README 和模块文档用于辅助定位;旧接口示例、设计蓝图与当前实现不一致时,以已检查的代码为准。

一个具体例子是分布式 MQ:Pulsar 实现在 extensions/message_queue/message_queue_pulsar.py,但工厂仍导入 extensions.runner.pulsar_mq.message_queue_pulsar,当前工作树里没有这个目标路径。因此页面将它画为可选但存在接线缺口的路径,不能把“目录中有实现”写成“启用即可运行”。

页面验证覆盖源码引用、图形几何、正文可读性和发布链接;没有运行真实模型、Pulsar 或 A2A 的端到端联调。图示的是这份源码的结构和行为依据。

源码依据:
openjiuwen/core/runner/drunner/dmessage_queue/message_queue_factory.py:14
openjiuwen/core/runner/drunner/dmessage_queue/message_queue_factory.py:24
openjiuwen/extensions/message_queue/message_queue_pulsar.py:106
openjiuwen/core/single_agent/__init__.py:23
openjiuwen/symphony/__init__.py:69

进程视图

ASYNC EXECUTION / SEQUENCE

以一次本地 Workflow 流式执行说明运行时协作。前四条生命线是同一 Python 进程内的对象或协程职责,只有最右侧是外部端点;它们不代表四个 worker。ReAct、Team、取消和子进程差异在下方展开。

Agent Core 进程视图一次本地 Workflow 流式调用在同一 Python 进程中创建后台执行与节点任务,Pregel 重复调度就绪节点,同时把输出流交付宿主;外部模型工具通过 I/O 调用。03 / PROCESS VIEW本地 Workflow 流式执行 · 前四个参与者同属一个 Python 进程LOOP重复超步 · 输出帧按需产生run_workflow_streamingcompile / invoke恢复状态 / 选择节点create_task × N模型 / 工具 I/O结果 / chunk写入 Session 输出流yield chunk汇合本轮任务结果图执行结束流关闭 / 迭代完成CALLER宿主消费协程async for chunkIN PROCESSRunner / Workflow准备 Session · 后台执行IN PROCESSPregel 调度协程就绪节点 · 通道 · 图状态IN PROCESS节点任务 × Nasyncio TasksEXTERNAL模型 / 工具端点网络或其他 I/O调用 / 提交结果 / 完成主输出流生命线 ≠ 独立进程

以一次本地 Workflow 流式执行说明运行时协作。前四条生命线是同一 Python 进程内的对象或协程职责,只有最右侧是外部端点;它们不代表四个 worker。ReAct、Team、取消和子进程差异在下方展开。

01

先分清进程、执行对象与异步任务

默认嵌入式运行中,宿主 Python 进程持有 Runner、资源实例、Session 和事件循环。图中的 Runner、Workflow、Pregel、节点任务是同一进程内的职责分解;它们没有各自独立的操作系统进程。

一次工作流执行可以生成一个后台执行任务和多个节点 Task。多个 Task 在等待模型或工具 I/O 时交错推进。只有显式调用子进程入口、使用外部 Harness,或访问远程 Agent,才引入额外进程或主机边界。

这与 Studio 进程图的视角不同:Studio 先有 HTTP worker,再由该 worker 内的协程进入 Core;本图从 SDK 调用开始展开 worker 内部发生的事情。

源码依据:
openjiuwen/core/runner/runner.py:78
openjiuwen/core/runner/runner.py:137
openjiuwen/core/workflow/workflow.py:524
openjiuwen/core/workflow/workflow.py:534
openjiuwen/core/graph/pregel/task.py:27
openjiuwen/core/runner/spawn/process_manager.py:461

02

Runner 准备实例与 Session

调用 Runner.run_workflow_streaming 后,Runner 根据参数判断传入的是 Workflow 实例还是资源 ID。实例直接使用;ID 则从资源管理器取出。Session 可以来自会话 ID、已有 Workflow Session,或由 Agent Session 派生。

Runner 将调用委托给 Workflow.stream,并在异步迭代时逐段向宿主交付 chunk。对 Agent 来说,Runner 还会准备 Agent Session,并在正常执行完成后调用 post_run

“准备”没有把整张工作流提交给一个固定的远程队列。本地 API 的主路径就是进程内的方法调用;分布式和消息订阅是另外配置的能力。

源码依据:
openjiuwen/core/runner/runner.py:380
openjiuwen/core/runner/runner.py:438
openjiuwen/core/runner/runner.py:499
openjiuwen/core/runner/runner.py:511
openjiuwen/core/runner/runner.py:651

03

图编译与超步调度

Workflow 启动后台 stream_process,在其中编译并调用执行图。PregelLoop 先查看是否有可恢复的状态;没有时从起点触发,有状态时恢复通道、步数和待执行节点。

每一轮称为一个“超步”:先确定就绪节点,再为它们创建 Task,等待本轮任务结果,最后把结果转为通道消息并推进下一轮。不是任意节点都能同时执行,依赖、分支和汇合条件会决定谁已就绪。

图中的 LOOP 框代表这段重复调度。若节点里还包含循环或子工作流,会继续在这一机制上组合,而不是为每个节点分配一个 worker 进程。

源码依据:
openjiuwen/core/workflow/workflow.py:524
openjiuwen/core/workflow/_workflow.py:293
openjiuwen/core/graph/graph.py:239
openjiuwen/core/graph/pregel/engine.py:39
openjiuwen/core/graph/pregel/engine.py:99
openjiuwen/core/graph/pregel/task.py:27

04

并发来自 await,不存在固定的“每 Core 并发数”

TaskExecutorPool.submit 使用 asyncio.create_task;本轮等待使用 asyncio.wait(..., FIRST_EXCEPTION)。没有异常时等待任务完成;出现异常时会处理失败并取消仍在运行的同批任务。这里的 Pool 名称不意味着操作系统进程池。

ReAct 的工具调用还支持并行配置,并会按工具的并行安全属性与资源顺序安排执行。I/O 等待适合异步重叠,阻塞式或 CPU 密集的代码则可能拖住同一事件循环,不能把 Task 数当成 CPU 并行度。

实际并发受宿主进程数、业务任务成本、模型限流、连接池和存储吞吐约束。队列大小或分布式请求上限只是局部配置,不是吞吐承诺;需要使用真实任务测量延迟、内存和错误率。

源码依据:
openjiuwen/core/graph/pregel/task.py:19
openjiuwen/core/graph/pregel/task.py:40
openjiuwen/core/single_agent/ability_manager.py:329
openjiuwen/core/single_agent/ability_manager.py:393
openjiuwen/core/single_agent/ability_manager.py:431
openjiuwen/core/single_agent/ability_manager.py:1148
openjiuwen/core/runner/runner_config.py:39
openjiuwen/core/runner/message_queue_inmemory.py:27

05

执行和流消费同时推进

图执行在后台生产数据,Workflow 外层从 StreamWriterManager 消费输出并 yield 给上层,因此无需等所有节点完成才显示第一段结果。图完成时,执行侧关闭 emitter,消费侧完成等待并在适用时输出 workflow_final

invoke 也复用这条内部链,只是将输出收集成 WorkflowOutput。遇到交互事件时,返回状态是 INPUT_REQUIRED;正常结束为 COMPLETED

SDK 的 chunk 可以包含业务输出、调试或交互信息。是否逐段转发、怎样转换成 SSE、怎样响应客户端断开,由宿主服务和所选 stream modes 决定。

源码依据:
openjiuwen/core/workflow/workflow.py:365
openjiuwen/core/workflow/workflow.py:501
openjiuwen/core/workflow/workflow.py:528
openjiuwen/core/workflow/workflow.py:542
openjiuwen/core/workflow/workflow.py:549
openjiuwen/core/session/agent.py:236

06

中断恢复与取消是两种不同语义

交互中断表示流程需要新的输入才能继续。图引擎将相关的待执行节点、通道和图状态交给存储;后续执行使用相应会话身份和交互输入,恢复这段逻辑状态。

取消表示正在运行的异步任务收到停止请求。Workflow 会取消未结束的后台任务,Pregel 会取消本轮节点任务并继续传播取消。取消不能撤回已经发送到外部工具的写操作,也不能保证所有第三方调用立即停止。

Checkpoint 恢复的是执行数据,不是原来的 Task、线程或进程。默认内存 Checkpointer 在进程结束后不会保留;跨重启恢复还需要适当的持久后端、相容的执行定义和正确的 Session 标识。

源码依据:
openjiuwen/core/graph/pregel/engine.py:64
openjiuwen/core/graph/pregel/engine.py:174
openjiuwen/core/graph/pregel/engine.py:39
openjiuwen/core/graph/pregel/task.py:97
openjiuwen/core/workflow/workflow.py:567
openjiuwen/core/workflow/workflow.py:588
openjiuwen/core/session/checkpointer/checkpointer.py:108
openjiuwen/core/session/checkpointer/persistence.py:725

07

Agent 与 Team 的运行如何套进来

ReAct 在一次调用内反复执行模型与能力循环。调用 Workflow 能力时,AbilityManager 创建或派生 Workflow Session,再进入本图的工作流链。单 Agent 和工作流可以嵌套,不是每次只能二选一。

高层团队由 TeamRuntimeManager 选择启动或恢复动作,再执行 Leader;成员的消息、任务和交互由团队运行层协调。Team 的并发门禁与生命周期是额外约束,不能用“异步就可以无限并发”来推断同一会话的行为。

Runner.start 建立运行期 TaskGroup;停止时会取消相关后台任务并释放资源。资源注册表、运行中的任务与持久会话是三个不同层面,各有自己的清理责任。

源码依据:
openjiuwen/core/single_agent/agents/react_agent.py:2739
openjiuwen/core/single_agent/ability_manager.py:1360
openjiuwen/core/runner/team_runner.py:151
openjiuwen/agent_teams/runtime/manager.py:115
openjiuwen/core/runner/runner.py:137
openjiuwen/core/runner/runner.py:267
openjiuwen/core/runner/runner.py:329
openjiuwen/core/common/task_manager/manager.py:252

08

什么时候才会真的出现另一个进程

Runner.spawn_agent 接收可序列化的 SpawnAgentConfig,调用 asyncio.create_subprocess_exec 启动当前 Python 解释器,以 -m openjiuwen.core.runner.spawn.child_process 进入子进程。

父子之间通过标准输入输出管道传送消息;返回的 SpawnedProcessHandle 提供 PID、状态、消息、关闭及健康检查操作。子进程会有自己的 Runner 和 Python 内存,父进程的资源对象不会因同名而自动共享。

另一路是远程 Agent 的 A2A / MQ 通信,或者第三方 Harness SDK 自己管理的进程。它们应在部署视图中按实际边界展开,不能把普通 run_agent 一律理解为远程调度。

源码依据:
openjiuwen/core/runner/runner.py:541
openjiuwen/core/runner/runner.py:587
openjiuwen/core/runner/spawn/process_manager.py:33
openjiuwen/core/runner/spawn/process_manager.py:461
openjiuwen/extensions/a2a/a2a_server_adapter.py:26
openjiuwen/harness_providers/factory.py:42

部署视图

EMBEDDED SDK / OPTIONAL ENDPOINTS

Core 的主要部署形式是安装进宿主 Python 环境。图中展示代码支持的运行位置与可选通信路径;机器、容器、副本与网络端口由宿主配置,不能照搬 Studio Runtime 的 Kubernetes 模板。

Agent Core 部署视图Core SDK 安装在宿主 Python 进程中,可选启动本机子进程或调用 A2A 远端 Agent,并按配置接入模型工具、状态存储和消息队列;Pulsar 工厂在当前快照有导入路径缺口。04 / DEPLOYMENT VIEW默认嵌入宿主进程;跨进程、远端与持久化均由使用方选择宿主机器 / 容器 · 实例数由应用配置可配置依赖 · 实际部署位置由使用方决定可选远端主机 / 容器HTTP(S)协议 / 端口:按后端MQstdin / stdoutA2A HTTP(S):配置PYTHON宿主 Python 进程业务服务 / CLI / Studio Runtime应用版本openjiuwen SDK0.1.18Runner + 执行对象 + Event Loop默认:distributed_mode = falseSession / Checkpointer:默认进程内存OPTIONALPython 子进程 · 按需启动spawn.child_process · openjiuwen 0.1.18ENDPOINT模型 / 工具端点LLM · HTTP · MCPOPTIONAL状态与数据后端KV / Redis / DB · 按功能接入MQPulsar 适配(可选)当前工厂导入路径待核对OPTIONALA2A 远端 AgentPython / SDK · 按应用版本监听地址 / 端口来自配置跨边界调用可选路径非默认组件版本与位置见正文依据

Core 的主要部署形式是安装进宿主 Python 环境。图中展示代码支持的运行位置与可选通信路径;机器、容器、副本与网络端口由宿主配置,不能照搬 Studio Runtime 的 Kubernetes 模板。

01

基础落点:把 Core 安装进宿主 Python 环境

最基本的形态是一台开发机、虚拟机或容器中的 Python 应用,安装 openjiuwen 并调用 SDK。宿主可以是 Studio Runtime,也可以是自己的 API 服务、CLI 或批处理脚本。

图中版本 0.1.18 来自这份源码的 pyproject 声明,表示本次分析对象;它不是对任何线上环境已安装版本的探测。主机和副本由宿主部署方案决定,所以图中不编造固定 Pod、CPU、内存或副本数量。

当前页面部署到 Cloudflare Pages 的是这份静态架构文档,Core SDK 的 Python 执行仍属于应用运行环境。

源码依据:
pyproject.toml:5
openjiuwen/core/runner/runner.py:682
Studio / agent-runtime/pyproject.toml:4

02

默认本地模式,不要求先部署消息中间件

GLOBAL_RUNNER 使用 DEFAULT_RUNNER_CONFIG,其中 distributed_mode=False,队列类型配置为 FAKE。因此普通本地 Agent / Workflow 调用不以外部 Pulsar 为前提。

需要特别区分:RunnerConfig 类的字段默认值是 distributed_mode=True,但 SDK 全局 Runner 使用的预置配置把它覆盖成 False。只看字段声明容易得出相反结论;应用若自行构建并设置 RunnerConfig,应核对完整配置。

图中的模型、存储和远端路径都按实际能力配置接入。一个只运行内存内计算的工作流,不会因为安装了 Core 就自动依赖 Redis、数据库和消息队列。

源码依据:
openjiuwen/core/runner/runner_config.py:61
openjiuwen/core/runner/runner_config.py:92
openjiuwen/core/runner/runner.py:88
openjiuwen/core/runner/runner.py:267
openjiuwen/core/runner/runner.py:682

03

模型、工具和状态存储分别接入

模型和 HTTP / MCP 工具通过配置的端点调用。MCP 既可以使用远程 HTTP,也可以采用 stdio 启动本地服务;“工具”这个逻辑概念并不规定唯一网络形态。

Checkpoint 默认保存在内存;PersistenceCheckpointer 可使用 SQLite、Shelve 或 KV 存储能力,Redis Checkpointer 属于可选扩展。向量检索、长期记忆、对象存储等也要结合具体功能选择后端。

增加宿主副本时,各进程的内存状态不会自动同步。要把会话切到另一进程,需要可访问的持久状态、稳定会话 ID、资源注册和一致的执行定义;一个外部数据库本身并不等于完整的故障迁移方案。

源码依据:
openjiuwen/harness_providers/factory.py:83
openjiuwen/core/runner/resources_manager/resource_manager.py:964
openjiuwen/core/session/checkpointer/checkpointer.py:108
openjiuwen/core/session/checkpointer/persistence.py:725
openjiuwen/core/session/checkpointer/persistence.py:976
pyproject.toml:105

04

可选的本机子进程隔离

显式 spawn 路径在同一机器或容器边界内启动 Python 子进程,通过 stdin / stdout 管道通信。这是代码中可以直接看到的进程放置决定,所以图中把子进程放在宿主机器区域内,而不是画成另一台远程服务器。

子进程有自己的生命周期和资源占用。主进程保存句柄并可进行健康检查或关闭;实际数量取决于应用调用,不存在“安装一个 Core 默认附带 N 个 worker”的固定关系。

这条路径没有额外开放一个通用业务 HTTP 端口;若子进程中运行的工具或应用另行监听端口,那是它们自己的配置。

源码依据:
openjiuwen/core/runner/runner.py:541
openjiuwen/core/runner/spawn/process_manager.py:25
openjiuwen/core/runner/spawn/process_manager.py:33
openjiuwen/core/runner/spawn/process_manager.py:461

05

可选的远程 Agent:A2A 与消息队列

A2A 适配把 Agent 接到可发布的远端接口。当前 A2AServerAdapter 从 interface URL 解析监听地址,并提供 FastAPI / Uvicorn 服务集成;适配器中存在端口回退值 8000,它不是所有 Core 应用的统一默认服务端口。

分布式 MQ 路径则围绕 Agent 请求主题与 Runner 回复主题组织消息。配置中可选 Pulsar,也保留 Fake MQ;使用这一机制还需要服务端资源注册、通信组件和对应依赖。

当前快照的 Pulsar 工厂导入路径与实现目录不一致。图中用虚线标记该可选路径,并说明需要先核对接线;本页没有把它当成已完成联调的可用部署。

源码依据:
openjiuwen/extensions/a2a/a2a_server_adapter.py:26
openjiuwen/extensions/a2a/a2a_server_adapter.py:98
openjiuwen/core/runner/runner_config.py:39
openjiuwen/core/runner/runner.py:306
openjiuwen/core/runner/drunner/dmessage_queue/message_queue_factory.py:24
openjiuwen/extensions/message_queue/message_queue_pulsar.py:106

06

可选依赖按能力安装

pyproject 将许多集成划入 extras,例如 all-a2apulsarredissqlitesandboxobservability,以及第三方 Harness 的 claudecodexdsh

使用本地 ReAct 与使用外部 Harness 所需的运行环境不同。Provider 工厂决定实际实现;第三方 Provider 还依赖相应 SDK、服务地址、登录方式或执行环境。

all 在当前声明中只聚合特定集成集合,并不等于包中每一种可选能力。部署时以所用入口和 extras 的实际依赖声明为准。

源码依据:
pyproject.toml:105
pyproject.toml:129
pyproject.toml:162
openjiuwen/harness_providers/factory.py:35
openjiuwen/harness_providers/factory.py:42

07

可观测性有独立模板,不是 Core 的服务集群

仓库 deploy/observability 中提供了 OTel Collector 与 Langfuse 等组件的 Compose 模板,用于接收、存储和查看轨迹。模板中的 Collector 暴露 4317 / 4318,Langfuse Web 暴露 3000

这些端口属于观测配套服务,不是 Agent 推理执行端口。模板里的存储与队列支撑观测系统,也不能全部视为普通 Core 调用的强制依赖。

主部署图为保持清晰,将可观测性接入放在本节解释。要单独部署观测栈,应按模板与当前 exporter 配置核对地址、存储和访问控制。

源码依据:
deploy/observability/docker-compose.yml:1
openjiuwen/extensions/observability/setup.py:1

08

回到 Studio:服务层、引擎层和部署层如何对齐

Studio Runtime 可以作为图左侧的宿主:它接收 HTTP 请求、把 IR 组装成执行对象,再调用 Core;Core 完成 Agent / Workflow 等执行并返回结果或流;服务层再生成对外响应。

Studio 的 Nginx、Uvicorn worker、NodePort 和容器副本是宿主部署选择。Core 的 Runner、Pregel Task 与 Session 则处在宿主进程内;增加一个 Workflow 节点不会自动增加一个 Pod,增加一个 Agent 对象也不会自动增加一个 worker。

扩容时首先识别瓶颈:宿主接入容量、Python 计算、模型配额、工具 I/O 或状态存储。四图结合起来,才能把“代码组件是什么”“运行时由谁执行”“最终部署在哪里”分清楚。

源码依据:
Studio / agent-runtime/pyproject.toml:4
Studio / agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:94
openjiuwen/core/runner/runner.py:359
openjiuwen/core/runner/runner.py:408
openjiuwen/core/graph/pregel/task.py:27
openjiuwen/core/runner/spawn/process_manager.py:461