Spring AI 系列3: Promt提示词

news2025/7/27 5:05:59

一、Promt提示词

Promt提示是引导 AI 模型生成特定输出的输入, 提示的设计和措辞会显著影响模型的响应。

在 Spring AI 中与 AI 模型交互的最低层级,处理提示有点类似于在 Spring MVC 中管理”视图”。 这涉及创建带有动态内容占位符的大段文本。 这些占位符随后会根据用户请求或应用程序中的其他代码进行替换。 另一个类比是包含某些表达式占位符的 SQL 语句。

随着 Spring AI 的发展,它将引入更高级别的与 AI 模型交互的抽象。 本节描述的基础类在其角色和功能上可以类比为 JDBC。 例如,ChatModel 类类似于 JDK 中的核心 JDBC 库。 ChatClient 类类似于 JdbcClient,它构建在 ChatModel 之上,并通过 Advisor 提供更高级的构造,能够考虑与模型的历史交互、用额外的上下文文档增强提示,并引入代理行为。

提示的结构在 AI 领域内随着时间的推移而演变。 最初,提示只是简单的字符串。 随着时间的推移,它们发展为包含特定输入占位符,如”USER:“,AI 模型能够识别。 OpenAI 通过在处理前将多条消息字符串分类为不同角色,为提示引入了更多结构。

prompt()

这个无参数方法让您开始使用流畅 API,允许您构建用户、系统和其他提示部分。

prompt(Prompt prompt)

这个方法接受 Prompt 参数,让您传入使用 Prompt 的非流畅 API 创建的 Prompt 实例。

prompt(String content)

这是一个类似于前一个重载的便捷方法。它接受用户的文本内容。


二、Prompt  API 概述

2.1 、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;
}

2.2、Message

Message 接口封装了提示的文本内容、元数据属性集合和称为 MessageType 的分类。

public interface Content {

	String getContent();

	Map<String, Object> getMetadata();
}

public interface Message extends Content {

	MessageType getMessageType();
}

多模态消息类型还实现了 MediaContent 接口,提供 Media 内容对象列表。

public interface MediaContent extends Content {

	Collection<Media> getMedia();

}

Message 接口有多种实现,对应于 AI 模型可以处理的不同类别的消息。 模型根据对话角色区分消息类别。

2.3 、 MessageType 消息角色

这些角色由 MessageType 有效映射。每条消息都被分配了一个特定角色。 这些角色对消息进行分类,为 AI 模型澄清每个提示片段的上下文和目的。 这种结构化方法增强了与 AI 的交流的细致性和有效性,因为提示的每一部分在交互中都扮演着独特且明确定义的角色。

系统角色

指导 AI 的行为和响应风格,设置参数或规则,规定 AI 如何解释和回复输入。类似于在开始对话前为 AI 提供指令。

用户角色

代表用户的输入——他们对 AI 的问题、命令或陈述。这个角色是基础,因为它构成了 AI 响应的依据。

助手角色

AI 对用户输入的响应。不仅仅是答案或反应,对于维持对话的流畅性至关重要。 通过跟踪 AI 先前的响应(其”助手角色”消息),系统确保交互的连贯性和上下文相关性。 助手消息还可能包含函数工具调用请求信息。 这就像 AI 的一个特殊功能,在需要时用于执行特定功能,如计算、获取数据或其他超出对话的任务。

工具/函数角色

工具/函数角色专注于响应工具调用助手消息时返回额外信息。

角色在 Spring AI 中以枚举方式表示

public enum MessageType {

	USER("user"),

	ASSISTANT("assistant"),

	SYSTEM("system"),

	TOOL("tool");

    ...
}

2.4、PromptTemplate

Spring AI 中提示模板的关键组件是 PromptTemplate 类,旨在便于创建结构化提示,然后将其发送给 AI 模型进行处理。

public class PromptTemplate implements PromptTemplateActions, PromptTemplateMessageActions {

    // 其他方法后续讨论
}

该类使用 TemplateRenderer API 渲染模板。默认情况下,Spring AI 使用基于 Terence Parr 开发的开源 StringTemplate 引擎的 StTemplateRenderer 实现。模板变量由 {} 语法标识,但您也可以配置分隔符以使用其他语法。

public interface TemplateRenderer extends BiFunction<String, Map<String, Object>, String> {

	@Override
	String apply(String template, Map<String, Object> variables);

}

Spring AI 使用 TemplateRenderer 接口处理变量到模板字符串的实际替换。 默认实现使用 StringTemplate。 如果需要自定义逻辑,您可以提供自己的 TemplateRenderer 实现。 对于不需要模板渲染的场景(例如模板字符串已完整),可以使用提供的 NoOpTemplateRenderer

PromptTemplate promptTemplate = PromptTemplate.builder()
    .renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
    .template("""
            告诉我 5 部由 <composer> 作曲的电影名称。
            """)
    .build();

String prompt = promptTemplate.render(Map.of("composer", "John Williams"));

该类实现的接口支持提示创建的不同方面:

  • PromptTemplateStringActions 专注于创建和渲染提示字符串,代表最基本的提示生成形式。

  • PromptTemplateMessageActions 针对通过生成和操作 Message 对象进行提示创建。

  • PromptTemplateActions 旨在返回 Prompt 对象,可传递给 ChatModel 以生成响应。

虽然这些接口在许多项目中可能不会被广泛使用,但它们展示了提示创建的不同方法。

实现的接口如下:

public interface PromptTemplateStringActions {

	String render();

	String render(Map<String, Object> model);

}

PromptTemplateStringActions 方法

public interface PromptTemplateMessageActions {

	Message createMessage();

    Message createMessage(List<Media> mediaList);

	Message createMessage(Map<String, Object> model);

}

PromptTemplateMessageActions 方法

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);

}

PromptTemplateActions 方法

Prompt create():生成不带外部数据输入的 Prompt 对象,适用于静态或预定义的提示。
Prompt create(ChatOptions modelOptions):生成不带外部数据输入且带有特定聊天请求选项的 Prompt 对象。
Prompt create(Map<String, Object> model):扩展提示创建能力以包含动态内容,接受 Map<String, Object>,每个 map 条目是提示模板中的占位符及其关联的动态值。
Prompt create(Map<String, Object> model, ChatOptions modelOptions):扩展提示创建能力以包含动态内容,接受 Map<String, Object>,每个 map 条目是提示模板中的占位符及其关联的动态值,并带有特定的聊天请求选项。

2.5、示例用法

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();

三、构建提示(Prompt)的三种模式

提示是引导模型输出的关键,ChatClient支持三种构建方式,满足不同复杂度需求:

3.1、逐层构建(复杂场景)

显式添加系统消息、用户消息,支持动态参数替换:

String response = chatClient.prompt()  
    .system(s -> s.text("以{style}风格回答").param("style", "古风"))  // 系统消息含占位符  
    .user("解释什么是人工智能")  // 用户消息  
    .option(OpenAiChatOptions.builder().temperature(0.8).build())  // 模型参数(如OpenAI特有参数)  
    .call()  
    .content();  

优势:细粒度控制消息结构,支持多轮对话历史拼接。

3.2、预构建Prompt对象(批量处理)

适用于提示模板化场景,提前组装消息列表:

// 定义提示模板  
Prompt promptTemplate = Prompt.builder()  
    .systemMessage("你是一个幽默的助手")  
    .userMessage("讲一个{topic}相关的笑话")  
    .build();  

// 运行时填充参数  
Prompt dynamicPrompt = promptTemplate.replaceParams(Map.of("topic", "程序员"));  
ChatResponse response = chatClient.prompt(dynamicPrompt).call().chatResponse();  

最佳实践:将常用提示模板存入数据库或配置中心,实现动态加载。

3.3、快捷方式(极简场景)

单行代码完成用户消息提交,适用于简单问答:

String answer = chatClient.prompt("如何煮咖啡").call().content();  

注意:此模式默认无系统消息,模型行为依赖其基础训练数据。


四、ChatClient响应处理:从文本到结构化数据

4.1、 获取完整元数据(性能监控和Token消耗计算)

通过chatResponse()获取包含令牌消耗、生成结果列表的完整响应:

ChatResponse response = chatClient.prompt()  
    .user("计算1+1等于多少")  
    .call()  
    .chatResponse();  

System.out.println("总令牌数:" + response.getMetadata().getUsage().getTotalTokens());  
System.out.println("生成结果:" + response.getResults().get(0).getOutput());  

关键元数据:

  • totalTokens:请求+响应的总令牌数(影响调用成本)。

  • completionTokens:响应生成的令牌数。

  • promptTokens:提示内容的令牌数。

4.2、 自动映射Java对象(结构化输出)

通过entity()方法将模型输出转为自定义实体,需确保输出格式符合JSON规范:

// 定义目标实体  
record Recipe(String dish, List<String> ingredients) {}  

// 生成食谱并映射  
Recipe salad = chatClient.prompt()  
    .user("生成一份蔬菜沙拉食谱,以JSON格式输出")  
    .call()  
    .entity(Recipe.class);  // 自动解析JSON为对象  

System.out.println("菜名:" + salad.dish());  
System.out.println("食材:" + salad.ingredients());  

进阶技巧:结合StructuredOutputConverter自定义解析逻辑,处理非标准格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2398947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis:安装与常用命令

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Redis &#x1f525; 安装 Redis 使⽤apt安装 apt install redis -y⽀持远程连接 修改 /etc/redis/redis.conf 修改 bind 127.0.0.1 为 bind 0.0.0.0 修改 protected-mode yes 为 protected-mo…

Mac 芯片系列 安装cocoapod 教程

安装声明&#xff1a; 本人是在搭梯子的环境下安装成功&#xff0c;前提是必须安装好安装homebrew环境。 1.检测rudy的源 2.查看源(目的:检测rudy的源) gem sources - l 3.移除源(目的:移除rudy自带的源) gem sources --remove https://rubygems.org/ 4.更换源(目的:替换成国…

智启未来:AI重构制造业供应链的五大革命性突破

一、需求预测&#xff1a;让供应链“未卜先知” 1.1 从经验判断到数据预言 传统供应链依赖人工分析历史数据&#xff0c;但面对市场波动、设备突发故障等不确定性&#xff0c;往往反应滞后。AI通过整合工业物联网&#xff08;IIoT&#xff09;传感器数据、生产排程、供应商交…

Linux进程间通信----简易进程池实现

进程池的模拟实现 1.进程池的原理&#xff1a; 是什么 进程池是一种多进程编程模式&#xff0c;核心思想是先创建好一定数量的子进程用作当作资源&#xff0c;这些进程可以帮助完成任务并且重复利用&#xff0c;避免频繁的进程的创建和销毁的开销。 下面我们举例子来帮助理…

解锁Java多级缓存:性能飞升的秘密武器

一、引言 文末有彩蛋 在当今高并发、低延迟的应用场景中&#xff0c;传统的单级缓存策略往往难以满足性能需求。随着系统规模扩大&#xff0c;数据访问的瓶颈逐渐显现&#xff0c;如何高效管理缓存成为开发者面临的重大挑战。多级缓存架构应运而生&#xff0c;通过分层缓存设…

(纳芯微)NCA9548- DTSXR 具有复位功能的八通道 I²C 开关、所有I/O端子均可承受5.5V输入电压

深圳市润泽芯电子有限公司 推荐NOVOSENSE(纳芯微)品牌 NCA9548- DTSXR TSSOP-24封装 NCA9548- DTSXR 具有复位功能的八通道 IC 开关、所有I/O端子均可承受5.5V输入电压 产品描述 NCA9548是通过I2C总线控制的八路双向转换开关。 SCL / SDA上行数据分散到八对下行数据或通道。…

013旅游网站设计技术详解:打造一站式旅游服务平台

旅游网站设计技术详解&#xff1a;打造一站式旅游服务平台 在互联网与旅游业深度融合的时代&#xff0c;旅游网站成为人们规划行程、预订服务的重要工具。一个功能完备的旅游网站&#xff0c;通过用户管理、订单管理等核心模块&#xff0c;实现用户与管理员的高效交互。本文将…

2024 CKA模拟系统制作 | Step-By-Step | 12、题目搭建-创建多容器Pod

目录 免费获取题库配套 CKA_v1.31_模拟系统 一、题目 二、考点分析 1. 多容器 Pod 的理解 2. YAML 配置规范 3. 镜像版本控制 三、考点详细讲解 1. 多容器 Pod 的工作原理 2. 容器端口冲突处理 3. 资源隔离机制 四、实验环境搭建步骤 总结 免费获取题库配套 CKA_v…

优化 Spring Boot API 性能:利用 GZIP 压缩处理大型有效载荷

引言 在构建需要处理和传输大量数据的API服务时&#xff0c;响应时间是一个关键的性能指标。一个常见的场景是&#xff0c;即使后端逻辑和数据库查询已得到充分优化&#xff0c;当API端点返回大型数据集&#xff08;例如&#xff0c;数千条记录的列表&#xff09;时&#xff0…

【C盘瘦身】给DevEco Studio中HarmonyOSEmulator(鸿蒙模拟器)换个地方,一键移动给C盘瘦身

文章目录 一、HarmonyOSEmulator的安装路径二、修改路径 一、HarmonyOSEmulator的安装路径 之前安装了华为的DevEco Studio&#xff0c;当时没注意&#xff0c;后来C盘告急&#xff0c;想着估计是鸿蒙的模拟器占用空间比较大&#xff0c;一检查还真是躺在C盘。路径如下&#x…

ORACLE 缺失 OracleDBConsoleorcl服务导致https://xxx:port/em 不能访问

这个原因是&#xff0c;操作过一下 ORCL的服务配置变更导致的。 再PATH中添加个环境变量&#xff0c;路径如下 管理员权限运行cmd 等待创建完成 大概3分钟 查看服务 点击第一个访问&#xff0c;下图登录后的截图

VScode自动添加指定内容

在 VS Code 中&#xff0c;可以通过配置 用户代码片段&#xff08;User Snippets&#xff09; 或使用 文件模板扩展 来实现新建指定文件类型时自动添加指定内容。以下是具体方法&#xff1a; 方法 1&#xff1a;使用 VS Code 内置的「用户代码片段」 适用场景&#xff1a;适用…

Ubuntu 22.04 安装 Nacos 记录

Ubuntu 22.04 安装 Nacos 记录 本文记录了在 Ubuntu 22.04 系统上安装 Nacos 的完整过程&#xff0c;适用于本地测试或生产部署的基础搭建。 一、官方资源 官网下载地址&#xff1a;https://nacos.io/download/nacos-server/官网文档&#xff1a;https://nacos.io/docs/lates…

相机--RGBD相机

教程 分类原理和标定 原理 视频总结 双目相机和RGBD相机原理 作用 RGBD相机RGB相机深度&#xff1b; RGB-D相机同时获取两种核心数据&#xff1a;RGB彩色图像和深度图像&#xff08;Depth Image&#xff09;。 1. RGB彩色图像 数据格式&#xff1a; 标准三通道矩阵&#…

记一次idea中lombok无法使用的解决方案

在注解处理器下&#xff0c;一般 Default 为“启用注解处理”和“从项目类路径获取处理器”&#xff0c;但是我的项目中的为选择“处理器路径”&#xff0c;导致了无法识别lombok&#xff0c;因此&#xff0c;需要改为使用“从项目类路径获取处理器”这个选项。如下图所示&…

贪心算法应用:硬币找零问题详解

贪心算法与硬币找零问题详解 贪心算法&#xff08;Greedy Algorithm&#xff09;在解决优化问题时表现出简洁高效的特点&#xff0c;尤其适用于特定结构的组合优化问题。本文将用2万字篇幅&#xff0c;深入探讨贪心算法在硬币找零问题中的应用&#xff0c;覆盖算法原理、正确性…

深入理解 x86 汇编中的重复前缀:REP、REPZ/REPE、REPNZ/REPNE(进阶详解版)

一、重复前缀&#xff1a;串操作的 “循环加速器” 如果你写过汇编代码&#xff0c;一定遇到过需要重复处理大量数据的场景&#xff1a; 复制 1000 字节的内存块比较两个长达 200 字符的字符串在缓冲区中搜索特定的特征值 手动用loop指令编写循环&#xff1f;代码冗长不说&a…

Docker 在 AI 开发中的实践:GPU 支持与深度学习环境的容器化

人工智能(AI)和机器学习(ML),特别是深度学习,正以前所未有的速度发展。然而,AI 模型的开发和部署并非易事。开发者常常面临复杂的依赖管理(如 Python 版本、TensorFlow/PyTorch 版本、CUDA、cuDNN)、异构硬件(CPU 和 GPU)支持以及环境复现困难等痛点。这些挑战严重阻…

学习NuxtLink标签

我第一次接触这个标签&#xff0c;我都不知道是干嘛的&#xff0c;哈哈哈哈&#xff0c;就是他长得有点像routerLink&#xff0c;所以我就去查了一下&#xff01;哎&#xff01;&#xff01;&#xff01;真是一样的&#xff0c;哈哈哈哈&#xff0c;至少做的事情是一样的&#…

基于PostGIS的GeoTools执行原生SQL查询制图实践-以贵州省行政区划及地级市驻地为例

目录 前言 一、空间相关表简介 1、地市行政区划表 2、地市驻地信息表 3、空间查询检索 二、GeoTools制图实现 1、数据类型绑定 2、WKT转Geometry 3、原生SQL转SimpleFeatureCollection 4、集成调用 5、成果预览 三、总结 前言 在当今这个信息爆炸的时代&#xff0c…