Agents CLI 扩展: 不改 用 ADK, 也能 走 同 一套 部署 和 评 测
命令面上有六条假定 ADK 运行时,另外大约十八条不绑框架。没有扩展时,为一个项目换框架等于二十四条命令都用不上。LangChain 模板对 google-adk 依赖为零,grep 退出码是 1;运行时加载器宣布正在套用 6 条扩展命令。

本文目录
用扩展把任意框架接进 Agents CLI 的评测和部署
Pier Paolo Ippolito,产品经理。Elia Secchi,解决方案专家。2026 年 10 月 21 日。
Agents CLI 扩展系统的端到端走通:一份 LangChain 实例,再加一条自定义的部署策略。
引言
Agents CLI 在 Google Cloud Next '26 上推出时,只坚持一件事:从想法到 Google Cloud 上的生产智能体,应该走同一套命令。用 Agent Development Kit(ADK,谷歌的智能体开发套件)的团队,这条路走得通。跑 agents-cli create,写智能体逻辑,大约三十分钟就能部署到 Cloud Run,可观测性和评测已经接上。
那之后,框架更杂了。除了 ADK,开发者还会在 LangChain、LangGraph、Deep Agents 这类新来者,或贴着某一业务域做的自研框架之间选。不同团队偏好不同。绿地原型上合适的选择,很少也是生产迁移上合适的选择。企业管理员还可能要在整条智能体开发生命周期(ADLC,从搭建、运行、评测到部署的那一套步骤)上,给所有开发团队加上治理:一次合规扫描、一道单点登录闸门、一跳模型风险管理。
团队能不能用上 Agents CLI 里已经做好的部署、评测和可观测性,却不必改用 ADK,也不必接受每条命令的默认行为?从 1.5.0 起,可以。Agents CLI 带了扩展系统。开发者可以覆盖或新增命令,不必分叉这个工具。1.8.0 带上第一方 LangChain 扩展:和框架绑在一起的命令换成 LangChain 对应物,生命周期的其余部分不动。
下面走两条路。第一条用第一方扩展,把一个 LangChain 智能体搭起来、跑起来、部署出去、评测一遍,看 LangChain 上的 ADLC。第二条自己写一个小扩展,用软件物料清单(SBOM,一份列出项目依赖的清单)扫描包住 deploy,演示企业平台团队怎样把自家策略套到每个项目上。两条路用的是同一套机制。
框架绑死的问题
今天多数智能体开发工具链有同一个限制:它们认定某一种框架。部署目标、CI/CD、评测用具、可观测性接线,都假设开发者已经用了那个框架。框架对得上,这条意见很强的路就好用。对不上,只剩三种差选择。
第一种是分叉 CLI,自己维护一份分叉,每次上游发布再同步。这笔维护税是永久的,上游的每一处改进都得手工合进分叉。第二种是用自定义脚本包住 CLI,另做一层命令,再去调底下的工具。问题是开发者和他们的编码助手会忘掉包装层,直接调底下的工具,绕过本来要加的那层。第三种是走开,从头做。这能吃掉好几个工程师月,而且很少做得像上游那样完整。
问题出现在两种场合。一种是企业客户采用 Agents CLI:受监管行业里,中央平台团队常常要求每次 deploy 都包一层合规检查,login 走公司单点登录,评测走模型风险管理流水线。这些要求今天要么分叉 CLI,要么再做一层包装。另一种是大部分时间用 ADK、但某一个项目必须跑非 ADK 框架的团队。在 Agents CLI 的命令面上,有六条命令假定 ADK 运行时:playground、run,以及四条 eval 子命令。另外大约十八条(scaffold、infra、deploy、publish、login 以及同类)不绑框架。没有扩展时,只为一个项目选非 ADK 框架,等于二十四条命令都用不上。
扩展系统用一种机制处理这两种场合。
Agents CLI 扩展是什么
一个 Agents CLI 扩展,是 Git 仓库里的一个目录,里面只有一个文件 agents-cli-extension.yaml。这个文件声明扩展覆盖哪些内置命令、新增哪些命令。官方文档里的说法是:
扩展用来把 agents-cli 接到它自己不带的工作流上:另一种智能体框架、一个组织的部署策略,或你自己的一条命令。不用分叉这个工具。
扩展有两种形状。命令覆盖替换 playground、deploy 或 eval generate 这类内置命令的行为。被覆盖的命令原样收到用户参数,所以用法仍和原生命令一致。新命令则把 CLI 目前没有的工作流暴露成 agents-cli <你的命令>。两种形状可以放在同一个扩展里。多数不算小的扩展会两种都用。
扩展通过 Git 仓库分发,不走专门的包注册表。设计借自 gemini-cli 的扩展模型。没有中央索引要发布,没有包格式要维护,也没有所有权名册要申请。任何 Git 仓库里的任何目录都可以当扩展。版本、钉死和分发由 Git 做。对企业平台团队,这就是建一个内部的 platform-extensions 仓库,让开发者指向它,不用再协调外部注册表。
引用形式
按扩展放在哪里、开发者想怎么用,引用方式有几种:
# First-party shorthand, which resolves to the google/agents-cli repository
agents-cli extension add <name>
# Any organization or repository on GitHub, including self-hosted Git servers
agents-cli extension add acme/platform-extensions
agents-cli extension add acme/platform-extensions#soc2-deploy
# A local path, which is typically used during extension development
agents-cli extension add local@../my-extension#<name> 让一个 Git 仓库放下多个扩展,片段标识选出其中一个。企业平台仓库常常把一组相关扩展(一个管 deploy,一个管 login,一个管 scaffold create)放在同一个仓库里,所有权和发布节奏共用。
作用域
扩展装在两个作用域。默认是项目作用域:扩展和它的锁文件条目提交进项目自己的仓库。队友和 CI 检出后就带上。另一种是用户作用域,用 --global 打开。扩展存在用户主目录的配置里,对本机每个项目生效。扩展必须在任何项目出现之前就可用时,用用户作用域。例如一个框架引导扩展,它要改的是 agents-cli create 本身。
两个作用域定义了同一条命令时,项目作用域赢。agents-cli info 会标出每条生效命令的来源。作用域是故意写明的:扩展系统不会悄悄合并或覆盖扩展。冲突会在安装时,或在 extension list 的输出里,摆到开发者面前。
锁文件和生命周期
扩展系统跟 uv 或 npm 一样:安装时把 Git 引用解析成确切的提交 SHA,把这个 SHA 记进锁文件(lockfile,钉住已审过的那一版代码的文件),每次全新检出都按锁文件还原那一份审过的代码。agents-cli install 按钉住的 SHA 恢复已纳入的工作副本,不把钉往前推。这样 CI 和本地跑的是逐位相同的代码。要把钉推进到所跟踪引用上的最新提交,开发者跑 agents-cli extension update。它会重新解析引用,并再次询问是否信任第三方。
扩展系统在 v1.8.0 标成实验性。清单模式和命令面在定稿前仍可能以不兼容的方式变化,所以依赖它的团队应钉住 Agents CLI 版本。
用 Agents CLI 跑 LangChain
LangChain 第一方扩展是一个项目模板:一条命令搭出一个已经接进 Agents CLI 生命周期的 LangChain 智能体。得到的项目对 google-adk 的依赖是零,部署到 Cloud Run 走的代码路径和 ADK 项目相同。模板自己的描述是:
通过 agents-cli 的生命周期运行 LangChain 智能体、LangGraph 图和 Deep Agents。
在现代 LangChain(1.0 及以后)里,状态管理层由 LangGraph 提供,所以这三种框架共用同一种图表示。同一份模板用同一套代码服务这三个社区。
准备
开始之前需要:
Python 3.11 or later
uv package manager
Google Cloud SDK (gcloud)还要一个已开通计费的 Google Cloud 项目。还没有的话,可以在 https://console.cloud.google.com/ 建。
开发机上还没有 Agents CLI 时,一条命令装上:
uvx google-agents-cli setup然后向 Google Cloud 认证,并打开智能体运行时要依赖的 API:
gcloud auth application-default login
gcloud config set project YOUR_PROJECT_ID
gcloud services enable aiplatform.googleapis.com run.googleapis.com artifactregistry.googleapis.com步骤 1:搭项目
搭脚手架和安装扩展是同一次操作。不必先装扩展再搭项目。直接让 agents-cli create 指向扩展的模板,并钉到一个发布标签:
agents-cli create my-agent \
--agent google/agents-cli/extensions/langchain/template@v1.8.0 \
-d cloud_run
cd my-agent && agents-cli install输出确认脚手架成功:
Agents CLI v1.8.0
Fetching remote template: google/agents-cli/extensions/langchain/template@v1.8.0
> Verifying GCP credentials...
> ✓ Connected to project: your-project
✅ Success! Your agent project is ready.搭出来的项目根上已经有 agents-cli-extension.yaml。下次任何命令被调用时,它会在项目作用域自动加载。没有东西要手工安装,因为项目本身就是这个扩展的安装。搭 LangChain 项目的人不必知道扩展系统存在。这条命令看起来就像一次原生的 agents-cli create,只是产出的是 LangChain 项目而不是 ADK 项目。
步骤 2:看生成的结构
脚手架产出的是:
my-agent/
├── agents-cli-extension.yaml # auto-loaded project-scope overrides
├── agents-cli-manifest.yaml # project configuration (deployment target, etc.)
├── GEMINI.md # project's coding-agent guide
├── langgraph.json # LangGraph dev-server configuration
├── pyproject.toml # langchain, langgraph, langchain-google-genai
├── Dockerfile # identical CMD to any ADK project
├── app/
│ ├── agent.py # exports root_agent: CompiledStateGraph
│ ├── fast_api_app.py # exposes `app: FastAPI` on A2A
│ └── app_utils/
│ ├── a2a.py # LangGraphAgentExecutor and A2A routes
│ └── telemetry.py # Cloud Trace and GenAI logging
├── scripts/
│ ├── run.py # drop-in replacement for `agents-cli run`
│ ├── eval_generate.py # drop-in replacement for `agents-cli eval generate`
│ └── publish.py # Agent-Runtime-aware refusal wrapper
├── tests/
│ └── eval/datasets/basic-dataset.json
├── deployment/ # Terraform infrastructure modules
├── uv.lock
└── .agents/skills/agents-cli-langchain/ # the project's own coding-agent skill结构和 ADK 项目像:同样的 app/、同样的 tests/、deployment/ 下同样的 Terraform、根上同样的清单。两处不同是顶上的 agents-cli-extension.yaml(带着 LangChain 覆盖),以及 langgraph.json(配置本地 playground 用的 LangGraph 开发服务器)。
智能体定义在 app/agent.py:
"""LangChain agent: a Gemini ReAct agent with a sample tool."""
import os
from dotenv import load_dotenv
from langchain.agents import create_agent
from langchain_google_genai import ChatGoogleGenerativeAI
from langgraph.graph.state import CompiledStateGraph
load_dotenv()
if not (os.environ.get("GOOGLE_API_KEY") or os.environ.get("GEMINI_API_KEY")):
import google.auth
_, project_id = google.auth.default()
os.environ["GOOGLE_CLOUD_PROJECT"] = project_id
os.environ["GOOGLE_CLOUD_LOCATION"] = "global"
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True"
LLM = "gemini-3.8-flash"
llm = ChatGoogleGenerativeAI(model=LLM, temperature=0)
def get_weather(query: str) -> str:
"""Simulates a web search. Use it get information on weather."""
if "sf" in query.lower() or "san francisco" in query.lower():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
root_agent: CompiledStateGraph = create_agent(
model=llm, tools=[get_weather], system_prompt="You are a helpful assistant"
)智能体用 langchain.agents.create_agent 创建,编译成 LangGraph 的 CompiledStateGraph。root_agent 上的类型标注把这一点写明。现代 LangChain 用 LangGraph 做状态管理层,所以模板才能用同一条生命周期同时支持 LangChain 智能体、LangGraph 图和 Deep Agents:三者都编译成同一种底层图。
脚手架项目不依赖 ADK。可以直接核:
$ grep -r "google.adk\|google-adk" pyproject.toml app/
$ echo "exit: $?"
exit: 1grep 没有匹配,退出码 1 确认没有 ADK 引用。pyproject.toml 里确实出现的 google-\* 包,是任何 Google Cloud Python 项目都会带的:google-cloud-aiplatform[evaluation]、google-cloud-logging、langchain-google-genai,以及 OpenTelemetry 的 Google Cloud 导出器。
接着用一条提示跑它:
agents-cli run "what's the weather in San Francisco?"命令产出:
WARNING:root:agents-cli: applying 6 extension command(s): eval.dataset [langchain/project], eval.generate [langchain/project], eval.optimize [langchain/project], playground [langchain/project], publish.gemini-enterprise [langchain/project], run [langchain/project]
The weather in San Francisco is currently 60°F and foggy.背后,Vertex AI 上的 Gemini-3.8-flash 在进程内调用了编译好的图,调用了 get_weather("San Francisco"),收到模拟的有雾回答,再把最后一句推回给用户。警告行列出哪些扩展命令在生效,每条被覆盖的命令一项。这行警告是故意的:覆盖会悄悄改变原生行为,所以加载器总是宣布哪些命令被谁截住。
本地查看时,agents-cli playground 在 8080 端口拉起 LangGraph Studio,替换本来会出现的 ADK 网页界面。
要确认扩展改了哪些命令,可以看帮助输出:
$ agents-cli --help | grep -E "playground|run "
playground Start the local LangGraph dev server. [↑ langchain]
run Run the compiled agent graph with a single prompt. [↑ langchain][↑ langchain] 后缀是扩展系统的信号:这条命令被覆盖了,以及负责的扩展叫什么。看终端的人和编码助手都能一眼看出,这个项目里哪些命令行为不同。
要一份完整清单,agents-cli info 列出每个生效扩展,以及它实际执行的命令向量:
Extensions (experimental):
eval.dataset (override, project) <- langchain: uv run python scripts/unsupported.py eval dataset
eval.generate (override, project) <- langchain: uv run python scripts/eval_generate.py
eval.optimize (override, project) <- langchain: uv run python scripts/unsupported.py eval optimize
playground (override, project) <- langchain: uv run langgraph dev --no-browser --port 8080
publish.gemini-enterprise (override, project) <- langchain: uv run --with pyyaml python scripts/publish.py
run (override, project) <- langchain: uv run python scripts/run.py一共六处覆盖,落在三类里:四处和框架绑在一起的替换(playground、run、eval.generate、publish.gemini-enterprise),两处明确拒绝(eval.dataset 和 eval.optimize 需要一个 ADK 智能体对象才能内省,所以 LangChain 项目干净地拒绝它们,而不是产出无效结果)。publish.gemini-enterprise 的覆盖还有一层:只在 Agent Runtime 这个部署目标上拒绝,在 Cloud Run 和 GKE 上则交给原生命令。
步骤 4:部署到 Cloud Run
deploy 没有被 LangChain 扩展覆盖。把 LangChain 项目部署到 Cloud Run,走的代码路径和部署 ADK 项目完全一样:
agents-cli deploy底下的机制是对项目的 Dockerfile 执行 gcloud run deploy --source .。Dockerfile 里有:
CMD ["uv", "run", "uvicorn", "app.fast_api_app:app", "--host", "0.0.0.0", "--port", "8080"]这条 CMD 和 ADK 项目 Dockerfile 里的那条相同。LangChain 模板用 FastAPI 提供 A2A(Agent-to-Agent,智能体对智能体)协议流量,应用暴露在 app.fast_api_app:app。部署路径不必知道驱动智能体的是哪种框架,因为 uvicorn 和 gcloud run deploy 对着的是 FastAPI 这份契约。
infra、scaffold enhance、scaffold upgrade、install、info、setup、lint、login 也一样。在 LangChain 项目里它们都没变。这些命令上一年的 Agents CLI 工作,LangChain 项目免费得到,ADK 和 LangChain 两条代码路径之间没有要维护的分叉。
步骤 5:跑评测
LangChain 项目里的评测,沿用 ADK 走通里熟悉的模式,只有一处不同:eval generate 被覆盖,用来驱动 LangChain 图;后面的评测步骤仍用原生命令:
agents-cli eval generate --dataset tests/eval/datasets/basic-dataset.json \
-o tests/eval/output/
agents-cli eval grade --traces tests/eval/output/basic-dataset.json \
--config tests/eval/eval_config.yaml
agents-cli eval compare tests/eval/output/run_1.json tests/eval/output/run_2.json被覆盖的 eval generate 产出标准的 EvaluationDataset 格式。原生的 eval grade、eval compare、eval analyze 知道怎么消费它。评测服务和评分量规不绑框架。
开发者若调用一条被拒绝的 eval 子命令,扩展给出清楚说明,而不是静默失败:
$ agents-cli eval dataset synthesize
agents-cli eval dataset is not supported by the langchain extension:
it runs the agent through ADK's user simulator, which needs google-adk
in this project's venv.清楚的拒绝比静默失败有用。编码助手在驱动终端时,尤其如此,否则它会在放弃之前把一条坏命令重试很多次。
自己写一个扩展
LangChain 模板是扩展系统的第一方演示。同一套机制对任何想改 Agents CLI 命令面的团队开放。企业平台团队可以在内部编写并分发扩展,把策略写成代码,通过他们已经在用的 Git 基础设施发出去。团队里每个开发者随后默认走同一套检查。
为了说明这个模式,这里做一个叫 sbom-deploy 的小扩展。它用 SBOM 扫描包住 deploy,发现任何严重漏洞就拒绝部署。清单模式的权威说明在扩展编写文档里。
步骤 1:写扩展清单
先为扩展建一个目录,在根上加清单文件:
# agents-cli-extension.yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/google/agents-cli/main/schemas/agents-cli-extension-v1alpha1.schema.json
schema: agents-cli-extension/v1alpha1
name: sbom-deploy
description: Scan the project SBOM, then run the native agents-cli deploy.
requires:
agents_cli: ">=1.5,<2"
on_incompatible: warn
commands:
override:
deploy:
run: ["bash", "scripts/sbom_then_deploy.sh"]
description: SBOM scan via syft+grype, then the built-in deploy.
add:
sbom-report:
run: ["bash", "scripts/sbom_report.sh"]
description: Produce an SBOM for the current project (no deploy).清单有五个顶层键,多一个都不允许。模式用严格校验,所以 reqires: 这种拼写错误会在安装时失败,并给出“你是不是想写”的建议,而不是悄悄丢掉这次覆盖。
schema 标明清单模式版本。name 是单个路径分量(斜杠和上级目录引用会被拒绝),并成为 extensions/ 下存放纳入副本的目录名。requires 声明扩展支持哪些 Agents CLI 版本,以及版本不匹配时的策略(warn 或 error)。commands 才是真正的覆盖和新增。
编写文档里还有两条特别值得知道的约束。可以覆盖一条具体子命令(例如 eval.generate),但不能覆盖一整组顶层命令(例如把 eval 整个盖掉)。run: 是命令向量,不是 shell 命令,所以把多条命令串起来必须写在包装脚本里,不能写在清单里。
步骤 2:写包装脚本
因为 run: 是不经 shell 执行的命令向量,要把多个操作串起来,就得写一个按顺序执行它们的包装脚本:
#!/usr/bin/env bash
# scripts/sbom_then_deploy.sh
set -euo pipefail
cd "$(dirname "$0")/.."
echo "[sbom-deploy] generating SBOM..."
syft dir:. -o cyclonedx-json > /tmp/sbom.cdx.json
echo "[sbom-deploy] scanning for criticals..."
grype sbom:/tmp/sbom.cdx.json --fail-on critical
# AGENTS_CLI_DISABLE_OVERRIDES=1 is already set by the loader,
# so this call hits the built-in deploy. No infinite recursion.
echo "[sbom-deploy] SBOM clean; running native deploy..."
exec agents-cli deploy "$@"让这件事成立的是 AGENTS_CLI_DISABLE_OVERRIDES=1。Agents CLI 会在任何经由覆盖调用的脚本环境里设置它。包装脚本递归调用 agents-cli deploy 时,调用落到原生 deploy,不会再绕回自己的覆盖。没有特殊语法,也没有递归。
可以直接核。演示里把 SBOM 扫描换成几句 echo,用来确认环境和参数:
$ agents-cli deploy --project foo
[sbom-deploy] (demo) would scan SBOM here...
[sbom-deploy] AGENTS_CLI_DISABLE_OVERRIDES=1
[sbom-deploy] would then shell to: agents-cli deploy --project foo--project foo 原样传进包装脚本。环境变量在脚本开始执行前就由加载器设好。包装脚本具备交给原生命令所需的一切。
步骤 3:安装并核对
清单和包装脚本就位后可以安装。开发时指向本地路径:
agents-cli extension add local@../my-sbom-extension扩展推到 Git 仓库之后,同一语法配远程引用也能用:
agents-cli extension add acme/platform-extensions#sbom-deploy --ref v1.0.0安装之后,列出已装扩展并看帮助,确认扩展在生效:
$ agents-cli extension list
Extensions:
langchain project (commands: eval.dataset, eval.generate, eval.optimize, playground, publish.gemini-enterprise, run)
sbom-deploy project (commands: deploy, sbom-report) requires: >=1.5,<2
$ agents-cli --help | grep -A1 -E "deploy|sbom-report"
deploy SBOM scan via syft+grype, then the built-in deploy. [↑
sbom-deploy]
sbom-report Produce an SBOM for the current project (no deploy). [↑
sbom-deploy]
$ agents-cli deploy --help
Usage: agents-cli deploy [OPTIONS] [EXTRA_ARGS]...
Overrides `deploy` via extension 'sbom-deploy' (project scope).
SBOM scan via syft+grype, then the built-in deploy.
Runs: bash scripts/sbom_then_deploy.sh
Argv after the command name passes through to the script verbatim.
To bypass extension overrides and run the built-in:
AGENTS_CLI_DISABLE_OVERRIDES=1 agents-cli deploy每条被覆盖命令旁边的 [↑ sbom-deploy],是扩展系统给使用者的信号:行为已被修改。
锁文件纪律
背后,extension add 把 Git 引用解析成确切的提交 SHA,并把这次解析记在项目根的锁文件里:
# agents-cli-extensions.yaml (lockfile; commit this to version control)
extensions:
- name: sbom-deploy
source: acme/platform-extensions#sbom-deploy
ref: v1.0.0
sha: a1b2c3d4...
scope: project锁文件和 extensions/ 下纳入的工作副本都应该提交。全新检出时,agents-cli install 按钉住的 SHA 重新物化那份审过的代码,方式如同 uv sync 或 npm install 恢复钉住的依赖。install 从不把钉往前推,所以同一个提交的两次部署之间,扩展不能自己改变行为。
要把钉推进到所跟踪引用(分支、标签或 SHA)上的最新提交,开发者跑 agents-cli extension update sbom-deploy。要换到另一个标签或分支,用新的 --ref 再跑一次 agents-cli extension add。
接下来
Agents CLI 一开始是一条把 ADK 智能体发到 Google Cloud 的、意见很强的路。有了扩展系统,这些意见现在可以由你覆盖、替换或增补。
开始
两条命令安装 Agents CLI,并搭一个 LangChain 智能体:
uvx google-agents-cli setup
agents-cli create my-agent --agent google/agents-cli/extensions/langchain/template@v1.8.0 -d cloud_run文档在这几处:扩展总览 https://google.github.io/agents-cli/guide/extensions/ ,使用扩展 https://google.github.io/agents-cli/guide/extensions/using/ ,编写扩展 https://google.github.io/agents-cli/guide/extensions/authoring/ ,第一方扩展 https://google.github.io/agents-cli/guide/extensions/first-party/ 。Agents CLI 的完整源代码,包括第一方模板,在 https://github.com/google/agents-cli 。
出处:Pier Paolo Ippolito,Elia Secchi,Powering the Agent Development Lifecycle with any framework, from ADK to LangChain and beyond,2026-10-21,https://developers.googleblog.com/powering-the-agent-development-lifecycle-with-any-framework-from-adk-to-langchain-and-beyond/ ,CC BY 4.0。
觉得有用,转给同事
微信扫码
用微信扫一扫,在手机上打开后即可转发。