Agent 场景选模型平台要看哪几件事:工具调用机制对比
数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。
做 Agent 的时候选模型平台,「支持 function calling」这句话几乎等于没说——六家平台都支持,但差异全在细节里:工具是你执行还是平台替你执行、能不能强制模型这轮必须调工具、工具多了有没有按需加载的通道、多轮循环的刹车在服务端还是在你手里、失败的工具调用算不算钱、工具声明放在哪会把前缀缓存打掉。这六件事任何一件跟你的架构不合,迁移成本就不是「改个 base_url」那么轻。下面按你真正会踩到的顺序逐条对照官方文档来看。
一、先分清:工具是你执行,还是平台替你执行
这是第一道分水岭,却常被一句「都支持工具调用」盖过去。
xAI 的官方《Tools Overview》把工具明确分成两类:Built-in Tools(由 xAI 托管、在服务端自动执行的工具)和 Function Calling(你自己定义、由你执行的函数)。文档写得很直白:内置工具跑在 xAI 的服务器上,你只提供工具配置,执行和返回结果由 API 负责;function calling 则是模型请求、你决定被调用时发生什么。声明方式也简洁,在 tools 数组里放 { "type": "web_search" } 这样的对象即可。
MiniMax 的《服务端工具(Server Tools)》页面走的是同一条思路,但边界画得更窄。官方明确列了支持范围:接口仅 Anthropic Messages API(/anthropic/v1/messages),可用工具只有 web_search 一个,声明方式是在 tools 数组里加一个 type 为 web_search_20250305 的工具。文档还专门解释了这个带日期后缀的类型标识沿用 Anthropic 的命名约定,工具能力变化时会以新的日期后缀发新版本。这一页同时标注该能力处于 Beta 阶段,功能与参数可能会调整——做架构决策时这句话的分量不轻。
智谱 GLM 的形态又不一样。《联网搜索》页把搜索拆成三种服务:Web Search API(直接拿结构化搜索结果)、对话中的网络搜索(把搜索结果融进模型生成并标注来源)、以及搜索智能体。其中「对话中的网络搜索」是在 tools 里放一个 type 为 web_search 的对象,并在同名的 web_search 子对象里配置 enable、search_engine、search_result、search_prompt、count、search_domain_filter、search_recency_filter、content_size 这一串字段。注意这里 search_prompt 是可以写提示词的——你能直接影响模型怎么消化搜索结果。
阶跃星辰在《工具调用》API 参考页里列了两个官方工具:互联网搜索和知识库搜索。互联网搜索的声明方式是 type 固定为 web_search,并通过 function.description 描述什么样的信息需要模型去搜。官方原文说明,搜索完成后结果会「以上下文的方式,插入到对话中」交给模型推理。
Kimi 的路径最特别。《如何在 Kimi API 中使用官方工具》给的是 Formula API 官方工具通道,走 OpenAI 协议的标准 function tool 流程,一共四步:GET /v1/formulas/{uri}/tools 拿工具声明(uri 形如 moonshot/web-search:latest)→ POST /v1/chat/completions 带上声明拿到 tool_calls → POST /v1/formulas/{uri}/fibers 按 tool_calls 原样执行 → 再回 /v1/chat/completions 带上 role: "tool" 的结果拿最终回答。也就是说,工具的实现由平台托管,但每一步的编排还是你的代码在发——它介于纯客户端工具和 Grok 那种全自动服务端工具之间。文档还特别注明,在 kimi-k3 上使用联网搜索等官方工具时请走这条 Formula 通道。
Gemini 这边能核到的是官方一条错误消息里枚举出的受支持工具类型:function、code_execution、mcp_server、filesystem、google_maps、google_search、bash、computer_use、file_search、url_context。这是枚举取值而不是行情数字,可以作为形态判断的依据,但来源是错误信息中的枚举,具体以官方参考文档当前版本为准。
选型结论:如果你的 Agent 就是「搜一下再答」,Grok 和 MiniMax 那种服务端自动执行能省掉整套多轮回传代码;如果工具要访问你自己的数据库和内部系统,那再多的内置工具也帮不上忙,得看后面几件事。
二、你能不能命令模型「这轮必须调工具」
这一件事上六家的差距大到可以直接淘汰候选。
智谱 GLM 的《工具调用》页对 tool_choice 的说明是:控制函数调用策略,默认且仅支持 auto。这句话对 Agent 架构的影响是实打实的——如果你的工作流要求「这轮必须先检索、不许模型凭记忆答」,在 GLM 上你没法用参数把它钉死,只能靠提示词和后置校验来兜。
Kimi 在《工具调用约束》页给的选择最全:"required" 强制本轮至少调用一个工具、"none" 完全禁止产生 tool_calls、"auto"(不传时的默认值)由模型自行决定,此外 tool_choice 还能传一个函数对象来强制调用指定工具。这一页还埋了一个很容易被踩的限制:指定函数调用当前与思考开启不兼容,思考开启时传入会返回 400 错误,错误信息是 tool_choice 'specified' is incompatible with thinking enabled。做深度推理型 Agent 的话,这两个能力你只能二选一。
顺带说一个官方给出的组合技:首轮用 "required" 强制模型调用 search_tools,检索完成后恢复 "auto"。这就是下一节要讲的工具搜索模式。
阶跃星辰和 GLM 落在同一档,而且官方把话写得同样明确。《Responses API》创建响应的参考页对 tool_choice 的说明是:工具调用策略,当前仅支持字符串 "auto",由模型自行决定是否调用工具。《Tool Call 使用建议》那一页的两段完整示例代码里,请求参数用的也都是 tool_choice="auto"。
这里要提醒一个查文档时容易走岔的地方:阶跃另有一页标题就叫《工具调用》的 API 参考,那一页讲的是 tools 数组怎么写——每个成员的 type 当前仅支持 function,function 对象包含 name、description、parameters 三个字段——全篇没有出现 tool_choice,去那一页翻取值说明会扑空。要核这条约束,得翻 Responses API 的创建响应参考页。
所以到这一节为止,「本轮必须先调工具」这个开关,六家里 Kimi 给得最全;GLM 的《工具调用》页写的是默认且仅支持 auto,阶跃的 Responses API 参考页写的是当前仅支持 "auto",两家的结论一致。落在这两家上,强制调用只能靠提示词加后置校验兜,而提示词兜不住的那部分风险,得在架构设计里提前留出重试和降级的位置。
三、工具一多,谁给你兜住上下文膨胀
Agent 项目做到第三个月,工具通常都不止十个。这时候把全部工具声明塞进请求顶层的 tools 字段会出什么事,Kimi 的《动态加载工具》页给了一个专门的名字:工具定义膨胀(Tool Definition Bloat)。官方描述的两个后果是:每个请求都要携带全部工具的描述和参数 schema,token 消耗高;候选工具越多,模型也越容易选错工具、构造出错误的调用参数。
Kimi 给出的解法是在 messages 里插一条 role 为 system 的消息,通过这条消息的 tools 字段声明要加载的工具。几条关键规则值得抄下来:
- 携带
tools的 system 消息与普通 input messages 地位相同,它出现在messages的哪个位置,工具就从哪个位置开始对模型可见; - 动态加载的工具与顶层
tools声明的全局工具并存,模型能同时看到两类; - 动态注入必须是完整的工具定义(
name、description、parameters都要有),不能只传工具名去引用全局已声明的工具。
在这个机制之上,官方给了实现 tool search 的路子:API 层面没有专门的 tool search 接口,但你可以在顶层只声明一个由你后端实现的 search_tools 工具,在 system prompt 里声明可被搜索的关键词,模型先调 search_tools,你再按返回结果把对应工具的完整声明动态插进去。这样无论工具总量多大,每轮请求里实际存在的声明都只有少量几个。
两个限制必须记住:动态加载工具目前仅 kimi-k3 支持,在其他模型(如 kimi-k2.6)上请求会返回 tokenization failed 错误;携带 tools 的 system 消息不能再携带 content 字段,否则请求会以 400 报错(cannot be used with content)。
其他几家在这一格上没有对应机制,但有相关约束。阶跃星辰的《工具调用》页明确写了「函数数量建议控制在合理规模,过多的函数定义会消耗较多 prompt token,并可能降低模型的命中准确率」,对 name 那一条则是建议而非强制:官方原话是建议使用英文字母、数字、下划线与连字符,遵循一条以字母或下划线开头的正则,并给了长度上限(正则与上限以官方文档当前版本为准),同时提醒用语义化的英文名更容易被模型识别。这里「建议」和「必须」的区别值得留意:官方文档没有把它写成硬性校验,所以选型阶段不要按强制约束去设计工具名的生成逻辑,把它当成一条应当遵守的命名规范来落就好。Kimi 的官方工具页也提醒,function.name 在一次 API 请求中必须唯一,否则该请求会被视为非法请求并立即返回 400(invalid_request_error,错误信息形如 function name get_weather is duplicated);同时使用多个 formula 时,还得自己维护 function.name 到 formula_uri 的映射。
四、多轮循环的刹车在谁手里
Agent 最怕的不是不干活,是停不下来。
xAI 在《Tool Usage Details》里提供了 max_turns 参数,但这个参数的语义有个反直觉的地方,官方特意加粗强调过:max_turns 限制的不是工具调用的个数,而是 agentic 循环里 assistant 轮次的个数。一个「turn」是「模型分析上下文 → 决定调用一个或多个工具(可能并行)→ 工具执行返回结果 → 模型处理结果」这样一次迭代,所以单个 turn 里模型可以并行调很多工具。文档也说明,不指定 max_turns 时服务端会套用一个全局默认上限,达到上限后 agent 会停止追加工具调用,基于已收集的信息生成最终回答(具体默认值以官方文档当前版本为准)。
《Advanced Usage》页还讲了混合使用服务端工具和客户端工具时的行为,这一段直接决定你的循环代码怎么写:xAI 会自动执行模型决定使用的服务端工具;而当模型调用客户端工具时,agent 执行会暂停,把 tool call 返回给你,由你执行后追加结果、发起一次新的后续请求。关键是——这个后续请求会重新开始计算 max_turns。官方把客户端工具调用形容成会重置轮次计数器的「检查点」。如果你以为设了 max_turns 就等于给整条链路封了顶,那是误读。
想判断某个返回的 tool call 到底是不是需要你本地执行的,xAI SDK 提供了 get_tool_call_type,返回值是 "client_side_tool"、"web_search_tool"、"x_search_tool"、"code_execution_tool"、"collections_search_tool"、"mcp_tool" 这一组;走 Responses API 的话就看 response.output[].type,"function_call" 表示客户端工具需要本地执行,"web_search_call"、"mcp_call" 之类则是服务端已经处理完的。
MiniMax 那边因为整个搜索流程在一次请求内完成,官方给的提醒不是循环失控而是超时:搜索行为完全在服务端完成,单次请求的耗时可能比不启用工具时更长,请合理设置客户端超时时间。这条在网关和反向代理层同样要跟着调,不然工具还没跑完连接先被掐了。
五、工具的账怎么算、怎么对
单价一律看各家官方定价页,这里只讲口径——而口径才是账单对不上时真正的坑。
xAI 把两个指标分得很清楚,这一段的口径设计很值得抄:response.tool_calls 返回的是 agentic 过程中所有被尝试的工具调用,包含失败的那些;response.server_side_tool_usage 返回的是成功执行的工具及其调用次数映射,官方原文说明这一项决定你的计费。两者会在什么情况下不一致,文档也列了:模型试图浏览不存在的网页、抓取已删除的帖子等执行错误,参数畸形无法处理,以及工具执行链路的临时性网络或服务故障。结论很实用——失败的尝试不计费,所以拿 tool_calls 的条数去估账单必然偏高。
同一页还提醒了 agentic 请求的 token 结构与普通对话不同:completion_tokens 只代表模型最终的文本输出,通常比你预期的小得多,因为中间的推理和工具编排都在内部完成;prompt_tokens 是整个 agentic 过程中所有推理请求的累计输入 token,每次请求都包含到那一步为止的完整对话历史,会随进程增长;此外还有 reasoning_tokens(内部推理)和 cached_prompt_text_tokens(命中缓存的 prompt token 数)。看到 prompt_tokens 数字大得离谱先别慌,先确认是不是 agentic 累计口径。
Kimi 的 Formula 通道把计费点标得很明确:四步流程里的第三步——POST /v1/formulas/{uri}/fibers 按 tool_calls 原样执行——这一步产生 tool_call 计费。也就是说模型「决定要调」不产生工具费用,你真去执行 fiber 才产生。
阶跃星辰在《网络搜索使用建议》里写明互联网搜索工具按实际调用的次数计费。这类按次计费的服务端工具,在成本模型里跟 token 是两条独立的线,做预算和做监控时都要分开估、分开看。
六、工具声明会不会顺手打掉你的前缀缓存
Agent 的上下文长、轮次多,缓存命中率直接决定成本量级。而工具声明恰恰落在前缀里,动态增删工具就等于动前缀。
Kimi 的《动态加载工具》页对这件事专门给了一整节,把机制写得很直白:上下文缓存按前缀匹配,前缀中任何位置发生变化,该位置之后的缓存都会失效。由此推出三条原则:
- 追加,不要插入:新的工具声明一律追加到
messages末尾,已有前缀保持不变;向对话中间插入或修改任何消息(包括已注入的工具声明),都会使变更位置之后的缓存无法命中; - 保留已注入的声明:动态工具声明按请求生效,服务端不会记住。建议后续请求原样保留已加载的声明,这样工具保持可用、前缀保持稳定。若不再携带,该工具即失效,且由于
messages变了,变更位置之后的前缀缓存也可能无法命中; - 核心工具固定在顶层声明并保持不变:官方明确说顶层全局工具声明不影响缓存命中,保持稳定即可让前缀缓存持续有效,只有按需使用的工具才做动态注入。
另有两条配套事实:tool_choice 是请求级参数,官方说明设不设置它不会破坏前缀缓存,可以放心按请求粒度调整;上下文缓存本身有一个 prompt tokens 的最小门槛,低于门槛的请求不会被缓存而是被丢弃(门槛数值以官方文档为准)。
xAI 那边给的是趋势性描述:agentic 请求在各步之间大部分 prompt 保持不变,因此能显著受益于 prompt caching。想把各家缓存形态的差异一次看全,可以对照模型 API 缓存计费机制那篇通用机制。
七、流式输出下,工具调用是流出来的还是整块给的
这一条在做实时交互界面时会直接决定你的前端怎么写,而两家的做法正好相反。
智谱 GLM 有专门的《工具流式输出》页,说明在 GLM-5.2、GLM-5.1、GLM-5、GLM-4.7 上工具调用支持开启响应的流式输出,允许在不进行缓冲或 JSON 验证的情况下流式传输工具使用参数。用法是 stream=True 配合 tool_stream=True,流式响应的 delta 对象里会有 reasoning_content(推理过程)、content(回答文本)、tool_calls(工具调用信息)三类字段。官方示例的拼装逻辑是按 tool_call.index 归组,同一个 index 第二次出现时把 function.arguments 往后追加——参数是一段一段拼出来的,你的解析代码必须自己攒完再解析 JSON。
xAI 的《Function Calling》页则在开头挂了一条 WARNING:在流式场景下,function call 是在单个 chunk 里整体返回的,不会跨 chunk 流式输出。同一体系里服务端工具的行为又不一样——《Tool Usage Details》说流式 agentic 请求可以通过 chunk 对象上的 tool_calls 实时观察模型做出的每一次工具调用决策,但服务端工具的执行输出不会在 API 响应里返回,agent 只在内部用它来组织最终回答。想在界面上展示「正在搜索……」是可以的,想展示搜到了什么原文就不行。
这两种形态的差别意味着,同一套流式渲染代码在两家之间几乎不能直接复用。相关细节可以看GLM 流式工具调用怎么拼装和 Grok function calling 与工具体系。
八、MCP 接不接、怎么接
如果你的 Agent 已经在用 MCP 生态,这一格是硬约束。
xAI 提供 Remote MCP Tools,由 xAI 代管与 MCP 服务器的连接和交互,配置项包括必填的 server_url(官方说明只支持 Streaming HTTP 与 SSE 两种传输)、必填的 server_label(用于工具调用名前缀),以及可选的 server_description、allowed_tools(xAI 原生 SDK 里叫 allowed_tool_names)、authorization、headers。官方还标了一条兼容性缺口:OpenAI Responses API 里的 require_approval 和 connector_id 参数当前不受支持。这条如果你的审批流依赖 require_approval,就要在选型阶段改设计。
智谱这边是把搜索做成了 MCP Server 让第三方客户端接:官方《联网搜索》页给了在支持 MCP 协议的客户端(如 Cursor、Cherry Studio)中配置 zhipu-web-search-sse 的示例,并注明 Cursor 的 MCP 需在 Composer 的 Agent 模式下使用。方向和 xAI 正好相反——一个是模型去连你的 MCP 服务器,一个是把自家能力暴露成 MCP 服务器给编辑器用。别把这两件事当成同一个「支持 MCP」。
Gemini 的受支持工具类型枚举里出现了 mcp_server,可以作为形态判断的参考,更细的配置方式在官方文档里没有找到相关说明。
九、可用性这条,其实要放在最前面
前面八件事都是技术选择,只有这一件是准入。
Gemini 的官方区域说明里,Gemini API 与 Google AI Studio 在官方页列出的国家/地区推出,该列表中不包含中国大陆;官方对不在支持区域者给出的路径是改用 Gemini Enterprise Agent Platform 中的 Gemini API。另有两条非区域的准入条件:最低年龄要求,以及需在 Google 账号中完成年龄验证。国内团队要合规使用,方向只有企业采购路径或者换用国内合规平台,这一步没有捷径可走,也不该去找捷径。
值得一提的是迁移成本:Google 的两条产品线共用统一的 Gen AI SDK,从 Developer API 切到 Enterprise Agent Platform 主要是改客户端初始化那几行(Python 里给 genai.Client() 加上 vertexai=True 与 project、location),generate_content 的调用代码本身不变。官方对两条线的定位是:Developer API 是构建与扩缩的最快路径,除非需要特定的企业控制,多数开发者应当用 Developer API。
最后:三个值得单独拎出来的坑
第一,把「支持工具调用」当成一句可以打勾的能力。到这里应该看清楚了:GLM 的 tool_choice 默认且仅支持 auto,阶跃星辰的 Responses API 同样写明当前仅支持 "auto",两家都给不了强制调用;Kimi 的取值最全,但它的指定函数调用与思考模式互斥;MiniMax 的服务端工具只有一个且只走 Anthropic 接口——这些都是会改架构的差异,不是打勾能盖住的。
第二,用 tool_calls 的条数估工具账单。xAI 明确区分了尝试次数和计费的成功次数,Kimi 明确把计费点落在执行 fiber 那一步,阶跃的互联网搜索按实际调用次数计费。三家的口径都不一样,拿一家的心智去看另一家的账单,对不上是必然的。
第三,为了省 token 每轮动态改工具声明,结果把缓存全打掉了。Kimi 那三条原则(追加不插入、原样保留已注入声明、核心工具固定在顶层)看着朴素,但真正决定了长链路 Agent 的成本量级。
下一步建议这样做:把你 Agent 里的工具按「必须本地执行」和「可以交给平台」分成两堆,先看候选平台的服务端工具能不能吃掉第二堆;再拿你最长的一条工具链去核对 max_turns 这类循环上限的语义;最后按各家官方定价页的口径分别估一遍 token 线和工具调用线。真要换平台的时候,可以顺手过一遍换模型厂商的迁移检查清单。