作为开发者,你是否曾困惑:
为什么大模型能查股票价格、查天气?
一个只会“词语接龙”的概率模型,怎么突破虚拟限制调用外部工具?
明明训练数据里没有实时数据,却能返回精准的股票收盘价?

这篇文章,我会用可直接运行的Node.js代码,拆解LLM工具调用的底层逻辑,从0到1实现股票价格查询的工具调用,让你彻底搞懂:

  • 工具调用不是“黑魔法”,而是精心设计的交互流程
  • 如何用JSON Schema给大模型“植入工具认知”
  • 传统代码如何和大模型协作完成任务
    在这里插入图片描述

一、核心认知:LLM本质是“缸中大脑”

先打破一个误区:大模型没有自我意识

它本质上只是一个“Next Token Prediction”(下一个词预测)的概率模型,像被困在服务器里的“缸中大脑”——看不见屏幕、摸不到键盘,只能处理文本。

工具调用的核心,是把复杂的软件函数(比如查股票价格),降维成大模型能理解的自然语言说明书,再通过传统代码执行工具逻辑,最后把结果返回给大模型生成最终回答。

二、实战场景:实现股票收盘价查询工具调用

我们以“查询青岛啤酒收盘价”为例,完整实现一次LLM工具调用流程,技术栈:

  • Node.js + dotenv(环境变量管理)
  • OpenAI SDK(兼容DeepSeek API)
  • 自定义工具函数 + 大模型交互逻辑

步骤1:环境准备与依赖安装

首先初始化项目,安装所需依赖:

# 初始化package.json
npm init -y

# 安装依赖
npm install openai dotenv

步骤2:完整可运行代码

创建index.js文件,复制以下代码(记得配置.env文件):

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

// 初始化DeepSeek客户端(兼容OpenAI SDK)
const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: process.env.DEEPSEEK_BASE_URL
});

// 1. 定义工具(给大模型的"使用说明书")
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']
      }
    }
  }
];

// 2. 传统软件逻辑:实现工具函数(真实场景可替换为API调用)
function get_closing_price(name) {
  if (name === '青岛啤酒') {
    return '67.92';
  } else if (name === '贵州茅台') {
    return '1488.21';
  } else {
    return '未找到该股票';
  }
}

// 3. 封装大模型调用函数
async function sendMessage(messages) {
  const res = await client.chat.completions.create({
    model: 'deepseek-v4-pro', // 替换为你使用的模型
    messages,
    tools, // 传入工具定义
    tool_choice: 'auto' // 让大模型自动决定是否调用工具
  });
  return res;
}

// 4. 核心交互逻辑
async function main() {
  // 初始化对话上下文
  let messages = [
    { role: 'user', content: '青岛啤酒的收盘价是多少?' }
  ];

  // 第一次调用大模型:判断是否需要调用工具
  const response = await sendMessage(messages);
  const message = response.choices[0].message;
  console.log('模型返回message 对象', JSON.stringify(message));

  // 将大模型的响应加入上下文
  messages.push({
    role: message.role,
    content: message.content,
    tool_calls: message.tool_calls
  });

  // 关键判断:如果大模型返回了工具调用指令
  if (response.choices[0].message.tool_calls) {
    const toolCall = response.choices[0].message.tool_calls[0];
    
    // 处理股票价格查询工具
    if (toolCall.function.name === 'get_closing_price') {
      // 解析大模型传递的参数
      const args = JSON.parse(toolCall.function.arguments);
      // 执行传统工具函数,获取结果
      const price = get_closing_price(args.name);
      console.log('股票收盘价', price);

      // 将工具执行结果加入上下文(关键:返回给大模型)
      messages.push({
        role: 'tool', // 标记为工具返回结果
        content: price,
        tool_call_id: toolCall.id // 通过ID关联工具调用
      });

      console.log('更新后完整对话上下文:', messages);

      // 第二次调用大模型:基于工具结果生成最终回答
      const finalRes = await sendMessage(messages);
      console.log('最终模型返回:', finalRes.choices[0].message.content);
    } else if (toolCall.function.name === 'get_weather') {
      // 扩展:天气查询工具逻辑(可自行实现)
    }
  }
}

// 执行主函数
main();

步骤3:配置环境变量

创建.env文件,填入你的DeepSeek API信息:

DEEPSEEK_API_KEY=你的DeepSeek API密钥
DEEPSEEK_BASE_URL=DeepSeek API的baseURL(例如:https://api.deepseek.com/v1)

步骤4:运行代码

node index.js

运行后你会看到:

  1. 大模型先返回工具调用指令(而非直接回答)
  2. 代码执行get_closing_price函数获取价格
  3. 工具结果返回给大模型
  4. 大模型生成最终的自然语言回答

三、关键拆解:工具调用的3个核心阶段

1. 认知植入:把工具“翻译”成大模型能懂的语言

代码里的tools数组,就是给大模型的“工具使用说明书”,核心是JSON Schema

  • name:工具函数名(唯一标识)
  • description:工具用途(大模型靠这个判断是否调用)
  • parameters:参数约束(类型、描述、必传项)

⚠️ 踩坑提醒:

  • 描述越具体,大模型调用越精准!比如把“股票名称”改成“股票名称,例如:青岛啤酒、贵州茅台”,能大幅降低参数错误率。
  • 参数约束必须严格(比如required),否则大模型可能漏传参数。

2. 决策阶段:大模型判断是否调用工具

当用户提问“青岛啤酒的收盘价是多少?”,大模型会:

  1. 检查自身训练数据:没有实时股票数据,无法直接回答
  2. 匹配工具列表:发现get_closing_price工具能解决这个问题
  3. 返回tool_calls字段:包含要调用的工具名、参数、唯一ID

3. Runtime介入:传统代码执行工具逻辑

这是最关键的“人类兜底”环节:

  • 代码解析tool_calls里的指令
  • 调用对应的传统函数(get_closing_price
  • 获取结果后,把结果以role: tool的形式加入对话上下文
  • 再次调用大模型,让它基于工具结果生成自然语言回答

四、踩坑提醒(避坑指南)

  1. 工具描述模糊导致调用失败
    ❌ 错误示例:description: "查股票价格"
    ✅ 正确示例:description: "获取指定A股股票的当日收盘价,参数为股票全称"

  2. 参数解析异常
    大模型返回的arguments是字符串,必须用JSON.parse解析,建议加try-catch:

    let args;
    try {
      args = JSON.parse(toolCall.function.arguments);
    } catch (e) {
      console.error('参数解析失败:', e);
      args = {};
    }
    
  3. 上下文管理混乱
    每次交互都要把大模型响应、工具结果加入messages数组,否则大模型会“失忆”,无法关联工具结果生成回答。

  4. API兼容问题
    不同厂商的LLM API(如DeepSeek、OpenAI)对tool_calls的格式略有差异,需根据文档调整。

五、总结

工具调用的本质,是LLM的语言能力 + 传统代码的执行能力的结合:

  1. 用JSON Schema给大模型“植入工具认知”
  2. 大模型做“决策”:判断是否调用工具、传什么参数
  3. 传统代码做“执行”:调用工具、获取结果
  4. 大模型做“总结”:把工具结果转换成自然语言回答

这套逻辑不仅适用于股票查询,还能扩展到天气查询、Excel分析、网页搜索等场景——这也是AI Agent的核心基础。

最后

本文的完整源码(包含天气查询工具的扩展实现)已整理好,你可以查看仓库获取:[完整源码地址](替换为你的源码地址,若无则注明“私信我获取完整源码”)。

掌握工具调用后,你可以解锁更多场景:让大模型调用API查实时数据、操作数据库、甚至控制硬件设备——这才是AI落地的核心能力。

如果这篇文章对你有帮助,欢迎点赞+收藏,后续会更新“AI Agent操作本地文件”“多工具串联调用”等实战内容!# 告别LLM能力边界!30分钟掌握AI工具调用核心逻辑
作为开发者,你是否曾困惑:
为什么大模型能查股票价格、查天气?
一个只会“词语接龙”的概率模型,怎么突破虚拟限制调用外部工具?
明明训练数据里没有实时数据,却能返回精准的股票收盘价?

这篇文章,我会用可直接运行的Node.js代码,拆解LLM工具调用的底层逻辑,从0到1实现股票价格查询的工具调用,让你彻底搞懂:

  • 工具调用不是“黑魔法”,而是精心设计的交互流程
  • 如何用JSON Schema给大模型“植入工具认知”
  • 传统代码如何和大模型协作完成任务

一、核心认知:LLM本质是“缸中大脑”

先打破一个误区:大模型没有自我意识

它本质上只是一个“Next Token Prediction”(下一个词预测)的概率模型,像被困在服务器里的“缸中大脑”——看不见屏幕、摸不到键盘,只能处理文本。

工具调用的核心,是把复杂的软件函数(比如查股票价格),降维成大模型能理解的自然语言说明书,再通过传统代码执行工具逻辑,最后把结果返回给大模型生成最终回答。

二、实战场景:实现股票收盘价查询工具调用

我们以“查询青岛啤酒收盘价”为例,完整实现一次LLM工具调用流程,技术栈:

  • Node.js + dotenv(环境变量管理)
  • OpenAI SDK(兼容DeepSeek API)
  • 自定义工具函数 + 大模型交互逻辑

步骤1:环境准备与依赖安装

首先初始化项目,安装所需依赖:

# 初始化package.json
npm init -y

# 安装依赖
npm install openai dotenv

步骤2:完整可运行代码

创建index.js文件,复制以下代码(记得配置.env文件):

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

// 初始化DeepSeek客户端(兼容OpenAI SDK)
const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: process.env.DEEPSEEK_BASE_URL
});

// 1. 定义工具(给大模型的"使用说明书")
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']
      }
    }
  }
];

// 2. 传统软件逻辑:实现工具函数(真实场景可替换为API调用)
function get_closing_price(name) {
  if (name === '青岛啤酒') {
    return '67.92';
  } else if (name === '贵州茅台') {
    return '1488.21';
  } else {
    return '未找到该股票';
  }
}

// 3. 封装大模型调用函数
async function sendMessage(messages) {
  const res = await client.chat.completions.create({
    model: 'deepseek-v4-pro', // 替换为你使用的模型
    messages,
    tools, // 传入工具定义
    tool_choice: 'auto' // 让大模型自动决定是否调用工具
  });
  return res;
}

// 4. 核心交互逻辑
async function main() {
  // 初始化对话上下文
  let messages = [
    { role: 'user', content: '青岛啤酒的收盘价是多少?' }
  ];

  // 第一次调用大模型:判断是否需要调用工具
  const response = await sendMessage(messages);
  const message = response.choices[0].message;
  console.log('模型返回message 对象', JSON.stringify(message));

  // 将大模型的响应加入上下文
  messages.push({
    role: message.role,
    content: message.content,
    tool_calls: message.tool_calls
  });

  // 关键判断:如果大模型返回了工具调用指令
  if (response.choices[0].message.tool_calls) {
    const toolCall = response.choices[0].message.tool_calls[0];
    
    // 处理股票价格查询工具
    if (toolCall.function.name === 'get_closing_price') {
      // 解析大模型传递的参数
      const args = JSON.parse(toolCall.function.arguments);
      // 执行传统工具函数,获取结果
      const price = get_closing_price(args.name);
      console.log('股票收盘价', price);

      // 将工具执行结果加入上下文(关键:返回给大模型)
      messages.push({
        role: 'tool', // 标记为工具返回结果
        content: price,
        tool_call_id: toolCall.id // 通过ID关联工具调用
      });

      console.log('更新后完整对话上下文:', messages);

      // 第二次调用大模型:基于工具结果生成最终回答
      const finalRes = await sendMessage(messages);
      console.log('最终模型返回:', finalRes.choices[0].message.content);
    } else if (toolCall.function.name === 'get_weather') {
      // 扩展:天气查询工具逻辑(可自行实现)
    }
  }
}

// 执行主函数
main();

步骤3:配置环境变量

创建.env文件,填入你的DeepSeek API信息:

DEEPSEEK_API_KEY=你的DeepSeek API密钥
DEEPSEEK_BASE_URL=DeepSeek API的baseURL(例如:https://api.deepseek.com/v1)

步骤4:运行代码

node index.js

运行后你会看到:

  1. 大模型先返回工具调用指令(而非直接回答)
  2. 代码执行get_closing_price函数获取价格
  3. 工具结果返回给大模型
  4. 大模型生成最终的自然语言回答

三、关键拆解:工具调用的3个核心阶段

1. 认知植入:把工具“翻译”成大模型能懂的语言

代码里的tools数组,就是给大模型的“工具使用说明书”,核心是JSON Schema

  • name:工具函数名(唯一标识)
  • description:工具用途(大模型靠这个判断是否调用)
  • parameters:参数约束(类型、描述、必传项)

⚠️ 踩坑提醒:

  • 描述越具体,大模型调用越精准!比如把“股票名称”改成“股票名称,例如:青岛啤酒、贵州茅台”,能大幅降低参数错误率。
  • 参数约束必须严格(比如required),否则大模型可能漏传参数。

2. 决策阶段:大模型判断是否调用工具

当用户提问“青岛啤酒的收盘价是多少?”,大模型会:

  1. 检查自身训练数据:没有实时股票数据,无法直接回答
  2. 匹配工具列表:发现get_closing_price工具能解决这个问题
  3. 返回tool_calls字段:包含要调用的工具名、参数、唯一ID

3. Runtime介入:传统代码执行工具逻辑

这是最关键的“人类兜底”环节:

  • 代码解析tool_calls里的指令
  • 调用对应的传统函数(get_closing_price
  • 获取结果后,把结果以role: tool的形式加入对话上下文
  • 再次调用大模型,让它基于工具结果生成自然语言回答
    在这里插入图片描述

四、踩坑提醒(避坑指南)

  1. 工具描述模糊导致调用失败
    ❌ 错误示例:description: "查股票价格"
    ✅ 正确示例:description: "获取指定A股股票的当日收盘价,参数为股票全称"

  2. 参数解析异常
    大模型返回的arguments是字符串,必须用JSON.parse解析,建议加try-catch:

    let args;
    try {
      args = JSON.parse(toolCall.function.arguments);
    } catch (e) {
      console.error('参数解析失败:', e);
      args = {};
    }
    
  3. 上下文管理混乱
    每次交互都要把大模型响应、工具结果加入messages数组,否则大模型会“失忆”,无法关联工具结果生成回答。

  4. API兼容问题
    不同厂商的LLM API(如DeepSeek、OpenAI)对tool_calls的格式略有差异,需根据文档调整。

五、总结

工具调用的本质,是LLM的语言能力 + 传统代码的执行能力的结合:

  1. 用JSON Schema给大模型“植入工具认知”
  2. 大模型做“决策”:判断是否调用工具、传什么参数
  3. 传统代码做“执行”:调用工具、获取结果
  4. 大模型做“总结”:把工具结果转换成自然语言回答

这套逻辑不仅适用于股票查询,还能扩展到天气查询、Excel分析、网页搜索等场景——这也是AI Agent的核心基础。

最后

本文的完整源码(包含天气查询工具的扩展实现)已整理好,你可以查看仓库获取:[Knowledge_Repository/ai/agent/tool_use at main · Guwen-yue/Knowledge_Repository](替换为你的源码地址,若无则注明“私信我获取完整源码”)。

掌握工具调用后,你可以解锁更多场景:让大模型调用API查实时数据、操作数据库、甚至控制硬件设备——这才是AI落地的核心能力。

如果这篇文章对你有帮助,欢迎点赞+收藏,后续会更新“AI Agent操作本地文件”“多工具串联调用”等实战内容!

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐