Tool Use 底层原理:当"缸中大脑"遇上物理世界——LLM 工具调用的认知哲学与技术实现

20 阅读5分钟

Tool Use 底层原理:当"缸中大脑"遇上物理世界——LLM 工具调用的认知哲学与技术实现

LLM 本质上只是被困在服务器里的"词语接龙机器",看不见屏幕、摸不到键盘。那么,它是如何突破物理限制,去调用 API、读取数据库、操作物理世界的工具的?本文从技术哲学的视角,深入解析 Tool Use 的三大核心机制。


前言

那个在显卡里疯狂跑的 LLM,本质上还是词语接龙的游戏。它是被困在服务器里的缸中大脑——看不见屏幕,摸不到键盘,更无法感知物理世界的变化。

那么问题来了:一个只能预测"下一个词的概率模型",是怎么突破物理限制,去调用 API、读取数据库、操作物理世界的工具的?

答案藏在 Tool Use(工具调用) 的三个核心机制中。


一、缸中大脑:LLM 的本质

1.1 Next Token Prediction

LLM 在做什么?

输入:"今天天气"
预测:下一个词是什么?
  → "晴朗"(概率 0.35)
  → "真好"(概率 0.22)
  → "不错"(概率 0.18)
  → ...

输出:选择概率最高的词

💡 LLM 的本质:一个巨大的概率模型,基于训练数据中的统计规律,预测"给定上文后,下一个词应该是什么"。

1.2 LLM 的物理限制

┌─────────────────────────────────────────┐
│              LLM(缸中大脑)             │
│                                         │
│  · 看不见屏幕                           │
│  · 摸不到键盘                           │
│  · 无法感知物理世界                     │
│  · 知识有截止日期                       │
│  · 无法执行任何代码                     │
│                                         │
│  它能做的唯一一件事:                   │
│  根据输入文本,预测输出文本             │
└─────────────────────────────────────────┘

这就是为什么 LLM 需要工具

场景LLM 能做什么LLM 不能做什么
股价查询生成"查询股价"这段文字真正访问股票 API
天气查询生成"查询天气"这段文字真正获取实时天气
文件分析生成"读取文件"这段文字真正打开文件
电脑操作生成"点击按钮"这段文字真正点击屏幕

⚠️ 关键洞察:LLM 生成的一切都是文本。它生成的"调用代码"本质上和"诗歌"没有区别——都是一串字符。

1.3 不是 LLM 在操作,是你在操作

用户以为的:
  "LLM 很聪明,它会调用 API 帮我查股价"

实际的:
  "LLM 生成了一段文本,你的程序识别这段文本,
   然后你去调用 API,把结果再喂给 LLM"

这是一个精心设计的错觉——用户以为是 LLM 完成的,其实不是。

二、Tool Use 的三大核心机制

2.1 机制一:认知植入(Cognitive Implantation)

问题:LLM 不懂什么是天气 API,也不懂数据库查询,那它怎么知道该调用什么工具?

答案:在执行任务之前,在 system prompt 里配置工具的时候,就在做一件非常精妙的事——认知植入

传统编程:
  function get_weather(city) {
    return fetch(`/api/weather?city=${city}`);
  }
  // LLM 看不懂这段代码

认知植入:
  {
    "name": "get_weather",
    "description": "获取指定城市的天气",
    "parameters": {
      "city": { "type": "string", "description": "城市名称" }
    }
  }
  // LLM 能看懂这段 JSON,因为它是自然语言

核心思想

复杂软件工具(API / 函数 / 数据库)
      │
      ▼
JSON Schema(结构化的自然语言说明书)
      │
      ▼
LLM 能理解的文本描述

💡 降维为语言:一个复杂的软件工具(如 get_closing_price),被降维成了一个纯粹的文本描述(JSON Schema)。LLM 不做代码执行,它只做自然语言理解——而 JSON Schema 恰好是结构化的自然语言。

2.2 机制二:意图识别(Intent Recognition)

问题:LLM 怎么知道"现在该调用工具了"?

答案:LLM 进行一系列的快速评估,然后停止和你的对话,转而开始自言自语(思考)

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

LLM 的推理过程:

第1步:我能直接回答吗?
  → 不行,我没有实时数据

第2步:认知植入里有工具吗?
  → 有!get_closing_price 工具

第3步:这个工具能回答用户的问题吗?
  → 能!工具描述是"获取指定股票的收盘价"4步:生成调用请求
  → content: ""
  → tool_calls: [{
       type: 'function',
       function: {
         name: 'get_closing_price',
         arguments: '{"name": "青岛啤酒"}'
       }
     }]

LLM 停止对话 → 生成调用代码 → 等待结果

意图识别的关键

要素作用
descriptionLLM 判断"这个工具能回答用户问题吗?"
parametersLLM 判断"需要什么参数?参数从用户输入中怎么提取?"
tool_choice: 'auto'让 LLM 自己决定是否调用工具

2.3 机制三:Runtime 介入

问题:LLM 生成了调用代码,但它不能执行——谁来执行?

答案Runtime(运行时)——你的程序。

传统软件 Runtime:
  Node.js / Python / Java 执行代码,调用工具

AI 时代的 Runtime:
  人 / AI 都可以调用
  只管一件事:执行,拿到结果

┌─────────────────────────────────────────┐
│              完整流程                    │
├─────────────────────────────────────────┤
│  1. 用户提问                            │
│  2. LLM 推理 → 生成 tool_calls          │
│  3. Runtime(程序)执行工具函数          │
│  4. Runtime 获取结果                    │
│  5. 结果返回给 LLM(不是直接给用户)      │
│  6. LLM 基于结果生成最终回答             │
│  7. 回答展示给用户                       │
└─────────────────────────────────────────┘

⚠️ 不是直接返回给用户:工具的执行结果要先返回给 LLM,让 LLM 基于完整的上下文(用户问题 + 工具结果)生成最终回答。这样 LLM 才能"理解"工具返回了什么,并给出人性化的解释。


三、完整代码实现

3.1 项目结构

tool-use-demo/
├── .env              # API Key
├── index.mjs         # 主程序
└── package.json

3.2 核心代码

import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();

// 缸中大脑
const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: process.env.DEEPSEEK_BASE_URL
});

// ===== 第一步:认知植入 —— 将工具降维为语言 =====
const tools = [
  {
    type: "function",
    function: {
      name: "get_closing_price",
      description: "获取指定股票的收盘价",
      parameters: {
        type: "object",
        properties: {
          name: {
            type: "string",
            description: "股票名称"
          }
        },
        required: ["name"]
      }
    }
  },
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "获取指定城市的天气",
      parameters: {
        type: "object",
        properties: {
          city: {
            type: "string",
            description: "城市名称"
          }
        },
        required: ["city"]
      }
    }
  }
];

// ===== 第二步:传统软件 Runtime —— 工具函数 =====
function get_closing_price(name) {
  if (name === '青岛啤酒') return '67.92';
  if (name === '贵州茅台') return '1488.21';
  return '未找到该股票';
}

function get_weather(city) {
  if (city === '上海') return '晴朗,25°C';
  if (city === '北京') return '多云,22°C';
  return '未找到该城市天气';
}

// ===== 第三步:发送消息到 LLM =====
async function sendMessage(messages) {
  const res = await client.chat.completions.create({
    model: 'deepseek-v4-pro',
    messages,
    tools,
    tool_choice: 'auto'  // 让 LLM 自动决定是否调用工具
  });
  return res;
}

// ===== 第四步:主流程 =====
async function main() {
  let messages = [
    { role: 'user', content: '青岛啤酒的收盘价是多少?' }
  ];

  // 第一次调用:LLM 进行意图识别
  const response = await sendMessage(messages);
  const message = response.choices[0].message;
  console.log('模型返回:', JSON.stringify(message, null, 2));

  // 将 LLM 的回复加入对话历史
  messages.push({
    role: message.role,
    content: message.content,
    tool_calls: message.tool_calls
  });

  // 检查是否需要调用工具
  if (message.tool_calls) {
    const toolCall = message.tool_calls[0];

    // Runtime 介入:执行工具
    if (toolCall.function.name === 'get_closing_price') {
      const args = JSON.parse(toolCall.function.arguments);
      const price = get_closing_price(args.name);
      console.log('工具执行结果:', price);

      // 将工具结果返回给 LLM
      messages.push({
        role: 'tool',
        content: price,
        tool_call_id: toolCall.id
      });
    }

    console.log('更新后的对话上下文:', JSON.stringify(messages, null, 2));

    // 第二次调用:LLM 基于工具结果生成最终回答
    const finalRes = await sendMessage(messages);
    console.log('最终回答:', finalRes.choices[0].message.content);
  }
}

main();

3.3 执行流程图解

Messages 数组的演变:

初始状态:
  [{ role: 'user', content: '青岛啤酒的收盘价是多少?' }]

第1次请求  LLM 返回 tool_calls:
  [
    { role: 'user', content: '青岛啤酒的收盘价是多少?' },
    {
      role: 'assistant',
      content: null,
      tool_calls: [{
        function: { name: 'get_closing_price', arguments: '{"name":"青岛啤酒"}' }
      }]
    }
  ]

Runtime 执行工具后:
  [
    { role: 'user', content: '青岛啤酒的收盘价是多少?' },
    { role: 'assistant', content: null, tool_calls: [...] },
    { role: 'tool', content: '67.92', tool_call_id: 'call_xxx' }
  ]

第2次请求  LLM 生成最终回答:
  [
    ...,
    { role: 'assistant', content: '青岛啤酒的收盘价是 67.92 元。' }
  ]

四、Tool Use 的本质:新旧范式的融合

4.1 传统编程 vs LLM 编程

传统编程:
  if (userQuestion.includes('股价')) {
    const stock = extractStockName(userQuestion);
    const price = getStockPrice(stock);
    return `股价是 ${price}`;
  }
  // 开发者写死逻辑

LLM 编程(Tool Use):
  // 开发者只定义工具(JSON Schema)
  // LLM 自己判断:"这个问题需要调用哪个工具?"
  // LLM 自己提取参数
  // LLM 自己生成回答
  // 开发者只需要实现工具函数

4.2 谁在做决策?

┌─────────────────────────────────────────┐
│         Tool Use 决策链                  │
├─────────────────────────────────────────┤
│                                         │
│  人类开发者:定义工具(JSON Schema)      │
│       ↓                                 │
│  LLM:判断是否需要工具、选择哪个工具      │
│        提取参数、生成调用请求             │
│       ↓                                 │
│  Runtime(程序):执行工具函数            │
│       ↓                                 │
│  LLM:基于工具结果生成最终回答            │
│       ↓                                 │
│  用户:获得人性化回答                     │
│                                         │
└─────────────────────────────────────────┘

💡 核心洞察:在 Tool Use 中,人类定义能力边界,LLM 做智能决策,Runtime 做物理执行。三者的协作,让"缸中大脑"突破了物理世界的限制。


五、知识图谱

Tool Use 底层原理
├── LLM 的本质
│   ├── Next Token Prediction
│   ├── 缸中大脑(物理限制)
│   └── 只能生成文本,不能执行
├── Tool Use 三大机制
│   ├── 认知植入(Cognitive Implantation)
│   │   ├── JSON Schema → 自然语言说明书
│   │   ├── 工具降维为语言
│   │   └── LLM 只懂自然语言
│   ├── 意图识别(Intent Recognition)
│   │   ├── 快速评估:我能回答吗?
│   │   ├── 检查认知植入中的工具
│   │   └── 生成 tool_calls(自言自语)
│   └── Runtime 介入
│       ├── LLM 不能执行,开发者可以
│       ├── 执行工具 → 获取结果
│       └── 结果返回 LLM(不是直接给用户)
├── 完整实现
│   ├── tools 定义(JSON Schema)
│   ├── 工具函数实现
│   ├── sendMessage 封装
│   └── 主流程(两次调用)
└── 新旧范式融合
    ├── 传统编程:写死逻辑
    └── LLM 编程:定义工具,LLM 决策

六、总结

本文从技术哲学的视角,深入解析了 Tool Use 的底层原理:

  1. LLM 的本质是 Next Token Prediction,是被困在服务器里的"缸中大脑"——它看不见屏幕、摸不到键盘,只能生成文本。
  2. 认知植入将复杂的软件工具降维为 JSON Schema(结构化的自然语言说明书),让 LLM 通过自然语言理解"这是什么工具、能做什么"。
  3. 意图识别是 LLM 的推理过程:先判断能否直接回答,再检查认知植入中的工具,最后生成调用请求("自言自语")。
  4. Runtime 介入是程序执行工具函数,将结果返回给 LLM(不是直接给用户),让 LLM 基于完整上下文生成人性化的最终回答。
  5. Tool Use 不是 LLM 在操作物理世界,而是一个精心设计的协作流程:人类定义工具、LLM 做智能决策、Runtime 做物理执行。
  6. 从传统编程到 LLM 编程,范式正在转变:从"写死逻辑"到"定义工具,让 LLM 自己决策"。

🚀 学习建议:理解 Tool Use 的底层原理后,你就能设计出更合理的工具描述(JSON Schema),让 LLM 更准确地识别意图、提取参数。记住:描述越具体清晰,LLM 的决策越准确。


参考资源


📌 标签:#ToolUse #LLM #Agent #认知植入 #意图识别 #Runtime #缸中大脑 #NextTokenPrediction

💬 互动:你觉得 Tool Use 是 LLM"突破物理限制"的方式,还是"人类精心设计的错觉"?欢迎在评论区讨论!