从零到一:开启 LangChain 的 AI 工程化之旅

引言:为什么在 2025 年我们需要 LangChain?

2022 年底,ChatGPT 的横空出世标志着大模型(LLM)时代的到来。但在实际开发中,我们很快发现:直接调用大模型接口就像是在裸奔。 当你的业务逻辑变得复杂------需要动态构造提示词、需要串联多个任务、需要根据不同模型进行适配时,简单的 fetch 或官方 SDK 就会显得捉襟见肘。

这正是 LangChain 存在的意义。它不仅是一个 AI 开发框架,更是一套关于 "如何构建 AI 应用" 的方法论。

第一层:基础适配------让 LLM "拔插式"接入

在传统的开发模式中,如果你想从 OpenAI 切换到 DeepSeek,可能需要重写大量的接口调用逻辑。LangChain 通过适配器模式(Adapter Pattern)解决了这个问题。

1.1 环境搭建与依赖

基于 Node.js 环境,我们首先在 package.json 中配置 "type": "module",并安装核心包:

Bash 复制代码
pnpm i langchain @langchain/deepseek dotenv

1.2 像配置驱动一样配置模型

通过 dotenv 管理环境变量,代码会自动识别.env文件中的 DEEPSEEK_API_KEY

JavaScript 复制代码
import { ChatDeepSeek } from '@langchain/deepseek';

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

1.3 实战:如何"一行代码"换模型?

这是最体现工程化价值的地方。 假设今天 DeepSeek 维护,你需要紧急切换到 OpenAI,你只需要做两件事:

  1. 安装新适配器pnpm add @langchain/openai
  2. 修改导入与实例化
JavaScript 复制代码
// 只需要改动这两行
import { ChatOpenAI } from '@langchain/openai'; 

const model = new ChatOpenAI({ model: 'gpt-4o' }); 

// --- 以下所有业务代码一个字都不用改 ---
const res = await model.invoke("什么是闭包?");
console.log(res.content);

为什么能这么快?

因为在 LangChain 的世界里,所有的模型对象(model)都继承自同一个基类。它们拥有统一的接口规范:无论底层是 DeepSeek 还是 OpenAI,它们都认识 .invoke()。这种解耦意味着你的业务逻辑(Chain、Agent、Tooling)被保护在一个稳定的"外壳"里,不受底层模型更迭的影响。

核心价值: 此时的 LLM 变得可拔插。你可以随时通过更改一行代码,将 DeepSeek 换成 Anthropic 或其他模型,而不需要改动核心业务逻辑。

第二层:提示词工程------将"黑盒"转化为结构化资产

在 AI 应用开发中,开发者常说 LLM 是一个"黑盒"。要打开这个黑盒,关键就在于 Prompt(提示词) 。LangChain 并不是简单地发送一段话给模型,而是通过工程化的手段,将提示词转化为可复用、可变量化、可维护的模板

2.1 从"硬编码"到"模板化"

在早期的 AI 开发中,我们可能会直接拼凑字符串。但在 LangChain 中,我们使用 PromptTemplate

JavaScript 复制代码
import { PromptTemplate } from '@langchain/core/prompts';

// 使用静态方法 fromTemplate 创建模板
const prompt = PromptTemplate.fromTemplate(`
    你是一个{role},
    请用不超过 {limit} 字回答以下问题:
    {question}?
`);

这种做法的工程价值在于:

  • 解耦逻辑与内容:提示词的"结构"被固定下来,而"角色"、"字数"、"内容"(具体问题)则通过变量动态注入。
  • 静态方法与类属性PromptTemplate.fromTemplate 是一个静态方法,它直接属于类而非实例,这使得模板的创建更加标准和统一。

2.2 变量注入:赋予 AI 不同的"灵魂"

通过模板的 .format() 方法,我们可以轻松地改变 AI 的行为模式。通过传入不同的参数,AI 瞬间从一个通用助手变成了一个严苛的"前端面试官":

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

这种参数化设计是实现自动化测试动态响应 的基础。你可以预设一套角色库,根据用户的不同需求,动态切换 role 参数,而无需修改底层的模型调用代码。

2.3 迈向可预测的输出

为模型设置了 temperature: 0.7。在提示词工程中,模板 + 温度控制 是一套组合拳。

  • 模板保证了输入结构的稳定性。

  • 温度控制(Temperature)决定了输出的创造性与确定性。

    对于面试官这种场景,0.7 的温度既能保持专业性,又能让回答不那么机械死板。

第三层:LCEL 与 Chain------构建 AI 应用的"流水线"

在 LangChain 1.0+ 版本中,最重大的变革莫过于 LCEL(LangChain Expression Language,LangChain 表达式语言) 的引入。如果你熟悉 Linux 的管道符 | 或者 JavaScript 的函数组合,你会发现 LCEL 的逻辑如出一辙。

3.1 什么是 LCEL?

Chain(链) 是 LangChain 的灵魂,它将多个原子化的组件(提示词、模型、解析器)连接成一个可执行的任务序列。而 LCEL 则是构建这些链的"粘合剂"。

最简洁的 LCEL 写法:

js 复制代码
const chain = prompt.pipe(model);

这行代码看似简单,实际上它在底层实现了一套极其复杂的协议映射prompt 输出的是一个 PromptValue 对象,而 model 能够自动识别并接收这个对象,将其转化为 LLM 需要的 API 调用格式。

下面是一段完整使用代码:

JavaScript 复制代码
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}
`);

// 提示词节点 -> 模型节点 -> 自动执行
const chain = prompt.pipe(model);

const response = await chain.invoke({
    topic: '闭包',
});

console.log(response.text);

3.2 深度解析:Runnable 协议

LCEL 的强大源于所有组件都遵循统一的 Runnable 协议 。这意味着无论是一个简单的提示词模板,还是一个复杂的业务函数,只要它符合 Runnable 规范,就可以被 .pipe()

当你调用 chain.invoke() 时,内部发生了以下链式反应:

  1. 输入转化 :将 { topic: '闭包' } 注入 PromptTemplate
  2. 渲染:模板生成最终的字符串提示词。
  3. 预测 :将字符串传递给 ChatDeepSeek,模型进行推理。
  4. 返回 :模型返回一个 BaseMessage 对象,包含生成的文本。

第四层:复杂逻辑编排------从"对话框"走向"工作流"

在实际的业务场景中,AI 任务往往不是一次 invoke 就能解决的。例如,你需要先让 AI 检索资料,再根据资料生成草案,最后对草案进行精简。这种**多步推理(Multi-step Reasoning)**正是 LangChain 1.2+ 版本中 RunnableSequence 的用武之地。

4.1 核心逻辑:解耦与职责分明

实现一个"知识精炼"系统。它的核心思想是将一个复杂的长任务拆解为两个原子级的子任务:

  1. 子任务 A(解释链) :负责生成深度内容,覆盖定义、原理和使用方式。
  2. 子任务 B(总结链) :负责对 A 的输出进行二次加工,提炼出 3 个核心要点。
JavaScript 复制代码
// 子任务 A:专家模式,负责产出深度内容
const explainPrompt = PromptTemplate.fromTemplate(`
    你是一个前端专家,请详细介绍以下概念: {topic}
    要求: 覆盖定义、原理、使用方式、不超过300字。
`);

// 子任务 B:精简模式,负责产出核心要点
const summaryPrompt = PromptTemplate.fromTemplate(`
    请将以下前端概念解释总结为3个核心要点(每点不超过20字): 
    {explanation}
`);

const explainChain = explainPrompt.pipe(model);

const summaryChain = summaryPrompt.pipe(model);

4.2 深度解析:数据的流水线流动

最精妙的部分------如何将上一步的输出精准地喂给下一步

RunnableSequence.from([...]) 中,每一步不仅仅是在调用模型,还在进行数据清洗和重新包装

JavaScript 复制代码
const fullChain = RunnableSequence.from([
    // 第一步:处理原始 topic,调用 explainChain,并提取 text 属性
    (input) => explainChain.invoke({ topic: input.topic }).then(res => res.text),
    
    // 第二步:接收第一步产生的字符串(explanation),作为第二步的输入
    (explanation) => summaryChain.invoke({ explanation: explanation }).then(res => 
        `知识点详解:${explanation}\n\n总结要点:${res.text}`
    )
]);

为什么这种"编排"比直接拼字符串更强?

  • 状态管理:每一步的输出都可以被单独拦截、记录或修改。
  • 类型安全:在复杂的应用中,你可以确保传给模型 B 的数据一定是模型 A 处理过的纯文本,而不是包含原始 Metadata 的复杂对象。
  • 并发潜力 :虽然这里是顺序执行,但 RunnableSequence 允许你轻松切换到 RunnableParallel(并行执行),这在需要同时调用多个模型对比结果时非常有用。

总结:从"调包侠"到"AI 架构师"

通过这四层递进的学习,我们不难发现 LangChain 的核心逻辑:

LangChain = 统一接口 (Language Model) + 灵活组合 (Chain)

  1. 解耦:不绑定特定的模型供应商。
  2. 结构化:用模板管理提示词,告别乱糟糟的字符串拼接。
  3. 流式化:用 LCEL 构建清晰的业务逻辑流水线。
  4. 工程化:将复杂的 AI 任务转化为可预测、可扩展的代码结构。

LangChain 并不是让事情变得复杂,而是为日益复杂的 AI 应用提供了工业级的脚手架。如果你正准备从简单的 API 调用转向开发复杂的 AI Agent 或 RAG 系统,那么掌握这套组合拳将是你的必修课。

相关推荐
大厂技术总监下海2 小时前
没有千卡GPU,如何从0到1构建可用LLM?nanoChat 全栈实践首次公开
人工智能·开源
机器之心2 小时前
谁还敢说谷歌掉队?2025年,它打了一场漂亮的翻身仗
人工智能·openai
元智启2 小时前
企业AI智能体加速产业重构:政策红利与场景落地双轮驱动——从技术验证到价值交付的范式跃迁
人工智能·重构
智算菩萨2 小时前
强化学习从单代理到多代理系统的理论与算法架构综述
人工智能·算法·强化学习
机器之心2 小时前
字节做了个 AI 手机,钉钉做了台 AI 主机
人工智能·openai
天一生水water2 小时前
nano banana pro绘图示例
人工智能·智慧油田
机器之心2 小时前
实测MiniMax M2.1之后,我们终于看懂了其招股书里的技术底气
人工智能·openai
AI小怪兽2 小时前
YOLO11-4K:面向4K全景图像实时小目标检测的高效架构
人工智能·目标检测·计算机视觉·目标跟踪·架构
CICI131414132 小时前
焊接机器人负载能力选择标准
网络·数据库·人工智能