基于若依-vue-plus框架的LangChain4j AI大模型集成标准规范。全面规范模型配置管理、类型安全服务定义、RAG(检索增强生成)实现、流式响应处理及安全性保障。 触发场景: - 开发智能客服系统、文档问答助手、代码生成工具 - 集成LLM大模型接口(OpenAI、智谱AI、通义千问等) - 实现知识库问答、文档检索、语义搜索功能 - 开发需要流式响应的AI交互界面 - 构建RAG(检索增强生成)应用 触发词:AI集成、LangChain4j、大模型、RAG、流式输出、智谱AI、通义千问、OpenAI、向量检索、嵌入模型、Prompt工程
Scanned 6/3/2026
Install to Claude Code
npx -y skills add majiayu000/claude-skill-registry --skill ai-langchain4j --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ai Langchain4j?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/majiayu000-ai-langchain4j)More formats (shields.io, HTML) on the badges page.
---
name: ai-langchain4j
description: |
基于若依-vue-plus框架的LangChain4j AI大模型集成标准规范。全面规范模型配置管理、类型安全服务定义、RAG(检索增强生成)实现、流式响应处理及安全性保障。
触发场景:
- 开发智能客服系统、文档问答助手、代码生成工具
- 集成LLM大模型接口(OpenAI、智谱AI、通义千问等)
- 实现知识库问答、文档检索、语义搜索功能
- 开发需要流式响应的AI交互界面
- 构建RAG(检索增强生成)应用
触发词:AI集成、LangChain4j、大模型、RAG、流式输出、智谱AI、通义千问、OpenAI、向量检索、嵌入模型、Prompt工程
---
# AI 大模型集成规范
> 本规范基于LangChain4j框架,为若依-vue-plus项目定义统一的AI大模型集成标准。确保代码的可维护性、安全性和扩展性。
## 核心规范
### 规范1:模型配置与类型安全服务
**目标**:实现模型配置的集中管理和类型安全的AI服务定义。
**详细说明**:
1. **配置管理**:使用`ChatLanguageModel`构建器配置大模型,严禁在代码中硬编码API Key
2. **配置来源**:API Key必须从配置中心(如Nacos)或`application.yml`读取
3. **接口定义**:推荐使用LangChain4j的`AiServices`接口定义模式,将系统提示词(System Message)与业务逻辑解耦
4. **动态参数**:模型参数(temperature、topK、maxTokens等)应支持动态配置
5. **多模型支持**:设计时应考虑多模型切换能力(智谱AI、通义千问、OpenAI等)
**实现要点**:
- 使用`@ConfigurationProperties`绑定配置
- 通过工厂模式支持多模型动态切换
- 提供模型健康检查接口
```java
// ============ 配置属性类 ============
@Data
@Component
@ConfigurationProperties(prefix = "ai.model")
public class AiProperties {
private String provider; // openai/zhipu/qwen
private String baseUrl;
private String apiKey;
private String modelName;
private Double temperature = 0.7;
private Integer maxTokens = 2000;
private Integer timeout = 60; // 秒
}
// ============ 配置类:动态初始化模型 ============
@Configuration
@EnableConfigurationProperties(AiProperties.class)
public class LangChain4jConfig {
@Bean
public ChatLanguageModel chatLanguageModel(AiProperties properties) {
// 根据provider动态选择模型
return switch (properties.getProvider()) {
case "openai" -> OpenAiChatModel.builder()
.baseUrl(properties.getBaseUrl())
.apiKey(properties.getApiKey())
.modelName(properties.getModelName())
.temperature(properties.getTemperature())
.maxTokens(properties.getMaxTokens())
.timeout(Duration.ofSeconds(properties.getTimeout()))
.logRequests(true)
.logResponses(true)
.build();
case "zhipu" -> ZhipuAiChatModel.builder()
.apiKey(properties.getApiKey())
.modelName(properties.getModelName())
.temperature(properties.getTemperature())
.build();
// 其他模型...
default -> throw new IllegalArgumentException("不支持的模型提供商: " + properties.getProvider());
};
}
// 流式模型配置
@Bean
public StreamingChatLanguageModel streamingChatLanguageModel(AiProperties properties) {
return OpenAiStreamingChatModel.builder()
.baseUrl(properties.getBaseUrl())
.apiKey(properties.getApiKey())
.modelName(properties.getModelName())
.temperature(properties.getTemperature())
.build();
}
}
// ============ 定义类型安全的AI服务接口 ============
public interface AiAssistant {
/**
* 通用对话接口
* @param userMessage 用户消息
* @return AI响应
*/
@SystemMessage("""
你是一个专业的若依框架助手。
- 回答必须简洁、准确、专业
- 使用Java代码示例时,遵循阿里巴巴Java开发规范
- 涉及若依框架时,优先使用框架提供的工具类
""")
String chat(@UserMessage String userMessage);
/**
* 实体提取接口
* @param text 待提取文本
* @return JSON格式的实体列表
*/
@SystemMessage("""
提取以下文本中的关键实体(人名、地名、组织、时间等)。
返回格式:{"entities": [{"type": "人名", "value": "张三"}]}
""")
String extractEntities(@UserMessage String text);
/**
* 代码审查接口
* @param code 待审查的代码
* @return 审查建议
*/
@SystemMessage("""
你是一个资深Java代码审查专家。
审查以下代码,关注:
1. 代码规范性
2. 性能问题
3. 安全隐患
4. 可维护性
返回格式化的审查报告。
""")
String reviewCode(@UserMessage String code);
}
// ============ 服务实现:通过AiServices自动生成代理 ============
@Service
public class AiAssistantService {
private final AiAssistant aiAssistant;
public AiAssistantService(ChatLanguageModel chatLanguageModel) {
this.aiAssistant = AiServices.create(AiAssistant.class, chatLanguageModel);
}
public String chat(String message) {
return aiAssistant.chat(message);
}
}
```
### 规范2:RAG检索增强与向量化存储
**目标**:构建高效的知识库问答系统,实现精准的语义检索。
**详细说明**:
1. **向量化**:使用`EmbeddingModel`将文本转换为向量表示
2. **存储选择**:根据规模选择合适的`EmbeddingStore`(内存/Redis/Milvus)
3. **文档切分**:使用`DocumentSplitter`合理切分长文档(推荐500-1000字符/片段)
4. **检索策略**:使用`ContentRetriever`检索相关片段,支持Top-K和相似度阈值
5. **上下文构建**:将检索结果与用户问题组合成完整Prompt
**实现要点**:
- 文档预处理:去除无关字符、统一格式
- 向量索引优化:定期重建索引
- 相似度计算:余弦相似度 > 0.7为相关片段
- 缓存机制:常见问题的检索结果缓存
```java
// ============ RAG配置类 ============
@Configuration
public class RagConfig {
/**
* 嵌入模型配置
*/
@Bean
public EmbeddingModel embeddingModel(AiProperties properties) {
return OpenAiEmbeddingModel.builder()
.baseUrl(properties.getBaseUrl())
.apiKey(properties.getApiKey())
.modelName("text-embedding-ada-002") // 或使用国产模型
.build();
}
/**
* 向量存储(示例:内存存储,生产环境建议使用Redis/Milvus)
*/
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return new InMemoryEmbeddingStore<>();
}
/**
* 文档切分器
*/
@Bean
public DocumentSplitter documentSplitter() {
return DocumentSplitters.recursive(
500, // 每个片段最大字符数
100, // 片段间重叠字符数(保持上下文连贯)
new OpenAiTokenizer() // Token计数器
);
}
}
// ============ RAG服务实现 ============
@Service
@Slf4j
public class AiRagService {
private final StreamingChatLanguageModel streamingModel;
private final EmbeddingModel embeddingModel;
private final EmbeddingStore<TextSegment> embeddingStore;
private final ContentRetriever contentRetriever;
public AiRagService(StreamingChatLanguageModel streamingModel,
EmbeddingModel embeddingModel,
EmbeddingStore<TextSegment> embeddingStore) {
this.streamingModel = streamingModel;
this.embeddingModel = embeddingModel;
this.embeddingStore = embeddingStore;
// 构建检索器:Top-3相关片段,相似度阈值0.7
this.contentRetriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(3)
.minScore(0.7)
.build();
}
/**
* 导入文档到知识库
* @param filePath 文档路径
*/
public void ingestDocument(String filePath) {
try {
// 1. 加载文档
Document document = FileSystemDocumentLoader.loadDocument(filePath);
// 2. 切分文档
DocumentSplitter splitter = DocumentSplitters.recursive(500, 100);
List<TextSegment> segments = splitter.split(document);
// 3. 向量化并存储
List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
embeddingStore.addAll(embeddings, segments);
log.info("成功导入文档: {}, 切分为{}个片段", filePath, segments.size());
} catch (Exception e) {
log.error("文档导入失败: {}", filePath, e);
throw new BusinessException("文档导入失败");
}
}
/**
* 流式问答 + RAG
* @param query 用户问题
* @return 流式响应
*/
public Flux<String> streamChatWithRag(String query) {
// 1. 检索相关上下文
List<Content> relevantContents = contentRetriever.retrieve(Query.from(query));
// 2. 构建包含上下文的Prompt
String context = relevantContents.stream()
.map(Content::textSegment)
.map(TextSegment::text)
.collect(Collectors.joining("\n\n"));
String enhancedPrompt = String.format("""
基于以下知识库内容回答用户问题:
【知识库内容】
%s
【用户问题】
%s
【要求】
- 优先使用知识库内容回答
- 如果知识库无相关内容,明确告知用户
- 回答要准确、简洁、专业
""", context, query);
// 3. 流式调用模型
return Flux.create(sink -> {
streamingModel.generate(enhancedPrompt, new StreamingResponseHandler<AiMessage>() {
@Override
public void onNext(String token) {
sink.next(token);
}
@Override
public void onComplete(Response<AiMessage> response) {
sink.complete();
log.info("流式响应完成,Token使用: {}", response.tokenUsage());
}
@Override
public void onError(Throwable error) {
log.error("流式响应错误", error);
sink.error(error);
}
});
});
}
/**
* 普通问答(非流式)
*/
public String chatWithRag(String query) {
List<Content> relevantContents = contentRetriever.retrieve(Query.from(query));
String context = relevantContents.stream()
.map(Content::textSegment)
.map(TextSegment::text)
.collect(Collectors.joining("\n\n"));
Prompt prompt = Prompt.from(
SystemMessage.from("你是知识库问答助手,基于提供的上下文回答问题"),
UserMessage.from("上下文:\n" + context + "\n\n问题:" + query)
);
Response<AiMessage> response = chatLanguageModel.generate(prompt);
return response.content().text();
}
}
// ============ Controller层:SSE流式响应 ============
@RestController
@RequestMapping("/ai/chat")
@Slf4j
public class AiChatController {
@Resource
private AiRagService aiRagService;
/**
* 流式问答接口(SSE)
*/
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> streamChat(@RequestParam String query) {
return aiRagService.streamChatWithRag(query)
.map(token -> ServerSentEvent.<String>builder()
.data(token)
.build())
.doOnComplete(() -> log.info("流式响应完成: {}", query))
.doOnError(e -> log.error("流式响应异常", e));
}
/**
* 普通问答接口
*/
@PostMapping("/ask")
public R<String> ask(@RequestBody AiChatRequest request) {
String answer = aiRagService.chatWithRag(request.getQuery());
return R.ok(answer);
}
}
```
### 规范3:流式响应处理
**目标**:优化用户体验,避免长时间等待。
**详细说明**:
1. **场景判断**:超过3秒的推理请求必须使用流式响应
2. **技术选型**:Web端使用SSE(Server-Sent Events),WebSocket适用于双向通信场景
3. **错误处理**:流式过程中的异常必须优雅处理并通知前端
4. **超时控制**:设置合理的超时时间(推荐60秒)
5. **取消机制**:支持用户主动取消正在进行的流式响应
**前端对接示例**:
```javascript
// Vue3 + EventSource 接收SSE流式响应
const streamChat = async (query) => {
const eventSource = new EventSource(`/ai/chat/stream?query=${encodeURIComponent(query)}`);
let fullResponse = '';
eventSource.onmessage = (event) => {
const token = event.data;
fullResponse += token;
// 实时更新UI
chatMessage.value = fullResponse;
};
eventSource.onerror = (error) => {
console.error('流式响应错误:', error);
eventSource.close();
ElMessage.error('AI响应异常,请重试');
};
eventSource.addEventListener('done', () => {
eventSource.close();
console.log('流式响应完成');
});
};
```
### 规范4:Prompt工程最佳实践
**目标**:提升模型输出质量和稳定性。
**详细说明**:
1. **结构化Prompt**:使用明确的分隔符(如【】、===)区分不同部分
2. **角色定义**:在SystemMessage中明确AI的身份和职责
3. **输出格式**:要求模型返回结构化数据时,提供JSON Schema示例
4. **Few-Shot**:复杂任务提供2-3个示例(输入-输出对)
5. **约束条件**:明确禁止事项和输出要求
**Prompt模板示例**:
```java
@SystemMessage("""
【角色】你是一个资深Java后端开发专家,熟悉Spring Boot和若依框架
【任务】根据用户需求生成符合规范的代码
【要求】
1. 代码必须遵循阿里巴巴Java开发规范
2. 使用若依框架提供的BaseController、BaseEntity等基类
3. 添加详细的中文注释
4. 包含必要的参数校验和异常处理
【禁止】
- 不要生成硬编码的配置信息
- 不要使用已废弃的API
- 不要省略异常处理代码
【输出格式】
返回完整的Java类代码,包含package、import和类定义
""")
String generateCode(@UserMessage String requirement);
```
## 禁止事项
### 安全相关
- ❌ **禁止硬编码API Key**:API Key必须从配置中心或环境变量读取,严禁写入代码或提交到Git
- ❌ **禁止发送敏感数据**:未经脱敏的个人信息、密码、密钥等敏感数据禁止注入Prompt
- ❌ **禁止盲目信任输出**:AI生成的代码、SQL、Shell命令必须人工审核或沙箱验证后才能执行
- ❌ **禁止跳过权限校验**:AI接口必须进行身份认证和权限验证
- ❌ **禁止忽略数据脱敏**:日志记录的Prompt和Response必须脱敏处理
### 性能相关
- ❌ **禁止同步阻塞调用**:超过3秒的推理请求必须使用流式或异步任务机制
- ❌ **禁止无限制并发**:必须使用线程池和限流机制(如Sentinel)控制并发数
- ❌ **禁止忽略Token限制**:前端必须进行输入长度校验,后端必须进行Token计数和截断
### 质量相关
- ❌ **禁止使用不稳定的Prompt**:Prompt必须经过测试验证,避免随意修改导致输出不稳定
- ❌ **禁止缺少错误处理**:所有AI调用必须包含try-catch和超时处理
- ❌ **禁止缺少日志记录**:必须记录请求参数、响应结果、耗时、Token消耗等关键信息
- ❌ **禁止忽略模型切换**:代码应支持多模型动态切换,不能硬绑定特定厂商
### 成本相关
- ❌ **禁止无限制调用**:必须设置用户维度的调用频率限制(如QPM、QPD)
- ❌ **禁止忽略成本监控**:必须记录Token消耗并进行成本统计和告警
- ❌ **禁止滥用高级模型**:简单任务应使用便宜的模型,复杂任务再使用高级模型
## 实施指南
### 快速开始
1. **添加依赖**(pom.xml)
```xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>0.35.0</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>0.35.0</version>
</dependency>
<!-- RAG相关依赖 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings</artifactId>
<version>0.35.0</version>
</dependency>
```
2. **配置文件**(application.yml)
```yaml
ai:
model:
provider: openai # 可选:openai/zhipu/qwen
base-url: https://api.openai.com/v1
api-key: ${AI_API_KEY} # 从环境变量读取
model-name: gpt-4o-mini
temperature: 0.7
max-tokens: 2000
timeout: 60
```
3. **初始化配置类**:参考"规范1"中的`LangChain4jConfig`
4. **定义AI服务接口**:参考"规范1"中的`AiAssistant`
5. **实现业务逻辑**:参考"规范2"中的`AiRagService`
### 典型应用场景
#### 场景1:智能客服机器人
- 导入产品文档、FAQ到知识库
- 使用RAG检索相关答案
- 流式输出提升用户体验
#### 场景2:代码生成助手
- 定义代码生成AI服务接口
- 提供详细的Prompt模板
- 生成符合项目规范的代码
#### 场景3:文档智能问答
- 上传PDF/Word文档
- 自动切分并向量化
- 支持自然语言查询
#### 场景4:数据分析助手
- 将数据库Schema注入Prompt
- 生成SQL查询语句
- 解释查询结果(需人工审核SQL)
## 参考代码
### 项目结构
```
ruoyi-ai/
├── config/
│ ├── LangChain4jConfig.java # 模型配置
│ ├── RagConfig.java # RAG配置
│ └── AiProperties.java # 配置属性类
├── service/
│ ├── AiAssistant.java # AI服务接口定义
│ ├── AiAssistantService.java # 通用对话服务
│ ├── AiRagService.java # RAG服务
│ └── AiCodeGeneratorService.java # 代码生成服务
├── controller/
│ ├── AiChatController.java # 对话接口
│ └── AiKnowledgeController.java # 知识库管理接口
└── domain/
├── dto/
│ ├── AiChatRequest.java
│ └── AiChatResponse.java
└── vo/
└── TokenUsageVO.java
```
### 关键文件路径
- 核心配置:`ruoyi-ai/src/main/java/com/ruoyi/ai/config/LangChain4jConfig.java`
- RAG服务:`ruoyi-ai/src/main/java/com/ruoyi/ai/service/AiRagService.java`
- 流式接口:`ruoyi-ai/src/main/java/com/ruoyi/ai/controller/AiChatController.java`
- 前端组件:`ruoyi-ui/src/views/ai/chat/index.vue`(SSE流式接收示例)
- 配置文件:`ruoyi-ai/src/main/resources/application-ai.yml`
## 检查清单
### 开发阶段
- [ ] **配置管理**
- [ ] API Key从配置中心或环境变量读取
- [ ] 支持多模型动态切换(至少2个提供商)
- [ ] 模型参数可配置(temperature、maxTokens等)
- [ ] 配置了合理的超时时间(推荐60秒)
- [ ] **服务定义**
- [ ] 使用AiServices接口定义模式
- [ ] SystemMessage与业务逻辑解耦
- [ ] Prompt结构化且经过测试验证
- [ ] 包含清晰的角色、任务、要求、禁止项
- [ ] **RAG实现**(如果需要)
- [ ] 正确配置EmbeddingModel
- [ ] 选择合适的EmbeddingStore(内存/Redis/Milvus)
- [ ] 文档切分大小合理(500-1000字符)
- [ ] 设置了相似度阈值(推荐>0.7)
- [ ] 实现了文档导入和更新机制
- [ ] **流式响应**
- [ ] 超过3秒的请求使用StreamingChatLanguageModel
- [ ] Controller正确处理Flux/SseEmitter
- [ ] 前端正确接收SSE流式数据
- [ ] 实现了错误处理和超时机制
- [ ] 支持用户取消正在进行的请求
### 安全阶段
- [ ] **数据安全**
- [ ] 敏感数据已脱敏处理
- [ ] 日志中的Prompt和Response已脱敏
- [ ] API Key未硬编码或提交到Git
- [ ] 实现了接口权限校验
- [ ] **输出安全**
- [ ] AI生成的代码/SQL需人工审核
- [ ] 实现了输出内容过滤机制
- [ ] 不直接执行AI生成的命令
### 性能阶段
- [ ] **并发控制**
- [ ] 配置了线程池管理AI请求
- [ ] 实现了限流机制(Sentinel/RateLimiter)
- [ ] 设置了用户维度的QPM/QPD限制
- [ ] **成本控制**
- [ ] 前端进行输入长度校验
- [ ] 后端进行Token计数和截断
- [ ] 记录Token消耗并统计
- [ ] 设置了成本告警阈值
- [ ] **缓存优化**
- [ ] 常见问题使用缓存(Redis)
- [ ] RAG检索结果合理缓存
- [ ] 模型响应缓存(相同问题)
### 质量阶段
- [ ] **错误处理**
- [ ] 所有AI调用包含try-catch
- [ ] 超时异常有明确提示
- [ ] 流式响应错误优雅降级
- [ ] **日志记录**
- [ ] 记录请求参数(脱敏后)
- [ ] 记录响应结果(脱敏后)
- [ ] 记录耗时和Token消耗
- [ ] 记录异常堆栈信息
- [ ] **监控告警**
- [ ] 接入APM监控(如Skywalking)
- [ ] 配置响应时间告警
- [ ] 配置错误率告警
- [ ] 配置成本异常告警
### 测试阶段
- [ ] **单元测试**
- [ ] 测试模型配置初始化
- [ ] 测试AI服务接口调用
- [ ] 测试RAG检索逻辑
- [ ] 测试异常处理逻辑
- [ ] **集成测试**
- [ ] 测试端到端流式响应
- [ ] 测试不同模型切换
- [ ] 测试并发场景
- [ ] 测试超时场景
- [ ] **压力测试**
- [ ] 测试系统最大QPS
- [ ] 测试长连接数上限
- [ ] 测试内存占用情况
## 常见问题
### Q1:如何选择合适的EmbeddingStore?
**A**:
- **开发/测试环境**:使用`InMemoryEmbeddingStore`(简单快速)
- **小规模生产**(<10万条):使用`RedisEmbeddingStore`(易维护)
- **大规模生产**(>10万条):使用`MilvusEmbeddingStore`或`PineconeEmbeddingStore`(专业向量数据库)
### Q2:如何优化RAG检索准确率?
**A**:
1. **优化文档切分**:根据文档类型调整切分大小(技术文档500字符,对话数据200字符)
2. **提升检索质量**:调整Top-K(3-5)和相似度阈值(0.7-0.8)
3. **改进Prompt**:在Prompt中明确要求"基于上下文回答,找不到则明确告知"
4. **文档预处理**:去除无关字符、统一格式、补充元数据
### Q3:流式响应如何处理超时?
**A**:
```java
// 在Flux中添加超时控制
return aiRagService.streamChatWithRag(query)
.timeout(Duration.ofSeconds(60))
.onErrorResume(TimeoutException.class, e ->
Flux.just("响应超时,请稍后重试")
);
```
### Q4:如何实现多模型成本对比?
**A**:
1. 创建`TokenUsageRecorder`记录每次调用的Token消耗
2. 按模型维度统计总消耗
3. 根据官方定价计算成本:`成本 = (inputTokens * 输入单价 + outputTokens * 输出单价) / 1000`
### Q5:生产环境如何保证API Key安全?
**A**:
1. **本地开发**:使用`.env`文件(已加入`.gitignore`)
2. **测试环境**:使用配置中心(Nacos)加密配置
3. **生产环境**:使用密钥管理服务(如AWS KMS、阿里云KMS)
4. **权限控制**:限制只有运维人员可查看完整Key
## 扩展资源
### 官方文档
- LangChain4j官方文档:https://docs.langchain4j.dev
- Spring AI文档:https://docs.spring.io/spring-ai/reference
### 模型提供商
- OpenAI:https://platform.openai.com/docs
- 智谱AI:https://open.bigmodel.cn/dev/api
- 通义千问:https://help.aliyun.com/zh/dashscope
- Kimi(月之暗面):https://platform.moonshot.cn/docs
### 向量数据库
- Milvus:https://milvus.io/docs
- Pinecone:https://docs.pinecone.io
- Weaviate:https://weaviate.io/developers/weaviate
---
**版本**:v1.0.0
**最后更新**:2026-01-26
**维护者**:AI开发团队Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!