Google 在 agents-cli 的 v1.5.0 里上线了扩展系统。一个目录里放一份 YAML 文件,CLI 就能识别,agents-cli deploy会跑你写的合规检查,而不是内置那套。不用 fork,不用团队总忘记调用的包装脚本,也不用每个版本都去 rebase 一份分叉副本。

打开网易新闻 查看精彩图片

官方把这套东西说成是框架锁定终结。CLI 里二十多条命令,有六条左右绑定了 ADK 运行时,剩下的 deploy、infra、publish、login 都与框架无关。扩展系统让一个 LangChain 项目替换掉那六条,继承其余十八条。设计本身是好的。

但有一件事留给了使用者:写这个扩展。

这不是小事。清单文件很严格。run:是一个不带 shell 执行的 argv 向量,任何链式操作都得塞进脚本里。有些命令是保留的,不能认领。你可以覆盖eval.generate,但不能覆盖eval这一组。键名拼错,加载器会提示,还会给个"你是不是想写",但那是在你读完文档之后。

有人做了个工具来填这道缝,有意思的部分不在模型调用,而在分工:模型负责写,CLI 负责判。

整个技术栈很薄:Node 服务端、React 前端、从 PyPI 装的 agents-cli 1.11.0,以及任意 OpenAI 兼容的模型端点。

流程是这样的:你输入一段策略,模型返回 JSON,包含命令、脚本和演示命令;服务端据此渲染出 agents-cli-extension.yaml,模型全程不碰 YAML;然后在一个一次性项目里调用真实的agents-cli extension add,再跑extension list、info、deploy --help,把真实的标准输出流式推到浏览器;最后执行agents-cli deploy,门禁跑起来,然后以非零状态退出。

界面上"verdict"下面显示的每一行,都是机器上那个二进制吐出的 stdout 或 stderr。没有 fixture,没有录制的 cassette,没有友好的转述。CLI 没装,应用就告诉你 pip 命令,而不是假装一切正常。

为什么不让模型直接写 YAML?因为那样你就在调试一个语言模型生成的 YAML,这属于最不愉快的调试体验之一。清单有五六个顶层键,schema 用了extra="forbid",拼错就是硬失败,报错信息还算友好,但代价是先烧掉一次模型调用。

模型真正要做的决定其实很小:这条策略归哪条命令、包装脚本干什么、读哪个状态文件。所以分工被切成两半:

  • 模型负责:名称、描述、理由、commands.overridecommands.add、脚本体、演示命令
  • 服务端负责:拼写、结构、schema 合规的一切

服务端里有个renderManifest(spec)函数,先校验扩展名,不匹配[A-Za-z0-9._-]+就直接抛错,然后按行拼出 schema、name、description、requires 等字段。模型永远不写 YAML,也就永远不会写出一个拼错键名的 YAML。

流式输出这块,客户端用的是 reader 循环而不是 EventSource,因为请求是带 body 的 POST,EventSource 干不了这个。有个细节很多人会写错:buf = lines.pop()。数据块不尊重行边界,最后一段几乎总是半个 JSON 对象,把它留到下一块再拼,三个字符,省掉一整类间歇性解析错误。

实测下来,RUNNING 横幅在 9.3 秒出现,此时安装步骤已经完成;ACCEPTED 在 29.9 秒出现,共五步。同样的实际耗时,感知速度完全不同。

CLI 跑通时会打印什么,两条命令比任何截图都有说服力。agents-cli info会列出扩展,标着 experimental,deploy 显示为 override、project 级别。这些输出就是判据本身。

过程中还踩到一个布局 bug:网格项默认min-width: auto,最小值取内容的宽度,一行很长的 YAML 把那一列的下限撑到自身宽度,左面板被压到 128px。它只在编译之后出现,因为那是该区域第一次有内容的时刻,所以空状态测试是干净的。

修复只有一行:给网格列用minmax(0, 1fr),给面板加min-width: 0。教训是,任何装代码块的网格都需要这两样,而且布局 bug 要靠断言而不是靠眼睛。现在有一个 Playwright 检查,走 1440、1280、1184、1024、921、920、820 和 390 像素,量两列宽度,比例超出 0.8 到 1.25 或页面出现横向溢出就失败。它五秒内抓到了第二个 bug。

下一步能做什么?最有趣的缺口是:这个工具回答的是"这个扩展怎么写",而不是"这个项目该强制什么"。把它指向一个真实仓库,读 agents-cli-manifest.yaml 和 Dockerfile,它就能提出这个项目明显需要的那两三条策略。那是另一个产品,也是更好的一个。

第二个缺口是验证深度。对 deploy 的覆盖目前跑完门禁后会撞上内置命令,在沙箱里停在"未配置部署目标"。一个伪造云调用的 dry run 模式能让演示走到真正的部署路径,有趣的失败都住在那里。

第三个是 CI。npm run compile -- --policy policy.md --out extensions/,不带界面,CLI 拒绝结果时以非零退出,平台团队就能把策略放在 git 里,让二进制来把关 PR。那才是真实组织会部署的版本,离现在大概八十行。

扩展系统目前标记为实验性,所以把 CLI 版本钉死。以上所有内容都是在 agents-cli 1.11.0、schema agents-cli-extension/v1alpha1、macOS 加 Python 3.12 上构建和测试的。

整件事一句话:模型可以挑对命令、写对 bash,但它绝不该成为判定自己输出是否合法的那一方。