Google 与多家行业合作伙伴公布了 Agentic Resource Discovery(ARD)规范。这项开放标准关注的不是智能体如何调用工具,而是调用之前更棘手的几个问题:有哪些工具可用、去哪里找到它们、能力描述是否可信,以及不同平台能否理解同一份资源信息。
ARD 试图在 MCP、OpenAPI 等现有执行协议之上增加一个发现层。执行协议继续负责“怎么调用”,目录和注册中心则负责回答“应该调用谁”。这种分工让智能体可以在运行时发现能力,而不必把所有工具地址和配置写死在代码里。
发现层与执行层解决不同问题
一个典型的智能体工具链可以拆成三个阶段:
- 发布:工具、API 或其他智能体向目录公开自己的能力、入口和元数据。
- 发现与验证:调用方查询注册中心,筛选候选资源,并检查发布者、版本和完整性信息。
- 执行:选定资源后,再通过 MCP、OpenAPI 所描述的 HTTP API,或其他既有协议完成调用。
这里最重要的边界是:ARD 并不需要取代 MCP 或 OpenAPI。OpenAPI 擅长描述 HTTP 接口的路径、参数和响应;MCP 为模型与工具、资源之间的交互提供协议;ARD 所强调的目录与注册机制,则让调用方先定位这些描述文件和服务。
这类似于软件包索引与包格式之间的关系。索引帮助开发者找到包,包格式和运行时负责安装与执行。把两类职责混在一起,往往会造成重复定义和协议耦合。
动态发现不能只看能力名称
如果智能体仅根据 capability: send_email 自动选择工具,风险很高。两个资源可能声明相同能力,但它们的数据边界、认证方式、运行区域和维护状态完全不同。
面向生产环境的发现记录至少需要考虑以下信息:
- 稳定的资源标识和版本。
- 能力描述以及对应的执行协议。
- MCP 服务地址或 OpenAPI 文档地址。
- 发布者身份和所有权信息。
- 认证要求、权限范围与数据处理边界。
- 元数据的签名、摘要或其他完整性证明。
- 生命周期状态,例如测试、稳定、弃用或撤销。
来源摘要没有给出 ARD 的正式字段结构或验证算法,因此不能把某个自定义 YAML 当成官方格式。下面的示例只是一个可以本地运行的简化模型,用来展示目录查询与摘要验证如何衔接;接入正式实现时,应替换为规范定义的模式、签名机制和注册中心接口。
可以这样实践:构建一个最小发现目录
创建 catalog.json,其中登记两个能力。示例使用本地文件保存 OpenAPI 文档,并用 SHA-256 演示完整性检查:
{
"resources": [
{
"id": "com.example.weather.current",
"version": "1.0.0",
"capabilities": ["weather.current"],
"protocol": "openapi",
"descriptor": "weather-openapi.yaml",
"sha256": "REPLACE_AFTER_HASHING",
"status": "stable"
},
{
"id": "com.example.docs.search",
"version": "0.3.0",
"capabilities": ["documents.search"],
"protocol": "mcp",
"descriptor": "https://tools.example.com/mcp",
"status": "testing"
}
]
}
再创建一个最小的 weather-openapi.yaml:
openapi: 3.1.0
info:
title: Current Weather API
version: 1.0.0
paths:
/weather:
get:
operationId: getCurrentWeather
parameters:
- name: city
in: query
required: true
schema:
type: string
responses:
"200":
description: Current weather
计算摘要,并把输出填入 catalog.json 的 sha256 字段:
sha256sum weather-openapi.yaml
以下 discover.py 可以按能力和状态查询目录,同时验证本地描述文件。它只使用 Python 标准库,可直接运行:
import hashlib
import json
from pathlib import Path
import sys
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as file:
for chunk in iter(lambda: file.read(65536), b""):
digest.update(chunk)
return digest.hexdigest()
def discover(capability: str) -> list[dict]:
catalog = json.loads(Path("catalog.json").read_text(encoding="utf-8"))
matches = []
for resource in catalog["resources"]:
if capability not in resource.get("capabilities", []):
continue
if resource.get("status") != "stable":
continue
descriptor = resource["descriptor"]
if not descriptor.startswith(("https://", "http://")):
expected = resource.get("sha256")
actual = sha256(Path(descriptor))
if not expected or actual != expected:
raise RuntimeError(f"descriptor verification failed: {descriptor}")
matches.append(resource)
return matches
if __name__ == "__main__":
requested = sys.argv[1] if len(sys.argv) > 1 else "weather.current"
print(json.dumps(discover(requested), indent=2))
运行查询:
python discover.py weather.current
这个例子刻意把“发现”和“执行”分开。脚本只返回已通过本地完整性检查的稳定资源,并不直接调用天气接口。下一步应由执行组件读取经过验证的 OpenAPI 文档,再生成或发起 HTTP 请求。
信任模型决定 ARD 能否进入生产环境
动态发现扩大了系统能力,也扩大了供应链攻击面。恶意注册记录可以把智能体引向伪造端点;过期描述可能导致参数误用;即使元数据没有被篡改,合法工具也可能申请超出任务所需的权限。
生产接入时,可以设置几条硬约束:
- 只信任明确配置的注册中心和发布者。
- 验证签名、摘要、证书和资源版本,验证失败时默认拒绝。
- 将“找到资源”与“批准调用”分开,高风险操作继续要求策略检查或人工确认。
- 对工具权限采用最小授权,并限制网络、文件和凭据访问。
- 缓存目录结果时设置有效期,同时支持撤销和紧急禁用。
- 记录发现条件、候选资源、选择结果和实际调用,便于审计。
ARD 的价值不在于再创造一种工具调用协议,而在于让工具生态拥有可查询、可验证、可互操作的入口。落地时应先从内部目录和只读能力开始,保留现有 MCP 或 OpenAPI 执行链路;等发布者治理、验证策略和审计机制稳定后,再逐步开放跨组织的动态发现。