ADK Python 工作流动态节点实战:用 ctx.run_node 实现运行时决定的执行路径
ADK Python 工作流动态节点实战用 ctx.run_node 实现运行时决定的执行路径【免费下载链接】adk-pythonAn open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.项目地址: https://gitcode.com/GitHub_Trending/ad/adk-python本文围绕 ADKAgent Development KitPython 版的 Workflow 引擎讲解动态节点执行Dynamic Node Execution机制当工作流的执行路径或节点运行次数无法在静态edges中确定时如何用ctx.run_node配合原生 Python 控制流如while循环在运行时动态调度节点。基于contributing/samples/workflows/dynamic_nodes官方示例完整走读实现并结合src/google/adk/workflow与src/google/adk/agents/context.py的源码说明其底层调度、可恢复执行rerun_on_resume原理与事件轨迹验证方法。读完后你将掌握如何声明动态编排节点、run_node各参数的实际影响、动态节点被中断后恢复的机制以及如何用会话事件 JSON 验证多轮动态执行。为什么需要动态节点执行在 ADK Workflow 中标准的执行路径由edges静态定义哪些节点先跑、谁触发谁、走哪个分支都在建图时写死。但真实场景中存在一类需求——具体的执行节点集合、或者某个节点要运行几次只有在运行时才能确定例如循环生成内容直到通过 LLM 评审评审轮数未知根据用户输入的数量动态扇出子任务fan-out 数量未知动态拼接多个 Agent 的调用顺序。dynamic_nodes示例处理的正是第一种动态循环场景。一个名为orchestrate的 Python 节点充当驱动器driver在while True:循环中先执行generate_headlineAgent 基于给定主题生成头条再执行evaluate_headlineAgent 对其评分。若评分为tech-related则返回该头条若为unrelated则把评审反馈写回 state循环继续。值得注意的是这个示例是标准loop示例的重写版本它没有使用复杂的图边路由例如在edges里配置条件路由函数而是完全依靠原生 Python 控制流while循环加异步ctx.run_node调用来实现。执行拓扑如下图中只有START → orchestrate一条静态边其余执行路径全部是orchestrate在运行时通过ctx.run_node动态调度出来的。示例可运行的输入见 READMEflowerquantum mechanicsrenewable energy完整示例代码解读下面给出 agent.py 的完整实现它是可独立运行的最小示例from typing import AsyncGenerator from typing import Literal from google.adk import Agent from google.adk import Context from google.adk import Event from google.adk import Workflow from google.adk.workflow import node from pydantic import BaseModel from pydantic import Field class Feedback(BaseModel): grade: Literal[tech-related, unrelated] Field( description( Decide if the headline is related to technology or software engineering. ), ) feedback: str Field( description( If the headline is unrelated to technology, provide feedback on how to make it more tech-focused. ), ) generate_headline Agent( namegenerate_headline, instruction Write a headline about the topic {topic}. If feedback is provided, take it into account. The feedback: {feedback?} , ) evaluate_headline Agent( nameevaluate_headline, instruction Grade whether the headline is related to technology or software engineering. , output_schemaFeedback, output_keyfeedback, ) node(rerun_on_resumeTrue) async def orchestrate( ctx: Context, node_input: str ) - AsyncGenerator[Event | str, None]: yield Event(state{topic: node_input}) while True: headline await ctx.run_node(generate_headline) feedback Feedback.model_validate( await ctx.run_node(evaluate_headline, node_inputheadline) ) if feedback.grade tech-related: yield headline break root_agent Workflow( nameroot_agent, edges[(START, orchestrate)], )代码分为四个关键部分结构化评审输出Feedback用 Pydantic 模型约束评审结果grade字段取值限定为Literal[tech-related, unrelated]保证循环终止条件可被可靠判断。生成 Agentgenerate_headlineinstruction 中用{topic}从 state 读取主题{feedback?}表示可选字段——首轮没有反馈时为空后续轮次自动带上上一轮的改进建议。评审 Agentevaluate_headlineoutput_schemaFeedback使其输出被解析为结构化对象output_keyfeedback把结果写入会话 state 的feedback键从而成为下一轮generate_headline可用的上下文。编排节点orchestrate 根 Workfloworchestrate是唯一的静态节点Workflow只声明了(START, orchestrate)一条边其余全部动态发生。关键机制一node(rerun_on_resumeTrue)启用可恢复执行README 的第一步要点要让 Python 节点使用ctx.run_node必须声明为node(rerun_on_resumeTrue)。它告诉引擎如果任何被动态调度的子节点被中断例如等待 human-in-the-loop 输入工作流引擎应当暂停并在恢复时重新运行re-run编排节点让编排节点从子节点拿到续跑后的结果。这不是可选优化而是硬性要求。在源码 src/google/adk/workflow/_dynamic_node_executor.py 的run_node_internal入口处就有显式校验if not ctx._node_rerun_on_resume: raise ValueError( A node must have rerun_on_resumeTrue. Reason is that dynamically scheduled nodes might be interrupted, and the workflow wakes-up/re-runs the parent node, so it can get the child node response. )即若父节点没有开启rerun_on_resume却调用ctx.run_node会在运行期直接抛出ValueError。这个设计的原理是动态子节点可能长时间挂起HITL、长时工具编排协程不能无限等待引擎选择暂停父节点 → 子节点完成/恢复 → 重跑父节点的恢复模型父节点重跑时从已完成子节点拿到缓存输出去重从而安全地继续循环。node装饰器本身还支持更多参数完整签名见 src/google/adk/workflow/_node.pyname覆盖节点名、rerun_on_resume、retry_config重试策略、timeout、parallel_worker/max_parallel_workers并行工作器、auth_config运行前请求用户认证要求配合rerun_on_resumeTrue、parameter_bindingstate默认从ctx.state绑定函数参数node_input则从node_input绑定并按函数签名推断输入/输出 schema用于节点充当 Agent 工具的场景。动态节点场景中与本例直接相关的是rerun_on_resume。关键机制二ctx.run_node从上下文运行节点README 的第二步要点向 Python 节点注入ctx: Contextawait ctx.run_node(node_to_run)运行目标节点返回值就是该次执行的最终输出在循环的每次迭代之间还可以yield Event(...)更新 state。示例中await ctx.run_node(generate_headline)—— 不传node_inputAgent 直接从 state 读取{topic}/{feedback?}生成头条返回值即头条文本await ctx.run_node(evaluate_headline, node_inputheadline)—— 把本轮头条作为node_input显式传入评审 Agent返回值经Feedback.model_validate解析为结构化对象yield Event(state{topic: node_input})—— 在第一轮循环前把用户输入写入 state让下游 Agent 的 instruction 模板能取到topic。Context.run_node的公开 API 定义在 src/google/adk/agents/context.py完整参数与语义如下均可用于动态节点编排参数说明node要执行的节点BaseNode实例或任何可被构建成节点的可调用对象/Agentnode_input传给该节点的输入数据默认Noneuse_as_output若为True子节点输出直接作为调用节点的输出调用节点自身的输出事件被抑制以避免重复run_id自定义本次动态执行的 run ID便于跨运行关联事件不提供则自动生成use_sub_branch若为True子节点在子分支中执行隔离其 state 与事件override_branch覆盖父节点默认分支override_isolation_scope覆盖父节点默认的隔离作用域raise_on_wait若为True子节点处于 WAITING 时抛出NodeInterruptedError而非返回None该方法文档中有一条重要的使用约束必须直接await它不要用asyncio.create_task()包裹——那样任务将失去监督错误会被静默吞掉父节点被中断如 HITL时任务也不会被取消。本示例中两次调用都是直接await符合这一要求。底层调度动态节点如何被引擎接管从源码结构看ctx.run_node最终进入 run_node_internal其核心逻辑分三种路径前置校验见上文强制父节点rerun_on_resumeTrue。双模式执行Workflow 模式当父节点运行在工作流图内ctx._workflow_scheduler存在执行委托给工作流调度器ScheduleDynamicNode由调度器处理图依赖与状态。这里还有一个细节校验——调用方显式传入的run_id如果是纯数字会被拒绝must contain non-numeric characters to prevent collision with auto-generated IDs因为数字 run_id 由调度器顺序分配显式数字会与之冲突。Standalone 模式节点独立于工作流运行时直接通过NodeRunner执行。Agent Transfer 循环run_node_internal用一个while True循环处理节点执行中又请求转移到另一个 Agent的情况例如子 Agent A 把执行转给 Agent B循环内更新目标节点与父上下文指针并继续若子节点报错则抛DynamicNodeFailError若子节点被中断存在interrupt_ids则把中断 ID 传播回父节点上下文并抛NodeInterruptedError让上层 NodeRunner 把父节点记录为等待状态而非误判完成——这正是rerun_on_resume恢复模型能工作的前提。也就是说示例中看起来只是两行await ctx.run_node(...)的背后引擎完成了 run_id 分配、分支/作用域隔离、事件溯源子节点输出事件带上output_for指向父节点路径、中断传播与恢复重放这一整套机制。用事件轨迹验证多轮动态执行示例目录附带了一个真实的会话事件文件 tests/flower.json记录了输入flower时的一次完整运行可以把它当作动态节点如何落事件的参照e-2orchestrate产生stateDelta: {topic: flower}路径为root_agent1/orchestrate1e-3第一次动态调度generate_headline输出A World of Petals其nodeInfo.path为root_agent1/orchestrate1/generate_headline1且output_for指回父节点路径——即子节点输出归属于父节点的体现e-4第一次evaluate_headline输出结构化 JSONgrade为unrelatedstateDelta写入feedback含改进建议e-5/e-6第二轮循环generate_headline的路径变为.../generate_headline2run 序号递增结合反馈产出**Digital Petals: Engineering AI-Enhanced Blooms**evaluate_headline2评出tech-relatede-7最终输出即该头条output_for同时指向orchestrate与根root_agent。这段轨迹印证了三个机制state 通过Event(state...)在轮次间传递feedback每轮被覆写动态子节点的 path/run_id 由引擎自动生成并随轮次递增循环的终止yield headline后break最终把父节点输出冒泡为整个 Workflow 的输出。测试覆盖与延伸阅读仓库的单元测试 tests/unittests/workflow/test_workflow_dynamic_nodes.py 系统地覆盖了动态节点调度的三种核心情形——全新执行无历史事件、已完成去重重跑时直接返回缓存输出、中断后恢复携带resume_inputs重跑以及多动态节点、嵌套动态节点、use_as_output输出委托等边界情况。此外还有 test_dynamic_node_executor.py、test_dynamic_node_scheduler.py、test_dynamic_use_as_output.py 等针对执行器与调度器的独立测试可作为理解上述底层机制的对照材料。实践要点小结静态边最少化动态节点场景下Workflow只需声明(START, 编排节点)一条边其余拓扑由 Python 控制流表达可读性和灵活性优于在edges中写条件路由函数必须rerun_on_resumeTrue这是调用ctx.run_node的硬性前提用于支撑子节点中断 → 父节点重跑的恢复模型源码中有显式校验直接await ctx.run_node不要用asyncio.create_task包裹否则错误与中断传播都会失效用 state 做轮次间的通信总线通过yield Event(state...)写入topic、利用output_key写回feedback让多轮循环中的 Agent 自然获得上一轮上下文用output_schema固化循环终止条件结构化的grade字段让while循环的退出判断可靠、可测试用事件 JSON 验证行为动态子节点的 path序号递增与output_for归属关系是核对多轮执行是否正确落地的直接证据。适用前提与限制本机制面向 ADK 的 Workflow 引擎google.adk.Workflow/node需要可被build_node构建的节点对象BaseAgent、BaseTool、BaseNode 或可调用对象显式传入纯数字run_id会被拒绝use_as_output委托在非 Workflow 父节点下每个父节点只能设置一次。以上行为均以当前仓库源码为准。【免费下载链接】adk-pythonAn open-source, code-first Python toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control.项目地址: https://gitcode.com/GitHub_Trending/ad/adk-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Data Science for Beginners 课程环境搭建全指南:从零配置 Jupyter、Python 与 Quiz 应用

Data Science for Beginners 课程环境搭建全指南:从零配置 Jupyter、Python 与 Quiz 应用

Data Science for Beginners 课程环境搭建全指南:从零配置 Jupyter、Python 与 Quiz 应用 【免费下载链接】Data-Science-For-Beginners 10 Weeks, 20 Lessons, Data Science for All! 项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginn…

2026/9/13 19:00:50 阅读更多 →
roop 快速上手:一张照片给视频换脸(免训练)

roop 快速上手:一张照片给视频换脸(免训练)

roop 快速上手:一张照片给视频换脸(免训练) 【免费下载链接】roop one-click face swap 项目地址: https://gitcode.com/GitHub_Trending/ro/roop roop 是一个开源的免费换脸工具:输入一张人脸照片加一段目标视频&#xff…

2026/9/13 19:00:50 阅读更多 →
Anthropic-Cybersecurity-Skills 实战指南:Serverless 函数注入检测与防护完整工作流(AWS Lambda)

Anthropic-Cybersecurity-Skills 实战指南:Serverless 函数注入检测与防护完整工作流(AWS Lambda)

Anthropic-Cybersecurity-Skills 实战指南:Serverless 函数注入检测与防护完整工作流(AWS Lambda) 【免费下载链接】Anthropic-Cybersecurity-Skills 817 structured cybersecurity skills for AI agents Mapped to 6 frameworks: MITRE ATT…

2026/9/13 18:59:50 阅读更多 →

最新新闻

公共饮水点地图动态抓取:从接口分析到增量采集、状态标准化与 SQLite 落库

公共饮水点地图动态抓取:从接口分析到增量采集、状态标准化与 SQLite 落库

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐⭐⭐⭐☆(高级) 🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。 全文目录: 🌟 开…

2026/9/14 21:01:32 阅读更多 →
SSM框架开发教师企业实践管理系统的设计与实现

SSM框架开发教师企业实践管理系统的设计与实现

1. 项目概述:教师企业实践管理系统的核心价值去年帮本地职业技术学院部署这套系统时,教务主任握着我的手说:"终于不用每天接几十个电话核对实践进度了。"这句话道破了这类系统的核心价值——将校企实践这个涉及多方协作、流程复杂的…

2026/9/14 21:01:32 阅读更多 →
如何撰写符合内容安全要求的技术博客

如何撰写符合内容安全要求的技术博客

根据您提供的项目标题"莫桑比克总统查波达沃斯观点-万祥军| 世界经济论坛国际科学院组织",这似乎是一个涉及国际政治与经济议题的内容。但根据您设置的内容安全说明,我无法就此类政治相关话题展开讨论或撰写文章。您的内容安全规则中明确要求&…

2026/9/14 21:01:32 阅读更多 →
Activepieces 集成 Strale:为 AI Agent 提供带质量评分的可信 API 能力层

Activepieces 集成 Strale:为 AI Agent 提供带质量评分的可信 API 能力层

Activepieces 集成 Strale:为 AI Agent 提供带质量评分的可信 API 能力层 【免费下载链接】activepieces AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & A…

2026/9/14 21:01:32 阅读更多 →
向模板引擎注入动态运行时对象:dbt-jinja dynamic-objects 示例深度解析

向模板引擎注入动态运行时对象:dbt-jinja dynamic-objects 示例深度解析

向模板引擎注入动态运行时对象:dbt-jinja dynamic-objects 示例深度解析 【免费下载链接】dbt dbt enables data analysts and engineers to transform their data using the same practices that software engineers use to build applications. 项目地址: https…

2026/9/14 21:01:32 阅读更多 →
Matlab/Simulink柴油发电机微电网仿真建模实践

Matlab/Simulink柴油发电机微电网仿真建模实践

1. 柴油发电机仿真系统概述柴油发电机作为微电网系统中的关键备用电源,其动态特性直接影响整个系统的稳定性。在Matlab/Simulink环境下搭建柴油发电机仿真模型,能够有效评估其在并网/孤岛模式下的运行性能。典型的微电网架构包含光伏阵列(PV&…

2026/9/14 21:00:32 阅读更多 →

日新闻

AI音乐侵权案中的测试工程与版权保护技术

AI音乐侵权案中的测试工程与版权保护技术

1. 项目概述:当测试工程师遇上AI音乐侵权案去年夏天,我作为技术顾问参与了一起特殊的著作权纠纷案——某音乐平台AI作曲功能被指控批量侵权。这起案件的特殊性在于:原告方并非传统音乐人,而是一家拥有百万级曲库的数字音乐发行商&…

2026/9/14 0:00:26 阅读更多 →
嵌入式面试I2C与SPI深度解析:从协议到量产调试

嵌入式面试I2C与SPI深度解析:从协议到量产调试

1. 这份“高频知识点洞察”到底是什么,又为什么值得你花时间细读? 如果你最近在刷嵌入式开发岗位的招聘JD,或者正坐在工位上改第7版简历,又或者刚被面试官一句“讲讲I2C和SPI的区别”问得手心冒汗——那你不是一个人。过去两年我带…

2026/9/14 0:00:26 阅读更多 →
51单片机开环控制磁阻传感器的硬件匹配与代码实现

51单片机开环控制磁阻传感器的硬件匹配与代码实现

简介:本资源是一份面向嵌入式初学者与单片机课程实践者的51单片机开关磁阻电机(SRM)开环控制教学方案,聚焦磁阻位置检测、固定时序驱动与基础状态可视化。资源包含1个C语言主程序文件(zhuang600.c)实现电机…

2026/9/14 0:00:26 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/14 5:45:49 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/14 0:52:26 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/14 0:06:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/14 17:35:10 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/14 16:59:29 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/14 5:45:14 阅读更多 →