Function Calling(工具调用)的完整流程是怎样的?

进阶高频原理约 4 分钟读完

一句话回答

模型本身不执行任何函数。流程是:开发者把工具的名称、描述和参数的 JSON Schema 传给模型;模型判断需要调用时,返回"调用哪个工具、参数是什么";应用代码执行工具,把结果作为新消息回传给模型;模型根据结果继续推理,直到给出最终回答。

详细解析

一次完整的调用

文本
用户:北京今天要带伞吗?
  ↓
应用 → 模型:对话消息 + 工具列表(get_weather 的定义)
  ↓
模型 → 应用:调用 get_weather,参数 {"city": "北京"}
  ↓
应用执行 get_weather,得到 {"weather": "小雨", "temp": 18}
  ↓
应用 → 模型:把工具结果追加到对话里
  ↓
模型 → 应用:北京今天有小雨,建议带伞。

代码示例

各家 SDK 的字段名不同,下面是通用写法:

JavaScript
const tools = [
  {
    name: 'get_weather',
    description: '查询指定城市今天的天气。用户问天气、穿衣、出行建议时使用。',
    parameters: {
      type: 'object',
      properties: {
        city: { type: 'string', description: '城市名,如:北京' },
      },
      required: ['city'],
    },
  },
]

async function chat(userInput) {
  const messages = [{ role: 'user', content: userInput }]

  // 限制最大轮数,防止模型反复调用工具陷入死循环
  for (let step = 0; step < 10; step++) {
    const res = await llm.chat({ messages, tools })
    messages.push(res.message)

    // 没有工具调用,说明这就是最终回答
    if (!res.toolCalls?.length) return res.message.content

    for (const call of res.toolCalls) {
      const result = await runTool(call.name, call.arguments) // 执行前要校验参数
      messages.push({ role: 'tool', toolCallId: call.id, content: JSON.stringify(result) })
    }
  }
  throw new Error('工具调用轮数超过上限')
}

工具描述决定调用质量

  • description 写清楚工具做什么、什么时候用、什么时候不要用
  • 参数用 enum、格式说明等约束取值范围
  • 工具太多时模型容易选错,可以按场景动态挑选要提供的工具

面试官可能追问

模型返回的参数一定合法吗?

不一定。可能缺字段、类型不对,甚至编造参数值。执行前要按 Schema 校验。部分平台提供严格模式,可以保证输出的参数符合 Schema。

多个工具调用可以并行吗?

可以。很多模型支持一次返回多个工具调用,互相没有依赖的调用可以并发执行,等结果全部回传后模型再继续。

工具执行失败了怎么办?

把错误信息作为工具结果返回给模型,让它决定重试、换一个工具,还是告诉用户。同时给工具设置超时,给整个循环设置最大轮数。

转账、删除数据这类敏感操作怎么处理?

不要让模型直接执行。执行前加人工确认,工具按最小权限设计,并记录完整的调用日志。

易错点

  • 不要说"模型调用了 API"。准确的说法是:模型提出调用请求,应用执行调用
  • 工具返回的结果会占用上下文,返回内容要尽量精简

AI 模拟面试官

用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮

登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录

这道题你掌握了吗?

选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。

学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。