提示词基础
提示词是引导AI模型生成特定输出的输入内容。提示词的设计与措辞会极大影响模型的回复结果。
在Spring AI与AI模型交互的底层层面,提示词的处理方式和Spring MVC中视图(View)的管理有些相似:都是构建带有占位符的大段文本,再根据用户请求或应用内其他代码动态替换占位符内容。也可以类比为带有表达式占位符的SQL语句。
随着Spring AI的迭代演进,会推出更高层级的抽象来简化AI模型交互。本节介绍的基础类,其作用和地位可类比JDBC:
ChatModel类比JDK中核心的JDBC基础库;ChatClient类比JdbcClient,基于ChatModel构建,通过顾问(Advisor)提供更高级能力,比如关联历史对话、为提示词补充上下文文档、实现智能体行为等。
在AI领域,提示词的结构也在不断演变:最初只是简单字符串;后来增加了带标识的输入占位符(如 USER:);OpenAI 进一步强化了提示词结构化能力,将多条消息按不同角色分类后再交由AI模型处理。
API 概览
Prompt 类
开发中常调用 ChatModel 的 call() 方法,传入 Prompt 实例并返回 ChatResponse。
Prompt 是有序消息对象 Message 集合与请求配置 ChatOptions 的容器。每条 Message 在提示词中承担独立角色,拥有专属内容与意图,涵盖用户提问、AI回复、背景信息等。通过多角色消息组合,可实现与AI模型复杂、精细化的交互对话。
以下为精简版 Prompt 类源码(省略构造器与工具方法):
public class Prompt implements ModelRequest<List<Message>> {
private final List<Message> messages;
private ChatOptions chatOptions;
}便捷工具方法
Prompt 提供按角色快速获取消息的便捷方法:
单条消息获取
getUserMessage():返回提示词中最后一条用户消息,无则返回空用户消息getSystemMessage():返回提示词中第一条系统消息,无则返回空系统消息getLastUserOrToolResponseMessage():获取最后一条用户或工具响应消息,适用于会话续接场景
多条消息获取
getUserMessages():按顺序返回所有用户消息列表getSystemMessages():按顺序返回所有系统消息列表
这类方法在多轮对话、按角色批量处理消息时非常实用。
Message 消息接口
Message 接口封装了提示词文本内容、元数据属性集合,以及消息类型枚举 MessageType。
public interface Content {
String getContent();
Map<String, Object> getMetadata();
}
public interface Message extends Content {
MessageType getMessageType();
}多模态消息类型还实现了 MediaContent 接口,支持媒体内容列表:
public interface MediaContent extends Content {
Collection<Media> getMedia();
}Message 有多种实现类,对应AI模型可识别的不同消息类别。AI模型会根据对话角色区分消息类型。
Spring AI 消息角色 API
消息角色由枚举 MessageType 统一映射定义。
消息角色说明
每条消息都会被分配专属角色,用于划分消息类型,让AI明确提示词各部分的上下文与用途。结构化角色划分能提升AI交互的精准度与有效性。
系统角色(System Role):约束AI行为与回复风格,设定AI解读和应答的规则,相当于对话前给AI下达全局指令。
用户角色(User Role):代表用户输入,包括提问、指令、陈述内容,是AI生成回复的基础依据。
助手角色(Assistant Role):AI对用户输入的回复,不仅是简单应答,更是维持对话连贯性的关键。助手消息还可包含函数工具调用请求,用于执行计算、数据查询等对话之外的任务。
工具/函数角色(Tool/Function Role):专门用于响应助手工具调用消息,返回额外业务数据。
Spring AI 中角色通过枚举定义:
public enum MessageType {
USER("user"),
ASSISTANT("assistant"),
SYSTEM("system"),
TOOL("tool");
...
}PromptTemplate 提示词模板
PromptTemplate 是Spring AI提示词模板化的核心类,用于快速构建结构化提示词并发送给AI模型处理。
public class PromptTemplate implements PromptTemplateActions, PromptTemplateMessageActions {
// 其他方法后续介绍
}该类基于 TemplateRenderer 接口渲染模板,默认采用基于 StringTemplate 引擎的 StTemplateRenderer。默认使用 {} 作为占位符分隔符,也可自定义分隔符。
public interface TemplateRenderer extends BiFunction<String, Map<String, Object>, String> {
@Override
String apply(String template, Map<String, Object> variables);
}TemplateRenderer 负责模板变量替换,默认实现为 StringTemplate;开发者可自定义实现类;无需模板渲染时可使用内置无操作实现 NoOpTemplateRenderer。
自定义分隔符渲染器示例:
PromptTemplate promptTemplate = PromptTemplate.builder()
.renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
.template("""
Tell me the names of 5 movies whose soundtrack was composed by <composer>.
""")
.build();
String prompt = promptTemplate.render(Map.of("composer", "John Williams"));模板相关接口
PromptTemplate 实现三类接口,覆盖不同提示词构建方式:
PromptTemplateStringActions:专注生成和渲染纯文本提示词,是最基础的提示词生成方式PromptTemplateMessageActions:通过创建和组装Message对象生成提示词PromptTemplateActions:直接生成Prompt对象,可直接传入ChatModel获取回复
接口定义如下:
public interface PromptTemplateStringActions {
String render();
String render(Map<String, Object> model);
}render():无入参渲染模板为最终文本,适用于无动态占位符的静态模板render(Map):传入键值对变量,替换模板占位符生成带动态内容的提示词
public interface PromptTemplateMessageActions {
Message createMessage();
Message createMessage(List<Media> mediaList);
Message createMessage(Map<String, Object> model);
}createMessage():创建静态无参消息对象createMessage(List<Media>):创建包含文本和媒体内容的消息createMessage(Map):传入变量映射,生成带动态内容的消息对象
public interface PromptTemplateActions extends PromptTemplateStringActions {
Prompt create();
Prompt create(ChatOptions modelOptions);
Prompt create(Map<String, Object> model);
Prompt create(Map<String, Object> model, ChatOptions modelOptions);
}create():生成静态Prompt对象create(ChatOptions):生成带聊天配置参数的Promptcreate(Map):传入动态变量生成Promptcreate(Map, ChatOptions):同时传入动态变量与聊天配置,生成完整Prompt
使用示例
基础模板示例:
PromptTemplate promptTemplate = new PromptTemplate("Tell me a {adjective} joke about {topic}");
Prompt prompt = promptTemplate.create(Map.of("adjective", adjective, "topic", topic));
return chatModel.call(prompt).getResult();多角色消息组合示例:
String userText = """
Tell me about three famous pirates from the Golden Age of Piracy and why they did.
Write at least a sentence for each pirate.
""";
Message userMessage = new UserMessage(userText);
String systemText = """
You are a helpful AI assistant that helps people find information.
Your name is {name}
You should reply to the user's request with your name and also in the style of a {voice}.
""";
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
List<Generation> response = chatModel.call(prompt).getResults();示例通过系统提示模板创建带变量的系统消息,再与用户消息组合为完整 Prompt,提交给 ChatModel 获取生成结果。
自定义模板渲染器
可实现 TemplateRenderer 自定义渲染逻辑,也可直接配置默认 StTemplateRenderer 修改分隔符。当提示词包含JSON内容时,可更换占位符符号避免语法冲突,如使用 <>。
PromptTemplate promptTemplate = PromptTemplate.builder()
.renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
.template("""
Tell me the names of 5 movies whose soundtrack was composed by <composer>.
""")
.build();
String prompt = promptTemplate.render(Map.of("composer", "John Williams"));读取资源文件作为模板
Spring AI 支持Spring资源抽象 Resource,可将提示词放在配置文件中直接加载使用:
@Value("classpath:/prompts/system-message.st")
private Resource systemResource;
// 直接传入资源构建系统提示模板
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);提示词工程
在生成式AI开发中,提示词编写是开发者的核心工作。提示词的质量与结构直接决定AI输出效果。精心设计提示词能大幅提升AI返回结果的精准度。
提示词的分享与交流是AI社区常态,既能共建学习氛围,也能沉淀大量高效通用提示词方案。相关研究表明,以「深呼吸,分步解决这个问题」开头的提示词,能显著提升AI的解题效率,体现措辞对大模型性能的重要影响。
随着AI技术快速迭代,掌握高效提示词用法是一项长期能力。开发者应重视提示词工程,借鉴社区经验与学术研究优化提示词设计思路。
编写优质提示词核心要素
指令说明:向AI给出清晰直白的任务指令,如同与人沟通,让AI明确预期目标
外部上下文:按需补充背景信息与参考依据,帮AI理解完整业务场景
用户输入:用户直接提问或需求描述,是提示词的核心主体
输出格式约束:指定AI回复格式(如JSON),需注意模型不一定严格遵守,可能附带额外描述或格式瑕疵
编写提示词时,提供标准问答示例能引导AI理解查询结构与意图,返回更精准贴合需求的内容。本文不深入讲解高阶技巧,但可作为进一步学习提示词工程的入门基础。
基础应用技巧
文本摘要:精简长篇文本,保留核心要点、剔除冗余信息
问答提取:根据用户问题,从指定文本中精准抽取对应答案
文本分类:按内容将文本自动划分到预设类别
对话交互:实现多轮往复对话,模拟自然交流流程
代码生成:根据自然语言需求生成可运行代码片段
高阶应用技巧
零样本/少样本学习:无需或仅需少量示例,模型依靠泛化能力完成全新任务
思维链(Chain-of-Thought):串联多轮AI回复,保持对话逻辑连贯、上下文关联
ReAct 推理行动模式:AI先对输入做逻辑推理,再决策执行动作或生成回复,融合理解与决策能力
微软提示词框架:一套标准化的提示词编写与优化方法论,指导开发者构建高效提示词,提升交互清晰度与执行效率
令牌 Token 详解
令牌是AI模型处理文本的基本单位,充当自然语言与模型可识别格式之间的转换桥梁:输入时文本转为令牌,输出时令牌还原为文字。分词(Tokenization)就是将文本拆分为令牌的过程,是模型理解和处理语言的基础。
直观理解:1个令牌约对应3/4个英文单词。例如莎士比亚全集约90万单词,折算约120万令牌。可通过OpenAI分词工具在线体验文字转令牌效果。
令牌在计费与模型能力上有实际业务意义:
计费规则:大模型服务普遍按令牌用量计费,输入提示词与输出回复均计入总量,精简提示词可降低使用成本
模型令牌上限:不同模型有不同令牌上限,即上下文窗口,代表单次可处理的最大信息量。如GPT-3上限4K令牌,Claude 2、Llama 2可达100K,部分研究模型支持百万级令牌
上下文窗口:超出令牌上限的输入无法被模型处理,因此只需传入最小必要信息,无需冗余内容
响应元数据:模型回复元数据中包含令牌消耗数量,可用于用量统计与成本管控