Appearance
工具调用(Tool Calling)让 LLM 可以请求调用外部函数。OpenRouter 统一了跨模型的工具调用接口,分三步完成:首先发送带工具定义的请求,模型返回工具调用建议,然后你执行工具并将结果返回给模型,最后模型生成最终回复。工具不会由模型直接执行,而是由你的代码负责调用。
OpenRouter 工具调用(Tool Calling)
工具调用(也叫函数调用)让 LLM 可以"请求"使用外部工具。LLM 不会直接调用工具——它只是建议应该调用哪个工具和传入什么参数,实际调用由你的代码完成。
通过 openrouter.ai/models?supported_parameters=tools 查看支持工具调用的模型。
三步工作流程
第一步:带工具定义的推理请求
在请求中定义可用工具:
json
{
"model": "openai/gpt-4o",
"messages": [
{ "role": "user", "content": "What is the weather in San Francisco?" }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g. San Francisco"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
}
]
}第二步:模型返回工具调用建议
当模型决定需要调用工具时,响应的 finish_reason 为 "tool_calls":
json
{
"choices": [{
"message": {
"role": "assistant",
"tool_calls": [{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"San Francisco\", \"unit\": \"celsius\"}"
}
}]
},
"finish_reason": "tool_calls"
}]
}第三步:执行工具并返回结果
你的代码执行工具,将结果发回模型:
json
{
"model": "openai/gpt-4o",
"messages": [
{ "role": "user", "content": "What is the weather in San Francisco?" },
{
"role": "assistant",
"tool_calls": [/* 上一步模型返回的 tool_calls */]
},
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "{\"temperature\": 18, \"conditions\": \"Partly cloudy\"}"
}
],
"tools": [/* 同上 */]
}模型收到工具结果后,生成最终用户回复。
完整 TypeScript 示例
typescript
import { OpenRouter } from '@openrouter/sdk';
const openRouter = new OpenRouter({ apiKey: '<OPENROUTER_API_KEY>' });
// 定义工具
const tools = [{
type: 'function' as const,
function: {
name: 'get_weather',
description: 'Get weather for a location',
parameters: {
type: 'object',
properties: {
location: { type: 'string', description: 'City name' },
},
required: ['location'],
},
},
}];
// 第一次请求
const firstResponse = await openRouter.chat.send({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: 'What is the weather in Tokyo?' }],
tools,
});
const message = firstResponse.choices[0].message;
if (message.tool_calls) {
// 执行工具(你的业务逻辑)
const toolResult = { temperature: 22, conditions: 'Sunny' };
// 第二次请求,携带工具结果
const finalResponse = await openRouter.chat.send({
model: 'openai/gpt-4o',
messages: [
{ role: 'user', content: 'What is the weather in Tokyo?' },
{ role: 'assistant', tool_calls: message.tool_calls },
{
role: 'tool',
tool_call_id: message.tool_calls[0].id,
content: JSON.stringify(toolResult),
},
],
tools,
});
console.log(finalResponse.choices[0].message.content);
}tool_choice 参数
控制模型是否调用工具:
| 值 | 行为 |
|---|---|
"auto" | 模型自行决定(默认) |
"none" | 不调用工具,直接生成文字 |
"required" | 必须调用至少一个工具 |
{ "type": "function", "function": { "name": "..." } } | 强制调用指定工具 |
并行工具调用
支持工具调用的模型可以在一次响应中建议调用多个工具(parallel_tool_calls),减少往返次数。设置 parallel_tool_calls: false 可强制按顺序调用。
常见问题
Q: 如何判断哪些模型支持工具调用?
A: 访问 openrouter.ai/models?supported_parameters=tools,或通过 Models API 检查 supported_parameters 字段是否包含 "tools"。
Q: 工具参数的 arguments 是字符串还是对象?
A: 是 JSON 字符串,需要 JSON.parse(message.tool_calls[0].function.arguments) 才能得到对象。
Q: 工具调用能和流式传输一起用吗?
A: 可以。流式传输时,工具调用参数会逐步流出,你可以实时构建参数对象,或等到 finish_reason: "tool_calls" 后再处理。