📚 目录
LangChain 是什么?
🤔 一句话解释
LangChain 是一个开源框架(不是编程语言),用于简化大语言模型(LLM)应用的开发。
🎯 定位与本质
| 是什么 | 不是什么 |
|
✅ 一个 JavaScript/TypeScript 库(npm 包) ✅ 一套工具和组件的集合 ✅ AI 应用开发的"脚手架" ✅ 提示词工程的工程化方案 |
❌ 不是编程语言 ❌ 不是 AI 模型本身 ❌ 不是云服务平台 ❌ 不是必须使用的 |
💡 它解决什么问题?
没有 LangChain 的痛点:
// ❌ 手动拼接提示词(容易出错)
const prompt = `你是翻译助手,把"${userInput}"从${lang1}翻译成${lang2}`;
// ❌ 手动调用 API
const response = await fetch("https://api.xxx.com/chat", {
method: "POST",
body: JSON.stringify({ messages: [{ role: "user", content: prompt }] }),
});
// ❌ 手动解析结果
const data = await response.json();
const text = data.choices[0].message.content;
// ❌ 每次都要重复这个流程...
有了 LangChain 的优雅方式:
// ✅ 定义可复用的模板
const prompt = ChatPromptTemplate.fromMessages([
["system", "You are a translator from {input_lang} to {output_lang}"],
["human", "{text}"],
]);
// ✅ 一行代码构建 Chain(自动化流程)
const chain = prompt.pipe(llm).pipe(new StringOutputParser());
// ✅ 简洁调用,自动处理所有细节
const result = await chain.invoke({
input_lang: "English",
output_lang: "Chinese",
text: "Hello",
});
🚀 为什么要使用 LangChain?
| 优势 | 说明 | 实际价值 |
|---|---|---|
| 标准化 | 统一的 API 和设计模式 | 降低学习成本,代码更易维护 |
| 模块化 | Prompt、LLM、Parser 可独立组合 | 灵活扩展,复用性强 |
| 抽象化 | 屏蔽底层 API 调用细节 | 专注业务逻辑,不用关心 HTTP 请求 |
| 工程化 | 提供错误处理、重试、流式输出等 | 生产级别的可靠性 |
| 多模型支持 | 轻松切换 OpenAI、DeepSeek、Claude 等 | 不被单一供应商绑定 |
🎨 核心概念速览
LangChain 把 AI 应用开发分解成 3 个核心组件:
1. Prompt Template(提示词模板)
↓ 格式化用户输入
2. LLM(大语言模型)
↓ 生成 AI 响应
3. Output Parser(输出解析器)
↓ 格式化 AI 输出
最终结果
就像搭积木一样,用 .pipe() 把组件连接起来,形成一条 Chain(链)。
🎯 适合什么场景?
✅ 适合使用 LangChain 的场景:
- 构建聊天机器人、智能客服
- 文档分析、信息提取
- 内容生成(文章、代码、翻译)
- 复杂推理任务(需要 Chain of Thought)
- 需要结构化输出的场景(JSON 格式)
- 需要集成多个 AI 模型的应用
⚠️ 可能不需要 LangChain 的场景:
- 只是简单调用一次 AI(直接用 API 就够了)
- 对性能要求极致(框架有一定开销)
- 团队完全没有 Node.js/Python 基础
🌍 LangChain 生态
LangChain 有两个官方版本:
- LangChain.js (JavaScript/TypeScript) - 本文档使用的版本
- LangChain Python (Python) - 原始版本,功能更丰富
两者核心概念一致,API 设计相似,学会一个就能快速上手另一个。
📖 本文档的目标
通过 6 个实战示例,让你掌握:
- ✅ 如何用 LangChain 构建 AI 应用
- ✅ 提示词工程的核心技巧
- ✅ 结构化输出的实现方法
- ✅ 从简单对话到复杂推理的完整路径
现在你已经知道 LangChain 是什么了,接下来让我们动手搭建环境,开始实战! 👇
0. 🚀 快速开始:用 Trae 搭建实践环境
💡 学习编程最重要的是动手实践!
本文档提供的所有示例代码都可以通过 Trae AI 编辑器的 Solo (Builder) 模式一键生成,让你在 5 分钟内快速搭建起完整的学习环境。
📋 环境要求
- Node.js: v18.0.0 或更高版本(推荐使用 v20.x)
- 包管理器: npm 或 pnpm
- API Key: DeepSeek API Key(免费注册:platform.deepseek.com)
🛠️ 使用 Trae 一键搭建环境
步骤 1: 唤起 Trae Builder 模式
- 打开 Trae 编辑器
- 按下
Cmd + I(macOS) 或Ctrl + I(Windows) - 或切换到 Builder (Solo) 模式
步骤 2: 复制以下提示词发送给 Trae
我想学习 LangChain,请帮我在当前目录下搭建一个 Node.js 学习环境:
1. 创建 package.json,指定 Node.js 版本为 18+,使用 ES Module (type: "module")
2. 安装以下依赖:
- langchain (核心库)
- @langchain/deepseek (DeepSeek 集成)
- @langchain/core (核心组件)
- zod (结构化输出验证)
- dotenv (环境变量管理)
3. 创建示例代码文件(请写出完整可运行的代码):
- src/simple-llm-app.js: 实现一个英中翻译的流式输出 Chain
- src/cot.js: 实现 Chain of Thought 思维链推理案例
- src/few-shot-learning.js: 实现 Few-Shot Learning 少样本学习案例
- src/sentiment-analysis.js: 实现情感分析的结构化输出案例
- src/structure-output.js: 实现信息提取的 Zod Schema 案例
4. 创建 .env 文件,内容为:
DEEPSEEK_API_KEY=
并在注释中提示需要在 platform.deepseek.com 获取 API Key
5. 创建 .gitignore 文件,忽略 node_modules 和 .env
完成后,告诉我如何运行这些示例。
步骤 3: 配置 API Key
- 访问 DeepSeek 开放平台 注册账号
- 创建 API Key(新用户有免费额度)
- 打开项目中的
.env文件 - 将获取的 API Key 填入:
DEEPSEEK_API_KEY=sk-your-api-key-here
步骤 4: 运行示例
# 基础翻译示例(流式输出)
node src/simple-llm-app.js
# 思维链推理示例
node src/cot.js
# 少样本学习示例
node src/few-shot-learning.js
# 情感分析示例(结构化输出)
node src/sentiment-analysis.js
# 信息提取示例
node src/structure-output.js
📦 依赖包说明
| 依赖包 | 版本建议 | 用途 |
|---|---|---|
langchain | latest | LangChain 核心库 |
@langchain/deepseek | latest | DeepSeek 模型集成 |
@langchain/core | latest | Prompt、Parser 等核心组件 |
zod | latest | TypeScript-first 的数据验证库 |
dotenv | latest | 环境变量管理 |
🎯 为什么选择 Trae + Solo 模式?
✅ 零配置烦恼: 无需手动查文档、调版本、配依赖
✅ 完整可运行: 生成的代码包含完整的导入、注释和错误处理
✅ 快速迭代: 随时可以让 Trae 修改代码、添加新功能
✅ 边学边问: 遇到不懂的概念,直接选中代码问 Trae
💡 学习建议
- 按顺序运行: 从
simple-llm-app.js开始,逐步理解基础概念 - 修改参数实验: 尝试修改 temperature、prompt 等参数,观察输出变化
- 提出问题: 选中代码片段,问 Trae "这段代码是做什么的?"
- 扩展功能: 告诉 Trae "帮我添加一个 xxx 功能"
- 结合本文档: 运行代码的同时,对照本文档理解原理
1. LangChain 基本使用语法
1.1 基础依赖与初始化
// 必要的导入
import { ChatDeepSeek } from "@langchain/deepseek";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import "dotenv/config";
// 初始化 LLM(大语言模型)
const llm = new ChatDeepSeek({
model: "deepseek-chat",
temperature: 0.7, // 控制输出的随机性,0-1 之间
});
核心参数说明:
model: 指定使用的模型名称temperature: 温度参数0: 确定性输出,适合分类、信息提取等任务0.7: 平衡创造性和确定性,适合对话、翻译1.0: 更具创造性,适合创作类任务
1.2 Chain(链)的构建方式
Chain 是 LangChain 的核心概念,通过 .pipe() 方法连接各个组件:
// 基本 Chain 结构:Prompt -> LLM -> Output Parser
const chain = prompt.pipe(llm).pipe(new StringOutputParser());
工作流程:
prompt: 构造提示词模板llm: 将提示词发送给大模型outputParser: 解析模型输出
1.3 调用方式
// 方式1:invoke - 一次性获取完整结果
const result = await chain.invoke({
input_language: "English",
output_language: "Chinese",
text: "Hello",
});
// 方式2:stream - 流式输出(适合长文本)
const stream = await chain.stream({ text: "Hello" });
for await (const chunk of stream) {
process.stdout.write(chunk);
}
2. 提示词与输入格式化
2.1 基础提示词模板(ChatPromptTemplate)
格式一:多角色对话模板
const prompt = ChatPromptTemplate.fromMessages([
[
"system",
"You are a helpful assistant that translates {input_language} to {output_language}.",
],
["human", "{text}"],
]);
角色说明:
system: 系统提示词,定义 AI 的角色、任务和规则human: 用户输入内容ai: AI 的回复(多轮对话时使用)
变量插值:
- 使用
{变量名}占位符 - 调用时通过对象传入:
chain.invoke({ input_language: "English", text: "Hello" })
格式二:使用 Message 类构造
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
const messages = [
new SystemMessage("你是一个资深工程师..."),
new HumanMessage("如何优化网页性能?"),
];
const result = await llm.invoke(messages);
2.2 Few-Shot 提示词模板(少样本学习)
Few-Shot Learning 是通过提供示例来"教会"模型特定的任务格式。
import { FewShotPromptTemplate, PromptTemplate } from "@langchain/core/prompts";
// 1. 定义单个示例的格式
const examplePrompt = PromptTemplate.fromTemplate(
"Question: {question}\nAnswer: {answer}"
);
// 2. 准备示例数据
const examples = [
{
question: "给 function add(a, b) { return a + b; } 写注释",
answer:
"/** 两个数字相加求和\n * @param {number} a\n * @param {number} b\n * @returns {number} */",
},
{
question: "给 function getUser(id) { return db.findUserById(id); } 写注释",
answer:
"/** 根据ID从数据库中获取用户\n * @param {string} id\n * @returns {Object|null} */",
},
];
// 3. 创建 Few-Shot 模板
const prompt = new FewShotPromptTemplate({
examples: examples,
examplePrompt: examplePrompt,
suffix: "Question: {input}", // 用户的实际输入
inputVariables: ["input"],
});
使用场景:
- 代码注释生成
- 特定格式的文本生成
- 风格模仿
- 数据转换
注意事项:
- 示例中包含花括号
{}时需要转义:\{\}→{{}}} - 示例数量通常 2-5 个即可,太多会消耗过多 token
2.3 Chain of Thought(思维链)提示词
通过精心设计的 System Prompt 引导模型进行逐步推理:
const systemPrompt = `你是一个负责排查网页性能问题的资深工程师。
请使用 Chain-of-Thought(连锁思维)在内部系统性地分析问题。
输出格式严格分为两部分:
1) Reasoning Summary: 一段简短的思考过程概述
2) Final Answer: 按照步骤给出可操作的建议
a) 性能监控方法
b) 数据分析要点
c) 找到瓶颈后的解决方案
d) 验证方法
`;
const messages = [
new SystemMessage(systemPrompt),
new HumanMessage("如果一个网页加载速度慢,该如何处理?"),
];
CoT 的关键要素:
- 角色设定: 明确 AI 的专业身份
- 推理引导: 要求模型展示思考过程
- 输出结构: 定义清晰的输出格式
- 步骤化: 将复杂问题分解为多个步骤
3. 输出格式化方法
3.1 基础输出解析器(StringOutputParser)
将 LLM 返回的 ChatMessage 对象转换为纯字符串:
import { StringOutputParser } from "@langchain/core/output_parsers";
const chain = prompt.pipe(llm).pipe(new StringOutputParser());
const result = await chain.invoke({ text: "Hello" });
// result 是 string 类型
适用场景:
- 简单的文本生成
- 对话系统
- 翻译任务
3.2 结构化输出(withStructuredOutput + Zod)
强制 LLM 输出符合特定结构的 JSON 数据。
3.2.1 基本用法
import { z } from "zod";
// 1. 定义 Zod Schema
const userProfileSchema = z.object({
name: z.string().describe("用户的姓名"),
age: z.number().optional().describe("用户的年龄"),
gender: z.enum(["male", "female", "other", "unknown"]),
skills: z.array(z.string()).describe("技能列表"),
});
// 2. 绑定到 LLM
const structuredLlm = llm.withStructuredOutput(userProfileSchema);
// 3. 构建 Chain
const chain = prompt.pipe(structuredLlm);
// 4. 调用
const result = await chain.invoke({
introduction: "我叫张三,28岁...",
});
// result 是一个类型安全的 JavaScript 对象
console.log(result.name); // "张三"
console.log(result.skills); // ["Node.js", "React"]
3.2.2 Zod Schema 常用字段类型
| Zod 类型 | 说明 | 示例 |
|---|---|---|
z.string() | 字符串 | z.string().describe("姓名") |
z.number() | 数字 | z.number().min(1).max(10) |
z.boolean() | 布尔值 | z.boolean().describe("是否同意") |
z.enum([...]) | 枚举值 | z.enum(["low", "medium", "high"]) |
z.array(...) | 数组 | z.array(z.string()) |
z.object({...}) | 嵌套对象 | z.object({ city: z.string() }) |
.optional() | 可选字段 | z.string().optional() |
.describe("...") | 字段描述 | 帮助 LLM 理解字段含义 |
3.2.3 实战案例:情感分析
const sentimentSchema = z.object({
category: z.enum(["褒义", "贬义", "中性"]).describe("情感分类"),
intensity: z.number().min(1).max(10).describe("情感强烈程度 (1-10)"),
reason: z.string().describe("判断理由,引用关键词"),
});
const structuredLlm = llm.withStructuredOutput(sentimentSchema);
const chain = prompt.pipe(structuredLlm);
const result = await chain.invoke({
text: "这家餐厅的服务太棒了!",
});
// 输出:
// {
// "category": "褒义",
// "intensity": 9,
// "reason": "关键词'太棒了'表达了强烈的赞扬"
// }
3.2.4 实战案例:日程信息提取
const calendarEventSchema = z.object({
eventName: z.string().describe("事件名称"),
date: z.string().describe("日期时间,格式:YYYY-MM-DD HH:mm"),
location: z.string().optional().describe("地点"),
participants: z.array(z.string()).describe("参与人员"),
priority: z.enum(["low", "medium", "high"]).describe("优先级"),
});
const result = await chain.invoke({
text: "下周五下午3点,我和老张、小李要在星巴克开会,讨论新项目架构,这事儿非常重要!",
current_time: new Date().toLocaleString(),
});
// 输出:
// {
// "eventName": "新项目架构讨论会",
// "date": "2025-12-06 15:00",
// "location": "星巴克",
// "participants": ["老张", "小李"],
// "priority": "high"
// }
结构化输出的优势:
- ✅ 类型安全: 自动类型校验,避免运行时错误
- ✅ 格式保证: LLM 必须输出符合 Schema 的数据
- ✅ 易于集成: 可直接用于后续业务逻辑
- ✅ 自动解析: 无需手动
JSON.parse()
技术原理:
- 依赖模型的 Tool Calling (Function Calling) 能力
- LangChain 将 Zod Schema 转换为函数定义
- 模型被强制调用该函数并返回符合格式的参数
4. 核心概念与最佳实践
4.1 核心组件关系图
用户输入
↓
PromptTemplate(格式化输入)
↓
LLM(大语言模型推理)
↓
OutputParser(格式化输出)
↓
最终结果
4.2 温度参数选择指南
| 任务类型 | 推荐温度 | 说明 |
|---|---|---|
| 信息提取、分类 | 0 - 0.1 | 需要确定性输出 |
| 翻译、问答 | 0.3 - 0.7 | 平衡准确性和流畅性 |
| 创意写作 | 0.7 - 1.0 | 需要更多随机性 |
4.3 提示词工程最佳实践
✅ 好的提示词
const goodPrompt = `你是一个专业的代码审查工程师。
任务:分析用户提交的代码,找出潜在问题。
输出格式:
1. 安全问题(如果有)
2. 性能问题(如果有)
3. 可维护性建议
4. 总体评分(1-10)
要求:
- 每个问题需指出具体行号
- 给出修复建议
- 如果没有问题,明确说明"无问题"
`;
特点:
- ✅ 明确角色定位
- ✅ 清晰的任务描述
- ✅ 结构化的输出格式
- ✅ 具体的约束条件
❌ 不好的提示词
const badPrompt = "帮我看看这段代码有没有问题";
问题:
- ❌ 过于模糊
- ❌ 没有输出格式要求
- ❌ 没有评判标准
4.4 Chain 复用与扩展
// 基础 Chain
const translationChain = prompt.pipe(llm).pipe(new StringOutputParser());
// 可以用同一个 Chain 处理不同输入
await translationChain.invoke({
input_language: "English",
output_language: "Chinese",
text: "Hello",
});
await translationChain.invoke({
input_language: "Japanese",
output_language: "English",
text: "こんにちは",
});
4.5 错误处理
try {
const result = await chain.invoke({ text: "..." });
console.log(result);
} catch (error) {
if (error.message.includes("API key")) {
console.error("请检查 .env 文件中的 DEEPSEEK_API_KEY");
} else if (error.message.includes("rate limit")) {
console.error("API 调用频率超限,请稍后重试");
} else {
console.error("未知错误:", error);
}
}
4.6 性能优化建议
- 使用流式输出: 对于长文本生成,使用
stream()提升用户体验 - 合理设置温度: 确定性任务使用低温度,减少不必要的随机性
- 缓存提示词: 对于固定的提示词模板,可以预先构建 Chain
- 批量处理: 使用
chain.batch([input1, input2, ...])批量处理多个输入
5. 完整示例索引
📁 Demo 文件说明
| 文件名 | 核心知识点 | 适合场景 |
|---|---|---|
simple-llm-app.js | 基础 Chain、PromptTemplate、流式输出 | 翻译、对话 |
cot.js | Chain of Thought、SystemMessage | 复杂推理任务 |
few-shot-learning.js | Few-Shot Learning、示例学习 | 代码生成、格式转换 |
sentiment-analysis.js | 结构化输出、枚举类型 | 文本分类 |
structure-output.js | Zod Schema、信息提取 | 数据提取 |
structured-output-zod.js | 复杂结构化输出、日程提取 | 实体识别 |
6. 快速速查表
导入速查
// 模型
import { ChatDeepSeek } from "@langchain/deepseek";
// 提示词
import {
ChatPromptTemplate,
PromptTemplate,
FewShotPromptTemplate,
} from "@langchain/core/prompts";
// 消息类型
import {
HumanMessage,
SystemMessage,
AIMessage,
} from "@langchain/core/messages";
// 输出解析
import { StringOutputParser } from "@langchain/core/output_parsers";
// 结构化输出
import { z } from "zod";
// 环境变量
import "dotenv/config";
常用模式速查
// 模式1:简单对话
const chain = ChatPromptTemplate
.fromMessages([["system", "..."], ["human", "{input}"]])
.pipe(llm)
.pipe(new StringOutputParser());
// 模式2:结构化输出
const structuredLlm = llm.withStructuredOutput(schema);
const chain = prompt.pipe(structuredLlm);
// 模式3:Few-Shot
const fewShotPrompt = new FewShotPromptTemplate({
examples: [...],
examplePrompt: PromptTemplate.fromTemplate("..."),
suffix: "{input}",
inputVariables: ["input"],
});
7. 学习建议
- 从简单开始: 先掌握
simple-llm-app.js的基础流程 - 理解 Prompt Engineering: 提示词设计是 LangChain 的核心
- 实践结构化输出:
withStructuredOutput是生产环境的必备技能 - 阅读官方文档: LangChain.js Documentation
- 实验不同模型: 尝试不同的 temperature 和 model 参数
8. 常见问题 FAQ
Q1: 如何选择 invoke 还是 stream?
- invoke: 需要等待完整结果后再处理(如结构化输出)
- stream: 需要实时展示结果(如聊天界面)
Q2: withStructuredOutput 报错怎么办?
- 确保模型支持 Tool Calling(DeepSeek V3 支持)
- 检查
@langchain/deepseek版本是否最新 - 确认 Zod Schema 定义正确
Q3: Few-Shot 的示例数量如何选择?
- 通常 2-5 个示例即可
- 示例质量比数量更重要
- 注意 token 消耗
Q4: 如何调试 Chain?
// 打印格式化后的提示词
const formatted = await prompt.format({ input: "test" });
console.log(formatted);
// 单独测试 LLM
const result = await llm.invoke([new HumanMessage("test")]);
console.log(result);
9. 🎉 开始你的 LangChain 实践之旅
不要只是阅读,马上动手!
最后的建议: LangChain 的本质是提示词工程的工程化。掌握好提示词设计,你就掌握了 80% 的 LangChain。
📖 看懂文档 ≠ 会用技术
💻 写出代码 ≠ 理解原理
🚀 动手实践 = 真正掌握
现在就开始:
-
⚡ 5 分钟快速开始
- 打开 Trae,切换到 Solo 模式
- 复制第 0 章的提示词
- 让 AI 帮你生成完整的学习环境
-
🎯 30 分钟核心实践
- 运行所有 6 个示例代码
- 修改提示词,观察输出变化
- 尝试调整 temperature 参数
-
🔥 1 小时深度学习
- 实现一个自己的应用场景(如:简历解析、文章摘要)
- 结合 Few-Shot 和结构化输出
- 使用 Chain of Thought 解决复杂问题
实践挑战建议
🥉 初级挑战
- 实现一个多语言翻译器(支持 3 种以上语言)
- 创建一个代码注释生成器(支持多种编程语言)
- 做一个简单的情感分析工具
🥈 中级挑战
- 实现一个智能客服问答系统(使用 Few-Shot)
- 创建一个简历解析工具(提取姓名、技能、经验等)
- 做一个文章摘要生成器(包含关键词提取)
🥇 高级挑战
- 实现一个多轮对话的面试官(记录上下文)
- 创建一个代码审查助手(使用 Chain of Thought)
- 做一个个性化的学习计划生成器
遇到问题?
- 代码报错: 检查 Node.js 版本和依赖是否正确安装
- API 调用失败: 确认
.env文件中的 API Key 是否正确 - 输出不符合预期: 优化提示词,增加更明确的指令和示例
- 不理解概念: 选中代码问 Trae,或回到本文档对应章节
分享你的成果
如果你完成了某个挑战,或者创建了有趣的应用,欢迎分享:
- 📝 写一篇实践总结
- 💡 在技术论坛分享你的经验
- 🤝 帮助其他正在学习的开发者
🌟 记住: 最好的学习方式不是收藏文档,而是打开编辑器,写下第一行代码。
LangChain 不生产智能,它是连接你的创意与 AI 能力的桥梁。而 Trae,就是帮你快速架起这座桥梁的最佳工具。
现在就开始你的 AI 应用开发之旅吧!🚀