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

第五章 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月

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

相关推荐
Yeh2020582 小时前
JDBC笔记
笔记
本旺2 小时前
[AIAgent-MCP]MCP Client 全景:Elicitation、Roots 与 Sampling 一次讲透
人工智能·ai·aiagent·mcp
LuoQuHen2 小时前
第一章:什么是AI Agent?—— 为什么它正在改变AI的未来
人工智能·ai·chatgpt·agent
zero15972 小时前
Python 8天极速入门笔记(大模型工程师专用):第四篇-判断与循环(Python流程控制,批量处理必备)
笔记·python·ai编程
Xudde.2 小时前
班级作业笔记报告0x03
笔记
猹叉叉(学习版)2 小时前
【系统分析师_知识点整理】 9.系统规划与分析
笔记·软考·系统分析师·系统规划
迷海2 小时前
docker命令大全
java·docker·eureka
杜子不疼.2 小时前
高并发场景下 Spring MVC + 虚拟线程 vs WebFlux 选型对比
java·人工智能·spring·mvc
gis分享者2 小时前
OpenClaw 的核心组件有哪些?请描述它们之间的关系
ai·面试·关系·核心组件·openclaw·小龙虾