我们常把大模型比作“聪明的嘴”——它能说会道,但不能做事。
比如你问:“北京今天天气怎么样?”
它可能会凭记忆瞎猜,或者直接回答:“我不知道。”
但如果我们能让它调用一个真实的天气接口呢?
答案就不再是猜测,而是准确数据。
LangChain 提供了一套优雅的机制——Tools(工具) ,让大模型不仅能“说”,还能“做”。
本文将通过两个简单例子(查天气 + 加法),带你掌握如何用 @langchain/core/tools 和 bindTools 实现函数调用。
一、为什么需要 Tools?
大模型的本质是“语言预测器”,它没有访问外部世界的能力。
但现实中的 AI 应用往往需要:
- 查询数据库
- 调用 API
- 执行计算
- 操作文件
这些能力,统称为 “工具调用”(Tool Calling) 。
LangChain 的 tool 函数,就是用来把 JavaScript 函数包装成模型可调用的工具。
配合支持函数调用的模型(如 DeepSeek、GPT-4、Claude 等),就能实现“AI 决策 → 调用工具 → 返回结果”的闭环。
二、第一步:定义你的工具
我们先模拟一个天气数据库:
const fakeWeatherDB = {
北京: { temp: "30°C", condition: "晴", wind: "微风" },
上海: { temp: "28°C", condition: "多云", wind: "东风 3 级" },
广州: { temp: "32°C", condition: "阵雨", wind: "南风 2 级" },
};
然后用 tool() 包装成一个可被模型调用的工具:
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
const weatherTool = tool(
async ({ city }) => {
const weather = fakeWeatherDB[city];
if (!weather) {
return `暂无${city}的天气信息`;
}
return `当前${city}的天气是${weather.temp}, ${weather.condition}, 风力${weather.wind}`;
},
{
name: 'weather',
description: "查询指定城市的今日天气情况",
schema: z.object({
city: z.string().describe("要查询天气的城市")
})
}
);
关键点解析:
- 第一个参数:实际执行的异步函数,接收结构化参数
name:工具的唯一标识,模型通过它决定调用哪个工具description:告诉模型这个工具是干什么的(影响调用决策)schema:用 Zod 定义输入参数的类型和描述,模型据此生成合法参数
Zod 是一个强大的 TypeScript 运行时校验库,LangChain 用它来确保模型传参的合法性。
同样,我们再定义一个加法工具:
const addTool = tool(
async ({ a, b }) => String(a + b),
{
name: 'add',
description: "计算两个数字的和",
schema: z.object({
a: z.number().describe("第一个数字"),
b: z.number().describe("第二个数字")
})
}
);
现在,我们有了两个“能力”:查天气、做加法。
三、第二步:把工具绑定给模型
接下来,让模型知道它“能用哪些工具”。
import { ChatDeepSeek } from '@langchain/deepseek';
const model = new ChatDeepSeek({
model: 'deepseek-chat',
temperature: 0,
}).bindTools([addTool, weatherTool]);
.bindTools() 是关键——它会:
- 自动提取每个工具的
name、description、schema - 将这些信息作为“函数签名”注入到模型的上下文
- 告诉模型:“你可以调用这些函数,按这个格式传参”
此时,模型就从“纯聊天模式”升级为“可调用工具模式”。
四、第三步:触发调用并处理结果
我们问模型一个问题:
const res = await model.invoke("北京今天的天气怎么样?");
如果模型判断需要调用工具,res 中会包含 tool_calls 字段:
if (res.tool_calls?.length) {
const call = res.tool_calls[0];
if (call.name === 'weather') {
const result = await weatherTool.invoke(call.args);
console.log("最终结果:", result);
}
}
输出:
最终结果: 当前北京的天气是30°C, 晴, 风力微风
整个流程如下:
- 用户提问 → 模型分析是否需要外部工具
- 若需要,模型返回
tool_calls(包含工具名 + 参数) - 我们根据
name路由到对应工具,用args调用 - 工具执行后返回真实结果
- (可选)把结果再喂给模型,生成自然语言回复
注意:目前我们手动处理了工具调用。LangChain 也提供了
createToolCallingAgent等高级封装,可自动完成整个 loop。
五、结语:AI 的未来是“会用工具的人”
大模型真正的价值,不在于它能背多少知识,而在于它能否合理调度外部能力。
LangChain 的 tool + bindTools 机制,正是通往这一目标的桥梁。
无论是查天气、发邮件、查订单,还是控制智能家居,背后都是同一个模式:
定义工具 → 绑定模型 → 处理调用
你不需要教模型“怎么查天气”,只需要给它一个叫 weather 的工具,它自己就知道何时用、怎么用。
而这,或许才是“智能助手”的真正含义。
试试看:把
fakeWeatherDB换成真实 API(如和风天气),你的 AI 就能提供全国任意城市的实时天气了!