Claude-skill-registry ai-langchain4j
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/ai-langchain4j" ~/.claude/skills/majiayu000-claude-skill-registry-ai-langchain4j && rm -rf "$T"
manifest:
skills/data/ai-langchain4j/SKILL.mdsafety · automated scan (low risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- references .env files
- references API keys
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
AI 大模型集成规范
本规范基于LangChain4j框架,为若依-vue-plus项目定义统一的AI大模型集成标准。确保代码的可维护性、安全性和扩展性。
核心规范
规范1:模型配置与类型安全服务
目标:实现模型配置的集中管理和类型安全的AI服务定义。
详细说明:
- 配置管理:使用
构建器配置大模型,严禁在代码中硬编码API KeyChatLanguageModel - 配置来源:API Key必须从配置中心(如Nacos)或
读取application.yml - 接口定义:推荐使用LangChain4j的
接口定义模式,将系统提示词(System Message)与业务逻辑解耦AiServices - 动态参数:模型参数(temperature、topK、maxTokens等)应支持动态配置
- 多模型支持:设计时应考虑多模型切换能力(智谱AI、通义千问、OpenAI等)
实现要点:
- 使用
绑定配置@ConfigurationProperties - 通过工厂模式支持多模型动态切换
- 提供模型健康检查接口
// ============ 配置属性类 ============ @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检索增强与向量化存储
目标:构建高效的知识库问答系统,实现精准的语义检索。
详细说明:
- 向量化:使用
将文本转换为向量表示EmbeddingModel - 存储选择:根据规模选择合适的
(内存/Redis/Milvus)EmbeddingStore - 文档切分:使用
合理切分长文档(推荐500-1000字符/片段)DocumentSplitter - 检索策略:使用
检索相关片段,支持Top-K和相似度阈值ContentRetriever - 上下文构建:将检索结果与用户问题组合成完整Prompt
实现要点:
- 文档预处理:去除无关字符、统一格式
- 向量索引优化:定期重建索引
- 相似度计算:余弦相似度 > 0.7为相关片段
- 缓存机制:常见问题的检索结果缓存
// ============ 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:流式响应处理
目标:优化用户体验,避免长时间等待。
详细说明:
- 场景判断:超过3秒的推理请求必须使用流式响应
- 技术选型:Web端使用SSE(Server-Sent Events),WebSocket适用于双向通信场景
- 错误处理:流式过程中的异常必须优雅处理并通知前端
- 超时控制:设置合理的超时时间(推荐60秒)
- 取消机制:支持用户主动取消正在进行的流式响应
前端对接示例:
// 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工程最佳实践
目标:提升模型输出质量和稳定性。
详细说明:
- 结构化Prompt:使用明确的分隔符(如【】、===)区分不同部分
- 角色定义:在SystemMessage中明确AI的身份和职责
- 输出格式:要求模型返回结构化数据时,提供JSON Schema示例
- Few-Shot:复杂任务提供2-3个示例(输入-输出对)
- 约束条件:明确禁止事项和输出要求
Prompt模板示例:
@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消耗并进行成本统计和告警
- ❌ 禁止滥用高级模型:简单任务应使用便宜的模型,复杂任务再使用高级模型
实施指南
快速开始
- 添加依赖(pom.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>
- 配置文件(application.yml)
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
-
初始化配置类:参考"规范1"中的
LangChain4jConfig -
定义AI服务接口:参考"规范1"中的
AiAssistant -
实现业务逻辑:参考"规范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 - 前端组件:
(SSE流式接收示例)ruoyi-ui/src/views/ai/chat/index.vue - 配置文件:
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:
- 优化文档切分:根据文档类型调整切分大小(技术文档500字符,对话数据200字符)
- 提升检索质量:调整Top-K(3-5)和相似度阈值(0.7-0.8)
- 改进Prompt:在Prompt中明确要求"基于上下文回答,找不到则明确告知"
- 文档预处理:去除无关字符、统一格式、补充元数据
Q3:流式响应如何处理超时?
A:
// 在Flux中添加超时控制 return aiRagService.streamChatWithRag(query) .timeout(Duration.ofSeconds(60)) .onErrorResume(TimeoutException.class, e -> Flux.just("响应超时,请稍后重试") );
Q4:如何实现多模型成本对比?
A:
- 创建
记录每次调用的Token消耗TokenUsageRecorder - 按模型维度统计总消耗
- 根据官方定价计算成本:
成本 = (inputTokens * 输入单价 + outputTokens * 输出单价) / 1000
Q5:生产环境如何保证API Key安全?
A:
- 本地开发:使用
文件(已加入.env
).gitignore - 测试环境:使用配置中心(Nacos)加密配置
- 生产环境:使用密钥管理服务(如AWS KMS、阿里云KMS)
- 权限控制:限制只有运维人员可查看完整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开发团队