收藏本站,收获最前沿的人工智能与编程资讯!!

Spring AI 提示词处理 Prompt 类的使用

技术文档 16℃ 0

提示词基础

提示词是引导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 类

开发中常调用 ChatModelcall() 方法,传入 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):生成带聊天配置参数的 Prompt

  • create(Map):传入动态变量生成 Prompt

  • create(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,部分研究模型支持百万级令牌

  • 上下文窗口:超出令牌上限的输入无法被模型处理,因此只需传入最小必要信息,无需冗余内容

  • 响应元数据:模型回复元数据中包含令牌消耗数量,可用于用量统计与成本管控

相关推荐