adk-python ManagedAgent 实战:自定义托管 Agent 资源的控制面生命周期(创建、复用与删除)
2026/9/13 20:26:03 网站建设 项目流程

adk-python ManagedAgent 实战:自定义托管 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-python

本篇围绕 custom_agent 示例 讲解 ADK Python 中ManagedAgent控制面生命周期:如何通过 genai 客户端创建一个人格与服务器端工具已"烘焙"进去的、持久化命名的自定义托管 Agent 资源,再用adk run/adk web驱动它完成多轮对话,最后将其删除。读完本文,你能完整掌握托管 Agent 的创建参数、运行方式、异步就绪问题处理,以及api_client数据面/控制面复用的底层原理。

一、示例定位:内联配置 vs 自定义资源

ManagedAgent支持两种配置方式,选择边界必须清晰:

  • 内联配置(不需要创建资源)ManagedAgent直接接受instruction=...作为人格(persona),也接受tools=[google_search]作为服务器端工具。分别参见 system_instruction 示例 与 basic 示例。
  • 自定义资源(本示例):当你需要一个人格与服务器端工具固化进资源、并且可以被其他应用和其他会话通过 id 复用的可复用、服务器托管 Agent 时,才需要通过控制面创建一个具名的 Agent 资源。

本示例 agent.py 驱动的就是这条完整生命周期:用--create预置资源(复用ManagedAgent已经持有的 genai 客户端root_agent.api_client,它同时暴露 interactions 与 agent create/delete 两个平面),然后用adk web/adk run驱动root_agent,最后用--delete删除。

完整的后端选择、鉴权与凭据准备,参见 ManagedAgent 官方指南。

二、前置条件:必须使用 GEAP / Vertex 后端

自定义 Agent 的创建只能走GEAP / Vertex 后端globallocation);Gemini API 后端无法创建 Agent 资源。这一点在源码中被硬性执行:

  • _managed_agent.py 中把_MANAGED_AGENT_LOCATION = 'global'写死为常量,因为 Managed Agents API 只在global位置提供服务,地域端点会拒绝这些调用(例如抛出 "Resource setup has just started");
  • _validate_client_location 对注入的企业(Vertex)客户端做位置校验:若客户端的location不是global,直接抛出ValueError,避免以静默失败的方式浪费排障时间;
  • 单元测试 test_managed_agent.py(test_lazy_client_enterprise_uses_global_location)验证了企业模式下惰性创建的客户端确实带enterprise=True, location='global'

因此运行本示例前,需要按指南配置 Google Cloud 凭据(例如gcloud auth application-default login)并启用企业后端(GOOGLE_GENAI_USE_ENTERPRISE或旧式的GOOGLE_GENAI_USE_VERTEXAI)。

三、示例代码全解析

示例的核心结构非常精简,全文如下(取自 contributing/samples/managed_agent/custom_agent/agent.py):

import argparse from dotenv import load_dotenv from google.adk.agents import ManagedAgent load_dotenv() _AGENT_ID = 'adk-custom-search-agent' _SYSTEM_INSTRUCTION = ( 'You are a concise research assistant. Use Google Search to ground every ' 'answer in current sources, cite the sources you used, and keep answers to ' 'a few sentences.' ) root_agent = ManagedAgent( name='custom_managed_agent', agent_id=_AGENT_ID, environment={'type': 'remote'}, ) def main() -> None: """Create or delete the custom managed-agent resource.""" parser = argparse.ArgumentParser( description='Create or delete the custom managed agent for this sample.' ) parser.add_argument( '--create', action='store_true', help='Create the custom managed agent.' ) parser.add_argument( '--delete', action='store_true', help='Delete the custom managed agent.' ) args = parser.parse_args() if not (args.create or args.delete): parser.print_help() return # ManagedAgent's genai client also exposes agent create/delete. client = root_agent.api_client if args.create: client.agents.create( id=_AGENT_ID, base_agent='antigravity-preview-05-2026', system_instruction=_SYSTEM_INSTRUCTION, tools=[{'type': 'google_search'}], ) print(f'Created "{_AGENT_ID}".') if args.delete: client.agents.delete(id=_AGENT_ID) print(f'Deleted "{_AGENT_ID}".')

代码里有三个关键点:

  1. root_agent只声明、不携带人格ManagedAgent(name=..., agent_id=_AGENT_ID, environment={'type': 'remote'})中没有内联instructiontools——因为人格(_SYSTEM_INSTRUCTION)和google_search工具是在创建资源时固化的(见client.agents.create(...)),运行时通过agent_id连接即自动获得这些能力。
  2. agent_id是资源句柄'adk-custom-search-agent'就是创建出来的具名资源 id;创建成功后,任何应用只要把ManagedAgent(agent_id='adk-custom-search-agent')指向它,就能共享同一份人格与工具配置。
  3. 创建在基座 Agent 之上扩展base_agent='antigravity-preview-05-2026'表示在 Google 一方托管的 Antigravity 基座 Agent 上叠加自定义system_instructiontools=[{'type': 'google_search'}],而不是从零开始。

四、三步运行生命周期

# 1. 创建自定义 Agent(只需一次)。 python contributing/samples/managed_agent/custom_agent/agent.py --create # 2. 与它对话。预置可能需要几分钟(项目里第一个 Agent 会更久), # 所以 --create 之后稍等片刻再发起第一轮对话。 adk run contributing/samples/managed_agent/custom_agent # 或者:adk web # 3. 用完后删除。 python contributing/samples/managed_agent/custom_agent/agent.py --delete

异步创建是必须理解的细节--create在 Agent 完全就绪之前就返回了。如果第一轮对话报出 "not found" / "being created" 类错误,等几秒后重试即可——这不是配置错误,而是资源仍在预置中。官方指南也明确说明:自定义 Agent 的system_instruction和 tools 在创建时就已固定,创建过程是异步的("the agent takes a short while to become ready"),参见 ManagedAgent 指南。

五、api_client:一个客户端横跨数据面与控制面

"复用ManagedAgent已持有的 genai 客户端来创建/删除资源"是本示例最值得借鉴的技巧。其底层实现在 ManagedAgent.api_client:

  • 它是一个惰性属性:构造时可以不传客户端,首次访问时按环境变量解析后端——若GOOGLE_GENAI_USE_ENTERPRISE(或旧式GOOGLE_GENAI_USE_VERTEXAI)启用,则以enterprise=True, location='global'构造google.genai.Client;否则构造开发者 API 客户端;
  • 该 genai 客户端既暴露interactions(数据面,即 Agent 对话时调用的interactions.create),又暴露agents.create/agents.delete(控制面,即 Agent 资源本身的增删),因此示例里client = root_agent.api_client之后直接client.agents.create(...)即可,不需要另行配置第二个客户端;
  • 若你在构造时显式注入了api_client,ADK 会先做global位置校验(企业客户端),并原样返回注入的客户端、不会向调用方的客户端附加额外的http_options——这一点由 test_injected_client_is_not_tagged 等测试固化。

六、运行时状态恢复:为什么多轮对话能"接得上"

示例中environment={'type': 'remote'}为每个 interaction 提供一个远程沙箱(此项是可选的——basic 示例同样使用,而工具不需要沙箱的示例可以省略;对照 remote_mcp 示例)。多轮对话能够连续的关键在于 ADK 本地的"最小状态"设计,源码位于 ManagedAgent._run_async_impl:

  • 每轮开始时,_find_previous_interaction_state(定义于 interactions_processor.py)扫描该 Agent 在当前分支上的历史会话事件,恢复出最近的previous_interaction_id与沙箱environment_id
  • 恢复到的previous_interaction_id会作为create_kwargs传给 interactions 请求,environment则优先取上轮恢复的沙箱 id(prev_environment_id or self.environment),从而让对话历史和沙箱在同一环境里延续
  • 一切请求均以background=True+ 流式方式发出(Managed Agents API 的工作流要求),响应事件实时流回 ADKRunner

这意味着本地 ADK 会话只持久化两个 id,真正的对话源(source of truth)在服务端;ADK 从不把历史轮次重新发给后端。示例中"Summarize that in one sentence"这类追问能成功,正是这条恢复链在起作用。

七、示例输入与交互流图

回答基于实时搜索,具体文本会有波动。推荐的验证输入:

  • What are the most significant AI announcements this week?创建出的 Agent 人格("concise" + "cite the sources")会让它简洁作答并引用来源,搜索由服务器端google_search完成;
  • Summarize that in one sentence.复用恢复出的 interaction 的追问轮(多轮链式调用)。

整体交互流(与 README 中的 Graph 一致):

八、How To 要点速查

要点做法
定义自定义 Agentclient.agents.create(...)传入system_instruction(人格)与服务器端tools(此处为{'type': 'google_search'}),基于antigravity-preview-05-2026基座 Agent 扩展
复用 ManagedAgent 客户端root_agent.api_clientManagedAgent已持有的 genai 客户端;其agents.create/agents.delete覆盖控制面
预置沙箱ManagedAgent(environment={'type': 'remote'})为每个 interaction 提供远程沙箱——可选,且沙箱 id 会被自动恢复复用
运行--create预置、--delete删除;中间阶段root_agent就是普通的BaseAgentadk web/adk run(或Runner)均可驱动

九、适用前提与限制

结合 ManagedAgent 指南 与 源码实现,使用该能力前需注意:

  • 位置锁定(仅 GEAP):Managed Agents API 目前仅从global位置提供服务,使用地域端点的企业客户端会在构造时抛出ValueError
  • 仅支持服务器端工具:客户端执行的工具(Python 函数、callable)和裸 MCP 配置不被支持,传入会抛NotImplementedError(见 _resolve_backend_tools 的校验分支);
  • 仅流式交互:Agent 原生以stream=True创建 background interaction 并消费流,尚不支持非流式轮询执行;
  • 创建异步--create返回后资源可能仍在预置,首轮流失败时应按"not found / being created"语义稍候重试。

配套的相关示例(同属 managed_agent 目录):basic、code_execution、system_instruction、remote_mcp、single_turn,可对照理解"内联配置"与"自定义资源"两条路径的差异。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询