提示词 (Prompt)

引言

在生成式 AI 应用中,Prompt(提示)是与大型语言模型(LLM)交互的核心输入格式。Prompt 的设计不仅决定了模型理解任务的准确度,还直接影响生成结果的风格、长度、结构与可控性。随着模型能力和应用场景的不断丰富,Prompt 的结构也从最初的简单文本演进为支持多角色区分、占位符模板化、工具调用等高级特性。本文将系统梳理 Prompt 的演变历程、角色(Role)分类及职责、Spring AI 中 Prompt API 的详细使用方法,以及 PromptTemplate 的模板化实践,并在每个小节提供详尽的文字说明和代码示例。


一、Prompt 的演变历程

Prompt 的演进大致可分为三个阶段:

1.1 初始阶段:简单字符串

背景与特点
  • 实现方式:直接将用户意图用自然语言表述为一条字符串,传入模型。

  • 示例

    Tell me a joke about cats.
  • 优点:上手门槛低,无需额外框架或结构。

  • 局限:无法提供上下文区分,也难以对输出进行精细控制,适用于单轮、简单的任务。

使用场景
  • 问答类 Chatbot 的一次性查询
  • 单条文本生成,如自动撰写短消息或标语

1.2 占位符与参数化

为什么要参数化?
  • 当同一类任务需要多次调用时,硬编码不同 Prompt 会导致维护成本高。
  • 参数化模板能够通过动态替换变量,提高 Prompt 的复用性和可维护性。
基本示例
String template = "Tell me a {adjective} joke about {topic}.";
String adjective = "silly";
String topic = "robots";
// 使用简单替换实现参数化
String prompt = template.replace("{adjective}", adjective).replace("{topic}", topic);
System.out.println(prompt);
// 输出:Tell me a silly joke about robots.
详细说明
  1. 模板定义:使用 {} 包裹的占位符表示可替换的变量位置。
  2. 动态赋值:在运行时根据业务逻辑提供不同的变量值。
  3. 字符串替换:示例中使用 String.replace 实现,适合简单场景,但无法处理复杂数据类型(如列表、条件逻辑)。
参数化模板的优势
  • 高复用性:一份模板可支持多种输入组合。
  • 易于维护:模板与参数分离,修改模板无需改动调用代码。
  • 结构化:在模板中明确标识可变部分,增强可读性。

1.3 多角色消息流与上下文管理

角色化的必要性

随着对话式应用需求的增长,仅靠单条字符串难以维护多轮对话上下文,也无法区分系统指令与用户输入。引入角色(Role)后,每条消息都可携带角色标签,明确其在对话中的作用。

角色类型
  • SYSTEM:设定对话基调、行为规范或全局约束。
  • USER:真实用户的提问或指令。
  • ASSISTANT:模型的回复,用于记录对话历史和保持连贯性。
  • TOOL:外部工具或函数调用的输入/输出信息。
示例代码
List<Message> messages = new ArrayList<>();// 系统角色:初始化对话规则
messages.add(new SystemMessage("You are a professional travel planner. Provide concise and accurate travel advice."));// 用户角色:用户发起需求
messages.add(new UserMessage("I want to visit Xinjiang in autumn. What do you recommend?"));// 模型角色:占位符,由模型生成后再添加到列表
// messages.add(new AssistantMessage(modelOutput));// 下一轮用户角色:继续提问
// messages.add(new UserMessage("What is the weather forecast there for the next 3 days?"));
详细说明
  1. SystemMessage:通过 new SystemMessage(...) 创建,内容为对模型的全局指令。
  2. UserMessage:通过 new UserMessage(...) 创建,内容为用户输入。
  3. AssistantMessage:模型生成的回复,由程序接收并添加,用于多轮对话。
  4. Role 的作用:模型在生成回复时会根据角色区分系统指令与用户对话,确保响应符合预期。

二、Prompt 中的角色(Role)详解

在 Spring AI 中,MessageType 枚举将角色明确定义为四种类型:

public enum MessageType {SYSTEM("system"),   // 系统指令USER("user"),       // 用户输入ASSISTANT("assistant"), // 模型回复TOOL("tool");       // 工具调用
}

2.1 系统角色(System Role)

  • 主要职责:向模型提供身份设定、业务规则或回答风格。

  • 典型指令

    • “You are a helpful assistant that speaks formally.”
    • “Only answer questions related to legal advice.”
代码示例
Message system = new SystemMessage("You are a financial advisor. Provide concise and accurate investment suggestions in JSON format."
);
扩展说明
  • 可以通过添加元数据(metadata)为系统消息携带额外信息,如时间戳或优先级。
  • 多个 SystemMessage 可按顺序添加,以分阶段设定对话规则。

2.2 用户角色(User Role)

  • 主要职责:传达用户的具体需求或问题。
  • 设计要点:用户消息应清晰、简洁,避免含糊不清的描述。
代码示例
Message user = new UserMessage("Please recommend three budget-friendly hotels in Tokyo for a family of four."
);
扩展说明
  • 可在用户消息中列出多步操作,模型会尝试按顺序执行。
  • 对于复杂查询,建议在一条消息中明确所有必要参数,如时间、人数、预算等。

2.3 助手角色(Assistant Role)

  • 主要职责:承载模型的回复内容,同时可触发工具调用。
  • 触发工具调用:当模型需要执行计算或外部操作时,会在 AssistantMessage 中返回 function_call 字段,表明后续需调用对应工具。
代码示例
// 模型生成的回复示例
Message assistant = new AssistantMessage("The weather in Xinjiang for the next 3 days is:\nDay1: 18°C, sunny\nDay2: 20°C, partly cloudy\nDay3: 17°C, light rain"
);
扩展说明
  • 在接收到 AssistantMessage 后,程序应检查是否存在工具调用请求,并根据 tool_name 和 arguments 调用相应工具。
  • 回复中可包含结构化内容(如 JSON、表格等),便于后续解析。

2.4 工具/功能角色(Tool/Function Role)

  • 主要职责:传递外部工具执行结果,如 API 调用、数据库查询或数学运算。
  • 示例场景:天气查询、汇率转换、订单查询等。
代码示例
// 工具调用返回示例
Message tool = new ToolMessage("{ \"location\": \"Xinjiang\", \"forecast\": [18,20,17] }"
);
扩展说明
  • ToolMessage 的 content 通常为 JSON 格式,程序解析后将结果注入下一次 Prompt。
  • 多个工具调用可串联使用,形成复杂工作流。

三、Spring AI 的 Prompt API 深入

Spring AI 提供了 Prompt 和 Message 等核心类,简化 Prompt 构建与调用流程。以下示例演示完整调用链路,并对关键方法进行详细解读。

3.1 构建 Prompt 实例

// 1. 导入依赖:确保已引入 spring-ai 相关库// 2. 构建消息列表
List<Message> messages = new ArrayList<>();
messages.add(system);
messages.add(user);// 3. 创建 Prompt 对象
Prompt prompt = new Prompt(messages)// 4. 可选:设置 ChatOptions,如温度、最大 Token.options(ChatOptions.builder().temperature(0.5).maxTokens(500).build());
详细说明
  1. 消息列表初始化:使用 ArrayList 存储各角色消息,顺序决定 Prompt 的上下文顺序。
  2. Prompt 构造函数new Prompt(List<Message>) 将消息列表复制到内部。
  3. 链式调用:通过 options(...) 方法设置模型参数,如温度(temperature)控制随机性,maxTokens 控制最大生成长度。

3.2 调用 ChatModel

// 5. 使用 ChatModel 或 ChatClient 发起调用
ChatResponse response = chatModel.call(prompt);// 6. 解析响应
String reply = response.getResult().getOutput().getContent();
System.out.println("Assistant: " + reply);
详细说明
  • ChatModel.call():接收 Prompt,发送给底层 LLM 服务,并返回 ChatResponse
  • ChatResponse:封装模型生成的所有输出,包括文本、工具调用请求、Usage 信息等。
  • getResult().getOutput().getContent():提取生成文本内容。

3.3 动态添加消息

在多轮对话中,可根据上一轮回复动态添加消息:

// 上一轮回复添加为 AssistantMessage
messages.add(new AssistantMessage(reply));// 下一轮用户输入
messages.add(new UserMessage("Thank you. Can you also suggest local cuisines?"));// 重新构建并调用 Prompt
Prompt nextPrompt = new Prompt(messages);
ChatResponse nextResp = chatModel.call(nextPrompt);
详细说明
  • 将模型回复添加到消息列表,保证上下文连贯性。
  • 新的用户消息与历史消息一起传入,模型能够参考整个对话历史。

四、PromptTemplate:高级模板化设计

当 Prompt 逻辑复杂、参数众多时,手动拼接字符串或管理消息列表容易出错。PromptTemplate 基于 StringTemplate 引擎提供了灵活的模板化方案。

public class PromptTemplate implements PromptTemplateActions, PromptTemplateMessageActions {private final String template;public PromptTemplate(String template) {this.template = template;}// render/create 方法由接口提供,具体由 StringTemplate 引擎实现
}

4.1 渲染为纯文本

// 无参数模板
PromptTemplate staticTpl = new PromptTemplate("List three facts about the moon.");
String staticPrompt = staticTpl.render();
// staticPrompt == "List three facts about the moon."// 带参数模板
PromptTemplate paramTpl = new PromptTemplate("List three {adjective} facts about the {subject}.");
String dynamicPrompt = paramTpl.render(Map.of("adjective", "interesting","subject", "moon"
));
// dynamicPrompt == "List three interesting facts about the moon."
详细说明
  • render():直接输出模板内容,适用于静态 Prompt。
  • render(Map):根据键值对替换占位符,适用于简单参数化需求。

4.2 生成 Message 对象

// 仅文本消息
Message msg1 = paramTpl.createMessage(Map.of("adjective", "funny","subject", "penguins"
));
// msg1.getContent() -> "List three funny facts about the penguins."
// 默认角色为 USER,可通过重载指定其他角色
详细说明
  • createMessage(Map):将渲染后的文本封装为 UserMessage,简化消息构建流程。
  • 也可使用重载方法传入媒体列表(图片、音频等),扩展多模态能力。

4.3 生成完整 Prompt

// 创建带系统和用户消息的模板
String tpl = "<system>You are {role}.</system>" +"<user>Summarize the following text: {text}</user>";
PromptTemplate fullTpl = new PromptTemplate(tpl);Map<String,Object> data = Map.of("role", "an academic writer","text", "Artificial intelligence is transforming industries..."
);// 生成 Prompt 并设置选项
Prompt fullPrompt = fullTpl.create(data).options(ChatOptions.builder().maxTokens(200).build());ChatResponse fullResp = chatModel.call(fullPrompt);
System.out.println(fullResp.getResult().getOutput().getContent());
详细说明
  • 模板标签:使用 <system><user> 标签将渲染内容分配给不同角色。
  • create(Map):渲染并拆分消息为多条 Message,并封装为 Prompt
  • options(...):为该 Prompt 单独设置模型参数。

五、进阶用法与最佳实践

  1. 分层组织 Prompt

    • 将不同职责的消息(系统、用户、助手、工具)分层组织,保持清晰的调用链路。
    • 例如,先添加所有系统级指令,再添加用户级查询,最后再执行工具调用。
  2. 语义化占位符

    • 使用有意义的占位符名称,如 {userName}{startDate},提高模板可读性和可维护性。
  3. 模板管理

    • 将常用 PromptTemplate 存储在配置文件或数据库中,支持在线更新和版本控制。
    • 结合 CI/CD 流程,实现模板自动化测试与回滚。
  4. 工具调用预留

    • 在模板中预先定义工具调用点,如 Please fetch current weather via function_call.
    • 模型在生成时会自动触发 function_call,程序接收后执行相应工具。
  5. 性能与成本控制

    • 缓存静态 Prompt 或已渲染模板,减少重复渲染开销。
    • 控制消息列表长度,定期对历史对话进行摘要或清理,避免超出模型上下文窗口。
  6. 安全与合规

    • 对用户输入进行校验和清洗,避免注入恶意指令。
    • 记录 Prompt 与响应日志,确保可审计、可追溯。

六、总结

Prompt 设计是生成式 AI 应用的基础,直接影响模型的行为和输出质量。通过理解 Prompt 的演变历程、合理划分角色、熟练使用 Spring AI 提供的 Prompt API 与 PromptTemplate 工具,开发者可以构建出灵活、高效且易维护的对话系统。结合最佳实践,您将能够在各类业务场景中充分发挥 LLM 的潜力,为用户带来流畅、智能的交互体验。


本文示例基于 Spring AI 框架及 StringTemplate 引擎,旨在为开发者提供系统的 Prompt 设计指导。

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

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

相关文章

十二、C++速通秘籍—静态库,动态库

上一章节&#xff1a; 十一、C速通秘籍—多线程-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/147055932?spm1001.2014.3001.5502 本章节代码&#xff1a; cpp2/library CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppst…

什么是继承?js中有哪儿些继承?

1、什么是继承&#xff1f; 继承是面向对象软件技术中的一个概念。 2、js中有哪儿些继承&#xff1f; js中的继承有ES6的类class的继承、原型链继承、构造函数继承、组合继承、寄生组合继承。 2.1 ES6中类的继承 class Parent {constructor() {this.age 18;} }class Chil…

Linux进程通信入门:匿名管道的原理、实现与应用场景

Linux系列 文章目录 Linux系列前言一、进程通信的目的二、进程通信的原理2.1 进程通信是什么2.2 匿名管道通讯的原理 三、进程通讯的使用总结 前言 Linux进程间同通讯&#xff08;IPC&#xff09;是多个进程之间交换数据和协调行为的重要机制&#xff0c;是我们学习Linux操作系…

探秘Transformer系列之(26)--- KV Cache优化 之 PD分离or合并

探秘Transformer系列之&#xff08;26&#xff09;— KV Cache优化 之 PD分离or合并 文章目录 探秘Transformer系列之&#xff08;26&#xff09;--- KV Cache优化 之 PD分离or合并0x00 概述0x01 背景知识1.1 自回归&迭代1.2 KV Cache 0x02 静态批处理2.1 调度策略2.2 问题…

十大PDF解析工具在不同文档类别中的比较研究

PDF解析对于包括文档分类、信息提取和检索在内的多种自然语言处理任务至关重要&#xff0c;尤其是RAG的背景下。尽管存在各种PDF解析工具&#xff0c;但它们在不同文档类型中的有效性仍缺乏充分研究&#xff0c;尤其是超出学术文档范畴。通过使用DocLayNet数据集&#xff0c;比…

HarmonyOS-ArkUI 装饰器V2 @ObservedV2与@Trace装饰器

参考文档: 文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-new-observedv2-and-trace-V14#trace%E8%A3%85%E9%A5%B0%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84由于V2的装饰器比V1的装饰器更加易用,尽管学习的过程中用到的都是V1的装饰器,但…

GPT - GPT(Generative Pre-trained Transformer)模型框架

本节代码主要为实现了一个简化版的 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型。GPT 是一种基于 Transformer 架构的语言生成模型&#xff0c;主要用于生成自然语言文本。 1. 模型结构 初始化部分 class GPT(nn.Module):def __init__(self, vocab…

基于FPGA的六层电梯智能控制系统 矩阵键盘-数码管 上板仿真均验证通过

基于FPGA的六层电梯智能控制系统 前言一、整体方案二、软件设计总结 前言 本设计基于FPGA实现了一个完整的六层电梯智能控制系统&#xff0c;旨在解决传统电梯控制系统在别墅环境中存在的个性化控制不足、响应速度慢等问题。系统采用Verilog HDL语言编程&#xff0c;基于Cyclo…

车载通信系统中基于ISO26262的功能安全与抗辐照协同设计研究

摘要&#xff1a;随着智能网联汽车的快速发展&#xff0c;车载通信系统正面临着功能安全与抗辐照设计的双重挑战。在高可靠性要求的车载应用场景下&#xff0c;如何实现功能安全标准与抗辐照技术的协同优化&#xff0c;构建满足ISO26262安全完整性等级要求的可靠通信架构&#…

Node.js种cluster模块详解

Node.js 中 cluster 模块全部 API 详解 1. 模块属性 const cluster require(cluster);// 1. isMaster // 判断当前进程是否为主进程 console.log(是否为主进程:, cluster.isMaster);// 2. isWorker // 判断当前进程是否为工作进程 console.log(是否为工作进程:, cluster.isW…

融合动态权重与抗刷机制的网文评分系统——基于优书网、IMDB与Reddit的混合算法实践

✨ Yumuing 博客 &#x1f680; 探索技术的每一个角落&#xff0c;解码世界的每一种可能&#xff01; &#x1f48c; 如果你对 AI 充满好奇&#xff0c;欢迎关注博主&#xff0c;订阅专栏&#xff0c;让我们一起开启这段奇妙的旅程&#xff01; 以权威用户为核心&#xff0c;时…

使用Golang打包jar应用

文章目录 背景Go 的 go:embed 功能介绍与打包 JAR 文件示例1. go:embed 基础介绍基本特性基本语法 2. 嵌入 JAR 文件示例项目结构代码实现 3. 高级用法&#xff1a;嵌入多个文件或目录4. 使用注意事项5. 实际应用场景6. 完整示例&#xff1a;运行嵌入的JAR 背景 想把自己的一个…

前端大屏可视化项目 局部全屏(指定盒子全屏)

需求是这样的&#xff0c;我用的项目是vue admin 项目 现在需要在做大屏项目 不希望显示除了大屏的其他东西 于是想了这个办法 至于大屏适配问题 请看我文章 底部的代码直接复制就可以运行 vue2 px转rem 大屏适配方案 postcss-pxtorem-CSDN博客 <template><div …

《2025蓝桥杯C++B组:D:产值调整》

**作者的个人gitee**​​ 作者的算法讲解主页▶️ 每日一言&#xff1a;“泪眼问花花不语&#xff0c;乱红飞过秋千去&#x1f338;&#x1f338;” 题目 二.解题策略 本题比较简单&#xff0c;我的思路是写三个函数分别计算黄金白银铜一次新产值&#xff0c;通过k次循环即可获…

[VTK] 四元素实现旋转平移

VTK 实现旋转&#xff0c;有四元数的方案&#xff0c;也有 vtkTransform 的方案&#xff1b;主要示例代码如下&#xff1a; //构造旋转四元数vtkQuaterniond rotation;rotation.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(90.0),0.0, 1.0, 0.0);//构造旋转点四元数v…

华为hcie证书的有效期怎么判断?

在ICT行业&#xff0c;华为HCIE证书堪称含金量极高的“敲门砖”&#xff0c;拥有它往往意味着在职场上更上一层楼。然而&#xff0c;很多人在辛苦考取HCIE证书后&#xff0c;却对其有效期相关事宜一知半解。今天&#xff0c;咱们就来好好唠唠华为HCIE证书的有效期怎么判断这个关…

【精品PPT】2025固态电池知识体系及最佳实践PPT合集(36份).zip

精品推荐&#xff0c;2025固态电池知识体系及最佳实践PPT合集&#xff0c;共36份。供大家学习参考。 1、中科院化学所郭玉国研究员&#xff1a;固态金属锂电池及其关键材料.pdf 2、中科院物理所-李泓固态电池.pdf 3、全固态电池技术研究进展.pdf 4、全固态电池生产工艺.pdf 5、…

MySQL 中为产品添加灵活的自定义属性(如 color/size)

方案 1&#xff1a;EAV 模型&#xff08;最灵活但较复杂&#xff09; 适合需要无限扩展自定义属性的场景 -- 产品表 CREATE TABLE products (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100),price DECIMAL(10,2) );-- 属性名表 CREATE TABLE attributes (id INT PRIMA…

CSPM认证对项目论证的范式革新:从合规审查到价值创造的战略跃迁

引言 在数字化转型浪潮中&#xff0c;全球企业每年因项目论证缺陷导致的损失高达1.7万亿美元&#xff08;Gartner 2023&#xff09;。CSPM&#xff08;Certified Strategic Project Manager&#xff09;认证体系通过结构化方法论&#xff0c;将传统的项目可行性评估升级为战略…

CLIP中的Zero-Shot Learning原理

CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09;是一种由OpenAI提出的多模态模型&#xff0c;它通过对比学习的方式同时学习图像和文本的表示&#xff0c;并且能在多种任务中进行零样本学习&#xff08;Zero-Shot Learning&#xff09;。CLIP模型的核心创…