跳转到内容

高级 API 用法

WebSocket 模式

Responses API 可以通过一个持久的 WebSocket 连接到 /v1/responses 来驱动,而不是为每个轮次都打开一个新的 HTTP 请求。在第一次响应之后,后续轮次只需要发送新的输入项以及一个 previous_response_id — 服务器会在开放的套接字中将先前状态保存在内存中。

这适用于零数据保留(ZDR)和 store=false,因为关于续期的内容不需要接触持久存储。

适用场景

WebSocket 模式针对具有许多连续工具调用的代理工作负载 — 编码代理、编排循环、任何与模型来回交互数十次的场景。

每个轮次都跳过连接设置,只发送新的输入而不是完整的对话内容,这在长期运行中会累积优势。在我们对具有大量工具调用的代理工作负载的内部基准测试中,与使用相同 previous_response_id 链接的重复 HTTP 请求相比,我们测量到端到端延迟降低了约 20%。

打开连接并发送第一轮

WebSocket 升级成功后,每个轮次都由客户端发送 response.create 消息来启动。正文形状与 Responses 创建请求正文 相同,但不包括仅传输相关的字段,如 streambackground(响应始终作为套接字上的事件流式返回)。

python
import json
import os
from websocket import create_connection

ws = create_connection(
    "wss://api.x.ai/v1/responses",
    header=[
        f"Authorization: Bearer {os.environ['XAI_API_KEY']}",
    ],
)

ws.send(
    json.dumps(
        {
            "type": "response.create",
            "model": "grok-4.5",
            "store": False,
            "input": [
                {
                    "type": "message",
                    "role": "user",
                    "content": [{"type": "input_text", "text": "Find fizz_buzz()"}],
                }
            ],
            "tools": [],
        }
    )
)
javascript
import WebSocket from "ws";

const ws = new WebSocket("wss://api.x.ai/v1/responses", {
  headers: {
    Authorization: \`Bearer \${process.env.XAI_API_KEY}\`,
  },
});

ws.on("open", () => {
  ws.send(
    JSON.stringify({
      type: "response.create",
      model: "grok-4.5",
      store: false,
      input: [
        {
          type: "message",
          role: "user",
          content: [{ type: "input_text", text: "Find fizz_buzz()" }],
        },
      ],
      tools: [],
    })
  );
});

ws.on("message", (data) => {
  console.log(JSON.parse(data.toString()));
});

使用 generate: false 进行预热

如果您已经知道下一轮所需的工具、指令或系统消息,可以通过发送带有 generate: falseresponse.create 来预先连接。服务器准备请求状态但不运行模型 — 不返回任何输出。预热仍然会发出一个响应 ID,您可以通过 previous_response_id 从该 ID 链接后续内容,这样实际的生成轮次可以更快开始。

继续运行

对于每个后续轮次,发送一个新的 response.create 并包含:

  • previous_response_id — 此链上最后一个响应的 ID。
  • input — 仅此轮的新内容(通常是工具输出加上下一个用户消息)。不要重新发送先前历史;服务器已有这些内容。
python
ws.send(
    json.dumps(
        {
            "type": "response.create",
            "model": "grok-4.5",
            "store": False,
            "previous_response_id": "resp_123",
            "input": [
                {
                    "type": "function_call_output",
                    "call_id": "call_123",
                    "output": "tool result",
                },
                {
                    "type": "message",
                    "role": "user",
                    "content": [{"type": "input_text", "text": "Now optimize it."}],
                },
            ],
            "tools": [],
        }
    )
)
javascript
ws.send(
  JSON.stringify({
    type: "response.create",
    model: "grok-4.5",
    store: false,
    previous_response_id: "resp_123",
    input: [
      {
        type: "function_call_output",
        call_id: "call_123",
        output: "tool result",
      },
      {
        type: "message",
        role: "user",
        content: [{ type: "input_text", text: "Now optimize it." }],
      },
    ],
    tools: [],
  })
);

链接在套接字上的工作方式

previous_response_id 的行为方式与在 HTTP 上相同,但 WebSocket 路径有一个额外的内存快捷方式。每个开放的连接在其每连接缓存中保存其最新响应的状态。从该响应继续运行完全不需要访问存储,这就是为什么 WebSocket 模式可以安全地与 store=false 和 ZDR 一起使用。

如果您引用一个不再在连接缓存中的旧 previous_response_id

  • 使用 store=true 时,服务器可能会从持久状态中重新加载它,但您会失去内存延迟优势。
  • 使用 store=false 或在 ZDR 下,没有可回退的存储可读取,轮次会因 previous_response_not_found 而失败。

失败的轮次(4xx5xx)会将其 previous_response_id 从连接缓存中驱逐,这样重试不会从损坏的状态继续。

连接限制和行为

  • 事件类型和顺序与现有的 Responses 流式传输格式相同。
  • 一个连接按顺序处理轮次 — 在一个轮次进行中发送第二个 response.create 将排队,而不是多路复用。
  • 需要并行轮次?打开多个连接。
  • 单个连接可以保持开启状态最多 25 分钟。之后,服务器会关闭它,您需要重新连接。

重新连接

当套接字断开(网络波动、部署、达到 25 分钟上限)时,打开一个新连接并选择适用的恢复路径:

  1. 如果您使用了 store=true 并且仍然有有效的响应 ID,只需在新套接字上使用 previous_response_id 和新的输入项继续。
  2. 否则(例如 store=false 或遇到 previous_response_not_found),完全删除 previous_response_id 并通过发送下一轮的完整输入上下文开始一个新链。

错误

一些错误响应特定于 WebSocket 模式,值得明确处理。

previous_response_not_found

当请求的 previous_response_id 不在连接缓存中且无法从存储中重新加载时返回(例如 ZDR、store=false 或先前失败被驱逐)。

json
{
  "type": "error",
  "status": 400,
  "error": {
    "code": "previous_response_not_found",
    "message": "Previous response with id 'resp_abc' not found.",
    "param": "previous_response_id"
  }
}

websocket_connection_limit_reached

在服务器关闭已达到最大 25 分钟的连接之前发送。打开一个新的 WebSocket 并使用上述模式之一重新连接。

json
{
  "type": "error",
  "status": 400,
  "error": {
    "type": "invalid_request_error",
    "code": "websocket_connection_limit_reached",
    "message": "Responses websocket connection limit reached (25 minutes). Create a new websocket connection to continue."
  }
}

相关指南

本文档为 docs.x.ai 全站中文翻译,由 AI 自动翻译生成。代码示例请以原文为准。