Skip to content

链 (Chains) 详解

基础链 (LLMChain)

基础链是 LangChain 4J 中最基本的链类型,它将提示词模板和语言模型组合在一起:

基本用法

java
import dev.langchain4j.chain.llm.LLMChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.prompt.PromptTemplate;

// 创建提示词模板
PromptTemplate promptTemplate = PromptTemplate.from("请解释 {topic} 的概念");

// 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .build();

// 创建 LLM 链
LLMChain chain = LLMChain.builder()
        .promptTemplate(promptTemplate)
        .model(model)
        .build();

// 运行链
String response = chain.run("量子计算");
System.out.println(response);

带输出解析器的链

可以添加输出解析器,将模型输出转换为结构化数据:

java
import dev.langchain4j.output.parser.JsonOutputParser;

// 定义结果类
class TopicExplanation {
    private String concept;
    private String applications;
    private String challenges;
    // getters and setters
}

// 创建 JSON 输出解析器
JsonOutputParser<TopicExplanation> parser = new JsonOutputParser<>(TopicExplanation.class);

// 创建提示词模板,要求输出 JSON 格式
PromptTemplate promptTemplate = PromptTemplate.from(
        "请解释 {topic} 的概念,以 JSON 格式输出,包含 concept、applications、challenges 字段"
);

// 创建带输出解析器的链
LLMChain chain = LLMChain.builder()
        .promptTemplate(promptTemplate)
        .model(model)
        .outputParser(parser)
        .build();

// 运行链,获取结构化结果
TopicExplanation result = chain.run("量子计算");
System.out.println(result.getConcept());
System.out.println(result.getApplications());
System.out.println(result.getChallenges());

顺序链 (SequentialChain)

顺序链按顺序执行多个链,将一个链的输出作为下一个链的输入:

基本用法

java
import dev.langchain4j.chain.sequential.SequentialChain;

// 创建第一个链(生成话题)
PromptTemplate topicTemplate = PromptTemplate.from("请为 {subject} 生成 3 个相关的讨论话题");
LLMChain topicChain = LLMChain.builder()
        .promptTemplate(topicTemplate)
        .model(model)
        .build();

// 创建第二个链(详细讨论)
PromptTemplate detailTemplate = PromptTemplate.from("请详细讨论以下话题:{topic}");
LLMChain detailChain = LLMChain.builder()
        .promptTemplate(detailTemplate)
        .model(model)
        .build();

// 创建顺序链
SequentialChain sequentialChain = SequentialChain.builder()
        .addChain(topicChain)
        .addChain(detailChain)
        .build();

// 运行顺序链
Map<String, Object> inputs = new HashMap<>();
inputs.put("subject", "人工智能");
inputs.put("topic", "{{$0}}"); // 使用第一个链的输出作为第二个链的输入

String result = sequentialChain.run(inputs);
System.out.println(result);

带多个输入输出的顺序链

java
// 创建顺序链,指定输入输出映射
SequentialChain sequentialChain = SequentialChain.builder()
        .addChain(topicChain, "subject", "topics")
        .addChain(detailChain, "topics", "detailedDiscussion")
        .build();

// 运行顺序链
Map<String, Object> inputs = new HashMap<>();
inputs.put("subject", "人工智能");

Map<String, Object> results = sequentialChain.runForMap(inputs);
System.out.println("生成的话题:" + results.get("topics"));
System.out.println("详细讨论:" + results.get("detailedDiscussion"));

并行链 (ParallelChain)

并行链同时执行多个链,然后合并结果:

基本用法

java
import dev.langchain4j.chain.parallel.ParallelChain;

// 创建多个链
LLMChain chain1 = LLMChain.builder()
        .promptTemplate(PromptTemplate.from("请解释 {topic} 的概念"))
        .model(model)
        .build();

LLMChain chain2 = LLMChain.builder()
        .promptTemplate(PromptTemplate.from("请列出 {topic} 的应用场景"))
        .model(model)
        .build();

LLMChain chain3 = LLMChain.builder()
        .promptTemplate(PromptTemplate.from("请讨论 {topic} 的未来发展"))
        .model(model)
        .build();

// 创建并行链
ParallelChain parallelChain = ParallelChain.builder()
        .addChain(chain1, "topic", "concept")
        .addChain(chain2, "topic", "applications")
        .addChain(chain3, "topic", "future")
        .build();

// 运行并行链
Map<String, Object> inputs = new HashMap<>();
inputs.put("topic", "量子计算");

Map<String, Object> results = parallelChain.runForMap(inputs);
System.out.println("概念:" + results.get("concept"));
System.out.println("应用场景:" + results.get("applications"));
System.out.println("未来发展:" + results.get("future"));

自定义链开发

您可以通过实现 Chain 接口来创建自定义链:

基本自定义链

java
import dev.langchain4j.chain.Chain;

public class CustomChain implements Chain {
    private final LLMChain llmChain;
    private final String suffix;
    
    public CustomChain(LLMChain llmChain, String suffix) {
        this.llmChain = llmChain;
        this.suffix = suffix;
    }
    
    @Override
    public String run(Map<String, Object> inputs) {
        // 运行基础链
        String result = llmChain.run(inputs);
        // 添加后缀
        return result + "\n" + suffix;
    }
    
    @Override
    public Map<String, Object> runForMap(Map<String, Object> inputs) {
        String result = run(inputs);
        Map<String, Object> output = new HashMap<>();
        output.put("result", result);
        return output;
    }
}

高级自定义链

java
public class MultiStepChain implements Chain {
    private final List<Chain> chains;
    
    public MultiStepChain(List<Chain> chains) {
        this.chains = chains;
    }
    
    @Override
    public String run(Map<String, Object> inputs) {
        Map<String, Object> currentInputs = new HashMap<>(inputs);
        String lastResult = "";
        
        for (Chain chain : chains) {
            Map<String, Object> result = chain.runForMap(currentInputs);
            // 将当前链的输出作为下一个链的输入
            currentInputs.putAll(result);
            lastResult = result.values().iterator().next().toString();
        }
        
        return lastResult;
    }
    
    @Override
    public Map<String, Object> runForMap(Map<String, Object> inputs) {
        Map<String, Object> currentInputs = new HashMap<>(inputs);
        
        for (Chain chain : chains) {
            Map<String, Object> result = chain.runForMap(currentInputs);
            currentInputs.putAll(result);
        }
        
        return currentInputs;
    }
}

链的组合与嵌套

您可以将不同类型的链组合在一起,形成更复杂的处理流程:

java
// 创建基础链
LLMChain conceptChain = LLMChain.builder()
        .promptTemplate(PromptTemplate.from("请解释 {topic} 的概念"))
        .model(model)
        .build();

LLMChain applicationChain = LLMChain.builder()
        .promptTemplate(PromptTemplate.from("请列出 {topic} 的应用场景"))
        .model(model)
        .build();

// 创建并行链
ParallelChain parallelChain = ParallelChain.builder()
        .addChain(conceptChain, "topic", "concept")
        .addChain(applicationChain, "topic", "applications")
        .build();

// 创建总结链
LLMChain summaryChain = LLMChain.builder()
        .promptTemplate(PromptTemplate.from("请根据以下信息总结 {topic}:\n概念:{concept}\n应用场景:{applications}"))
        .model(model)
        .build();

// 创建顺序链
SequentialChain sequentialChain = SequentialChain.builder()
        .addChain(parallelChain, "topic", "concept,applications")
        .addChain(summaryChain, "topic,concept,applications", "summary")
        .build();

// 运行组合链
Map<String, Object> inputs = new HashMap<>();
inputs.put("topic", "量子计算");

Map<String, Object> results = sequentialChain.runForMap(inputs);
System.out.println("总结:" + results.get("summary"));

最佳实践

  1. 模块化设计:将复杂任务分解为多个简单的链
  2. 合理组合:根据任务需求选择合适的链类型
  3. 错误处理:添加适当的错误处理机制
  4. 性能优化:对于并行任务使用并行链
  5. 可扩展性:设计可重用的链组件
  6. 监控与日志:添加监控和日志记录
  7. 测试:为链编写单元测试
  8. 文档:为自定义链添加详细的文档