文章目录
- [1. 提示词工程](#1. 提示词工程)
-
- [1.1 定义](#1.1 定义)
- [1.2 为什么需要提示词工程?](#1.2 为什么需要提示词工程?)
- [1.3 提示词工程的核心理念](#1.3 提示词工程的核心理念)
- [1.4 本指南的阅读路线](#1.4 本指南的阅读路线)
- [2. LLM 配置](#2. LLM 配置)
-
- [2.1 LLM 提供商选择](#2.1 LLM 提供商选择)
- [2.2 LLM 输出参数配置](#2.2 LLM 输出参数配置)
-
- [2.2.1 Temperature(温度)](#2.2.1 Temperature(温度))
- [2.2.2 MaxTokens(最大输出长度)](#2.2.2 MaxTokens(最大输出长度))
- [2.2.3 Top-K 与 Top-P(采样控制)](#2.2.3 Top-K 与 Top-P(采样控制))
- [2.2.4 结构化响应格式(Entity Mapping)](#2.2.4 结构化响应格式(Entity Mapping))
- [2.2.5 模型专用配置](#2.2.5 模型专用配置)
- [3. Prompt Engineering 核心技法](#3. Prompt Engineering 核心技法)
-
- [3.1 Zero-Shot 零样本提示](#3.1 Zero-Shot 零样本提示)
- [3.2 One-Shot & Few-Shot 少样本提示](#3.2 One-Shot & Few-Shot 少样本提示)
- [3.3 系统提示、角色提示与上下文提示](#3.3 系统提示、角色提示与上下文提示)
-
- [3.3.1 系统提示(System Prompting)](#3.3.1 系统提示(System Prompting))
- [3.3.2 角色提示(Role Prompting)](#3.3.2 角色提示(Role Prompting))
- [3.3.3 上下文提示(Contextual Prompting)](#3.3.3 上下文提示(Contextual Prompting))
- [3.4 Step-Back 回溯提示](#3.4 Step-Back 回溯提示)
- [3.5 Chain of Thought (CoT) 思维链](#3.5 Chain of Thought (CoT) 思维链)
-
- [3.5.1 Zero-Shot CoT](#3.5.1 Zero-Shot CoT)
- [3.5.2 Few-Shot CoT](#3.5.2 Few-Shot CoT)
- [3.6 Self-Consistency 自洽性](#3.6 Self-Consistency 自洽性)
- [3.7 Tree of Thoughts (ToT) 思维树](#3.7 Tree of Thoughts (ToT) 思维树)
- [3.8 自动提示工程](#3.8 自动提示工程)
- [3.9 代码提示](#3.9 代码提示)
-
- [3.9.1 编写代码](#3.9.1 编写代码)
- [3.9.2 解释代码](#3.9.2 解释代码)
- [3.9.3 代码翻译](#3.9.3 代码翻译)
- [4. 总结](#4. 总结)
1. 提示词工程
1.1 定义
提示词工程(
Prompt Engineering) 是一门关于如何设计、编写和优化 输入给大型语言模型(LLM)的提示词(Prompt),以引导模型产出更准确、更可靠、更符合预期的输出的经验学科。
简单来说:LLM 就像一位知识渊博但需要精确指令的助手 ------ 你如何提问 ,直接决定了它能给你多好的答案 。同样的模型,不同的提示词写法,效果可能天差地别。这条规律几乎适用于所有 LLM 应用场景:分类、摘要、翻译、问答、代码生成、创意写作......
举个例子,当你直接对模型说:
"这篇文章表达了什么情绪?"
你可能会得到一个啰嗦的、模棱两可的回复。但如果你这样写:
"将以下影评分类为
POSITIVE、NEUTRAL或NEGATIVE。仅返回标签。"
模型会直接给出一个干净的、可解析的结果。这就是提示词工程的价值所在。
1.2 为什么需要提示词工程?
| 痛点 | 提示词工程的解法 |
|---|---|
| 模型输出不稳定,每次结果不一样 | 调低 Temperature + 明确的格式约束 |
| 模型"瞎编"(幻觉) | 提供上下文 + 引用约束 + Few-Shot 示例 |
| 复杂推理结果不正确 | 使用 Chain of Thought(思维链)让其逐步推理 |
| 输出格式难以解析 | System Prompt 指定 JSON 输出 + 结构化映射 |
| 同一类问题反复调优很累 | 使用自动提示工程(APE)让 AI 自己优化 Prompt |
1.3 提示词工程的核心理念
提示词工程不是"碰运气式"地试各种说法,而是一套有章可循的系统性方法论。其核心理念可以归纳为三条原则:
- 明确性(Clarity):指令要具体、无歧义。不要指望模型"猜"你的意图。
- 结构性(Structure) :善用
System Prompt(全局指令)、User Prompt(具体任务)、Context(背景信息)三层架构来组织信息。 - 迭代性(Iteration) :好的
Prompt是试出来的。从简单开始,观察输出,逐步添加约束、示例和格式要求。
1.4 本指南的阅读路线
本文将理论与实践结合,按以下路线展开:
- 第 2 章 ------
LLM配置 :在写Prompt之前,先了解如何配置模型参数(Temperature、MaxTokens、Top-K/Top-P等),它们与Prompt的效果密不可分。 - 第 3 章 ------ 九大核心技法 :逐一讲解
Zero-Shot、Few-Shot、系统/角色/上下文提示、Step-Back、CoT、Self-Consistency、ToT、自动提示工程、代码提示,每项技法都配有可运行的Java代码示例。 - 第 4 章 ------ 总结与最佳实践:一张对比表 + 五条生产环境黄金法则。
- 第 5 章 ------ 参考文献:所有技法对应的原始论文链接,方便深入研读。
💡 本文特色 :所有示例代码均使用
Spring AI的ChatClientAPI编写,展示了如何将提示词工程理论落地为生产级Java代码。
2. LLM 配置
在深入 Prompt Engineering 技法之前,首先要学会如何与大型语言模型(LLM)"对话"。Spring AI 为我们提供了一整套配置 LLM 的机制,涵盖模型选型与关键生成参数调优。
2.1 LLM 提供商选择
Spring AI 支持多种 LLM 提供商(如 OpenAI、Anthropic、Google Vertex AI、AWS Bedrock、Ollama 等),让你无需修改业务代码即可切换模型 ------ 只需更改配置即可。
只需添加对应的 Starter 依赖 spring-ai-starter-model-<MODEL-PROVIDER-NAME>。例如,启用 Anthropic Claude API:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-anthropic</artifactId>
</dependency>
指定 LLM 模型名称:
java
.options(ChatOptions.builder()
.model("claude-3-7-sonnet-latest") // 使用 Anthropic Claude 模型
.build())
📖 更多模型接入细节可查阅 Spring AI 参考文档。
2.2 LLM 输出参数配置
Spring AI 通过 ChatOptions Builder 提供了丰富的生成控制选项。下面逐一说明关键参数。
2.2.1 Temperature(温度)
控制模型输出的随机性 与创造性:
| 温度值 | 特性 | 适用场景 |
|---|---|---|
0.0~0.3(低) |
确定性高,输出聚焦 | 事实问答、分类任务、需高一致性的场景 |
0.4~0.7(中) |
确定性与创意兼顾 | 通用对话场景 |
0.8~1.0(高) |
富有创造力,结果多变 | 创意写作、头脑风暴、多样性生成 |
java
.options(ChatOptions.builder()
.temperature(0.1) // 极低温度,输出高度确定性
.build())
2.2.2 MaxTokens(最大输出长度)
限制模型单次生成的最大 Token 数量(Token ≈ 词/子词):
- 短(
5-25):适用于单词、短语或分类标签。 - 中(
50-500):适用于段落或简要说明。 - 长(
1000+):适用于长文、故事或复杂解释。
java
.options(ChatOptions.builder()
.maxTokens(250) // 中等长度响应
.build())
2.2.3 Top-K 与 Top-P(采样控制)
精细控制生成过程中的 Token 选择:
Top-K:将候选Token限制在概率最高的K个中。K值越大,多样性越高(常用40~50)。Top-P(核采样):从累计概率超过P的最小Token集合中动态采样。常用值0.8~0.95。
java
.options(ChatOptions.builder()
.topK(40) // 仅考虑概率最高的 40 个 Token
.topP(0.8) // 从覆盖 80% 概率质量的 Token 中采样
.build())
2.2.4 结构化响应格式(Entity Mapping)
除了纯文本响应(.content()),Spring AI 还能直接将 LLM 返回的内容映射为 Java 对象(通过 .entity()):
java
enum Sentiment {
POSITIVE, NEUTRAL, NEGATIVE
}
Sentiment result = chatClient.prompt("...")
.call()
.entity(Sentiment.class);
当配合
System Prompt指示模型返回结构化数据时,此功能尤其强大。
2.2.5 模型专用配置
ChatOptions 提供了跨供应商 的统一接口,同时 Spring AI 也提供了各模型专用的选项类,暴露特定供应商的独特能力:
OpenAI 专用参数:
java
OpenAiChatOptions openAiOptions = OpenAiChatOptions.builder()
.model("gpt-4o")
.temperature(0.2)
.frequencyPenalty(0.5) // OpenAI 频次惩罚
.presencePenalty(0.3) // OpenAI 存在惩罚
.responseFormat(new ResponseFormat("json_object")) // JSON 模式
.seed(42) // 确定性生成
.build();
String result = chatClient.prompt("...")
.options(openAiOptions)
.call()
.content();
Anthropic 专用参数:
java
AnthropicChatOptions anthropicOptions = AnthropicChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(0.2)
.topK(40) // Anthropic Top-K
.thinking(AnthropicApi.ThinkingType.ENABLED, 1000) // 深度思考配置
.build();
String result = chatClient.prompt("...")
.options(anthropicOptions)
.call()
.content();
⚠️ 使用模型专用配置时,代码将与特定供应商绑定,丧失可移植性。这是一个高级特性 vs 供应商独立性之间的权衡。
3. Prompt Engineering 核心技法
下面逐一实现 Prompt Engineering Guide 中的核心技法,理论与实践并重。
3.1 Zero-Shot 零样本提示
概念 :不给任何示例,直接让模型完成任务。LLM 在海量文本上训练,已内化了"翻译""摘要""分类"等概念,无需额外演示。
适用场景 :任务定义清晰、示例编写成本高、希望保持 Prompt 简洁。
java
public void pt_zero_shot(ChatClient chatClient) {
enum Sentiment {
POSITIVE, NEUTRAL, NEGATIVE
}
Sentiment reviewSentiment = chatClient.prompt("""
Classify movie reviews as POSITIVE, NEUTRAL or NEGATIVE.
Review: "Her" is a disturbing study revealing the direction
humanity is headed if AI is allowed to keep evolving,
unchecked. I wish there were more movies like this masterpiece.
Sentiment:
""")
.options(ChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(0.1)
.maxTokens(5)
.build())
.call()
.entity(Sentiment.class);
System.out.println("Output: " + reviewSentiment);
}
要点:
- 低温(
0.1)确保分类结果确定性高。 .entity(Sentiment.class)直接将结果映射为Java枚举,避免字符串解析。
📖 参考文献:Brown, T. B., et al. (2020). "Language Models are Few-Shot Learners." arXiv:2005.14165
3.2 One-Shot & Few-Shot 少样本提示
概念 :提供 1 个(One-Shot)或多个(Few-Shot,通常 3-5 个)示例,让模型从示例中学习输入-输出的映射模式。
适用场景:需要特定输出格式、边缘情况处理、任务定义存在歧义时。
java
public void pt_one_shot_few_shots(ChatClient chatClient) {
String pizzaOrder = chatClient.prompt("""
Parse a customer's pizza order into valid JSON
EXAMPLE 1:
I want a small pizza with cheese, tomato sauce, and pepperoni.
JSON Response:
```
{
"size": "small",
"type": "normal",
"ingredients": ["cheese", "tomato sauce", "pepperoni"]
}
```
EXAMPLE 2:
Can I get a large pizza with tomato sauce, basil and mozzarella.
JSON Response:
```
{
"size": "large",
"type": "normal",
"ingredients": ["tomato sauce", "basil", "mozzarella"]
}
```
Now, I would like a large pizza, with the first half cheese and mozzarella.
And the other tomato sauce, ham and pineapple.
""")
.options(ChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(0.1)
.maxTokens(250)
.build())
.call()
.content();
}
要点:
- 示例的质量和多样性对性能影响极大。
- 通过示例隐性定义输出格式,模型会模仿
JSON结构。
📖 参考文献:Brown, T. B., et al. (2020). "Language Models are Few-Shot Learners."arXiv:2005.14165
3.3 系统提示、角色提示与上下文提示
3.3.1 系统提示(System Prompting)
为模型设定全局行为框架,定义"大方向"------输出格式、语气、伦理边界、角色定义等。与具体用户查询分离,持续影响整个会话。
java
public void pt_system_prompting_1(ChatClient chatClient) {
String movieReview = chatClient
.prompt()
.system("Classify movie reviews as positive, neutral or negative. Only return the label in uppercase.")
.user("""
Review: "Her" is a disturbing study revealing the direction
humanity is headed if AI is allowed to keep evolving,
unchecked. It's so disturbing I couldn't watch it.
Sentiment:
""")
.options(ChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(1.0)
.topK(40)
.topP(0.8)
.maxTokens(5)
.build())
.call()
.content();
}
配合 Entity Mapping 使用:
java
record MovieReviews(Movie[] movie_reviews) {
enum Sentiment { POSITIVE, NEUTRAL, NEGATIVE }
record Movie(Sentiment sentiment, String name) {}
}
MovieReviews movieReviews = chatClient
.prompt()
.system("""
Classify movie reviews as positive, neutral or negative. Return valid JSON.
""")
.user("""
Review: "Her" is a disturbing study revealing the direction
humanity is headed if AI is allowed to keep evolving,
unchecked. It's so disturbing I couldn't watch it.
JSON Response:
""")
.call()
.entity(MovieReviews.class);
📖 参考文献:OpenAI. (2022). System Message
3.3.2 角色提示(Role Prompting)
让模型扮演特定角色/人设,影响生成内容的风格、深度与视角。
java
// 基础角色提示
public void pt_role_prompting_1(ChatClient chatClient) {
String travelSuggestions = chatClient
.prompt()
.system("""
I want you to act as a travel guide. I will write to you
about my location and you will suggest 3 places to visit near
me. In some cases, I will also give you the type of places I
will visit.
""")
.user("""
My suggestion: "I am in Amsterdam and I want to visit only museums."
Travel Suggestions:
""")
.call()
.content();
}
// 角色 + 风格指令
public void pt_role_prompting_2(ChatClient chatClient) {
String humorousTravelSuggestions = chatClient
.prompt()
.system("""
I want you to act as a travel guide. I will write to you about
my location and you will suggest 3 places to visit near me in
a humorous style.
""")
.user("""
My suggestion: "I am in Amsterdam and I want to visit only museums."
Travel Suggestions:
""")
.call()
.content();
}
📖 参考文献:Shanahan, M., et al. (2023). "Role-Play with Large Language Models."arXiv:2305.16367
3.3.3 上下文提示(Contextual Prompting)
通过参数注入额外背景信息,丰富模型对具体场景的理解,获得更贴合上下文的回复。
java
public void pt_contextual_prompting(ChatClient chatClient) {
String articleSuggestions = chatClient
.prompt()
.user(u -> u.text("""
Suggest 3 topics to write an article about with a few lines of
description of what this article should contain.
Context: {context}
""")
.param("context", "You are writing for a blog about retro 80's arcade video games."))
.call()
.content();
}
Spring AI的.param()方法让上下文注入变得简洁优雅:变量占位符{context}➕ 运行时传参.param("context", value)。
📖 参考文献:Liu, P., et al. (2021). "What Makes Good In-Context Examples for GPT-3?" arXiv:2101.06804
3.4 Step-Back 回溯提示
概念:面对复杂问题时,先"退一步"思考更宏观的基础概念/原理,获得足够背景知识后再解决具体问题。
流程:
- 第一步:提出一个抽象层面的问题,让模型给出核心概念/原理。
- 第二步:将第一步的结果作为上下文,注入到具体任务的
Prompt中。
java
public void pt_step_back_prompting(ChatClient.Builder chatClientBuilder) {
var chatClient = chatClientBuilder
.defaultOptions(ChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(1.0)
.topK(40)
.topP(0.8)
.maxTokens(1024)
.build())
.build();
// 第一步:获取高层概念
String stepBack = chatClient
.prompt("""
Based on popular first-person shooter action games, what are
5 fictional key settings that contribute to a challenging and
engaging level storyline in a first-person shooter video game?
""")
.call()
.content();
// 第二步:利用第一步的概念完成主任务
String story = chatClient
.prompt()
.user(u -> u.text("""
Write a one paragraph storyline for a new level of a first-
person shooter video game that is challenging and engaging.
Context: {step-back}
""")
.param("step-back", stepBack))
.call()
.content();
}
适用场景:复杂推理、需要专业知识的问题、希望获得更深入回答的场合。
📖 参考文献:Zheng, Z., et al. (2023). "Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models."arXiv:2310.06117
3.5 Chain of Thought (CoT) 思维链
概念 :通过引导模型逐步推理 ("Let's think step by step"),让其显式展示中间推理过程,从而在复杂推理任务上获得更高的准确性。
3.5.1 Zero-Shot CoT
java
public void pt_chain_of_thought_zero_shot(ChatClient chatClient) {
String output = chatClient
.prompt("""
When I was 3 years old, my partner was 3 times my age. Now,
I am 20 years old. How old is my partner?
Let's think step by step.
""")
.call()
.content();
}
3.5.2 Few-Shot CoT
java
public void pt_chain_of_thought_singleshot_fewshots(ChatClient chatClient) {
String output = chatClient
.prompt("""
Q: When my brother was 2 years old, I was double his age. Now
I am 40 years old. How old is my brother? Let's think step
by step.
A: When my brother was 2 years, I was 2 * 2 = 4 years old.
That's an age difference of 2 years and I am older. Now I am 40
years old, so my brother is 40 - 2 = 38 years old. The answer
is 38.
Q: When I was 3 years old, my partner was 3 times my age. Now,
I am 20 years old. How old is my partner? Let's think step
by step.
A:
""")
.call()
.content();
}
关键魔咒 :"Let's think step by step" 是触发模型展示推理过程的经典提示语。
📖 参考文献:Wei, J., et al. (2022). "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models." arXiv:2201.11903
3.6 Self-Consistency 自洽性
概念 :对同一问题多次运行模型(配合较高温度),收集多条推理路径,然后通过多数投票 选出最终答案。本质上是对 LLM 输出的"集成学习"。
java
public void pt_self_consistency(ChatClient chatClient) {
String email = """
Hi,
I have seen you use Wordpress for your website. A great open
source content management system. I have used it in the past
too. It comes with lots of great user plugins. And it's pretty
easy to set up.
I did notice a bug in the contact form, which happens when
you select the name field. See the attached screenshot of me
entering text in the name field. Notice the JavaScript alert
box that I inv0k3d.
But for the rest it's a great website. I enjoy reading it. Feel
free to leave the bug in the website, because it gives me more
interesting things to read.
Cheers,
Harry the Hacker.
""";
record EmailClassification(Classification classification, String reasoning) {
enum Classification {
IMPORTANT, NOT_IMPORTANT
}
}
int importantCount = 0;
int notImportantCount = 0;
// 对同一输入运行 5 次
for (int i = 0; i < 5; i++) {
EmailClassification output = chatClient
.prompt()
.user(u -> u.text("""
Email: {email}
Classify the above email as IMPORTANT or NOT IMPORTANT. Let's
think step by step and explain why.
""")
.param("email", email))
.options(ChatOptions.builder()
.temperature(1.0) // 高温度增加多样性
.build())
.call()
.entity(EmailClassification.class);
if (output.classification() == EmailClassification.Classification.IMPORTANT) {
importantCount++;
} else {
notImportantCount++;
}
}
// 多数投票决定最终分类
String finalClassification = importantCount > notImportantCount ?
"IMPORTANT" : "NOT IMPORTANT";
}
适用场景:高风险决策、复杂推理、需要比单次响应更可靠答案的场合。
代价 :多次 API 调用带来额外的计算成本与延迟。
📖 参考文献:`ang, X., et al. (2022). "Self-Consistency Improves Chain of Thought Reasoning in Language Models."arXiv:2203.11171
3.7 Tree of Thoughts (ToT) 思维树
概念 :ToT 是 CoT 的进阶,将问题求解视为搜索过程------同时探索多条推理路径,评估每条路径的前景,然后深入挖掘最有希望的分支。
以下是一个(简化版)国际象棋开局探索示例:
java
public void pt_tree_of_thoughts_game(ChatClient chatClient) {
// 第一步:生成多个初始走法
String initialMoves = chatClient
.prompt("""
You are playing a game of chess. The board is in the starting position.
Generate 3 different possible opening moves. For each move:
1. Describe the move in algebraic notation
2. Explain the strategic thinking behind this move
3. Rate the move's strength from 1-10
""")
.options(ChatOptions.builder().temperature(0.7).build())
.call()
.content();
// 第二步:评估并选出最优走法
String bestMove = chatClient
.prompt()
.user(u -> u.text("""
Analyze these opening moves and select the strongest one:
{moves}
Explain your reasoning step by step, considering:
1. Position control
2. Development potential
3. Long-term strategic advantage
Then select the single best move.
""").param("moves", initialMoves))
.call()
.content();
// 第三步:基于最优走法,推演未来棋局
String gameProjection = chatClient
.prompt()
.user(u -> u.text("""
Based on this selected opening move:
{best_move}
Project the next 3 moves for both players. For each potential branch:
1. Describe the move and counter-move
2. Evaluate the resulting position
3. Identify the most promising continuation
Finally, determine the most advantageous sequence of moves.
""").param("best_move", bestMove))
.call()
.content();
}
ToT 三部曲:
- 生成多样化的候选方案
- 评估各方案的优劣
- 深入探索最优分支
📖 参考文献:Yao, S., et al. (2023). "Tree of Thoughts: Deliberate Problem Solving with Large Language Models."arXiv:2305.10601
3.8 自动提示工程
概念 :用 AI 来生成和评估不同的 Prompt 变体 ,系统性地找到最优 Prompt 表述,实现"用 AI 提升 AI"的元层面优化。
java
public void pt_automatic_prompt_engineering(ChatClient chatClient) {
// 生成 10 个同义变体
String orderVariants = chatClient
.prompt("""
We have a band merchandise t-shirt webshop, and to train a
chatbot we need various ways to order: "One Metallica t-shirt
size S". Generate 10 variants, with the same semantics but keep
the same meaning.
""")
.options(ChatOptions.builder()
.temperature(1.0) // 高温度激发创意
.build())
.call()
.content();
// 评估并选出最佳变体
String output = chatClient
.prompt()
.user(u -> u.text("""
Please perform BLEU (Bilingual Evaluation Understudy) evaluation on the following variants:
----
{variants}
----
Select the instruction candidate with the highest evaluation score.
""").param("variants", orderVariants))
.call()
.content();
}
适用场景 :优化生产系统 Prompt、手工调优已到瓶颈的复杂任务、规模化提升 Prompt 质量。
📖 参考文献:Zhou, Y., et al. (2022). "Large Language Models Are Human-Level Prompt Engineers." arXiv:2211.01910
3.9 代码提示
概念 :针对代码相关任务的专用 Prompt 技法,包括编写代码 、解释代码 和代码翻译 。一般使用较低温度(0.1-0.3)以获取确定性输出。
3.9.1 编写代码
java
public void pt_code_prompting_writing_code(ChatClient chatClient) {
String bashScript = chatClient
.prompt("""
Write a code snippet in Bash, which asks for a folder name.
Then it takes the contents of the folder and renames all the
files inside by prepending the name draft to the file name.
""")
.options(ChatOptions.builder()
.temperature(0.1) // 低温度确保代码确定性
.build())
.call()
.content();
}
3.9.2 解释代码
java
public void pt_code_prompting_explaining_code(ChatClient chatClient) {
String code = """
#!/bin/bash
echo "Enter the folder name: "
read folder_name
if [ ! -d "$folder_name" ]; then
echo "Folder does not exist."
exit 1
fi
files=( "$folder_name"/* )
for file in "${files[@]}"; do
new_file_name="draft_$(basename "$file")"
mv "$file" "$new_file_name"
done
echo "Files renamed successfully."
""";
String explanation = chatClient
.prompt()
.user(u -> u.text("""
Explain to me the below Bash code:
```
{code}
```
""").param("code", code))
.call()
.content();
}
3.9.3 代码翻译
java
public void pt_code_prompting_translating_code(ChatClient chatClient) {
String bashCode = """
#!/bin/bash
echo "Enter the folder name: "
read folder_name
if [ ! -d "$folder_name" ]; then
echo "Folder does not exist."
exit 1
fi
files=( "$folder_name"/* )
for file in "${files[@]}"; do
new_file_name="draft_$(basename "$file")"
mv "$file" "$new_file_name"
done
echo "Files renamed successfully."
""";
String pythonCode = chatClient
.prompt()
.user(u -> u.text("""
Translate the below Bash code to a Python snippet:
{code}
""").param("code", bashCode))
.call()
.content();
}
适用场景:自动化文档生成、快速原型、编程学习辅助、跨语言代码迁移。
📖 参考文献:
Chen, M., et al. (2021). "Evaluating Large Language Models Trained on Code."arXiv:2107.03374
4. 总结
Spring AI 为 Prompt Engineering 的九大核心技法提供了优雅的 Java API:
| 技法 | 核心思路 | Spring AI 关键特性 |
|---|---|---|
Zero-Shot |
无示例直接执行 | .entity() 类型映射 |
Few-Shot |
提供示例引导模式 | 文本块 + .content() |
System/Role/Context |
全局框架 + 角色 + 上下文 | .system() / .param() |
Step-Back |
先抽象后具体 | 两步 .call() + 上下文注入 |
CoT |
逐步推理 | "Let's think step by step" |
Self-Consistency |
多次采样 + 投票 | 循环调用 + 多数表决 |
ToT |
多路径探索 + 评估择优 | 多阶段 Prompt 串联 |
| 自动提示工程 | AI 优化 AI |
生成变体 + 评估选取 |
| 代码提示 | 写/解释/翻译代码 | 低温度 + 结构化输出 |
最佳实践:
- 不要孤立使用单一技法 ------ 组合使用 往往效果更佳。例如:
System Prompt+Few-Shot+CoT。 - 针对不同任务调优
Temperature/Top-K/Top-P参数。 - 对关键决策场景引入
Self-Consistency。 - 善用
.entity()实现类型安全的结构化响应。 - 通过上下文提示注入业务领域知识。