09-Chain设计模式完全指南

2 阅读11分钟

掌握如何在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
├─ 特点:前一步输出→后一步输入
├─ 适用:多步工作流、固定流程
├─ 记忆:无(每步独立)
└─ 用户感受:工业流程、确定性

详细对比表

维度ConversationalChainSequential ChainTransform 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.51000 × 200 tokens × 价格)
└─ 适合:<100轮/用户的对话

Sequential Chain(顺序链)
├─ 平均延迟:200ms/步骤
├─ 步骤数:通常3-5步 = 600-1000ms总耗时
├─ 内存占用:固定(无Memory管理)
├─ Token消耗:固定(每步独立)
├─ 总成本:¥8.53步 × 300 tokens × 价格)
└─ 适合:固定流程处理

Transform Chain(转换链)
├─ 平均延迟:150ms/转换
├─ 转换数:通常2-4次 = 300-600ms总耗时
├─ 内存占用:固定
├─ Token消耗:固定
├─ 总成本:¥5.22步 × 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能够记住对话历史。