AGENT STUDIO / RUNTIME ARCHITECTURE · 2026-09-17

Agent Runtime · 四视图与执行流程

四个架构视图说明职责、代码、进程与部署;Workflow 流程图与序列图将一次执行对应到逻辑模块和具体调用。依据当前工作区源码与仓库部署模板整理。

逻辑视图

ARCHITECTURE

回答“系统提供哪些职责、这些职责如何协作”。每次分发选择一个顶层 Runner;模式框内展开主要组件,底部列出共享能力。

Agent Runtime 逻辑视图执行接口层接收 HTTP 请求并准备上下文,由编排层按模式选择一个顶层 Runner。Workflow 包含 IRConverter、LazyWorkflow / Workflow、会话与恢复及流包装;ReAct 包含 ReActAgent、工具与工作流能力、会话与流适配;Controller / PlanExecute 使用 IRConverter 构建分层 Agent Group,由成员 Agent 的控制或规划策略推进执行。各模式复用共享能力,通过事件适配输出结果。01 / LOGICAL VIEW三种执行模式,共用资源能力与输出协议提交执行包装结果流工作流ReActController / PlanExecuteHTTP执行接口层(HTTP 入口)接收请求 · 校验 · 准备执行上下文CORE请求编排与模式分发IR / context → ir_executeOUTPUT事件适配与输出EventHandler → SSE / JSONMODEWorkflowWorkflowRunnerIRConverterIR → LazyWorkflowLazyWorkflow / Workflow延迟构图 · 节点 / 分支 / 循环执行会话、恢复与流包装Session · Checkpoint · 事件包装MODEReActReActAgentRunnerReActAgentLLM · Prompt · 推理 / 工具循环工具与工作流能力Plugins · MCP · Skills · Workflow会话与流适配Session · ReactStreamDataAdapterMODEController / PlanExecuteControllerRunnerIRConverterIR → Agent GroupHierarchicalAgentGroup控制 Agent · 成员 Agent · 消息调度成员 Agent 的执行策略ControllerMode / PlanExecuteModeRESOURCES共享能力(4 组)模型接入LLM / model_service工具执行MCP / API / Skills / Code知识与记忆KB · 可选 LTM状态与恢复Redis / checkpoint依赖 / 协作关系内部主要组件 / 职责顶层 Runner 按请求择一 · 能力可复用

入口与三条执行路径

执行接口层向 Runtime 的调用方提供智能体 / 工作流运行 HTTP 接口。收到请求后完成校验、版本解析、历史与环境变量加载,准备执行上下文,再交给 ir_execute() 选择一个顶层 Runner。

Workflow:IRConverter 将 IR 转成 LazyWorkflow 壳对象。首次 invoke / stream 时,壳对象再调用转换器构建完整图,并委托底层 SDK Workflow 推进节点、分支及循环。同一个壳对象后续调用复用已构建的图。

Workflow 的“会话、恢复与流包装”合并三项协作职责:创建 Workflow Session;通过 CheckpointerFactory 查询检查点,并用 InteractiveInput 携带用户输入恢复中断;通过 WorkflowStreamDataWrapper 将执行产生的 chunk 包装为运行事件,再交给外层事件适配与输出。

ReAct:ReActAgent 配置模型、提示词与迭代限制,推进模型判断与工具调用循环。Runner 注册 Plugins、MCP、Skills 及 Workflow 能力,创建执行 Session,并使用 ReactStreamDataAdapter 适配 SDK 流事件。

Controller / PlanExecute:IRConverter 构建或恢复 HierarchicalAgentGroup。组内的 HierarchicalControlAgent 选择成员,通过 StandaloneRunner 调度消息;成员 Agent 的 ControllerModePlanExecuteMode 决定控制或规划执行策略,随后由 ControllerStreamDataAdapter 适配输出。

如何理解内部小框

小框表示该分支使用的主要组件或聚合职责;ReActAgentIRConverterLazyWorkflowWorkflowHierarchicalAgentGroup 是具体类名,“工具与工作流能力”“会话与流适配”“会话、恢复与流包装”“执行策略”是逻辑分组。位置不表示独立进程,也不表示源码专属归属;成员执行策略实际属于 Group 中的成员 Agent。

IRConverter 实现在 Runtime 的 jiuwen 包中,被 Workflow 与 Controller 两条路径复用;ReAct 注册子工作流时也会调用它。图中将其在 ReAct 的用途合并进“工具与工作流能力”。顶层 Runner 择一,并不限制执行过程中组合调用其他能力。

共享能力合并为 4 组:知识库通过适配器接入,长期记忆可关闭或降级,沙箱按配置启用。省略管理、构建、日志与监控等旁路;DeepResearch 在当前执行入口被拒绝,不列为可执行模式。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/serve/apis/app_run.py:673
agent-runtime/agent_runtime/serve/apis/orchestration.py:133
agent-runtime/agent_runtime/event_handler/event_handler.py:33
agent-runtime/agent_runtime/runner/workflow_runner.py:226,264,339,480,575,588
agent-runtime/jiuwen/extension/workflow/lazy_workflow.py:48,96,121,138
agent-runtime/agent_runtime/runner/workflow_stream_data_wrapper.py:252,321
agent-runtime/agent_runtime/runner/react_agent_runner.py:430,655,695,741,759,804,835
agent-runtime/agent_runtime/runner/controller_runner.py:70,86,161,203,206
agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:980,1535,1591,1633
agent-runtime/jiuwen/multi_agent/agent_group/hierarchical_group/agent_group.py:27
agent-runtime/jiuwen/multi_agent/agent_group/hierarchical_group/control_agent.py:23,58
agent-runtime/jiuwen/controller/agent/control_mode/control_factory.py:14
agent-runtime/agent_runtime/memory/adapter/ltm_manager.py:62

开发视图

DEPENDENCY GRAPH

回答“代码放在哪里、哪些包依赖哪些包”。箭头指向被依赖包,徽标统计当前图里指向该包的入边。

Agent Runtime 开发视图运行服务包依赖 jiuwen、共享包及 openjiuwen SDK;jiuwen 的 IR 编译器又引用 runtime 节点扩展,构成包级依赖环;builder 独立复用共享包。02 / DEVELOPMENT VIEW运行服务、构建服务、共享包与 SDK 的代码边界model_serviceCYCLEPACKAGE1 in运行服务包agent-runtime/agent_runtime/serve · runner · extension · memoryPACKAGE0 in独立构建服务agent_builder/构建 / 提示词 / 模型测试PACKAGE1 inIR 编译与多智能体控制agent-runtime/jiuwen/IRConverter · controller · groupSHARED2 in共享包(3 个)packages/model_service · storage · utilsSDK3 inopenjiuwen / agent-coregit dependency @ developIR 编译器回引runtime 节点扩展调用方 → 被依赖包橙色虚线:包级依赖环N in:图内入边数

依赖环与共享边界

agent_runtime.runner 引用 jiuwen 的 IR 加载与转换;jiuwen/ir_converter.py 又导入 runtime 的代码、知识检索、问题交互等节点。此处标的是包级依赖环,不代表每次导入都会报循环导入错误。

共享包完整名称:model_servicestoragecommon_utils。共享包到 SDK 的边具体由 model_service 提供。

独立服务与 SDK 来源

builder 与 runtime 的互不导入边界有仓库测试约束;两者复用共享能力,不是同一个运行服务。图中省略 builder 的内部依赖及 FastAPI、Pydantic 等通用依赖。

runtime 声明从 agent-core 的 develop 分支安装 openjiuwen;本地 agent-core/ 目录不等于已被当前环境加载的 SDK。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/runner/workflow_runner.py:27
agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:16
agent-runtime/pyproject.toml:11,75
packages/model_service/model_service/client.py:2
agent_builder/tests/test_no_agent_runtime_imports.py:16
agent_builder/tests/test_runtime_decoupled.py:23

进程视图

SEQUENCE / CONCURRENCY

回答“运行时谁在执行、如何并发和跨进程协作”。展示流式执行中的一种交错顺序;A、B 是多 worker 场景示意。

Agent Runtime 进程视图流式请求由 worker A 的请求协程执行;取消请求可落到 worker B,写 Redis 标记并发布事件,worker A 的订阅协程取消本地任务并注销执行。03 / PROCESS VIEW请求协程执行;Redis 把取消信号送回持有任务的进程OPT[执行仍在飞;取消请求可落到另一个 worker]执行请求登记执行归属模型 / 工具 I/OchunkSSE 事件POST /cancel校验后置位 / 广播signal acceptedruntime:canceltask.cancel()finally: 注销执行CLIENT调用方HTTP / SSEPROCESS执行 worker A请求协程 + 订阅协程STATERedis共享归属 / 取消标记PROCESS取消 worker B另一个进程(可选)ENDPOINT外部模型 / 工具await I/O请求 / 调用返回异步通知SSE 主响应

进程内执行

每个 Python worker 运行 FastAPI/Uvicorn 事件循环。Runner 的执行与事件包装是请求内的协程 / 异步生成器调用,模型和工具 I/O 可通过 await 让出事件循环。

每个 worker 在 lifespan 启动一个取消订阅协程,并维护本进程的 conversation_id → Task 注册表。图中合并在 A 这条进程生命线里;并非为每个 Runner 启动新进程。

取消语义与限制

取消接口校验归属后写标记并发布 runtime:cancel;只有持有任务的进程会命中注册表并执行 task.cancel()。HTTP 接受响应不保证任务已停止,广播与响应的先后可变化。

正常完成会在流末尾发送唯一 done;运行中被取消的 SSE 无 done,finally 注销。此图针对注册过的流式执行,不扩展为阻塞调用或单节点调试的统一保证。默认 Kubernetes 模板只有 1 个 Python worker,此时执行与取消请求由同一进程处理。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/EIStart_base.py:10
agent-runtime/agent_runtime/serve/server.py:196
agent-runtime/agent_runtime/serve/apis/orchestration.py:339,491
agent-runtime/agent_runtime/serve/execution_registry.py:77,194,216,226

部署视图

KUBERNETES DEPLOYMENT

回答“软件装在哪里、由什么进程运行、通过哪些端口通信”。边界内仅展示模板明确声明的 Service 与 Pod。

Agent Runtime 部署视图仓库 Kubernetes 模板将 NodePort Service 指向一个 studio-runtime Pod,Pod 内 Nginx 代理至一个 Python worker;Redis、对象存储、模型工具和可选 OpenSearch 仅声明为可配置依赖端点。04 / DEPLOYMENT VIEW仓库 Kubernetes 模板快照 · 非线上环境实测Kubernetes · namespace: default依赖端点 · 实际位置未声明HTTP:31014TCP:6379HTTP(S):配置HTTP(S):配置HTTP(S):配置SERVICEstudio-runtimeport = targetPort: 31014PODx1studio-runtime · Podstudio-runtime1.0.0.20260526091150.x86_6401 Nginx0.0.0.0:31014 · least_connupstream → 127.0.0.1:3101502 Python / Uvicorn ×10.0.0.0:31015NGINX_LOAD_BALANCING=trueGUNICORN_WORK_NUM=1requests = limits: 2 CPU / 4 Gi/dev/shm: emptyDir(Memory), 2 GiENDPOINTRedisREDIS_HOST: 未配置ENDPOINT对象存储STORAGE_TYPE=OBSENDPOINT模型 / 工具端点LLM · MCP · 可选 SandboxOPTIONALOpenSearch(长期记忆)MEMORY_ENABLED=falseNodePort :31014入口暴露在节点端口跨 Pod 依赖调用可选 / 默认关闭x1:副本数;端口随配置变化

模板的实际值

replicas=1,NodePort / Service / targetPort 均为 31014,HTTPS 关闭。镜像标签取自 YAML。启用 Nginx 负载均衡后,启动脚本以 PORT+i 启动 Python worker:当前 worker 监听 0.0.0.0:31015,Nginx 经 127.0.0.1:31015 转发并关闭 SSE 缓冲。

CPU/内存 requests 与 limits 都为 2 CPU / 4 Gi;/dev/shm 为 2 Gi 的内存 emptyDir。健康探针走 31014;不代表生产容量或高可用承诺。

未声明的位置与合并项

Redis 主机、对象存储 endpoint 等需部署时填写。右侧只表示配置依赖,不能据此认定它们位于集群外或同一命名空间。HTTP(S) 的端口取各 endpoint;并未假设统一为 443。

模型、MCP 和可选沙箱合为一个端点组;OpenSearch 只用于可选长期记忆。省略 manager、builder、console、监控与代码执行子进程。Docker Compose 是另一套部署方案,未混入此图。

源码定位(相对 agent-studio)

deploy/k8s/studio-runtime.yaml:1,23,149,201,316
docker/studio-runtime/script/start_nginx_lb.sh:15,25,44,145
docker/studio-runtime/script/start_server.sh:72
docker/studio-runtime/Dockerfile
agent-runtime/agent_runtime/EIStart_base.py:10

Workflow 完整流程

FLOWCHART · LOGICAL MAPPING

以一次 Workflow HTTP 请求为主线:先看 01—07 的执行准备与图执行,再看持续发生的 08—10 事件输出;05A / 05B 区分首次执行和检查点恢复。

Workflow 完整执行流程工作流 HTTP 请求先经接口校验及模式分发,WorkflowRunner 读取 IR 并转换为 LazyWorkflow,查询检查点后分别构造首次或恢复输入,首次使用时构建完整图并执行。执行中按需调用共享能力,产生的事件经 WorkflowStreamDataWrapper、stream_response 和 EventHandler 持续向外传递。交互节点挂起时保存检查点并返回问题,用户下一次提交答案时重新进入请求链路并恢复执行。05 / WORKFLOW EXECUTION FLOW从请求到结果:每一步都标明它在逻辑视图中的位置A / 执行接口与请求编排B / WorkflowRunner:转换、准备与图执行C / 运行事件传递与结果输出run_streaming按需调用需用户输入每个 chunk 随产随传问题 / 挂起事件调用方发起工作流请求workflow_id · conversation_id · queryHTTP01 校验请求,准备执行上下文逻辑视图:执行接口层(HTTP 入口)解析版本与 IR 路径 · 加载历史 / 环境变量DISPATCH02 规范参数,选择 WorkflowRunner逻辑视图:请求编排与模式分发ir_execute:读取 mode · 可选输入审核 · 注册执行任务CONVERT03 读取 IR,生成 LazyWorkflow 壳对象逻辑视图:Workflow → IRConverter提取节点定义 · async_ir_to_workflow · 尚未构建完整图CONTEXT04 创建对话上下文,检查中断状态逻辑视图:Workflow → 会话、恢复与流包装CheckpointerFactory · 查询检查点 · 处理取消标记有可恢复检查点?且未被取消NEW05A 首次执行:构造普通输入逻辑视图:Workflow → 会话、恢复与流包装query + 全局状态 · 新建 Session · 保存执行 / 追踪标识RESUME05B 恢复执行:构造交互输入Workflow → 会话、恢复与流包装InteractiveInput · 复用执行与追踪标识BUILD06 首次使用时构建完整工作流图逻辑视图:Workflow → LazyWorkflow / Workflowinstantiate → IRConverter 构图;同一壳对象后续复用EXECUTE07 按图执行节点、分支和循环逻辑视图:Workflow → LazyWorkflow / Workflowworkflow.stream(inputs, session, context)RESOURCES节点按需使用共享能力共享能力:模型 / 工具 / 知识记忆 / 状态各节点按需调用;并非执行后的固定一步INTERRUPT交互分支:保存检查点,挂起Workflow → 会话、恢复与流包装返回问题;用户下一次提交答案时从 01 重新进入WRAP08 将执行 chunk 包装成运行事件逻辑视图:Workflow → 会话、恢复与流包装WorkflowStreamDataWrapper:节点 / 消息 / 交互事件STREAM09 透传运行事件,处理流收尾逻辑视图:请求编排与模式分发stream_response:可选输出审核 · 末尾 done · finally 注销OUTPUT10 转换协议,向调用方输出逻辑视图:事件适配与输出EventHandler:逐帧 SSE,或消费内部流后汇总 JSON本轮请求结束返回完成结果,或交互问题与挂起状态这张图如何对应逻辑视图步骤第二行直接给出对应的模块或内部小框。同一个模块会出现在多个阶段,例如编排层先负责分发,后负责运行事件与本轮收尾。范围:Workflow HTTP 入口的内部流式执行。外部请求 stream=false 时,由输出层汇总 JSON。07—10 是边执行、边输出的事件管道图还在执行时,已有 chunk 就会经过 08 → 09 → 10。只有流结束时,编排层才处理 done 并注销执行任务。挂起后,当前 HTTP 请求结束,检查点继续保留。用户携带同一会话的新输入再次请求:01 → … → 05B。“本轮流结束”不等于“整个工作流已完成”。步骤推进 / 分支执行中的事件流按需调用共享能力

从流程反看逻辑模块

01 对应执行接口层;02、09 对应请求编排与模式分发。03 对应 Workflow 框内的 IRConverter;06、07 对应 LazyWorkflow / Workflow;04、05、08 及交互分支 对应会话、恢复与流包装;10 对应事件适配与输出。共享能力由具体节点按需调用,不是执行链末尾的串行步骤。

图展示实际执行及事件传递顺序。异步生成器与 EventHandler 的外层包装会提前建立,消费流时才驱动内部执行;因此不能把 08—10 理解为等待全部节点完成后的三个处理步骤。图未表示进程边界。

Workflow HTTP 入口构造的内部请求固定使用 streaming。调用方设置 stream=false 时,EventHandler 消费内部事件流并汇总 JSON;并不因此选择另一个 Runner。

恢复、取消与本图范围

交互中断由工作流检查点机制保存状态。下一次请求仍经过入口、分发、IR 转换与会话准备,随后通过 InteractiveInput 恢复检查点;不是让原来的 HTTP 请求一直等待。新请求可创建新的 LazyWorkflow 壳对象,图实例化后由检查点机制恢复执行状态。

stream_response 在内部事件流结束时发送唯一的末尾 done,并在 finally 中注销当前执行任务;done 是本轮流的结束信号,不单独证明业务工作流成功完成。运行中被取消时,原流没有 done,finally 仍注销。检查点已被取消的会话不会按 05B 正常续跑,Runner 会清理相应状态并按新执行处理。

为突出核心步骤,入口校验失败、输入审核拦截、IR 构建失败、节点异常与取消的独立分支合并为本说明。这些路径可能提前返回或中止,不保证走完整条主线。模型、工具、知识库及可选记忆不逐一展开;单节点调试与其他 Runner 不在本图范围。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/serve/apis/app_run.py:333,535,636,656
agent-runtime/agent_runtime/serve/apis/orchestration.py:133,153,225,339,417
agent-runtime/agent_runtime/runner/workflow_runner.py:283,301,328,371,455,481,575,588
agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:1591,1613,1633
agent-runtime/jiuwen/extension/workflow/lazy_workflow.py:48,96,121,138
agent-runtime/agent_runtime/runner/fast_redis_checkpointer.py:108,168,219
agent-runtime/agent_runtime/runner/workflow_stream_data_wrapper.py:252,321
agent-runtime/agent_runtime/event_handler/event_handler.py:151,194,228

序列① 主调用链

SEQUENCE · OVERVIEW

对应流程步骤 01—10。把执行接口与编排合为一条生命线;把转换器、LazyWorkflow 与 SDK Workflow 合为“工作流组件”,具体调用见下一张图。

序列① 主调用链与事件返回调用方发起 Workflow HTTP 请求;接口与编排层准备上下文并提前建立 EventHandler 外层响应包装。消费响应流时驱动 WorkflowRunner 及工作流组件执行。每个 chunk 经 Runner、编排层、EventHandler 返回调用方,内部流结束后处理末尾 done 并注销执行。06A / WORKFLOW SEQUENCE先建立响应包装,再由流的消费驱动执行;事件沿调用链逐层返回LOOP[每个执行 chunk;图仍可继续运行]01 HTTP 执行请求01–02 校验与选择模式提前建立响应包装消费 body_iterator02 run_streaming03–07 准备 / 执行yield chunk08 包装运行事件09 内部 SSE 事件10 增量 SSE末尾 done / 注销本轮响应结束CLIENT调用方HTTP / SSERUNTIME执行接口与编排app_run / ir_executeRUNNERWorkflowRunner执行准备 / 流包装WORKFLOW工作流组件IRConverter / WorkflowOUTPUT事件适配与输出EventHandler调用 / 局部动作返回 / yield对外响应(强调)时间自上而下

调用与消费的先后

ir_execute() 返回内部 StreamingResponse 后,接口先建立 EventHandler 外层包装。真正消费外层 body iterator 时,内部异步生成器才持续推进 Runner。因此“事件适配与输出”在执行前已接入,在执行中持续处理结果。

03—07 合并了多次调用和 Runner 自身的准备动作,下一张图展开 IR 转换、输入分支与延迟构图。生命线表示逻辑调用角色,不是不同进程;激活条表示本段交互仍在进行,不表示持续占用 CPU。

本轮流结束的含义

这里展示外部 stream=true。外部设置 stream=false 时,EventHandler 同样消费内部流,但在最后汇总 JSON;不会逐帧把 SSE 发给调用方。

“末尾 done / 注销”合并两个相邻收尾动作:编排层先发内部唯一末尾 done,随后在 finally 注销执行。内部 done 还会经过 EventHandler 协议映射,不应理解为对外原样透传。取消时原流无 done,finally 仍执行。交互挂起时本轮结束也不代表整个工作流完成。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/serve/apis/app_run.py:535,636
agent-runtime/agent_runtime/serve/apis/orchestration.py:153,339,401,417
agent-runtime/agent_runtime/runner/workflow_runner.py:283,575,588
agent-runtime/agent_runtime/event_handler/event_handler.py:151,194,228

序列② 构图与输入

SEQUENCE · INITIAL / RESUME

展开主图中 03—07 的组件调用。ALT 两个区域互斥;首次和恢复都会创建本轮 Session,恢复分支复用此前的执行 / 追踪标识并携带交互输入。

序列② IR 转换、输入分支与图执行WorkflowRunner 调用 IRConverter 得到 LazyWorkflow 壳对象,然后查询会话检查点。首次执行构造普通输入,恢复执行构造 InteractiveInput;调用 LazyWorkflow.stream 时才构建完整 SDK Workflow,并逐层返回 chunk。06B / WORKFLOW SEQUENCEIRConverter 先返回轻量壳对象;首次 stream 再构建完整图ALT[首次:普通 query + 全局状态][恢复:inputs = InteractiveInput]03 async_ir_to_workflowLazyWorkflow 壳对象04 查询检查点检查点查询结果05A 新建会话 / 保存标识05B 新建会话 / 复用标识06 stream(inputs, session)首次使用:构建完整图SDK Workflow 实例07 workflow.stream执行 chunk向 Runner yield chunkRUNNERWorkflowRunner03–07 执行准备STATE会话与检查点Session / CheckpointerCONVERTERIRConverterIR → Workflow 对象LAZYLazyWorkflow延迟构建 / 委托ENGINESDK Workflow节点 / 分支 / 循环调用 / 局部动作返回 / yield对外响应(强调)时间自上而下

与三个内部小框的对应

调用 IRConverter 对应“IRConverter”小框;查询检查点、构造输入与会话对应“会话、恢复与流包装”;LazyWorkflow 与 SDK Workflow 对应“LazyWorkflow / Workflow”。Runner 会先读取 IR、提取节点定义,本图合并其本地准备过程。

“会话与检查点”合并会话创建辅助函数、CheckpointerFactory 及执行 / 追踪标识存储,不表示它们属于单一类。取消标记另由 Runner 查询;普通 inputs 或 InteractiveInput 由 Runner 本地构造,写在 ALT 条件中。

延迟构图与共享能力

LazyWorkflow.instantiate() 首次使用时回调 IRConverter.build_openjiuwen_workflow_from_ir() 构建 SDK Workflow。壳对象缓存该实例,同一对象后续调用复用;新 HTTP 请求不保证复用同一个壳对象。

模型、工具、知识记忆等共享能力由具体节点按需调用;本图将它们合并在 SDK Workflow 的执行中。这里只画第一个 chunk,主图的 LOOP 表示后续持续返回。已有检查点被取消时会进行状态清理,不进入正常恢复分支。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/runner/workflow_runner.py:301,328,339,371,455,481,588
agent-runtime/jiuwen/serve/controllers/execution/ir_converter.py:1591,1613,1633
agent-runtime/jiuwen/extension/workflow/lazy_workflow.py:48,96,138

序列③ 挂起与恢复

SEQUENCE · SUSPEND / RESUME

承接主图已经开始的执行,展示一次成功的交互中断与恢复。“新请求”是时间上更晚的一次调用;生命线的延续不代表复用同一个 Python 对象。

序列③ 交互挂起与下一次请求恢复工作流遇到交互节点时保存 checkpoint,返回问题并结束本轮响应。用户在下一次 HTTP 请求中提交答案,使用同一 conversation_id 重新进入入口、编排和 Runner,携带 InteractiveInput 从检查点继续执行。06C / WORKFLOW SEQUENCE本轮挂起并结束响应;用户下一次提交答案,才恢复后续节点等待用户下一次输入:检查点保留,原 HTTP 请求已经结束已进入图执行保存交互 checkpoint交互 chunk / 问题包装为交互事件返回问题,结束本轮响应新请求:同一会话 + 答案重新经过入口与模式分发重建图 + InteractiveInput加载 checkpoint,继续执行后续节点 chunk运行事件增量输出 / 本轮完成结果CLIENT调用方同一 conversation_idRUNTIME接口、编排与输出app_run / EventHandlerRUNNERWorkflowRunner准备输入 / 包装事件STATEFUL工作流与检查点Workflow / Checkpointer调用 / 局部动作返回 / yield对外响应(强调)时间自上而下

恢复的是执行状态

原请求收到交互问题后结束;用户提交答案时仍经过入口校验、模式分发、IR 转换、会话与输入准备。这里将这些重复准备合并为两条调用,细节见前两张图。

Runner 使用 req.resume_input or req.query 构造 InteractiveInput,检查点机制恢复中断位置;不会让已经完成的前置业务节点正常重跑一遍。新的 LazyWorkflow 可以重新构建图结构,图结构重建与业务节点重跑是不同的动作。

范围与异常

这张图只展示检查点有效且未被取消的正常续跑。检查点缺失、已取消、输入无效、节点执行失败等路径可能转为新执行或提前退出,没有画成这条成功路径的一部分。

整个页面合并了存储读取、具体工具 / 模型调用、可选记忆和日志细节。三张图共同覆盖主流程、首次 / 恢复输入以及挂起后的新请求,均沿用当前工作区源码结论。

源码定位(相对 agent-studio)

agent-runtime/agent_runtime/runner/workflow_runner.py:371,377,455,481,493,588
agent-runtime/agent_runtime/runner/fast_redis_checkpointer.py:168,219
agent-runtime/agent_runtime/serve/apis/orchestration.py:339,417
agent-runtime/agent_runtime/event_handler/event_handler.py:151,194