函数调用

让 AI 模型调用外部工具和 API,扩展能力边界

概述

Ling.AI 透传 OpenAI 兼容的工具调用能力。对于 /v1/chat/completions,请使用 toolstool_choiceparallel_tool_calls 等字段;模型需要调用工具时,会在回复中返回 tool_calls

计费提示

工具描述也会计入输入 Token。工具越多、描述越长,请求成本和延迟越高,建议只传当前问题所需的工具子集。

MCP

如果您已经有可直接复用的 MCP Server,且希望通过 Responses API 直接接入外部工具生态,请参考 MCP 指南。MCP 和函数调用都能扩展模型能力,但前者更偏向复用现成服务,后者更适合自定义本地工具。

Chat Completions

推荐使用 tools 数组定义函数。每个工具元素都采用 OpenAI 兼容格式:{"type":"function","function":{...}}

Python
from openai import OpenAI
import json

client = OpenAI(
    base_url="https://api.vip.lingapi.ai/v1",
    api_key="sk-xxxxxxxx"
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "查询指定城市的当前天气。",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,例如北京、上海。"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="qwen3.5-plus",
    messages=[
        {"role": "user", "content": "北京天气怎么样?"}
    ],
    tools=tools
)

message = response.choices[0].message
print(message.tool_calls)

tool_calls 响应

当模型决定调用工具时,返回消息中的 tool_calls 会包含函数名和参数字符串。

JSON
{
  "role": "assistant",
  "content": "",
  "tool_calls": [
    {
      "id": "call_123",
      "type": "function",
      "function": {
        "name": "get_current_weather",
        "arguments": "{\"location\":\"北京\"}"
      }
    }
  ]
}

完整流程

完整链路是“两次模型调用 + 一次或多次本地工具执行”:先让模型决定是否调用工具,再把工具输出以 role=tool 的消息补回上下文,让模型产出最终自然语言回复。

Python
from openai import OpenAI
import json

client = OpenAI(
    base_url="https://api.vip.lingapi.ai/v1",
    api_key="sk-xxxxxxxx"
)

def get_current_weather(location: str) -> str:
    return f"{location}今天多云。"

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "查询指定城市的当前天气。",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string"}
                },
                "required": ["location"]
            }
        }
    }
]

messages = [{"role": "user", "content": "北京天气怎么样?"}]

first = client.chat.completions.create(
    model="qwen3.5-plus",
    messages=messages,
    tools=tools
)

message = first.choices[0].message
messages.append(message)

if not message.tool_calls:
    print(message.content)
else:
    tool_call = message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)
    tool_result = get_current_weather(args["location"])

    messages.append({
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": tool_result
    })

    second = client.chat.completions.create(
        model="qwen3.5-plus",
        messages=messages,
        tools=tools
    )

    print(second.choices[0].message.content)

并行工具调用

如果多个工具调用之间互不依赖,可以开启 parallel_tool_calls,让模型在一次回复里返回多个 tool_calls

Python
response = client.chat.completions.create(
    model="qwen3.5-plus",
    messages=[
        {"role": "user", "content": "北京和上海的天气如何?"}
    ],
    tools=tools,
    parallel_tool_calls=True
)

Responses API

如果您使用 /v1/responses,工具定义和工具结果格式会有所不同:工具列表采用扁平格式,工具调用结果需要回传为 function_call_output

Python
from openai import OpenAI
import json

client = OpenAI(
    base_url="https://api.vip.lingapi.ai/v1",
    api_key="sk-xxxxxxxx"
)

tools = [
    {
        "type": "function",
        "name": "get_current_weather",
        "description": "查询指定城市的当前天气。",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {"type": "string"}
            },
            "required": ["location"]
        }
    }
]

conversation = [{"role": "user", "content": "北京天气怎么样?"}]
response = client.responses.create(
    model="qwen3.5-plus",
    input=conversation,
    tools=tools
)

function_calls = [item for item in response.output if item.type == "function_call"]
for call in function_calls:
    args = json.loads(call.arguments)
    tool_output = f"{args['location']}今天多云。"
    conversation.append({
        "type": "function_call",
        "name": call.name,
        "arguments": call.arguments,
        "call_id": call.call_id
    })
    conversation.append({
        "type": "function_call_output",
        "call_id": call.call_id,
        "output": tool_output
    })

final_response = client.responses.create(
    model="qwen3.5-plus",
    input=conversation,
    tools=tools
)

print(final_response.output_text)

流式工具调用

流式场景下,工具调用信息会分片出现在 delta.tool_calls 中,参数字符串需要按 index 进行拼接。详细 SSE 处理方式可配合 流式响应文档 使用。

最佳实践

  • 工具描述尽量精简,只保留当前问题需要的工具,避免无关工具拉高输入 Token。
  • 高风险写操作不要直接暴露给模型,建议由模型生成请求,再由人确认执行。
  • 如果工具之间存在依赖关系,请关闭并行工具调用,按串行方式逐步执行。
  • 若要查看主接口的字段定义,请同时参考 Chat 接口文档