跳到主要内容

5 Spring AI 提示词

1. 简介:什么是 Spring AI 提示词?

Spring AI 的 Prompt (提示词) 系统为与 AI 模型通信提供了一种结构化、类型安全的方式。Prompt 类充当了一个容器,组织了 Message (消息) 对象和可选的 ChatOptions (聊天选项),从而支持复杂的多次对话,并实现对模型行为的精确控制。

1.1 Prompt 类

public class Prompt implements ModelRequest<List<Message>> {

private final List<Message> messages;

private ChatOptions chatOptions;

public Prompt(List<Message> messages) {
this.messages = messages;
}

public Prompt(List<Message> messages, ChatOptions chatOptions) {
this.messages = messages;
this.chatOptions = chatOptions;
}

@Override
public List<Message> getInstructions() {
return messages;
}

@Override
public ChatOptions getOptions() {
return chatOptions;
}
}

Prompt 类是向 AI 模型发送请求的主要抽象。它封装了:

  • Messages:代表对话历史的消息对象序列。
  • ChatOptions:模型特定的参数(如温度 temperature、最大 token 数等)。

1.2 Message 接口

每一条 Message 在提示词中都体现了独特的角色,其内容和意图各不相同:

public interface Content {

String getContent();

Map<String, Object> getMetadata();
}

public interface Message extends Content {

MessageType getMessageType();
}

为了支持多模态(文本 + 图像、音频等),消息还可以实现:

public interface MediaContent extends Content {

Collection<Media> getMedia();
}

1.3 消息类型与角色

Spring AI 通过 MessageType 枚举定义了四种主要的消息角色:

public enum MessageType {
USER("user"), // 用户的输入 —— 问题、命令、陈述
ASSISTANT("assistant"), // AI 对用户输入的响应
SYSTEM("system"), // 指导 AI 行为和风格的指令
TOOL("tool"); // 来自工具/函数调用的附加信息
}

角色功能:

角色目的用法
SYSTEM指导 AI 的行为和响应风格在对话前设定参数、规则和上下文
USER代表用户的输入向 AI 提出的问题、命令或陈述
ASSISTANTAI 对用户输入的响应维持对话流和上下文
TOOL返回来自工具调用的信息提供函数执行产生的数据

1.4 为什么使用 Spring AI 提示词?

直接调用 LLM API:                      使用 Spring AI 提示词:
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ 手动字符串拼接 │ │ 类型安全的消息 API │
│ 易出错的 JSON 处理 │ │ 响应式的 ChatClient API │
│ 缺乏模板结构 │ │ 内置 PromptTemplate │
│ 手动跟踪对话历史 │ │ ChatMemory 深度集成 │
│ 不同供应商格式不一 │ │ 供应商无关的抽象层 │
└─────────────────────────────────┘ └─────────────────────────────────┘
代码脆弱、重复性高 → 代码整洁、易于维护

核心优势:

  1. 类型安全:在编译阶段检查消息类型和结构。
  2. 模板管理:内置对参数化提示词的支持。
  3. 供应商无关:无需更改代码即可在 OpenAI、Anthropic、Gemini 之间切换。
  4. 对话管理:轻松追踪多轮对话。
  5. 多模态支持:针对文本、图像、音频和视频的统一 API。

2. 提示词架构与设计哲学

2.1 设计原则

Spring AI 的提示词系统建立在三大核心原则之上:

2.1.1 流式 API 设计 (Fluent API)

// 链式方法调用,代码可读性高、声明式
String response = chatClient.prompt()
.system("你是一个得力的助手")
.user("什么是 Spring AI?")
.call()
.content();

2.1.2 类型安全

// 强类型在编译时捕捉错误
Message systemMessage = new SystemMessage("你是一位资深的 Java 开发专家");
Message userMessage = new UserMessage("请评审这段代码");

List<Message> messages = List.of(systemMessage, userMessage);
Prompt prompt = new Prompt(messages);

2.1.3 可扩展性

// 易于添加自定义消息类型、渲染器和顾问 (Advisors)
public class CustomMessage implements Message {
// 自定义实现
}

2.2 架构概览

┌─────────────────────────────────────────────────────────────────────┐
│ ChatClient (入口点) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ ChatClient.prompt() 流式 API │ │
│ │ .system() / .user() / .advisors() / .options() / .call() │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────┐
│ Prompt (提示词) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ List<Message> ChatOptions │ │
│ │ ┌────────┐ ┌────────┐ ┌─────────────────────────┐ │ │
│ │ │ SYSTEM │ │ USER │ ... │ model, temperature, │ │ │
│ │ │ │ │ │ │ maxTokens, 等 │ │ │
│ │ └────────┘ └────────┘ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────────┐
│ ChatModel 抽象层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ OpenAI │ │Anthropic │ │ Gemini │ │ Ollama │ ... │
│ │ ChatModel│ │ChatModel │ │ ChatModel│ │ ChatModel│ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────────┘

3. ChatClient.prompt() API —— 完整参考

ChatClient 提供了一套流式 API 用于构建提示词并调用 AI 模型。它同时支持同步和流式编程模型。

3.1 基础 ChatClient 设置

@Configuration
public class ChatClientConfig {

@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder.build();
}
}

3.2 发起提示词的三种方式

@Service
@RequiredArgsConstructor
public class PromptService {

private final ChatClient chatClient;

// 方式 1:流式 API (最常用)
public String promptWithFluentApi(String userInput) {
return chatClient.prompt() // 开始流式 API
.user(userInput) // 添加用户消息
.call() // 执行
.content(); // 提取内容
}

// 方式 2:使用已有的 Prompt 对象
public String promptWithPromptObject(Prompt existingPrompt) {
return chatClient.prompt(existingPrompt) // 使用预构建的 Prompt
.call()
.content();
}

// 方式 3:直接传字符串的便捷方法
public String promptWithString(String message) {
return chatClient.prompt(message) // .user(message) 的简写
.call()
.content();
}
}

3.3 系统消息与用户消息

// 基础系统消息与用户消息
String response = chatClient.prompt()
.system("你是一个得力的 Java 开发助手")
.user("如何在 Spring Boot 中创建 REST 控制器?")
.call()
.content();

// 带参数的系统消息
String response = chatClient.prompt()
.system(s -> s
.text("你正在为 {company} 担任 {role}。请保持 {tone}。")
.param("role", "资深开发工程师")
.param("company", "TechCorp")
.param("tone", "简洁且专业"))
.user("解释一下依赖注入")
.call()
.content();

// 带参数的用户消息
String response = chatClient.prompt()
.user(u -> u
.text("将 '{text}' 翻译为 {language}")
.param("text", "Hello, world!")
.param("language", "西班牙语"))
.call()
.content();

3.4 执行模式:Call vs Stream

// 简单的阻塞调用 —— 直接返回字符串
String response = chatClient.prompt()
.user("什么是 Spring AI?")
.call()
.content();

// 获取包含元数据的完整 ChatResponse
ChatResponse response = chatClient.prompt()
.user("什么是 Spring AI?")
.call()
.chatResponse();

String content = response.getResult().getOutput().getText();
Usage usage = response.getMetadata().getUsage();

log.info("Token 消耗:输入={}, 输出={}",
usage.getPromptTokens(),
usage.getCompletionTokens());

// 类型安全的实体提取
ProductAnalysis analysis = chatClient.prompt()
.user("分析这款产品:无线蓝牙耳机")
.call()
.entity(ProductAnalysis.class);

4. 消息类型与角色详解

4.1 消息的各种实现

Spring AI 为每种消息类型都提供了具体实现:

// 系统消息 —— 设定 AI 行为和上下文
SystemMessage systemMsg = new SystemMessage(
"你是一位资深的 Java 开发专家。请提供带有解释的代码示例。"
);

// 用户消息 —— 代表用户的输入
UserMessage userMsg = new UserMessage(
"如何在 Spring Boot 中创建 REST 端点?"
);

// 助手消息 —— 代表 AI 的回复
AssistantMessage assistantMsg = new AssistantMessage(
"要在 Spring Boot 中创建 REST 端点,请使用 @RestController 注解..."
);

// 工具消息 —— 包含工具调用的结果
ToolMessage toolMsg = new ToolMessage(
"tool_call_id_123",
"东京当前天气为 22°C,晴天。"
);

5. PromptTemplate 深度解析

PromptTemplate 提供了提示词的一等公民管理,支持变量替换、自定义分隔符以及资源加载。

5.1 基础模板用法

// 创建带占位符的模板
PromptTemplate template = PromptTemplate.builder()
.template("""
请将以下文本翻译为 {language}。
保持原始语气和风格。

文本: {text}

翻译结果:
""")
.build();

// 使用变量渲染模板
Map<String, Object> variables = Map.of(
"language", "西班牙语",
"text", "Hello, world!"
);

String renderedPrompt = template.render(variables);

6. 提示词顾问 (Prompt Advisors)

Advisor API 采用强大的责任链模式来修改提示词和响应。顾问可以增强提示词、添加上下文、记录交互以及实现横向关注点。

6.1 内置顾问示例

@Component
public class PromptAdvisorConfig {

// 简单日志顾问 —— 记录所有提示词与响应
@Bean
public SimpleLoggerAdvisor simpleLoggerAdvisor() {
return new SimpleLoggerAdvisor();
}
}

7. 高级提示词模式

7.1 少样本提示词 (Few-Shot Prompting)

// 通过示例进行分类
String fewShotPrompt = """
将以下电子邮件分类至以下类别:
- INQUIRY: 客户咨询信息
- SUPPORT: 客户反馈问题
- SALES: 客户有意购买
- OTHER: 其他

示例:
邮件: "你们的白金计划多少钱?"
类别: SALES

邮件: "我登不上账号了,救命!"
类别: SUPPORT

现在请分类:
邮件: "{email}"
类别:
""";

7.2 思维链提示词 (Chain-of-Thought)

// 引导模型进行分步推理
String cotPrompt = """
让我们一步步思考来解决这个问题。

问题: {problem}

推理步骤:
1. 理解问题核心
2. 识别已知约束
3. 探索可能的方案
4. 评估优劣
5. 给出最终建议
""";

总结

Spring AI 的提示词系统不仅仅是字符串拼接,它是一套结构化、工程化的 AI 通信框架:

  1. 类型安全:利用 Java 强类型减少运行时错误。
  2. 抽象一致:统一管理不同模型供应商的差异。
  3. 功能强大:通过 Template 和 Advisors 实现了高度的灵活性和可观测性。
  4. 易于集成:与 Spring Boot 生态完美融合,适合构建企业级 AI 应用。

第 05 章结束。下一章:第 06 章:评估与版本管理