模型选择本地模型ollama安装https://ollama.com/download下载好安装模型 量力而安装 我安装的是 https://ollama.com/library/qwen2.5:1.5bollama run qwen2.5:1.5b测试在线模型可选择去阿里百炼获取https://bailian.console.aliyun.com/cn-beijing/?tabmodel#/model-market调用模型依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId version3.5.8/version /dependency !-- Spring AI Alibaba Agent Framework -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-agent-framework/artifactId version1.1.2.0/version /dependency !-- DashScope ChatModel 支持如果使用其他模型请跳转 Spring AI 文档选择对应的 starter -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId version1.1.2.0/version /dependency配置server: port: 8080 spring: ai: dashscope: api-key: ${apiKey}编写controllerpackage com.cyz.controller; import org.springframework.ai.chat.model.ChatModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; RestController public class ChatController { Autowired private ChatModel chatModel; GetMapping(/chat) public String chat(RequestParam(input) String input) { return chatModel.call(input); } GetMapping(/stream) public FluxString stream(RequestParam(input) String input) { return chatModel.stream(input); } }测试阻塞式流式源码分析查找自动配置类我们使用的是对话模型所以看 DashScopeChatAutoConfiguration 就行了这边spring会为我们创建一个对话模型查看DashScopeChatModel对话模型使用的是哪个模型查看配置类是qwen-plus查看所有模型名称 DashScopeModel如何自定义模型改成 deepseek-r1server: port: 8080 spring: ai: dashscope: api-key: ${apiKey} chat: options: model: deepseek-r1为什么不需要配置baseUrl由此可知不配就取默认的类的继承关系以对话模型为例其他类型模型是类似的都继承model类每种模型都有对应的DashScopeXXXModel如下模型名称作用DashScopeChatModel对话模型EmbeddingModel向量模型DashScopeImageModel图片模型DashScopeVideoModel视频模型DashScopeAudioSpeechModel文本to语音Messages 消息Messages 是 Spring AI Alibaba 中模型交互的基本单元。它们代表模型的输入和输出携带在与 LLM 交互时表示对话状态所需的内容和元数据。Messages 是包含以下内容的对象Role角色- 标识消息类型如system、user、assistantContent内容- 表示消息的实际内容如文本、图像、音频、文档等Metadata元数据- 可选字段如响应信息、消息 ID 和 token 使用情况Spring AI Alibaba 提供了一个标准的消息类型系统可在所有模型提供商之间工作确保无论调用哪个模型都具有一致的行为。基础使用文本类型GetMapping(/chat) public String chat(RequestParam(input) String input) { return chatModel.call(input); }系统角色用户角色GetMapping(/chat) public String chat(RequestParam(input) String input) { SystemMessage systemMsg new SystemMessage(你是编程助手,名字叫小编); UserMessage userMsg new UserMessage(input); Prompt promptnew Prompt(List.of(systemMsg,userMsg)); return chatModel.call(prompt).getResult().getOutput().getText(); }系统角色用户角色辅助角色GetMapping(/chat) public String chat(RequestParam(input) String input) { SystemMessage systemMsg new SystemMessage(你是编程助手,名字叫小编); UserMessage userMsg new UserMessage(input); AssistantMessage assistantMessage new AssistantMessage(你是个java程序员); Prompt promptnew Prompt(List.of(systemMsg,userMsg,assistantMessage)); return chatModel.call(prompt).getResult().getOutput().getText(); }会用java语言回答消息类型System Message系统消息- 告诉模型如何行为并为交互提供上下文User Message用户消息- 表示用户输入和与模型的交互Assistant Message助手消息- 模型生成的响应包括文本内容、工具调用和元数据Tool Response Message工具响应消息- 表示工具调用的输出System MessageSystemMessage表示一组初始指令用于引导模型的行为。你可以使用系统消息来设置语气、定义模型的角色并建立响应指南。SystemMessage 基础指令示例// 基础指令 SystemMessage systemMsg new SystemMessage(你是一个有帮助的编程助手。); Listorg.springframework.ai.chat.messages.Message messages List.of( systemMsg, new UserMessage(如何创建 REST API) ); ChatResponse response chatModel.call(new Prompt(messages));SystemMessage 详细角色设定示例// 详细的角色设定 SystemMessage systemMsg new SystemMessage( 你是一位资深的 Java 开发者擅长 Web 框架。 始终提供代码示例并解释你的推理。 在解释中要简洁但透彻。 ); Listorg.springframework.ai.chat.messages.Message messages List.of( systemMsg, new UserMessage(如何创建 REST API) ); ChatResponse response chatModel.call(new Prompt(messages));User MessageUserMessage表示用户输入和交互。它们可以包含文本、图像、音频、文件和任何其他数量的多模态内容。文本内容// 使用消息对象 ChatResponse response chatModel.call( new Prompt(List.of(new UserMessage(什么是机器学习))) ); // 使用字符串快捷方式 // 使用字符串是单个 UserMessage 的快捷方式 String response chatModel.call(什么是机器学习);消息元数据import java.util.Map; UserMessage userMsg UserMessage.builder() .text(你好) .metadata(Map.of( user_id, alice, // 可选识别不同用户 session_id, sess_123 // 可选会话标识符 )) .build();注意元数据字段的行为因提供商而异 - 有些用于用户识别有些则忽略它。要检查请参考模型提供商的文档。多模态内容UserMessage可以包含多模态内容如图像import org.springframework.ai.content.Media; import org.springframework.util.MimeTypeUtils; import java.net.URL; // 从 URL 创建图像 UserMessage userMsg UserMessage.builder() .text(描述这张图片的内容。) .media(Media.builder() .mimeType(MimeTypeUtils.IMAGE_JPEG) .data(new URL(https://example.com/image.jpg)) .build()) .build();Assistant MessageAssistantMessage表示模型调用的输出。它们可以包括多模态数据、工具调用以及你稍后可以访问的提供商特定元数据。AssistantMessage 基础使用示例ChatResponse response chatModel.call(new Prompt(解释 AI)); AssistantMessage aiMessage response.getResult().getOutput(); System.out.println(aiMessage.getText());AssistantMessage对象由模型调用返回其中包含响应中的所有相关元数据。提供商对消息类型的权重/上下文化方式不同这意味着有时手动创建新的AssistantMessage对象并将其插入消息历史中就像它来自模型一样会很有帮助。手动创建 AssistantMessage 示例import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.UserMessage; // 手动创建 AI 消息例如用于对话历史 AssistantMessage aiMsg new AssistantMessage(我很乐意帮助你回答这个问题); // 添加到对话历史 Listorg.springframework.ai.chat.messages.Message messages List.of( new SystemMessage(你是一个有帮助的助手), new UserMessage(你能帮我吗), aiMsg, // 插入就像它来自模型一样 new UserMessage(太好了22 等于多少) ); ChatResponse response chatModel.call(new Prompt(messages));AssistantMessage 属性text: 消息的文本内容metadata: 消息的元数据映射toolCalls: 模型进行的工具调用列表media: 媒体内容列表如果有工具调用当模型进行工具调用时它们包含在AssistantMessage中import org.springframework.ai.chat.messages.AssistantMessage.ToolCall; ChatResponse response chatModel.call(prompt); AssistantMessage aiMessage response.getResult().getOutput(); if (aiMessage.hasToolCalls()) { for (ToolCall toolCall : aiMessage.getToolCalls()) { System.out.println(Tool: toolCall.name()); System.out.println(Args: toolCall.arguments()); System.out.println(ID: toolCall.id()); } }Token 使用Spring AI Alibaba 的ChatResponse可以在其元数据中保存 token 计数和其他使用元数据ChatResponse response chatModel.call(new Prompt(你好)); ChatResponseMetadata metadata response.getMetadata(); // 访问使用信息 if (metadata ! null metadata.getUsage() ! null) { System.out.println(Input tokens: metadata.getUsage().getPromptTokens()); System.out.println(Output tokens: metadata.getUsage().getCompletionTokens()); System.out.println(Total tokens: metadata.getUsage().getTotalTokens()); }流式和块在流式传输期间你将收到可以组合成完整消息对象的块import reactor.core.publisher.Flux; FluxChatResponse responseStream chatModel.stream(new Prompt(你好)); StringBuilder fullResponse new StringBuilder(); responseStream.subscribe( chunk - { String content chunk.getResult().getOutput().getText(); fullResponse.append(content); System.out.print(content); } );Tool Response Message对于支持工具调用的模型AI 消息可以包含工具调用。工具消息用于将单个工具执行的结果传回模型。import org.springframework.ai.chat.messages.ToolResponseMessage; import org.springframework.ai.chat.messages.ToolResponseMessage.ToolResponse; // 在模型进行工具调用后 AssistantMessage aiMessage AssistantMessage.builder() .content() .toolCalls(List.of( new AssistantMessage.ToolCall( call_123, tool, get_weather, {location: San Francisco} ) )) .build(); // 执行工具并创建结果消息 String weatherResult 晴朗22°C; ToolResponseMessage toolMessage ToolResponseMessage.builder() .responses(List.of( new ToolResponse(call_123, get_weather, weatherResult) )) .build(); // 继续对话 Listorg.springframework.ai.chat.messages.Message messages List.of( new UserMessage(旧金山的天气怎么样), aiMessage, // 模型的工具调用 toolMessage // 工具执行结果 ); ChatResponse response chatModel.call(new Prompt(messages));ToolResponseMessage 属性responses: ToolResponse 对象列表每个包含id: 工具调用 ID必须与 AIMessage 中的工具调用 ID 匹配name: 调用的工具名称responseData: 工具调用的字符串化输出多模态内容多模态性指的是处理不同形式数据的能力如文本、音频、图像和视频。Spring AI Alibaba 包含这些数据的标准类型可以跨提供商使用。聊天模型可以接受多模态数据作为输入并生成它作为输出。下面我们展示包含多模态数据的输入消息的简短示例。图像输入import org.springframework.ai.content.Media; import org.springframework.util.MimeTypeUtils; import java.net.URL; // 从 URL UserMessage message UserMessage.builder() .text(描述这张图片的内容。) .media(Media.builder() .mimeType(MimeTypeUtils.IMAGE_JPEG) .data(new URL(https://example.com/image.jpg)) .build()) .build(); // 从本地文件 import org.springframework.core.io.ClassPathResource; UserMessage message UserMessage.builder() .text(描述这张图片的内容。) .media(new Media( MimeTypeUtils.IMAGE_JPEG, new ClassPathResource(images/photo.jpg) )) .build();音频输入import org.springframework.ai.content.Media; import org.springframework.util.MimeTypeUtils; UserMessage message UserMessage.builder() .text(描述这段音频的内容。) .media(new Media( MimeTypeUtils.parseMimeType(audio/wav), new ClassPathResource(audio/recording.wav) )) .build();视频输入import org.springframework.ai.content.Media; import org.springframework.util.MimeTypeUtils; UserMessage message UserMessage.builder() .text(描述这段视频的内容。) .media(Media.builder() .mimeType(MimeTypeUtils.parseMimeType(video/mp4)) .data(new URL(https://example.com/path/to/video.mp4)) .build()) .build();与 Chat Models 一起使用Chat models 接受消息对象序列作为输入并返回ChatResponse包含AssistantMessage作为输出。交互通常是无状态的因此简单的对话循环涉及使用不断增长的消息列表调用模型。基础对话示例import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.prompt.Prompt; import java.util.ArrayList; import java.util.List; ChatModel chatModel // ... 初始化 ListMessage conversationHistory new ArrayList(); // 第一轮对话 conversationHistory.add(new UserMessage(你好)); ChatResponse response1 chatModel.call(new Prompt(conversationHistory)); conversationHistory.add(response1.getResult().getOutput()); // 第二轮对话 conversationHistory.add(new UserMessage(你能帮我学习 Java 吗)); ChatResponse response2 chatModel.call(new Prompt(conversationHistory)); conversationHistory.add(response2.getResult().getOutput()); // 第三轮对话 conversationHistory.add(new UserMessage(从哪里开始)); ChatResponse response3 chatModel.call(new Prompt(conversationHistory));使用 Builder 模式Spring AI Alibaba 的消息类提供了 builder 模式以便于构建// UserMessage with builder UserMessage userMsg UserMessage.builder() .text(你好我想学习 Spring AI Alibaba) .metadata(Map.of(user_id, user_123)) .build(); // SystemMessage with builder SystemMessage systemMsg SystemMessage.builder() .text(你是一个 Spring 框架专家) .metadata(Map.of(version, 1.0)) .build(); // AssistantMessage with builder AssistantMessage assistantMsg AssistantMessage.builder() .content(我很乐意帮助你学习 Spring AI Alibaba) .build();消息复制和修改// 复制消息 UserMessage original new UserMessage(原始消息); UserMessage copy original.copy(); // 使用 mutate 创建修改的副本 UserMessage modified original.mutate() .text(修改后的消息) .metadata(Map.of(modified, true)) .build();在 ReactAgent 中使用ReactAgent 自动管理消息历史但你也可以直接使用消息import com.alibaba.cloud.ai.graph.agent.ReactAgent; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.messages.AssistantMessage; ReactAgent agent ReactAgent.builder() .name(my_agent) .model(chatModel) .systemPrompt(你是一个有帮助的助手) .build(); // 使用字符串 AssistantMessage response1 agent.call(你好); // 使用 UserMessage UserMessage userMsg new UserMessage(帮我写一首诗); AssistantMessage response2 agent.call(userMsg); // 使用消息列表 ListMessage messages List.of( new UserMessage(我喜欢春天), new UserMessage(写一首关于春天的诗) ); AssistantMessage response3 agent.call(messages);Tools待更新