主题模式
工具调用
工具调用介绍
工具调用(Function/Tool Calling)让大模型按既定接口规范与外部系统交互:当模型判断需要调用某工具时,会严格按 JSON Schema 生成结构化参数,客户端执行工具并把结果返回给模型,完成复杂任务编排与系统集成。
功能特性
- 结构化参数生成:基于 JSON Schema,生成可直接调用的函数参数。
- 多工具并行/串行:根据模型判断可一次返回多个工具调用或分步调用。
- 可控执行:支持“自动选择工具”“强制指定某工具”或关闭工具。
- 通用协议:AIPing 支持 OpenAI 格式与 Anthropic 格式的工具定义与调用,支持接入 Claude Code、Codex、Cursor 等外部编程工具。
工具调用参数(OpenAI 格式)
请求参数说明
工具调用请求中的关键字段:
- 端点:https://aiping.cn/api/v1
- messages:对话消息数组。
- tools:工具列表。每个工具为
{"type":"function","function":{name, description, parameters}}。 - tool_choice:
"auto":自动选择是否与哪个工具。"required":强制模型必须调用至少一个工具。"none":禁用工具。{"type":"function","function":{"name":"xxx"}}:强制使用指定函数。
响应参数说明
核心响应参数说明:
choices[].message.content:模型自然语言回答。choices[].message.tool_calls:工具调用数组。choices[].finish_reason:结束原因。id, created, usage:请求元数据与令牌统计。
工具调用参数(Anthropic 格式)
核心参数说明
- 端点:https://aiping.cn/api/v1/anthropic
注:AIPing 当前仅支持部分模型使用 Anthropic 格式端点,查询方式见《查询 Anthropic 端点可用模型》一节。推荐使用 "minimax-m2" 和 "glm-4.6",以下文档示例以 "minimax-m2" 为例。
- messages:对话消息数组。
- tools:工具列表,每个工具为
{name, description, input_schema}。 - input_schema 使用 JSON Schema。
- 其他通用生成参数:model, max_tokens, temperature, system 等。
响应参数说明
content[]:响应内容块数组,块类型可能为:{"type":"text","text":"..."}:自然语言文本。{"type":"tool_use","id":"...","name":"...","input":{...}}:工具调用。
- stop_reason:结束原因(如达到 tokens、需要工具结果继续等)。
- id, usage:请求元数据与令牌统计。
查询 Anthropic 端点可用模型
AIPing 的 Anthropic 端点提供了兼容 Anthropic API 的模型查询端点,允许用户查看当前可用的 Anthropic 兼容模型列表。
请求示例
bash
curl -X GET "https://aiping.cn/api/v1/anthropic/v1/models" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"响应格式
成功响应返回 JSON 格式数据:
json
{
"data": [
{
"id": "DeepSeek-V3.1",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "DeepSeek-V3.1",
"type": "model"
},
{
"id": "DeepSeek-V3.2-Exp",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "DeepSeek-V3.2-Exp",
"type": "model"
},
{
"id": "GLM-4.5",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "GLM-4.5",
"type": "model"
},
{
"id": "GLM-4.5-Air",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "GLM-4.5-Air",
"type": "model"
},
{
"id": "GLM-4.6",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "GLM-4.6",
"type": "model"
},
{
"id": "Kimi-K2-Instruct",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "Kimi-K2-Instruct",
"type": "model"
},
{
"id": "Kimi-K2-Thinking",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "Kimi-K2-Thinking",
"type": "model"
},
{
"id": "MiniMax-M2",
"created_at": "1970-01-01T00:00:00Z",
"display_name": "MiniMax-M2",
"type": "model"
}
],
"first_id": "DeepSeek-V3.1",
"has_more": false,
"last_id": "MiniMax-M2"
}获取单个模型详情
除了查询模型列表,还可以获取特定模型的详细信息:
bash
GET /v1/anthropic/v1/models/{model_id}如果模型不存在或不在允许列表中,将返回 404 错误。
在各类工具中使用 AIPing
下面介绍在各类工具中使用 AIPing ,见在各类场景中使用 AiPing
示例代码
OpenAI 格式工具调用
python
#!/usr/bin/env python3
import os
import sys
import json
from openai import OpenAI
# 定义工具
def search_books(search_terms):
query = " ".join(search_terms).lower()
catalog = [
{"id": 4300, "title": "Ulysses", "authors": [{"name": "Joyce, James"}]},
{"id": 2814, "title": "Dubliners", "authors": [{"name": "Joyce, James"}]},
{"id": 4217, "title": "A Portrait of the Artist as a Young Man", "authors": [{"name": "Joyce, James"}]},
{"id": 766, "title": "Chamber Music", "authors": [{"name": "Joyce, James"}]},
]
if "joyce" in query or "乔伊斯" in query:
return catalog
return []
def main() -> int:
base_url = os.getenv("BASE_URL", "https://aiping.cn/api/v1")
api_key = os.getenv("API_KEY", "<YOUR_AIPING_KEY>")
client = OpenAI(base_url=base_url, api_key=api_key)
tools = [
{
"type": "function",
"function": {
"name": "search_books",
"description": "根据关键词检索本地书目(静态样例)",
"parameters": {
"type": "object",
"properties": {
"search_terms": {
"type": "array",
"items": {"type": "string"},
"description": "检索关键词列表"
}
},
"required": ["search_terms"],
"additionalProperties": False,
},
},
}
]
messages = [
{"role": "user", "content": "乔伊斯的书名有哪些?请列出标题。"}
]
# 请求携带 tools
first = client.chat.completions.create(
model="MiniMax-M2",
messages=messages,
tools=tools,
tool_choice={"type": "function", "function": {"name": "search_books"}},
max_tokens=2048,
)
choice = first.choices[0]
if not choice.message.tool_calls:
print("[ERROR] model did not return tool_calls", file=sys.stderr)
return 3
assistant_tool_calls = [
{
"id": tc.id,
"type": "function",
"function": {
"name": tc.function.name,
"arguments": tc.function.arguments,
},
}
for tc in (choice.message.tool_calls or [])
]
messages.append({
"role": "assistant",
"content": None,
"tool_calls": assistant_tool_calls,
})
# 执行工具并附加 tool 结果
for tc in (choice.message.tool_calls or []):
args = json.loads(tc.function.arguments or "{}")
res = search_books(args.get("search_terms", []))
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": json.dumps(res, ensure_ascii=False),
})
# 把工具结果交回模型
second = client.chat.completions.create(
model="MiniMax-M2",
messages=messages,
tools=tools,
max_tokens=2048,
)
final_text = (second.choices[0].message.content or "").strip()
print({"model": second.model, "final_text": final_text})
return 0
if __name__ == "__main__":
raise SystemExit(main())Anthropic 格式工具调用
python
#!/usr/bin/env python3
import os
import sys
import json
import requests
# 定义工具
def search_books(search_terms):
query = " ".join(search_terms).lower()
catalog = [
{"id": 4300, "title": "Ulysses", "authors": [{"name": "Joyce, James"}]},
{"id": 2814, "title": "Dubliners", "authors": [{"name": "Joyce, James"}]},
{"id": 4217, "title": "A Portrait of the Artist as a Young Man", "authors": [{"name": "Joyce, James"}]},
{"id": 766, "title": "Chamber Music", "authors": [{"name": "Joyce, James"}]},
]
if "joyce" in query or "乔伊斯" in query:
return catalog
return []
def main() -> int:
base_url = os.getenv("BASE_URL", "https://aiping.cn/api/v1/anthropic")
api_key = os.getenv("API_KEY", "<YOUR_AIPING_KEY>")
url = f"{base_url}/v1/messages"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
tools = [
{
"name": "search_books",
"description": "根据关键词检索本地书目(静态样例)",
"input_schema": {
"type": "object",
"properties": {
"search_terms": {
"type": "array",
"items": {"type": "string"},
"description": "检索关键词列表"
}
},
"required": ["search_terms"],
"additionalProperties": False,
},
}
]
messages = [
{
"role": "user",
"content": [{
"type": "text",
"text": (
"请严格按照以下要求完成:\n"
"1) 必须调用工具 search_books,并使用参数 search_terms=['Joyce'] 或 ['乔伊斯'];\n"
"2) 获取结果后,仅输出书名列表(中文名可选)。\n"
"注意:不调用工具请不要直接回答。"
)
}]
}
]
r1 = requests.post(
url,
headers=headers,
data=json.dumps({
"model": "MiniMax-M2",
"max_tokens": 2048,
"tools": tools,
"messages": messages,
}),
timeout=60,
)
r1.raise_for_status()
data1 = r1.json()
tool_use_block = None
for block in data1.get("content", []) or []:
if block.get("type") == "tool_use" and block.get("name") == "search_books":
tool_use_block = block
break
if not tool_use_block:
texts = []
for b in data1.get("content", []) or []:
if b.get("type") == "text" and "text" in b:
texts.append(b["text"])
final_text = "".join(texts).strip()
print({"model": data1.get("model"), "final_text": final_text})
return 0
args = tool_use_block.get("input", {})
result = search_books(args.get("search_terms", []))
# 把上轮 assistant 的 tool_use 原样带回,再追加 user 的 tool_result
messages2 = [
messages[0],
{"role": "assistant", "content": [tool_use_block]},
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": tool_use_block["id"],
"content": json.dumps(result, ensure_ascii=False),
}],
},
]
r2 = requests.post(
url,
headers=headers,
data=json.dumps({
"model": "MiniMax-M2",
"max_tokens": 2048,
"tools": tools,
"messages": messages2,
}),
timeout=60,
)
r2.raise_for_status()
data2 = r2.json()
texts = []
for b in data2.get("content", []) or []:
if b.get("type") == "text" and "text" in b:
texts.append(b["text"])
final_text = "".join(texts).strip()
print({"model": data2.get("model"), "final_text": final_text})
return 0
if __name__ == "__main__":
raise SystemExit(main())