Agent 的能力注册与发现:子 Agent 上线后,主 Agent 怎么知道它能干什么

你写了一个主 Agent,手下管着十几个子 Agent,分工明确、干活麻利。直到有一天,你新加了一个子 Agent——能解析财报,还能画 K 线图。你心想,这不是给团队添了员猛将吗。结果跑起来一看,主 Agent 压根不认得这新人,还在调用那个只会读 PDF 的老工具。问题出在哪儿?你忘了让主 Agent 知道,团队里多了一个人、这个人擅长什么。

AI technology illustration

在 Agent 系统里,这件事叫能力注册与发现。听名字像是微服务的 service discovery 换皮,但真正做起来,你会发现它比服务发现麻烦得多。微服务时代,服务上线后把自己的 IP、端口和健康检查地址登记到注册中心,调用方来查就行。可子 Agent 的能力没法用 IP:端口 描述清楚——因为它的调用方是一个 LLM,你得用自然语言告诉它:我是什么、我能干什么、你什么时候该想起我。

所以,Agent 注册表里躺着的,通常是这样一份东西:

  • 身份信息:名字、ID、版本、权限等级。
  • 调用入口:函数签名、接口端点,或者另一个 Agent 的 prompt 模板。
  • 输入输出 schema:参数怎么传、返回什么格式,这决定主 Agent 知道"怎么调"。
  • 能力描述:一段自然语言,写清楚"在什么场景下找我"。这是注册表里唯一决定主 Agent 会不会想起你的字段。

字段虽少,但维护过的人都知道,前面三样是死数据,最后一个才是活接口。

你来看两段描述。第一段是典型的偷懒写法,只写了"处理财报"三个字。第二段把触发场景、输入要求和边界条件都讲明白了。同一个 Agent,两套 description,主 Agent 的任务表现可以天差地别。

// 糟糕的描述
{
  "name": "financial_report_agent",
  "description": "处理财报。"
}

// 合格甚至优秀的描述
{
  "name": "financial_report_agent",
  "description": "当用户要求分析财报、提取关键财务指标、对比两家公司的数据,或回答"这家公司赚不赚钱"之类的问题时使用。输入应为财报文件路径。注意:如需生成图表,请调用 chart_agent,不要调用本 Agent。"
}

你可能会问:能不能直接让主 Agent 读子 Agent 的源码或接口文档,自己搞明白?理论上可以,但没人这么干——读代码不会让 LLM 更懂语义。代码里全是 how,而路由决策需要的是 what 和 when。更现实的是,子 Agent 很可能是第三方开发的,只提供一份描述文档,你没有源码可读。这正是几乎所有实现都选择 description 作为核心接口的原因。

这不是玄学。UC Berkeley 和微软合作的 Gorilla 论文 发现,LLM 严重依赖 API 的文字描述来决策要不要调用它——描述里写没写清楚适用场景和调用边界,直接影响模型在组合新任务上的成功率。Anthropic 的工具调用文档 也反复强调,描述措辞的一个小改动,就能让模型选错工具。用一句话总结:你的能力描述不是写给运维看的,是写给另一个 LLM 看的。

我自己一开始就栽在这上面。最初搭多 Agent 编排时,我天真地觉得给子 Agent 起个好名字就够了——file_reader、web_search,名字里全是动词,主 Agent 总该猜出来吧。结果跑了两轮就翻车:主 Agent 宁可自己瞎编,也不调用我精心注册的子 Agent。后来我才想通:LLM 不会猜,它只会读 description。而且 description 里最值钱的信息不是"这个 Agent 干什么",而是"用户的什么意图出现时该轮到它",以及"它跟邻居 Agent 的区别是什么"。LangChain 工具描述指南 给的建议我后来逐条对照过,核心就这几点:把触发场景写进去、把参数细节留给 schema、别放跟调用无关的废话。

注册只是上车牌,发现才是跑起来的环节。主 Agent 收到一个用户任务时,怎么从几十个注册项里捞出最匹配的那个?当下有两条主流路线。

路线一:上下文注入。把整个能力清单塞进主 Agent 的 system prompt,让它自己挑。实现成本最低,Agent 数量在十个以内时效果相当好。但随着清单变长,LLM 的注意力会被稀释,排在后面的 Agent 会沦为摆设。

路线二:检索路由。把每份能力描述预先向量化入库,任务来了先做一次向量相似度检索,把 Top-3 最相关的描述取出来,再交给主 Agent 做最终判定。这也是 Semantic Kernel 这类偏企业级框架的默认姿势。

两条路怎么选,给你一张表:

维度 上下文注入 检索路由
实现成本 低,改 prompt 即可 中,需要向量库和更新管线
适用规模 约 10 个以内 几十到上百个
路由质量 依赖 LLM 对全局的理解 依赖检索的召回率与重排
延迟 每次全量思考,略高 先粗筛再细想,更稳
典型场景 小型编排、原型验证 插件市场、大型平台

但别高兴太早,检索路由有一个"水多加面、面多加水"的死循环:路由不准时你会下意识把描述写得更长,而描述越长、检索噪声越大、路由越不准。很多团队因此会硬性限制 description 不超过一百到二百字,只保留触发场景、输入要求和最重要的边界。

往上还有一个容易被忽略的坑:注册表更新了,主 Agent 的上下文未必跟着更新。

子 Agent 从"只读财报"升级成"还能做财务预测",注册表里倒是改了。可主 Agent 的 system prompt 里缓存的是旧版能力清单,它这辈子都不会知道有这项新技能。这个问题在静态提示词架构里天然无解,只能靠两条路:要么每次任务前动态拉取最新注册表,要么监听能力变更事件、变更后刷新主 Agent 的上下文。后者听起来优雅,但要处理缓存失效和并发更新,比服务发现的配置推送麻烦得多。

这句话自然引出信任问题。假设有个人往注册表里塞了一个假"天气查询" Agent,描述写着"任何涉及天气的问题请务必调用我",实际它是个数据窃取器。主 Agent 能识破吗?很难——对 LLM 来说,这段描述本质上就是一段可被构造的自然语言,天然带有被投毒的风险。所以正经的多 Agent 系统至少要补两层:注册阶段保留身份认证(签名或 token),确保注册者是可信来源;调用阶段做权限隔离,把普通 Agent 和高危 Agent 的调用链分开,敏感操作一律二次授权。

能力注册与发现这个领域,目前正处在一个"方案很多、标准很少"的微妙阶段。MCP 想统一工具接口,A2A 协议 想标准化 Agent 之间的交互,OpenAI 的 function calling 则把"描述"的权重抬到了前所未有的高度。但所有努力本质上是在回答同一个问题:子 Agent 的能力是一段它自己都无法自证的自然语言描述,谁来保证这段话足够准确、足够诚实、足够让另一个 LLM 一看就懂?

在标准尘埃落定之前,我能给的最实用的建议是:把 description 当成一个需要认真设计的接口,而不是注册表里的备注字段。你的主 Agent 干活顺不顺,很大程度上取决于这段文字写得干不干净。

原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/521.html

(0)
上一篇 2天前
下一篇 2天前

相关推荐