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

发布时间:2026/11/6 1:53:18

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/11/6 20:03:10

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

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

2026/11/6 3:06:34

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

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

2026/11/6 22:33:04

电工证可以安装电吗?网上查询报名不再怕被中介坑

电工证可以安装电吗?网上查询报名不再怕被中介坑 不知道去哪报名怕被中介坑,其实电工证的报考流程早就规范化, 各地市安全生产教育培训中心 都有明确的报名渠道,你只需要掌握正确的方法。 网上查询…

2026/11/6 22:33:04

广西怎么去考低压电工证?学历不高也能报名,官方报名入口在这里

广西怎么去考低压电工证?学历不高也能报名,官方报名入口在这里 你是不是也担心自己学历不高,报不了低压电工证?别急,广西的官方报名入口对学历要求并不高,只要你是初中及以上学历,就能报名参加低压电工证的考试。不管是想转行还是提升技能,低压电工证…

2026/11/6 22:33:04

低压电工证科三题库保姆级教程:别再被中介坑了,自己看懂报名流程

低压电工证科三题库保姆级教程:别再被中介坑了,自己看懂报名流程 你是不是也经常听到别人说“低压电工证科三题库很难”,但又不知道从哪下手?更担心自己报名被中介骗钱、被坑?别急,今天我就给你一套保姆级教程,从报名流程到题库复习,都给你安排得明明…

2026/11/6 22:33:04

别怕学历低!弱电电工证样板官方报名入口全攻略

别怕学历低!弱电电工证样板官方报名入口全攻略 你是不是也在担心学历不够, 弱电电工证样板 根本报不了名?别急,这篇文章就是为你准备的。我曾和你一样,是驻马店一所高校的应届毕业生,学的是工程类专业,但对特种作业证书一窍不通。今天我来告诉你,怎…

2026/11/6 22:28:04

邓州考电工证在哪里考真实经历告诉你怎么避开报名坑

邓州考电工证在哪里考真实经历告诉你怎么避开报名坑 你是不是也和我一样,学历不高怕报不上名?去年我跟着工头一起去邓州考电工证,报名的时候被问得一头雾水,心里直打鼓,怕因为学历问题被拒之门外。结果呢?人家根本没提学历,反而问了我是不是有相关工作…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/6 1:03:39

MCU晶振电路设计全解析:从负载电容计算到PCB布局调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

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

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