市面上现在支持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会根据调用结果来回答你的问题,这才是一个完整的流程,网上很多都是只讲了第一步如何构建初始的请求。