岛屿可以找到海
岛屿可以找到海

记一次openAI通过FuncCall接入mcp的方法

市面上现在支持funcCall的模型越来多,各种个样的文档都说兼容openAI的用法却都没说具体怎么用的,openAI的文档说实话写的我是没看懂。

首先第一次请求需要在请求中构建出所有的工具,这个很简单,基本上文档都写了,如下是一个调用高德地图mcp的案例,可以看到tool_calls字段包含了所有高德mcp的工具方法。

{
	"messages": [{
		"content": "查询一下乌鲁木齐新市区的经纬度",
		"role": "user"
	}],
	"model": "gemini-2.5-pro",
	"stream": true,
	"temperature": 0.6,
	"tools": [{
			"type": "function",
			"function": {
				"name": "maps_regeocode",
				"description": "将一个高德经纬度坐标转换为行政区划地址信息",
				"parameters": {
					"type": "object",
					"properties": {
						"location": {
							"description": "经纬度",
							"type": "string"
						}
					},
					"required": [
						"location"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_geo",
				"description": "将详细的结构化地址转换为经纬度坐标。支持对地标性名胜景区、建筑物名称解析为经纬度坐标",
				"parameters": {
					"type": "object",
					"properties": {
						"address": {
							"description": "待解析的结构化地址信息",
							"type": "string"
						}
					},
					"required": [
						"address"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_ip_location",
				"description": "IP 定位根据用户输入的 IP 地址,定位 IP 的所在位置",
				"parameters": {
					"type": "object",
					"properties": {
						"ip": {
							"description": "IP地址",
							"type": "string"
						}
					},
					"required": [
						"ip"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_weather",
				"description": "根据城市名称或者标准adcode查询指定城市的天气",
				"parameters": {
					"type": "object",
					"properties": {
						"city": {
							"description": "城市名称或者adcode",
							"type": "string"
						}
					},
					"required": [
						"city"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_search_detail",
				"description": "查询关键词搜或者周边搜获取到的POI ID的详细信息",
				"parameters": {
					"type": "object",
					"properties": {
						"id": {
							"description": "关键词搜或者周边搜获取到的POI ID",
							"type": "string"
						}
					},
					"required": [
						"id"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_bicycling",
				"description": "骑行路径规划用于规划骑行通勤方案,规划时会考虑天桥、单行线、封路等情况。最大支持 500km 的骑行路线规划",
				"parameters": {
					"type": "object",
					"properties": {
						"destination": {
							"description": "目的地经纬度,坐标格式为:经度,纬度",
							"type": "string"
						},
						"origin": {
							"description": "出发点经纬度,坐标格式为:经度,纬度",
							"type": "string"
						}
					},
					"required": [
						"origin",
						"destination"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_direction_walking",
				"description": "步行路径规划 API 可以根据输入起点终点经纬度坐标规划100km 以内的步行通勤方案,并且返回通勤方案的数据",
				"parameters": {
					"type": "object",
					"properties": {
						"destination": {
							"description": "目的地经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						},
						"origin": {
							"description": "出发点经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						}
					},
					"required": [
						"origin",
						"destination"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_direction_driving",
				"description": "驾车路径规划 API 可以根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案,并且返回通勤方案的数据。",
				"parameters": {
					"type": "object",
					"properties": {
						"destination": {
							"description": "目的地经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						},
						"origin": {
							"description": "出发点经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						}
					},
					"required": [
						"origin",
						"destination"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_direction_transit_integrated",
				"description": "公交路径规划 API 可以根据用户起终点经纬度坐标规划综合各类公共(火车、公交、地铁)交通方式的通勤方案,并且返回通勤方案的数据,跨城场景下必须传起点城市与终点城市",
				"parameters": {
					"type": "object",
					"properties": {
						"city": {
							"description": "公共交通规划起点城市",
							"type": "string"
						},
						"cityd": {
							"description": "公共交通规划终点城市",
							"type": "string"
						},
						"destination": {
							"description": "目的地经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						},
						"origin": {
							"description": "出发点经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						}
					},
					"required": [
						"origin",
						"destination",
						"city",
						"cityd"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_distance",
				"description": "距离测量 API 可以测量两个经纬度坐标之间的距离,支持驾车、步行以及球面距离测量",
				"parameters": {
					"type": "object",
					"properties": {
						"destination": {
							"description": "终点经度,纬度,坐标格式为:经度,纬度",
							"type": "string"
						},
						"origins": {
							"description": "起点经度,纬度,可以传多个坐标,使用竖线隔离,比如120,30|120,31,坐标格式为:经度,纬度",
							"type": "string"
						}
					},
					"required": [
						"origins",
						"destination"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_text_search",
				"description": "关键词搜,根据用户传入关键词,搜索出相关的POI",
				"parameters": {
					"type": "object",
					"properties": {
						"keywords": {
							"description": "搜索关键词",
							"type": "string"
						}
					},
					"required": [
						"keywords"
					]
				}
			}
		},
		{
			"type": "function",
			"function": {
				"name": "maps_around_search",
				"description": "周边搜,根据用户传入关键词以及坐标location,搜索出radius半径范围的POI",
				"parameters": {
					"type": "object",
					"properties": {
						"location": {
							"description": "中心点经度纬度",
							"type": "string"
						}
					},
					"required": [
						"location"
					]
				}
			}
		}
	]
}

如上是第一次调用大模型时的结构,然后发出提问后,AI会根据tool_calls响应出适合调用的tool名称以及参数

比如:tool:maps_geo arguments:{“address”:”乌鲁木齐市新市区”}

然后你这边的llm应用再去调用相应的工具,而你需要把工具这边的响应内容、以及AI调用到tool和参数也添加到聊天记录中,就如同添加AI的回答到聊天记录中一样。

  {
   "content": "",
   "function_call": null,
   "role": "assistant",
   "tool_calls": [
    {
     "function": {
      "arguments": "{\"address\":\"乌鲁木齐市新市区\"}",
      "name": "maps_geo"
     },
     "id": "function-call-3593472046455991621",
     "index": 0,
     "type": "function"
    }
   ]
  },
  {
   "content": "{\n  \"return\": [\n    {\n      \"country\": \"中国\",\n      \"province\": \"新疆维吾尔自治区\",\n      \"city\": \"乌鲁木齐市\",\n      \"citycode\": \"0991\",\n      \"district\": \"新市区\",\n      \"street\": [],\n      \"number\": [],\n      \"adcode\": \"650104\",\n      \"location\": \"87.592684,43.893023\",\n      \"level\": \"区县\"\n    }\n  ]\n}",
   "name": "maps_geo",
   "role": "tool",
   "tool_call_id": "function-call-3593472046455991621"
  }

如上代码全部添加到messages数组中,构建为聊天记录的一部分,后续AI会根据调用结果来回答你的问题,这才是一个完整的流程,网上很多都是只讲了第一步如何构建初始的请求。

岛屿可以找到海

记一次openAI通过FuncCall接入mcp的方法
市面上现在支持funcCall的模型越来多,各种个样的文档都说兼容openAI的用法却都没说具体怎么用的,openAI的文档说实话写的我是没看懂。 首先第一次请求需要在请求中构建出所有的工具,…
扫描二维码继续阅读
2025-09-24