高级 API 用法

Batch API

Batch API 支持以更低价格和更高 rate limit 异步处理大量请求。价格详情请参阅Batch API 价格。如果实时请求需要更低延迟,请参阅Priority Processing

什么是 Batch API?

发起标准 Grok API 调用时,你会发送请求并等待即时响应。这种方式非常适合 Chatbot、实时 Assistant 等交互式应用,以及任何用户正在等待响应的场景。

Batch API 采用不同方式。请求不会立即处理,而是提交到 queue 后在后台执行。你不会立刻收到响应,而是在稍后回来获取结果。

与实时 API 请求的主要区别:

实时 APIBatch API
响应时间即时(秒级)通常在 24 小时内*
成本标准价格优惠价格(查看详情
Rate Limit受每分钟限制请求不计入 rate limit
使用场景交互式、实时后台处理、批量任务

* 处理时间: 大多数 Batch Request 会在24 小时内完成,但处理时间可能因系统负载和 Batch Size 而异。完成时间为 best effort,不作保证。

何时使用 Batch API

当不需要即时结果并希望降低 API 成本时,Batch API 是理想选择:

  • 运行评测和 Benchmark - 使用数千个 prompt 测试模型表现

  • 处理大型 Dataset - 分析客户反馈、分类 Support Ticket、提取实体

  • 大规模内容审核 - 审核积压的用户生成内容

  • 文档摘要 - 批量处理报告、研究论文或法律文档

  • Data Enrichment Pipeline - 为 Database Record 添加 AI 生成的洞察

  • 计划的夜间任务 - 生成日报或为 Dashboard 准备数据

工作原理

Batch API workflow 包含四个主要步骤:

  1. 创建 Batch - Batch 是将相关请求组织在一起的 container

  2. 添加请求 - 将 inference request 提交到 Batch Queue

  3. 监控进度 - 轮询 Batch Status 以追踪完成情况

  4. 获取结果 - 获取所有已处理请求的 response

下面逐步介绍。

步骤 1:创建 Batch

Batch 是请求的 container,可以把它理解为将相关工作组织在一起的 folder。你可以针对不同 dataset、实验或任务类型分别创建 Batch。

创建 Batch 后会收到 batch_id,用于添加请求和获取结果。

curl -X POST https://api.x.ai/v1/batches \\
  -H "Content-Type: application/json" \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -d '{
    "name": "customer_feedback_analysis"
  }'

步骤 2:向 Batch 添加请求

Batch 创建后即可向其中添加请求。每个请求都会异步处理。

使用 xAI SDK 添加 Batch Request 很简单:文本使用 chat.create(),图像使用 image.prepare(),视频使用 video.prepare(),Video Extension 使用 video.prepare_extension(),然后将它们作为 list 传入。也可以上传 JSONL 文件

重要: 为每个请求分配唯一的 batch_request_id。该 ID 用于将结果匹配回原始请求,在处理数百或数千个 item 时尤为重要。如果未提供 ID,我们会生成 UUID。使用自有 ID 有助于实现 idempotency(确保请求只处理一次),并将 Batch Request 与自有系统中的 record 关联。

from xai_sdk import Client
from xai_sdk.chat import system, user
from xai_sdk.tools import web_search, x_search, mcp

client = Client()

batch_requests = []

# Chat completion with tools
chat = client.chat.create(
    model="grok-4.3",
    batch_request_id="chat_001",
    tools=[web_search(), x_search()],
)
chat.append(system("Analyze market sentiment from recent news and posts."))
chat.append(user("What is the current sentiment around TSLA stock?"))
batch_requests.append(chat)

# Image generation
image_req = client.image.prepare(
    prompt="A sleek modern laptop on a minimalist desk",
    model="grok-imagine-image-quality",
    batch_request_id="img_001",
)
batch_requests.append(image_req)

# Image edit
image_edit_req = client.image.prepare(
    prompt="Add a rainbow in the background",
    model="grok-imagine-image-quality",
    image_url="https://picsum.photos/800",
    batch_request_id="img_edit_001",
)
batch_requests.append(image_edit_req)

# Video generation
video_req = client.video.prepare(
    prompt="A product rotating on a turntable with dramatic lighting",
    model="grok-imagine-video",
    batch_request_id="vid_001",
)
batch_requests.append(video_req)

# Video edit
video_edit_req = client.video.prepare(
    prompt="Make it slow motion",
    model="grok-imagine-video",
    video_url="https://lorem.video/cat_360p_3s",
    batch_request_id="vid_edit_001",
)
batch_requests.append(video_edit_req)

# Video extension
video_ext_req = client.video.prepare_extension(
    prompt="The camera slowly pans to reveal a sunset behind the mountains",
    model="grok-imagine-video",
    video_url="https://lorem.video/cat_360p_3s",
    duration=6,
    batch_request_id="vid_ext_001",
)
batch_requests.append(video_ext_req)

# Remote MCP
mcp_chat = client.chat.create(
    model="grok-4.3",
    batch_request_id="mcp_001",
    tools=[mcp(server_url="https://mcp.deepwiki.com/mcp")],
)
mcp_chat.append(user("What does the xai-sdk-python repo do?"))
batch_requests.append(mcp_chat)

# Add all requests to the batch
client.batch.add(batch_id=batch.batch_id, batch_requests=batch_requests)
print(f"Added {len(batch_requests)} requests to batch")

步骤 3:监控 Batch 进度

添加请求后,它们会开始在后台处理。由于 Batch Processing 是异步的,需要轮询 Batch Status 才能知道结果何时就绪。

Batch State 包含 pending、successful 和 failed request 的 counter。请定期轮询,直到 num_pending 变为 0,表示所有请求均已处理完成(成功或出错)。

# Check batch status
curl https://api.x.ai/v1/batches/{batch_id} \\
  -H "Authorization: Bearer $XAI_API_KEY"

# Response includes state with request counts:
# {
#   "state": {
#     "num_requests": 100,
#     "num_pending": 25,
#     "num_success": 70,
#     "num_error": 5
#   }
# }

理解 Batch State

Batch API 在两个层级追踪 state:Batch Level单个 Request Level

Batch-level State显示指定 Batch 中所有请求的汇总进度,可通过 batch.state method 返回的 client.batch.get() object 访问:

Counter说明
num_requests添加到 Batch 的请求总数
num_pending等待处理的请求
num_success成功完成的请求
num_error因错误失败的请求
num_cancelled已取消的请求

num_pending 变为 0 时,所有请求都已处理完毕(成功、出错或取消)。

单个 Request State描述每个请求在生命周期中的位置,可通过 batch_request_metadata method 返回的 client.batch.list_batch_requests() method 访问。时,Batch API 是理想选择:

State说明
pending请求已进入 queue,正在等待处理
succeeded请求成功完成,结果可用
failed请求在处理过程中遇到错误
cancelled请求已取消(例如 Batch 在该请求处理前被取消)

Batch 生命周期: Batch 也可以被取消或过期。如果取消 Batch,pending request 将不再处理,但已完成结果仍然可用。Batch 设有过期时间,过期后结果将无法访问,请在获取 Batch 详情时检查 expires_at 字段。

步骤 4:获取结果

可以随时获取结果,即使整个 Batch 尚未完成。单个请求处理完成后结果就会立即可用,因此可以在其他请求仍在处理时开始使用已完成结果。

每个结果都通过先前分配的 batch_request_id 关联到原始请求。对于 Chat Completion,使用 result.response,它包含熟悉的字段:.content.usage.finish_reason 等。对于图像请求,使用 result.image_response,其中提供 .url.base64.usage.model。对于视频请求,使用 result.video_response,其中提供 .url.duration.usage.model。这些 response type 与常规 client.image.sample()client.video.generate() method 返回的类型相同。

SDK 提供方便的 .succeeded.failed property,用于分离成功 response 和 error。

分页: 结果按页返回。使用 limit 参数控制 page size,并使用 pagination_token 获取后续页面。当 pagination_tokenNone 时,表示已经到达末尾。

from xai_sdk import Client

client = Client()

# Paginate through all results
all_succeeded = []
all_failed = []
pagination_token = None

while True:
    # Fetch a page of results (limit controls page size)
    page = client.batch.list_batch_results(
        batch_id=batch.batch_id,
        limit=100,
        pagination_token=pagination_token,
    )
    
    # Collect results from this page
    all_succeeded.extend(page.succeeded)
    all_failed.extend(page.failed)
    
    # Check if there are more pages
    if page.pagination_token is None:
        break
    pagination_token = page.pagination_token

# Process results - handle different response types
print(f"Successfully processed: {len(all_succeeded)} requests")
for result in all_succeeded:
    rid = result.batch_request_id
    resp = result.proto.response

    if resp.HasField("completion_response"):
        # Chat completion response
        print(f"[{rid}] {result.response.content}")
        print(f"  Tokens used: {result.response.usage.total_tokens}")
    elif resp.HasField("image_response"):
        # Image generation response
        print(f"[{rid}] Image URL: {result.image_response.url}")
    elif resp.HasField("video_response"):
        # Video generation response
        print(f"[{rid}] Video URL: {result.video_response.url}")

if all_failed:
    print(f"\\nFailed: {len(all_failed)} requests")
    for result in all_failed:
        print(f"[{result.batch_request_id}] Error: {result.error_message}")

其他操作

除核心 workflow 外,Batch API 还提供管理 Batch 的其他操作。

取消 Batch

可以在所有请求完成前取消 Batch。已处理请求的结果仍然可用,但 pending request 不会继续处理。无法向已取消的 Batch 添加更多请求。

curl -X POST https://api.x.ai/v1/batches/{batch_id}:cancel \\
  -H "Authorization: Bearer $XAI_API_KEY"

列出所有 Batch

查看团队的所有 Batch。Batch 会保留到过期为止(请检查 expires_at 字段)。该 endpoint 支持相同的 limitpagination_token 参数,用于对大型列表分页。

curl "https://api.x.ai/v1/batches?limit=20" \\
  -H "Authorization: Bearer $XAI_API_KEY"

检查单个请求状态

如需详细追踪,可以检查 Batch 中每个请求的 metadata,其中显示单个请求的 status、timing 和其他详情。该 endpoint 支持相同的 limitpagination_token 参数,用于对大型 Batch 分页。

curl "https://api.x.ai/v1/batches/{batch_id}/requests?limit=50" \\
  -H "Authorization: Bearer $XAI_API_KEY"

追踪成本

每个 Batch 都会追踪总处理成本。处理完成后可访问 cost breakdown 了解支出。价格详情请参阅价格页面中的 Batch API 价格

# Get batch with cost information
curl -s "https://api.x.ai/v1/batches/{batch_id}/results?limit=100" \\
  -H "Authorization: Bearer $XAI_API_KEY"

# Cost per result can be found on response.results[].batch_result.response.chat_get_completion.usage.cost_in_usd_ticks
# Cost is returned in ticks (1e-10 USD) for precision

完整示例

此端到端示例演示一个真实的 Batch Workflow:大规模分析客户反馈。它会创建 Batch、提交反馈 item 进行情感分析、等待处理并输出结果。为简化示例,这里不对结果分页;处理更大型的 Batch 时,请参阅步骤 4了解分页。

import time
from xai_sdk import Client
from xai_sdk.chat import system, user

client = Client()

# Sample dataset: customer feedback to analyze
feedback_data = [
    {"id": "fb_001", "text": "Absolutely love this product! Best purchase ever."},
    {"id": "fb_002", "text": "Delivery was late and the packaging was damaged."},
    {"id": "fb_003", "text": "Works fine, nothing special to report."},
    {"id": "fb_004", "text": "Customer support was incredibly helpful!"},
    {"id": "fb_005", "text": "The app keeps crashing on my phone."},
]

# Step 1: Create a batch
print("Creating batch...")
batch = client.batch.create(batch_name="feedback_sentiment_analysis")
print(f"Batch created: {batch.batch_id}")

# Step 2: Build and add requests
print("\\nAdding requests...")
batch_requests = []
for item in feedback_data:
    chat = client.chat.create(
        model="grok-4.3",
        batch_request_id=item["id"],
    )
    chat.append(system(
        "Analyze the sentiment of the customer feedback. "
        "Respond with exactly one word: positive, negative, or neutral."
    ))
    chat.append(user(item["text"]))
    batch_requests.append(chat)

client.batch.add(batch_id=batch.batch_id, batch_requests=batch_requests)
print(f"Added {len(batch_requests)} requests")

# Step 3: Wait for completion
print("\\nProcessing...")
while True:
    batch = client.batch.get(batch_id=batch.batch_id)
    pending = batch.state.num_pending
    completed = batch.state.num_success + batch.state.num_error
    
    print(f"  {completed}/{batch.state.num_requests} complete")
    
    if pending == 0:
        break
    time.sleep(2)

# Step 4: Retrieve and display results
print("\\n--- Results ---")
results = client.batch.list_batch_results(batch_id=batch.batch_id)

# Create a lookup for original feedback text
feedback_lookup = {item["id"]: item["text"] for item in feedback_data}

for result in results.succeeded:
    original_text = feedback_lookup.get(result.batch_request_id, "")
    sentiment = result.response.content.strip().lower()
    print(f"[{sentiment.upper()}] {original_text[:50]}...")

# Report any failures
if results.failed:
    print("\\n--- Errors ---")
    for result in results.failed:
        print(f"[{result.batch_request_id}] {result.error_message}")

# Display cost
cost_usd = batch.cost_breakdown.total_cost_usd_ticks / 1e10
print("\\nTotal cost: $%.4f" % cost_usd)

上传 JSONL 文件

除了通过 SDK 添加请求,还可以上传 JSONL 文件来创建 Batch。通过脚本、pipeline 或外部工具生成请求时,这种方式很实用。

文件中的每一行都是包含四个字段的 JSON object:custom_id(唯一标识符,对应 batch_request_id)、method(始终为 "POST")、url(API endpoint path)和 body(与该 endpoint 的 REST API Reference匹配的 JSON request payload)。

JSON

{"custom_id": "chat-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "grok-4.3", "messages": [{"role": "user", "content": "Classify this as positive, negative, or neutral: The product exceeded my expectations!"}]}}
{"custom_id": "search-1", "method": "POST", "url": "/v1/responses", "body": {"model": "grok-4.3", "tools": [{"type": "web_search"}, {"type": "x_search"}], "input": [{"role": "user", "content": "What are the latest SpaceX launches?"}]}}
{"custom_id": "mcp-1", "method": "POST", "url": "/v1/responses", "body": {"model": "grok-4.3", "tools": [{"type": "mcp", "server_label": "deepwiki", "server_url": "https://mcp.deepwiki.com/mcp"}], "input": [{"role": "user", "content": "What does the xai-sdk-python repo do?"}]}}
{"custom_id": "img-1", "method": "POST", "url": "/v1/images/generations", "body": {"model": "grok-imagine-image-quality", "prompt": "A futuristic city skyline at sunset"}}
{"custom_id": "img-edit-1", "method": "POST", "url": "/v1/images/edits", "body": {"model": "grok-imagine-image-quality", "prompt": "Add a rainbow", "image": {"url": "https://picsum.photos/800"}}}
{"custom_id": "vid-1", "method": "POST", "url": "/v1/videos/generations", "body": {"model": "grok-imagine-video", "prompt": "A rocket launching from Mars", "duration": 8}}
{"custom_id": "vid-edit-1", "method": "POST", "url": "/v1/videos/edits", "body": {"model": "grok-imagine-video", "prompt": "Make it slow motion", "video": {"url": "https://lorem.video/cat_360p_3s"}}}
{"custom_id": "vid-ext-1", "method": "POST", "url": "/v1/videos/extensions", "body": {"model": "grok-imagine-video", "prompt": "The camera slowly pans to reveal a sunset", "video": {"url": "https://lorem.video/cat_360p_3s"}, "duration": 6}}

同一文件中可以混合不同 endpoint。每个请求都会独立路由。

支持的 url 值:

URL说明
/v1/chat/completionsChat Completion
/v1/responsesModel Response
/v1/images/generations图像生成
/v1/images/edits图像编辑
/v1/videos/generations/v1/videos视频生成
/v1/videos/edits视频编辑
/v1/videos/extensions视频扩展

通过 Files API上传文件,然后创建引用该文件的 Batch:

from xai_sdk import Client

client = Client()

# Upload the JSONL file
file = client.files.upload(
    file=open("batch_requests.jsonl", "rb"),
)

# Create a batch with the file ID
batch = client.batch.create(
    batch_name="sentiment_analysis",
    input_file_id=file.id,
)
print(f"Created batch: {batch.batch_id}")

文件会在后台异步处理。如果任意一行无效,Batch 会被取消并返回错误消息。监控进度和获取结果的方式与 Inline Batch 相同。

File-based Batch 创建后即被封存,无法再通过 AddBatchRequests 添加更多请求。最大文件大小为 200 MB,最多包含 50,000 个请求。文件中的每个 custom_id 必须唯一。

限制

Batch

  • 一个团队可以拥有不限数量的 Batch。

  • Batch 创建速率上限:每个团队每秒创建 2 个 Batch。

Batch Request

  • 理论上,一个 Batch 可以包含不限数量的请求,但超大型 Batch(超过 1,000,000 个请求)可能会为保障处理稳定性而限流。

  • 可添加到 Batch 的每个单独请求最大 payload size 为 25 MB

  • 一个团队最多可以发送 1000 次 add-batch-requests API 调用;限额周期为 30 秒(这是团队所有 Batch 共享的 rolling limit)。

  • 图像和视频结果包含 signed URL,该 URL 会在 1 小时后过期。获取结果后请及时下载媒体。

Tool Use

Batch Request 同时支持Server-side Tool和 Client-side Function Tool。

  • Server-side Tool(Web Search、Code Execution、MCP 等)的工作方式与实时 API 相同:在处理过程中执行,并返回最终 response。

  • Client-side Function Tool也受支持:模型会在 response 中返回 tool_calls,供你离线处理。Multi-turn Tool Calling 需要提交新的 Batch Request,并在对话中包含 Tool Result Message。