前言
在 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)
工作流引擎是整个系统的核心,负责:
- 加载和解析工作流定义
- 管理执行上下文
- 调度节点执行
- 处理流程控制
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 | - | 简化代码 |
九、扩展建议
- 向量检索增强 - 集成 Milvus/Pinecone 实现语义检索
- 缓存层 - Redis 缓存高频检索结果
- 监控告警 - 集成 Prometheus/Grafana
- 可视化编辑器 - 拖拽式设计工作流
结语
通过这个项目,我们展示了如何构建一个功能完善的 RAG 工作流智能体。核心思想是将复杂的业务逻辑拆分为独立的节点,通过工作流引擎统一调度,既保证了代码的可维护性,又提供了足够的灵活性。
希望这个分享对大家有所帮助!