第五章 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 使用建议
- 简单场景 :使用
ChatClient.prompt().system().user().call()链式 API - 需要精细控制 :创建
SystemMessage+UserMessage组装Prompt - 多模型切换 :通过
@Qualifier区分不同的 ChatModel
本章重点:
- 理解 Prompt 的组成:系统消息 + 用户消息
- 掌握多种创建和使用 Prompt 的方式
- 学会在系统中切换使用不同模型
下章剧透(s06):
了解了 Prompt 的基本使用后,下一章我们将学习 PromptTemplate(提示词模板)------如何用占位符实现可复用的提示词。
📝 编辑者 :Flittly
📅 更新时间 :2026年3月
🔗 相关资源:【SpringAIAlibaba新手村系列】(5)Prompt 提示词基础与多种消息类型