Google 正式发布 pkg.go.dev v1 REST API,八个端点提供包元数据/版本/符号/依赖关系/漏洞查询,明确表示首要目标是为 LLM 和 Agent 提供确定性上下文。
多年来,一个程序想要了解 Go 包,唯一的办法是从 pkg.go.dev 上抓取 HTML,然后祈祷页面结构别在眼皮底下变来变去。
这种情况在六月发生了变化——Google 推出了 pkg.go.dev API:八个无状态的 JSON 端点,提供包和模块的元数据、版本、符号、谁导入了什么、搜索以及漏洞信息。API 附带了 OpenAPI 规范和一个参考 CLI 工具 pkgsite-cli。目前已从 v1beta 升级到 v1。公告写道:"结构化的 API 访问一直是 pkg.go.dev 最高需求的功能之一。"
包注册表的 API 本身不算新闻,真正的重点在于它的用途。Google 直接点名了头号消费者:
LLMs and agents need precise context. This API provides the data required for agents and models to reason deterministically about Go packages.
LLM 和 Agent 需要精确的上下文。这个 API 提供了 Agent 和模型对 Go 包进行确定性推理所需的数据。
Google Open Source Blog,"面向 Go 的新版 pkg.go.dev API"
注册表不只是获得了一个 API,而是一个为机器阅读而设计的 API。
这正是我用 ax-go 在工具层面正在做的事情。
Agent 遇到普通的 CLI 不得不重新抓取一遍:解析 --help、猜测 flags、运行命令、祈祷输出稳定。ax-go 终结了这一切。它提供了一个 __schema 命令,Agent 运行后可以立即获取工具的命令、flags 和类型信息作为 JSON,而且输出足够确定——相同输入,相同字节。同一命令还支持 MCP:__schema --as=mcp 以 Agent 运行时期望的格式返回这些信息。
两个层次,一个转变:
同样的问题,同样的答案:别再让机器逆向工程你本可以直接给它的结构。
有意思的是,你可以看到这两个层次如何交汇。用新 API 指向 ax-go 自己的页面:
curl https://pkg.go.dev/v1/package/github.com/rshade/ax-go
你会得到 JSON 返回:模块路径、最新版本和简介("Package ax provides the Agentic Experience foundation for Go CLI tools.")。符号和版本各自有独立的端点。一个专门让 Go CLI 对 Agent 可读的工具库,现在在注册表层面也通过一个为此而生的端点变得可读了。
再看 Google 发布的参考客户端是什么:pkgsite-cli,一个消费 JSON API 的 Go 命令行工具。这不是巧合,这就是形态——一个基于结构化后端的 CLI,旨在被人、脚本或 Agent 驱动,而不会改变其返回内容。它和 ax-go 标准化的形态是一样的,由 Go 团队发布作为自家 API 的正门。
我在七月起草了这篇文章的大部分内容。随后八月 Go 1.27 发布,继续为我提供了更多佐证。
没有 flagship 特性,只是默认行为在移动:
go test -json 现在用 OutputType 字段(error、error-continue、frame)标记输出行。解析测试结果的 Agent 可以区分堆栈跟踪和普通输出,无需靠正则表达式去猜。
go test 默认运行 stdversion vet 检查,标记使用比模块 go 指令更新的 stdlib 符号的代码。人类很少犯这种错误,但在更新代码上训练的模型会不断犯这类错误。现在工具链开箱即用地捕获它。
go fix 新增了四个现代化工具:以确定性方式应用机械迁移,而不是让 Agent 逐 token 去推理。
生态系统也在回应。同一个月,JetBrains 发布了 Modern Go Guidelines,这是一个插件,提供了 Agent 可直接运行的 CLI:list 返回适合你 Go 版本的指南,explain 给出具体案例,两者都基于 go.mod 中锁定的版本。一个 IDE 公司,发布的 CLI 预期的读者是 Agent。
Google 直接说这个 API 是为 Agent 服务的。对于工具链,我的解读是:1.27 的发布说明里一次都没有提到"agent"。它出现在默认值里,一个 JSON 字段、一个 vet 检查逐步累积。这就是当一个生态系统停止争论方向、开始假设它时的样子。
ax-go v0.7.0 于 9 月 24 日发布,其最好的功能始于 finfocus(我的 FinOps CLI,一个 ax-go 的使用者)的 bug 报告。
在 v0.6.0 上,finfocus __schema --as=mcp 列出了 37 个工具。其中四类都是陷阱:
调度是串行的,所以一次对阻塞器的调用会拖累后面所有的调用。Agent 读取那个列表时,无法区分哪些是工具、哪些是陷阱。
Hidden 是唯一的杠杆,但它用错了:它剪掉整个子树,同时也把命令从 --help 中移除,对人类也不可见。所以 v0.7.0 做了两件事。它自己跳过 groups 和 help。而 mcp.Exclude(cmd) 将一个命令标记为 not-a-tool,同时保留它在 --help 中的位置,也保留其子命令。
静态的 __schema --as=mcp 和运行中的服务器以相同的方式遵守它,所以 Agent 预先读取的列表就是它可以调用的列表。finfocus 从 37 个工具减少到 14 个(ax-go#253,finfocus#1509)。
结构只在它真实可信的时候才有帮助。一份包含会导致机器卡住的东西的机器可读列表,比没有列表更糟糕。
当支撑你的平台决定 Agent 是一等公民时,你在其上构建的工具可以停止伪装。
抓取的成本总是以脆弱性来支付的:标记变了,--help 重排了,Agent 就坏了。结构化端点是生态系统在为此买单。Go 正在注册表层面和工具链默认行为中决定:下一个读者是机器。我一直在 CLI 层面赌同样的事情。v0.7.0 就是赌注的代价:列表必须正确。