Grok 推理强度怎么控制:reasoning_effort 四档与推理 token 计费

2026-08-25

数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。

Grok 的推理强度只有一个旋钮,但它有两个入口、两套文档说法,以及一个容易被忽略的计费后果。 入口方面,Responses API 的请求体里既有结构化的 reasoning.effort,也有一个顶层的 reasoning_effort——官方明确写了后者是「非标准字段」,只有在 reasoning 整个对象没设置时才会被读取,两个都写就是白写一个。档位方面,官方的推理能力文档给出 low / medium / high / xhigh 四档,high 是默认值,并且写明推理不能被关闭;但 REST API 参考页(跟能力文档是两个不同页面)里,请求体字段的描述又是另一套:限定的是另一个模型代次,取值里多出一个 none,默认值也不一样。计费方面,推理 token 是要按总消耗计费的,而 high 默认档意味着你什么都不设,拿到的就是花推理 token 最多的那一类档位之一。这三件事凑在一起,就是很多人第一个月账单看不懂的原因。

先搞清楚参数写在哪一层

Grok 的 Responses API 请求体里,推理相关的字段实际上分散在两处。

一处是 reasoning 对象,里面的 effort 是主字段。官方 API 参考对它的描述是「约束推理模型在回答前思考的强度」。同一个对象里还有 generate_summarysummary 两个字段,但官方对这两个的说明都是「仅为兼容性保留」,其中 summary 虽然列出了 autoconcisedetailed 三个可选值,官方却直接写明「模型将始终返回 detailed」。也就是说你在这两个字段上花的力气不会改变任何行为,这个设计有点反直觉,但文档说得很直白。

另一处是与 reasoning 平级的顶层 reasoning_effort。官方对它的定性是:这是 reasoning 配置的替代写法,属于非标准字段,目的是让用户少写一层嵌套,并且只有在 reasoning 字段未设置时才会被读取。这句定性是 POST /v1/responses 请求体下的原文,只在这个端点成立——别直接套到别的端点上,后面有一节专门说为什么。

这条优先级规则是实际接入时最容易踩的坑。官方给的 OpenAI 兼容 SDK 示例,写法是 reasoning={"effort": "high"};而不少团队的模型调用层为了兼容别家接口,会在封装里固定塞一个顶层 reasoning_effort。两种写法叠在一起时,按官方这句规则,顶层那个不会被读取,请求也不会报错——最终生效的是 reasoning 对象里的值,而不是你在调用处传的那个。排查这类「参数明明写了却没生效」的问题,先确认是不是同时写了两层,再去怀疑别的。

官方的 xAI SDK 走的是另一条路:在 client.chat.create() 里直接传 reasoning_effort 参数;Vercel AI SDK 则是放在 providerOptions.xai.reasoningEffort 里;OpenAI 兼容 SDK 用的是 reasoning={"effort": ...}。四种写法对应同一个后端能力,选一种写法贯彻到底,别在同一个项目里混着来。

四个档位,官方各自给了什么定位

官方能力文档给出的四档,以及它对每一档的适用场景描述如下(这是官方原文给的定位,不是性能承诺):

  • low:会用掉一些推理 token,但仍然快。官方点名的场景是「对延迟敏感的 agentic 用法和简单的工具调用」。
  • medium:思考更多,官方给的场景是「复杂数据分析和长上下文推理」。
  • high:默认档,用更多推理 token 做更深的思考,官方场景是「非常有挑战的问题、复杂数学、多步逻辑、竞赛级任务」。
  • xhigh:官方描述为「最大推理深度,相应地延迟也更高」,场景是「最难的问题,答案质量比响应时间更重要的场合」。

两个必须记住的限制条件。第一,xhigh 是从 grok-4.6 起才有的,官方明确写了在不支持它的模型上(文档举的例子是 grok-4.5),传 "xhigh" 会被当作 "high" 处理——注意是静默降级,不是报错,所以你以为自己在用最深档,账单和结果其实都停在 high。第二,官方能力文档说 reasoning_effortgrok-4.6grok-4.5 支持,而 Batch 接口的请求体文档又单独写了「grok-4 不支持该参数,用了会报错」。跨模型迁移时这条要单独核。

「推理能不能关掉」,官方文档里有两种说法

这是本篇最需要如实交代的一点。

能力文档那一节写得很硬:reasoning_effort 未指定时默认为 "high"推理不能被禁用

但 REST API 参考页里,同一句字段说明写的是另一套:仅由 grok-4.3 支持,可选值包含 none(完全禁用推理)、low(未指定时的默认值)、mediumhigh

关键是这套说明挂在哪个字段上——两个端点还不一样,这也是最容易写错的地方:

  • POST /v1/chat/completions 的请求体里,这套说明挂在顶层的 reasoning_effort 上。这个端点的请求体字段清单里根本没有 reasoning 对象,只有 reasoning_effort 这一个入口。
  • POST /v1/responses 的请求体里,挂的是 reasoning 对象下的 effortGET /v1/responses/{response_id} 回读一条响应时,返回体里同样按 reasoning.effort 回显这个配置。

所以别把两个端点的同名字段当成同一个字段。上一节讲的「顶层 reasoning_effort 是非标准字段、只在 reasoning 未设置时才读」,原文只出现在 POST /v1/responses 下;chat/completions 下那个同名的顶层字段,官方挂的是完全不同的一段说明。反过来也一样:你按 Responses API 的习惯在 chat/completions 里写 reasoning: {effort: ...},写的是一个官方请求体清单里不存在的字段。这类多写的字段最难查,因为它通常既不报错也不生效。

两处说的是不同模型代次上的不同行为,落到你手上就是一句话:以你实际调用的那个模型对应的章节为准,并且在下单前回官方文档当前版本核一遍默认值。不要拿本文(或任何二手文章)里的默认值去做成本估算,模型一换代这个默认值就可能变。真正稳妥的做法是显式传 effort,不依赖默认——显式传的代价只有一行代码,依赖默认的代价是某天悄悄换了档位而你不知道。

推理 token 在 usage 里怎么看

官方把推理消耗单独暴露成了字段,这点做得比较实在。

在 Responses API 的响应体里,usage.output_tokens_details.reasoning_tokens 是「模型为推理生成的 token 数」,官方定义原文如此。同时 usage.output_tokens 的定义是「最新上下文里的补全 + 推理 token」,也就是说推理 token 已经被算进输出侧,不是额外挂在外面的一项。至于同一层的 total_tokens,官方在 Responses API 的响应体里只给了一句「使用的 token 总数」,没有展开说明它由哪几部分构成——真正把口径写细的是下一段要讲的压缩端点,那里的 total_tokens 才明确写成「输入 + 输出,含推理」。字段同名、说明详略不同,这是读 API 参考时很容易顺手把一处定义套到另一处的地方,做成本核对时以你实际调用的那个端点下的定义为准。

结论很直接:你在监控里只看 total_tokens 是看不出推理占比的,必须把 output_tokens_details.reasoning_tokens 单独打出来。官方的流式示例里就是这么做的——一边流一边读 response.usage.reasoning_tokens,在正式内容还没开始吐的时候把它当作「思考中」的进度指示。这个用法值得抄,它同时解决了两件事:给用户一个等待反馈,给你一份逐请求的推理消耗记录。

还有一个容易被漏掉的入口:POST /v1/responses/compact 这个上下文压缩端点,它自己的 usage.output_tokens_details 里同样带 reasoning_tokens 字段。压缩这一步本身也会产生推理消耗。做长会话的项目如果把压缩当成「省钱操作」而不计入成本模型,账就对不上。这块的机制可以对照 Grok 上下文压缩怎么用 一起看。

另外 max_output_tokens 这个参数的官方定义是「一次响应能生成的最大 token 数,包含输出和推理两部分」。这意味着高 effort 档下推理会挤占你留给正文的额度——如果发现回答被截断,先看是不是推理吃掉了预算,而不是急着加长 prompt。未设置时官方有一个默认上限,具体数值以官方文档当前版本为准。

拿到推理过程:摘要流与加密内容

Grok 提供了两条看到「模型在想什么」的路径,机制完全不同。

一条是推理摘要。官方说明 grok-4.6 会暴露模型内部推理的摘要。在 OpenAI 兼容 SDK 下,流式事件类型是 response.reasoning_text.deltaresponse.reasoning_summary_text.delta;xAI SDK 下读 chunk.reasoning_content;Vercel AI SDK 下判断 part.type === 'reasoning-delta'。三套 SDK 三个名字,迁移时是个小坑。

另一条是加密推理内容。官方说明这部分推理内容由 xAI 加密,需要在请求里传 include: ["reasoning.encrypted_content"](xAI SDK 里对应 use_encrypted_content=True)才会返回。它的用途不是给你看的——是让你把加密内容回传到下一次请求的输入里,为后续对话补充上下文。官方还提了一句:用 Vercel AI SDK 时,只要没有显式设置 store: false,加密推理内容会被自动带上,不用额外配置。

这里牵出服务端存储的话题。Grok 默认会把之前的输入、推理内容和模型响应保存在服务端,你可以用 previous_response_id 接着聊而不必重发整段对话;不想存就在请求里设 store: false(xAI SDK 是 store_messages=False)。但官方同时说明服务端存储有保留期限,超期会被清除,想在那之后继续同一段对话,就得自己把历史和加密推理内容存在本地再传回去——具体期限以官方文档为准。选 store: false 的项目要特别注意一个限定:前面那条「加密推理内容会被自动带上」的说明,官方是专门针对 Vercel AI SDK 讲的,而且成立的前提正是「没有显式设置 store: false」。所以在这套 SDK 上,一旦为了不落库而关掉服务端存储,自动携带这件事也跟着没了,得自己把加密内容接回下一次请求。其他 SDK 官方没有给出同类说明,别默认它们的行为一致。

这几个参数和推理模型互斥

官方能力文档单独列了一条:presencePenaltyfrequencyPenaltystop 不能与推理模型一起使用,带了这些参数的请求会返回错误

这条值得贴在代码注释里。很多团队的模型调用层是共用一个参数封装的,stop 序列尤其常见——从非推理模型切到推理模型时,封装层原样透传,请求就直接失败了。排查的时候容易误判成鉴权或模型名问题,因为报错点离参数很远。

另外两个「会被静默忽略」的字段也一并记下:logprobsgrok-4.20 及更新的模型上不支持,设置了会被静默忽略;include 里 OpenAI 那个 message.output_text.logprobs 同样是「接受但静默忽略」。静默忽略比报错更难查,别指望它会提醒你。

多智能体模型上,effort 的含义变了

grok-4.20-multi-agent 是个例外,必须单独说。官方写明:在这个模型上,reasoning.effort 控制的是参与协作的 agent 数量,而不是推理深度。xAI SDK 里对应的是一个独立参数 agent_count;OpenAI SDK、Vercel AI SDK 和 REST 都靠 reasoning.effort 的取值映射到两档配置——低两档映射到较少 agent,高两档映射到较多 agent。官方给的选择建议是:快速、聚焦的查询用少 agent 档,深度、多面向的研究用多 agent 档。该功能官方标注为 beta,接口和行为可能变。

计费上这个模型有个明确警告:官方说明主导 agent 和所有子 agent 消耗的全部 token 都要计费,包括输入、输出和推理 token;任何 agent 发起的服务端工具调用也都计入工具用量并计费。换句话说,在这个模型上把 effort 从低档拨到高档,成本影响不是线性的一点点,是整支 agent 队伍的规模变了。

成本这块,实际该怎么做

把上面的机制串成可执行的动作:

第一,显式传档,按任务分级。 不要全局一个档走天下。官方给的四档定位本身就是任务分级指南——简单工具调用走 low,长上下文分析走 medium,硬骨头才上 highxhigh。默认是 high,意味着「什么都不设」是四档里偏贵的那一侧,这跟很多人的直觉相反。

第二,把 reasoning_tokens 打进日志。 按接口、按 effort 档、按模型三个维度分组统计,你才能看出到底是哪条链路在烧推理 token。总量指标看不出这个。成本监控的通用做法可以参考 API 成本监控怎么做,Grok 侧的计费口径见 Grok API 计费机制

第三,能异步的走 Batch。 官方定价页的 Batch 一节写明,Batch 优惠适用于全部 token 类型——输入、输出、缓存和推理 token 都在内,也就是说高 effort 档多花的那部分推理消耗同样能享受到。但这里有两个限定条件不能丢:其一,官方写明优惠幅度按模型不同而不同;其二,官方在同一节列了一份适用模型清单,并明确说清单之外的模型没有 Batch 优惠。换句话说「走 Batch 能省」不是无条件成立的,取决于你用的是哪个模型,落地前请回官方定价页当前版本对一遍清单。用法见 Grok Batch API 怎么用

第四,超时值单独设。 官方文档里涉及推理模型的多个章节,示例代码都把客户端超时显式调长了,注释写的就是「为推理模型覆盖默认超时」。高 effort 档下如果沿用默认超时,很可能在模型还没想完的时候就被客户端掐断——请求已经产生了推理 token,结果你一个字都没拿到。这是最亏的一种失败。

最容易栽的坑

按踩中概率排序:顶层 reasoning_effortreasoning.effort 同时写,前者被忽略;在不支持 xhigh 的模型上传 xhigh,静默降级成 high;从非推理模型切过来时透传了 stop,请求直接报错;默认档是 high 却以为是低档,第一个月账单超预期;max_output_tokens 被推理吃掉一大块导致正文截断。

这五个里有三个是静默失败——不报错、不提示,只是结果和你想的不一样。所以接入 Grok 推理模型的第一件事不是调参,是reasoning_tokens 和实际生效的 effort 值一起打进日志,让静默失败变得可见。参数值本身随时会变,日志里那两个数字才是你自己的事实来源。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。