Spring AI 系列3: Promt提示词

一、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> {@OverrideString 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.pswp.cn/bicheng/82944.shtml

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

相关文章

随叫随到的电力补给:移动充电服务如何重塑用户体验?

在快节奏的现代生活中&#xff0c;电力已成为维系日常运转的隐形血脉。智能手机、电动汽车、便携设备的普及&#xff0c;让“电量焦虑”逐渐演变为一种时代症候。而移动充电服务的兴起&#xff0c;正悄然改变这一局面。它像一位隐形的能源管家&#xff0c;随时响应需求&#xf…

LeetCode 75. 颜色分类 - 双指针法高效解决(Java实现)

文章目录 问题描述算法思路&#xff1a;三指针分区法核心思想指针定义 Java实现算法执行流程关键问题解析&#xff1a;为什么交换0后不需要重新检查&#xff1f;交换0时的两种情况分析详细解释&#xff1a; 复杂度分析示例演示&#xff08;输入&#xff1a;[2,0,2,1,1,0]&#…

【MySQL】C语言连接

要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去官网下载 我们使用C接口库来进行连接 要正确使用&#xff0c;我们需要做一些准备工作: 保证mysql服务有效在官网上下载合适自己平台的mysql connect库&#xff0c;以备后用 下载开发库 s…

NFS 挂载配置与优化最佳实践指南

文章目录 NFS 挂载配置与优化最佳实践指南1. 服务器端配置1.1 安装 NFS 服务1.2 配置共享目录常用配置选项说明 1.3 启动与检查服务 2. 客户端挂载2.1 安装 NFS 客户端2.2 挂载 NFS 共享2.3 自动挂载 3. 客户端挂载选项4. 性能优化与故障排查4.1 性能优化建议4.2 常见问题排查 …

3D PDF如何制作?SOLIDWORKS MBD模板定制技巧

SOLIDWORKS制作3D PDF模版 SOLIDWORKS MBD能够帮助工程师以清晰直观的方式描述产品尺寸信息。在3D PDF文件中&#xff0c;用户可以自由旋转和移动视图&#xff0c;方便查看模型的各个尺寸细节。 本文将带您一步步学习如何使用SOLIDWORKS MBD制作专业的3D PDF模板&#xff0c;…

Unity-QFramework框架学习-MVC、Command、Event、Utility、System、BindableProperty

QFramework QFramework简介 QFramework是一套渐进式、快速开发框架&#xff0c;适用于任何类型的游戏及应用项目&#xff0c;它包含一套开发架构和大量的工具集 QFramework的特性 简洁性&#xff1a;QFramework 强调代码的简洁性和易用性&#xff0c;让开发者能够快速上手&a…

R3GAN训练自己的数据集

简介 简介&#xff1a;这篇论文挑战了"GANs难以训练"的广泛观点&#xff0c;通过提出一个更稳定的损失函数和现代化的网络架构&#xff0c;构建了一个简洁而高效的GAN基线模型R3GAN。作者证明了通过合适的理论基础和架构设计&#xff0c;GANs可以稳定训练并达到优异…

【PhysUnits】15.1 引入P1后的加一特质(add1.rs)

一、源码 代码实现了类型系统中的"加一"操作&#xff08;Add1 trait&#xff09;&#xff0c;用于在编译期进行数字的增量计算。 //! 加一操作特质实现 / Increment operation trait implementation //! //! 说明&#xff1a; //! 1. Z0、P1,、N1 1&#xff0…

记录算法笔记(2025.5.29)最小栈

设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int get…

Android高级开发第一篇 - JNI(初级入门篇)

文章目录 Android高级开发JNI开发第一篇&#xff08;初级入门篇&#xff09;&#x1f9e0; 一、什么是 JNI&#xff1f;✅ 为什么要用 JNI&#xff1f; ⚙️ 二、开发环境准备开发工具 &#x1f680; 三、创建一个支持 JNI 的 Android 项目第一步&#xff1a;创建新项目项目结构…

PyTorch Image Models (timm) 技术指南

timm PyTorch Image Models (timm) 技术指南功能概述 一、引言二、timm 库概述三、安装 timm 库四、模型加载与推理示例4.1 通用推理流程4.2 具体模型示例4.2.1 ResNeXt50-32x4d4.2.2 EfficientNet-V2 Small 模型4.2.3 DeiT-3 large 模型4.2.4 RepViT-M2 模型4.2.5 ResNet-RS-1…

openEuler安装MySql8(tar包模式)

操作系统版本&#xff1a; openEuler release 22.03 (LTS-SP4) MySql版本&#xff1a; 下载地址&#xff1a; https://dev.mysql.com/downloads/mysql/ 准备安装&#xff1a; 关闭防火墙&#xff1a; 停止防火墙 #systemctl stop firewalld.service 关闭防火墙 #systemc…

从零开始的数据结构教程(六) 贪心算法

&#x1f36c; 标题一&#xff1a;贪心核心思想——发糖果时的最优分配策略 贪心算法 (Greedy Algorithm) 是一种简单直观的算法策略。它在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望得到一个全局最优解。这就像你…

CPP中CAS std::chrono 信号量与Any类的手动实现

前言 CAS&#xff08;Compare and Swap&#xff09; 是一种用于多线程同步的原子指令。它通过比较和交换操作来确保数据的一致性和线程安全性。CAS操作涉及三个操作数&#xff1a;内存位置V、预期值E和新值U。当且仅当内存位置V的值与预期值E相等时&#xff0c;CAS才会将内存位…

Axure设计案例——科技感对比柱状图

想让数据对比展示摆脱平淡无奇&#xff0c;瞬间抓住观众的眼球吗&#xff1f;那就来看看这个Axure设计的科技感对比柱状图案例&#xff01;科技感设计风格运用独特元素打破传统对比柱状图的常规&#xff0c;营造出一种极具冲击力的视觉氛围。每一组柱状体都仿佛是科技战场上的士…

怒更一波免费声音克隆和AI配音功能

宝子们&#xff01; 最近咱软件TransDuck的免费声音克隆和AI配音功能被大家用爆啦&#xff01;感谢各位自来水疯狂安利&#xff01;&#xff01; DD这里也是收到好多用户提的宝贵建议&#xff01;所以&#xff0c;连夜肝了波更新&#xff01; 这次重点更新使用克隆音色进行A…

UDP协议原理与Java编程实战:无连接通信的奥秘

1.UDP协议核心原理 1. 无连接特性&#xff1a;快速通信的基石 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是TCP/IP协议族中无连接的轻量级传输层协议。与TCP的“三次握手”建立连接不同&#xff0c;UDP通信无需提前建立链路&#xff0c;发送…

vue-seamless-scroll 结束从头开始,加延时后滚动

今天遇到一个大屏需求&#xff1a; 1️⃣初始进入页面停留5秒&#xff0c;然后开始滚动 2️⃣最后一条数据出现在最后一行时候暂停5秒&#xff0c;然后返回1️⃣ 依次循环&#xff0c;发现vue-seamless-scroll的方法 ScrollEnd是监测最后一条数据消失在第一行才回调&#xff…

[Protobuf] 快速上手:安全高效的序列化指南

标题&#xff1a;[Protobuf] (1)快速上手 水墨不写bug 文章目录 一、什么是protobuf&#xff1f;二、protobuf的特点三、使用protobuf的过程&#xff1f;1、定义消息格式&#xff08;.proto文件&#xff09;(1)指定语法版本(2)package 声明符 2、使用protoc编译器生成代码&…

uniapp调用java接口 跨域问题

前言 之前在Windows10本地 调试一个旧项目&#xff0c;手机移动端用的是Uni-app&#xff0c;vue的版本是v2。后端是java spring-boot。运行手机移动端的首页请求后台接口老是提示错误信息。 错误信息如下&#xff1a; Access to XMLHttpRequest at http://localhost:8080/api/…