从零开始LangChain:构建你的第一个AI应用工作流
引言
2022年ChatGPT横空出世,让全世界见识了大型语言模型(LLM)的魔力。但你知道吗?有一个叫LangChain的框架其实比ChatGPT还早,最近它发布了1.0+版本,成为了AI应用开发的“明星框架”。
LangChain是什么?拆开名字:Lang(语言) + Chain(链)。它把大语言模型和一系列任务节点像链条一样连接起来,形成一个工作流。就像n8n、Coze这些可视化工具把节点串起来一样,LangChain用代码的方式帮你搭建AI应用。
这篇文章我会带你从零开始,一步步用LangChain写几个小例子,从最简单的模型调用,到用“链”组合复杂的任务流程。所有代码都基于ES Module(type: "module"),你可以直接复制运行。
环境准备:先跑通一个最简单的例子
在开始之前,确保你安装了Node.js(18+版本),然后创建一个新项目,安装必要的依赖:
npm init -y
npm install dotenv langchain @langchain/deepseek
在package.json中加入 "type": "module",这样我们就可以使用import语法。
创建一个.env文件,放你的DeepSeek API密钥(如果没有可以去platform.deepseek.com申请):
DEEPSEEK_API_KEY=你的密钥
现在,写第一个脚本main.js:
import 'dotenv/config'
import { ChatDeepSeek } from '@langchain/deepseek'
// 初始化模型
const model = new ChatDeepSeek({
model: 'deepseek-reasoner',
temperature: 0, // 控制随机性,0表示最确定
})
// 调用模型
const res = await model.invoke('用一句话解释什么是RAG')
console.log(res.content)
运行node main.js,你应该能看到模型输出的回答。
这段代码做了什么?
ChatDeepSeek是一个“适配器”,LangChain用它来统一不同大模型的接口。以后换GPT、Claude,只需要改一下import和配置,其余代码几乎不用动。model.invoke是最核心的方法,把问题传给模型,然后得到回答。- API密钥从环境变量自动读取,不用写在代码里,安全又方便。
这就是LangChain最基础的用法:把大模型当成一个可调用的函数。
第一章:更灵活的提问——提示词模板
直接写死的提问太死板了。如果我想让模型扮演不同角色、限制回答长度,每次都拼接字符串会很麻烦。LangChain提供了PromptTemplate,像填空一样生成提示词。
新建1.js:
import 'dotenv/config'
import { ChatDeepSeek } from '@langchain/deepseek'
import { PromptTemplate } from '@langchain/core/prompts'
// 定义一个模板
const prompt = PromptTemplate.fromTemplate(`
你是一个{role}。
请用不超过{limit}字回答以下问题:
{question}
`)
// 填入具体内容
const promptStr = await prompt.format({
role: '前端面试官',
limit: '50',
question: '什么是闭包'
})
console.log('生成的提示词:', promptStr)
// 调用模型
const model = new ChatDeepSeek({
model: 'deepseek-reasoner',
temperature: 0.7,
})
const res = await model.invoke(promptStr)
console.log('回答:', res.content)
运行后,你会看到模型根据“前端面试官”的身份,用不超过50字解释了闭包。
- 如图
PromptTemplate让我们把提示词的结构和内容分离,方便复用。比如你可以换一个角色问同样的问题,只需改format的参数即可。
第二章:什么是“链”?用pipe连接节点
上面的例子还是两步走:先生成提示词,再调用模型。LangChain的核心理念是“链”(Chain),它可以把多个步骤像管道一样连接起来,成为一个可执行的单元。
新建2.js:
import 'dotenv/config'
import { ChatDeepSeek } from '@langchain/deepseek'
import { PromptTemplate } from '@langchain/core/prompts'
const model = new ChatDeepSeek({
model: 'deepseek-reasoner',
temperature: 0.7,
})
const prompt = PromptTemplate.fromTemplate(`
你是一个前端专家,用一句话解释:{topic}
`)
// 用 pipe 把 prompt 和 model 连接成一个链
const chain = prompt.pipe(model)
//打印chain可以看到它的类型为RunnableSequence,和它的节点
console.log(chain)
// 直接调用链,传入变量
const res = await chain.invoke({
topic: '闭包'
})
console.log(res.content)
- 执行效果图
- 执行打印chain
- 执行打印输出结果
注意看,prompt.pipe(model)返回了一个新的对象,它也是一个“可运行”的链。我们调用chain.invoke({ topic: '闭包' }),内部会自动执行:
- 用传入的
{topic: '闭包'}填充prompt模板,生成提示词。 - 把提示词传给model,得到回答。
- 返回最终结果。
整个过程就像工厂流水线:原材料(topic)进入第一道工序(prompt模板),产物(提示词)直接传给下一道工序(模型),最后产出成品(回答)。
这就是LangChain最基础的链:RunnableSequence(可运行序列)。你不需要手动调用两次,代码更简洁,逻辑更清晰。
第三章:组合多个链——复杂任务的工作流
现实中的AI任务往往不止一步。比如我想让模型先详细解释一个概念,然后把这个解释总结成三个要点。这需要两个步骤,而且第二步要用到第一步的输出。
LangChain提供了RunnableSequence来组合多个链。我们新建3.js:
import { ChatDeepSeek } from '@langchain/deepseek'
import { PromptTemplate } from '@langchain/core/prompts'
import { RunnableSequence } from '@langchain/core/runnables'
import 'dotenv/config'
const model = new ChatDeepSeek({
model: 'deepseek-reasoner',
temperature: 0.7,
})
// 第一步:详细解释概念
const explainPrompt = PromptTemplate.fromTemplate(`
你是一个前端专家,请详细介绍以下概念:{topic}
要求:覆盖定义、原理、使用方式,不超过300字。
`)
// 第二步:总结要点
const summaryPrompt = PromptTemplate.fromTemplate(`
请将以下前端概念解释总结为3个核心要点(每个要点不超过20字):
{explaination}
`)
// 分别构建两个链
const explainChain = explainPrompt.pipe(model)
//我们打印explainChain也可以看到它的类型和节点
console.log(explainChain)
const summaryChain = summaryPrompt.pipe(model)
// 用 RunnableSequence 组合它们
const fullChain = RunnableSequence.from([
// 第一步:输入 topic -> 得到详细解释
async (input) => {
const res = await explainChain.invoke({ topic: input.topic })
return res.content // 将解释传给下一步
},
// 第二步:拿到上一步的解释 -> 生成总结
async (explaination) => {
const res = await summaryChain.invoke({ explaination })
return `知识点:${explaination}\n总结:${res.content}`
},
])
// 执行完整链
const res = await fullChain.invoke({
topic: '闭包'
})
console.log(res)
- 效果图
- 打印explainChain
2.打印输出结果
这段代码稍微复杂一点,但逻辑很清晰:
explainChain:输入topic,输出详细解释。summaryChain:输入explaination(详细解释),输出总结。- 我们用
RunnableSequence.from([...])把两个步骤串起来。数组里的每个元素是一个函数,接收上一步的输出,返回下一步的输入。 - 最后调用
fullChain.invoke({ topic: '闭包' }),内部自动执行两步,并把最终结果返回。
运行后你会看到模型先给出了关于闭包的详细解释(不超过300字),然后给出了三个要点总结。整个流程自动化完成,无需人工介入。
深入理解:LangChain的适配器模式与可拔插设计
你可能注意到,所有代码中我们只引用了@langchain/deepseek这一个具体模型包。如果我想换成OpenAI的GPT,该怎么做?只需要:
npm install @langchain/openai
然后把import { ChatDeepSeek }改成import { ChatOpenAI },model参数稍作调整即可,其余代码几乎不用动。
这就是LangChain的“适配器模式”。它定义了一套统一的接口(如invoke、stream等),各个模型厂商通过适配器实现这些接口。这样一来,你的业务逻辑和具体模型解耦,大模型更新换代再快,你只需换一个适配器,不用重写应用。
总结
通过这几个小例子,我们走过了LangChain的入门之路:
- 基础调用:用适配器连接大模型,执行最简单的问答。
- 提示词模板:用
PromptTemplate动态构造输入,让提示词更灵活。 - 简单链:用
pipe把模板和模型连接起来,形成可复用单元。 - 复杂链:用
RunnableSequence组合多个链,实现多步骤工作流。
LangChain不仅仅是“链”,它还是一个完整的AI应用开发框架,提供了记忆、工具调用、代理(Agent)等高级功能。但无论多复杂的功能,底层都离不开我们今天学到的核心思想:把任务拆分成节点,用链条连接,让流程自动化。
现在你已经掌握了LangChain的基本功,可以尝试用它搭建更酷的应用了,比如文档问答机器人、自动化报告生成器等等。如果在实践中遇到问题,欢迎在评论区留言交流。