长时间解码

借助长时间解码,Gemini 4 Argon 可以生成超出单次请求输出限制的内容,以执行深度推理任务,最高可达到统一的 100 万个 token 的上下文窗口(1,048,576 个 token,在输入、思考和输出之间共享)。

仅更改模型 ID 不会启用长时间解码。如果没有其他设置,流式调用输出将停止在 64K 个 token,非流式调用输出将停止在 32K 个 token。启用长时间解码的最快方法是升级 Google GenAI SDK 并将 max_output_tokens 设置为大于 65,536。本指南介绍了长时间解码的工作原理、使用场景以及如何使用 generateContent 启用长时间解码。

长时间解码的工作原理

单个流式或 SDK 请求最多可生成 64K 个 token,而非流式 REST 请求最多可生成 32K 个 token。当响应需要更多 token 时,模型会在多个请求和响应跃点中生成响应,每个跃点都会从上一个跃点停止的位置继续。

  • 统一的输入和输出 token 限制 :输入、思考、函数调用和最终响应共享一个 100 万个 token 的窗口。输出最多可以使用 1,048,576 减去您的输入 token 数。
  • 每个跃点的上限 :一个跃点最多返回 65,536 个输出 token。非流式 REST 请求最多返回 32,768 个 token。
  • 继续信号 :如果模型达到上限且还有剩余 token,则响应将以 finish_reason: CONTINUATION 和 continuation_token 结尾。
  • 下一个跃点 :客户端使用该 token 再次发送相同的请求。模型将从停止的位置继续。
  • 所有跃点的总数 :max_output_tokens 设置所有跃点的思考和输出 token 总数。
  • 停止信号 :当模型使用所有 max_output_tokens 时,响应将以 finish_reason: MAX_TOKENS 结尾。

对于难题,跃点可能会将其所有 token 用于内部思考,并返回带有 continuation_token 的空文本。这是正常现象,最终答案会在后续跃点中出现。

默认输出限制

如果不使用长时间解码,单个请求将停止在以下每个请求的限制:

  • 通过 Google GenAI SDK (generate_content) 发出的流式请求和非流式请求 :默认输出 token 数为 64K。
  • 直接非流式 REST 调用 (generateContent) :默认输出 token 数为 32K。在没有 continuation_token 的非流式 REST 调用中将 max_output_tokens 设置为大于 32,768 会返回 400 错误。
调用模型的方式 不使用长时间解码时的输出限制 启动时长时间解码 您需要采取的措施
Google GenAI SDK,最新版本 64K 是,SDK 会为您继续 设置 max_output_tokens。
Google GenAI SDK,旧版本,非流式 64K 否 升级 SDK。
REST streamGenerateContent 64K 是,使用您自己的循环 编写循环。请参阅选项 2。
REST generateContent 32K 是,使用您自己的循环 编写循环。请参阅选项 2。

何时使用长时间解码

大多数请求都在单次请求限制内完成(流式和 SDK 调用为 64K 个 token,非流式 REST 调用为 32K 个 token)。当响应需要的思考和输出 token 总数超过单次请求允许的 token 数时,请使用长时间解码。提高 max_output_tokens 会为模型提供更高的上限,以便模型能够推理解决难题,而不是让标准答案更长。

工作负载 使用长时间解码? 原因
复杂的数学、科学、研究和正式证明 是 模型可以使用超过 64K 个 token 来探索和检查其推理。
最复杂的编码和智能体任务 是 某些任务在一个响应中需要超过 64K 个 token 的思考和代码。大多数编码和智能体任务都在 64K 个 token 以内完成。
在输出限制处停止的评估工具 是 当模型将整个 64K 或 32K 请求用于思考时,长时间解码可防止答案被截断。
聊天、问答、摘要、分类和提取 否 这些任务在 32K 个 token 以内完成。
请求固定长度,例如“写一本 70 万字的书” 否 模型不会遵循长度目标。
以许多短轮次调用工具的智能体 否 每个轮次都很短。每个轮次的大量输出会快速填满统一的 100 万个输入和输出 token 的窗口。
接近 100 万个输入 token 限制的提示 否 输出只能使用 100 万减去您的输入 token 数。
对延迟时间敏感的请求 否 长时间解码可以运行几分钟。

设置较高的 max_output_tokens 会为模型提供更多空间来思考难题,但模型仍然会决定要编写多少内容。如需控制模型使用的推理工作量,请设置 thinking_level。

启用长时间解码

您可以使用 Google GenAI SDK(选项 1,建议大多数应用使用)自动运行长时间解码,也可以编写自己的继续循环(选项 2)。这两个选项都支持完整的 100 万个 token 的上下文窗口。

选项 1:Google GenAI SDK(推荐) 选项 2:您自己的流式循环 选项 2:您自己的非流式循环
谁启动每个跃点 SDK。您设置 max_output_tokens。 您的代码,在每个检查点或流式传输中断后 您的代码,每 32K 个 token
每个请求的 token 数 每个跃点 64K 每个流式传输 64K,在 32K 后每 5K 个 token 设一个检查点 每个请求 32K
每个请求的时间限制 20 分钟 20 分钟 20 分钟
存储 无服务器存储 无服务器存储 无服务器存储
适用场景 大多数应用 REST 调用方和流式传输的自定义工具 简单评估工具

加密的 continuation_token 在请求之间携带模型的状态,因此服务器上不会存储任何内容。

选项 1:使用 Google GenAI SDK(推荐)

在最新的 Google GenAI SDK 中,系统会为流式和非流式调用默认启用 automatic_continuation,因此您无需进行设置。当您将 max_output_tokens 设置为高于每个请求的上限时,SDK 会自动运行继续跃点并返回一个组合响应。

  1. 升级 SDK。

    Python

    pip install -U "google-genai>=2.30.1"
    

    JavaScript

    npm install "@google/genai@>=2.29.1"
    
  2. 将 max_output_tokens 设置为大于 65,536。

    Python

    from google import genai
    from google.genai import types
    
    client = genai.Client()  # Reads GEMINI_API_KEY
    
    response = client.models.generate_content(
        model="gemini-4-argon",
        contents="Write a complete, rigorous proof of the prime number theorem.",
        config=types.GenerateContentConfig(
            max_output_tokens=262_144,  # Total thinking and output for all hops
            thinking_config=types.ThinkingConfig(thinking_level="high"),
            automatic_continuation=True,  # Default. Shown for clarity.
        ),
    )
    
    print(response.text)
    print("Finish reason:", response.candidates[0].finish_reason)
    print("Prompt size:", response.usage_metadata.initial_prompt_token_count)
    print("Billed tokens:", response.usage_metadata.total_token_count)
    

    JavaScript

    import { GoogleGenAI, ThinkingLevel } from "@google/genai";
    
    const ai = new GoogleGenAI({}); // Reads GEMINI_API_KEY
    
    const response = await ai.models.generateContent({
      model: "gemini-4-argon",
      contents: "Write a complete, rigorous proof of the prime number theorem.",
      config: {
        maxOutputTokens: 262144, // Total thinking and output for all hops
        thinkingConfig: { thinkingLevel: ThinkingLevel.HIGH },
        automaticContinuation: true, // Default. Shown for clarity.
      },
    });
    
    console.log(response.text);
    console.log("Finish reason:", response.candidates?.[0]?.finishReason);
    console.log("Prompt size:", response.usageMetadata?.initialPromptTokenCount);
    console.log("Billed tokens:", response.usageMetadata?.totalTokenCount);
    

请注意以下几点:

  • 流式传输 :generate_content_stream (Python) 和 generateContentStream (JavaScript) 也会为您继续。如果流式传输在检查点后中断,SDK 会从该检查点恢复。
  • 超时 :超时和重试适用于每个跃点,而不是整个运行。
  • 手动控制 :如需自行运行循环,请设置 automatic_continuation=False (Python) 或 automaticContinuation: false (JavaScript)。然后按照选项 2 进行操作。
  • 使用情况 :使用情况字段显示所有跃点的总和。如需获取提示的大小,请读取 initial_prompt_token_count。请参阅统计 token 数量。

选项 2:编写自己的循环

如果您直接调用 REST、使用没有最新 SDK 的语言或需要完全控制,请编写自己的循环。您还可以参考我们在 Python 和 JavaScript/TypeScript 中的 Google GenAI SDK 实现。

遵循以下规则:

  1. 在每个跃点上发送相同的请求。发送原始 contents、system_instruction、tools 和 generation_config。保持 max_output_tokens 不变。
  2. 不要将部分输出添加到 contents。continuation_token 携带模型的状态,包括其思考。
  3. 仅发送最新的 token。每个 token 都包含之前的所有进度。
  4. 在 finish_reason 为 CONTINUATION 时继续。在任何其他完成原因时停止。
  5. 在最后一个跃点后加入各个部分。将所有跃点的各个部分合并为一个模型轮次,用于对话历史记录。

Python

from google import genai
from google.genai import types

client = genai.Client()  # Reads GEMINI_API_KEY
PROMPT = "Write a complete, rigorous proof of the prime number theorem."
parts = []
token = None

while True:
    response = client.models.generate_content(
        model="gemini-4-argon",
        contents=PROMPT,  # The original contents on every request
        config=types.GenerateContentConfig(
            max_output_tokens=262_144,  # The same total on every request
            thinking_config=types.ThinkingConfig(thinking_level="high"),
            automatic_continuation=False,  # You run the loop
            continuation_token=token,
        ),
    )
    candidate = response.candidates[0]
    if candidate.content and candidate.content.parts:
        parts.extend(candidate.content.parts)
    token = candidate.continuation_token
    if candidate.finish_reason != types.FinishReason.CONTINUATION or not token:
        break

print("".join(p.text for p in parts if p.text and not p.thought))
print("Finish reason:", candidate.finish_reason)

JavaScript

import { GoogleGenAI, ThinkingLevel } from "@google/genai";

const ai = new GoogleGenAI({}); // Reads GEMINI_API_KEY
const PROMPT = "Write a complete, rigorous proof of the prime number theorem.";
const parts = [];
let token = undefined;
let candidate = undefined;

while (true) {
  const response = await ai.models.generateContent({
    model: "gemini-4-argon",
    contents: PROMPT, // The original contents on every request
    config: {
      maxOutputTokens: 262144, // The same total on every request
      thinkingConfig: { thinkingLevel: ThinkingLevel.HIGH },
      automaticContinuation: false, // You run the loop
      continuationToken: token,
    },
  });
  candidate = response.candidates?.[0];
  if (candidate?.content?.parts) {
    parts.push(...candidate.content.parts);
  }
  token = candidate?.continuationToken;
  if (candidate?.finishReason !== "CONTINUATION" || !token) {
    break;
  }
}

console.log(parts.filter((p) => p.text && !p.thought).map((p) => p.text).join(""));
console.log("Finish reason:", candidate?.finishReason);

REST

# Hop 1: send the request with max_output_tokens.
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-4-argon:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "Write a complete, rigorous proof of the prime number theorem."}]}],
    "generationConfig": {
      "maxOutputTokens": 262144,
      "thinkingConfig": {"thinkingLevel": "high"}
    }
  }'

# Hop 2: if finishReason is CONTINUATION, send the same request plus the token.
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-4-argon:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "Write a complete, rigorous proof of the prime number theorem."}]}],
    "generationConfig": {
      "maxOutputTokens": 262144,
      "thinkingConfig": {"thinkingLevel": "high"}
    },
    "continuationToken": "TOKEN_FROM_HOP_1"
  }'

完全用于思考的跃点会返回带有 finishReason: "CONTINUATION" 的空 text。将其视为正常进度并请求下一个跃点:

{
  "candidates": [{
    "content": {"role": "model", "parts": [{"text": ""}]},
    "finishReason": "CONTINUATION",
    "continuationToken": "CiQ4ZmQ3..."
  }],
  "usageMetadata": {
    "promptTokenCount": 142,
    "candidatesTokenCount": 0,
    "thoughtsTokenCount": 32768,
    "totalTokenCount": 32910
  }
}

流式循环 需要再添加一条规则。在前 32,768 个 token 之后,流式传输每 5,000 个 token 发送一个检查点 token。将新数据块保留在待处理列表中。当数据块具有 continuation_token 时,将待处理的数据块移至已提交的输出并保存该 token。如果流式传输中断,请舍弃待处理的数据块并从最后一个 token 恢复。如果流式传输在第一个检查点之前中断,请再次发送原始请求。

设置 max_output_tokens

max_output_tokens 设置所有跃点的思考和输出的组合限制。降低此值不会使模型思考得更简洁,而是会更快地截断响应。

您的工作负载 建议的 max_output_tokens
限制低于 32K 的现有应用 将其提高到 32,768。
长时间编码和智能体任务 从 65,536 开始。
复杂的数学、科学、研究和证明 测试值从 262,144 到 1,048,576 减去您的输入 token 数。

如需使用更少的 token,请降低 thinking_level。对于最复杂的推理任务,请使用 high。对于大多数编码和智能体工作,请使用 medium(默认值)。对于不太复杂的任务,请使用 low。

处理长时间运行的请求

由于 Gemini 4 Argon 在难题上的思考时间比 Gemini 3.x 模型长,因此您应增加客户端超时时间,以免长时间请求过早断开连接。

  • 非流式调用 :服务器会在 10 分钟后关闭连接。
  • 流式调用 :服务器会在 20 分钟后关闭流式传输。
  • 客户端超时 :将 HTTP 读取超时时间设置为 20 分钟。3 分钟或 5 分钟的超时时间会过早停止请求。

在 Python 中,以毫秒为单位在客户端上设置超时时间:

client = genai.Client(http_options=types.HttpOptions(timeout=1_200_000))  # 20 minutes

对于客户端轮询的作业,Interactions API 会在服务器上运行长时间解码。请参阅后台执行。

当模型使用所有输出 token 时恢复

当响应以 MAX_TOKENS 结尾时,它仍然包含 continuation_token。您有以下两种选择:

  • 继续 :使用该 token 和更高的 max_output_tokens 发送相同的请求。该值必须高于目前使用的 token 数。否则,API 会返回 400 错误。
  • 重新开始 :使用更高的 max_output_tokens 和无 token 发送原始请求。您需要为两次运行付费。

统计 token 数量

使用自动继续时,usage_metadata 会报告所有跃点的总数。SDK 会将每个计数字段相加:prompt_token_count、cached_content_token_count、candidates_token_count、thoughts_token_count 和 total_token_count。

prompt_token_count 会将每个跃点的输入 token 数相加。每个跃点都会将您的提示以及目前生成的所有内容作为输入发送回模型,因此在每个后续跃点中,相同的 token 会再次被统计。例如,使用 Google GenAI SDK 时,一个包含 1,000 个 token 的提示会生成 200,000 个 token 的思考和输出,需要四个跃点:

跃点 发送给模型的输入 输入 token 数
1 提示 1,000
2 提示 + 跃点 1 66,536
3 提示 + 跃点 1 和 2 132,072
4 提示 + 跃点 1 到 3 197,608
总计 397,216

prompt_token_count 报告大约 397,000 个 token(重复的跃点输入会自动通过隐式缓存获得 95% 的自动折扣),而 total_token_count 报告大约 597,000 个 token,即使实际上下文大小仅为大约 201,000 个 token:1,000 个 token 的提示加上 200,000 个 token 的思考和输出。非流式 REST 循环使用 32K 个跃点,因此相同的输出需要七个跃点,并报告 695,128 个输入 token。

调用模型的方式 usage_metadata 显示的内容 费用 提示大小
Google GenAI SDK,自动继续(默认) 所有跃点的总数 按原样读取使用情况字段。 读取 usage_metadata.initial_prompt_token_count (Python) 或 usageMetadata.initialPromptTokenCount (JavaScript)。
使用 automatic_continuation=False 的 SDK 或 REST 每个响应一个跃点 将每个字段跨跃点相加。 从第一个跃点读取 prompt_token_count。

prompt_token_count 和 total_token_count 是每个跃点的总和,而不是上下文的大小。请勿使用它们来决定何时总结或修剪对话历史记录(上下文压缩),或强制执行上下文限制。如需估算上下文大小,请将表格中的提示大小添加到 candidates_token_count 和 thoughts_token_count。

在运行长时间解码之前,请更新智能体框架、评估工具或代理:

  • 智能体和评估工具:如果您的代码压缩上下文或在达到 token 限制时停止运行,请使用 initial_prompt_token_count(或 REST 中第一个跃点的 prompt_token_count)而不是相加的 prompt_token_count。在一个跃点中完成的响应在这两个字段中报告相同的值,因此短期测试不会显示该问题。
  • 调用 REST 的代理和网关 :每个 REST 响应仅报告其自己的跃点。将每个字段跨跃点相加以计算费用,并将第一个跃点的 promptTokenCount 作为提示大小。否则,您的用户看到的数字与 SDK 用户看到的相同请求的数字不同。
  • 日志和序列化响应 :SDK 会在客户端上计算 initial_prompt_token_count。它不在 REST 响应或 SDK 的 JSON 输出(例如 model_dump())中。如果以后需要,请将其另存为一个单独的值。

如果您在自己的循环中进行流式传输,则 usage_metadata 在每个流式传输中是累积的。仅保留每个流式传输的最后一个值,然后将这些值跨跃点相加。

了解结算

您需要为每个跃点中的每个 token 付费,包括仅包含思考的跃点。

  • 缓存折扣 :隐式缓存会将每个跃点中重复的输入折扣 95%。在促销期间,缓存的输入费用为每 100 万个 token 0.10 美元,而不是 2.00 美元。
  • 缓存过期 :缓存会在 15 到 20 分钟未使用后过期。跃点之间长时间暂停会再次按完整输入费率收费。
  • 失败的非流式跃点 :只有在响应完成时,您才需要付费。失败或中断的请求费用为 0 美元。
  • 中断的流式传输 :在 32K 个 token 之前中断的流式传输费用为 0 美元。之后,您需要支付到最后一个检查点 token 的费用,因为您可以从该检查点恢复。

问题排查

问题 原因和解决方法
输出在 64K 或 32K 处停止,并显示 CONTINUATION 模型还有剩余 token,但没有任何内容继续请求。升级 SDK 或添加循环。
输出在 64K 或 32K 处停止,并显示 MAX_TOKENS 未设置 max_output_tokens 或设置得太低。将其设置为大于 65,536。
带有 MAX_TOKENS 的空文本 模型将所有 token 用于思考。提高 max_output_tokens 或降低 thinking_level。
400:“继续 token 已使用输出 token...” max_output_tokens 不高于目前使用的 token 数。提高此值。
thinking_level: "minimal" 的错误,或带有 thinking_level 的 thinking_budget 的错误 Gemini 4 Argon 不支持 minimal。请使用 low、medium 或 high。设置 thinking_level 或 thinking_budget,而不是同时设置两者。
thinking_budget、temperature、top_p 或 top_k 的警告 Gemini 4 Argon 会忽略或映射这些字段。请使用 thinking_level,并移除抽样参数。
请求在 3 或 5 分钟后结束 客户端超时时间太短。将其设置为 20 分钟。
上下文压缩过早开始 工具读取相加的输入。请改为读取 initial_prompt_token_count。

限制

  • OpenAI 兼容性端点 :长时间解码不可用。输出在每个请求的上限处停止。
  • 旧版 SDK :低于备注中最低版本的版本不会自动继续。
  • 长度 :模型不会遵循 token 长度或字数目标。

核对清单

  • 将 Google GenAI SDK 升级到最低版本。
  • 将 max_output_tokens 设置为大于 65,536。
  • 使用 thinking_level(low、medium 或 high),而不是 thinking_budget。
  • 将 HTTP 读取超时时间设置为 20 分钟。
  • 使用 initial_prompt_token_count 进行上下文大小和压缩。
  • 在进行大规模评估之前,先运行一个提示作为测试。

后续步骤