在 LangChain 中,链(Chain) 是将模型、提示词、解析器等组件连接成完整 AI 工作流的核心抽象。它让开发者能够像搭积木一样,标准化、模块化地构建复杂的 LLM 应用。本文将从基础语法到高级模式,带你彻底掌握链的设计与优化。
为什么需要链?
假设你要开发一个智能客服系统,流程大致为:
-
理解用户问题
-
查询知识库
-
生成回答
-
格式化输出
如果没有链,你需要手动编写每一步的逻辑,难以复用、测试和维护。链正是为解决这一问题而生:它将工作流封装为可调用的单元,并通过 LCEL(LangChain Expression Language) 实现声明式的组件拼接。
1. 链的基本概念
1.1 最简单的链
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 推荐的链构建方式,它通过 RunnableSequence、RunnableParallel、RunnableBranch 等原语,让链的组合能力大幅提升。
2.1 LCEL 基础语法
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 实战:翻译 + 摘要链
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)
根据问题类型,自动分流到技术链或通用链。
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)
同时进行情感分析、主题提取、字数统计,提升效率。
const parallelChain = RunnableParallel({
sentiment: sentimentChain,
topics: topicChain,
length: lengthChain
});
const analysis = await parallelChain.invoke({ text: "..." });
3.3 循环链(带记忆)
使用 BufferMemory 和 ConversationChain 实现多轮对话记忆。
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 })追踪调用链。
const tracedChain = yourChain.withConfig({
runName: "MyTranslationChain",
tags: ["production"]
});
4.2 性能优化
-
批量处理:使用
.batch()代替循环.invoke() -
缓存:为模型启用
InMemoryCache -
超时与重试:
.withConfig({ timeout: 10000, maxRetries: 2 }) -
并发控制:
.withConfig({ maxConcurrency: 5 })
5. 实战项目:智能客服链
将意图识别、路由、专业回复整合为一条完整客服流水线。
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 是未来:使用
RunnableSequence、RunnableParallel、RunnableBranch实现任意复杂逻辑。 -
模式多样性:顺序、分支、并行、循环,覆盖 90% 以上业务场景。
-
可观测性:链的每一步都可插入调试逻辑,并与 LangSmith 无缝集成。
链是 LangChain 的灵魂。掌握链的设计与组合,意味着你能够将碎片化的 LLM 调用,构建成健壮、高效的生产级应用。从今天开始,用 LCEL 重构你的工作流吧。