【SpringAIAlibaba新手村系列】(5)Prompt 提示词基础与多种消息类型

简介: 本章详解Spring AI 1.1.2中Prompt核心机制:以System/User/Assistant/Tool四类消息构建结构化提示,强调“角色决定语义”;涵盖多模型配置、链式API与底层Message组装两种实践方式,并给出系统消息设计最佳实践。

第五章 Prompt 提示词基础与多种消息类型

版本标注

  • Spring AI: 1.1.2
  • Spring AI Alibaba: 1.1.2.0

章节定位

  • Prompt 仍然是基础,但在 1.1.2.x 中,Prompt 往往会与 Tool Calling、MCP、RAG、结构化输出、Agent System Prompt、Routing Prompt 一起协同工作。

s01 > s02 > s03 > s04 > [ s05 ] s06 > s07 > s08 > s09 > s10 > s11 > s12 > s13 > s14 > s15 > s16 > s17 > s18

"同一句话, 放在不同消息角色里, 效果可能完全不同" -- Prompt 的本质不是提问, 而是精确表达任务。


一、Prompt 的核心概念

1.1 什么是 Prompt?

Prompt(提示词) 是我们与 AI 沟通的唯一方式,你可以把它理解成:

"给 AI 写的 prompt 就是给 AI 下达的指令或提出的问题"

就像和人沟通一样,你说的越清楚,对方理解得越准确。Prompt 写得好不好,直接决定了 AI 输出的质量。

1.2 Prompt 的组成要素

一个完整的 Prompt 通常由两部分组成:

┌────────────────────────────────────────────────────┐
│                    Prompt 的组成                    │
├────────────────────────────────────────────────────┤
│                                                    │
│  【系统消息 System Message】                        │
│  ─────────────────────────                         │
│  你是一个法律助手,只回答法律相关问题               │
│  其他问题回复"抱歉,我只能回答法律问题"             │
│                                                    │
│  【用户消息 User Message】                          │
│  ──────────────────                                │
│  什么是知识产权法?                                │
│                                                    │
└────────────────────────────────────────────────────┘

1.3 Spring AI 中的消息类型

在 Spring AI 中,消息被抽象为几个类:

消息类型 说明 典型用途
SystemMessage 系统提示词,设定 AI 角色和行为 "你是一个Java专家"
UserMessage 用户消息,实际的问题 "什么是反射?"
AssistantMessage AI 的回复消息 记录对话历史
ToolResponseMessage 工具调用返回的结果 天气查询结果

二、多种模型支持

2.1 多模型配置

本章的项目展示了如何在同一个应用中支持多个不同的 AI 模型:

// 项目中配置了两种模型
@Resource(name = "deepseek")       // DeepSeek 开源模型
private ChatModel deepseekChatModel;

@Resource(name = "qwen")           // 阿里云通义千问
private ChatModel qwenChatModel;

// 对应的两个 ChatClient
@Resource(name = "deepseekChatClient")
private ChatClient deepseekChatClient;

@Resource(name = "qwenChatClient")
private ChatClient qwenChatClient;

2.2 模型选择策略

不同模型有不同的特点:

模型 特点 适用场景
DeepSeek 开源免费,中文能力强 成本敏感场景
Qwen (通义千问) 阿里云服务稳定,中文优化好 生产环境首选

三、项目代码详解

3.1 控制器代码

package com.atguigu.study.controller;

import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.ToolResponseMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;

/**
 * Prompt 提示词控制器
 * 展示各种 Prompt 的使用方式
 */
@RestController
public class PromptController
{
   
    // 注入 DeepSeek 模型和 ChatClient
    @Resource(name = "deepseek")
    private ChatModel deepseekChatModel;

    @Resource(name = "qwen")
    private ChatModel qwenChatModel;

    @Resource(name = "deepseekChatClient")
    private ChatClient deepseekChatClient;

    @Resource(name = "qwenChatClient")
    private ChatClient qwenChatClient;

    /**
     * 方式一:使用 ChatClient 的简洁 API(推荐)
     * 
     * .system() 方法设置系统提示词
     * .user() 方法设置用户消息
     * .stream() 开启流式输出
     *
     * 接口:http://localhost:8005/prompt/chat?question=火锅介绍下
     */
    @GetMapping("/prompt/chat")
    public Flux<String> chat(String question)
    {
   
        return deepseekChatClient.prompt()
            // system() 设置系统消息:AI的角色设定
            .system("你是一个法律助手,只回答法律问题,"
                   + "其它问题回复,我只能回答法律相关问题,其它无可奉告")
            // user() 设置用户消息
            .user(question)
            // stream() 流式输出
            .stream()
            .content();
    }

    /**
     * 方式二:使用底层 Message 对象(更底层灵活)
     * 
     * 创建 SystemMessage 和 UserMessage 对象
     * 组合成 Prompt 进行调用
     * 
     * 接口:http://localhost:8005/prompt/chat2?question=葫芦娃
     */
    @GetMapping("/prompt/chat2")
    public Flux<ChatResponse> chat2(String question)
    {
   
        // 1. 系统消息:设定AI为"讲故事助手"
        SystemMessage systemMessage = new SystemMessage(
            "你是一个讲故事的助手,每个故事控制在300字以内"
        );

        // 2. 用户消息:用户的问题
        UserMessage userMessage = new UserMessage(question);

        // 3. 组合成 Prompt
        //    Prompt 是 Message 的容器,可以包含多个消息
        Prompt prompt = new Prompt(userMessage, systemMessage);

        // 4. 调用并返回流式响应
        return deepseekChatModel.stream(prompt);
    }

    /**
     * 方式三:提取响应中的文本
     * 
     * 获取 ChatResponse 对象后,需要手动提取内容
     * 
     * 接口:http://localhost:8005/prompt/chat3?question=葫芦娃
     */
    @GetMapping("/prompt/chat3")
    public Flux<String> chat3(String question)
    {
   
        SystemMessage systemMessage = new SystemMessage(
            "你是一个讲故事的助手,每个故事控制在600字以内且以HTML格式返回"
        );

        UserMessage userMessage = new UserMessage(question);
        Prompt prompt = new Prompt(userMessage, systemMessage);

        // 使用 map 转换响应,提取文本内容
        // getResults().get(0) 获取第一个结果块
        // getOutput().getText() 获取生成的文本
        return deepseekChatModel.stream(prompt)
            .map(response -> response.getResults().get(0).getOutput().getText());
    }

    /**
     * 方式四:获取 AssistantMessage 对象
     * 
     * 如果需要获取 AI 回复的完整对象(包含元数据)
     * 可以获取 AssistantMessage
     * 
     * 接口:http://localhost:8005/prompt/chat4?question=葫芦娃
     */
    @GetMapping("/prompt/chat4")
    public String chat4(String question)
    {
   
        // 通过 ChatClient 获取完整响应
        AssistantMessage assistantMessage = deepseekChatClient.prompt()
                .user(question)
                .call()
                .chatResponse()            // 获取 ChatResponse 对象
                .getResult()               // 获取结果
                .getOutput();              // 获取输出消息

        // 通过 getText() 获取文本内容
        return assistantMessage.getText();
    }

    /**
     * 方式五:模拟工具调用场景(ToolResponseMessage)
     * 
     * 这个示例展示了 ToolResponseMessage 的使用场景
     * 实际使用会在 ToolCalling 章节详细讲解
     * 
     * 接口:http://localhost:8005/prompt/chat5?city=北京
     */
    @GetMapping("/prompt/chat5")
    public String chat5(String city)
    {
   
        // 1. 用户问题:询问城市天气
        String answer = deepseekChatClient.prompt()
                .user(city + "未来3天天气情况如何?")
                .call()
                .chatResponse()
                .getResult()
                .getOutput()
                .getText();

        // 2. 模拟工具返回结果(实际是外部工具调用的返回值)
        ToolResponseMessage toolResponseMessage = new ToolResponseMessage(
                List.of(
                    // ToolResponse 参数:toolCallId, toolName, content
                    new ToolResponseMessage.ToolResponse("1", "获得天气", city)
                )
        );

        // 3. 组合结果
        //    在实际应用中,会把工具返回的信息再发送给 AI,让它结合信息回答
        String toolResponse = toolResponseMessage.getText();
        String result = answer + toolResponse;

        return result;
    }
}

四、系统消息的最佳实践

4.1 系统消息的作用

系统消息(SystemMessage)就像是给 AI 设置的"人格"和"工作规则":

// ❌ 模糊的系统消息(AI 可能自由发挥)
.system("你是一个助手")

// ✅ 明确的系统消息(AI 知道该怎么做)
.system("""
    你是一个专业的Java技术博主。
    1. 回答问题时优先使用代码示例
    2. 解释概念时要用通俗易懂的语言
    3. 每次回答控制在500字以内
    4. 使用Markdown格式输出代码块
    """)

4.2 优秀的系统消息包含要素

要素 说明 示例
角色设定 AI 是什么身份 "你是一个法律顾问"
能力边界 能回答什么,不能回答什么 "只回答法律相关问题"
输出格式 要求如何返回结果 "用HTML格式返回"
字数控制 要求输出多长 "控制在300字以内"
风格要求 语气、措辞要求 "用通俗易懂的语言"

五、本章小结

5.1 核心概念回顾

概念 说明
Prompt 提示词,发送给 AI 的完整指令
SystemMessage 系统消息,设定 AI 的角色和行为
UserMessage 用户消息,用户实际提出的问题
AssistantMessage AI 回复的消息对象
ToolResponseMessage 工具调用返回的结果消息

5.2 使用建议

  1. 简单场景:使用 ChatClient.prompt().system().user().call() 链式 API
  2. 需要精细控制:创建 SystemMessage + UserMessage 组装 Prompt
  3. 多模型切换:通过 @Qualifier 区分不同的 ChatModel

本章重点

  1. 理解 Prompt 的组成:系统消息 + 用户消息
  2. 掌握多种创建和使用 Prompt 的方式
  3. 学会在系统中切换使用不同模型

下章剧透(s06):

了解了 Prompt 的基本使用后,下一章我们将学习 PromptTemplate(提示词模板)——如何用占位符实现可复用的提示词。


📝 编辑者:Flittly
📅 更新时间:2026年3月
🔗 相关资源Spring AI Prompt 官方文档

目录
相关文章
|
24天前
|
人工智能 前端开发 Java
【SpringAIAlibaba新手村系列】(4)流式输出与响应式编程
本文围绕 Spring AI 中的流式输出与响应式编程展开,重点解释了传统一次性响应与流式返回的差异,以及 Flux 在异步数据流中的核心作用。文章结合 ChatModel.stream() 与 ChatClient 的多种代码示例,说明如何实现 AI 内容的边生成边返回,并帮助读者理解流式调用在用户体验、性能和长文本场景中的实际价值。
495 4
【SpringAIAlibaba新手村系列】(4)流式输出与响应式编程
|
存储 人工智能 Java
【SpringAIAlibaba新手村系列】(3)ChatModel 与 ChatClient 的深度对比
本章深度解析 Spring AI 中 `ChatModel`(底层接口)与 `ChatClient`(高级封装)的本质区别:前者如“手动挡”,精准控制但需写大量样板代码;后者似“智能点餐机”,链式调用、支持系统提示、模板、工具调用等,开发高效。初学者推荐优先使用 `ChatClient`。
351 0
【SpringAIAlibaba新手村系列】(3)ChatModel 与 ChatClient 的深度对比
|
22天前
|
人工智能 JSON Java
【SpringAIAlibaba新手村系列】(7)结构化输出与对象映射
本文详解 Spring AI 结构化输出功能,通过 Java Record 与 .entity() 方法,实现 AI 的 JSON 响应自动映射为 Java 对象,解决纯文本难以集成的问题。文中还对比了 Lambda 写法并提供 Prompt 设计最佳实践。
199 3
|
21天前
|
人工智能 自然语言处理 前端开发
【SpringAIAlibaba新手村系列】(9)Text to Image 文本生成图像技术
本文介绍 Spring AI 中的文生图能力,围绕 ImageModel、ImagePrompt 与阿里云百炼图像模型展开,演示如何根据文字描述生成图片链接,并结合 Prompt 编写技巧与参数配置,帮助开发者提升生成效果与落地能力。
251 8
|
人工智能 JavaScript Java
【SpringAIAlibaba新手村系列】(1)初识 Spring AI Alibaba 框架
本文介绍了SpringAIAlibaba框架的基本概念和使用方法。作为Spring官方AI框架的阿里云实现版本,它简化了Java开发者调用AI模型的过程。文章详细讲解了核心概念如ChatModel、ChatClient,以及阿里云百炼平台的功能。通过HelloWorld项目示例,展示了如何配置APIKey、编写控制层代码,实现普通调用和流式输出两种AI交互方式。重点阐述了SpringAI与SpringAIAlibaba的关系,以及自动配置机制的工作原理,帮助开发者快速上手这一框架。
1809 4
|
20天前
|
NoSQL Java 数据库
【SpringAIAlibaba新手村系列】(11)Embedding 向量化与向量数据库
本文围绕 Embedding 与向量数据库展开,讲解了文本向量化、相似度检索和 VectorStore 的基本用法,并结合 SimpleVectorStore 示例说明了 Spring 中自动装配与手动注册 Bean 的区别,为后续学习 RAG 打下基础。
305 4
【SpringAIAlibaba新手村系列】(11)Embedding 向量化与向量数据库
|
9天前
|
人工智能 JSON Java
【SpringAIAlibaba新手村系列】(6)PromptTemplate 提示词模板与变量替换
本章详解Spring AI的PromptTemplate提示词模板机制,涵盖变量替换、系统消息模板(SystemPromptTemplate)、外部文件加载等核心功能,助力实现提示词参数化、复用与动态组装,提升RAG、Agent及结构化输出场景下的开发效率与可维护性。
133 6
|
9天前
|
人工智能 Java API
【SpringAIAlibaba新手村系列】(2)Ollama 本地大模型调用
本章详解如何用Spring AI接入Ollama本地大模型:解决远程调用的联网依赖、隐私泄露与费用问题;支持Qwen、Llama等开源模型,零成本、低延迟、全离线运行;重点掌握`@Qualifier`多模型注入、流式响应(Flux)及本地API(`http://localhost:11434`)集成。
346 5
|
24天前
|
存储 人工智能 Java
吃透 Spring AI Alibaba 多智能体|四大协同模式+完整代码
本文详细讲解 Spring AI Alibaba Multi-Agent 多智能体架构,包含顺序执行、并行执行、LLM 路由、监督者四大协同模式,搭配可运行代码示例与真实业务场景,从零带你上手多智能体开发。
845 3
|
21天前
|
人工智能 JavaScript Java
【SpringAIAlibaba新手村系列】(10)Text to Voice 文本转语音技术
本文围绕 Spring AI Alibaba 1.1.2.2 的文本转语音实现展开,记录了基于 DashScopeAudioSpeechModel 与 stream() 的可运行方案。文章重点说明了模型、音色、输出格式与流式拼接音频文件的关键细节。
227 6

热门文章

最新文章