OpenAI Responses API教程:调用MCP工具

本教程面向有编程基础的开发者,深入讲解如何在OpenAI Responses API中集成MCP(模型上下文协议)工具。内容涵盖MCP工具的基本配置、调用流程、参数说明、错误处理及最佳实践,并重点分析了工具列表缓存、allowed_tools过滤、推理模型选择等高级优化策略。通过实际案例(如价格分析代理)展示MCP与内置工具(如代码解释器、网络搜索)的组合使用,帮助开发者构建高效、可扩展的AI应用。

技术背景

构建智能体应用时,通常需要连接外部服务(如数据库、电商平台、监控系统等)。传统函数调用方式要求为每个操作编写自定义包装器,并在模型、后端和外部服务之间进行多次网络往返,导致延迟高、代码冗余、难以维护。MCP(模型上下文协议)提供了一种标准化接口,允许模型直接与远程MCP服务器通信,服务器集中管理工具列表,模型通过一次配置即可调用多个工具,显著降低集成复杂度和延迟。适用场景包括电商购物车操作、支付链接生成、DevOps监控、消息通知等。主要限制包括:MCP仍处于早期阶段,工具列表可能庞大导致token开销,需要谨慎管理;服务器稳定性影响响应;需要处理工具调用审批流程。

核心原理

MCP工具的核心原理是:在API请求的tools数组中声明MCP服务器,运行时自动检测传输协议(可流式HTTP或SSE),调用服务器的tools/list获取工具列表,并将其作为mcp_list_tools项注入模型上下文。模型根据工具描述决定调用哪个工具,每次调用产生mcp_tool_call项,默认需要用户批准(可通过require_approval禁用)。批准后,运行时执行调用,流式返回结果,模型可继续调用其他工具或生成最终答案。关键设计决策包括:工具列表缓存(只要mcp_list_tools项存在,不重复获取),allowed_tools过滤以减少token,以及支持与内置工具(如code_interpreter、web_search_preview)组合使用。

架构分析

系统架构采用客户端-服务器模式:客户端(Responses API)作为模型与MCP服务器之间的中介。MCP服务器是独立的远程服务,暴露标准化的工具列表(tools/list)和工具调用端点。Responses API运行时负责协议适配、工具列表缓存、审批流程和结果流式返回。组件关系:模型通过API请求中的tools数组声明MCP服务器,运行时与服务器通信,将工具列表注入上下文,模型决策调用,运行时执行并返回结果。设计思想是集中式工具管理,减少后端协调,通过缓存和过滤优化性能。

完整实战教程

简介

MCP(模型上下文协议)工具允许你通过标准化的接口将外部工具集成到Responses API中。本指南将帮助你理解如何配置和使用这些工具。

前提条件

配置MCP工具

要使用MCP工具,你需要在API请求中指定工具定义。以下是一个示例:

{
"tools": [
{
"type": "mcp",
"name": "my_tool",
"url": "https://example.com/mcp"
}
]
}

调用MCP工具

在对话中,模型可以决定调用MCP工具。当模型调用工具时,API会返回一个工具调用响应,你需要执行工具并将结果返回给API。

示例请求

{
"model": "gpt-4",
"messages": [
{"role": "user", "content": "使用我的工具查询天气"}
],
"tools": [
{
"type": "mcp",
"name": "weather_tool",
"url": "https://example.com/weather"
}
]
}

处理工具调用

当API返回工具调用时,你会收到类似下面的响应:

{
"tool_calls": [
{
"id": "call_123",
"name": "weather_tool",
"arguments": {"location": "北京"}
}
]
}

你需要执行工具,然后将结果作为消息发送回API。

参数说明

错误处理

如果工具调用失败,你可以返回错误信息,模型会据此调整响应。

最佳实践

完整示例

以下是一个完整的Python示例,演示如何使用MCP工具:

import requests

# 定义工具
tools = [
    {
        "type": "mcp",
        "name": "weather_tool",
        "url": "https://example.com/weather"
    }
]

# 发送请求
response = requests.post(
    "https://api.openai.com/v1/responses",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "model": "gpt-4",
        "messages": [{"role": "user", "content": "北京天气如何?"}],
        "tools": tools
    }
)

# 处理响应
if response.status_code == 200:
    data = response.json()
    if "tool_calls" in data:
        for call in data["tool_calls"]:
            # 执行工具并返回结果
            result = execute_tool(call["name"], call["arguments"])
            # 将结果发送回API
            # ...

结论

通过MCP工具,你可以轻松扩展Responses API的功能。遵循本指南,你可以快速集成自定义工具,实现更复杂的AI应用。

构建智能体应用通常需要连接外部服务。传统上,这是通过函数调用实现的,其中每个操作都会在模型、后端和外部服务之间进行往返,等待响应,最后将结果返回给模型。这个过程引入了多次网络跳转和显著的延迟,使得扩展和管理变得繁琐。

Responses API 中托管的模型上下文协议(MCP)工具使这变得更加容易。无需手动将每个函数调用连接到特定服务,您可以配置模型一次以指向一个 MCP 服务器(或多个!)。该服务器充当集中式工具主机,公开标准命令,如“搜索产品目录”或“将商品添加到购物车”。这允许更简单的编排和集中式工具管理。借助 MCP,模型直接与 MCP 服务器交互,减少延迟并消除后端协调。

MCP 工具简化的用例

MCP 显著降低了构建与外部服务交互的产品的摩擦,使您能够无缝地将不同的服务连接在一起。以下是一些用例示例,这些用例曾经涉及摩擦,但现在由于模型可以直接与远程 MCP 服务器通信而变得更加简单。

| 领域 | MCP 工具解锁的用例 | 之前的摩擦 |

|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|

| 商业/支付 | - 将商品添加到 Shopify 购物车并在一次交互中返回结账链接——"添加 Allbirds Men's Tree Dasher 2,尺码 10" → 购物车链接 <br> - 生成 Stripe 支付链接 | 函数调用意味着您必须编写自定义的 cart_add 或 create_payment_link 包装器,并托管自己的中继服务器。 |

| 开发运维与代码质量| - 向 Sentry 询问特定文件中的最新错误,然后在同一对话中打开一个带有建议修复的 GitHub issue | 在辅助循环中链接两个不同的第三方 API 涉及 webhook 粘合和状态管理。 |

| 消息/通知 | - 通过网页搜索获取早晨的热门足球头条,并在一次调用中让 Twilio 将摘要发送到电话号码 | 需要在您的后端拼接两个工具调用,并自己批量处理最终的 SMS 负载。 |

工具的工作原理

从高层来看,MCP 工具的工作方式如下:

  1. 声明服务器:当你在 tools 数组中添加一个 MCP 块时,Responses API 运行时首先会检测服务器使用哪种传输协议,是较新的“可流式 HTTP”还是较旧的基于 SSE 的 HTTP 变体,并使用该协议进行通信。
  2. 导入工具列表:运行时调用服务器的 tools/list,并传递你提供的任何请求头(API 密钥、OAuth 令牌等)。然后,它会将结果写入模型上下文中的一个 mcp_list_tools 项。只要该项存在,就不会再次获取列表。你可以使用 allowed_tools 来限制模型可以看到的内容。

OpenAI 在每次请求后会丢弃请求头值以及 MCP server_url 中除 schema、域名和子域名之外的所有内容。授权密钥和服务器 URL 必须包含在每次 API 调用中。这些值不会出现在响应对象中。Schema 在可能的情况下使用“严格”模式,否则将按原样加载。

  1. 调用和批准工具:一旦模型知道可用的操作,它就可以调用其中一个。每次调用都会产生一个 mcp_tool_call 项,默认情况下,流会暂停等待你的明确批准,但一旦你信任该服务器,就可以禁用此功能。

批准后,运行时执行调用,流式返回结果,模型决定是链接另一个工具还是返回最终答案。

使用 MCP 构建时的最佳实践

MCP 仍处于早期阶段,因此以下最佳实践可以在构建时提高模型性能和表现。

过滤工具以避免负载膨胀

远程服务器通常会暴露大量工具,而不考虑模型将如何解释和使用它们。默认情况下,这可能导致包含数十个端点,每个端点都附带冗长的定义,如名称、描述和 JSON 模式,这些都会向模型的上下文添加数百个 token 并增加延迟。更糟糕的是,许多服务器会返回整个数据对象,例如完整的 Stripe 发票记录,即使只有几个字段与模型的任务相关。为了在生产环境中优化性能,请在 Responses API 中使用 allowed_tools 参数来限制服务器 mcp_list_tools 中包含的工具。这可以减少 token 开销,缩短响应时间,并缩小模型的决策空间。您可能还想完全排除某些工具,例如那些能够执行写入操作或具有财务或安全影响的工具。

curl https://api.openai.com/v1/responses -i \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4.1",
    "tools": [
        {
            "type": "mcp",
            "server_label": "gitmcp",
            "server_url": "https://gitmcp.io/openai/tiktoken",
            "allowed_tools": ["search_tiktoken_documentation", "fetch_tiktoken_documentation"],
            "require_approval": "never"
        }
    ],
    "input": "how does tiktoken work?"
}'

通过缓存和保留推理模型用于高复杂度任务来降低延迟和令牌数

模型首次连接到服务器时,会为每个添加的 MCP 服务器创建一个类型为 mcp_list_tools 的新项目。只要该项目存在于模型的上下文中,我们就不会再次调用服务器上的 tools/list。这类似于用户对话级别的缓存。如果 mcp_list_tools 不存在,我们会再次从 MCP 服务器导入工具列表。在后续 API 请求中传递 previous_response_id 是确保在后续轮次中 mcp_list_tools 项目存在于模型上下文中的一种方式。或者,你也可以手动将项目传递给新的响应。另一个影响延迟和输出令牌数的杠杆是是否使用推理模型,因为推理模型会产生更多的输出令牌以及推理令牌。例如,以下两个示例 curl 比较了使用和不使用推理模型时产生的令牌数:

场景 1:非推理模型

curl https://api.openai.com/v1/responses \   
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4.1",
    "tools": [
      {
        "type": "mcp",
        "server_label": "gitmcp",
        "server_url": "https://gitmcp.io/openai/tiktoken",
        "require_approval": "never"
      }
    ],
    "input": "how does tiktoken work?" 
  }'
  "usage": {
    "input_tokens": 280,
    "input_tokens_details": {
      "cached_tokens": 0
    },
    "output_tokens": 665,
    "output_tokens_details": {
      "reasoning_tokens": 0
    },
    "total_tokens": 945
  }

场景2:没有 previous_response_id 的推理模型

curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "o4-mini",
    "tools": [
      {
        "type": "mcp",
        "server_label": "gitmcp",
        "server_url": "https://gitmcp.io/openai/tiktoken",
        "require_approval": "never"
      }
    ],
    "input": "how does tiktoken work?",
    "reasoning": {
      "effort": "medium",
      "summary": "auto"
    } 
  }'
  "usage": {
    "input_tokens": 36436,
    "input_tokens_details": {
      "cached_tokens": 22964
    },
    "output_tokens": 1586,
    "output_tokens_details": {
      "reasoning_tokens": 576
    },
    "total_tokens": 38022 
    }

将 MCP 与其他工具结合使用

MCP 工具只是工具数组中的另一个条目,因此模型可以将其与 code_interpreter、web_search_preview 或 image_generation 等托管工具以及您定义的任何自定义工具无缝结合使用。您还可以同时使用多个远程 MCP 服务器。

在此示例中,我们将创建一个代理,作为一家虚构瑜伽服装店的价格分析师:它首先从 Alo Yoga MCP 服务器获取当前竞争对手的女式短裤、瑜伽裤和背心价格,然后通过托管的网络搜索工具获取优衣库相同三个类别的价格。使用代码解释器,它分析通过 Files 端点预加载的 CSV 中上周的销售数据,以计算每件商品的收入和平均订单价值。然后,它衡量每个商品与最新获取的优衣库和 Alo Yoga 基准价格之间的价格差距。任何价格高于或低于市场 15% 或以上的产品都会被标记,代理会提供一份简洁的文本报告,总结差异和关键收入统计数据。

system_prompt= """You are a pricing analyst for my clothing company. Please use the MCP tool 
to fetch prices from the Alo Yoga MCP server for the categories of women's 
shorts, yoga pants, and  tank tops. Use only the MCP server for Alo yoga data, don't search the web. 

Next, use the web search tool to search for Uniqlo prices for women's shorts, yoga pants, and tank tops. 

In each case for Alo Yoga and Uniqlo, extract the
price for the top result in each category. Also provide the full URLs
 
Using the uploaded CSV file of sales data from my store, and with the 
code interpreter tool calculate revenue by product item, compute average order-value on a transaction level, and calculate the percentage price gap between the CSV data and Uniqlo/Alo Yoga prices. 
Flag products priced 15% or more above or below the market. 
Create and output a short report including the findings.

# Steps

1. **Fetch Alo Yoga Prices:**
   - Use the Alo Yoga MCP server to fetch prices for the following products:
High-Waist Airlift Legging
Sway Bra Tank
 5" Airlift Energy Short

- Ensure you find prices for each. 
- Extract the price of the top result for each category.
- include  URL links 


2. **Query Uniqlo Prices:**
   - Use the Web-Search tool to search non-sale prices for the following Uniqlo products: 
Women's AIRism Soft Biker Shorts
Women's AIRism Soft Leggings
Women's AIRism Bra Sleeveless Top
- Ensure you find non-sale prices for each. 
- Extract the price for the top result in each category.
- include  URL links 

3. **Sales Data Analysis:**
   - Use the uploaded CSV sales data to calculate revenue across each 
   product item.
   - Determine the average order-value on a transaction level.
   - For each SKU, compute the percentage price gap between the 
   CSV data and Uniqlo/Alo Yoga prices.
   - Flag products priced ≥ 15% above or below the market.

4. **Report:**
   - Compile and output a report including the flagging results

# Output Format
- A short text report explaining:
  - Any products that are priced ≥ 15% above or below the market, 
  with specific details. """

以下是一个示例 curl,其中包含上述系统提示的占位符。

curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4.1",
    "input": [
      {
        "role": "system",
        "content": [
          {
            "type": "input_text",
            "text": "ABOVE_SYSTEM_PROMPT"
          }
        ]
      }
    ],
    "tools": [
      {
        "type": "web_search_preview",
        "user_location": {
          "type": "approximate",
          "country": "US"
        },
        "search_context_size": "medium"
      },
      {
        "type": "code_interpreter",
        "container": {
          "type": "auto",
          "file_ids": [
            "file-WTiyGcZySaU6n218gj4XxR"
          ]
        }
      },
      {
        "type": "mcp",
        "server_url": "https://www.aloyoga.com/api/mcp",
        "server_label": "aloyoga",
        "allowed_tools": [
          "search_shop_catalog",
          "get_product_details"
        ],
        "require_approval": "never"
      }
    ],
    "temperature": 1,
    "max_output_tokens": 2048,
    "top_p": 1,
    "store": true
  }'

模型能够将其从 MCP 工具和网络搜索中获得的结果延续到代码解释器步骤中,以生成一份内容如下、格式清晰易读的报告:

您的商店销售与价格分析

与市场的定价差距

| 类别 | 商店平均价格 | 与 Alo Yoga 的差距 (%) | 标记(≥15%) | 与优衣库的差距 (%) | 标记(≥15%) |

| --- | --- | --- | --- | --- | --- |

| 短裤 | $60.00 | -31.8% | 是 | +100.7% | 是 |

| 背心 | $75.00 | -14.8% | | +114.9% | 是 |

| 瑜伽裤 | $110.00 | -14.1% | | +267.9% | 是 |

建议与标记

标记的产品(价格差距≥15%):

短裤的定价显著低于高端竞争对手(Alo Yoga),但远高于平价替代品(优衣库)。如果您想在高端市场竞争,可以考虑提高价格。如果您想瞄准预算型买家,降价也是合理的。您的多数背心和瑜伽裤定位类似——远低于 Alo,但远高于优衣库。

___

改进 MCP 工具调用的提示指南

根据您的使用场景,您可能会发现模型会调用许多 MCP 调用,例如在使用目录搜索工具时。为了避免对大型产品库存进行无休止的迭代,建议指示模型将其搜索限制为 N 个项目,并且仅在用户明确要求更多信息时才提供继续。这使响应保持专注和快速。

如果您使用的 MCP 服务器包含详尽的 mcp_list_tools,那么还值得包含一些有针对性的少样本示例,以展示模型如何选择正确的服务器并在获得所需内容后停止,而不是发出冗余调用。

最后,添加指导以提醒模型,如果用户查询中缺少关键信息(尺寸、颜色、产品线等),它应该提出后续问题,而不是发起广泛搜索。这个小的提示调整可以减少不必要的工具调用并提高答案质量。以下是一个示例提示,展示了这些指南如何组合在一起:

system_prompt= """You are an AI assistant that can call the following MCP servers:

1. allbirds_store
2. gitmcp

Steps
1. Use the MCP servers above to answer the user query, not every MCP server will relevant for a given query so you can choose which ones to invoke.  
2. If the user’s request lacks essential details (size, color, etc.), ask a follow-up question first rather than guessing and using the MCP server tool prematurely. 
3. If searching for products in a catalog, only return 4 results at a time before asking the user whether they want to see more. 

### Few-shot examples

# EX1 — Direct product search, then fetch variant details
user: Do you have the Allbirds Tree Runner in men’s size 10?  
assistant: {"name":"allbirds_store.search_shop_catalog",
            "arguments":{"query":"Tree Runner",
                         "context":"Men’s size 10 shoes"}}
# (assume the search returns product_id "gid://shopify/Product/987")  
assistant: {"name":"allbirds_store.get_product_details",
            "arguments":{"product_id":"gid://shopify/Product/987",
                         "options":{"Size":"10"}}}

# EX2 — Clarify missing size, then two-step color variant lookup
user: I want the Tree Runner in blue.  
assistant: Sure — what size do you need?  
user: Size 10.  
assistant: {"name":"allbirds_store.search_shop_catalog",
            "arguments":{"query":"Tree Runner",
                         "context":"Blue variant, size 10"}}
# (assume the search returns product_id "gid://shopify/Product/987")  
assistant: {"name":"allbirds_store.get_product_details",
            "arguments":{"product_id":"gid://shopify/Product/987",
                         "options":{"Size":"10","Color":"Blue"}}}

# EX3 — Git docs: search then fetch specific file
user: Can you show me how tiktoken does byte-pair encoding?  
assistant: {"name":"gitmcp.search_website_documentation",
            "arguments":{"query":"tiktoken byte-pair encoding"}}
# (assume the search returns document_id "docs/ENCODING.md")  
assistant: {"name":"gitmcp.fetch_website_documentation",
            "arguments":{"document_id":"docs/ENCODING.md"}} """
curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4.1",
    "input": [
      {
        "role": "system",
        "content": [
          {
            "type": "input_text",
            "text": "ABOVE_SYSTEM_PROMPT"
          }
        ]
      },
      {
        "role": "user",
        "content": [
          {
            "type": "input_text",
            "text": "find me womens tree loungers in size 8"
          }
        ]
      }
    ],
    "tools": [
      {
        "type": "mcp",
        "server_url": "https://www.allbirds.com/api/mcp",
        "server_label": "allbirds",
        "allowed_tools": [
          "search_shop_catalog",
          "get_cart",
          "update_cart",
          "search_shop_policies_and_faqs",
          "get_product_details"
        ],
        "require_approval": "never"
      },
      {
        "type": "mcp",
        "server_label": "gitmcp",
        "server_url": "https://gitmcp.io/openai/tiktoken",
        "allowed_tools": [
          "fetch_tiktoken_documentation",
          "search_tiktoken_documentation",
          "search_tiktoken_code",
          "fetch_generic_url_content"
        ],
        "require_approval": "never"
      }
    ],
    "temperature": 1,
    "max_output_tokens": 2048
  }'

结论

托管式 MCP 工具通过 Responses API 使外部服务可用。连接远程服务器并让运行时缓存其工具列表,可避免在应用程序代码中管理该网络跳转。使用 allowed_tools 可以减少 token 开销,并为模型提供简洁、可发现的操作集。你可以将 MCP 与内置工具(如 code_interpreter、web_search_preview 或 image_gen)结合使用,以实现多服务工作流。

常见问题

常见错误及排查方法:1. 工具调用失败:检查MCP服务器URL是否可访问,认证头是否正确,服务器是否支持所需协议。2. 工具列表未加载:确认mcp_list_tools项是否在上下文中,若不存在,检查是否传递了previous_response_id或手动添加。3. token开销过大:使用allowed_tools过滤工具,避免加载不必要的大对象。4. 模型未调用工具:检查工具描述是否清晰,或提供少样本示例。5. 审批流程卡住:设置require_approval为never(信任服务器后)。生产环境优化:使用缓存减少重复获取工具列表;选择非推理模型降低token消耗;对工具调用设置超时和重试机制;监控MCP服务器稳定性。

企业应用扩展

进一步优化:1. 结合函数调用与MCP,实现混合工具集成。2. 使用多个MCP服务器,通过server_label区分。3. 利用流式响应实时处理工具结果。4. 实现自定义MCP服务器,扩展工具集。5. 结合向量数据库,实现基于语义的工具选择。6. 使用缓存策略(如Redis)存储工具列表,减少API调用。7. 设计工具调用链,实现复杂工作流。8. 监控工具调用频率,进行成本控制。

总结

本教程面向有编程基础的开发者,深入讲解如何在OpenAI Responses API中集成MCP(模型上下文协议)工具。内容涵盖MCP工具的基本配置、调用流程、参数说明、错误处理及最佳实践,并重点分析了工具列表缓存、allowed_tools过滤、推理模型选择等高级优化策略。通过实际案例(如价格分析代理)展示MCP与内置工具(如代码解释器、网络搜索)的组合使用,帮助开发者构建高效、可扩展的AI应用。

内容来源与验证

继续系统学习

站内还有更多完整实战教程

加入会员,解锁全部教程、完整代码与持续更新内容。

加入会员
查看全部AI 智能体教程