ADK Python 应用容器 App 完全指南:从根 Agent 绑定到跨切面配置
ADK Python 应用容器 App 完全指南从根 Agent 绑定到跨切面配置【免费下载链接】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-pythonApp是 ADK Pythongoogle.adk应用的最顶层容器它把根 Agent或工作流根节点与仅属于整个应用的配置——应用名称、插件、上下文缓存context caching、事件压缩event compaction与可恢复性resumability——绑定在一起。读完本文你将掌握如何用App组织一个完整 ADK 应用、如何通过 CLI 或编程方式运行它、如何配置三项跨切面能力以及它与旧版裸 Agent 传参方式Runner(agent..., app_name...)之间的差异与迁移要点。App 是什么为什么需要这个顶层容器一个 Agent 描述的只是对话中的一个参与者一个模型、一段指令、一组工具也许还有若干子 Agent。但在真实部署中有很多东西不属于任何一个 Agent而是属于整个应用应用名称会话session按应用名索引一个应用只有一个名字插件plugins需要观察整棵 Agent 树上的每一个 Agent、每一次模型调用和每一次工具调用跨切面配置上下文缓存、事件压缩、可恢复性作用于整棵 Agent 树而不是树中的某一个节点。App就是承载这些内容的地方。从源码看它本质上是一个Pydantic 模型继承自pydantic.BaseModel持有root_agent加上上述应用级配置见 src/google/adk/apps/app.py。这样配置就跟随 Agent 定义一起流动而不是散落在每一个构造Runner的调用点。值得注意的是App没有单独的根节点字段工作流的根BaseNode同样放在root_agent字段中App的校验逻辑接受BaseAgent或BaseNode两种类型。Runner在内部会把传入的参数归一化为AppRunner._resolve_app所以直接传一个裸 Agent 也能跑但只有App能携带这些跨切面配置。官方推荐路径是Runner(app...)这一点在本文App 与裸 Agent 的区别一节详述。快速开始把 Agent 包装进 App定义一个带工具调用的 Agent再用App把它包起来。下面这个例子构建了一个带get_weather工具的天气 Agent并将其放入名为weather_app的App中同时挂载了LoggingPluginfrom google.adk.agents import LlmAgent from google.adk.apps import App from google.adk.plugins import LoggingPlugin def get_weather(city: str) - str: Returns a one-line weather report for the given city. return fIt is sunny in {city}. root_agent LlmAgent( nameweather_agent, modelgemini-2.5-flash, instructionAnswer weather questions using the get_weather tool., tools[get_weather], ) app App( nameweather_app, root_agentroot_agent, plugins[LoggingPlugin()], )这里的App是插件能够生效的关键Runner(plugins...)已弃用而且也只有App能设置缓存、压缩与可恢复性三项配置。仓库中有一个完整可运行的官方示例自定义了CountInvocationPlugin统计 Agent 与 LLM 调用次数并组合了上下文缓存与事件压缩配置见 contributing/samples/core/app/agent.py。运行你的 AppCLI 与编程两种方式方式一交给 CLI 命令adk run、adk web、adk api_server都会为你构建Runner。它们会先在 Agent 模块中查找模块级变量app只有在找不到App时才回退到root_agent。因此把上面的App导出为模块级app变量这三条命令就能自动拾取插件和全部跨切面配置。当以这种方式加载 Agent 时如果 app 名称与 Agent 所在目录不一致Runner会打印一条警告日志并提示它期望的目录名。从源码看这一逻辑位于Runner._enforce_app_name_alignmentsrc/google/adk/runners.pyRunner会通过_adk_origin_app_name元数据或模块路径推断 Agent 的来源目录与app_name比对。重命名目录或 App 使二者一致即可消除警告。该警告同样会出现在会话查找失败的报错提示中_format_session_not_found_message提示可能是名称不一致导致Runner找不到会话。方式二编程驱动如果你要自己驱动 App则需要创建会话服务、把App交给Runner然后运行一轮用户对话并逐条打印事件import asyncio from google.adk.runners import Runner from google.adk.sessions import InMemorySessionService from google.genai import types async def main() - None: session_service InMemorySessionService() session await session_service.create_session( app_nameapp.name, user_iduser ) runner Runner(appapp, session_servicesession_service) async for event in runner.run_async( user_iduser, session_idsession.id, new_messagetypes.Content( roleuser, parts[types.Part(textWhat is the weather in Zurich?)], ), ): if event.content and event.content.parts: print(event.author, event.content.parts[0].text) if __name__ __main__: asyncio.run(main())注意会话是在app.name下创建的。会话服务按应用名索引所有会话所以App上的名称与查找会话时使用的名称必须一致。Runner在初始化时会把self.app_name app_name or app.namesrc/google/adk/runners.py后续的get_session/create_session全部使用该名称。App 与裸 Agent 的区别两条路径并不等价Runner同时接受App或裸 Agent并且会在做任何其他事情之前先把裸 Agent 变成App。但这两条路径并不等价# Current: the App carries the application-wide configuration. runner Runner(appapp, session_servicesession_service) # Legacy: the agent is wrapped in an App for you. runner Runner( app_nameweather_app, agentroot_agent, session_servicesession_service, )旧形式是 ADK 1.x 接受的写法目前仍然支持但它与App路径有三点差异跳过校验包装过程会绕过App的字段校验源码中用的是App.model_construct见 src/google/adk/runners.py因此一个App会拒绝的应用名在这里反而会被接受跨切面配置无法设置context_cache_config、events_compaction_config、resumability_config都会被留空。Runner没有对应的参数App是设置它们的唯一途径plugins参数已弃用Runner(plugins[...])会触发DeprecationWarning如果同时传入app和plugins会直接抛出ValueError——请把插件放到App上。相关校验逻辑在Runner._resolve_appsrc/google/adk/runners.py。另外当app与app_name同时给出时会话查找以app_name为准而app.name保持不变。同时传两者通常不是你想要的。Runner构造时还要求app、agent、node三者恰好提供一个否则抛出ValueErrorsrc/google/adk/runners.py。App 字段详解字段类型默认值说明namestr必填应用名称会话按它索引。root_agentBaseAgent或BaseNode必填执行入口。BaseNode是google.adk.workflow中的工作流节点基类因此Workflow也可以作为根。pluginslist[BasePlugin][]应用级插件其回调对每一次 Agent、模型调用与工具调用都会触发。context_cache_configContextCacheConfig \| NoneNone为应用内所有 LLM Agent 启用上下文缓存缺省表示缓存关闭。events_compaction_configEventsCompactionConfig \| NoneNone对较早的会话事件做摘要防止上下文无限增长。resumability_configResumabilityConfig \| NoneNone允许调用在长时间运行的函数调用处暂停并在之后恢复。App的 Pydantic 配置为extraforbidsrc/google/adk/apps/app.py会禁止未知关键字——拼错的字段名会抛出ValidationError而不是被静默忽略。应用命名规则应用名必须以字母开头之后可包含字母、数字、下划线和连字符user被拒绝因为它是保留给最终用户输入的名称。源码中的正则与校验见validate_app_namesrc/google/adk/apps/app.py_VALID_APP_NAME_RE re.compile(r^[a-zA-Z][a-zA-Z0-9_-]*$)如果你想在构造 App 之前先校验名称可以直接从google.adk.apps.app导入validate_app_name使用。App的模型校验器也会在构造时调用它并在root_agent缺失或类型错误时抛出相应的ValueError/TypeError。三个配置类型的导入位置三个配置类型从不同位置导入注意不要弄混from google.adk.agents.context_cache_config import ContextCacheConfig from google.adk.apps import ResumabilityConfig from google.adk.apps.app import EventsCompactionConfig其中google.adk.apps只导出App和ResumabilityConfig见 src/google/adk/apps/init.pyEventsCompactionConfig需要从google.adk.apps.app导入。服务挂在 Runner 上而不是 App 上App只保存声明式配置。会话、制品artifact、记忆memory与凭据credential服务都是Runner的构造参数——它们是部署层面的接线wiring而不是应用定义的一部分。因此同一个App可以在测试中使用内存服务、在生产中使用持久化服务而无需任何改动。session_service是唯一必需的服务。本地开发时InMemoryRunner会提供内存版的会话、制品和记忆服务并接受同一个Appfrom google.adk.runners import InMemoryRunner runner InMemoryRunner(appapp)从源码看InMemoryRunner在初始化时自动装配InMemoryArtifactService、InMemorySessionService与InMemoryMemoryServicesrc/google/adk/runners.py非常适合测试与快速原型。Runner也支持auto_create_sessionTrue在会话不存在时自动创建。配置跨切面功能每个配置项只有设置到App上才会生效未设置时均保持惰性inertapp App( nameweather_app, root_agentroot_agent, context_cache_configContextCacheConfig( cache_intervals10, ttl_seconds1800, min_tokens2048 ), events_compaction_configEventsCompactionConfig( compaction_interval5, overlap_size1 ), resumability_configResumabilityConfig(is_resumableTrue), )上下文缓存ContextCacheConfigContextCacheConfig定义在 src/google/adk/agents/context_cache_config.py启用后作用于应用内所有LLM Agentcache_intervals复用同一份缓存的最大调用次数默认10取值范围1–100ge1, le100ttl_seconds缓存存活时间秒默认180030 分钟必须大于 0min_tokens启用缓存所需的最小前置请求 token 数默认0。注意它针对的是上一次请求的实际 prompt token 数。Gemini 模型自身的最小值始终生效Gemini 2.5 为 2048 tokenGemini 3 为 4096 token会话的首次请求不会创建缓存缓存最早从第二轮开始。调高该值可以避免为小请求付出缓存存储开销create_http_options可选的types.HttpOptions用于给CachedContent.create()设置超时如types.HttpOptions(timeout10000)表示 10 秒。缓存创建超时后请求会继续但不带缓存。事件压缩EventsCompactionConfigEventsCompactionConfig定义在 src/google/adk/apps/_configs.py。它至少需要一个触发器且两种触发器各是一对参数必须成对设置滑动窗口对compaction_intervaloverlap_size。compaction_interval表示新用户发起的调用数量达到多少时触发压缩必须 0overlap_size表示从前一次压缩范围末尾向前包含多少个调用使相邻摘要之间有重叠以保持上下文 0token 预算对token_thresholdevent_retention_size。token_threshold为调用后压缩的 token 阈值必须 0event_retention_size表示触发压缩时保留多少个原始事件不被压缩 0。校验器_validate_trigger_params强制要求token_threshold与event_retention_size必须同时设置compaction_interval与overlap_size必须同时设置两组至少配置一组否则抛出ValueError。从 src/google/adk/apps/compaction.py 的实现看滑动窗口压缩的流程是在每次调用完成后统计自上次压缩以来新增的调用数达到阈值后从新调用块起点往前数overlap_size个调用处开始、到当前块最后一个调用为止生成一个CompactedEvent摘要事件并追加到会话。例如compaction_interval2, overlap_size1时调用 1、2 完成后生成覆盖 [1,2] 的摘要调用 3、4 完成后生成覆盖 [2,4] 的摘要与上一次重叠调用 2。同时token 阈值压缩会读取最近一次事件中的prompt_token_count必要时以约 4 字符/token 估算并在压缩前通过最长自包含前缀算法保证不会把成对的工具调用/响应拆散。Summarizer 的默认行为如果summarizer未设置ADK 会用根 Agent 的模型自动构建LlmEventSummarizer——源码中_ensure_compaction_summarizer会检查config.summarizer为空时要求根 Agent 是LlmAgent并以LlmEventSummarizer(llmagent.canonical_model)初始化src/google/adk/apps/compaction.py。因此根 Agent 需要可用的 LLM 模型否则压缩配置会因缺少摘要器而报错。可恢复性ResumabilityConfigResumabilityConfig定义在 src/google/adk/apps/_configs.py目前只有一个字段is_resumable: bool False。启用后该能力作用于应用内所有 Agent允许调用在遇到长时间运行的函数调用时暂停并在之后从最后的事件恢复。注意 ADK 的恢复是**尽力而为best-effort**的详见下一节限制说明。已知限制与注意事项实验性配置EventsCompactionConfig、ResumabilityConfig、ContextCacheConfig三者都在构造时发出实验性警告源码中均标注了experimental装饰器并可能在无通知的情况下变更EventsCompactionConfig未被 re-exportgoogle.adk.apps只导出App和ResumabilityConfig请从google.adk.apps.app导入EventsCompactionConfig恢复是尽力而为的可能被恢复的工具必须具有幂等性因为恢复只保证至少一次执行at-least-once并且暂停期间任何内存态都会丢失这些约束在ResumabilityConfig的 docstring 中有明确说明见 src/google/adk/apps/_configs.py。相关示例官方提供了完整的应用配置示例含自定义插件、上下文缓存与事件压缩组合可直接参考 contributing/samples/core/app示例代码见其中的 agent.py。【免费下载链接】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),仅供参考