尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

使用 ADK + A2UI v0.9 构建 Gemini Enterprise 演示 Agent:从本地运行到 Cloud Run 部署全指南

使用 ADK + A2UI v0.9 构建 Gemini Enterprise 演示 Agent:从本地运行到 Cloud Run 部署全指南 使用 ADK A2UI v0.9 构建 Gemini Enterprise 演示 Agent从本地运行到 Cloud Run 部署全指南【免费下载链接】a2ui项目地址: https://gitcode.com/GitHub_Trending/a2/a2ui本指南基于仓库中 samples/community/agent/adk/gemini_enterprise/v0_9 目录下的官方示例README.md及其配套源码完整讲解如何用 Google Agent Development KitADK与 A2UI Agent SDK 构建一个A2UI v0.9 Demo通用演示 Agent它只支持 A2UI v0.9 协议使用 Gemini Enterprise 复合目录渲染 Material 组件与Canvas、IFrameSrcdoc、IFrameUrl自定义组件的富交互 UI并通过 A2AAgent-to-Agent协议对外提供服务可一键部署到 GCP Cloud Run。读完本文你将掌握该示例的架构拆解、本地运行与验证方法、Cloud Run 部署参数以及组件目录与 UI 模板的维护更新方式。示例概览一个展示 A2UI v0.9 能力的活菜单该示例是一个名为A2UI v0.9 Demo的通用演示 Agent。与单一功能的业务 Agent 不同它本身就是一个组件展示台——向它提问what can you do?它就会渲染一个 A2UICanvas侧边面板列出所有可演示的能力每个能力对应一个可点击的按钮。它能够演示的 UI 能力包括Material 基础组件卡片、文本、按钮、图标、图片、徽章badge。表单与输入MaterialInput、MaterialSelect、MaterialCheckbox、MaterialRadioButton、MaterialSlideToggle、MaterialSlider、MaterialChips、MaterialButtonToggle、MaterialDatepicker、MaterialTimepicker。标签页与布局MaterialTabs、MaterialExpansionPanel、MaterialGridList、MaterialRow、MaterialColumn。数据展示MaterialTable、MaterialProgressBar、MaterialProgressSpinner。对话框与菜单MaterialDialog、MaterialMenu。Canvas 侧边面板以Canvas为根组件在可调整大小的侧栏中渲染内容。Iframe 嵌入IFrameSrcdoc在沙箱 frame 中渲染 Agent 提供的 HTML与IFrameUrl嵌入经过白名单校验的 URL。餐厅查询查找餐厅并预订餐桌。这些能力都在 agent.py 中通过两个AgentSkill对外声明a2ui_demoA2UI v0.9 组件演示与find_restaurants餐厅查询工具并附带了可直接用于测试的示例提问如 Show me a demo of Material components、Render a contact form、Demo the Canvas side panel 等。与上游 restaurant_finder 示例的三点关键差异该示例最初移植自上游的 restaurant_finder 示例但做了三处本质性改造理解了这三点也就理解了整个示例的设计意图仅支持 A2UI v0.9。v0.8 的支持被完全移除Agent 只声明并对外提供 A2UI v0.9 扩展。在 agent.py 中通过A2UI_VERSION VERSION_0_9固定版本且在stream()方法里强制ui_version A2UI_VERSION无论客户端请求什么版本都按 v0.9 处理。使用 Gemini Enterprise 复合目录。Agent 不再使用打包的BasicCatalog而是加载本目录下的gemini_enterprise_composite_catalog.json。该目录是标准 Material 目录、基础目录与 Gemini Enterprise 自定义组件Canvas、IFrameSrcdoc、IFrameUrl三者的并集因此单个 surface 可以混用三种组件族。examples/0.9/下的 UI 模板正是混用了Material*、Canvas、IFrame*组件。通用化改造。Agent 不再局限于餐厅场景而是根据用户请求动态生成最能体现相关组件的 UI。项目结构与运行时架构该示例目录结构如下可对照 v0_9 目录查看v0_9/ ├── __main__.py # 本地运行的 click CLI 入口默认 localhost:10002 ├── main.py # Cloud Run 入口serve()端口取自 PORT 环境变量默认 8080 ├── agent.py # A2uiDemoAgentAgentCard、SchemaManager、LLM Agent、UI 校验重试 ├── agent_executor.py # A2uiDemoAgentExecutorA2A 请求分发与 UI 事件处理 ├── prompt_builder.py # ROLE_DESCRIPTION / UI_DESCRIPTION 提示词与纯文本回退提示 ├── tools.py # get_restaurants 工具函数 ├── deploy.sh # Cloud Run 一键部署脚本 ├── pyproject.toml # 依赖声明与 start 脚本入口 ├── gemini_enterprise_composite_catalog.json # 复合目录本地副本 ├── restaurant_data.json # 餐厅示例数据 └── examples/0.9/ # 13 个 A2UI v0.9 示例 UI 模板JSON服务端装配A2A Starlette两条入口路径最终都汇入同一个装配逻辑用A2AStarletteApplication把 AgentCard 与请求处理器包成 Starlette 应用再用uvicorn启动本地运行main.py通过click暴露--host默认localhost与--port默认10002参数并设置仅放行本地的 CORS 规则allow_origin_regexrhttp://localhost:\d。Cloud Runmain.py绑定0.0.0.0端口读取PORT环境变量默认8080CORS 放行任意http(s)://来源以支持远程 A2UI 客户端跨域调用Agent 的公开地址取自AGENT_URL环境变量由deploy.sh部署后写入本地则回退为http://host:port。两者都会在存在images/目录时挂载/static静态资源服务用于餐厅图片若目录不存在仅记录 warning 而不会导致启动失败。pyproject.toml中通过[project.scripts] start main:serve声明了 Cloud Run buildpack 启动 Cloud Run 时调用的入口。双 Agent 设计UI Agent 与纯文本回退 AgentA2uiDemoAgent 内部构建了两个独立的 ADK RunnerUI Runner携带A2uiSchemaManager加载复合目录系统提示词由schema_manager.generate_system_prompt(...)动态生成包含角色描述、UI 规则、完整 schema 与全部示例模板include_schemaTrue、include_examplesTrue、validate_examplesTrue。文本 Runner不加载 schema使用 prompt_builder.py 中的get_text_prompt()当客户端未启用 A2UI 扩展时以纯文本回复避免生成无法解析的 UI。两个 Runner 共享同一模型选择逻辑模型名取自MODEL环境变量默认gemini-2.5-flash且会去掉前缀只取最后一段如models/gemini-2.5-flash→gemini-2.5-flash。ADK 的服务Session、Memory、Artifact均使用内存实现适合演示场景。事件分发点击按钮如何变成 UIA2uiDemoAgentExecutor 负责把 A2A 请求拆解为三类文本消息直接透传给 LLM。run_demo_key事件来自 what can you do? 面板的演示按钮。设计上把演示 key直接编码进事件名如run_demo_iframe_srcdoc而不是放在context里因为模型可能漏填或绑定失败的 context 值而事件名永远存在同时保留context.demo值作为向后兼容回退。book_restaurant/submit_booking事件从context中提取restaurantName、partySize、reservationTime、dietary、imageUrl等字段组装成描述性 query。执行器当前仅支持非流式响应use_streaming False源码注释说明待后端支持后再重新开启流式它会吞掉中间的 working update只把is_task_completeTrue的最终 parts 一次性回给客户端。UI 校验与自动重试这是示例中最值得借鉴的工程细节stream()中实现了一次自动重试max_retries 1共 2 次尝试的 UI 生成闭环流式收集模型输出跳过thoughtTrue的思考 part同时用DirectJsonStreamParser实时解析。收集完毕后用parse_response解析出 A2UI JSON交给复合目录的selected_catalog.validator.validate(...)做 jsonschema 校验。校验失败时把错误信息拼进新的 query 重新请求Your previous response was invalid. {error_message} You MUST generate a valid response that strictly follows the A2UI JSON SCHEMA...。重试仍失败则返回纯文本兜底错误。同时示例按session_id缓存流式解析器上限 1000 个超出时按 LRU 淘汰保证同一会话内流式解析状态连续。前置条件与本地运行根据 README.md本地运行需要Python 3.14 或更高版本pyproject.toml中声明requires-python 3.14uv包管理器LLM 访问权限与 API keyGemini API key或配置 Vertex AI运行时依赖见 pyproject.toml包括a2a-sdk[http-server]0.3.25,0.4提供 Starlette/SSE 服务端、google-adk1.28.1、google-genai1.27.0、a2ui-agent-sdk0.3.0schema 管理、目录加载与解析以及jsonschema、click、uvicorn、python-dotenv等。Cloud Run 场景额外需要google-cloud-aiplatform1.84。启动步骤# 1. 创建环境变量文件并填入真实 API key不要提交 .env 到版本库 cp .env.example .env # 2. 启动 Agent 服务器uv 会自动按 pyproject.toml 创建虚拟环境并解析依赖 uv run .uv run .会命中pyproject.toml并执行__main__.py的 CLI 入口服务默认监听http://localhost:10002。若未设置GEMINI_API_KEY且未配置GOOGLE_GENAI_USE_VERTEXAITRUE启动会报错退出MissingAPIKeyError。用 curl 验证 A2A 服务在另一个终端窗口中可以先用 curl 验证 Agent 已就绪# 验证 A2A AgentCard包含 A2UI v0.9 扩展能力声明与两个 skill curl http://localhost:10002/.well-known/agent-card.json然后发送一条标准 A2A JSON-RPC 消息与 Agent 对话curl http://localhost:10002 \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 1, method: message/send, params: { message: { role: user, parts: [{text: What can you do?}], messageId: 1 } } }如果回复是 A2UI UI JSON其中version字段为v0.9说明 UI 生成与校验链路正常。值得注意的是agent_executor.py 注释特别说明客户端到服务器的 A2UI v0.9 消息信封中version用的是线协议字符串v0.9这与 a2ui SDK 常量VERSION_0_9值为0.9有意不同读取客户端事件时以v0.9为准。部署到 Cloud Rundeploy.sh支持从源码一键部署./deploy.sh PROJECT_ID SERVICE_NAME [MODEL_NAME]其中MODEL_NAME可选gemini-2.5-pro或gemini-2.5-flash默认。脚本的关键部署参数如下见 deploy.sh区域固定为us-central1内存1Gi--source .从源码构建--no-allow-unauthenticated默认不允许匿名访问首次部署即注入环境变量GOOGLE_CLOUD_PROJECT、GOOGLE_CLOUD_LOCATION、GOOGLE_GENAI_USE_VERTEXAITRUE切换到 Vertex AI 认证路径、MODEL、GOOGLE_PYTHON_PACKAGE_MANAGERuv部署完成后读取生成的 Service URL再执行一次gcloud run services update写入AGENT_URL使 AgentCard 对外公布真实的公开地址。复合目录与示例模板的维护gemini_enterprise_composite_catalog.json是公开的 A2UI v0.9 Gemini Enterprise 复合目录的本地副本。从文件头部可见其catalogId与$id均指向官方托管地址顶层components直接聚合了MaterialText、Canvas、IFrameSrcdoc等组件定义。该目录的引入意味着单个 surface 内可以混用 Material 组件、基础目录组件与企业自定义组件这是本示例区别于只使用BasicCatalog的普通示例的核心能力。维护时需要注意保持目录与示例模板同步。Agent 加载示例时设置了validate_examplesTrue即每个示例模板都会经 schema 校验。因此若目录增删了组件必须同步更新 examples/0.9 下的 13 个模板否则启动加载或系统提示词生成会失败。示例模板即少样本来源。系统提示词会把这些模板整体注入include_examplesTrue它们是模型生成 UI 时的格式参考。以 canvas_side_panel.json 为例它展示了标准三段式消息createSurface声明surfaceId、catalogId、theme→updateComponents以Canvas为根cardTitle/cardDescription/cardIcon/autoOpen配置开屏卡片→updateDataModel绑定表格行数据iframe_srcdoc.json 则展示了IFrameSrcdoc的htmlContent字段——完整的自包含 HTML 文档以及通过parent.postMessage({type:a2ui_action, action:iframe_clicked, data:...})把 frame 内点击回传给 Agent 的机制。提示词中的关键 UI 生成规则prompt_builder.py 中的UI_DESCRIPTION沉淀了大量工程经验值得在自建 A2UI Agent 时直接借鉴必须使用目录内的组件名禁止发明Column、Text、List这类通用名一律用MaterialColumn、MaterialRow、MaterialCard、MaterialText等目录名。目录没有 List 组件动态列表要用MaterialColumn/MaterialGridList加模板子节点{componentId: template-id, path: /items}实现。根组件约定默认用MaterialCardidroot包裹顶层内容只有 what can you do? 卡片与 Canvas/嵌入 URL 演示才使用Canvas根。事件必须带人类可读的prompt任何event的context中都要加一句描述用户意图的prompt字符串客户端用它作为用户的聊天消息否则会退化为泛化的 User action triggered。每次响应必须生成新的唯一surfaceId不得复用示例里的字面量如default、dashboard应附加随机后缀如demo-forms-a7f3c9但同一次响应内的createSurface/updateComponents/updateDataModel必须使用同一个 id。run_demo_*只是事件名不是工具Agent 唯一可调用的工具是get_restaurants演示按钮的事件名必须精确匹配run_demo_gallery、run_demo_forms、run_demo_tabs、run_demo_table、run_demo_dialog、run_demo_canvas、run_demo_iframe_srcdoc、run_demo_iframe_url、run_demo_restaurants九个 key。餐厅演示的逻辑也定义在提示词中列表数据经updateDataModel写入/items≤5 家餐厅用single_column_list模板超过 5 家用two_column_list预订请求用booking_form模板提交预订用confirmation模板。配套的 tools.py 中的get_restaurants工具目前只在查询含 new york/ny 时返回 restaurant_data.json 中的前count条数据并把数据中的本地地址http://localhost:10002替换为会话状态里的base_url保证图片等资源在部署后仍可访问。安全注意事项原文档明确强调这也是所有 A2UI/A2A 应用必须遵守的原则本示例仅用于演示 A2UI 与 A2A 协议的机制。在生产环境中任何不受你直接控制的 Agent 都应视为潜在不可信实体——来自外部 Agent 的全部运营数据AgentCard、消息、工件、任务状态都应作为不可信输入处理任何收到的 UI 定义或数据流同样不可信。开发者有责任实现相应的安全措施例如输入清洗input sanitization、Content Security PolicyCSP、对可选嵌入内容如IFrameSrcdoc渲染的 HTML进行严格隔离以及安全的凭据管理以保护自身系统与用户安全。部署时--no-allow-unauthenticated与IFrameUrl的白名单机制正是这一原则的落地体现。小结通过这个示例你可以看到一条完整的 A2UI v0.9 Agent 落地路径以 ADK 的LlmAgentRunner为推理底座以A2uiSchemaManager 复合目录为 UI 生成约束以 A2A 协议 Starlette 为服务载体再辅以流式解析 jsonschema 校验 自动重试的生成闭环与run_demo_*事件分发机制即可构建一个既能按需渲染复杂 Material UI、又能被任意 A2A 客户端发现和调用的可部署 Agent。建议在动手改造前通读 agent.py 的校验重试逻辑与 prompt_builder.py 的规则描述这两处集中体现了让 LLM 稳定产出合法 UI JSON 的关键工程实践。【免费下载链接】a2ui项目地址: https://gitcode.com/GitHub_Trending/a2/a2ui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表