Spring AI开发跃迁指南(第二章:急速上手3——Spring AI 提示词及提示词模版核心原理及使用实例)
1.提示词简介
提示词是引导 AI 模型生成特定输出的输入,这些提示的设计和措辞会显著影响模型的响应。关于提示词以及LLM中基本概念及入门的介绍请参考Spring AI开发跃迁指南(第一章:生态破局——Spring AI的颠覆性优势分析)。在人工智能领域,提示词的结构一直在不断发展。最初,提示符只是简单的字符串。随着时间的推移,它们逐渐包含特定输入的占位符,例如“USER:”,而人工智能模型可以识别这些占位符。OpenAI 通过在人工智能模型处理多个消息字符串之前,将它们分类到不同的角色中,为提示符引入了更丰富的结构。
2.源码分析及详解
通常使用ChatModel的call()方法,它接受一个Prompt实例并返回一个ChatResponse。
Prompt类源码:
public class Prompt implements ModelRequest { private final List messages; private ChatOptions chatOptions; // 省略构造函数和其他方法..... }
2.1.chatOptions
chatOptions请求容器,用于配置与大语言模型(LLM)交互时的参数选项,直接影响模型生成内容的质量、风格和性能。其核心参数如下:
-
温度控制(Temperature)
ChatOptions options = ChatOptions.builder() .temperature(0.7) // 默认值:0.7,范围:0-2 .build();
-
作用: 控制模型输出的随机性
- 低温度(接近 0):生成确定性强、聚焦性高的回答(适合代码生成、事实性问答)
- 高温度(接近 2):生成更具创造性、多样性的回答(适合故事创作、头脑风暴)
-
最大生成tokens(Max Tokens)
ChatOptions.builder() .maxTokens(200) // 限制回复最大长度 .build();
-
注意事项:
- 需预留足够 token 空间给提示词(总 token 数 ≤ 模型上下文窗口)
- 对于长文本生成,建议结合文本分块策略
-
Top-P 采样(Nucleus Sampling)
ChatOptions.builder() .topP(0.9) // 默认值:1.0,范围:0-1 .build();
-
作用: 只考虑概率质量累计达到 topP 的最小词元集合
- 与 temperature 互补,通常不同时调整
- 较小的 topP 值(如 0.9)可减少无关输出
-
频率惩罚(Frequency Penalty)
ChatOptions.builder() .frequencyPenalty(0.5) // 默认值:0,范围:-2.0到2.0 .build();
-
作用: 降低已出现词元的生成概率
- 正值: 减少重复表述(适合长文本生成)
- 负值: 增加重复可能性(适合诗歌、歌词创作)
-
存在惩罚(Presence Penalty)
ChatOptions.builder() .presencePenalty(0.5) // 默认值:0,范围:-2.0到2.0 .build();
-
区别于频率惩罚:
- 频率惩罚: 针对词元出现次数
- 存在惩罚: 针对词元是否出现过(更全局的惩罚)
-
停止词元(Stop Sequences)
ChatOptions.builder() .stop(List.of("```", "\n\n")) // 遇到这些词元时停止生成 .build();
-
典型应用场景:
- 代码生成时遇到代码块结束标记
- 对话系统中遇到特定分隔符
- 日志概率(Logprobs)
ChatOptions.builder() .logprobs(5) // 返回top 5候选词元的概率信息 .build();
- 用途:
- 模型行为调试
- 构建概率引导的生成系统
2.3.Message
Message接口封装了Prompt文本内容、元数据属性集合和称为MessageType的分类。
public interface Message extends Content { MessageType getMessageType(); } public interface Content { String getContent(); Map getMetadata(); }
多模态消息类型还实现了提供媒体内容对象列表的MediaContent接口:
public interface MediaContent extends Content { Collection getMedia(); }
Message接口的各种实现对应于AI模型可以处理的不同类别的消息,模型根据会话角色区分消息类别。
Mesage实现类如下:
UML图如下:
每个Message都被分配了一个特定的角色。这些角色对消息进行分类,阐明AI模型提示的每个部分的上下文和目的。这种结构化的方法增强了与AI交流的细微差别和有效性,因为提示的每个部分在交互中都扮演着不同的角色。
这些角色由MessageType指定:
- 系统角色(System Role): 引导AI的行为和响应风格,为AI如何解释和回复输入设置参数或规则,类似于在开始对话之前向AI提供指令。
- 用户角色(User Role): 代表用户的输入——他们向AI提出的问题、命令或语句。这个角色至关重要,因为它构成了AI响应的基础。
- 助手角色(Assistant Role): AI 对用户输入的响应,对于维持对话的流畅性至关重要。如记录历史对话响应,维持上下文连贯性。
- 工具/功能角色(Tool/Function Role): 工具/功能角色侧重于在响应工具呼叫助理消息时返回附加信息(触发外部工具调用如 API 查询等)。
public enum MessageType { USER("user"), ASSISTANT("assistant"), SYSTEM("system"), TOOL("tool"); ... }
3.PromptTemplate提示词模版
Spring AI 中的 提示词模板(Prompt Template) 是构建动态、灵活提示词(Prompt)的核心工具。它允许开发者将静态文本与动态变量结合,生成符合上下文需求的提示词,从而提高与大模型(如 ChatGPT、LLaMA 等)交互的效率和可控性。
作用:
- 动态内容生成:通过变量替换,基于不同输入生成定制化提示词。
- 代码复用:避免重复编写相似提示结构,提升代码可维护性。
- 上下文管理:整合系统指令、用户输入、历史对话等上下文信息。
- 格式标准化:统一提示词结构,确保模型输入格式符合预期。
3.1.核心类解析
- PromptTemplate类
PromptTemplate类是所有提示词模板的基类,旨在促进结构化提示的创建,然后将其发送到 AI 模型进行处理,是模板解析与变量替换的核心入口。
其UML图如下:
此类使用TemplateRendererAPI 来渲染模板。默认情况下,Spring AI 使用StTemplateRenderer基于 Terence Parr 开发的开源StringTemplate引擎的实现。模板变量通过语法标识{},但您也可以配置分隔符以使用其他语法。
public interface TemplateRenderer extends BiFunction { @Override String apply(String template, Map variables); }
- PromptTemplateStringActions接口
专注于创建和渲染提示字符串,代表提示生成的最基本形式。
public interface PromptTemplateStringActions { // 将提示模板渲染为最终的字符串格式,无需外部输入,适用于没有占位符或动态内容的模板 String render(); // 增强渲染功能以包含动态内容。它使用一个Map映射,其中key是提示模板中的占位符名称,value是要插入的动态内容 String render(Map model); }
- PromptTemplateMessageActions接口
适用于通过生成和操作Message对象进行快速创作。
public interface PromptTemplateMessageActions { // 创建一个Message没有附加数据的对象,用于静态或预定义的消息内容。 Message createMessage(); // 创建一个Message具有静态文本和媒体内容的对象。 Message createMessage(List mediaList); // 扩展消息创建以集成动态内容,接受Map每个条目代表消息模板中的占位符及其对应的动态值。 Message createMessage(Map model); }
4.PromptTemplateActions接口
旨在返回Prompt对象,可以将其传递ChatModel给生成响应。
public interface PromptTemplateActions extends PromptTemplateStringActions { // Prompt无需外部数据输入即可生成对象,非常适合静态或预定义提示。 Prompt create(); // 生成一个Prompt没有外部数据输入但带有聊天请求特定选项的对象。 Prompt create(ChatOptions modelOptions); // 扩展提示创建功能以包含动态内容,其中Map每个映射条目都是提示模板中的占位符及其关联的动态值。 Prompt create(Map model); // 扩展提示创建功能以包含动态内容,其中Map每个映射条目都是提示模板中的占位符及其关联的动态值,以及聊天请求的特定选项。 Prompt create(Map model, ChatOptions modelOptions); }
3.2.PromptTemplate子类
-
SystemPromptTemplate:设置模型行为规则,如回答风格、领域限制等。
-
AssistantPromptTemplate:维护对话上下文连贯性,支持多轮对话管理。
-
FunctionPromptTemplate:支持与FunctionRegistry注册的工具联动,可配置工具调用参数校验规则。
4.使用示例
4.1.基础示例
Spring AI 的提示词模板默认采用 {} 作为变量占位符,支持简单变量替换和复杂表达式。
public String generateStream2() { PromptTemplate promptTemplate = new PromptTemplate("告诉我演员{actor}的生平和作品,如果他不是演员则返回不是演员"); Prompt prompt = promptTemplate.create(Map.of("actor", "刘亦菲")); return chatClient.prompt(prompt).call().content(); }
复杂表达式: 可结合 Spring Expression Language (SpEL) 实现逻辑处理。
String template = "生成关于{theme}的{sentenceCount > 1 ? '多个故事' : '一个故事'},风格为{style}。"; Map vars = Map.of("theme", "太空探险", "sentenceCount", 3, "style", "科幻");
模版嵌套: 组合多个子模板实现模块化。
PromptTemplate headerTemplate = new PromptTemplate("你是一位资深{role},擅长用{style}风格写作。"); PromptTemplate bodyTemplate = new PromptTemplate("请就{topic}撰写一篇{length}字的文章。"); Map vars = Map.of("role", "科技评论员", "style", "批判性分析", "topic", "AI 伦理", "length", 800); Prompt combinedPrompt = new Prompt( headerTemplate.create(vars).getContents() + bodyTemplate.create(vars).getContents() );
4.2.文件模版
Spring AI 支持org.springframework.core.io.Resource抽象,因此您可以将提示数据放入可直接在 PromptTemplate中使用的文件
手动:
public String generateStream3() { // 从classpath加载模板文件(theme.st) Resource templateResource = new ClassPathResource("theme.st"); PromptTemplate promptTemplate = new PromptTemplate(templateResource); // 生成带格式的提示词 Prompt prompt = promptTemplate.create(Map.of("theme", "联邦学习")); return chatClient.prompt(prompt).call().content(); }
自动:
@Value("classpath:/prompts/system-message.st") private Resource systemResource;
然后将资源SystemPromptTemplate直接传递给。
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
-
-
-
-
-