
摘要Spring AI 通过消息Message抽象统一了与大模型的对话载体将系统指令、用户输入、助手回复和工具调用结果分别封装为四个独立的消息类。本文深入解析SystemMessage、UserMessage、AssistantMessage和ToolResponseMessage的底层设计、作用边界与配合方式并结合 Spring AI Alibaba DashScope 给出从环境配置到多轮对话、Function Calling 完整闭环的代码实践助你彻底吃透 Spring AI 的提示词工程核心。1. 四大角色整体设计Spring AI 将与模型的一次完整交互抽象为Message接口并针对对话中不同来源和用途的内容设计了四个具体的实现类。每条消息都携带一个专属的Role标识大模型通过这一角色区分语义边界从而彻底告别混乱的字符串拼接。角色类枚举类型核心作用使用位置与特性SystemMessageSYSTEM全局系统指令定义 AI 身份、输出规范、行为约束消息列表首位全局永久生效不被用户覆盖UserMessageUSER用户原始提问、业务输入、多模态内容对话输入源动态可变业务数据存放处AssistantMessageASSISTANT大模型历史回答、工具调用请求载体多轮上下文核心可携带ToolCall指令ToolResponseMessageTOOL外部工具执行结果Function Calling 闭环必备补齐数据后回传这四个角色的有序组合构成了 Prompt提示词最终交给模型推理。下面逐一拆解每个角色的设计意图和正确使用方式。2. 角色详解与使用规范2.1 SystemMessage —— 全局指挥官SystemMessage是对话中最高优先级的指令用于固定 AI 的人设、输出格式、领域约束和安全边界。在一轮完整对话的消息列表中通常只在最前面放置一条。⚠️ 使用禁忌不要把动态变化的业务数据如用户 ID、订单详情放入SystemMessage因为每次变更都会导致提示词整体发生变化白白消耗 token。系统消息应该保持稳定。SystemMessage systemMsg new SystemMessage(你是资深Java后端技术专家基于Spring AI Alibaba框架解答问题1. 回答必须附带可运行完整代码2. 代码使用Java17规范适配DashScope通义千问3. 不编造不存在的框架API解释简洁易懂。);2.2 UserMessage —— 人类输入载体所有来自用户侧的内容都通过UserMessage封装。它支持纯文本、图片多模态等输入是触发每一次对话的源头。在多轮对话中每一个新的用户提问都会创建一个新的UserMessage追加到消息列表末尾。// 普通文本提问UserMessage userMsg new UserMessage(讲解Spring AI Alibaba四大Prompt角色用法);// 多模态示例图片文本// UserMessage multiModalMsg new UserMessage(分析这张图片,// List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageResource)));2.3 AssistantMessage —— 模型双向载体AssistantMessage身兼两职普通对话存储模型上一轮的回复内容。在构建多轮对话 Prompt 时需要按顺序将历史AssistantMessage和后续UserMessage组合在一起完整还原对话上下文。Agent 工具调用当模型判断需要调用外部工具时它的回复会以AssistantMessage的形式返回但其中包含ListToolCall对象指明要调用的函数名和参数。多轮上下文拼接示例[SystemMessage, UserMessage1, AssistantMessage1, UserMessage2, AssistantMessage2, ...]// 普通回答AssistantMessage assistant new AssistantMessage(ChatModel是底层标准接口ChatClient是上层便捷封装。);// 工具调用框架自动生成// AssistantMessage 内含 toolCalls 字段2.4 ToolResponseMessage —— 外部数据桥梁仅在 Function Calling 场景出现。一条完整的工具调用链路为UserMessage → AssistantMessage(含 ToolCall) → 本地执行工具 → ToolResponseMessage → 二次请求模型ToolResponseMessage将工具执行的结果封装并将其与之前所有的消息系统、用户、助手工具调用合并再次发送给大模型由模型结合工具数据生成最终的自然语言回复。缺少该角色就无法实现联网查询、数据库检索等 Agent 能力。3. 项目环境配置3.1 Maven 依赖dependencygroupIdcom.alibaba.cloud.ai/groupIdartifactIdspring-ai-alibaba-starter-dashscope/artifactIdversion1.0.0-M6.1/version/dependency3.2 application.yml 通用配置spring:ai:dashscope:api-key: sk-你的灵积API密钥chat:options:model: qwen-turbotemperature: 0.73.3 两套接入方案Spring AI Alibaba 提供自动装配和手动配置两种方式推荐优先使用自动装配。方案一Starter 自动装配90% 场景首选只需引入 starter 并配置 ymlDashScopeAutoConfiguration会自动创建DashScopeApiAPI 客户端DashScopeChatModelChatModel接口实现业务代码直接注入ChatModel或ChatClient即可。无需任何配置类。方案二手动自定义配置类需要定制网络参数时当需要自定义连接超时、HTTP 代理或私有化地址时可以手动创建 Bean此时自动装配会失效并复用DashScopeProperties避免硬编码。Configurationpublic class DashScopeLLMConfig {Beanpublic DashScopeApi dashScopeApi(DashScopeProperties properties) {return DashScopeApi.builder().apiKey(properties.getApiKey()).connectTimeout(Duration.ofSeconds(30)).readTimeout(Duration.ofSeconds(60))// .baseUrl(私有化地址)// .proxy(自定义代理).build();}Beanpublic ChatModel chatModel(DashScopeApi api, DashScopeProperties properties) {return new DashScopeChatModel(api, properties.getChat().getOptions());}// 注册全局 ChatClient统一管理系统提示词Beanpublic ChatClient chatClient(ChatModel chatModel) {return ChatClient.builder(chatModel).defaultSystem(你是Spring AI Alibaba技术专家代码示例完整规范).defaultTemperature(0.7).build();}}4. 实战一基础多轮对话System User Assistant本案例演示如何手动组装三种角色消息并对比ChatModel底层 API 和ChatClient高层封装两种调用方式。RestControllerpublic class PromptRoleController {private final ChatModel chatModel;private final ChatClient chatClient;public PromptRoleController(ChatModel chatModel, ChatClient chatClient) {this.chatModel chatModel;this.chatClient chatClient;}// 方式一原生 ChatModel 手动构建多轮对话GetMapping(/chat/multi/sync)public String multiRoundSync() {SystemMessage systemMsg new SystemMessage(你是Java AI开发博主回答简短精炼);UserMessage user1 new UserMessage(什么是ChatModel与ChatClient区别);AssistantMessage assistant1 new AssistantMessage(ChatModel是底层标准接口ChatClient是上层便捷封装。);UserMessage user2 new UserMessage(开发中该优先使用哪一个);Prompt prompt new Prompt(List.of(systemMsg, user1, assistant1, user2));return chatModel.call(prompt).getResult().getOutput().getText();}// 方式二ChatClient 流式调用推荐GetMapping(/chat/client/stream)public FluxString clientStreamChat(RequestParam String query) {return chatClient.prompt().system(讲解代码附带完整示例).user(query).stream().content();}}ChatModel需要手动维护消息列表顺序适合底层精细控制。ChatClient内部自动管理上下文并支持链式 API更贴近业务开发。5. 实战二四大角色全闭环 Function Calling下面代码完整展示了 System、User、Assistant带 ToolCall和 ToolResponse 四个角色的协作过程实现“查询天气”的 Agent 功能。GetMapping(/chat/tool/allRole)public String toolCallAllRole() throws Exception {// 1. 系统消息约束必须使用工具SystemMessage systemMsg new SystemMessage(你拥有天气查询工具getCityWeather需要查询天气时必须调用该工具禁止编造数据。调用时传入参数city城市名称。);// 2. 用户消息UserMessage userMsg new UserMessage(查询北京今日气温);Prompt prompt new Prompt(List.of(systemMsg, userMsg));ChatResponse response chatModel.call(prompt);// 3. 获取助手消息可能包含工具调用AssistantMessage assistantMsg response.getResult().getOutput();if (!assistantMsg.getToolCalls().isEmpty()) {ToolCall toolCall assistantMsg.getToolCalls().get(0);// 解析参数JsonNode args new ObjectMapper().readTree(toolCall.arguments());String city args.get(city).asText();// 执行本地工具模拟String weatherData getCityWeather(city);// 4. 构造 ToolResponseMessageToolResponseMessage toolMsg new ToolResponseMessage(List.of(new ToolResponse(toolCall.id(), weatherData)));// 5. 拼接完整消息二次请求ListMessage fullMessages List.of(systemMsg, userMsg, assistantMsg, toolMsg);ChatResponse finalResp chatModel.call(new Prompt(fullMessages));return finalResp.getResult().getOutput().getText();}return assistantMsg.getText();}private String getCityWeather(String city) {return String.format(%s今日晴气温18~28℃微风, city);}关键步骤解析模型返回的AssistantMessage中getToolCalls()非空说明需要调用外部工具程序根据ToolCall中的函数名和参数执行本地逻辑并将结果封装为ToolResponseMessage第二次请求时消息列表必须为[System, User, Assistant(含ToolCall), ToolResponse]的顺序模型结合工具数据生成最终的自然语言回答。6. 总结与最佳实践职责分离SystemMessage定义稳态约束UserMessage承载动态输入AssistantMessage维护历史与工具指令ToolResponseMessage补全外部数据。各司其职避免混合。多轮上下文维护按顺序记录System → User → Assistant → User → Assistant ...切勿遗漏历史助手消息否则模型会丢失对话记忆。工具调用闭环当收到含有ToolCall的AssistantMessage时必须执行工具并附加ToolResponseMessage重新请求否则对话会中断或产生幻觉。优先使用 ChatClient日常开发推荐ChatClient的内置上下文管理、流式调用和默认系统提示词功能仅在需要极端控制消息列表时下沉到ChatModel。配置选择无特殊网络需求时用自动装配需要自定义超时、代理或私有化地址时手动创建 Bean同时复用DashScopeProperties保持配置统一。Spring AI 的四大角色设计不仅使得提示词构建更加模块化和类型安全也为后续的 Agent 编排、记忆管理打下了坚实的基础。理解并善用这些角色你将能够构建出更加稳定、智能的 AI 应用。