Prompt 提示词详解
简介
提示词(Prompt) 是指向 AI 模型提供的输入信息,用于指导模型生成特定的输出。提示词可以是问题、命令、描述、上下文信息等,目的是引导模型按照用户的期望提供有意义、相关或准确的答案。
提示词的设计原则
提示词优化示例
优化前: "给我讲讲spring ai"
优化后的提示词: " 我是一个ai小白, 有着 java 的基础知识, 给我讲一下spring ai, 说说它和以前的 spring 有哪些不同, 我怎么快速上手, 再讲讲它的优势和不足"
提示词模板设计
提示词的基本结构: 角色+指令+上下文+输入数据+输出格式+约束条件+示例。
- 指令(Instruction):定义 AI 的角色和任务。
- 上下文(Context):为 AI 提供背景信息,帮助生成更相关的内容。
- 输入数据(Input Data):具体的用户输入。
- 输出格式(Output Format):约束 AI 的输出。
- 约束条件(Constraints):对生成内容施加限制。
- 示例(Examples):提供参考回答,帮助模型理解预期。
示例:
你是一个资深程序员,
请你回答我接下来的问题,
我最近在学习spring ai,
请给我讲讲关于如何对接到OpenAi,
要求代码必须准确, 能直接拷贝运行,
例如xxxx,
代码请用 java 输出.
Spring AI Prompt 介绍
Prompt
类是 Spring AI 提供的一个封装,用于定义与 AI 模型交互时的请求结构。通过 Prompt,你可以规范化对话的输入输出,控制 AI 的响应行为和格式。
基础用法:
Prompt 提示词
代码示例:
Prompt prompt = new Prompt("请给我将一个笑话");
chatClient.prompt(prompt).call().content();
ChatOptions
字段解释:
字段 | 字段类型 | 解释 | 作用 | 示例值/取值范围 |
model | sring | Ai模型版本 | gpt-3.5-turbo | |
frequencyPenalty | double | 控制生成时对重复词的惩罚程度 | 用于防止生成内容中出现过多重复性描述 | [-2.0, 2.0], 值越大, 重复性越低 |
maxTokens | integer | 控制生成的最大字符数或词数(tokens 数量) | 用于限制模型生成内容的长度,避免输出过长的文本 | 200 |
presencePenalty | double | 对新话题的偏好 | 适合用于需要更具创意或广泛探索的生成任务 | [-2.0, 2.0], 值越大, 创新性更强 |
StopSequences | List | 设置生成结束的触发条件 | 当生成内容中出现指定的字符串时,模型会停止生成, 用于控制长度 | \n, END |
temperature | double | 控制生成文本的随机性 | [0.0, 1.0] 值越高(接近 1),生成的文本越多样化、更具创意,词的选择会更加随机 | |
topK | integer | 取生成文本的前xx个 | ||
topP | double | 采样范围 | top-p 与 temperature 可搭配使用 | [0.0, 1.0]
|
代码示例:
ChatOptions chatOptions = ChatOptions.builder()
.model("gpt-3.5-turbo")
.temperature(0.7)
.maxTokens(100)
.frequencyPenalty(0.5)
.presencePenalty(0.5)
.topK(50)
.topP(0.7)
.stopSequences(List.of("end"))
.build();
PromptTemplate 提示词模板
PromptTemplate能够帮助我们创建结构化提示词,是Spring AI提示词工程中的关键组件,提示词模板采用占位符的方式,通过格式化的提问,规避ai回答随机性问题。
该类实现了三个接口:PromptTemplateStringActions、PromptTemplateActions和PromptTemplateMessageActions,这些接口的主要功能也有所不同:
代码示例:
String template = """
请告诉我{author}最受欢迎的书是哪本?什么时间出版的?书的内容描述了什么?
""";
PromptTemplate promptTemplate = new PromptTemplate(template);
Prompt prompt = promptTemplate.create(Map.of("author", author));
String content = chatClient.prompt(prompt).call().content();
响应结果:
刘慈欣最受欢迎的书是《三体》(The Three-Body Problem),2008年首次出版,《三体》是一部硬科幻小说,讲述了人类在接触到一个神秘的外星文明“三体文明”后,面临的生存与发展危机。
BeanOutputConverter 输出对象转换器
虽然上面的ai回答了我们的问题, 但是如果我们想处理响应数据却比较难,因为响应数据没有进行统一的格式化。例如我们想做数据入库的时候,还需要解析响应内容。
好在spiring ai 已经提供了相关的能力。下面是代码示例:
/**
* 定义book对象
*/
@Data
public class BookResponse {
private String bookName;
private String authorName;
private String publishDate;
private String description;
}
public BookResponse promptTemplateChat(String author) {
String template = """
请告诉我{author}最受欢迎的书是哪本?什么时间出版的?书的内容描述了什么?
{format}
""";
// 构造 转换器对象
BeanOutputConverter<BookResponse> converter = new BeanOutputConverter<>(BookResponse.class);
PromptTemplate promptTemplate = new PromptTemplate(template);
Prompt prompt = promptTemplate.create(Map.of(
"author", author,
"format", converter.getFormat()
));
log.info("prompt: {}", prompt);
String content = sensenovaChatClient.prompt(prompt).call().content();
// 解析返回的结果
BookResponse book = converter.convert(content);
return book;
之所以能返回对象格式, 是因为 convert中的getFormat()方法指定了返回格式:
日志查看提问内容 :prompt 格式:
{messages=[UserMessage{content=' 请告诉我刘慈欣最受欢迎的书是哪本?什么时间出版的?书的内容描述了什么?
Your response should be in JSON format.
Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.
Do not include markdown code blocks in your response.
Remove the ```json markdown from the output.
Here is the JSON Schema instance your output must adhere to:
```{
"$schema" : "https://json-schema.org/draft/2020-12/schema",
"type" : "object",
"properties" : {
"authorName" : {
"type" : "string"
},
"bookName" : {
"type" : "string"
},
"description" : {
"type" : "string"
},
"publishDate" : {
"type" : "string"
}
},
"additionalProperties" : false
}```
', properties={messageType=USER}, messageType=USER}], modelOptions=null}
输出结果:
{
"authorName": "刘慈欣",
"bookName": "三体",
"description": "《三体》是刘慈欣创作的科幻小说,讲述了地球文明与外星文明三体文明的首次接触和交流,以及之后两个文明间的冲突与战争。",
"publishDate": "2008年"
}