当LLM学会"递纸条",AI是如何调用工具的

以前的大模型是没法直接告诉你今天的天气的,但随着时间的发展,LLM也学会了如何调用 工具(Tool),但这个工具调用背后真正的技术逻辑,不只是API

LLM 到底是什么?

技术上没那么玄乎。

LLM 做的事情只有一件:根据上文,猜下一个词

输入 1+1=,它猜后面是 2。输入 今天天气真,它猜下一个词是

这就是 Next Token Prediction------一次猜一个词,拼上去,再猜下一个,直到对话结束。

问题来了:你问它"青岛啤酒今天的收盘价",它怎么猜?

猜不了。训练数据截止于去年,股价是实时变动的。它没有任何渠道获取当下的信息。本质上,它是一堆跑在 GPU 上的矩阵运算,没有网络连接,没有文件系统,没有数据库驱动。

那为什么现在的 AI 都能查天气、查股价、读文件?

因为有人替它查好了

给 LLM 一张"工具清单"

LLM 不认识 API endpoint,也听不懂什么叫"调接口"。

但它能读懂结构化的文字描述。

所以第一步很简单:把你的函数封装成一个 JSON 格式的工具声明,描述清楚它叫什么、能干什么、需要什么参数。然后通过 API 的 tools 参数传给模型。

json

js 复制代码
{
  "type": "function",
  "function": {
    "name": "get_closing_price",
    "description": "获取指定股票在当日的收盘价",
    "parameters": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "股票名称,如'青岛啤酒'"
        }
      },
      "required": ["name"]
    }
  }
}

这一步在工程上叫作工具注册 ------把一段函数签名"翻译"成 LLM 能理解的语言,告诉它:"有个叫 get_closing_price 的工具,能查股价,你只需要提供股票名字就行。"

听起来复杂?其实就是把一个软件函数降维成一段文本,让 LLM 能"读懂"。唯一要注意的是 description 要写清楚------你说"获取信息",它可能查天气时也来调这个;你写"获取指定股票的收盘价",意图就锁得精准。因为 LLM 的决策本质上是概率性的:输入越模糊,输出就越随机。

LLM 不执行,它只"说"

用户问:"青岛啤酒的收盘价是多少?"

LLM 开始做一连串判断:

  • 训练数据里没有实时股价 → 不能直接回答。
  • tools 参数里有 get_closing_price → 这个工具能解决问题。
  • 用户问的是"青岛啤酒" → 参数填 name: "青岛啤酒"
  • 输出 tool_calls,不输出文字。

于是 LLM 返回了这样一个结构:

json

js 复制代码
{
  "id": "call_abc123",
  "type": "function",
  "function": {
    "name": "get_closing_price",
    "arguments": "{"name":"青岛啤酒"}"
  }
}

注意:content 字段是空的。LLM 没有直接回答用户,而是输出了一段"指令",告诉外部系统:去,调这个函数,传这个参数。

但它自己不动手------也动不了手。

打个比方:LLM 像一个被反锁在房间里的人。门缝下面可以塞纸条。它把"帮我查青岛啤酒的股价"写在纸条上塞出去,然后等着。外面的人查完了,把答案从门缝塞回来,它再根据答案组织语言回复用户。

这张纸条,就是 tool_calls

干活的其实是 Runtime

纸条塞出来了,总得有人去执行。

这个人就是 Runtime------也就是开发者写的代码。它的工作流程是这样的:

javascript

js 复制代码
const response = await sendMessage(messages, tools);  // 1. 发起请求,传入工具列表
const message = response.choices[0].message;

if (message.tool_calls) {                             // 2. 检测 LLM 是否请求调工具
    const toolCall = message.tool_calls[0];

    if (toolCall.function.name === 'get_closing_price') {
        const args = JSON.parse(toolCall.function.arguments);   // 3. 解析参数
        const price = get_closing_price(args.name);             // 4. 执行真实函数 → "67.92"

        messages.push(message);                        // 5. 把 LLM 的工具调用记录追加到上下文
        messages.push({
            role: 'tool',
            content: price,
            tool_call_id: toolCall.id
        });

        const finalRes = await sendMessage(messages);  // 6. 再次调用 LLM,带上工具执行结果
        // → "青岛啤酒的收盘价是 67.92 元"
    }
}

第 4 步那个 get_closing_price 函数,跟 AI 一毛钱关系都没有------它就是一段普通的 JavaScript:

javascript

js 复制代码
function get_closing_price(name) {
    if (name === '青岛啤酒') return '67.92';
    if (name === '贵州茅台') return '1234.11';
    return '未找到股票';
}

上面是 Demo 里的 mock 数据。真实场景中,这个函数会去查数据库、调第三方 API、读取文件------总之就是传统软件开发那一套。

新旧范式就在这里交汇。LLM 负责"说要调什么",传统代码负责"真的去调"。各司其职,然后通过 role: "tool" 那条消息重新接上头。

整个流程,一张图

text

js 复制代码
用户:"青岛啤酒收盘价?"
  ↓
第 1 次调 LLM(附带 tools 参数)→ LLM 不回答,输出 tool_calls
  ↓
Runtime 检测到 tool_calls → 解析参数 → 执行 get_closing_price("青岛啤酒") → "67.92"
  ↓
Runtime 把 "67.92" 以 role: "tool" 拼回消息历史
  ↓
第 2 次调 LLM(上下文里多了工具结果)→ "青岛啤酒的收盘价是 67.92 元"

用户视角:问了一个问题,得到了正确答案。丝滑。

开发者视角:调了两次 LLM,中间 Runtime 插了一脚,跑了一个真实函数。一点也不丝滑。

但产品层把这中间的往返完全封装了。用户看到的只是一个"智能助手"------这就是 Tool Use 在产品设计上的精妙之处。

这东西为什么重要

没有 Tool Use 的 LLM 是"死"的。

它能跟你聊哲学、写诗、解释量子力学------因为这些训练数据里都有。但你不能问它"今天我该不该带伞",它没有实时天气。你不能让它"帮我把这封邮件发了",它碰不到邮件服务器。

Tool Use 把它从"死的"变成了"活的"。

查天气、查股价、搜网页、发邮件、读 Excel、操作电脑------你在网上看到的那些 AI Agent 的炫酷 Demo,底层逻辑都是同一套三板斧:注册工具 → LLM 决策调哪个 → Runtime 去执行

豆包的网页搜索是这么做的,Claude 的 Excel 分析是这么做的,那些让 AI 自动操作电脑的"贾维斯"式 Demo,也是在这一层又一层的 Tool Use 上叠起来的。

本质上是一层精心设计的"假象"

写这篇文章,不是因为 Tool Use 技术本身有多难------拆开看,每一步都简单直白。

写它,是因为这个"假象"设计得太好了。

用户觉得 LLM 无所不能。但 LLM 从头到尾只做了一件事------猜下一个词。它凭的是一套精巧的外围机制:工具注册告诉它能用什么,意图识别让它知道什么时候该用,Runtime 替它把干不了的事干了。

公式只有一个:

text

ini 复制代码
LLM + Tools = Agent

LLM 是大脑------只负责推理和语言。Tool 是手脚------只负责执行。Runtime 是中间的神经系统------把大脑的指令传到手脚,再把手脚的结果传回大脑。

下次你跟 AI 说"帮我查下今天的天气"时,可以想想------说话的这会儿,它刚刚往门缝下面塞了一张纸条。

相关推荐
拾年2751 小时前
大模型的"聪明"从哪来?聊聊 AI 数据集的那些事儿
人工智能·深度学习·机器学习
拾年2751 小时前
从 Prompt 到 Context 再到 Harness:AI 工程化的三年三级跳
人工智能
用户3090463613942 小时前
Claude 不会直接执行你的函数,它只会生成一段结构化的工具调用请求。真正执行函数、访问数据库、请求外部 API 的动作,必须由你的后端完成。
人工智能
不加辣椒2 小时前
第14章 Prompt 编排与优化技术
人工智能
Bolt2 小时前
读懂 Claude Code `/loop` 与编码 Agent 的循环革命
人工智能·程序员·agent
用户208046804562 小时前
文本分块策略与最佳实践实战指南
人工智能
用户208046804563 小时前
文档解析实战:PDF、Word 与 HTML 的清洗提取指南
人工智能
得物技术4 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
HokKeung4 小时前
飞书 lark-cli 如何存储 tenant_access_token 和 user_access_token
人工智能·go