基于 LangChain4j 的 RAG 工作流智能体实战

前言

在 AI 应用开发中,RAG(检索增强生成)已经成为构建智能问答系统的核心技术方案。然而,简单的 RAG 往往难以应对复杂的业务场景。本文将分享一个基于 LangChain4j 实现的 RAG 工作流智能体项目,支持顺序、条件、路由、循环、并行五种执行模式。

一、项目概述

这是一个AI 智能体项目,而非普通的 AI 应用。它具有以下核心特征:

特征 说明
多步推理 问题理解 → 检索 → 评估 → 生成
决策能力 条件判断、路由分发
并行处理 多数据源同时检索
循环控制 支持重试机制
状态管理 ExecutionContext 维护执行状态

二、系统架构

2.1 整体架构图

复制代码
┌──────────────────────────────────────────────────────────────┐
│                      用户问题                                 │
└─────────────────────────┬────────────────────────────────────┘
                          │
                          ▼
┌──────────────────────────────────────────────────────────────┐
│                     WorkflowEngine                           │
│                    (工作流执行引擎)                            │
└─────────────────────────┬────────────────────────────────────┘
                          │
          ┌───────────────┼───────────────┐
          ▼               ▼               ▼
    ┌──────────┐    ┌──────────┐    ┌──────────┐
    │  节点1   │    │  节点2   │    │  节点N   │
    │ Executor │    │ Executor │    │ Executor │
    └────┬─────┘    └────┬─────┘    └────┬─────┘
         │               │               │
         └───────────────┼───────────────┘
                         ▼
┌──────────────────────────────────────────────────────────────┐
│                   ExecutionContext                            │
│               (执行上下文 - 状态共享)                           │
└──────────────────────────────────────────────────────────────┘

2.2 节点类型设计

项目定义了 14 种节点类型,分为两大类:

控制流节点:

  • START - 工作流入口
  • END - 工作流出口
  • CONDITION - 条件判断
  • ROUTE - 路由分发
  • LOOP_END - 循环控制
  • FORK - 并行开始
  • JOIN - 并行结束

业务逻辑节点:

  • UNDERSTAND - 问题理解
  • RETRIEVE - 知识检索
  • PARALLEL_SEARCH - 并行检索
  • EVALUATE - 结果评估
  • GENERATE - 答案生成

三、核心组件解析

3.1 工作流引擎 (WorkflowEngine)

工作流引擎是整个系统的核心,负责:

  1. 加载和解析工作流定义
  2. 管理执行上下文
  3. 调度节点执行
  4. 处理流程控制
java 复制代码
public class WorkflowEngine {
    private final List<NodeExecutor> executors = new ArrayList<>();
    
    public ExecutionResult execute(RagWorkflow workflow, String userQuestion, String sessionId) {
        ExecutionContext context = ExecutionContext.builder()
            .executionId(UUID.randomUUID().toString())
            .userQuestion(userQuestion)
            .sessionId(sessionId)
            .build();
        
        String currentNodeId = workflow.getStartNodeId();
        
        while (currentNodeId != null) {
            NodeExecutor.NodeExecutionResult result = executeNode(workflow, currentNodeId, context);
            
            if (!result.success()) {
                context.setStatus("FAILED");
                break;
            }
            
            currentNodeId = selectNextNode(result);
        }
        
        return ExecutionResult.success(context);
    }
}

3.2 节点执行器模式

每个节点类型对应一个独立的执行器,采用策略模式

java 复制代码
public interface NodeExecutor {
    Class<NodeType> getSupportedNodeType();
    boolean supports(NodeType nodeType);
    NodeExecutionResult execute(WorkflowNode node, ExecutionContext context);
}

问题理解节点示例:

java 复制代码
@Component
public class UnderstandNodeExecutor implements NodeExecutor {
    private final ChatModel chatModel;
    
    @Override
    public NodeExecutionResult execute(WorkflowNode node, ExecutionContext context) {
        String question = context.getUserQuestion();
        
        String prompt = """
            分析以下用户问题:
            1. 提取关键词
            2. 判断问题类型(PRODUCT/TECHNICAL/GENERAL)
            
            问题:%s
            """.formatted(question);
        
        String result = chatModel.chat(prompt);
        context.setVariable("analysis", result);
        
        return NodeExecutionResult.next("route");
    }
}

3.3 执行上下文 (ExecutionContext)

执行上下文贯穿整个工作流生命周期,负责状态管理:

java 复制代码
@Data
@Builder
public class ExecutionContext {
    private String executionId;
    private String userQuestion;
    private String sessionId;
    private String status;
    private Map<String, Object> variables;
    private List<ExecutionLog> logs;
    
    public void setVariable(String key, Object value) {
        variables.put(key, value);
    }
    
    public Object getVariable(String key) {
        return variables.get(key);
    }
}

四、五种执行模式实现

4.1 顺序执行

最简单的模式,节点按线性顺序执行。

4.2 条件判断

通过 CONDITION 节点实现:

java 复制代码
@Override
public NodeExecutionResult execute(WorkflowNode node, ExecutionContext context) {
    Object quality = context.getVariable("quality");
    
    if (quality != null && (Double) quality >= 0.6) {
        return NodeExecutionResult.next("generate");
    } else {
        return NodeExecutionResult.next("retrieve");
    }
}

4.3 路由分发

通过 ROUTE 节点根据问题类型分发:

复制代码
问题类型判断:
├── PRODUCT → 产品检索分支
├── TECHNICAL → 技术检索分支
└── GENERAL → 通用检索分支

4.4 循环控制

支持重试机制,最多循环 3 次:

java 复制代码
@Override
public NodeExecutionResult execute(WorkflowNode node, ExecutionContext context) {
    int retryCount = context.getVariable("retryCount", 0);
    
    if (retryCount >= 3) {
        // 达到最大循环次数,退出
        return NodeExecutionResult.next("generate");
    }
    
    // 增加重试次数,继续循环
    context.setVariable("retryCount", retryCount + 1);
    return NodeExecutionResult.loopBack("parallel_search");
}

4.5 并行执行

通过 FORK/JOIN 节点实现多分支并行:

java 复制代码
private String executeParallelNodes(List<String> nodeIds, ExecutionContext context) {
    ExecutorService executor = Executors.newFixedThreadPool(
        Math.min(nodeIds.size(), 10)
    );
    
    List<Future<?>> futures = nodeIds.stream()
        .map(nodeId -> executor.submit(() -> executeNode(nodeId, context)))
        .collect(Collectors.toList());
    
    // 等待所有任务完成
    executor.shutdown();
    executor.awaitTermination(60, TimeUnit.SECONDS);
    
    return "join_node";  // 汇聚到 JOIN 节点
}

五、工作流执行流程

复制代码
START ──▶ UNDERSTAND ──▶ ROUTE ──┬──▶ search_product ──┐
                                 ├──▶ search_technical ──┼──▶ PARALLEL_SEARCH
                                 └──▶ search_general  ────┘           │
                                                                   │
                                                                   ▼
                                                              EVALUATE
                                                                   │
                                                          quality >= 0.6?
                                                         /              \
                                                        是              否
                                                       /                \
                                                      ▼                  ▼
                                               ┌──────────┐      LOOP_CONTROL
                                               │ GENERATE │             │
                                               └────┬─────┘             │
                                                    │                   ▼
                                                    │            retryCount < 3?
                                                   / \                 是
                                                  /   \                │
                                                 /     \               ▼
                                                ▼       ▼        返回检索
                                              START   END

六、API 接口设计

6.1 问答接口

bash 复制代码
POST http://localhost:8989/api/rag/ask

{
    "question": "你们的产品有哪些功能?",
    "sessionId": "optional-session-id"
}

响应:

json 复制代码
{
    "success": true,
    "sessionId": "abc-123",
    "answer": "我们的智能助手支持...",
    "questionType": "PRODUCT",
    "keywords": ["产品", "功能"],
    "retryCount": 0,
    "quality": 0.85,
    "duration": 1234,
    "logs": [...]
}

6.2 工作流查询

bash 复制代码
GET http://localhost:8989/api/rag/workflow
GET http://localhost:8989/api/rag/workflow/svg

七、项目结构

复制代码
src/main/java/com/example/demo/rag/
├── model/                    # 数据模型
│   ├── WorkflowNode.java    # 工作流节点
│   ├── WorkflowEdge.java     # 工作流边
│   ├── RagWorkflow.java      # 工作流定义
│   ├── ExecutionContext.java # 执行上下文
│   ├── NodeType.java         # 节点类型
│   └── EdgeType.java         # 边类型
│
├── executor/                 # 节点执行器
│   ├── NodeExecutor.java     # 执行器接口
│   ├── StartNodeExecutor.java
│   ├── UnderstandNodeExecutor.java
│   ├── RouteNodeExecutor.java
│   ├── ParallelSearchNodeExecutor.java
│   ├── EvaluateNodeExecutor.java
│   ├── LoopNodeExecutor.java
│   ├── GenerateNodeExecutor.java
│   └── EndNodeExecutor.java
│
├── engine/                   # 工作流引擎
│   ├── WorkflowEngine.java
│   └── DefaultRagWorkflow.java
│
└── controller/               # API 控制器
    └── RagController.java

八、技术栈

技术 版本 用途
Spring Boot 3.2.6 Web 框架
LangChain4j 1.13.0 LLM 集成
H2 Database - 内存数据库
Lombok - 简化代码

九、扩展建议

  1. 向量检索增强 - 集成 Milvus/Pinecone 实现语义检索
  2. 缓存层 - Redis 缓存高频检索结果
  3. 监控告警 - 集成 Prometheus/Grafana
  4. 可视化编辑器 - 拖拽式设计工作流

结语

通过这个项目,我们展示了如何构建一个功能完善的 RAG 工作流智能体。核心思想是将复杂的业务逻辑拆分为独立的节点,通过工作流引擎统一调度,既保证了代码的可维护性,又提供了足够的灵活性。

希望这个分享对大家有所帮助!

相关推荐
aicat_cn8 小时前
从预测未来到控制未来:机器人世界模型全景综述
ai·大模型
千桐科技11 小时前
qKnow 智能体构建平台开源版 2.1.1 正式发布!优化非结构化抽取、知识库召回,全面升级系统稳定性与交互体验
大模型·llm·工作流·qknow·智能体构建平台
索西引擎12 小时前
【LangChain 1.0】 接入 Ollama:在本地跑通 DeepSeek-R1 的完整指南
langchain
苦逼的猿宝13 小时前
洗衣店订单管理系统(源码+论文)
java·毕业设计·springboot·计算机毕业设计
codefan※13 小时前
一键部署私人 LLM:Ollama + Docker 极简指南
运维·docker·容器·大模型·llm·本地部署·ollama
苦逼的猿宝14 小时前
宠物咖啡馆平台的设计与实现(源码+论文)
java·毕业设计·springboot·计算机毕业设计
龙骑士baby14 小时前
重建 AI 认知第 3 篇:Prompt Engineering——怎么让 AI 听懂你的话
ai·大模型·llm·prompt
猫先生Mr.Mao14 小时前
一文梳理主流 LLM 架构技术演进
人工智能·架构·大模型·llm·transformer
苦逼的猿宝14 小时前
医院管理系统.(源码+论文)
java·毕业设计·springboot·计算机毕业设计