借助任意框架推动智能体开发生命周期,从 ADK 到 LangChain 及更多框架
原题Powering the Agent Development Lifecycle with any framework, from ADK to LangChain and beyond
推荐理由使用不同智能体框架的团队,可参考扩展机制如何复用部署、评测和可观测性,并用自定义策略接入组织治理。
读前速览
借助全新的扩展系统,Agents CLI 现在支持 LangChain 和 LangGraph 等非 ADK 框架的完整开发生命周期,并允许覆盖命令和自定义策略。
框架灵活性
扩展系统可以通过覆盖特定命令,让 Agents CLI 支持多种智能体框架,例如 LangChain、LangGraph 和 Deep Agents,而不再局限于 ADK 这一种框架。
自定义策略执行
企业团队可以创建自定义扩展,为「deploy」等命令添加合规检查,例如 SBOM 扫描或 SSO 验证关卡,从而确保所有项目都遵循组织策略。
无缝集成
LangChain 扩展可直接替代 ADK 专用命令,因此无论使用哪种底层框架,开发者都能使用相同的 CLI 界面和部署流水线。
完整摘要
本文介绍了 Agents CLI 扩展系统。该系统让开发者能够将 CLI 用于 ADK 以外的框架,例如 LangChain。文章逐步讲解如何搭建 LangChain 项目脚手架、检查生成的项目结构、在本地运行智能体,以及将其部署到 Cloud Run。该系统还支持创建自定义扩展,以便在整个开发生命周期中执行特定策略,例如 SBOM 扫描。
目录 · 19 节
新 Agents CLI 扩展系统端到端演练:附 LangChain 实例和自定义部署策略End to end walkthrough of the new Agents CLI Extension System, with a worked LangChain example and a custom deploy policy
引言Introduction
当我们在 Google Cloud Next '26 上推出 Agents CLI 时,我们基于一个鲜明的主张来构建它:在 Google Cloud 上,从想法到投入生产的智能体,应该只需通过一个统一的命令界面即可完成。对于使用 Agent Development Kit (ADK) 构建应用的团队来说,这条明确的路径行之有效。你只需运行 agents-cli create,编写智能体逻辑,然后部署到 Cloud Run,同时配置好可观测性和评估,大约三十分钟就能完成。When we launched Agents CLI at Google Cloud Next '26, we built it around one strong opinion: going from an idea to a production agent on Google Cloud should take a single unified command surface. For teams building with Agent Development Kit (ADK), that opinionated path has worked. You run agents-cli create, write the agent logic, and ship to Cloud Run with observability and evals wired up, in about thirty minutes.
此后几个月,智能体框架生态变得更加多元。如今,除了 ADK,开发者还可以选择 LangChain 和 LangGraph、Deep Agents 这类专门的新兴框架,或是针对特定业务领域量身打造的内部框架。不同团队偏好不同的框架,而适合从零开始构建原型的选择,往往并不适合用于生产环境迁移。企业管理员可能还希望在所有开发团队的整个 ADLC 中强制执行治理政策,例如合规性扫描、SSO 关卡,以及模型风险管理环节。The agent framework landscape has grown more diverse in the months since. In addition to ADK, developers today pick between LangChain and LangGraph, specialized newcomers like Deep Agents, or in-house frameworks tailored to a specific business domain. Different teams prefer different frameworks, and the right choice for a greenfield prototype is rarely the right choice for a production migration. Enterprise admins may also have governance policies they want to enforce across the ADLC for all of their development teams, such as: a compliance scan, an SSO gate, a Model Risk Management hop.
团队能否受益于 Agents CLI 中的部署、评估和可观测性功能,而不必被迫采用 ADK,或接受每条命令的默认行为?从 1.5.0 版本开始,答案是肯定的。Agents CLI 现已内置扩展系统,开发者无需派生该工具,就能覆盖或添加命令。1.8.0 版本推出了官方 LangChain 扩展,它会用对应的 LangChain 命令替换与框架绑定的命令,同时保持其余生命周期环节不变。Can a team benefit from the deployment, evaluation, and observability work in Agents CLI without being forced to adopt ADK, or without being forced to accept the default behavior of every command? Starting with version 1.5.0, the answer is yes. Agents CLI now ships with an Extension System that lets developers override or add commands without forking the tool. Version 1.8.0 ships the first-party LangChain extension, which replaces the framework-coupled commands with their LangChain equivalents and leaves the rest of the lifecycle untouched.
下面我们将介绍两段实践流程。首先,为了向你展示如何将 ADLC 与 LangChain agents 结合使用,我们会演示如何通过官方扩展,按照 Agents CLI 的生命周期流程对 LangChain agent 进行脚手架搭建、运行、部署和评估。接着,我们会构建一个小型扩展,为 deploy 命令添加软件物料清单(SBOM)扫描,从而展示企业平台团队如何运用这一模式,在每个项目中强制执行自己的策略。这两段流程使用的是同一种机制。We will walk through two journeys below. First, to show you the ADLC with LangChain agents, we'll show you how you can scaffold, run, deploy, and evaluate a LangChain agent through the Agents CLI lifecycle using the first-party extension. Then we build our own small extension that wraps the deploy command with a Software Bill of Materials (SBOM) scan, demonstrating the pattern enterprise platform teams can use to enforce their own policies across every project. Both journeys use the same mechanism.
框架锁定问题The Framework Lock-in Problem
如今大多数智能体开发工具链都有一个共同的局限:它们都围绕某个特定框架进行了定制,其周边能力(部署目标、CI/CD 流水线、评估工具、可观测性集成)也都默认开发者采用了该框架。如果你的框架符合工具的预设,那么这条定制化路径就行得通;如果不符合,你就只剩下三个糟糕的选择。Most agent development toolchains available today share a limitation: they are opinionated about one specific framework, and the surrounding capabilities (deployment targets, CI/CD pipelines, evaluation harnesses, observability wiring) assume the developer has adopted that framework. When your framework matches the tool's assumption, the opinionated path works. When it does not, you're left with three bad options.
第一种做法是分叉 CLI,维护一个与上游不同步的副本,并在上游每次发布时重新同步。这会带来永久的维护成本,而且上游的每项改进都必须手动合并到分叉版本中。第二种做法是用自定义脚本封装 CLI,构建一套平行的命令接口来调用底层工具。问题在于,开发者(以及他们的编程助手)会忘记这个封装,直接调用底层工具,从而绕过预期的抽象层。第三种做法是放弃现有方案,从头开始构建所有东西,这可能耗费团队原本没有计划投入的数月工程时间,而且最终产出的工具很少能像上游项目那样精良。The first is to fork the CLI, maintaining a divergent copy and re-syncing it on every upstream release. You pay a permanent maintenance tax, and every upstream improvement has to be hand-merged into the fork. The second is to wrap the CLI behind custom scripts, building a parallel command surface that invokes the underlying tool. The problem is that developers (and their coding assistants) forget about the wrapper and call the underlying tool directly, bypassing the intended abstraction. The third is to walk away and build everything from scratch, which can consume several engineer-months of work that the team had not planned for, and which rarely produces tooling as polished as the upstream project.
这个问题会出现在两种场景中。一种是企业客户采用 Agents CLI:在受监管行业,中央平台团队往往要求每次调用 deploy 时都必须经过合规性检查,登录必须通过企业单点登录,或者评估必须纳入模型风险管理(Model Risk Management)流程。目前,要实现这些要求,客户只能分叉 CLI 或构建一层封装。另一种是大多数时候使用 ADK、但需要在某个特定项目中运行非 ADK 框架的团队。在 Agents CLI 的命令体系中,有六条命令依赖 ADK 运行时:playground、run 和四个 eval 子命令。另外约十八条命令(scaffold、infra、deploy、publish、login 等)与框架无关。没有扩展机制时,只要在单个项目中选择非 ADK 框架,就意味着无法使用全部二十四条命令。The problem shows up in two scenarios. One is enterprise customers adopting Agents CLI: in regulated industries, a central platform team often requires that every deploy invocation be wrapped with a compliance check, that login route through corporate single sign-on, or that evaluations flow through a Model Risk Management pipeline. Each of these requirements, implemented today, means either forking the CLI or building a wrapper layer. The other is teams that use ADK most of the time but need to run a non-ADK framework on a specific project. Within the Agents CLI command surface, six commands assume the ADK runtime: playground, run, and four eval subcommands. The other eighteen or so (scaffold, infra, deploy, publish, login, and friends) are framework-agnostic. Without extensions, choosing a non-ADK framework for a single project meant losing access to all twenty-four.
扩展系统通过一种机制同时处理这两者。The Extension System handles both with one mechanism.
什么是 Agents CLI 扩展?What are Agents CLI Extensions?
Agents CLI 扩展是 Git 仓库中的一个目录,其中包含一个名为 agents-cli-extension.yaml 的文件。该文件声明此扩展会覆盖哪些内置命令,以及会新增哪些命令。以下内容摘自官方文档:An Agents CLI extension is a directory in a Git repository that contains a single file called agents-cli-extension.yaml. The file declares which built-in commands the extension overrides and which new commands it adds. From the official documentation:
扩展让你无需分叉工具,就能让 agents-cli 适配它未内置支持的工作流——例如不同的智能体框架、组织的部署策略,或你自定义的命令。Extensions are how you adapt agents-cli to a workflow it doesn't ship with — a different agent framework, an org's deploy policy, or a command of your own — without forking the tool.
扩展有两种形式,详见“使用扩展”页面。命令覆盖会替换内置命令的行为,例如 playground、deploy 或 eval generate。被覆盖的命令会原样接收用户的参数,因此用户体验与原生命令保持一致。新命令则会以 agents-cli <your-command> 的形式,提供 CLI 当前尚不支持的工作流。这两种形式可以共存于同一个扩展中,而且大多数较复杂的扩展都会结合使用两者。Extensions take two shapes, described in the Using Extensions page. A command override replaces the behavior of a built-in like playground, deploy, or eval generate. The overridden command receives the user's arguments verbatim, so the user experience stays consistent with the native command. A new command exposes a workflow the CLI does not currently provide as agents-cli <your-command>. Both shapes can coexist in the same extension, and most non-trivial extensions use a combination of the two.
扩展通过 Git 仓库分发,而不是通过专用的包注册表分发。这一设计借鉴了 gemini-cli 项目采用的扩展模型。无需发布到中央索引,无需维护包格式,也无需申请加入所有者名录。任何 Git 仓库中的任何目录都可以作为扩展,而版本管理、锁定和分发则由 Git 负责。对企业平台团队而言,这意味着只需创建一个内部的 platform-extensions 仓库,并引导开发者使用它,无需与任何外部注册表协调。Extensions are distributed through Git repositories rather than through a dedicated package registry. The design draws from the extension model used by the gemini-cli project. There is no central index to publish to, no package format to maintain, and no ownership roster to apply for. Any directory inside any Git repository can serve as an extension, and Git handles the versioning, pinning, and distribution. For enterprise platform teams, this means creating an internal platform-extensions repository and pointing their developers at it, with no external registry to coordinate with.
参考表单Reference Forms
扩展可以通过多种方式引用,具体取决于它所在的位置以及开发者希望如何使用它:An extension can be referenced in several ways, depending on where it lives and how the developer wants to use it:
# 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 仓库容纳多个扩展,并通过片段标识符选择其中一个。企业平台仓库通常会将一组相关扩展(一个用于部署,一个用于登录,一个用于创建脚手架)打包在同一个仓库中,由同一团队负责,并采用统一的发布节奏。The #<name> syntax lets a single Git repository hold multiple extensions, with the fragment identifier selecting one of them. Enterprise platform repositories often bundle together a family of related extensions (one for deploy, one for login, one for scaffold create) under a single repo with shared ownership and release cadence.
作用域Scopes
扩展可以安装在两种作用范围内。默认是项目作用范围,扩展及其锁文件条目会提交到项目自己的代码仓库中。队友和 CI 流水线在检出项目时也会获取它。另一种是用户作用范围,通过 --global 标志启用;扩展会存储在用户的主目录配置目录中,并应用于这台机器上的所有项目。当扩展需要在任何项目尚不存在时就可用时,就应选择用户作用范围,例如用于配置 agents-cli create 命令本身的框架引导扩展。Extensions install at two scopes. The default is the project scope, where the extension and its lockfile entry are committed to the project's own repository. Teammates and CI pipelines pick it up on checkout. The alternative is the user scope, enabled via the --global flag, where the extension is stored in the user's home configuration directory and applies to every project on the machine. The user scope is the one you reach for when an extension needs to be available before any project exists, such as a framework bootstrap extension that configures agents-cli create itself.
当两个作用域定义了同一条命令时,以项目作用域为准,而 `agents-cli info` 会显示每条生效命令的来源。作用域的设计刻意保持明确:扩展系统不会静默合并或覆盖扩展,任何冲突都会在安装时或扩展列表输出中提示开发者。When both scopes define the same command, the project scope wins, and agents-cli info surfaces the source of each active command. Scoping is deliberately explicit: the Extension System will not silently merge or override extensions, and any conflict surfaces to the developer at install time or in the extension list output.
锁文件与生命周期Lockfile and Lifecycle
扩展系统遵循 uv 或 npm 等包管理器的原则:在安装时将 Git 引用解析为确切的提交 SHA,将解析出的 SHA 记录到锁文件中,并在每次全新检出时使用锁文件重新生成完全相同、经过审核的代码。agents-cli install 命令会根据固定的 SHA 恢复 vendored 工作副本,但不会推进固定版本,从而确保 CI 和本地开发运行的代码逐位完全一致。若要将固定版本推进到所跟踪引用的最新提交,开发者需运行 agents-cli extension update;该命令会重新解析引用,并再次提示用户确认对第三方的信任。完整生命周期请参阅 Using Extensions → Lifecycle 部分。The Extension System follows the discipline of package managers like uv or npm: it resolves a Git reference to an exact commit SHA at install time, records the resolved SHA in a lockfile, and uses the lockfile to re-materialize the exact reviewed code on every fresh checkout. The agents-cli install command restores the vendored working copy from the pinned SHA without advancing the pin, which guarantees that CI and local development run bit-for-bit identical code. To advance a pin to the latest commit on the tracked reference, the developer runs agents-cli extension update, which re-resolves the reference and re-prompts for third-party trust. The complete lifecycle is in the Using Extensions → Lifecycle section.
扩展系统在 v1.8.0 中被标记为实验性功能。在系统最终定型之前,清单架构和命令接口仍可能发生不兼容变更,因此依赖该系统的团队应固定 Agents CLI 的版本。The Extension System is marked experimental in v1.8.0. The manifest schema and the command surface may still change in breaking ways before the system is finalized, so teams depending on it should pin their Agents CLI version.
Running LangChain Through Agents CLI
LangChain 官方扩展是一个项目模板:只需一条命令,就能搭建一个可运行的 LangChain 智能体,并将其接入 Agents CLI 的生命周期。生成的项目不依赖 google-adk,并通过与 ADK 项目相同的代码路径部署到 Cloud Run。该模板自身的描述如下:The LangChain first-party extension is a project template: one command scaffolds a working LangChain agent wired into the Agents CLI lifecycle. The resulting project has zero google-adk dependency and deploys to Cloud Run through the same code path an ADK project uses. The template's own description reads:
Run LangChain agents, LangGraph graphs, and Deep Agents through the agents-cli lifecycle.
在现代版 LangChain(1.0 及更高版本)中,状态管理层由 LangGraph 提供,因此这三个框架共享同一种图表示。该模板使用同一套代码服务这三个社区。In modern LangChain (version 1.0 and later), the state management layer is provided by LangGraph, so the three frameworks share a common graph representation. The template serves all three communities with the same code.
先决条件Prerequisites
在开始之前,我们需要:Before we begin, we need:
Python 3.11 or later
uv package manager
Google Cloud SDK (gcloud)
还需要一个已启用结算功能的 Google Cloud 项目。如果你还没有,可以前往 console.cloud.google.com 创建。A Google Cloud project with billing enabled is also required. If you do not have one yet, it can be created at console.cloud.google.com.
如果开发机器上尚未安装 Agents CLI,可以通过一条命令完成安装:If Agents CLI is not already installed on the development machine, it can be installed in a single command:
uvx google-agents-cli setup
最后,我们通过 Google Cloud 进行身份验证,并启用该代理在运行时所依赖的 API:Finally, we authenticate with Google Cloud and enable the APIs the agent will depend on at runtime:
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:搭建项目骨架Step 1: Scaffolding the Project
搭建脚手架和安装扩展是同一项操作。我们不再先安装扩展再搭建项目,而是让 agents-cli create 直接使用扩展的模板,并固定到特定的发布标签:Scaffolding and extension installation are the same operation. Rather than installing an extension first and then scaffolding a project, we point agents-cli create directly at the extension's template, pinned to a specific release tag:
agents-cli create my-agent \
--agent google/agents-cli/extensions/langchain/template@v1.8.0 \
-d cloud_run
cd my-agent && agents-cli install
输出确认脚手架搭建成功:The output confirms the scaffold succeeded:
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 项目的开发者不需要知道 Extension System 的存在。这个命令看起来、用起来都像原生的 agents-cli create 调用,只不过它生成的是 LangChain 项目,而不是 ADK 项目。The scaffolded project already contains an agents-cli-extension.yaml at its root, which is auto-loaded at project scope the next time any command is invoked. There is nothing to install manually, because the project itself is the extension's installation. A developer scaffolding a LangChain project does not need to know the Extension System exists. The command looks and feels like a native agents-cli create invocation that happens to produce a LangChain project instead of an ADK one.
步骤 2:检查生成的结构Step 2: Inspecting the Generated Structure
这是脚手架工具生成的内容:Here's what the scaffolder produced:
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,以及根目录中的 manifest。两处区别是顶层的 agents-cli-extension.yaml(其中包含 LangChain 覆盖配置)和 langgraph.json 文件(用于配置本地 playground 使用的 LangGraph 开发服务器)。The structure looks similar to an ADK project: same app/, same tests/, same Terraform under deployment/, same manifest at the root. The two differences are the agents-cli-extension.yaml at the top (which carries the LangChain overrides) and the langgraph.json file (which configures the LangGraph dev server used by the local playground).
主代理定义位于 app/agent.py:The main agent definition lives in 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:这三者都会编译为相同的底层图。The agent is created with the langchain.agents.create_agent helper, which compiles into a LangGraph CompiledStateGraph. The type annotation on root_agent makes this explicit. Modern LangChain uses LangGraph as its state management layer, which is why the template is positioned as supporting LangChain agents, LangGraph graphs, and Deep Agents through the same lifecycle: all three compile to the same underlying graph.
生成的项目脚手架中不包含对 Agent Development Kit 的依赖。我们可以直接验证这一点:The scaffolded project contains no dependency on the Agent Development Kit. We can verify this directly:
$ grep -r "google.adk\|google-adk" pyproject.toml app/
$ echo "exit: $?"
exit: 1
The grep returns no matches, and the exit code of 1 confirms the absence of ADK references. The google-* packages that do appear in pyproject.toml are the ones any Google Cloud Python project would include: google-cloud-aiplatform[evaluation], google-cloud-logging, langchain-google-genai, and the OpenTelemetry Google Cloud exporters.
agents-cli run "what's the weather in San Francisco?"
该命令会生成:The command produces:
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"),收到了模拟的雾天响应,并推理出最终句子回复给用户。警告行会告知我们当前启用的扩展命令,每个被覆盖的命令对应一条记录。这条警告是有意为之:覆盖会悄然改变原生行为,因此加载器始终会声明哪些命令正被拦截,以及由谁拦截。Behind the scenes, Gemini-3.8-flash on Vertex AI has invoked the compiled graph in-process, called get_weather("San Francisco"), received the simulated foggy response, and reasoned the final sentence back to the user. The warning line tells us which extension commands are active, with one entry per overridden command. The warning is deliberate: an override quietly changes native behavior, so the loader always announces which commands are being intercepted and by whom.
对于本地检查器,agents-cli playground 会在 8080 端口启动 LangGraph Studio,取代原本会显示的 ADK Web UI。For a local inspector, agents-cli playground boots LangGraph Studio on port 8080, replacing the ADK web UI that would otherwise appear.
要确认扩展修改了哪些命令,我们可以查看帮助输出:To confirm which commands the extension has modified, we can inspect the help output:
$ 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] 后缀是扩展系统用来标示某条命令已被覆盖的方式,同时会显示负责此操作的扩展名称。阅读终端内容的人类开发者和编程助手都能一眼看出,在这个项目中哪些命令的行为有所不同。The [↑ langchain] suffix is the Extension System's way of signalling that a command has been overridden, together with the name of the extension responsible. Both human developers and coding assistants reading the terminal can tell at a glance which commands behave differently in this project.
如需查看完整清单,agents-cli info 会列出所有活动扩展及其执行的确切命令向量:For a complete inventory, agents-cli info lists every active extension together with the exact command vector it executes:
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 agent 对象以供检查,因此 LangChain 项目会明确拒绝,而不会生成无效结果);此外,publish.gemini-enterprise 覆盖项仅在 Agent Runtime 部署目标上拒绝,在 Cloud Run 和 GKE 上则委托给原生命令执行。First-party frameworks 页面提供了官方分类说明。Six overrides total, falling into three categories: four framework-coupled replacements (playground, run, eval.generate, and publish.gemini-enterprise), two explicit refusals (eval.dataset and eval.optimize need an ADK agent object to introspect, so the LangChain project refuses them cleanly rather than producing invalid results), and the publish.gemini-enterprise override additionally refuses only on the Agent Runtime deployment target while delegating to the native command on Cloud Run and GKE. The First-party frameworks page has the official breakdown.
第 4 步:部署到 Cloud RunStep 4: Deploying to Cloud Run
LangChain 扩展不会覆盖 deploy 命令。将 LangChain 项目部署到 Cloud Run 时,使用的代码路径与部署 ADK 项目完全相同:The deploy command is not overridden by the LangChain extension. Deploying a LangChain project to Cloud Run uses exactly the same code path as deploying an ADK project:
agents-cli deploy
底层机制会针对项目的 Dockerfile 调用 gcloud run deploy --source .,其中包含:The underlying mechanism shells out to gcloud run deploy --source . against the project's Dockerfile, which includes:
CMD ["uv", "run", "uvicorn", "app.fast_api_app:app", "--host", "0.0.0.0", "--port", "8080"]
该 CMD 与 ADK 项目 Dockerfile 中的 CMD 完全相同。LangChain 模板通过 FastAPI 处理 A2A(Agent-to-Agent,代理间)协议流量,并通过 app.fast_api_app:app 暴露应用。部署流程不需要知道为代理提供支持的是哪种框架,因为 uvicorn 和 gcloud run deploy 都基于 FastAPI 契约运行。That CMD is identical to the one in an ADK project's Dockerfile. The LangChain template serves A2A (Agent-to-Agent) protocol traffic over FastAPI, exposing the application under app.fast_api_app:app. The deployment path does not need to know which framework is powering the agent, because uvicorn and gcloud run deploy operate on the FastAPI contract.
infra、scaffold enhance、scaffold upgrade、install、info、setup、lint 和 login 也都一样。在 LangChain 项目中,它们全都保持不变。这些命令经过一年的 Agents CLI 开发后,便可直接用于 LangChain 项目,无需维护 ADK 和 LangChain 代码路径之间的任何分歧。The same holds for infra, scaffold enhance, scaffold upgrade, install, info, setup, lint, and login. All unchanged in a LangChain project. A year of Agents CLI work on these commands lands in LangChain projects for free, with no divergence to maintain between the ADK and LangChain code paths.
步骤 5:运行评估Step 5: Running Evaluations
LangChain 项目中的评估遵循 ADK 演练中熟悉的模式,区别在于:eval generate 步骤会被覆盖,以驱动 LangChain 图,而后续的评估步骤则使用原生命令:Evaluations in a LangChain project follow the familiar pattern from the ADK walkthrough, with one difference: the eval generate step is overridden to drive the LangChain graph, while the subsequent evaluation steps use the native commands:
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 命令都能读取这种格式。评估服务和评分标准与框架无关。The overridden eval generate command produces output in the standard EvaluationDataset format, which the native eval grade, eval compare, and eval analyze commands know how to consume. The evaluation service and the grading rubrics are framework-agnostic.
如果开发者调用某个被拒绝的 eval 子命令,扩展程序会给出清晰的说明,而不是默默失败:If a developer invokes one of the refused eval subcommands, the extension responds with a clear explanation rather than failing silently:
$ 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.
明确地拒绝比悄无声息地失败更有用,尤其是在编码助手操控终端的情况下;否则,它可能会反复重试出错的命令,最后才放弃。A clear refusal is more useful than a silent failure, especially when a coding assistant is driving the terminal and would otherwise retry a broken command multiple times before giving up.
编写自己的扩展程序Writing Your Own Extension
LangChain 模板是 Extension System 的官方示例,但任何希望自定义 Agents CLI 命令界面的团队都可以使用同一机制。企业平台团队可以在内部编写和分发扩展,将其策略编码为代码,并通过他们一贯使用的 Git 基础设施进行发布。之后,团队中的每位开发者都会默认遵循相同的检查。The LangChain template is the first-party demonstration of the Extension System, but the same mechanism is open to any team that wants to customize the Agents CLI command surface. Enterprise platform teams can author and distribute extensions internally, encoding their policies as code and shipping them through the Git infrastructure they already use for everything else. Every developer on the team then follows the same checks by default.
为说明这种模式,我们将构建一个名为 sbom-deploy 的小型扩展,用软件物料清单(SBOM)扫描封装 deploy 命令;如果发现任何严重漏洞,就拒绝部署。有关清单架构的权威参考资料,请参阅“编写扩展”页面。To illustrate the pattern, we will build a small extension called sbom-deploy that wraps the deploy command with a Software Bill of Materials (SBOM) scan, refusing to deploy if any critical vulnerabilities are found. The authoritative reference for the manifest schema is the Authoring Extensions page.
步骤 1:定义扩展清单Step 1: Defining the Extension Manifest
我们首先为扩展创建一个目录,并在其根目录下添加 manifest 文件:We begin by creating a directory for our extension and adding the manifest file at its root:
# 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: 这样的拼写错误会导致安装失败,并给出“你是不是想输入……”的提示,而不会静默丢弃该覆盖项。The manifest contains five top-level keys, and no others are allowed. The schema uses strict validation, so a typo like reqires: fails install with a did-you-mean suggestion rather than silently dropping the override.
schema 字段用于标识清单的架构版本。name 字段是单个路径组件(不允许使用斜杠和父目录引用),并会成为存储引入副本的 extensions/ 下的目录。requires 块声明扩展支持哪些版本的 Agents CLI,以及版本不匹配时控制行为的策略(warn 或 error)。commands 块用于定义实际的覆盖项和新增项。The schema field identifies the manifest schema version. The name field is a single path component (slashes and parent-directory references are rejected) and becomes the directory under extensions/ where the vendored copy is stored. The requires block declares which versions of Agents CLI the extension supports, together with a policy (warn or error) that controls behavior on a version mismatch. The commands block is where the actual overrides and additions live.
编写文档中的“重要规则”一节列出了其他值得了解的约束。其中有两点尤其重要:你可以覆盖特定子命令(例如 eval.generate),但不能覆盖顶层命令组(例如整个 eval);而 run: 是命令向量,不是 shell 命令,因此命令链必须写在包装脚本中,不能写在清单文件中。The Rules that matter section of the authoring docs enumerates additional constraints worth knowing about. Two in particular: you can override a specific subcommand (such as eval.generate) but not a top-level command group (such as eval as a whole), and run: is a command vector, not a shell command, so any chaining of commands has to happen inside a wrapper script rather than inside the manifest.
步骤 2:编写封装脚本Step 2: Writing the Wrapper Script
由于 run: 是一个不经 shell 执行的命令向量,因此要串联多个操作,就需要编写一个按顺序执行这些操作的包装脚本:Because run: is a command vector executed without a shell, chaining multiple operations means writing a wrapper script that sequences them explicitly:
#!/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 会在通过 override 调用的任何脚本的环境中设置该变量。当我们的封装脚本递归调用 agents-cli deploy 时,该调用会进入原生 deploy 命令,而不是再次回到我们自己的 override。无需特殊语法,也不会陷入递归。AGENTS_CLI_DISABLE_OVERRIDES=1 is what makes this work. Agents CLI sets it in the environment of any script invoked through an override. When our wrapper calls agents-cli deploy recursively, the call lands in the native deploy command rather than looping back to our own override. No special syntax, no recursion.
我们可以直接验证这一点。为了演示,我们将 SBOM 扫描替换为几条 echo 语句,用来确认环境和参数:We can verify this directly. For demonstration, we swap the SBOM scan for a few echo statements that confirm the environment and arguments:
$ 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 标志被原样传递给了包装器,而且加载器在我们的脚本开始执行之前就设置好了环境变量。包装器拥有委托给原生命令所需的一切。The --project foo flag passed through to the wrapper verbatim, and the environment variable was set by the loader before our script began executing. The wrapper has everything it needs to delegate to the native command.
步骤 3:安装与验证Step 3: Installing and Verifying
准备好清单和包装器后,我们就可以安装扩展了。开发期间,请指向本地路径:With the manifest and wrapper in place, we can install the extension. During development, point at the local path:
agents-cli extension add local@../my-sbom-extension
将扩展推送到 Git 仓库后,同样的语法也适用于远程引用:Once the extension has been pushed to a Git repository, the same syntax works with a remote reference:
agents-cli extension add acme/platform-extensions#sbom-deploy --ref v1.0.0
安装完成后,我们通过列出已安装的扩展并查看帮助输出,来确认该扩展已激活:After installation, we verify the extension is active by listing the installed extensions and inspecting the help output:
$ 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] 标签,是扩展系统向用户显示的信号,表示其行为已被修改。The [↑ sbom-deploy] tag next to each overridden command is the Extension System's user-facing signal that the behavior has been modified.
锁文件管理规范Lockfile Discipline
在幕后,extension add 将我们的 Git 引用解析为一个确切的提交 SHA,并将解析结果记录在项目根目录的锁文件中:Behind the scenes, extension add resolved our Git reference to an exact commit SHA and recorded the resolution in a lockfile at the project root:
# 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/ 下 vendored 的工作副本都应提交。全新检出时,agents-cli install 会根据固定的 SHA 重新生成完全经过审核的代码,就像 uv sync 或 npm install 恢复固定的依赖项一样。安装命令不会更新固定版本,因此同一提交的两次部署之间,扩展的行为不会发生变化。Both the lockfile and the vendored working copy under extensions/ should be committed. On a fresh checkout, agents-cli install re-materializes the exact reviewed code from the pinned SHA, the way uv sync or npm install restore pinned dependencies. The install command never advances the pin, so an extension cannot change its behavior between two deployments of the same commit.
要将固定版本更新到所跟踪引用(分支、标签或 SHA)的最新提交,开发者运行 `agents-cli extension update sbom-deploy`。要切换到其他标签或分支,请使用新的 `--ref` 重新运行 `agents-cli extension add`。完整生命周期详见“使用扩展 → 生命周期”一节。To advance the pin to the latest commit on the tracked reference (branch, tag, or SHA), the developer runs agents-cli extension update sbom-deploy. To switch to a different tag or branch, re-run agents-cli extension add with a new --ref. The complete lifecycle is detailed in the Using Extensions → Lifecycle section.
接下来呢?What's Next
Agents CLI 最初是一条颇具主张的路径,旨在将 ADK 智能体部署到 Google Cloud。如今,随着扩展系统的推出,这些主张都可以由你来覆盖、替换或扩展。Agents CLI began life as an opinionated path to shipping ADK agents on Google Cloud. With the Extension System in place, those opinions are now yours to override, replace, or augment.
开始使用Get started
安装 Agents CLI,并用两条命令搭建 LangChain 智能体:Install Agents CLI and scaffold a LangChain agent in two commands:
uvx google-agents-cli setup
agents-cli create my-agent --agent google/agents-cli/extensions/langchain/template@v1.8.0 -d cloud_run
然后浏览官方文档:扩展概览、使用扩展、编写扩展和一方扩展。Agents CLI 的完整源代码(包括一方模板)位于 github.com/google/agents-cli。Then explore the official documentation: the Extensions overview, Using extensions, Authoring extensions, and First-party extensions. The full source code of Agents CLI, including the first-party templates, is at github.com/google/agents-cli.