LangChain 链(Chains)完全指南:从线性流程到智能路由

在 LangChain 中,链(Chain) 是将模型、提示词、解析器等组件连接成完整 AI 工作流的核心抽象。它让开发者能够像搭积木一样,标准化、模块化地构建复杂的 LLM 应用。本文将从基础语法到高级模式,带你彻底掌握链的设计与优化。

为什么需要链?

假设你要开发一个智能客服系统,流程大致为:

  1. 理解用户问题

  2. 查询知识库

  3. 生成回答

  4. 格式化输出

如果没有链,你需要手动编写每一步的逻辑,难以复用、测试和维护。链正是为解决这一问题而生:它将工作流封装为可调用的单元 ,并通过 LCEL(LangChain Expression Language) 实现声明式的组件拼接。

1. 链的基本概念

1.1 最简单的链

javascript 复制代码
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";
import { StringOutputParser } from "@langchain/core/output_parsers";

const chain = ChatPromptTemplate.fromTemplate("讲一个关于{topic}的笑话")
  .pipe(new ChatOpenAI({ 
    apiKey: process.env.DEEPSEEK_API_KEY,
    baseURL: "https://api.deepseek.com/v1",
    model: "deepseek-chat"
  }))
  .pipe(new StringOutputParser());

const result = await chain.invoke({ topic: "程序员" });

这条链由三部分组成:提示词模板 → 模型 → 输出解析器 ,通过 .pipe() 方法串联,最终得到一个可调用的 Runnable 对象。

1.2 链的三种主要类型

类型 描述 适用场景
简单链 单输入 → 单输出,线性流程 翻译、摘要、简单问答
组合链 多个链组合,支持分支/循环 复杂决策、多步骤任务
路由链 根据输入选择不同子链 分类后处理、多功能助手

2. 使用 LCEL 构建链(核心)

LCEL 是 LangChain 1.0 推荐的链构建方式,它通过 RunnableSequenceRunnableParallelRunnableBranch 等原语,让链的组合能力大幅提升。

2.1 LCEL 基础语法

js 复制代码
import { RunnableSequence, RunnablePassthrough } from "@langchain/core/runnables";

const basicChain = RunnableSequence.from([
  (input) => ({ formatted_input: `问题:${input.question}` }),
  async (state) => {
    const model = new ChatOpenAI({ /* 配置 */ });
    return await model.invoke(state.formatted_input);
  },
  (response) => response.content
]);

2.2 实战:翻译 + 摘要链

js 复制代码
const translatePrompt = ChatPromptTemplate.fromTemplate(
  "将以下{sourceLang}文本翻译成{targetLang}:\n{text}"
);
const translateChain = translatePrompt.pipe(model).pipe(new StringOutputParser());

const summarizePrompt = ChatPromptTemplate.fromTemplate(
  "用{length}字总结以下文本:\n{text}"
);
const summarizeChain = summarizePrompt.pipe(model).pipe(new StringOutputParser());

const translateAndSummarizeChain = RunnableSequence.from([
  async (input) => {
    const translated = await translateChain.invoke({
      sourceLang: input.sourceLang,
      targetLang: input.targetLang,
      text: input.text
    });
    return { ...input, translatedText: translated };
  },
  async (state) => {
    const summary = await summarizeChain.invoke({
      text: state.translatedText,
      length: state.summaryLength || "100"
    });
    return { 
      original: state.text,
      translated: state.translatedText,
      summary 
    };
  }
]);

3. 高级链模式

3.1 条件路由链(RunnableBranch

根据问题类型,自动分流到技术链或通用链。

js 复制代码
const classifyChain = ChatPromptTemplate.fromTemplate(
  "判断以下问题类型,只返回'technical'或'general':\n问题:{question}"
).pipe(model).pipe(new StringOutputParser());

const technicalChain = ChatPromptTemplate.fromTemplate(
  "作为技术专家回答:{question}\n请提供详细的技术方案。"
).pipe(model).pipe(new StringOutputParser());

const generalChain = /* ... */;

const routerChain = RunnableBranch.from([
  [
    async (input) => {
      const classification = await classifyChain.invoke({ question: input.question });
      return classification.trim().toLowerCase() === "technical";
    },
    technicalChain
  ],
  [() => true, generalChain]
]);

const smartAssistantChain = RunnableSequence.from([
  RunnablePassthrough.assign({ classification: classifyChain }),
  routerChain
]);

3.2 并行处理链(RunnableParallel

同时进行情感分析、主题提取、字数统计,提升效率。

js 复制代码
const parallelChain = RunnableParallel({
  sentiment: sentimentChain,
  topics: topicChain,
  length: lengthChain
});

const analysis = await parallelChain.invoke({ text: "..." });

3.3 循环链(带记忆)

使用 BufferMemoryConversationChain 实现多轮对话记忆。

js 复制代码
import { BufferMemory } from "langchain/memory";
import { ConversationChain } from "langchain/chains";

const memory = new BufferMemory({ returnMessages: true, memoryKey: "chat_history" });
const conversationChain = new ConversationChain({
  llm: model,
  memory,
  prompt: ChatPromptTemplate.fromMessages([
    ["system", "你是一个有帮助的助手"],
    ["human", "{input}"]
  ])
});

await conversationChain.invoke({ input: "你好,我是小明" });
await conversationChain.invoke({ input: "你还记得我叫什么吗?" }); // ✅ 正确回答

4. 链的调试与优化

4.1 调试工具

  • 打印中间步骤 :在链中插入 (input) => { console.log(input); return input; }

  • LangSmith 集成 :使用 traceable 装饰器或 withConfig({ runName, tags }) 追踪调用链。

js 复制代码
const tracedChain = yourChain.withConfig({
  runName: "MyTranslationChain",
  tags: ["production"]
});

4.2 性能优化

  • 批量处理 :使用 .batch() 代替循环 .invoke()

  • 缓存 :为模型启用 InMemoryCache

  • 超时与重试.withConfig({ timeout: 10000, maxRetries: 2 })

  • 并发控制.withConfig({ maxConcurrency: 5 })

5. 实战项目:智能客服链

将意图识别、路由、专业回复整合为一条完整客服流水线。

js 复制代码
class SmartCustomerService {
  private model: ChatOpenAI;

  constructor() {
    this.model = new ChatOpenAI({
      apiKey: process.env.DEEPSEEK_API_KEY,
      baseURL: "https://api.deepseek.com/v1",
      model: "deepseek-chat"
    });
  }

  buildServiceChain() {
    // 1. 意图识别
    const intentChain = ChatPromptTemplate.fromTemplate(
      `识别用户意图,返回以下之一:
      - 'product_query' (产品查询)
      - 'technical_support' (技术支持)
      - 'complaint' (投诉)
      - 'other' (其他)
      用户问题:{question}`
    ).pipe(this.model).pipe(new StringOutputParser());

    // 2. 分支处理链
    const productChain = /* ... */;
    const techChain = /* ... */;
    const complaintChain = /* ... */;
    const defaultChain = ChatPromptTemplate.fromTemplate("回答问题:{question}")
      .pipe(this.model).pipe(new StringOutputParser());

    // 3. 路由
    const router = RunnableBranch.from([
      [async (input) => (await intentChain.invoke({ question: input.question })) === "product_query", productChain],
      [async (input) => (await intentChain.invoke({ question: input.question })) === "technical_support", techChain],
      [async (input) => (await intentChain.invoke({ question: input.question })) === "complaint", complaintChain],
      [() => true, defaultChain]
    ]);

    // 4. 完整链
    return RunnableSequence.from([
      RunnablePassthrough.assign({ intent: intentChain }),
      router,
      (response) => ({ answer: response, timestamp: new Date().toISOString() })
    ]);
  }
}

关键收获

✅ 核心知识点

  • 链即工作流:将组件连接为可复用、可组合的 AI 流水线。

  • LCEL 是未来 :使用 RunnableSequenceRunnableParallelRunnableBranch 实现任意复杂逻辑。

  • 模式多样性:顺序、分支、并行、循环,覆盖 90% 以上业务场景。

  • 可观测性:链的每一步都可插入调试逻辑,并与 LangSmith 无缝集成。

链是 LangChain 的灵魂。掌握链的设计与组合,意味着你能够将碎片化的 LLM 调用,构建成健壮、高效的生产级应用。从今天开始,用 LCEL 重构你的工作流吧。

相关推荐
golang学习记2 小时前
GitLens 十大神技:彻底改变你在 VS Code 中的 Git 工作流
前端·后端·visual studio code
SuperEugene2 小时前
后台权限与菜单渲染:基于路由和后端返回的几种实现方式
前端·javascript·vue.js
兆子龙2 小时前
WebSocket 入门:是什么、有什么用、脚本能帮你做什么
前端·架构
前端付豪2 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
月弦笙音2 小时前
【浏览器】这几点必须懂
前端
SuperEugene2 小时前
弹窗与抽屉组件封装:如何做一个全局可控的 Dialog 服务
前端·javascript·vue.js
UrbanJazzerati2 小时前
事件传播机制详解(附直观比喻和代码示例)
前端
青青家的小灰灰2 小时前
透视 React 内核:Diff 算法、合成事件与并发特性的深度解析
前端·javascript·react.js