把你的 API 暴露给大模型
LLM 原本什么都做不了
你让它"查北京今天天气",它只能根据训练数据瞎猜。它没有联网、没有 API、没有数据库。
**Function Calling(函数调用,也叫 Tool Use)**解决了这个问题:
你告诉模型"我这里有这些函数可以调",模型根据用户请求决定要不要调、用什么参数调,然后把结果告诉你的程序去真正执行。
注意:模型不真的执行函数,它只输出"应该怎么调"。真正执行的是你的代码。
一个完整的例子
import OpenAI from 'openai'
const client = new OpenAI()
// 1. 定义可用的工具
const tools = [
{
type: 'function',
function: {
name: 'get_weather',
description: '查询指定城市的当前天气',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: '城市名,如"北京"' },
},
required: ['city'],
},
},
},
]
// 2. 真正的工具实现(你的业务代码)
async function getWeather(city) {
// 假装调了一个天气 API
return { city, temperature: 22, condition: '晴' }
}
// 3. 发起对话
const messages = [
{ role: 'user', content: '北京今天天气怎样?' },
]
const res = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages,
tools, // 告诉模型有哪些工具
})
const msg = res.choices[0].message
console.log(msg)
// {
// role: 'assistant',
// content: null,
// tool_calls: [
// {
// id: 'call_abc',
// type: 'function',
// function: {
// name: 'get_weather',
// arguments: '{"city":"北京"}',
// },
// },
// ],
// }
看!模型没直接回答,而是告诉你:"我需要调 get_weather('北京')"。
完整闭环
// 4. 执行工具
messages.push(msg) // 把模型的 tool_calls 回复加进历史
for (const call of msg.tool_calls) {
const args = JSON.parse(call.function.arguments)
const result = await getWeather(args.city)
messages.push({
role: 'tool',
tool_call_id: call.id,
content: JSON.stringify(result),
})
}
// 5. 把结果喂回模型,让它组织最终回答
const final = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages,
tools,
})
console.log(final.choices[0].message.content)
// "北京今天晴,22 度,适合出门。"
所以整个流程是个循环:
用户提问
│
▼
LLM 决策 ──► 不需要工具 ──► 直接回答
│
├──► 需要工具
│ │
│ ▼
│ 执行工具
│ │
│ ▼
│ 结果喂回 LLM ──► 可能还要调下一个工具 ──► 循环
│
└─────► 最终回答多工具 + 并行调用
现代模型(GPT-4o、Claude 3.5+、DeepSeek-V3)支持并行调用多个工具,一次性说"我要查天气、查时间、查日历"。
const tools = [
{ type: 'function', function: { name: 'get_weather', ... } },
{ type: 'function', function: { name: 'get_time', ... } },
{ type: 'function', function: { name: 'search_web', ... } },
]
你的代码要处理 tool_calls 数组(可能不止一个)。
Schema 设计的艺术
工具的 parameters 用JSON Schema描述,这决定模型能不能正确调用。
// 用 zod + zod-to-json-schema 比手写 JSON Schema 舒服 100 倍
import { z } from 'zod'
import { zodToJsonSchema } from 'zod-to-json-schema'
const sendEmailSchema = z.object({
to: z.string().email().describe('收件人邮箱'),
subject: z.string().describe('邮件主题'),
body: z.string().describe('邮件正文,支持 Markdown'),
cc: z.array(z.string().email()).optional().describe('抄送列表'),
})
const tool = {
type: 'function',
function: {
name: 'send_email',
description: '发送一封邮件。只在用户明确要求时使用。',
parameters: zodToJsonSchema(sendEmailSchema),
},
}
description 的质量直接决定调用准确率。写清楚什么时候该用、什么时候不该用。
实际场景:前端可以用它做什么
1. 让 AI 操作 UI
const tools = [
{ name: 'set_theme', parameters: { theme: 'dark' | 'light' } },
{ name: 'navigate_to', parameters: { page: string } },
{ name: 'open_modal', parameters: { modal_id: string } },
]
// 用户说"切暗色模式",模型返回 set_theme({ theme: 'dark' }),前端执行
2. 智能搜索/填表
// 用户说"帮我订下周三下午北京飞上海的机票"
// 模型调 search_flights({ from, to, date, time_range })
3. 读写业务数据
const tools = [
{ name: 'create_task', ... },
{ name: 'list_my_tasks', ... },
{ name: 'mark_done', ... },
]
// 用户说"把今天的三件事标记完成",模型连调三次 mark_done
4. 从自然语言生成 SQL/GraphQL 5. 控制 Chrome 扩展、VS Code 插件
安全性(极重要!)
模型会出错、会被 Prompt 注入攻击。永远不要盲目信任 tool_calls。
// 灾难
async function execute(call) {
const args = JSON.parse(call.function.arguments)
if (call.function.name === 'delete_user') {
await db.deleteUser(args.userId) //
}
}
正确做法:
-权限校验:每个工具独立权限,按当前用户身份过滤
-危险操作需要用户确认:涉及扣费、删数据、发邮件的,弹窗二次确认
-参数校验:用 zod 严格校验 arguments
-工具分级:把工具分成"查询型"(安全)和"执行型"(敏感)
模型的 Function Calling 能力对比
| 模型 | 能力 |
|---|---|
| GPT-4o | 事实标准 |
| Claude 3.5/Opus 4 | 推理强,决策精准 |
| DeepSeek-V3 | 性价比高 |
| Gemini 2.0 | 支持 |
| Qwen 2.5+ | 开源里最好 |
| 小模型(7B 以下) | 基本不可用 |
想做 Function Calling,选模型至关重要。
和 Agent 的关系
Function Calling 是单步的:模型决定调一次工具 → 执行 → 模型看结果 → 回答。
Agent是在 Function Calling 基础上加循环和记忆,让模型能自主完成多步任务("帮我查天气、写邮件、发出去")。下一篇专门讲。
动手作业
给一个 Todo 应用加 AI 接口:
- 工具 1:
add_task({ title, due_date }) - 工具 2:
list_tasks({ filter: 'today'|'week'|'all' }) - 工具 3:
complete_task({ id })
要求:支持自然语言操作,比如"把明天的事推到下周一"(模型要能先 list 再 update)。
参考资料
- OpenAI Function Calling 文档 — 权威文档
- Anthropic Tool Use 文档 — Claude 的 Tool Use
- Vercel AI SDK: Tools — 前端友好的封装
- zod-to-json-schema
- OpenAPI → Tools 转换 — 把已有 REST API 变成 LLM 工具
版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。
(采用 CC BY-NC-SA 4.0 许可协议进行授权)
本文标题:Function Calling:让 AI 调用你的 API
本文链接:https://www.sshipanoo.com/blog/ai/ai-for-frontend/06-Function-Calling/
本文最后一次更新为 天前,文章中的某些内容可能已过时!