LangChain是什么,干什么的
LangChain是AI Agent 开发的一个框架。可以理解为:Lang + Chain = 语言模型 + 链式调用。它支持几乎所有的大模型(deepseek、chatGpt等),并且提供了统一的调用方式,让你轻松切换不同的模型
所以可以通过 LangChain 这个框架去开发AI Agent,方式是通过链式调用,把大模型(LLM)能力连接到实际应用中。
为什么需要LangChain
传统的AI对话开发:核心在于后端业务逻辑、数据库设计、API 接口等技术栈。
而AI Agent开发:核心变成了如何与大模型对话、如何优化提示词、如何管理对话流程
而Langchain就可以做到
对于前端来说难吗
LangChain 原生支持 TypeScript!这意味着前端开发者可以用自己熟悉的 JavaScript/TypeScript 来构建 AI 应用。
LangChain的6个核心
Models模型接入
首先安装一下环境
js
pnpm i @langchain/core @langchain/openai dotenv langchain zod
然后根目录创建.env文件
.env
DEEPSEEK_API_KEY="你的apikey,这里我用的deepSeek"
LangChain提供了统一的大模型接口
js
import { HumanMessage } from "@langchain/core/messages";
import { ChatOpenAI } from "@langchain/openai";
import dotenv from "dotenv";
dotenv.config();
// DeepSeek 配置(兼容 OpenAI 接口)
const deepseekModel = new ChatOpenAI({
model: "deepseek-chat",
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: 'https://api.deepseek.com/v1'
}
});
// 也可以使用其他模型
// const openaiModel = new ChatOpenAI({ model: "gpt-4", apiKey: process.env.OPENAI_API_KEY });
// const claudeModel = new ChatAnthropic({ model: "claude-3-opus-20240229", apiKey: process.env.ANTHROPIC_API_KEY });
// 统一调用方式
const messages = [new HumanMessage("你好,今天成都天气怎么样")];
const response = await deepseekModel.invoke(messages);
console.log(response.content);
Prompts提示词管理
基础模板
PromptTemplate.fromTemplate
js
/**
* 演示langchain创建prompt提示词
*/
import { PromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";
import dotenv from "dotenv";
dotenv.config();
// 创建提示词模板
const promptModel = PromptTemplate.fromTemplate(`
你是一个{role},
请用不超过{limit}个字符回答以下问题:
{question}
`);
// 根据模板,填充提示词
const createPrompt = await promptModel.format({
role: '专业翻译',
limit: 10,
question: '你好请翻译,我想知道你是男是女。',
});
// 初始化deepseek模型
const model = new ChatOpenAI({
model: 'deepseek-reasoner',
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: process.env.DEEPSEEK_API_URL,
}
});
// 调用模型
const response = await model.invoke(createPrompt);
console.log(response.content);
多消息模板
js
/**
* 演示langchain创建多消息prompt提示词
*/
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";
import dotenv from "dotenv";
dotenv.config();
// 创建提示词模板
const chatPrompt = ChatPromptTemplate.fromMessages([
{ role: 'system', content: '你是一个专业的{role},请用{language}回答。' },
{ role: 'human', content: '{input}' },
]);
// 根据模板,填充提示词
const createPrompt = await chatPrompt.formatMessages({
role: 'AI应用开发专家',
language: '中文',
input: '如何使用DeepSeekAPI',
});
// 初始化deepseek模型
const model = new ChatOpenAI({
model: 'deepseek-reasoner',
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: process.env.DEEPSEEK_API_URL,
},
});
// 调用模型
const response = await model.invoke(createPrompt);
console.log(response.content);
占位符模板(记忆)
js
const promptWithMemory = ChatPromptTemplate.fromMessages([
["system", "你是一个友好的 AI 助手,由深度求索公司开发"],
new MessagesPlaceholder("chat_history"), // 记忆会动态插入到这里
["human", "{input}"]
]);
Chains:流程编排
LangChain 表达式语言 (LCEL, LangChain Expression Language) 是最推荐的方式(类似于promise),它用 | 管道符将组件串联起来:
js
import { StringOutputParser } from "@langchain/core/output_parsers";
import { PromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";
import dotenv from 'dotenv';
dotenv.config();
// 配置 DeepSeek 模型
const model = new ChatOpenAI({
model: "deepseek-chat",
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: process.env.DEEPSEEK_API_URL,
}
});
const prompt = PromptTemplate.fromTemplate("给我讲一个关于{topic}的笑话,要简短有趣");
// 使用 LCEL 语法构建链
const chain = prompt.pipe(model).pipe(new StringOutputParser());
// 执行链
const result = await chain.invoke({ topic: "程序员" });
console.log(result);
// 我们也可以串联更复杂的操作
const complexChain = prompt
.pipe(model)
.pipe(new StringOutputParser())
.pipe((text) => `🤖 AI 说:${text}`); // 自定义处理
const upperResult = await complexChain.invoke({ topic: "AI" });
console.log(upperResult);
通过 pipe 方法串联。
Tools工具
工具是 Agent 的"手脚",可以拓展 Agent 的功能。LangChain 提供了多种定义工具的方式:
一个 LangChain 工具包含三个核心要素:
- name:工具名称,AI通过它选择工具
- description:工具描述,AI判断何时使用
- func:实际执行的函数
字符串输入
js
import { DynamicTool } from "@langchain/core/tools";
const simpleTool = new DynamicTool({
name: "get_time",
description: "获取当前时间",
func: async (input) => {
if (input) {
return '不告诉你'
}
return new Date().toLocaleString();
}
});
// 使用
const result = await simpleTool.func("当前时间");
console.log("当前时间:", result); //'不告诉你'
验证参数类型(推荐)
js
import { DynamicStructuredTool } from "langchain";
import z from "zod";
const weatherTool = new DynamicStructuredTool({
name: 'weather',
description: '查询天气信息,输入城市名称',
schema: z.object({
city: z.string().describe('城市名称'),
unit: z.enum(['celsius', 'fahrenheit']).optional().describe('温度单位')
}),
func: async ({ city, unit = 'celsius' }) => {
// 模拟天气数据
const weatherData = {
"北京": { temp: 22, condition: "晴" },
"上海": { temp: 18, condition: "雨" },
"武汉": { temp: 25, condition: "阴" }
};
const data = weatherData[city];
if (!data) {
return `未找到城市 "${city}" 的天气信息`;
}
const temp = unit === "celsius" ? `${data.temp}°C` : `${data.temp * 9 / 5 + 32}°F`;
return `${city}今天${data.condition},温度${temp}`;
}
})
const res = await weatherTool.func({ city: '北京' });
console.log(res);
// 北京今天晴,温度22°C
其中 zod 库可以帮我们验证参数类型,也能通过 describe 为模型提供参数说明。工具的 description 直接决定 AI 调用工具的准确率
zod schema 详解
基础类型
ts
const basicSchema = z.object({
name: z.string(), // 字符串
age: z.number(), // 数字
isActive: z.boolean(), // 布尔值
tags: z.array(z.string()) // 数组
});
带约束的类型
ts
const constrainedSchema = z.object({
name: z.string().min(1).max(100), // 长度限制
age: z.number().min(0).max(150), // 数值范围
email: z.string().email(), // 邮箱格式
url: z.string().url(), // URL格式
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/) // 正则匹配
});
可选和默认值
ts
const optionalSchema = z.object({
required: z.string(), // 必填
optional: z.string().optional(), // 可选
withDefault: z.string().default("默认值") // 带默认值
});
枚举类型
ts
const enumSchema = z.object({
status: z.enum(["pending", "done", "cancelled"]),
priority: z.enum(["low", "normal", "high"]).default("normal")
});
tool 错误处理
js
import { DynamicStructuredTool } from "langchain";
import z from "zod";
const robustTool = new DynamicStructuredTool({
name: "read_file",
description: "读取文件内容",
schema: z.object({
path: z.string().describe("文件路径")
}),
func: async ({ path }) => {
try {
const content = await fs.readFile(path, "utf-8");
// 限制返回长度,避免Token超限
if (content.length > 5000) {
return `${content.slice(0, 5000)}\n...(文件内容过长,已截断)`;
}
return content;
} catch (error) {
// 返回结构化错误,让AI能理解
if (error.code === "ENOENT") {
return `错误:文件 "${path}" 不存在。请检查文件路径是否正确。`;
}
if (error.code === "EACCES") {
return `错误:没有权限读取文件 "${path}"。`;
}
return `错误:读取文件失败 - ${error.message}`;
}
}
});
const res = await robustTool.func({ path: './package.json' });
console.log(res);
自定义工具类
js
import { Tool } from "@langchain/core/tools";
class CurrentTimeTool extends Tool {
name = "get_current_time";
description = "获取当前时间,输入时区(可选),返回当前日期和时间";
async _call(input: string): Promise<string> {
const timezone = input || "Asia/Shanghai";
const now = new Date();
return `当前时间 (${timezone}): ${now.toLocaleString('zh-CN', { timeZone: timezone })}`;
}
}
const timeTool = new CurrentTimeTool();
const result = await timeTool.invoke("Asia/Shanghai");
console.log(result); // 输出: 当前时间 (Asia/Shanghai): 2026/3/31 7:19:16
记忆Memory
js
import { InMemoryChatMessageHistory } from "@langchain/core/chat_history";
import { HumanMessage } from "@langchain/core/messages";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { RunnableWithMessageHistory } from "@langchain/core/runnables";
import { ChatOpenAI } from "@langchain/openai";
import dotenv from 'dotenv';
dotenv.config();
// 配置 DeepSeek 模型
const model = new ChatOpenAI({
model: "deepseek-chat",
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: process.env.DEEPSEEK_API_BASE_URL,
}
});
// 创建消息历史存储
const messageHistories = {};
// 创建带历史记录的链
const prompt = ChatPromptTemplate.fromMessages([
["system", "你是一个友好的AI助手。"],
new MessagesPlaceholder("history"),
["human", "{input}"],
]);
const chain = prompt.pipe(model);
const chainWithHistory = new RunnableWithMessageHistory({
runnable: chain,
getMessageHistory: async (sessionId) => {
if (!messageHistories[sessionId]) {
messageHistories[sessionId] = new InMemoryChatMessageHistory();
}
return messageHistories[sessionId];
},
inputMessagesKey: "input",
historyMessagesKey: "history",
});
// 多轮对话测试
async function runConversation() {
const sessionId = "user-123";
// 第一轮对话
const result1 = await chainWithHistory.invoke(
{ input: "你好,我叫小明" },
{ configurable: { sessionId } }
);
console.log("AI:", result1.content);
// 第二轮对话
const result2 = await chainWithHistory.invoke(
{ input: "我是一名程序员" },
{ configurable: { sessionId } }
);
console.log("AI:", result2.content);
// 第三轮对话 - AI 会记住前面的信息
const result3 = await chainWithHistory.invoke(
{ input: "我叫什么名字?做什么工作?" },
{ configurable: { sessionId } }
);
console.log("AI:", result3.content);
// 查看记忆内容
const history = messageHistories[sessionId];
const messages = await history?.getMessages();
console.log("\n=== 记忆内容 ===");
messages?.forEach((msg, idx) => {
const role = msg instanceof HumanMessage ? "用户" : "AI";
console.log(`${idx + 1}. ${role}: ${msg.content}`);
});
}
runConversation();
Agents:智能体
js
import { AgentExecutor, createToolCallingAgent } from "@langchain/classic/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { DynamicTool } from "@langchain/core/tools";
import { ChatOpenAI } from "@langchain/openai";
import dotenv from 'dotenv';
dotenv.config();
// 配置 DeepSeek 模型
const model = new ChatOpenAI({
model: "deepseek-chat",
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: process.env.DEEPSEEK_API_BASE_URL,
}
});
// 1. 定义工具
// 天气工具
const weatherTool = new DynamicTool({
name: "get_weather",
description: "获取指定城市的天气信息。输入城市名称,返回天气情况。",
func: async (city) => {
const weatherData = {
"北京": "晴天,25°C,微风",
"上海": "多云,28°C,湿度60%",
"广州": "雷阵雨,30°C,注意带伞"
};
return weatherData[city] || `${city}的天气:晴转多云,温度适中`;
}
});
// 计算器工具
const calculatorTool = new DynamicTool({
name: "calculator",
description: "计算数学表达式。输入数学表达式如 '23 * 45',返回计算结果。",
func: async (expression) => {
try {
const result = eval(expression);
return `${expression} = ${result}`;
} catch (error) {
return `计算错误:${error.message}`;
}
}
});
// 2. 定义提示模板
// 注意:不能自定义 system 提示,必须使用 MessagesPlaceholder("agent_scratchpad")
const prompt = ChatPromptTemplate.fromMessages([
["system", "You are a helpful assistant"], // 必须是英文基础提示(兼容工具调用)
new MessagesPlaceholder("chat_history"),
["human", "{input}"],
new MessagesPlaceholder("agent_scratchpad"), // 必须保留,不能修改
]);
// 3. 创建 Agent
const agent = await createToolCallingAgent({
llm: model,
tools: [weatherTool, calculatorTool],
prompt,
});
// 4. 创建 Agent 执行器
const executor = new AgentExecutor({
agent,
tools: [weatherTool, calculatorTool],
maxIterations: 5,
verbose: true,
returnIntermediateSteps: true,
});
// 5. 执行
const result = await executor.invoke({
input: "北京天气怎么样?然后帮我算一下 23*45",
chat_history: [] // 传入 chat_history,用于支持聊天历史
});
console.log("\n最终答案:", result);
Langchain实现一个简单的带记忆的对话
ts
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, AIMessage, BaseMessage } from "@langchain/core/messages";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import dotenv from "dotenv";
dotenv.config();
// 自定义 BufferMemory 类
class BufferMemory {
private messages: BaseMessage[] = [];
private maxMessages: number = 20;
constructor(options?: { maxMessages?: number }) {
this.maxMessages = options?.maxMessages || 20;
}
async addUserMessage(content: string) {
this.messages.push(new HumanMessage(content));
this.trimMessages();
}
async addAIMessage(content: string) {
this.messages.push(new AIMessage(content));
this.trimMessages();
}
private trimMessages() {
if (this.messages.length > this.maxMessages) {
this.messages = this.messages.slice(-this.maxMessages);
}
}
async getHistory() {
return this.messages;
}
async clear() {
this.messages = [];
}
}
async function chatWithMemory() {
// 配置模型
const model = new ChatOpenAI({
model: "deepseek-chat",
temperature: 0.7,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: process.env.DEEPSEEK_API_BASE_URL
}
});
// 创建记忆实例
const memory = new BufferMemory({ maxMessages: 10 });
// 创建提示模板
const prompt = ChatPromptTemplate.fromMessages([
["system", "你是一个友好的AI助手,用中文回答问题。"],
new MessagesPlaceholder("history"),
["human", "{input}"]
]);
// 创建对话函数
async function chat(input: string): Promise<string> {
// 获取历史消息
const history = await memory.getHistory();
// 构建输入
const formattedPrompt = await prompt.formatMessages({
input,
history
});
// 调用模型
const response = await model.invoke(formattedPrompt);
const responseText = response.content as string;
// 保存到记忆
await memory.addUserMessage(input);
await memory.addAIMessage(responseText);
return responseText;
}
// 多轮对话
const response1 = await chat("我叫张三");
console.log("AI:", response1);
const response2 = await chat("我叫什么名字?");
console.log("AI:", response2); // 会记得名字
// 查看历史
const history = await memory.getHistory();
console.log("\n=== 对话历史 ===");
history.forEach((msg, idx) => {
const role = msg instanceof HumanMessage ? "用户" : "AI";
console.log(`${idx + 1}. ${role}: ${msg.content}`);
});
}
chatWithMemory();
什么时候用 LangChain?
| 场景 | 推荐度 | 原因 |
|---|---|---|
| 多轮对话 + 记忆管理 | ✅ 强烈推荐 | Memory组件非常方便 |
| 多工具 Agent 系统 | ✅ 强烈推荐 | 省去大量循环代码 |
| RAG 应用(文档+检索) | ✅ 强烈推荐 | 内置检索器、向量存储 |
| 生产级应用(需可观测性) | ✅ 强烈推荐 | LangSmith追踪、回调 |
| 快速原型开发 | ✅ 强烈推荐 | 组件组合,快速迭代 |