动作空间问题:为什么给 AI Agent 更多工具反而会让表现变差
在扩展 AI Agent 时,大多数团队都会遇到一个违背直觉的失败模式:Agent 的工具集越强大,它的表现就越差。你为了处理更多场景而增加工具,准确率却下降了。你增加了更优秀的工具,它却变得更慢,并开始选错工具。你加入了编排逻辑来管理工具选择,结果你在原始的复杂性之上又重建了一层复杂性,而整个系统几乎无法运行。
增加工具的本能是错误的。生产环境中 Agent 的性能提升往往源于“删减”。
这并非假设。那些已经交付了长期运行的生产级 Agent(如编程助手、研究系统、自主任务运行器)的团队一致报告称,他们最大的性能提升来自于缩减动作空间,而非扩张。理解为什么会发生这种情况,以及如何围绕这一点进行设计,是 Agent 工程中最少被讨论但最具影响力的维度之一。
为什么工具数量会直接降低 Agent 的性能
当你向 LLM Agent 注册工具时,每个工具定义都会占用 token。一个带有名称、描述、参数和示例且文档齐全的工具可能会消耗 200–500 个 token。如果在 Prompt 中放入 50 个这样的工具,在 Agent 处理来自用户的第一条消息之前,你就已经预加载了 10,000–25,000 个 token。
这会产生三个复合问题。
第一个是注意力稀释 (attention dilution)。Transformer 的注意力是有限的。上下文中的 token 越多,意味着每个 token 分配到的注意力权重就比例越低。工具定义是结构性的——它们建立了动作空间——但它们会与指令 token、用户输入和累积的历史记录竞争模型有限的注意力预算。随着上下文的增长,模型正确推理出该使用哪个工具的能力就会下降。
第二个是选择噪声 (selection noise)。来自 Berkeley Function Calling Leaderboard 的研究表明,随着可用工具数量的增加,准确率会显著下降。只有 5 个工具时,最前沿的模型大多数时候都能选对。当增加到 20 个时,就会出现错误。当增加到 50 个以上时,模型会开始混淆外观相似的工具,幻觉出不存在的工具名称,或者在专用工具更有效的情况下默认使用通用工具。OpenAI 将 Agent 的工具上限设为 128 个——但性能滑坡早在达到该限制之前就已出现。
第三个是上下文混淆 (context confusion)——当指令、数据和结构标记都高密度存在时,LLM 很难区分它们。大型工具库会产生一种语义噪声:模型必须在工作记忆中同时保留更多的“如果这样,就那样”的关系,这挤占了更高层次的推理空间。你本想打造一把瑞士军刀,结果却递给模型一个五金店。
分层动作空间 (Hierarchical Action Space)
解决方法不是移除功能,而是将它们组织成与 Agent 实际运行方式相匹配的层级,这样模型就只能看到与当前任务相关的工具。
第一层:核心原子工具。 将其保持在 20 个左右。包括文件读/写、浏览器导航、Shell 执行、HTTP 请求,以及少量 Agent 特有的实用程序(如内存读/写)。这些是原语,每个任务都会用到,它们始终存在。
第二层:通用实用工具。 那些扩展了第一层能力但不需要 LLM 直接调用的工具。例如 CLI 工具、系统命令、包管理器。这些工具是可用的,但不需要出现在模型的主动上下文中。Agent 可以通过第一层的 Shell 执行来访问它们。
第三层:特定领域逻辑。 复杂的业务操作、多步流程、业务规则。不要将这些作为 LLM 工具暴露,而是将它们编码为代码或库函数,由 Agent 直接调用——从而避免对于本该是确定性的操作进行多次 LLM 往返。
这种结构意味着模型的主动上下文最多包含 20 个核心工具,以及当前任务所需的任何第三层函数。其他一切都被排除在外。
一个值得明确指出的失败模式是:基于动态 RAG 的工具定义。这看起来很聪明——根据当前的查询检索工具,不向 Agent 展示它不需要的工具。但在实践中,这会产生不稳定且非确定性的上下文。模型对于类似的查询会看到不同的工具子集。它会围绕那些并非总能出现的工具形成模式,甚至尝试调用当前不存在的工具(因为之前的步骤让它觉得这些工具是可用的)。对于生产级 Agent 来说,静态、可预测的工具集几乎总是优于动态工具集。
工具 RAG 作为折中方案
对于拥有真正庞大工具库的系统(如企业集成、API 网关、平台工具包),纯静态暴露是不可行的。基于检索的方法可以奏效,但必须谨慎实施。
原则是:基于与当前步骤的相关性来检索工具,而不是基于整体任务。一个处理多阶段数据管道的 Agent,在查询时应该看到数据库工具,在处理时看到转换工具,在报告时看到通知工具。将这三者混在一起会不必要地增加决策面。
关于 AutoTool(一个工具选择框架)的研究表明,这种方法可以在保持竞争力的任务完成率的同时,将推理成本降低多达 30%。动态工具依赖检索 (DTDR) 会根据初始查询和不断演变的执行上下文进行条件过滤,这能处理“正确工具取决于 Agent 已经做了什么”的情况——这比仅根据查询进行检索更合适。
约束条件:保持检索到的工具集尽可能小。每次检索调用 5 到 10 个工具是一个合理的上限。超过这个数量,你就会重新面临选择噪声问题。
Agent-as-Tool 模式
管理动作空间(action space)复杂度最强大的模式并不是工具组织——而是将决策完全移出动作选择循环。
与其让通用智能体通过对话协 调来调用专门的子智能体,不如将专门的智能体视为确定性函数。使用结构化输入和预期的输出 Schema 来调用它们。获取一个立即可用的结果。除非父级智能体需要理解子智能体为什么这样做,而不仅仅是产生了什么结果,否则不要向父级智能体暴露子智能体的内部推理或工具使用过程。
这反转了构建框架。父级智能体不需要理解如何使用代码审查智能体——它只需要知道”调用 code_review_agent(diff) → {issues: [], summary: string}”。子智能体是一个具有类型化接口的黑盒,就像普通软件中的函数调用一样。
实际的好处非常显著:
- 父级智能体的动作空间保持精简。它不需要了解子智能体内部使用的工具。
- 子智能体的结果不会污染父级智能体的上下文。你得到的是一个类型化的摘要,而不是一段需要解析的完整对话历史。
- 子智能体可以独立地开发、测试和改进。父级智能体的上下文并不关心子智能体的具体实现。
这种模式在以下情况会失效:当父级智能体确实需要子智能体的推理轨迹来做出下一个决策时。例如,软件规划智能体可能需要理解为什么子智能体标记了某个特定文件,而不仅仅是知道它被标记了。在这种情况下,请传递结构化的推理摘要,而不是原始的对话历史。永远不要将子智能体的完整上下文丢给父级——那是“通过共享内存来通信”的典型反模式。
通过通信而非共享上下文
Go 语言有一个非常 有用的并发原则:“不要通过共享内存来通信;而要通过通信来共享内存。”这同样适用于多智能体架构。
幼稚的多智能体设计会共享上下文:智能体 A 和智能体 B 都读取并写入同一个共享上下文对象。A 能看到 B 的中间步骤。B 能看到 A 的阶段性结果。随着每个智能体执行每一步,总上下文不断膨胀。到一个包含 3 个智能体的流水线的第 20 步时,你拥有的上下文窗口同时携带了所有三个智能体的历史记录——而模型正把注意力浪费在彼此的内部推理上,而不是任务本身。
更好的设计是显式地通信结果:智能体 A 产生一个类型化的输出。该输出成为智能体 B 的输入。B 看不到 A 的中间步骤——只能看到 A 的最终答案,且格式是为 B 设计的结构化格式。智能体通过定义良好的接口进行协作,而不是通过共享内存。
这在架构层面很重要,而不只是实现层面。在设计多智能体系统时,问题不应该是“每个智能体应该访问什么上下文?”,而是“下一个智能体完成工作所需的最小结构化输出是什么?”先定义这些接口。上下文管理自然会随之优化。
具体而言:
- 离散、可并行的任务 → 仅带有任务特定指令的新子智能体
- 具有依赖关系的顺序任务 → 类型化交接,而非共享历史
- 需要理解过程的复杂推理 → 结构化摘要,而非原始历史转储
衡量动作空间效率
在生产环境中,有两个指标值得显式追踪:
工具调用精确度 (Tool call precision): 在智能体进行的所有工具调用中,实际必要的比例是多少?动作空间臃肿的智能体往往会进行防御性调用——比如“以防万一”的检索、冗余检查,或者在只需一个工具时调用多个工具。高工具调用次数伴随中等的输出质量,是动作空间过载的信号。
工具选择准确率 (Tool selection accuracy): 对于有明确正确工具可选的任务,智能体是否能一致地选中它?波动的选择准确率(例如第 1 步正确,第 7 步错误)通常表明上下文腐烂 (context rot) 正在与巨大的动作空间发生负面反应。随着上下文的增长,模型对“哪个工具做什么”的掌握会松动。
这两个指标都可以通过真实的生产环境追踪记录(traces)进行测量。它们都不需要“以 LLM 为评判者”的评估。工具调用要么是必要的,要么不是;工具选择要么是正确的,要么不是。这些是更清晰的信号。
减法之道
智能体开发中的主导本能是做加法:当智能体无法完成某事时,增加一个工具。当协调变得笨拙时,增加一个编排层。当输出错误时,增加验证。
在生产环境中运行智能体足够久的从业者最终会学会减法版本:当智能体不可靠时,移除工具。当协调变得笨拙时,收窄接口。当输出错误时,检查动作空间是否过于嘈杂,导致模型无法清晰地思考其选项。
上下文工程(什么进入窗口,以及何时进入)是其中的一半。动作空间工程(智能体能做什么,以及如何组织)是另一半。大部分精力都花在了上下文上。但剩下的大部分收益其实在于动作空间设计。
模型并没有改变。你的工作是创造让它能够良好推理的条件。更少的工具、更简洁的接口以及智能体之间的类型化交接,往往比任何程度的提示词优化都更有价值。
- https://www.philschmid.de/context-engineering-part-2
- https://next.redhat.com/2025/11/26/tool-rag-the-next-breakthrough-in-scalable-ai-agents/
- https://arxiv.org/abs/2511.14650
- https://achan2013.medium.com/how-many-tools-functions-can-an-ai-agent-has-21e0a82b7847
- https://dev.to/terzioglub/why-llm-agents-break-when-you-give-them-tools-and-what-to-do-about-it-f5
- https://research.trychroma.com/context-rot
- https://arxiv.org/abs/2510.04618
- https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus
