For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主导航

在实时交互中使用工具

让实时语音智能体调用函数工具和远程 MCP 服务器。

您可以为 Realtime 会话添加工具,让模型在实时对话中查询数据、执行操作或调用服务。无论您的客户端使用 WebRTC 数据通道还是 WebSocket,工具配置都使用相同的事件接口。

如果应由您的应用执行工具并返回结果,请使用函数工具。如果应由 Realtime API 为您连接到远程工具服务器,请使用 MCP 工具。

选择工具类型

工具类型适用场景执行方
function您的应用负责业务逻辑、审批检查或私有系统访问。您的客户端或服务器接收函数调用并返回 function_call_output
搭配 server_url 使用的 mcp您希望模型调用远程 MCP 服务器提供的工具。Realtime API 调用远程 MCP 服务器。
搭配 connector_id 使用的 mcp您需要在现有模型中使用旧版内置连接器。Realtime API 使用您提供的授权调用连接器。

以下两个位置之一添加工具:

  • 如果您希望工具在整个会话中可用,请通过 session.update 中的 session.tools会话级别 添加工具。
  • 如果您只需要在一轮交互中使用工具,请通过 response.create 中的 response.tools响应级别 添加工具。

配置函数工具

如果工具需要在您的应用中运行,函数工具是合适的默认选择。模型输出函数调用参数,您的代码执行操作,然后通过 function_call_output 项将结果返回。

使用 session.update 配置函数工具
const event = {
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-2.1",
    tools: [
      {
        type: "function",
        name: "lookup_order",
        description: "Look up an order by its order number.",
        parameters: {
          type: "object",
          properties: {
            order_number: {
              type: "string",
              description: "The customer-facing order number.",
            },
          },
          required: ["order_number"],
        },
      },
    ],
    tool_choice: "auto",
  },
};

ws.send(JSON.stringify(event));

当模型调用函数时,监听函数调用项,运行您的应用逻辑,然后将输出返回:

发送函数调用输出
const event = {
  type: "conversation.item.create",
  item: {
    type: "function_call_output",
    call_id: functionCall.call_id,
    output: JSON.stringify({
      status: "shipped",
      delivery_date: "2026-05-09",
    }),
  },
};

ws.send(JSON.stringify(event));
ws.send(JSON.stringify({ type: "response.create" }));

如需按事件逐步了解函数调用的完整流程,请参阅管理对话

配置 MCP 工具

如果工具已由远程 MCP 服务器提供,或现有模型使用旧版内置连接器,MCP 工具就很适用。与函数工具不同,MCP 工具由 Realtime API 本身执行。

在 Realtime 中,MCP 工具的结构如下:

  • type: "mcp"
  • server_label
  • server_urlconnector_id,二选一
  • 可选的 authorizationheaders
  • 可选的 allowed_tools
  • 可选的 require_approval
  • 可选的 server_description

此示例让提供文档的 MCP 服务器在整个会话中可用:

使用 session.update 配置 MCP 工具
const event = {
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-2.1",
    output_modalities: ["text"],
    tools: [
      {
        type: "mcp",
        server_label: "openai_docs",
        server_url: "https://developers.openai.com/mcp",
        allowed_tools: ["search_openai_docs", "fetch_openai_doc"],
        require_approval: "never",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

旧版连接器

对于 2026 年 9 月 1 日之后发布的模型,connector_id 已弃用。 请使用 server_url 连接到远程 MCP 服务器,或使用 tunnel_id,通过 安全 MCP 隧道连接到本地 MCP 服务器。 现有模型仍支持连接器。以下示例使用 gpt-realtime-1.5,该模型在上述截止日期之前发布。

内置连接器使用相同的 MCP 工具结构,但传入的是 connector_id, 而不是 server_url。例如,Google Calendar 使用 connector_googlecalendar。在 Realtime 中,请使用这些内置连接器执行读取操作, 例如搜索或读取日历活动或电子邮件。通过 authorization 传入用户的 OAuth 访问 Token, 并尽可能使用 allowed_tools 限制可用工具的范围:

配置 Google Calendar 连接器
const event = {
  type: "session.update",
  session: {
    type: "realtime",
    model: "gpt-realtime-1.5",
    output_modalities: ["text"],
    tools: [
      {
        type: "mcp",
        server_label: "google_calendar",
        connector_id: "connector_googlecalendar",
        authorization: "<google-oauth-access-token>",
        allowed_tools: ["search_events", "read_event"],
        require_approval: "never",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

远程 MCP 服务器 不会自动接收完整的对话上下文, 但可以看到模型在工具调用中发送的任何数据。 使用 allowed_tools 限制可用工具的范围, 并对您不愿自动执行的任何操作要求审批。

Realtime MCP 流程

与 Realtime 的 function 工具不同,远程 MCP 工具 由 Realtime API 自身执行您的客户端不会运行远程工具 并返回 function_call_output,而是负责配置访问、监听 MCP 生命周期事件,以及在服务器要求审批时按需发送审批响应。

典型流程如下:

  1. 您发送 session.updateresponse.create,其中包含一个 typemcptools 条目。
  2. 服务器开始导入工具,并发出 mcp_list_tools.in_progress
  3. 在工具列表仍在加载时,模型无法调用尚未加载的工具。如果您希望等待工具加载后再开始依赖这些工具的一轮交互,请监听 mcp_list_tools.completeditem.typemcp_list_toolsconversation.item.done 事件会显示实际导入的工具名称。如果导入失败,您将收到 mcp_list_tools.failed
  4. 用户说话或发送文本后,由您的客户端创建响应,或根据会话配置自动创建响应。
  5. 如果模型选择了 MCP 工具,您将看到 response.mcp_call_arguments.deltaresponse.mcp_call_arguments.done
  6. 如果需要审批,服务器会添加一个 item.typemcp_approval_request 的对话项。您的客户端必须使用 mcp_approval_response 项回应。
  7. 工具开始运行后,您将看到 response.mcp_call.in_progress。如果执行成功,您随后会收到一个 item.typemcp_callresponse.output_item.done 事件;如果执行失败,您将收到 response.mcp_call.failed
  8. 某个响应的 response.done 可能会在其 MCP 调用完成之前到达。响应结束且其所有 MCP 调用均已完成后,请再发送一个 response.create 事件,让模型使用这些结果并继续对话。如果模型又发起了 MCP 调用,请重复此步骤。Realtime API 不会自动创建这些后续响应。

此事件处理程序会记录主要的 MCP 生命周期事件,但不管理后续响应:

在 Realtime 会话中监听 MCP 事件
function parseRealtimeEvent(rawMessage) {
  if (typeof rawMessage === "string") {
    return JSON.parse(rawMessage);
  }

  if (typeof rawMessage?.data === "string") {
    return JSON.parse(rawMessage.data);
  }

  return JSON.parse(rawMessage.toString());
}

function getOutputText(item) {
  if (item.type !== "message") return "";

  return (item.content ?? [])
    .filter((part) => part.type === "output_text")
    .map((part) => part.text)
    .join("");
}

ws.on("message", (rawMessage) => {
  const event = parseRealtimeEvent(rawMessage);

  switch (event.type) {
    case "mcp_list_tools.in_progress":
      console.log("Listing MCP tools for item:", event.item_id);
      break;

    case "mcp_list_tools.completed":
      console.log("MCP tool listing complete for item:", event.item_id);
      break;

    case "mcp_list_tools.failed":
      console.error("MCP tool listing failed for item:", event.item_id);
      break;

    case "conversation.item.done":
      if (event.item.type === "mcp_list_tools") {
        const names = event.item.tools.map((tool) => tool.name).join(", ");
        console.log(`MCP tools ready on ${event.item.server_label}: ${names}`);
      }

      if (event.item.type === "mcp_approval_request") {
        console.log(
          "Approval required for:",
          event.item.name,
          event.item.arguments
        );
      }
      break;

    case "response.mcp_call_arguments.done":
      console.log("Final MCP call arguments:", event.arguments);
      break;

    case "response.mcp_call.in_progress":
      console.log("Running MCP tool for item:", event.item_id);
      break;

    case "response.mcp_call.failed":
      console.error("MCP tool call failed for item:", event.item_id);
      break;

    case "response.output_item.done":
      if (event.item.type === "mcp_call") {
        console.log(
          `MCP output from ${event.item.server_label}.${event.item.name}:`,
          event.item.output
        );
      }

      if (event.item.type === "message") {
        console.log("Assistant:", getOutputText(event.item));
      }
      break;

    case "response.done":
      console.log("Realtime turn complete.");
      break;
  }
});

常见故障

  • mcp_list_tools.failed:Realtime API 无法从远程服务器或连接器导入工具。请检查 server_urlconnector_id、身份验证、服务器连接,以及您在 allowed_tools 中指定的所有工具名称。
  • response.mcp_call.failed:模型选择了工具,但工具调用未完成。请检查事件载荷和后续的 mcp_call 项,查看是否存在 MCP 协议、执行或传输错误。
  • mcp_approval_request 没有匹配的 mcp_approval_response:只有在您的客户端明确批准或拒绝后,工具调用才能继续。
  • mcp_list_tools.in_progress 仍处于活动状态时开始了一轮对话:该轮对话只能调用已完成加载的工具。
  • 响应使用了 tool_choice: "required",但当前没有可用工具:模型没有符合条件的工具可调用。请等待 mcp_list_tools.completed,确认至少已导入一个工具,或者为不需要工具的对话轮次使用其他 tool_choice 设置。
  • MCP 工具定义在开始导入前未通过验证:常见原因包括同一个 tools 数组中存在重复的 server_label、同时设置了 server_urlconnector_id、在初始会话创建请求中同时省略了这两项、使用了无效的 connector_id,或同时发送了 authorizationheaders.Authorization。对于连接器,请勿发送 headers.Authorization

批准或拒绝 MCP 工具调用

如果工具需要审批,Realtime API 会在对话中插入一个 mcp_approval_request 项。 要继续,请发送一个新的 conversation.item.create 事件,并将其 item.type 设为 mcp_approval_response

批准 MCP 请求
function approveMcpRequest(approvalRequestId) {
  const event = {
    type: "conversation.item.create",
    item: {
      id: `mcp_approval_${approvalRequestId}`,
      type: "mcp_approval_response",
      approval_request_id: approvalRequestId,
      approve: true,
    },
  };

  ws.send(JSON.stringify(event));
}

如果您拒绝该请求,请将 approve 设为 false,也可以附上 reason

仅为单个响应使用 MCP

如果 MCP 应 仅在单轮对话中可用,请将同一个 MCP 工具对象添加到 response.tools,而不是 session.tools

为单个响应添加 MCP 工具
const event = {
  type: "response.create",
  response: {
    output_modalities: ["text"],
    input: [
      {
        type: "message",
        role: "user",
        content: [
          {
            type: "input_text",
            text: "Which transport should I use for browser clients in the Realtime API?",
          },
        ],
      },
    ],
    tools: [
      {
        type: "mcp",
        server_label: "openai_docs",
        server_url: "https://developers.openai.com/mcp",
        allowed_tools: ["search_openai_docs", "fetch_openai_doc"],
        require_approval: "never",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

当只有一个响应需要外部上下文,或不同轮次的对话应使用不同的 MCP 服务器时,这种方式很有用。

复用先前定义的服务器标签

server_label 是当前 Realtime 会话中工具定义的固定句柄。 使用 server_label 加上 server_urlconnector_id 定义一次服务器或连接器后, 后续的 session.updateresponse.create 事件只需引用同一个 server_label, Realtime API 就会复用先前的定义, 无需您再次发送完整的工具对象。

复用先前定义的连接器
const event = {
  type: "response.create",
  response: {
    output_modalities: ["text"],
    input: [
      {
        type: "message",
        role: "user",
        content: [
          {
            type: "input_text",
            text: "Check my schedule for this afternoon.",
          },
        ],
      },
    ],
    // Reuses the google_calendar connector defined earlier in this session.
    tools: [
      {
        type: "mcp",
        server_label: "google_calendar",
      },
    ],
  },
};

ws.send(JSON.stringify(event));

这种复用仅限于当前会话。如果您启动新的 Realtime 会话,请再次发送 完整的 MCP 定义,以便服务器导入其工具列表。