从零开始构建 LangChain 应用:理解提示词、链式调用与工作流编排

44 阅读8分钟

LangChain 是当前 AI 应用开发中最受欢迎的框架之一。它以“语言(lang)+ 链(chain)”为核心理念,通过模块化、可组合的方式,将大语言模型(LLM)的能力封装成可复用、可配置、可串联的工作单元。本文将围绕一套由浅入深的代码示例,系统讲解如何使用 LangChain 构建结构清晰、逻辑明确的 AI 应用,并完整保留原始代码中的注释,帮助读者深入理解每一步的设计意图。


环境准备与基础调用

在开始之前,我们需要完成基本的项目初始化和依赖安装:

npm init -y

package.json 中添加 "type": "module" 以启用 ES 模块语法,并安装必要的依赖:

npm install langchain @langchain/deepseek dotenv

.env 文件用于存放 API 密钥等敏感信息。LangChain 能自动从 process.env 中读取对应服务所需的密钥,无需手动传入。

最简单的调用方式如下(main.js):

import 'dotenv/config'
import { ChatDeepSeek } from '@langchain/deepseek'


const model = new ChatDeepSeek({
  model: 'deepseek-reasoner',
  temperature: 0
  // baseURL ? 
  // apiKey ? 不需要传入 会自动查找
  // 适配器模式
  // langchain 帮我们适配了市面上大多数的llm  deepseek Qwen
})

// invoke 执行调用
const res = await model.invoke('用一句话解释什么是RAG ?')
console.log(res.content)

这段代码展示了 LangChain 的适配器模式:无论底层使用的是 DeepSeek、Qwen 还是其他厂商的大模型,LangChain 都提供了统一的接口(如 ChatDeepSeekChatQwen),开发者只需更换导入语句和构造函数即可切换模型,极大降低了集成成本。注释中提到“apiKey 不需要传入 会自动查找”,这正是通过 dotenv/config 加载 .env 文件后,LangChain 自动从环境变量中读取密钥的能力。


引入提示词模板:结构化输入

直接拼接字符串作为提示词容易出错且难以维护。LangChain 提供了 PromptTemplate 模块,用于定义带有占位符的结构化提示模板。

1.js 中,我们定义了一个通用的角色问答模板:

import 'dotenv/config'
// 导入.env中的环境变量

import { ChatDeepSeek } from '@langchain/deepseek'
// 适配器 Provider  帮我们省去了适配工作
// 适配大模型也是工作量

import { PromptTemplate } from '@langchain/core/prompts'
//提示词模块


// fromTemplate static方法 是属于类的 不是实例的
const prompt = PromptTemplate.fromTemplate(`
  你是一个{role},
  请用不超过{limit}字回答以下问题:
  {question}
  `)

const promptStr = await prompt.format({
  role: '前端面试官',
  limit: '50',
  question: '什么是闭包'
})

// const promptStr2 = await prompt.format({
//   role: '后端面试官',
//   limit: '50',
//   question: '什么是MVC'
// })

// console.log(promptStr)


const model = new ChatDeepSeek({
  model: 'deepseek-reasoner',
  temperature: 0.7
})

const res = await model.invoke(promptStr)

console.log(res.content)

这里的关键在于注释所强调的:“fromTemplate static方法 是属于类的 不是实例的”。这意味着我们直接通过类调用该方法创建模板,而不需要先实例化 PromptTemplate。同时,注释也指出“适配大模型也是工作量”,LangChain 正是通过封装这些细节,让开发者聚焦于业务逻辑而非底层适配。

通过 .format() 方法,可以将实际参数注入模板,生成完整的提示字符串。这种方式不仅提升了提示词的可读性和复用性,还避免了手动字符串拼接可能引入的格式错误。


构建第一个 Chain:自动化提示生成与调用

随着应用复杂度提升,手动调用 .format() 再传给模型显得冗余。LangChain 的核心思想之一就是将多个操作节点连接成链(Chain) ,实现端到端的自动化。

2.js 中,我们使用 RunnableSequence 构建了一个简单的链:

// chain
// AI 业务是复杂的 任务的拆分 分步骤处理 每一步做到可执行可配置
// 连接起来 形成工作流 -> Agent -> AI应用
// chain 是有先后顺序 有流程的  组织起来的

import 'dotenv/config'
import { ChatDeepSeek } from '@langchain/deepseek'
import { PromptTemplate } from'@langchain/core/prommts'
import { RunnableSequence } from '@langchain/core/runnables'

const model = new ChatDeepSeek({
  model: 'deepseek-reasoner',
  temperature: 0.7 // 随机性
})

const prompt = PromptTemplate.fromTemplate(`
  你是一个前端专家,用一句话解释:{topic}
  `)
// prompt 模版生成节点 ->  model 代表LLM节点  -> invoke 结束节点 调用大模型 发起请求
// pipe 管道  连接节点 形成工作流 连接成一个顺序执行的链 chain
const chain = prompt.pipe(model)
console.log(chain, chain instanceof RunnableSequence)
// RunnableSequence 构造函数 验证chain是RunnableSequence的实例 说明它是一个可运行的有序工作流
// runnable sequencial   workflow
// SequencialChain


const response = await chain.invoke({
  topic: '闭包'
})
// 输入 -> prompt.format() -> 生成完整prompt -> model.invoke() -> 输出
/*
在这里没有手动调用prompt.format() 而是自己在chain.invoke({ topic: '闭包' }) 传入参数
这背后是langchain自动完成了格式化操作

langchain在RunnableSequence执行时 自动识别PromptTemplate需要的输入变量(如 topic)
并调用其内部的.invoke() 或 .format() 方法完成模版渲染 再将结果传递给下一个节点(LLM)

*/

console.log(response.content)

注释清晰地描述了 Chain 的本质:“AI 业务是复杂的,任务的拆分,分步骤处理,每一步做到可执行可配置,连接起来形成工作流”。prompt.pipe(model) 创建了一个顺序执行的工作流:输入 → 提示模板渲染 → 模型调用 → 输出。

特别值得注意的是,注释解释了为何无需手动调用 .format():“langchain在RunnableSequence执行时自动识别PromptTemplate需要的输入变量(如 topic),并调用其内部的 .invoke().format() 方法完成模版渲染,再将结果传递给下一个节点(LLM)”。这种自动化机制大大简化了开发流程。

此外,通过 chain instanceof RunnableSequence 的验证,确认了所构建的对象确实是一个可运行的有序工作流,体现了 LangChain 对类型安全和可预测性的重视。


多阶段 Chain:任务拆解与结果加工

真实场景中,单一调用往往无法满足需求。例如,我们可能希望先让模型详细解释一个概念,再对其输出进行摘要。这就需要多阶段 Chain

3.js 中,我们定义了两个独立的子链:

import 'dotenv/config'

import { ChatDeepSeek } from "@langchain/deepseek"
import { PromptTemplate } from '@langchain/core/prompts'
import { RunnableSequence } from "@langchain/core/runnables"
// AI 应用的编程方式
// LLM 黑盒 打开  key prompt
// langchain AI应用的工程化

const model = new ChatDeepSeek({
  model: 'deepseek-reasoner',
  temperature: 0.7
})

const explainPrompt = PromptTemplate.fromTemplate(`
  你是一个前端专家,请详细介绍以下概念: {topic}
  要求: 覆盖定义、原理、使用方法,不超过300字。
  `)

const summaryPrompt = PromptTemplate.fromTemplate(`
  请将以下前端概念解释总结为3个核心要点 (每点不超过20字):
  {explanation}
  `)

const explainChain = explainPrompt.pipe(model)
console.log(explainChain)

const summaryChain = summaryPrompt.pipe(model)


const fullChain = RunnableSequence.from([
  (input) => explainChain.invoke({topic: input.topic}).then(res => res.text),
  (explanation) => summaryChain.invoke({explanation}).then(res => `知识点: ${explanation} 总结: ${res.text}`)
])// 这里的explanation自动接收explainChain输出的解释文本


const response = await fullChain.invoke({
  topic: '闭包'
})

console.log(response)

注释点明了 LangChain 的定位:“AI 应用的编程方式”、“LLM 黑盒打开”、“langchain AI应用的工程化”。这表明 LangChain 不仅是调用工具,更是工程实践的载体。

在这个例子中,fullChain 由两个异步函数组成:

  • 第一个接收原始输入(如 { topic: '闭包' }),调用 explainChain 并提取 .text
  • 第二个接收上一步的输出(即详细解释文本),作为 summaryChain 的输入。

注释特别说明:“这里的explanation自动接收explainChain输出的解释文本”,体现了 Chain 之间数据流的自然衔接。

最终,整个流程实现了“解释 → 摘要”的两阶段处理,展示了如何将复杂任务分解为多个可管理的子任务,并通过 Chain 编排成完整工作流。


LangChain 的工程化优势

1. 统一接口,模型可插拔

无论是 DeepSeek、Qwen、OpenAI 还是本地部署的 Llama,LangChain 都通过 ChatModel 抽象层提供一致的 .invoke().stream() 等方法。切换模型只需修改两行代码:

// 从 DeepSeek 切换到 Qwen
import { ChatQwen } from '@langchain/qwen'
const model = new ChatQwen({ model: 'qwen-max', temperature: 0 })

这种“拔插式”设计让开发者能灵活应对模型迭代、成本变化或合规要求。

2. 提示工程结构化

PromptTemplate 不仅支持静态模板,还支持动态变量、条件逻辑,使提示词成为可版本控制、可测试的代码资产,而非散落在各处的魔法字符串。


总结:从调用到构建

回顾我们的四段代码及其详尽注释:

  • main.js 展示了最基础的模型调用,并强调了适配器模式与自动密钥加载;
  • 1.js 引入了结构化提示模板,突出 fromTemplate 的静态特性与复用价值;
  • 2.js 实现了自动化的单链流程,解释了 Chain 如何自动完成提示渲染;
  • 3.js 构建了多阶段、多任务的复合 Chain,体现任务拆解与数据流传递。

这正是 LangChain 学习路径的缩影:从“如何调用 LLM”走向“如何构建 AI 应用”

LangChain 并不试图取代 LLM,而是为其提供工程脚手架。它把提示词、模型、工具、记忆等元素抽象为可组合的积木,让开发者能像搭建流水线一样构建智能应用。在这个 AIGC 时代,掌握 LangChain 这样的框架,意味着你不仅能使用 AI,更能工程化地驾驭 AI

对于前端或全栈开发者而言,LangChain 的 Node.js 支持使其无缝融入现有技术栈。无论是构建智能客服、文档助手,还是自动化内容生成系统,LangChain 都提供了一条清晰、稳健的实现路径——而这一切,都始于一行 .pipe() 和一条精心设计的提示模板。