一、基础
LangChain.js用于构建基于大语言模型(LLM)的应用程序,让LLM不再局限于机器人,而是能读文档、查资料、调工具、做决策、执行任务的智能系统。
一套稳定、可组合、可观测的抽象:模型统一接口(agent)、工具(函数)、流程(LangGraph)、智能体(create_agent)。
"LangChain 1.0 + LangGraph + create_agent":
LangChain 1.0 是核心框架(模型抽象、提示词、工具、RAG 组件);
LangGraph 1.0 是官方编排运行时(把流程变成图,支持持久化、人工介入、流式);
create_agent是智能体的标准入口;
LangSmith 是官方可观测与评测平台(追踪每一步、评测智能体轨迹)。
系统架构:
交互层:集成WebSocket实现实时通信,支持文本/语音双模态输入
处理层:包含对话引擎、知识库、上下文管理器三大模块
数据层:部署向量数据库(如Chroma)与关系型数据库混合存储方案
装包:需要node版本22+
npm install langchain @langchain/core // 核心包
npm install @langchain/openai // 使用特定LLM提供商
npm install @langchain/anthropic
按需安装:
eg: npm install langchain @langchain/openai @langchain/core zod
二、基本流程
提词板→解析器→向量存储,文档加载→构建RAG→创建Chain→创建Agent→部署运行
详细说就是:提词板根据上下文,输入问题 → 再通过解析器,解析成json或对象 → 加载文档并嵌入模型中,构建向量库→ 构建RAG检索器,在向量库进行查找最相关内容作为上下文,再连同问题输入给LLM → 创建一个链来组合提示词、模型、解析器 → 引入agent智能体来感知输入,LLM决策,调用工具(可选) → 执行,获取结果,输出回答
1、提词板
提示词模板:根据上下文,输入问题
// 构建prompt import { PromptTemplate } from "langchain/prompts"; const prompt = PromptTemplate.fromTemplate(` 当前上下文: {context} 用户问题: {question} 请以中文简洁回答,不要编造信息。 `);
2、初始化模型
模型看到有好几种创建方式:
// 第一种 // (1、配置环境key export OPENAI_API_KEY="your-api-key" // (2、config配置LLM module.exports = { llmConfig: { apiKey: process.env.OPENAI_API_KEY, modelName: "gpt-3.5-turbo-16k" }, }; // (3、构建agent模型 const { ChatOpenAI } = require("langchain/chat_models/openai"); const llm = new ChatOpenAI(config.llmConfig); // 第二种 import { ChatOpenAI} from "langchain/openai"; const model = new ChatOpenAI({model: 'gpt-4o'}); // 第三种(官网的) import { initChatModel } from "langchain"; const model = await initChatModel('gpt-4o', { temperature: 0.5, timeout: 300, maxTokens: 30000, });
new ChatOpenAI():针对特定提供商(OpenAI)的传统初始化方式;
代码直接依赖
@langchain/openai包;切换模型提供商换import,eg:Anthropic
initChatModel():LangChain 推荐的、跨提供商的统一初始化接口;
通过字符串指定模型名称和提供商(如
"openai:gpt-4o"或"anthropic:claude-3-5-sonnet"),无需为每个提供商导入不同的类;如果只传模型名(如
"gpt-4o"),它会自动推断提供商(前提是安装了相应的集成包)
3、解析器
将输入解析成json或对象
// (1) json import { JsonOutputParser } from "langchain/output_parsers"; const parser = new JsonOutputParser({ schema: { type:'object', properties: { summary: {type: 'string'}, keywords: {type: 'string', items: {type:'string'}} confidence: {type: 'number'} }, required: ['summary','keywords'] } }) // (2)对象 import { StringOutputParser } from "langchain"; const chain = prompt.pipe(model).pipe(new StringOutputParser());
3、加载文档库,构建向量库
将加载的知识文档库嵌入到模型中,构建向量库
import { PDFLoader} from "langchain/document_loaders/fs/pdf"; import { OpenAIEmbeddings} from "langchain/embeddings/openai"; import { MemoryVectorStore} from "langchain/vectorstores/memory"; // 1、加载文档 const loader = new PDFLoader('docs/technical-guide.pdf'); // 要加载的技术文档pdf const docs = await loader.load(); // 2、创建嵌入模型 const embeddings = new OpenAIEmbeddings({oprnAIAPIKey: 'sk-...'}); // 3、构建向量库 const vectorStore = await MemoryVectorStore.fromDucuments(docs, embeddings);向量库:建议用Pinecone、Chroma、Weavite等
4、构建RAG检索器
在向量库中查找最相关内容,作为上下文输入给LLM
// 1、构建rag const retriever = vectorStore.asRetriever({ seatchType: 'similarity', k: 3 }) // 2、自定义 import { Runnable } from 'langChain'; class RetrieverRunnable extends Runnable { async invoke(input: any, options?: any) { const docs = await this.retriever.invoke(input.question); return { question: input.question, context: docs.map(d: Document) => d.pageContent).join('\n'), } constructor(private retriever: any) { super(); } } const retrieverRunnable = new RetrieverRunnable(retriever)chain模式:检索器创建后嵌入链中,无分支逻辑;(必须)
agent模式:检索器作为工具传入,由模型决定调用(用不用可选)
5、创建链
链是组件的线性组合,通常使用管道符
|连接提示词、模型和解析器。chain模式:LCEL
全流程按顺序执行,不会跳过任何步骤:接收问题→调RAG检索→调LLM回答→输出结果
// 1、创建链 const chain = prompt.pipe(model).pipe(new StringOutputParser()); // 2、创建链 const { LLMChain } = require("langchain/chains"); const chain = new LLMChain({ llm, prompt, outputKey: "answer" }); // 3、导入 import { RetrievalQAChain } from "langchain/chains"; const chain = RetrievalQAChain.fromLLM({ new OpenAI({ openAIApiKey: 'sk-...', temperature: 0.3}), retriever, { prompt: promptTemplate, returnSourceDocuments: true, // 返回原始文档用于调试 } }); // 4、自定义rag链 const chain = RunnableSequence.from({ retrieverRunnable, prompt, model, new StringOutputParser() });
6、创建agent(可选)
agent让模型具备工具调用能力,结合工具列表进行动态决策。
调用模型方法:
// 第一种 import { creatReactAgent} from "langchain/agents"; const agent = new creatReactAgent({ llm: model, tools: [searchTool, calcullatorTool] //参考下面的写工具 }) // 第二种(官网的) import { createAgent, tool } from "langchain"; //如果按需安装了,这样导入 // import { createAgent } from "langchain/agents"; // import { tool } from "@langchain/core/tools"; import * as z from "zod"; // (1、写工具(执行的方法+接收的参数结构) const getWeather = tool( (input)=> `It's always sunny in ${ input.city }`, { name: "get_weather", description: "Get the weather for a given city", schema: z.object({ city: z.string().describe("The city to get the weather for"), }), } ); // (2、构建agent const agent = createAgent({ model: "gpt-5.5", tools: [getWeather], systemPrompt: SYSTEM_PROMPT, checkpointer, });
7、记忆
给agent加记忆,让它在多轮交互中记住对话内容及上下文。
(大模型本身是无状态的,每次请求都是独立事件,不额外做记忆管理的话,第二轮它就会忘了第一轮说过什么。)
记忆分:
短期记忆(会话级:存当前会话消息,受上下文窗口限制);
长期记忆(跨会话:提炼用户偏好和关键词存入向量库,下次会话检索注入上下文)
方法:简单缓存、滑动窗口、摘要压缩、混合检索
简单缓冲:把历史消息拼进 prompt 发回去。eg:
ConversationBufferMemory(长对话会爆 token);滑动窗口:只保留最近 K 条消息。(简单但会有“上下文悬崖”,重要信息被挤掉就永远忘了);
摘要压缩:超限后让 LLM 把旧消息总结成摘要。(保留要点但损失细节,还多一次调用成本);
混合检索(RAG 式):短期用缓冲+摘要,长期用向量库存关键事实,按语义相似度检索相关记忆再注入。(目前比较扎实的架构)。
import { MemorySaver } from '@langchain/langgraph'; const checkpointer = new MemorySaver()作用:上下文连贯、跨会话个性化、多步任务状态执行
8、查询
链或agent:
// 执行链 const result = await chain.invoke({input:'tell me why'}) // 执行agent const result = await agent.invoke({ message:[ { role: ''user', content: '搜索最新资讯' } ] }) console.log(result.message)
三、名词、方法、库解释
1、schema
描述工具“该接收什么参数”的结构化定义,通常以 JSON Schema 形式呈现。
通常包含
name、description和parameters三部分:{ "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的实时天气。", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["city"] } } }type:参数对象类型,通常为 object;
properties:各参数定义,包括类型、描述、枚举值、默认值等;
required:必填参数列表;
2、zod
定义结构化输出 Schema 的首选方案。
核心作用:提前声明好字段名、类型、取值范围,让模型只能在这个框架里作答,避免返回格式漂移的 JSON。
运行时校验、类型推导、langchain原生支持
import { z } from "zod"; // 1. 定义 Schema const UserSchema = z.object({ name: z.string().describe("用户姓名"), age: z.number().int().min(0).max(150).describe("用户年龄"), city: z.string().describe("所在城市"), }); // 2. 绑定到模型 const structuredModel = model.withStructuredOutput(UserSchema);
.describe():字段描述会原样传给模型,相当于贴在字段上的“免费提示词”,写清楚模型输出更准。常见问题:
400错误——Schema 里用了
\p{...}或环视等高级正则,转成 JSON Schema 后会被服务端拒绝。排查思路:本地用zodToJsonSchema打印转换结果,把带正则的字段改成.describe()或.min().max()长度约束。
3、chain和agent区别
chain:写死的固定流程。(步骤顺序写好,每次执行固定)
agent:模型自己决定怎么执行流程。(把工具交给大模型,运行时根据问题动态决定调哪个工具 / 按什么顺序调 / 调几次)
(1chain:预定义操作序列
执行路径:硬编码,输入→检索→拼Prompt→LLM输出,每一步必执行,没有分支跳转。
工具调用:工具节点是预埋的固定环节,LLM无权决定要不要调、调哪个。
典型代码:用
|操作符合成 LCEL 链,如prompt | model | outputParser,清晰直观。适用场景:流程标准化、步骤固定的任务,如固定知识库问答、文档批量摘要、工单格式化。
特点:稳定、易调试、高性能、灵活性差
(2agent:模型驱动的决策控制器
执行路径:运行时动态决定,不固定。常识问题直接答,缺资料才调RAG或搜索,缺多份数据就连续多轮调用工具。
工具调用:工具统一放进工具列表,LLM自主判断何时调用、调用哪个、调用几次。
典型代码:用
create_agent或AgentExecutor创建,传入 LLM 和工具集即可。适用场景:用户提问多变、路径不确定、需按需调用搜索/数据库/代码执行等工具的任务。
特点:灵活性强、稳定性下降、成本高、调试难、输出不稳定
X、注意事项(写在最后)
1、装包可按需装;
2、工具需要写好,模型才能用准;
3、RAG效果问题常在切分,按文档类型试chunk_size、overlap;
4、提示词是软约束,限流、鉴权、PII过滤这类确定性逻辑用中间件;
5、langSmith要最开始建,记录每次模型调用和工具调用,出问题方便查;
6、模型切换是换字符串;
学习参考
1、官方:LangChain overview - Docs by LangChain
2、各种 AI 们(我的问答小能手
3、LangChain 入门教学:一张地图搞懂模型、链、RAG、图与智能体-阿里云开发者社区