
LangChain.js + LangGraph.js 完整学习指南
面向前端工程师的 TypeScript AI 开发体系 · 2026 最新版
📍 为什么前端工程师要学这两个框架?
| 痛点 | LangChain.js + LangGraph.js 的解法 |
|---|---|
| 不会 Python,AI 开发门槛高 | 全 TypeScript/JavaScript,无学习成本迁移 |
| 不知道怎么调用 LLM | LangChain.js 提供统一模型接口(OpenAI/Claude/Gemini 同一 API) |
| 搭不出复杂 Agent 流程 | LangGraph.js 用状态机建模复杂工作流 |
| RAG/知识库不知道怎么做 | LangChain.js 内置文档加载→向量化→检索全流程 |
🗺️ 整体知识地图
LangChain.js 生态
├── langchain-core ← 基础抽象层(Runnable、LCEL、消息体系)
├── langchain ← 核心功能(Chain、Memory、Agent、RAG)
├── @langchain/openai ← 模型集成(OpenAI / ChatOpenAI)
├── @langchain/anthropic ← 模型集成(Claude)
├── @langchain/community ← 第三方集成(VectorDB、Tools)
└── @langchain/langgraph ← Agent 编排层(状态机/工作流)
架构分层
┌─────────────────────────────────────────────┐
│ 业务层 你的 Next.js / Node.js 应用 │
├─────────────────────────────────────────────┤
│ 编排层 @langchain/langgraph │ ← 复杂 Agent
├─────────────────────────────────────────────┤
│ 组件层 langchain(Chain/Memory/RAG) │ ← 功能模块
├─────────────────────────────────────────────┤
│ 核心层 langchain-core(Runnable/LCEL)│ ← 统一接口
├─────────────────────────────────────────────┤
│ 模型层 ChatOpenAI / ChatAnthropic │ ← LLM 调用
└─────────────────────────────────────────────┘
📚 学习路线(前端工程师专属)
阶段一:入门(1-2 周)
├── 环境搭建(npm + TypeScript 项目初始化)
├── 调通第一个 LLM 调用(ChatOpenAI)
├── 理解 Runnable 接口和 LCEL 管道语法
└── 实战:搭一个简单的问答 Chain
阶段二:进阶(2-4 周)
├── Prompt Templates(提示词模板设计)
├── Output Parsers(结构化输出)
├── Memory(对话历史管理)
├── Tools(工具调用)
└── 实战:搭一个多轮对话助手
阶段三:RAG 专项(2-3 周)
├── Document Loaders(加载 PDF/网页/Markdown)
├── Text Splitters(文档切片)
├── Embeddings(文本向量化)
├── Vector Stores(Pinecone/Chroma/FAISS)
└── 实战:搭一个知识库 Q&A 系统
阶段四:Agent 与 LangGraph(3-4 周)
├── 理解 Agent 模式(ReAct Loop)
├── LangGraph 核心概念(State/Node/Edge/Graph)
├── 条件路由与循环
├── Human-in-the-loop(人工介入)
├── Checkpointing(状态持久化)
└── 实战:搭一个多工具自主 Agent
阶段五:生产级实践(持续)
├── LangSmith(可观测性与调试)
├── 多 Agent 协作(Multi-Agent)
├── 流式输出(Streaming)
└── 与 Next.js API Route 集成
🧩 Part 1:LangChain.js 核心模块
1.1 环境安装
bash
# 基础包
npm install langchain @langchain/core
# 模型集成(按需安装)
npm install @langchain/openai
npm install @langchain/anthropic
npm install @langchain/google-genai
# 向量数据库(按需)
npm install @langchain/community
1.2 Runnable 接口:一切的基础
LangChain.js 的核心抽象。所有组件(LLM/Prompt/Parser/Chain)都实现了 Runnable 接口,拥有统一方法:
typescript
interface Runnable<Input, Output> {
invoke(input: Input): Promise<Output>; // 单次调用
stream(input: Input): AsyncIterable<Output>; // 流式输出
batch(inputs: Input[]): Promise<Output[]>; // 批量调用
}
前端类比:类似 Promise,统一了同步/异步接口;类似 React 组件,可以任意嵌套和组合。
1.3 LCEL(LangChain Expression Language)
用 | 管道符串联 Runnable,声明式构建 Chain:
typescript
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
const prompt = ChatPromptTemplate.fromTemplate("用一句话介绍{topic}");
const parser = new StringOutputParser();
// LCEL 管道:prompt → model → parser
const chain = prompt.pipe(model).pipe(parser);
const result = await chain.invoke({ topic: "React" });
// → "React 是 Facebook 开发的用于构建 UI 的 JavaScript 库。"
LCEL 常见模式:
typescript
import {
RunnableParallel,
RunnablePassthrough,
RunnableLambda,
} from "@langchain/core/runnables";
// 1. 并行执行
const parallel = RunnableParallel.from({
summary: summaryChain,
keywords: keywordsChain,
sentiment: sentimentChain,
});
// 2. 透传原始输入(常用于 RAG)
const ragChain = RunnableParallel.from({
context: retriever,
question: new RunnablePassthrough(),
}).pipe(answerChain);
// 3. 自定义函数节点
const transform = new RunnableLambda({
func: (input: string) => input.toUpperCase(),
});
1.4 Prompt Templates(提示词模板)
typescript
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
// ① 基础模板
const basicPrompt = ChatPromptTemplate.fromMessages([
["system", "你是一个专业的{role}。请用{style}风格回答。"],
["human", "{question}"],
]);
// ② 带历史记录的模板(多轮对话必用)
const chatPrompt = ChatPromptTemplate.fromMessages([
["system", "你是一个有帮助的助手。"],
new MessagesPlaceholder("chat_history"), // 注入对话历史
["human", "{input}"],
]);
// ③ Few-shot 模板(示例驱动)
const fewShotPrompt = ChatPromptTemplate.fromMessages([
["system", "你是代码审查专家。"],
["human", "审查这段代码:function add(a,b){return a+b}"],
["ai", "代码简洁但缺少类型注解,建议改为 TypeScript。"],
["human", "审查这段代码:{code}"], // 真实问题
]);
1.5 Output Parsers(输出解析器)
typescript
import { StringOutputParser, JsonOutputParser } from "@langchain/core/output_parsers";
import { StructuredOutputParser } from "@langchain/output-parsers";
import { z } from "zod";
// ① 字符串解析(最简单)
const strParser = new StringOutputParser();
// ② JSON 解析
const jsonParser = new JsonOutputParser();
// ③ Zod Schema 结构化解析(推荐)
const structuredParser = StructuredOutputParser.fromZodSchema(
z.object({
name: z.string().describe("人物姓名"),
age: z.number().describe("年龄"),
skills: z.array(z.string()).describe("技能列表"),
})
);
// 使用时需配合 format_instructions
const chain = prompt.pipe(model).pipe(structuredParser);
1.6 Memory(对话记忆)
typescript
import { BufferMemory, ConversationSummaryMemory } from "langchain/memory";
import { ConversationChain } from "langchain/chains";
// ① 缓冲记忆(保存完整历史)
const bufferMemory = new BufferMemory({
returnMessages: true,
memoryKey: "chat_history",
});
// ② 窗口记忆(只保留最近 k 轮)
const windowMemory = new BufferWindowMemory({
k: 5,
returnMessages: true,
});
// ③ 摘要记忆(LLM 自动总结,省 Token)
const summaryMemory = new ConversationSummaryMemory({
llm: new ChatOpenAI({ model: "gpt-4o-mini" }),
returnMessages: true,
});
// 配合 ConversationChain 使用
const chain = new ConversationChain({
llm: model,
memory: bufferMemory,
prompt: chatPrompt,
});
await chain.call({ input: "我叫 Alice" });
await chain.call({ input: "我叫什么名字?" }); // → "你叫 Alice"
1.7 Tools(工具)
Tools 是 Agent 调用外部能力的接口。
typescript
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";
// 定义自定义工具
const weatherTool = new DynamicStructuredTool({
name: "get_weather",
description: "查询指定城市的天气,用于回答天气相关问题",
schema: z.object({
city: z.string().describe("城市名称,如:北京、上海"),
}),
func: async ({ city }) => {
// 调用真实天气 API
const weather = await fetchWeatherAPI(city);
return `${city}今天${weather.condition},温度${weather.temp}℃`;
},
});
// 将工具绑定到模型
const modelWithTools = model.bindTools([weatherTool, searchTool]);
1.8 RAG(检索增强生成)
完整 RAG 流程:
文档 → Loader → Splitter → Embeddings → VectorStore → Retriever
查询 → Embeddings → 向量检索 → 召回文档 → 注入 Prompt → LLM → 答案
typescript
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { createRetrievalChain } from "langchain/chains/retrieval";
import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio";
// Step 1: 加载文档
const loader = new CheerioWebBaseLoader("https://example.com/docs");
const docs = await loader.load();
// Step 2: 切片
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
});
const splits = await splitter.splitDocuments(docs);
// Step 3: 向量化 + 存储
const embeddings = new OpenAIEmbeddings();
const vectorStore = await MemoryVectorStore.fromDocuments(splits, embeddings);
const retriever = vectorStore.asRetriever({ k: 4 });
// Step 4: 构建 RAG Chain
const qaPrompt = ChatPromptTemplate.fromMessages([
["system", "使用以下上下文回答问题,不知道就说不知道:\n\n{context}"],
["human", "{input}"],
]);
const combineChain = await createStuffDocumentsChain({ llm: model, prompt: qaPrompt });
const ragChain = await createRetrievalChain({
retriever,
combineDocsChain: combineChain,
});
const answer = await ragChain.invoke({ input: "文档说了什么?" });
🔄 Part 2:LangGraph.js 核心模块
2.1 核心思想
LangGraph.js 将 Agent 执行流程建模为有向图:
| 概念 | 类比 | 作用 |
|---|---|---|
| State(状态) | Redux store | 整个图共享的数据快照 |
| Node(节点) | 函数 / 组件 | 执行具体操作(调用 LLM、执行工具) |
| Edge(边) | 路由 / 条件 | 决定下一步走哪个节点 |
| Graph(图) | 工作流 | 将节点和边组装成可运行的 Agent |
| Checkpointer | 数据库 | 持久化状态,支持暂停/恢复 |
前端类比:就像 XState(状态机)+ Redux(状态管理)的结合,专为 AI Agent 设计。
2.2 状态定义(Annotation)
typescript
import { Annotation, MessagesAnnotation } from "@langchain/langgraph";
// 定义图的状态结构
const AgentState = Annotation.Root({
// 消息历史(内置 upsert Reducer)
...MessagesAnnotation.spec,
// 简单覆盖(新值替换旧值)
currentStep: Annotation<string>({
reducer: (_, next) => next,
default: () => "idle",
}),
// 累加器(数值累计)
retryCount: Annotation<number>({
reducer: (prev, next) => prev + next,
default: () => 0,
}),
// 列表追加
results: Annotation<string[]>({
reducer: (prev, next) => [...prev, ...next],
default: () => [],
}),
});
2.3 构建第一个 Graph(ReAct Agent)
typescript
import { StateGraph, END } from "@langchain/langgraph";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4o" }).bindTools([weatherTool, searchTool]);
const toolNode = new ToolNode([weatherTool, searchTool]);
// ---- 定义节点 ----
async function callAgent(state: typeof AgentState.State) {
const response = await model.invoke(state.messages);
return { messages: [response] };
}
// ---- 定义路由 ----
function routeAfterAgent(state: typeof AgentState.State) {
const lastMsg = state.messages[state.messages.length - 1];
// 有工具调用 → 去执行工具,否则 → 结束
if (lastMsg.tool_calls?.length) return "tools";
return END;
}
// ---- 构建图 ----
const graph = new StateGraph(AgentState)
.addNode("agent", callAgent)
.addNode("tools", toolNode)
.addEdge("__start__", "agent") // 入口 → agent
.addConditionalEdges("agent", routeAfterAgent) // 条件路由
.addEdge("tools", "agent") // 工具执行完 → 回 agent
.compile();
// ---- 运行 ----
const result = await graph.invoke({
messages: [{ role: "user", content: "北京今天天气怎么样?" }],
});
2.4 节点类型详解
typescript
// ① 普通节点(函数形式)
async function myNode(state: typeof AgentState.State) {
// 只需返回"增量更新",框架自动合并
return { currentStep: "processing" };
}
// ② 并行工具节点(内置)
import { ToolNode } from "@langchain/langgraph/prebuilt";
const toolNode = new ToolNode(tools); // 自动并行执行多个工具
// ③ 消息压缩节点(防止上下文溢出)
import { RemoveMessage } from "@langchain/core/messages";
async function compressMessages(state: typeof AgentState.State) {
if (state.messages.length < 20) return {};
const summary = await model.invoke([
new SystemMessage("用 2-3 句话总结对话要点"),
...state.messages.slice(0, -3),
]);
const toRemove = state.messages.slice(1, -3)
.map(m => new RemoveMessage({ id: m.id! }));
return { messages: [...toRemove, summary] };
}
2.5 条件路由(Conditional Edges)
typescript
// 简单路由
function route(state: AgentState): "tools" | "compress" | typeof END {
const last = state.messages.at(-1);
if (!last?.tool_calls?.length) return END;
if (state.messages.length > 20) return "compress";
return "tools";
}
// 复杂路由(返回对象配置跳转目标)
graph.addConditionalEdges("agent", route, {
tools: "tools",
compress: "compress",
[END]: END,
});
2.6 Human-in-the-loop(人机交互)
typescript
import { interrupt } from "@langchain/langgraph";
// 需要人工确认的节点
async function reviewNode(state: typeof AgentState.State) {
const lastMsg = state.messages.at(-1);
// 调用 interrupt() 暂停图执行,等待人工输入
const humanDecision = interrupt({
question: "是否批准以下操作?",
action: lastMsg?.content,
});
if (humanDecision === "approve") {
return { currentStep: "approved" };
} else {
return { currentStep: "rejected" };
}
}
// 恢复执行(传入人工决策)
const threadConfig = { configurable: { thread_id: "session-001" } };
await graph.invoke({ messages: [] }, threadConfig);
// 暂停后,恢复
await graph.invoke(
new Command({ resume: "approve" }),
threadConfig
);
2.7 Checkpointing(状态持久化)
typescript
import { MemorySaver } from "@langchain/langgraph";
import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres";
// ① 内存检查点(开发测试用)
const memorySaver = new MemorySaver();
// ② PostgreSQL 检查点(生产环境)
const pgSaver = PostgresSaver.fromConnString(
"postgresql://user:pass@localhost:5432/db"
);
// 编译时传入检查点
const graph = new StateGraph(AgentState)
// ... 添加节点边 ...
.compile({ checkpointer: memorySaver });
// 使用 thread_id 区分会话
const config = { configurable: { thread_id: "user-123-session-1" } };
await graph.invoke({ messages: [userMessage] }, config);
// 同一 thread_id → 自动恢复历史状态
await graph.invoke({ messages: [nextMessage] }, config);
2.8 多 Agent 协作(Multi-Agent)
typescript
import { createReactAgent } from "@langchain/langgraph/prebuilt";
// 创建专业子 Agent
const researchAgent = createReactAgent({
llm: model,
tools: [searchTool, webFetchTool],
messageModifier: "你是一个专业的研究员,负责收集信息",
});
const writerAgent = createReactAgent({
llm: model,
tools: [fileWriteTool],
messageModifier: "你是一个专业的写作者,负责撰写报告",
});
// 主图:协调子 Agent
const supervisorGraph = new StateGraph(AgentState)
.addNode("research", researchAgent)
.addNode("writer", writerAgent)
.addNode("supervisor", supervisorNode) // 决定下一步调用哪个子 Agent
.addEdge("__start__", "supervisor")
.addConditionalEdges("supervisor", routeToAgent)
.addEdge("research", "supervisor")
.addEdge("writer", "supervisor")
.compile();
2.9 LangGraph 适用场景判断
| 场景 | 是否推荐 LangGraph | 理由 |
|---|---|---|
| 单次 LLM 调用 | ❌ | 用 LCEL 就够了 |
| 简单线性流程(3步以内) | ❌ | 直接用 Chain |
| 2-3 个工具 + 条件分支 | ✅ | 刚好合适 |
| 多工具循环 + 人工审批 | ✅ | 优势明显 |
| 多 Agent 协作 | ✅ | 原生支持 |
| 需要暂停/恢复的长任务 | ✅ | Checkpointing 支持 |
🌊 Part 3:Streaming 流式输出
typescript
// LangChain.js 流式
const stream = await chain.stream({ topic: "TypeScript" });
for await (const chunk of stream) {
process.stdout.write(chunk);
}
// LangGraph.js 流式(支持多种模式)
// mode: "updates" 每个节点执行后推送增量
// mode: "values" 每步输出完整状态
// mode: "messages" 只推送消息 token
for await (const chunk of graph.stream(input, config, { streamMode: "messages" })) {
if (chunk.content) process.stdout.write(chunk.content);
}
// Next.js API Route 集成
export async function POST(req: Request) {
const { message } = await req.json();
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
for await (const chunk of chain.stream({ input: message })) {
controller.enqueue(encoder.encode(chunk));
}
controller.close();
},
});
return new Response(stream, {
headers: { "Content-Type": "text/event-stream" },
});
}
🔍 Part 4:LangSmith 调试与监控
typescript
// .env
LANGCHAIN_API_KEY=ls__xxxx
LANGCHAIN_TRACING_V2=true
LANGCHAIN_PROJECT=my-agent-project
// 代码中自动上报(无需改代码)
// 所有 invoke/stream 调用自动追踪到 LangSmith
// 手动标记关键节点
import { traceable } from "langsmith/traceable";
const myFunction = traceable(
async (input: string) => {
return await chain.invoke({ input });
},
{ name: "custom-chain", run_type: "chain" }
);
LangSmith 能看到什么:
- 每个 Chain/Node 的输入输出
- Token 消耗和延迟
- 报错栈追踪
- 多轮对话的完整执行路径
🚀 Part 5:实战项目推荐
项目 1:多轮问答助手(入门)
- 技术:LangChain.js + BufferMemory + ChatOpenAI
- 核心:LCEL 链 + 对话记忆
- 难度:⭐
项目 2:RAG 知识库问答(进阶)
- 技术:LangChain.js + Chroma/Pinecone + OpenAI Embeddings
- 核心:文档加载→向量化→检索→生成
- 难度:⭐⭐⭐
项目 3:自主 Agent(高级)
- 技术:LangGraph.js + ToolNode + 条件路由
- 核心:ReAct 循环 + 工具调用
- 难度:⭐⭐⭐⭐
项目 4:AI 营销自动化工作流(业务级)
- 技术:LangGraph.js + 多 Agent + Human-in-loop
- 流程:用户输入需求 → 研究 Agent 收集竞品 → 写作 Agent 生成文案 → 人工审批 → 发布
- 难度:⭐⭐⭐⭐⭐
📖 参考资源
| 资源 | 链接 |
|---|---|
| LangChain.js 官方文档 | https://js.langchain.com/docs/ |
| LangGraph.js 官方文档 | https://langchain-ai.github.io/langgraphjs/ |
| LangChain.js 中文教程 | https://js.langchain.ac.cn/ |
| LangSmith 平台 | https://smith.langchain.com/ |
| GitHub: langchainjs | https://github.com/langchain-ai/langchainjs |
| GitHub: langgraphjs | https://github.com/langchain-ai/langgraphjs |
| 前端工程师 RAG 实战 | https://juejin.cn/post/7548350039128358947 |
📅 整理时间:2026-04-16
📌 适用版本:LangChain.js v0.3.x · LangGraph.js v0.2.x