ADK Runner 与 InMemoryRunner 执行引擎完全指南:会话、事件流与生产化配置

发布时间:2026/9/13 14:37:44

ADK Runner 与 InMemoryRunner 执行引擎完全指南:会话、事件流与生产化配置 ADK Runner 与 InMemoryRunner 执行引擎完全指南会话、事件流与生产化配置【免费下载链接】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-pythonRunner是 ADKAgent Development Kit中位于顶层的执行引擎负责会话生命周期管理、持久化状态解析、Agent 调用分发与结构化事件流Event回传InMemoryRunner则是默认的内存实现适合本地开发、CLI 应用与单元测试。本文以 Runner 官方指南 为核心骨架结合 runners.py 源码与 test_runners.py 测试用例完整讲解 Runner 的初始化、run_async执行链路、配置项语义以及如何从内存版平滑迁移到数据库支撑的生产级 Runner。Runner 是什么外部调用方与 Agent 树之间的执行边界执行一个 LLM Agent 或 Workflow远不止调用一次模型那么简单它需要协调会话存储session storage、产物管理artifact management、插件回调plugin callbacks以及多轮消息状态。如果让调用方直接实例化 Flow 或操作原始 Session 对象执行基础设施就会和 Agent 业务逻辑混在一起。Runner正是为了解决这一分层问题而设计——它是外部调用方与内部 ADK Agent 树之间的执行边界。一个 Runner 将根 Agent 或App容器与以下服务绑定会话服务BaseSessionService查找/创建/持久化会话记忆服务BaseMemoryService跨会话的长期记忆检索产物服务BaseArtifactService存储会话事件之外的二进制载荷与文件凭据服务BaseCredentialService工具鉴权所需的 OAuth 凭据管理。在此基础上Runner 对外暴露四类标准执行方法方法同步/异步适用场景run_async异步生成器生产环境首选完整的事件流控制run同步生成器本地测试与便捷调用源码注明only for local testing and convenience purposerun_live异步生成器实时双向流式交互实验性见 Runner Live Streamingrun_debug异步快速调试助手自动处理会话与输出格式从源码看run同步接口本质上是在后台线程中通过asyncio.run驱动run_async再通过queue.Queue把事件转发回调用线程见 runners.pyrun_debug则是面向新手调试的便捷封装默认使用debug_user_id/debug_session_id复用同一 session_id 即可延续对话见 runners.py。快速开始App InMemoryRunner 三步跑通首个 Agent官方文档给出的最小可用示例是将根 Agent 包装进App容器挂载到InMemoryRunner创建会话后以结构化的types.Content消息调用run_asyncfrom google.adk.agents import LlmAgent from google.adk.apps import App from google.adk.runners import InMemoryRunner from google.genai import types root_agent LlmAgent( namegreeter, instructionGreet users politely and answer their questions., ) app App( namegreeter_app, root_agentroot_agent, ) runner InMemoryRunner(appapp) # In an async function: # 1. Create a session explicitly using the session service session await runner.session_service.create_session( app_nameapp.name, user_iduser_123, session_idsession_456, ) # 2. Run agent turn with the created session async for event in runner.run_async( user_iduser_123, session_idsession.id, new_messagetypes.Content( roleuser, parts[types.Part.from_text(textHello, ADK!)], ), ): if event.content and event.content.parts: for part in event.content.parts: if part.text: print(event.author, part.text)这段代码的执行语义是Runner 在应用greeter_app下检索会话session_456把用户消息追加进会话事件列表执行root_agent随后逐个产出包含模型回复与工具输出的Event对象。关于其中几个值得注意的细节new_message.role可以省略run_async内部会在检测到空 role 时自动补为user见 runners.py。作为根 Agent 的LlmAgent默认以modechat运行run_async会显式地把mode is None的根 Agent 修正为 chat 模式见 runners.py。用户消息中不能包含 function call否则会抛出ValueError而包含 function response 的消息会被视为对之前中断调用的恢复见 runners.py。工作原理一次run_async调用背后的完整链路官方文档给出了Runner、BaseSessionService、PluginManager、InvocationContext与根BaseAgent之间协作的时序图整个生命周期可以拆解为四个阶段1. 会话解析与归一化Runner首先把根目标归一化为App。在run_async中它通过app.name、user_id、session_id三元组从session_service检索活跃的Session。如果会话缺失且auto_create_sessionTrue则自动创建新会话否则抛出SessionNotFoundError。这一逻辑对应源码中的_get_or_create_session助手见 runners.py测试用例 test_runners.py 也验证了缺失会话时抛错的行为。2. 上下文构建与事件摄入调用方的new_message被作为authoruser的事件追加进会话。随后Runner构建InvocationContext将以下能力全部链接进去会话状态app:、user:、temp:三种作用域前缀产物服务、记忆服务插件管理器RunConfig含custom_metadata等按次调用配置。_new_invocation_context会读取 Runner 上的 artifact/memory/credential service、plugin manager、context cache config 与 resumability config 组装上下文见 runners.py。3. 执行与事件流Runner 驱动根 Agent 生成器。每产生一个Event先经过PluginManager.run_on_event_callback()处理插件可以返回替代事件Runner 会把插件的字段变更合并回原始事件保证流式输出与持久化一致见 runners.py再 yield 给调用方。整个执行包裹在_exec_with_plugin中先执行before_run回调可提前退出并直接产出模型事件再执行主循环最后在成功或早退时执行after_run回调见 runners.py。4. 会话持久化与事件压缩产生的非 partial 事件会被持久化到session_service。若App上配置了events_compaction_config则在整个调用迭代完成后执行事件压缩_run_post_invocation_compaction。压缩采用尽力而为策略若压缩期间会话被更新的轮次修改旧摘要会被丢弃而不是让已完成的调用失败见 runners.py。配置选项详解Runner 构造参数Runner(...)/InMemoryRunner(...)的构造参数如下选项类型默认值说明appApp \| NoneNone推荐入口绑定根 Agent、插件与应用级配置的App容器agentBaseAgent \| NoneNone遗留的根 Agent 参数内部包装为App与app互斥nodeBaseNode \| NoneNone根节点Workflow 入口与app、agent互斥app_namestr \| NoneNone应用名可覆盖app.nameInMemoryRunner默认InMemoryRunnersession_serviceBaseSessionServiceRunner 必填会话存储后端memory_serviceBaseMemoryService \| NoneNone跨会话长期记忆后端artifact_serviceBaseArtifactService \| NoneNone存储会话事件之外的二进制载荷credential_serviceBaseCredentialService \| NoneNone工具鉴权凭据服务auto_create_sessionboolFalserun_async时会话缺失是否自动创建pluginslist[BasePlugin] \| NoneNone已弃用请在App(plugins[...])上配置plugin_close_timeoutfloat5.0插件 close 方法的超时秒数源码层面的关键约束见 runners.pyapp、agent、node三者必须恰好提供其一多传或全不传都会抛出带明确提示的ValueError传入agent时app_name为必填使用裸agent时内部通过App.model_construct包装绕过App的严格校验这是 v1 遗留 API 的兼容路径因此不会自动获得context_cache_config、events_compaction_config、resumability_config等应用级配置。InMemoryRunner是Runner的子类构造时自动装配三件套见 runners.pyInMemorySessionService()InMemoryArtifactService()InMemoryMemoryService()因此在开发/测试阶段你不需要手动传入任何 service。RunConfig 选项RunConfig通过runner.run_async(..., run_configRunConfig(...))按次调用传入完整字段见 run_config.py选项类型默认值说明custom_metadatadict[str, Any] \| NoneNone附加到InvocationContext的自定义元数据键值get_session_configGetSessionConfig \| NoneNone会话检索与事件窗口加载的细粒度配置model_input_contextlist[types.Content] \| NoneNone仅注入本次调用的模型输入、不持久化的临时上下文max_llm_callsint500单次 run 执行的 LLM 调用上限结合源码以下细节值得展开max_llm_calls的默认值并非写死的 500默认值由_default_max_llm_calls()解析优先读取ADK_MAX_LLM_CALLS环境变量解析失败或未设置时才回退到 500。取值 0表示不设上限但源码会打印警告提示可能导致模型与 Agent 之间无限循环通信 sys.maxsize会直接报错见 run_config.py。get_session_config与GetSessionConfig支持num_recent_events只取最近 N 条事件0 表示不取事件负数抛错与after_timestamp只取时间戳之后的事件两个过滤维度见 base_session_service.py。与EventsCompactionConfig配合可以避免每次调用都加载完整事件历史。model_input_context的语义这些内容只进入本次调用的 LLM 请求不会被 Runner 持久化到会话适合注入仅本回合生效的临时上下文而不污染对话历史。此外RunConfig还包含面向 Live 场景的大量字段例如streaming_modeNONE/SSE/BIDI、save_live_blob保存实时音视频到会话与产物服务、output_audio_transcription/input_audio_transcription、response_modalities、tool_thread_pool_config等。save_input_blobs_as_artifacts与save_live_audio均已标记弃用官方建议改用SaveFilesAsArtifactsPlugin或save_live_blob。会话服务内存实现与持久化扩展点BaseSessionService是 Runner 依赖的会话抽象见 base_session_service.py核心接口包括create_session(app_name, user_id, state, session_id)新建会话get_session(app_name, user_id, session_id, config)读取会话list_sessions(app_name, user_id)按最后更新时间升序列出会话delete_session(...)删除会话append_event(session, event)追加事件同时更新会话状态session:作用域并应用/裁剪temp:临时状态。InMemorySessionService的内部存储是一个三层嵌套字典sessions[app_name][user_id][session_id]见 in_memory_session_service.py并在返回会话时把app_state与user_state合并进会话状态。它对事件追加做了幂等去重——同 id 且相等的重复投递事件会被丢弃避免并发广播共享状态时重复应用见 in_memory_session_service.py。同时该类在类文档中明确注明不适用于多线程生产环境仅供测试与开发使用。高级应用自定义持久化 Runner数据库支撑的会话生产环境中将数据库支撑的会话与记忆服务注入Runner即可获得持久化会话能力。文档给出的示例from google.adk.apps import App from google.adk.runners import Runner from google.adk.sessions import DatabaseSessionService app App(namecustomer_support, root_agentroot_agent) session_service DatabaseSessionService(db_urlpostgresql://...) runner Runner( appapp, session_servicesession_service, )这里的App是应用级配置的载体见 app.py可以承载name应用名须通过validate_app_name校验以字母开头仅含字母/数字/下划线/连字符且不能是保留名userroot_agent根 Agent 或根 Node二者必须提供其一plugins应用级插件列表events_compaction_config事件压缩配置context_cache_config作用于应用内所有 LLM Agent 的上下文缓存配置resumability_config可恢复性配置启用后支持中断调用的恢复。值得留意的是Runner在构造时会基于根 Agent 的定义位置推断其来源应用名当推断出的名称与runner.app_name不一致时会记录警告日志并在后续SessionNotFoundError的错误信息中附带对齐提示见 runners.py。自动会话创建默认情况下对不存在的session_id调用run_async会抛出SessionNotFoundError。如果希望省去显式create_session调用在会话缺失时自动创建只需在构造时设置auto_create_sessionTruerunner InMemoryRunner(appapp, auto_create_sessionTrue)从源码看auto_create_session同时作用于run_async、rewind_async与run_live的会话获取路径_get_or_create_session测试 test_runners.py 覆盖了普通 run、rewind、live 三种模式下的自动建会话行为。开启后无需手动调用session_service.create_sessionRunner 会在get_session返回空时用同样的(app_name, user_id, session_id)自动创建。限制与注意事项App 与裸 Agent 的差异Runner(agent...)只是把 Agent 包装进一个未经校验的App缺少context_cache_config、events_compaction_config与resumability_config。生产应用务必通过app传入显式构造的App。此外当应用支持 Agent 间 transfer 但没有配置上下文缓存时Runner 会发出警告每次 transfer 都会替换系统指令与工具集请求前缀变化导致整个 prompt 需要重新发送而无法命中缓存见 runners.py。InMemoryRunner 的易失性InMemoryRunner默认使用InMemorySessionService会话状态只存在于内存中进程终止即丢失。需要持久化的场景必须切换到数据库支撑的Runner。同步run的定位run仅供本地测试与便捷使用生产环境请使用run_async。相关指南与示例App Container —App配置、插件与横切能力的完整指南Runner Live Streaming — 基于run_live与LiveRequestQueue的实时双向流式指南Session and BaseSessionService — 会话存储后端与状态作用域指南Agent-to-Agent Sample — 通过Runner执行的多 Agent 示例应用runners.py —Runner/InMemoryRunner完整实现test_runners.py — Runner 行为测试覆盖会话创建、自动建会话、rewind、事件回调等场景。【免费下载链接】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),仅供参考
延伸阅读

更多相关文章

2026/9/13 14:32:44

跨境电商节日营销策略与实战指南

1. 跨境电商节日营销的重要性与挑战跨境电商的节日营销早已成为行业增长的黄金节点。根据行业数据显示,2023年全球跨境电商节日季销售额突破1.2万亿美元,占全年总交易量的35%以上。但与此同时,超过60%的卖家反映节日期间的广告成本上涨了3-5倍…

2026/9/13 14:32:44

AD7606+STM32F407以太网TCP高速上传:FSMC与LwIP关键配置

简介:基于 STM32F407 与 AD7606 的 16 位 8 通道数据采集及 TCP/IP 网络传输完整工程源码,面向嵌入式开发者、毕设/电赛备赛者及工业远程监测项目起步。程序覆盖 AD7606 的 SPI 高速采样、数值滤波处理,再到 STM32F407 以太网 MAC 外设的 LwI…

2026/9/13 17:12:55

CAN自定义协议设计:ID规划、数据编码与可靠性加固

1. 为什么“CAN自定义协议”不是填空题,而是系统级工程决策很多人第一次接触CAN总线时,看到标准帧里有11位ID、8字节数据、CRC校验、ACK应答这些固定结构,就下意识觉得:“协议不就是把数据塞进这8个字节里吗?ID随便设个…

2026/9/13 17:12:55

WW-Mutex中两种算法

1 Wait-Die If the transaction holding the lock is younger, the locking transaction waits. 如果持有锁的是新事务,那么正在请求锁的事务就选择等待 If the transaction holding the lock is older, the locking transaction backs off and dies. 如果持有锁的是…

2026/9/13 17:07:55

深度强化学习实战:基于MCTS与策略价值网络的Hex棋智能体

简介:面向高校计算机、人工智能相关专业课程设计与毕业设计,这份基于深度强化学习的Hex棋项目提供了一套可运行、可扩展的完整示例。项目将神经网络与强化学习结合,可用于训练六角棋盘对弈AI,代码中覆盖了CNN等网络结构、Q-learni…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/13 11:18:28

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码