Spring AI Alibaba 用户使用手册
1. 入门安装1.1 环境要求在开始之前请确保您的开发环境满足以下条件JDK: 17 或更高版本Spring Boot: 3.5.x 版本Maven: 3.8 或 Gradle 7.x阿里云账号: 用于获取 DashScope API Key1.2 创建 Spring Boot 项目推荐使用 Spring Initializr 创建项目选择以下依赖Spring Boot 3.5.8Spring Web其他您需要的依赖如 Lombok、Spring Data JPA 等1.3 添加 Maven 依赖在项目的pom.xml中添加 Spring AI Alibaba 的核心依赖?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.8/version relativePath/ /parent groupIdcom.example/groupId artifactIdspring-ai-alibaba-demo/artifactId version1.0.0/version nameSpring AI Alibaba Demo/name properties java.version17/java.version spring-ai-alibaba.version1.1.2.2/spring-ai-alibaba.version spring-ai.version1.1.2/spring-ai.version /properties dependencies !-- Spring Boot Web Starter -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI Alibaba Starter -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter/artifactId version${spring-ai-alibaba.version}/version /dependency !-- 可选Nacos 配置中心支持 -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-config-nacos/artifactId version${spring-ai-alibaba.version}/version /dependency !-- 可选Graph 可观测性支持 -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-graph-observation/artifactId version${spring-ai-alibaba.version}/version /dependency !-- 测试依赖 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies repositories !-- Spring Milestone Repository -- repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories /project依赖说明依赖作用是否必须spring-ai-alibaba-starter核心功能包含 Chat/Embedding/Image 模型支持是spring-ai-alibaba-starter-config-nacosNacos 配置中心集成支持动态配置否spring-ai-alibaba-starter-graph-observationMicrometer 可观测性支持否1.4 获取 API Key登录 阿里云百炼平台进入API Key 管理页面创建新的 API Key复制并保存好您的 Key格式通常为sk-xxxxxxxx2. 基础配置2.1 最小化配置在src/main/resources/application.yml中添加最基础的配置spring: ai: alibaba: dashscope: api-key: ${DASHSCOPE_API_KEY:your-api-key-here}安全提示生产环境建议将 API Key 配置在环境变量中避免硬编码到代码仓库。2.2 完整配置详解以下是生产环境推荐的完整配置spring: ai: alibaba: dashscope: # API 密钥配置 api-key: ${DASHSCOPE_API_KEY} # 聊天模型配置 chat: options: # 模型名称可选值 # - qwen-max: 通义千问 Max综合能力最强 # - qwen-plus: 通义千问 Plus平衡性能与成本 # - qwen-turbo: 通义千问 Turbo响应速度最快 model: qwen-max # 温度参数控制生成随机性 (0.0 - 2.0) # 越低越确定越高越创造性 temperature: 0.7 # 最大生成 token 数 max-tokens: 2048 # Top-P 采样控制多样性 (0.0 - 1.0) top-p: 0.9 # 重复惩罚系数 (1.0 - 2.0) # 越高越不容易重复 repetition-penalty: 1.1 # 向量模型配置 embedding: options: # 向量模型名称 model: text-embedding-v3 # 向量维度 dimensions: 1536 # 图像模型配置 image: options: # 图像生成模型 model: wanx-v1 # 图像尺寸 size: 1024x1024 # HTTP 客户端配置高级 client: # 连接超时时间秒 connect-timeout: 30 # 读取超时时间秒 read-timeout: 60 # 连接池最大连接数 max-connections: 100 # 单个路由最大连接数 max-connections-per-route: 202.3 配置参数调优建议参数默认值调优建议temperature0.7创意写作: 0.9代码生成: 0.2-0.5问答: 0.3-0.7max-tokens2048长文本生成可设为 4096 或更高top-p0.9与 temperature 配合通常保持 0.9-1.0repetition-penalty1.0对话场景建议 1.1-1.23. 对话功能3.1 使用 ChatClient 进行对话ChatClient是 Spring AI 提供的高级对话接口使用方式简单直观。代码示例import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; Service public class ChatService { private final ChatClient chatClient; // 通过构造函数注入 ChatClient public ChatService(ChatClient.Builder chatClientBuilder) { // 可以在这里设置默认的系统提示词 this.chatClient chatClientBuilder .defaultSystem(你是一个 helpful 的 AI 助手请用中文回答用户问题。) .build(); } /** * 单轮对话 */ public String chat(String userMessage) { return chatClient.prompt() .user(userMessage) .call() // 发起调用 .content(); // 获取文本内容 } /** * 多轮对话带上下文 */ public String chatWithHistory(String userMessage, String conversationHistory) { return chatClient.prompt() .system(以下是之前的对话历史 conversationHistory) .user(userMessage) .call() .content(); } /** * 流式输出打字机效果 */ public FluxString streamChat(String userMessage) { return chatClient.prompt() .user(userMessage) .stream() // 启用流式输出 .content(); } /** * 获取完整的响应对象 */ public ChatResponse chatWithMetadata(String userMessage) { return chatClient.prompt() .user(userMessage) .call() .chatResponse(); } }Controller 层示例import com.example.demo.service.ChatService; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; RestController RequestMapping(/api/chat) public class ChatController { private final ChatService chatService; public ChatController(ChatService chatService) { this.chatService chatService; } PostMapping(/ask) public String ask(RequestBody String message) { return chatService.chat(message); } PostMapping(value /stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString stream(RequestBody String message) { return chatService.streamChat(message); } }3.2 使用 ChatModel 进行底层控制如果您需要更精细的控制可以直接使用ChatModelimport org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.stereotype.Service; Service public class AdvancedChatService { private final ChatModel chatModel; public AdvancedChatService(ChatModel chatModel) { this.chatModel chatModel; } /** * 使用自定义参数进行对话 */ public String chatWithCustomOptions(String message) { // 创建自定义选项 OpenAiChatOptions options OpenAiChatOptions.builder() .model(qwen-max) .temperature(0.3) // 更确定的回答 .maxTokens(1024) .build(); // 构建 Prompt Prompt prompt new Prompt( new UserMessage(message), options ); // 调用模型 ChatResponse response chatModel.call(prompt); return response.getResult().getOutput().getText(); } }3.3 Spring AI 标准 vs Alibaba 扩展特性SPRING AI 标准SPRING AI ALIBABA 扩展模型支持OpenAI、Azure 等阿里云 DashScope 全系模型默认模型gpt-3.5-turboqwen-max中文优化基础支持针对中文场景深度优化向量模型text-embedding-ada-002text-embedding-v34. 文本向量化4.1 基础向量化将文本转换为向量Embedding用于语义搜索、相似度计算等场景import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.embedding.EmbeddingRequest; import org.springframework.ai.embedding.EmbeddingResponse; import org.springframework.stereotype.Service; import java.util.List; Service public class EmbeddingService { private final EmbeddingModel embeddingModel; public EmbeddingService(EmbeddingModel embeddingModel) { this.embeddingModel embeddingModel; } /** * 单文本向量化 */ public float[] embed(String text) { return embeddingModel.embed(text); } /** * 批量向量化 */ public Listfloat[] embedBatch(ListString texts) { EmbeddingRequest request new EmbeddingRequest(texts, null); EmbeddingResponse response embeddingModel.call(request); return response.getResults().stream() .map(result - result.getOutput()) .toList(); } /** * 计算两个文本的相似度 */ public double calculateSimilarity(String text1, String text2) { float[] embedding1 embed(text1); float[] embedding2 embed(text2); return cosineSimilarity(embedding1, embedding2); } /** * 余弦相似度计算 */ private double cosineSimilarity(float[] vec1, float[] vec2) { double dotProduct 0.0; double norm1 0.0; double norm2 0.0; for (int i 0; i vec1.length; i) { dotProduct vec1[i] * vec2[i]; norm1 vec1[i] * vec1[i]; norm2 vec2[i] * vec2[i]; } return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2)); } }4.2 向量存储与检索简单内存版import org.springframework.ai.document.Document; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.vectorstore.SimpleVectorStore; import org.springframework.stereotype.Service; import jakarta.annotation.PostConstruct; import java.util.List; import java.util.Map; Service public class SimpleVectorService { private final VectorStore vectorStore; private final EmbeddingService embeddingService; public SimpleVectorService(EmbeddingService embeddingService) { this.embeddingService embeddingService; // 使用内存向量存储仅适用于开发和测试 this.vectorStore SimpleVectorStore.builder(embeddingService.getEmbeddingModel()).build(); } /** * 添加文档到向量库 */ public void addDocument(String content, MapString, Object metadata) { Document document new Document(content, metadata); vectorStore.add(List.of(document)); } /** * 相似性搜索 */ public ListDocument search(String query, int topK) { return vectorStore.similaritySearch( SearchRequest.builder() .query(query) .topK(topK) .build() ); } }5. 图像生成5.1 基础图像生成import org.springframework.ai.image.ImageModel; import org.springframework.ai.image.ImagePrompt; import org.springframework.ai.image.ImageResponse; import org.springframework.stereotype.Service; Service public class ImageService { private final ImageModel imageModel; public ImageService(ImageModel imageModel) { this.imageModel imageModel; } /** * 根据描述生成图像 */ public String generateImage(String description) { ImagePrompt prompt new ImagePrompt(description); ImageResponse response imageModel.call(prompt); // 返回图像 URL return response.getResult().getOutput().getUrl(); } /** * 生成特定风格的图像 */ public String generateStyledImage(String description, String style) { String styledPrompt String.format( %s风格%s高质量细节丰富, description, style ); return generateImage(styledPrompt); } }6. RAG 检索增强RAGRetrieval-Augmented Generation将检索与生成结合让 AI 基于私有知识回答问题。6.1 完整 RAG 实现import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor; import org.springframework.ai.document.Document; import org.springframework.ai.reader.TextReader; import org.springframework.ai.transformer.splitter.TokenTextSplitter; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import jakarta.annotation.PostConstruct; import java.util.List; Service public class RagService { private final ChatClient chatClient; private final VectorStore vectorStore; public RagService(ChatClient.Builder chatClientBuilder, VectorStore vectorStore) { this.vectorStore vectorStore; this.chatClient chatClientBuilder .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore)) .build(); } /** * 加载文档到知识库 */ PostConstruct public void initKnowledgeBase() { // 方式1从文件加载 // Resource resource new ClassPathResource(knowledge.txt); // loadDocument(resource); // 方式2从字符串加载 String knowledge Spring AI Alibaba 是阿里云开发的 Spring AI 实现 提供了对 DashScope 模型的一站式支持。 支持的功能包括对话、向量化、图像生成等。 ; loadFromText(knowledge); } /** * 从文本加载知识 */ public void loadFromText(String text) { // 将长文本切分成小块 TokenTextSplitter splitter new TokenTextSplitter( 500, // 每个块的最大token数 50, // 重叠token数 10, // 最小块大小 1000, // 最大块大小 true // 保留分隔符 ); ListDocument documents splitter.split(new Document(text)); // 存储到向量库 vectorStore.add(documents); } /** * 基于知识库回答问题 */ public String askWithKnowledge(String question) { return chatClient.prompt() .user(question) .call() .content(); } }6.2 Controller 使用示例import com.example.demo.service.RagService; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; RestController RequestMapping(/api/rag) public class RagController { private final RagService ragService; public RagController(RagService ragService) { this.ragService ragService; } PostMapping(/ask) public String ask(RequestParam String question) { return ragService.askWithKnowledge(question); } PostMapping(/upload) public String uploadKnowledge(RequestParam(file) MultipartFile file) { try { String content new String(file.getBytes()); ragService.loadFromText(content); return 知识库更新成功; } catch (Exception e) { return 上传失败: e.getMessage(); } } }7. 工具函数Function Calling 让 AI 可以调用外部工具实现与真实世界的交互。7.1 定义工具函数import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.stereotype.Component; Component public class WeatherTools { /** * 获取城市天气 */ Tool(name get_weather, description 获取指定城市的当前天气信息) public String getWeather( ToolParam(description 城市名称如北京、上海) String city) { // 这里应该调用真实的天气 API // 示例返回 return String.format(%s今天天气晴朗气温25°C, city); } /** * 计算表达式 */ Tool(name calculate, description 计算数学表达式的结果) public double calculate( ToolParam(description 数学表达式如23*4) String expression) { // 简化实现生产环境应使用更安全的计算方式 return switch (expression) { case 23*4 - 14; case 100/5 - 20; default - 0; }; } }7.2 使用工具函数的 ChatClientimport com.example.demo.tools.WeatherTools; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.ToolCallbacks; import org.springframework.stereotype.Service; Service public class ToolChatService { private final ChatClient chatClient; public ToolChatService(ChatClient.Builder chatClientBuilder, WeatherTools weatherTools) { // 将工具函数注册到 ChatClient this.chatClient chatClientBuilder .defaultTools(ToolCallbacks.from(weatherTools)) .build(); } /** * 支持工具调用的对话 */ public String chatWithTools(String message) { return chatClient.prompt() .user(message) .call() .content(); } }7.3 测试工具调用SpringBootTest class ToolChatServiceTest { Autowired private ToolChatService toolChatService; Test void testWeatherQuery() { String response toolChatService.chatWithTools( 北京今天天气怎么样 ); System.out.println(response); // 输出北京今天天气晴朗气温25°C } Test void testCalculation() { String response toolChatService.chatWithTools( 帮我计算 23*4 等于多少 ); System.out.println(response); // 输出23*4 等于 14 } }8. 智能体 AgentAgent 是具备自主决策能力的智能体能够自动规划任务并使用工具。8.1 使用 ReactAgent 构建智能体import com.alibaba.cloud.ai.graph.agent.ReactAgent; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.tool.ToolCallback; import org.springframework.stereotype.Component; import java.util.List; Component public class ResearchAgent { private final ReactAgent agent; public ResearchAgent(ChatClient.Builder chatClientBuilder, ListToolCallback tools) { this.agent ReactAgent.builder() .name(research-agent) .description(一个研究型助手能够搜索信息并总结报告) .instruction( 你是一个专业的研究助手。当用户提出问题时 你需要 1. 分析问题需要哪些信息 2. 使用可用工具收集信息 3. 整理并总结答案 4. 如有必要请求用户澄清 ) .chatClient(chatClientBuilder.build()) .tools(tools) .build(); } /** * 执行研究任务 */ public String research(String topic) { return agent.call(topic).getText(); } }8.2 高级 Agent 配置基于 Nacosimport com.alibaba.cloud.ai.agent.nacos.NacosReactAgentBuilder; import com.alibaba.cloud.ai.graph.agent.ReactAgent; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class AgentConfiguration { Value(${spring.cloud.nacos.config.server-addr}) private String nacosServerAddr; /** * 从 Nacos 配置中心加载 Agent 配置 */ Bean public ReactAgent nacosAgent() { return new NacosReactAgentBuilder() .nacosOptions(options - options .serverAddr(nacosServerAddr) .agentName(my-intelligent-agent) .namespace(ai-agent) ) .build(); } }8.3 Nacos 配置格式在 Nacos 中创建以下配置文件agent-base.json:{ name: my-intelligent-agent, description: 智能客服助手, promptKey: customer-service-prompt, modelKey: qwen-max-config }customer-service-prompt.json:{ template: 你是专业的客服助手。请用友好、专业的语气回答用户问题。, variables: [user_name, product_name] }9. 故障排查9.1 常见问题与解决方案问题可能原因解决方案401 UnauthorizedAPI Key 无效或过期检查 API Key 配置确认未过期429 Too Many Requests超出请求频率限制降低请求频率或升级服务套餐Connection timeout网络问题或配置不当增加connect-timeout和read-timeoutNullPointerException模型未正确初始化检查依赖注入和配置类返回内容为空提示词问题或参数设置检查 prompt 和 temperature 设置9.2 调试日志配置在application.yml中开启调试日志logging: level: # 查看 HTTP 请求详情 org.springframework.web: DEBUG # 查看 AI 调用日志 org.springframework.ai: DEBUG # 查看 DashScope 调用日志 com.alibaba.cloud.ai: DEBUG9.3 健康检查接口import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; RestController public class HealthController { private final ChatClient chatClient; public HealthController(ChatClient.Builder chatClientBuilder) { this.chatClient chatClientBuilder.build(); } GetMapping(/health/ai) public String checkAI() { try { String response chatClient.prompt() .user(你好) .call() .content(); return AI 服务正常: response.substring(0, Math.min(20, response.length())); } catch (Exception e) { return AI 服务异常: e.getMessage(); } } }10. 最佳实践10.1 配置管理建议多环境配置# application-dev.yml开发环境 spring: ai: alibaba: dashscope: api-key: ${DEV_API_KEY} chat: options: model: qwen-turbo # 开发用轻量级模型 # application-prod.yml生产环境 spring: ai: alibaba: dashscope: api-key: ${PROD_API_KEY} chat: options: model: qwen-max # 生产用最强模型连接池优化spring: ai: alibaba: dashscope: client: max-connections: 200 max-connections-per-route: 50 connect-timeout: 10 read-timeout: 3010.2 性能优化建议流式输出对于长文本生成使用stream()而非call()批量向量化使用embedBatch()而非循环调用embed()向量缓存对于频繁查询的向量考虑使用 Redis 缓存异步处理使用Async注解处理非阻塞 AI 调用10.3 安全建议API Key 管理使用环境变量或配置中心存储定期轮换 API Key生产环境启用 IP 白名单输入过滤Service public class SafeChatService { private final ChatClient chatClient; private final ListString blockedWords List.of(敏感词1, 敏感词2); public String safeChat(String input) { // 输入过滤 if (containsBlockedWords(input)) { return 输入包含不适当内容; } return chatClient.prompt() .user(input) .call() .content(); } private boolean containsBlockedWords(String input) { return blockedWords.stream().anyMatch(input::contains); } }