文章目录
Pre
大模型开发 - 03 QuickStart_借助DeepSeekChatModel实现Spring AI 集成 DeepSeek
大模型开发 - 04 QuickStart_DeepSeek 模型调用流程源码解析:从 Prompt 到远程请求
大模型开发 - 05 QuickStart_接入阿里百炼平台:Spring AI Alibaba 与 DashScope SDK
大模型开发 - 06 QuickStart_本地大模型私有化部署实战:Ollama + Spring AI 全栈指南
大模型开发 - 07 ChatClient:构建统一、优雅的大模型交互接口
大模型开发 - 08 ChatClient:构建智能对话应用的流畅 API
大模型开发 - 09 ChatClient:基于 Spring AI 的多平台多模型动态切换实战
大模型开发 - 10 ChatClient:Advisors API 构建可插拔、可组合的智能对话增强体系
大模型开发 - 11 ChatClient:Advisor 机制详解:拦截、增强与自定义 AI 对话流程
概述
在构建基于大语言模型(LLM)的应用程序时,提示(Prompt) 是连接开发者意图与 AI 模型能力的核心桥梁。Spring AI 作为 Spring 生态系统中面向生成式 AI 的新成员,提供了一套结构化、类型安全且高度可扩展的提示管理机制。本文将深入剖析 Spring AI 中提示系统的设计理念、核心组件、使用方式以及提示工程的最佳实践,帮助开发者全面掌握这一关键能力。
一、提示(Prompt)的本质与 Spring AI 的类比
在 Spring AI 中,提示(Prompt) 是引导 AI 模型生成特定输出的输入指令。其设计和措辞对模型响应的质量、准确性与风格具有决定性影响。
Spring AI 将提示处理类比于 Spring MVC 中的 “视图(View)” 层:开发者编写包含占位符的模板文本(如 "Tell me a {adjective} joke about {topic}"
),运行时根据用户请求或业务逻辑动态填充这些占位符,最终生成完整的提示字符串。这种模式类似于 SQL 语句中的参数化查询(如 SELECT * FROM users WHERE name = ?
),通过占位符实现动态内容注入,避免硬编码并提升灵活性。
随着 Spring AI 的演进,其抽象层次也在不断提升:
- 底层基础类(如
ChatModel
) 类似于 JDBC —— 提供最原始、最直接的模型调用能力。 - 高层封装类(如
ChatClient
) 则类似于JdbcClient
—— 在ChatModel
之上构建,通过 Advisor(顾问) 机制支持上下文记忆、检索增强(RAG)、工具调用(Tool Calling)和智能体(Agentic)行为等高级功能。
这种分层设计使得开发者既能进行细粒度控制,也能快速构建复杂 AI 应用。
二、核心 API 概览:Prompt
与 Message
1. Prompt
类:结构化提示的容器
在 Spring AI 中,与 AI 模型交互的标准方式是调用 ChatModel.call(Prompt)
方法,该方法接收一个 Prompt
实例并返回 ChatResponse
。
Prompt
类的核心作用是封装一系列有序的 Message
对象以及可选的 ChatOptions
(模型调用参数)。其简化定义如下:
public class Prompt implements ModelRequest<List<Message>> {
private final List<Message> messages;
private ChatOptions chatOptions;
}
关键点:现代 AI 模型(如 OpenAI 的 GPT 系列)不再将提示视为单一字符串,而是由多条具有不同角色的消息组成的对话历史。
Prompt
正是这一理念的体现。
2. Message
接口:消息的抽象
每条 Message
代表对话中的一个语义单元,包含:
- 文本内容(
getContent()
) - 元数据(
getMetadata()
) - 消息类型(
getMessageType()
)
其接口定义如下:
public interface Content {
String getContent();
Map<String, Object> getMetadata();
}
public interface Message extends Content {
MessageType getMessageType();
}
对于多模态模型(支持图像、音频等),Message
还可实现 MediaContent
接口,提供媒体内容列表:
public interface MediaContent extends Content {
Collection<Media> getMedia();
}
三、消息角色(Roles):对话的语义结构
Spring AI 通过 MessageType
枚举定义了四种核心消息角色,这直接映射了主流 LLM(如 OpenAI、Anthropic)的对话协议:
public enum MessageType {
USER("user"),
ASSISTANT("assistant"),
SYSTEM("system"),
TOOL("tool");
}
1. 系统角色(SYSTEM)
- 作用:为 AI 设定行为准则、身份、风格或约束条件。
- 类比:给 AI 的“操作手册”或“角色设定卡”。
- 示例:
你是一个专业的历史学家,回答需严谨、引用可靠史料,避免虚构。
2. 用户角色(USER)
- 作用:代表用户的实际输入——问题、指令或陈述。
- 核心:这是触发 AI 响应的直接原因。
- 示例:
请简述法国大革命的主要原因。
3. 助手角色(ASSISTANT)
- 作用:AI 生成的回复。不仅包含答案,还可包含工具调用请求(Function/Tool Call)。
- 重要性:在多轮对话中,历史
ASSISTANT
消息是维持上下文连贯性的关键。 - 示例(含工具调用):
{ "role": "assistant", "content": null, "tool_calls": [{ "function": { "name": "get_weather", "arguments": "{ \"city\": \"Paris\" }" } }] }
4. 工具/函数角色(TOOL)
- 作用:向 AI 返回工具调用的结果,供其生成最终回答。
- 流程:
ASSISTANT
请求调用工具 → 应用执行工具 → 将结果以TOOL
消息形式回传给模型。 - 示例:
{ "role": "tool", "content": "{ \"temperature\": 22, \"unit\": \"Celsius\" }", "tool_call_id": "call_abc123" }
设计优势:这种角色分离机制使 Spring AI 能天然支持函数调用(Function Calling) 和 ReAct(Reason + Act) 等高级 AI 交互模式。
四、PromptTemplate
:动态提示生成的核心
1. 基本概念
PromptTemplate
是 Spring AI 中用于创建结构化、可参数化提示的核心类。它基于模板引擎,将静态模板与动态数据结合,生成最终的 Prompt
或 Message
。
默认使用 StringTemplate 引擎(由 Terence Parr 开发),占位符语法为 {variable}
,但支持自定义分隔符。
2. 核心接口与能力
PromptTemplate
实现了三个关键接口,覆盖不同层次的提示构建需求:
(1) PromptTemplateStringActions
:字符串级渲染
public interface PromptTemplateStringActions {
String render(); // 无参数渲染
String render(Map<String, Object> model); // 带参数渲染
}
(2) PromptTemplateMessageActions
:消息对象创建
public interface PromptTemplateMessageActions {
Message createMessage(); // 静态消息
Message createMessage(List<Media> mediaList); // 多模态消息
Message createMessage(Map<String, Object> model); // 动态消息
}
(3) PromptTemplateActions
:完整 Prompt 构建
public interface PromptTemplateActions extends PromptTemplateStringActions {
Prompt create(); // 静态 Prompt
Prompt create(ChatOptions modelOptions); // 带选项的 Prompt
Prompt create(Map<String, Object> model); // 动态 Prompt
Prompt create(Map<String, Object> model, ChatOptions modelOptions); // 动态+选项
}
3. 使用示例
示例 1:基础动态提示
PromptTemplate promptTemplate = new PromptTemplate("Tell me a {adjective} joke about {topic}");
Prompt prompt = promptTemplate.create(Map.of("adjective", "funny", "topic", "AI"));
ChatResponse response = chatModel.call(prompt);
示例 2:结合系统与用户消息
// 用户消息
String userText = "Tell me about three famous pirates...";
Message userMessage = new UserMessage(userText);
// 系统消息(带模板)
String systemText = "You are a helpful AI assistant named {name}. Reply in the style of a {voice}.";
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Sparrow", "voice", "pirate"));
// 构建完整 Prompt
Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
List<Generation> results = chatModel.call(prompt).getResults();
注意:消息顺序很重要!通常
SYSTEM
消息在前,USER
在后。
4. 自定义模板渲染器
为避免与 JSON 中的 {}
冲突,可自定义分隔符:
PromptTemplate promptTemplate = PromptTemplate.builder()
.renderer(StTemplateRenderer.builder()
.startDelimiterToken('<')
.endDelimiterToken('>')
.build())
.template("Tell me 5 movies by <composer>.")
.build();
String prompt = promptTemplate.render(Map.of("composer", "John Williams"));
// 输出: "Tell me 5 movies by John Williams."
5. 从资源文件加载模板
Spring AI 支持 org.springframework.core.io.Resource
,可将提示模板存于文件:
@Value("classpath:/prompts/system-message.st")
private Resource systemResource;
// 直接使用 Resource 构建模板
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
这有利于提示模板的外部化管理和版本控制。
五、提示工程(Prompt Engineering):提升 AI 输出质量的艺术
提示工程是生成式 AI 应用开发的核心技能。高质量的提示能显著提升模型输出的准确性、相关性和安全性。
1. 有效提示的关键组件
构建优秀提示应包含以下要素:
组件 | 说明 | 示例 |
---|---|---|
指令(Instructions) | 清晰、具体的任务描述 | “用三句话总结…” |
外部上下文(External Context) | 背景信息或约束 | “假设用户是高中生…” |
用户输入(User Input) | 核心问题或请求 | “解释量子纠缠” |
输出指示器(Output Indicator) | 期望的格式或结构 | “以 JSON 格式返回,包含 title 和 summary 字段” |
警告:模型可能不严格遵守格式要求(如在 JSON 前加说明文字),需结合后处理或 Schema 约束。
2. 高级提示技术
技术 | 描述 | Spring AI 支持 |
---|---|---|
Few-shot Learning | 提供示例引导模型 | 通过多条 USER /ASSISTANT 消息实现 |
Chain-of-Thought (CoT) | 要求模型“逐步思考” | 在系统消息中加入“Let’s think step by step” |
ReAct | 结合推理与行动(工具调用) | 通过 ASSISTANT → TOOL → ASSISTANT 流程实现 |
检索增强生成(RAG) | 注入外部知识 | 通过 ChatClient + Advisor 实现 |
3. 社区与研究洞察
- “Take a deep breath and work on this problem step by step” 被证明能显著提升复杂问题解决能力。
- 微软等公司已提出结构化提示框架,指导开发者系统化设计提示。
六、Tokens:AI 模型的“计量单位”
1. 什么是 Token?
Token 是 AI 模型处理文本的基本单位。一个 token ≈ 0.75 个英文单词。例如:
- Shakespeare 全集(90万词)≈ 120万 tokens
- “unbelievable” 可能被拆为
["un", "believ", "able"]
三个 tokens
2. Token 的实际影响
方面 | 说明 |
---|---|
计费 | 输入 + 输出 tokens 总数决定成本。精简提示可降本。 |
上下文窗口(Context Window) | 模型有最大 token 限制(如 GPT-3: 4K, Claude 2: 100K)。超限内容会被截断。 |
性能 | 更少 tokens 通常意味着更快响应。 |
3. 最佳实践
- 只传递必要信息:询问《哈姆雷特》时,无需包含莎翁其他作品。
- 监控响应元数据:
ChatResponse
包含使用的 token 数,可用于成本分析。
七、总结
Spring AI 的提示系统通过 Prompt
、Message
、MessageType
和 PromptTemplate
等组件,为开发者提供了:
- 类型安全的提示构建方式
- 角色清晰的对话结构支持
- 高度灵活的模板渲染机制
- 无缝集成 Spring 生态(如
@Value
加载资源)
随着 ChatClient
和 Advisor
等高层抽象的完善,Spring AI 将进一步简化 RAG、Agent、Tool Calling 等复杂场景的实现。
提示工程不是魔法,而是科学与艺术的结合。掌握 Spring AI 的提示系统,意味着你不仅是在调用 AI,更是在精心设计人与智能体的对话协议。持续学习社区最佳实践、实验不同提示策略、监控 token 使用,将是构建高效、可靠 AI 应用的关键。
延伸资源: