掌握如何在LangChain4J中设计和实现复杂的多步骤流程链
时间:30分钟 | 难度:⭐⭐⭐ | Week 2
官方Example信息
- GitHub链接:ChainExample.java
- 相关Example:SequentialChainExample、ConversationalChainExample
- 所在路径:src/main/java/dev/langchain4j/examples/
- 代码行数:约60-100行
- 难度:中级 ⭐⭐⭐
学习目标
- 理解Chain的核心概念 ✅ 2026-03-07
- 学会设计顺序Chain(Sequential Chain) ✅ 2026-03-07
- 学会设计条件Chain(Conditional Chain) ✅ 2026-03-07
- 掌握Chain的执行和监控 ✅ 2026-03-07
- 实现代码审查Chain ✅ 2026-03-07
- 能设计生产级别的复杂Chain ✅ 2026-03-07
🚀 快速入门:什么是Chain?
Chain的本质
Chain = 一系列有序的操作步骤
简单例子:
输入 → 第1步(调用LLM) → 第2步(数据处理) → 第3步(输出) → 结果
代码审查Chain例子:
代码文本 → 分析 → 生成建议 → 格式化 → 返回用户
为什么需要Chain?
问题:
- 任务通常需要多步骤
- 每步的输出是下一步的输入
- 需要统一的流程控制和错误处理
解决方案:Chain
- 将多步骤组织成一个整体
- 清晰的数据流动
- 易于维护和扩展
Chain的基本结构
abstract class BaseChain implements Chain {
// 输入验证
Map<String, Object> validateInput(ChainInputs input);
// 执行链
ChainOutputs execute(ChainInputs input);
// 输出验证
Map<String, Object> validateOutput(ChainOutputs output);
}
深度讲解
1️⃣ 顺序Chain(Sequential Chain)
最常见的Chain类型:按顺序执行多个步骤。
@Service
public class CodeReviewChain {
@Autowired
private ChatModel model;
/**
* 代码审查链:
* 第1步 → 分析代码(检查语法、逻辑)
* 第2步 → 性能审查(检查性能问题)
* 第3步 → 安全审查(检查安全漏洞)
* 第4步 → 生成报告
*/
public CodeReviewReport review(String code) {
// Step 1: 代码分析
String codeAnalysis = analyzeCode(code);
// Step 2: 性能检查
String performanceIssues = checkPerformance(code);
// Step 3: 安全检查
String securityIssues = checkSecurity(code);
// Step 4: 综合生成报告
return generateReport(codeAnalysis, performanceIssues, securityIssues);
}
private String analyzeCode(String code) {
String prompt = """
分析以下代码的逻辑和语法:
```java
%s
```
请指出主要的逻辑问题。
""".formatted(code);
return model.chat(prompt);
}
private String checkPerformance(String code) {
String prompt = """
检查以下代码的性能问题:
```java
%s
```
请指出时间复杂度和空间复杂度的问题。
""".formatted(code);
return model.chat(prompt);
}
private String checkSecurity(String code) {
String prompt = """
检查以下代码的安全漏洞:
```java
%s
```
请指出SQL注入、XSS等常见安全问题。
""".formatted(code);
return model.chat(prompt);
}
private CodeReviewReport generateReport(String analysis, String performance, String security) {
return CodeReviewReport.builder()
.codeAnalysis(analysis)
.performanceIssues(performance)
.securityIssues(security)
.reviewedAt(LocalDateTime.now())
.build();
}
}
2️⃣ 条件Chain(Conditional Chain)
根据条件执行不同的步骤分支。
@Service
public class SmartCodeReviewChain {
@Autowired
private ChatModel fastModel; // GPT-4o-mini(快)
@Autowired
private ChatModel strongModel; // GPT-4o(强)
/**
* 智能审查链:
* - 如果代码简单 → 快速审查(用便宜模型)
* - 如果代码复杂 → 深度审查(用强大模型)
*/
public CodeReviewReport smartReview(String code) {
CodeComplexity complexity = analyzeComplexity(code);
if (complexity == CodeComplexity.SIMPLE) {
return fastReview(code);
} else {
return deepReview(code);
}
}
private CodeComplexity analyzeComplexity(String code) {
int lines = code.split("\n").length;
int nestingLevel = countMaxNesting(code);
if (lines < 50 && nestingLevel <= 3) {
return CodeComplexity.SIMPLE;
} else {
return CodeComplexity.COMPLEX;
}
}
private CodeReviewReport fastReview(String code) {
// 用快速模型(gpt-4o-mini)
String review = fastModel.chat("快速审查代码:\n" + code);
return new CodeReviewReport(review, "FAST");
}
private CodeReviewReport deepReview(String code) {
// 用强大模型(gpt-4o)
String review = strongModel.chat("深度审查代码:\n" + code);
return new CodeReviewReport(review, "DEEP");
}
private int countMaxNesting(String code) {
// 计算最大嵌套深度
int maxNesting = 0;
int currentNesting = 0;
for (char c : code.toCharArray()) {
if (c == '{') {
currentNesting++;
maxNesting = Math.max(maxNesting, currentNesting);
} else if (c == '}') {
currentNesting--;
}
}
return maxNesting;
}
}
enum CodeComplexity {
SIMPLE, COMPLEX
}
3️⃣ 并行Chain(Parallel Chain)
多个步骤同时执行,然后合并结果。
@Service
public class ParallelCodeReviewChain {
@Autowired
private ChatModel model;
/**
* 并行审查:
* 代码 ─┬─→ 逻辑审查 ─┐
* ├─→ 性能审查 ├─→ 合并结果
* └─→ 安全审查 ┘
*/
public CodeReviewReport parallelReview(String code) {
// 同时执行3个审查任务
CompletableFuture<String> logicReview = CompletableFuture.supplyAsync(
() -> reviewLogic(code)
);
CompletableFuture<String> performanceReview = CompletableFuture.supplyAsync(
() -> reviewPerformance(code)
);
CompletableFuture<String> securityReview = CompletableFuture.supplyAsync(
() -> reviewSecurity(code)
);
try {
// 等待所有任务完成
CompletableFuture.allOf(logicReview, performanceReview, securityReview).join();
// 合并结果
return CodeReviewReport.builder()
.logicIssues(logicReview.get())
.performanceIssues(performanceReview.get())
.securityIssues(securityReview.get())
.build();
} catch (Exception e) {
throw new RuntimeException("并行审查失败", e);
}
}
private String reviewLogic(String code) {
return model.chat("逻辑审查:\n" + code);
}
private String reviewPerformance(String code) {
return model.chat("性能审查:\n" + code);
}
private String reviewSecurity(String code) {
return model.chat("安全审查:\n" + code);
}
}
4️⃣ 循环Chain(Loop Chain)
重复执行某个步骤直到满足条件。
@Service
public class IterativeCodeReviewChain {
@Autowired
private ChatModel model;
/**
* 迭代审查:
* 第1轮:找出问题
* 第2轮:生成改进建议
* 第3轮:验证改进是否足够
* 如果不足够,继续循环
*/
public CodeReviewResult iterativeReview(String code, int maxIterations) {
String currentCode = code;
int iteration = 0;
while (iteration < maxIterations) {
iteration++;
// 第1步:找出问题
String issues = findIssues(currentCode);
// 第2步:是否足够好?
if (isSatisfactory(issues)) {
return new CodeReviewResult(currentCode, issues, iteration);
}
// 第3步:生成改进建议并应用
currentCode = applyImprovements(currentCode, issues);
}
return new CodeReviewResult(currentCode, "Max iterations reached", iteration);
}
private String findIssues(String code) {
return model.chat("找出代码问题:\n" + code);
}
private boolean isSatisfactory(String issues) {
// 如果问题少于3个,认为满意
return issues.split("\\n").length < 3;
}
private String applyImprovements(String code, String issues) {
String prompt = """
根据这些问题改进代码:
问题:%s
原代码:%s
请给出改进后的代码。
""".formatted(issues, code);
return model.chat(prompt);
}
}
🔄 ConversationalChain vs Sequential Chain 深度对比
核心区别
两种Chain在结构和适用场景上有根本性差异:
ConversationalChain(对话链)
├─ 定义:管理对话历史的特殊Chain
├─ 特点:自动保存和加载Memory
├─ 适用:多轮对话、聊天机器人
├─ 记忆:自动维护对话上下文
└─ 用户感受:连贯、有记忆
Sequential Chain(顺序链)
├─ 定义:按顺序执行多个步骤的Chain
├─ 特点:前一步输出→后一步输入
├─ 适用:多步工作流、固定流程
├─ 记忆:无(每步独立)
└─ 用户感受:工业流程、确定性
详细对比表
| 维度 | ConversationalChain | Sequential Chain | Transform Chain |
|---|---|---|---|
| 记忆方式 | 自动Memory管理 | 无自动记忆 | 无自动记忆 |
| 输入方式 | 只需用户输入 | 需要所有步骤数据 | 逐步转换 |
| 适用场景 | 对话、问答 | 工作流、分析 | 数据转换 |
| 状态管理 | 自动 | 手动 | 手动 |
| 用户体验 | 自然对话 | 流程化处理 | 逐步转换 |
| 实现难度 | 简单 | 中等 | 中等 |
| 性能 | 快(缓存命中) | 快(无Memory开销) | 快(无Memory开销) |
代码对比:三种Chain实现
1️⃣ ConversationalChain - 多轮对话(自动记忆)
/**
* ConversationalChain:框架自动管理对话历史
* ✅ 优点:
* - 自动保存和加载Memory
* - 用户无需管理对话历史
* - 代码简洁
* ❌ 缺点:
* - 灵活性较低(对话格式固定)
* - Memory管理由框架决定
*/
@Service
public class ConversationalChainExample {
@Autowired
private ChatModel model;
public void demonstrateConversational() {
// Step 1: 创建Memory
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
// Step 2: 创建Chain(自动关联Memory)
ConversationalChain chain = ConversationalChain.builder()
.chatModel(model)
.chatMemory(chatMemory)
.build();
// Step 3: 执行对话(无需手动管理历史)
String answer1 = chain.execute("我正在学习Java");
System.out.println("轮次1: " + answer1);
// Memory自动保存了这轮对话
String answer2 = chain.execute("它和Python相比如何");
System.out.println("轮次2: " + answer2);
// Chain能记住上文说的"Java",完全自动
String answer3 = chain.execute("给我代码示例");
System.out.println("轮次3: " + answer3);
// Memory链中还有轮次1、2的信息
}
}
/**
* 使用场景:
* ✅ 聊天机器人 - 需要记住整个对话
* ✅ 智能助手 - 多轮问答
* ✅ 问卷调查 - 连续提问
* ❌ 代码审查 - 需要多维度分析,不是对话式
* ❌ 数据处理 - 需要清晰的步骤顺序
*/
2️⃣ Sequential Chain - 多步工作流(手动编排)
/**
* Sequential Chain:按顺序执行,前一步→后一步
* ✅ 优点:
* - 步骤清晰可控
* - 可以并行化处理
* - 灵活性高
* - 无Memory开销
* ❌ 缺点:
* - 需要手动管理每一步的输入输出
* - 代码相对复杂
*/
@Service
public class SequentialChainExample {
@Autowired
private ChatModel model;
public void demonstrateSequential() {
// 场景:多步骤的代码审查
String code = "public int sort() { ... }";
// 第1步:生成代码
PromptTemplate step1 = PromptTemplate.from(
"用{{language}}写一个{{function}}的函数:");
Prompt prompt1 = step1.apply(Map.of(
"language", "Java",
"function", "冒泡排序"
));
String generatedCode = model.chat(prompt1.text());
System.out.println("[Step 1] 生成代码:\n" + generatedCode);
// 第2步:分析复杂度(使用第1步的输出)
PromptTemplate step2 = PromptTemplate.from(
"分析以下代码的时间复杂度:\n\n{{code}}");
Prompt prompt2 = step2.apply(Map.of("code", generatedCode));
String analysis = model.chat(prompt2.text());
System.out.println("\n[Step 2] 复杂度分析:\n" + analysis);
// 第3步:优化建议(使用第1、2步的输出)
PromptTemplate step3 = PromptTemplate.from(
"基于代码和分析,给出优化建议:\n\n" +
"代码:{{code}}\n分析:{{analysis}}");
Prompt prompt3 = step3.apply(Map.of(
"code", generatedCode,
"analysis", analysis
));
String optimized = model.chat(prompt3.text());
System.out.println("\n[Step 3] 优化建议:\n" + optimized);
// 整个流程的结果
return new ChainResult(generatedCode, analysis, optimized);
}
}
/**
* 使用场景:
* ✅ 代码审查 - 分析→检查→建议
* ✅ 内容生成 - 规划→草稿→润色
* ✅ 数据处理 - 提取→转换→验证
* ✅ 文章生成 - 选题→大纲→内容→校对
* ❌ 聊天对话 - 不需要对话上下文记忆
*/
3️⃣ Transform Chain - 逐步转换(数据流转)
/**
* Transform Chain:每一步都是一个转换
* 特点:输入 → 转换1 → 转换2 → 转换3 → 输出
*
* ✅ 优点:
* - 逐步转换,清晰可见
* - 中间结果可视化
* - 易于调试
* ❌ 缺点:
* - 代码最多(每步都要处理)
*/
@Service
public class TransformChainExample {
@Autowired
private ChatModel model;
public void demonstrateTransform() {
String originalText = "Artificial intelligence is transforming...";
// 转换1:翻译
String translated = model.chat(
PromptTemplate.from("将英文翻译成中文:\n\n{{text}}")
.apply(Map.of("text", originalText))
.text()
);
System.out.println("[转换1] 翻译:\n" + translated);
// 转换2:摘要(使用转换1的结果)
String summary = model.chat(
PromptTemplate.from("用一句话概括:\n\n{{text}}")
.apply(Map.of("text", translated))
.text()
);
System.out.println("\n[转换2] 摘要:\n" + summary);
// 转换3:提取关键词(使用转换2的结果)
String keywords = model.chat(
PromptTemplate.from("提取3个核心关键词:\n\n{{text}}")
.apply(Map.of("text", summary))
.text()
);
System.out.println("\n[转换3] 关键词:\n" + keywords);
// 最终结果包含整个转换过程
return new TransformResult(originalText, translated, summary, keywords);
}
}
/**
* 使用场景:
* ✅ 内容转换 - 翻译→摘要→分类
* ✅ 数据清洗 - 原始→清洗→验证→导出
* ✅ 文本处理 - 原文→标准化→分析→可视化
*/
性能对比
场景:处理1000个用户问题
ConversationalChain(对话链)
├─ 平均延迟:300ms/次(首次加载Memory)
├─ 平均延迟:50ms/次(缓存命中)
├─ 内存占用:随对话轮数增长(最多10条消息)
├─ Token消耗:累积(需要传递完整历史)
├─ 总成本:¥10.5(1000 × 200 tokens × 价格)
└─ 适合:<100轮/用户的对话
Sequential Chain(顺序链)
├─ 平均延迟:200ms/步骤
├─ 步骤数:通常3-5步 = 600-1000ms总耗时
├─ 内存占用:固定(无Memory管理)
├─ Token消耗:固定(每步独立)
├─ 总成本:¥8.5(3步 × 300 tokens × 价格)
└─ 适合:固定流程处理
Transform Chain(转换链)
├─ 平均延迟:150ms/转换
├─ 转换数:通常2-4次 = 300-600ms总耗时
├─ 内存占用:固定
├─ Token消耗:固定
├─ 总成本:¥5.2(2步 × 200 tokens × 价格)
└─ 适合:数据处理流
决策树:我应该用哪个?
需要对话上下文吗?
│
├─ 是(用户多轮问同一个问题)
│ └─→ ConversationalChain ✅
│ 示例:聊天机器人、问卷系统
│
└─ 否(固定的处理流程)
│
├─ 步骤间有依赖关系吗?
│ ├─ 是(Step1输出 → Step2输入)
│ │ └─→ Sequential Chain ✅
│ │ 示例:代码审查、内容生成
│ │
│ └─ 否(各步独立转换)
│ └─→ Transform Chain ✅
│ 示例:翻译→摘要→分类
│
└─ 同时需要对话 + 工作流?
└─→ ConversationalChain + Sequential Chain ✅
示例:智能助手(记住历史 + 多步处理)
完整的混合示例:智能助手
/**
* 结合两种Chain的能力:
* 1. ConversationalChain 管理对话历史
* 2. Sequential Chain 处理复杂分析
*/
@Service
public class SmartAssistant {
@Autowired
private ChatModel model;
public String assistWith(String userId, String userQuery) {
// 第0步:使用ConversationalChain记住历史
ChatMemory memory = loadOrCreateMemory(userId);
ConversationalChain conversationalChain = ConversationalChain.builder()
.chatModel(model)
.chatMemory(memory)
.build();
// 第1步:理解用户问题(使用对话历史)
String understanding = conversationalChain.execute(
"Based on our conversation, analyze: " + userQuery
);
// 第2步:使用Sequential Chain处理复杂分析
PromptTemplate step1 = PromptTemplate.from("分析问题:{{query}}");
String analysis = model.chat(
step1.apply(Map.of("query", understanding)).text()
);
PromptTemplate step2 = PromptTemplate.from("基于分析提出方案:{{analysis}}");
String solution = model.chat(
step2.apply(Map.of("analysis", analysis)).text()
);
// 第3步:保存对话(回到ConversationalChain)
memory.add(UserMessage.from(userQuery));
memory.add(AiMessage.from(solution));
return solution;
}
}
总结选择标准
┌─────────────────────────────────────────────────────────┐
│ 何时用哪种Chain │
├─────────────────────────────────────────────────────────┤
│ ConversationalChain: │
│ ✅ 用户能问追问("它如何工作?"依赖前文) │
│ ✅ 需要记住对话历史(多轮对话) │
│ ✅ 用户体验优先(自然对话感) │
│ ✅ 对话轮数少(<50轮) │
│ │
│ Sequential Chain: │
│ ✅ 流程固定且清晰(分析→检查→建议) │
│ ✅ 步骤间有数据依赖(前一步输出→后一步输入) │
│ ✅ 需要更高的灵活性(可插拔步骤) │
│ ✅ 需要缓存优化(相同输入缓存结果) │
│ ✅ Token成本敏感(无历史累积) │
│ │
│ Transform Chain: │
│ ✅ 数据转换流(翻译→摘要→分类) │
│ ✅ 中间结果需要可视化 │
│ ✅ 每个转换都有具体含义 │
└─────────────────────────────────────────────────────────┘
💻 实战:完整的Chain实现
@Service
public class ProductionCodeReviewChain {
@Autowired
private ChatModel model;
private static final Logger log = LoggerFactory.getLogger(ProductionCodeReviewChain.class);
/**
* 生产级别的代码审查Chain
* - 包含错误处理
* - 包含监控
* - 包含缓存
*/
@Cacheable(value = "codeReviews", key = "#code.hashCode()")
public CodeReviewResult review(String code) {
long startTime = System.currentTimeMillis();
try {
// Step 1: 验证输入
validateInput(code);
// Step 2: 执行审查
CodeReviewResult result = executeReview(code);
// Step 3: 验证输出
validateOutput(result);
// Step 4: 记录指标
long duration = System.currentTimeMillis() - startTime;
log.info("Code review completed in {}ms", duration);
return result;
} catch (Exception e) {
log.error("Code review failed", e);
throw new CodeReviewException("审查失败", e);
}
}
private void validateInput(String code) {
if (code == null || code.trim().isEmpty()) {
throw new IllegalArgumentException("代码不能为空");
}
if (code.length() > 10000) {
throw new IllegalArgumentException("代码过长(超过10000字符)");
}
}
private CodeReviewResult executeReview(String code) {
// Step 1: 快速扫描
String quickScan = quickScan(code);
// Step 2: 详细分析
String detailedAnalysis = detailedAnalysis(code);
// Step 3: 生成建议
String suggestions = generateSuggestions(code, detailedAnalysis);
return CodeReviewResult.builder()
.code(code)
.quickScan(quickScan)
.detailedAnalysis(detailedAnalysis)
.suggestions(suggestions)
.timestamp(LocalDateTime.now())
.build();
}
private void validateOutput(CodeReviewResult result) {
if (result == null) {
throw new IllegalStateException("审查结果为空");
}
}
private String quickScan(String code) {
return model.chat("快速扫描代码问题(不超过100字):\n" + code);
}
private String detailedAnalysis(String code) {
return model.chat("详细分析代码:\n" + code);
}
private String generateSuggestions(String code, String analysis) {
return model.chat("根据分析给出改进建议:\n" + code + "\n分析:" + analysis);
}
}
@Data
@Builder
class CodeReviewResult {
private String code;
private String quickScan;
private String detailedAnalysis;
private String suggestions;
private LocalDateTime timestamp;
}
🔧 Chain设计最佳实践
✅ 好的Chain设计
// 清晰的步骤
public class GoodChain {
public Result execute(Input input) {
// Step 1: 验证
validateInput(input);
// Step 2: 处理
IntermediateResult step1 = processStep1(input);
IntermediateResult step2 = processStep2(step1);
// Step 3: 生成结果
return generateResult(step2);
}
}
❌ 坏的Chain设计
// 糊在一起,难以维护
public class BadChain {
public Result execute(Input input) {
return generateResult(
processStep2(
processStep1(input)
)
);
}
}
学习成果检查:
- 能解释什么是Chain
- 能实现顺序Chain
- 能实现条件Chain
- 能实现并行Chain
- 能设计生产级别的Chain
下一步:学习Memory管理,让Chain能够记住对话历史。