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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82944.shtml
英文地址,請注明出處:http://en.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/…