提示工程模式
基于全面的 Prompt Engineering Guide 的 Prompt Engineering 技术的实际实施。 该指南涵盖了有效提示工程的理论、原则和模式,而在这里,我们演示了如何使用 Spring AI 的 Fluent ChatClient API 将这些概念转换为有效的 Java 代码。 本文中使用的演示源代码可在以下网址获得:Prompt Engineering Patterns Examples。
1. 配置
配置部分概述了如何使用 Spring AI 设置和调整大型语言模型 (LLM)。 它涵盖了为您的使用案例选择合适的 LLM 提供程序,以及配置控制模型输出的质量、样式和格式的重要生成参数。
LLM 提供商选择
对于快速工程,您将首先选择一个模型。
Spring AI 支持多个 LLM 提供程序(例如 OpenAI、Anthropic、Google Vertex AI、AWS Bedrock、Ollama 等),让您无需更改应用程序代码即可切换提供程序 - 只需更新配置即可。
只需添加选定的 starter 依赖项spring-ai-starter-model-<MODEL-PROVIDER-NAME>
.
例如,以下是启用 Anthropic Claude API 的方法:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-anthropic</artifactId>
</dependency>
您可以指定 LLM 模型名称,如下所示:
.options(ChatOptions.builder()
.model("claude-3-7-sonnet-latest") // Use Anthropic's Claude model
.build())
在参考文档中查找有关启用每个模型的详细信息。
LLM 输出配置

在我们深入研究提示工程技术之前,必须了解如何配置 LLM 的输出行为。Spring AI 提供了几个配置选项,允许您通过 ChatOptions 构建器控制生成的各个方面。
所有配置都可以以编程方式应用,如以下示例所示,或者在开始时通过 Spring 应用程序属性应用。
温度
温度控制模型响应的随机性或“创造力”。
-
下限值 (0.0-0.3):更具确定性、更集中的响应。更适合于一致性至关重要的事实性问题、分类或任务。
-
中等值 (0.4-0.7):在确定性和创造力之间取得平衡。适用于一般用例。
-
较高的值 (0.8-1.0):更具创意、变化多端且可能令人惊讶的回答。更适合创意写作、头脑风暴或生成多种选择。
.options(ChatOptions.builder()
.temperature(0.1) // Very deterministic output
.build())
了解温度对于快速工程设计至关重要,因为不同的技术受益于不同的温度设置。
输出长度 (MaxTokens)
这maxTokens
parameter 限制模型可以在其响应中生成的标记 (单词片段) 的数量。
-
低值 (5-25):适用于单个单词、短语或分类标签。
-
中等值 (50-500):用于段落或简短说明。
-
高值 (1000+):用于长篇内容、故事或复杂的解释。
.options(ChatOptions.builder()
.maxTokens(250) // Medium-length response
.build())
设置适当的输出长度对于确保您获得完整的响应而没有不必要的冗长非常重要。
采样控制(Top-K 和 Top-P)
这些参数使您可以在生成过程中对令牌选择过程进行精细控制。
-
Top-K:将 Token 选择限制为 K 个最有可能的下一个 Token。较高的值(例如 40-50)会引入更多的多样性。
-
Top-P (nucleus sampling):从累积概率超过 P 的最小标记集中动态选择。0.8-0.95 等值很常见。
.options(ChatOptions.builder()
.topK(40) // Consider only the top 40 tokens
.topP(0.8) // Sample from tokens that cover 80% of probability mass
.build())
这些采样控制与温度结合使用,以塑造响应特性。
结构化响应格式
除了纯文本响应(使用.content()
),Spring AI 可以轻松地使用.entity()
方法。
enum Sentiment {
POSITIVE, NEUTRAL, NEGATIVE
}
Sentiment result = chatClient.prompt("...")
.call()
.entity(Sentiment.class);
当与指示模型返回结构化数据的系统提示结合使用时,此功能尤其强大。
特定于模型的选项
虽然便携式ChatOptions
提供了跨不同 LLM 提供程序的一致接口,Spring AI 还提供了特定于模型的选项类,这些类公开了特定于提供程序的功能和配置。这些特定于模型的选项允许您利用每个 LLM 提供商的独特功能。
// Using OpenAI-specific options
OpenAiChatOptions openAiOptions = OpenAiChatOptions.builder()
.model("gpt-4o")
.temperature(0.2)
.frequencyPenalty(0.5) // OpenAI-specific parameter
.presencePenalty(0.3) // OpenAI-specific parameter
.responseFormat(new ResponseFormat("json_object")) // OpenAI-specific JSON mode
.seed(42) // OpenAI-specific deterministic generation
.build();
String result = chatClient.prompt("...")
.options(openAiOptions)
.call()
.content();
// Using Anthropic-specific options
AnthropicChatOptions anthropicOptions = AnthropicChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(0.2)
.topK(40) // Anthropic-specific parameter
.thinking(AnthropicApi.ThinkingType.ENABLED, 1000) // Anthropic-specific thinking configuration
.build();
String result = chatClient.prompt("...")
.options(anthropicOptions)
.call()
.content();
每个模型提供商都有自己的聊天选项实现(例如OpenAiChatOptions
,AnthropicChatOptions
,MistralAiChatOptions
),该接口公开提供程序特定的参数,同时仍实现通用接口。这种方法使您可以灵活地使用可移植选项来实现跨提供商兼容性,或者在需要访问特定提供商的独特功能时使用特定于模型的选项。
请注意,当使用特定于模型的选项时,您的代码会绑定到该特定提供程序,从而降低可移植性。这是在访问特定于提供程序的高级功能与在应用程序中保持提供程序独立性之间的权衡。
2. 提示工程技术
以下每个部分都实现了指南中的特定提示工程技术。 通过遵循 “Prompt Engineering” 指南和这些实现,您不仅会全面了解可用的提示工程技术,还会了解如何在生产 Java 应用程序中有效地实现它们。
2.1 零次提示
零镜头提示涉及要求 AI 执行任务而不提供任何示例。这种方法测试模型从头开始理解和执行指令的能力。大型语言模型在大量文本语料库上进行训练,使它们能够理解 “翻译”、“摘要” 或 “分类” 等任务,而无需明确的演示。
Zero-shot 非常适合模型在训练期间可能看到类似示例的简单任务,以及您希望最小化提示长度时。但是,性能可能会因任务复杂性和说明的制定程度而异。
// Implementation of Section 2.1: General prompting / zero shot (page 15)
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, TB, et al. (2020 年)。“语言模型是少数机会的学习者。”arXiv:2005.14165。https://arxiv.org/abs/2005.14165
2.2 一次性和几次提示
Few-shot 提示为模型提供了一个或多个示例,以帮助指导其响应,这对于需要特定输出格式的任务特别有用。通过显示所需 input-output 对的模型示例,它可以学习模式并将其应用于新 inputs,而无需显式更新参数。
One-shot 提供单个示例,当示例成本高昂或模式相对简单时,这非常有用。Few-shot 使用多个示例(通常为 3-5 个)来帮助模型更好地理解更复杂任务中的模式或说明正确输出的不同变化。
// Implementation of Section 2.2: One-shot & few-shot (page 16)
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();
}
对于需要特定格式设置、处理边缘情况的任务,或者当任务定义可能不明确而没有示例时,Few-shot 提示特别有效。示例的质量和多样性会显著影响性能。
参考:Brown, TB, et al. (2020 年)。“语言模型是少数机会的学习者。”arXiv:2005.14165。https://arxiv.org/abs/2005.14165
2.3 系统、上下文和角色提示
系统提示
系统提示为语言模型设置整体上下文和目的,定义模型应该做什么的 “大局”。它为模型的响应建立了行为框架、约束和高级目标,与特定的用户查询分开。
系统提示在整个对话中充当持续的“使命宣言”,允许您设置全局参数,如输出格式、语气、道德界限或角色定义。与侧重于特定任务的用户提示不同,系统提示规定了应如何解释所有用户提示。
// Implementation of Section 2.3.1: System prompting
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();
}
当与 Spring AI 的实体映射功能结合使用时,系统提示功能特别强大:
// Implementation of Section 2.3.1: System prompting with JSON output
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);
系统提示对于多轮次对话特别有价值,可确保多个查询之间的行为一致,以及建立应应用于所有响应的格式约束(如 JSON 输出)。
参考:打开人工智能。(2022). “系统消息。”https://platform.openai.com/docs/guides/chat/introduction
角色提示
角色提示指示模型采用特定角色或角色,这会影响它生成内容的方式。通过为模型分配特定的身份、专业知识或视角,您可以影响其响应的风格、语气、深度和框架。
角色提示利用模型的能力来模拟不同的专业领域和沟通方式。常见角色包括专家(例如,“您是一位经验丰富的数据科学家”)、专业人士(例如,“充当旅行指南”)或风格角色(例如,“像莎士比亚一样解释”)。
// Implementation of Section 2.3.2: Role prompting
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();
}
可以通过样式说明来增强角色提示:
// Implementation of Section 2.3.2: Role prompting with style instructions
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. 等人(2023 年)。“使用大型语言模型进行角色扮演。”arXiv:2305.16367。https://arxiv.org/abs/2305.16367
上下文提示
上下文提示通过传递上下文参数为模型提供额外的背景信息。这种技术丰富了模型对特定情况的理解,从而能够实现更相关和量身定制的响应,而不会使主要指令变得混乱。
通过提供上下文信息,您可以帮助模型了解与当前查询相关的特定域、受众、约束或背景事实。这导致了更准确、相关和适当构建的响应。
// Implementation of Section 2.3.3: Contextual prompting
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() 方法注入上下文变量,使上下文提示变得干净。当模型需要特定的领域知识时,当根据特定受众或场景调整响应时,以及确保响应与特定约束或要求保持一致时,此技术特别有价值。
参考:Liu, P. 等人(2021 年)。“什么才是 GPT-3 的好上下文示例?” arXiv:2101.06804。https://arxiv.org/abs/2101.06804
2.4 后退提示
后退提示首先通过获取背景知识,将复杂的请求分解为更简单的步骤。这种技术鼓励模型首先从直接问题中“退后一步”,以考虑更广泛的上下文、基本原则或与问题相关的一般知识,然后再解决特定查询。
通过将复杂问题分解为更易于管理的组件并首先建立基础知识,该模型可以更准确地回答困难的问题。
// Implementation of Section 2.4: Step-back prompting
public void pt_step_back_prompting(ChatClient.Builder chatClientBuilder) {
// Set common options for the chat client
var chatClient = chatClientBuilder
.defaultOptions(ChatOptions.builder()
.model("claude-3-7-sonnet-latest")
.temperature(1.0)
.topK(40)
.topP(0.8)
.maxTokens(1024)
.build())
.build();
// First get high-level concepts
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();
// Then use those concepts in the main task
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. 等人(2023 年)。“退后一步:在大型语言模型中通过抽象唤起推理。”arXiv:2310.06117。https://arxiv.org/abs/2310.06117
2.5 思维链 (CoT)
Chain of Thought 提示鼓励模型逐步推理问题,从而提高复杂推理任务的准确性。通过明确要求模型展示其工作或以逻辑步骤思考问题,您可以显著提高需要多步骤推理的任务的性能。
CoT 的工作原理是鼓励模型在产生最终答案之前生成中间推理步骤,类似于人类解决复杂问题的方式。这使得模型的思维过程清晰,并有助于它得出更准确的结论。
// Implementation of Section 2.5: Chain of Thought (CoT) - Zero-shot approach
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();
}
// Implementation of Section 2.5: Chain of Thought (CoT) - Few-shot approach
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” 触发模型展示其推理过程。CoT 对于数学问题、逻辑推理任务和任何需要多步骤推理的问题特别有价值。它通过明确中间推理来帮助减少错误。
参考:Wei, J. 等人(2022 年)。“在大型语言模型中提示引发推理的思维链。”arXiv:2201.11903。https://arxiv.org/abs/2201.11903
2.6 自洽
自洽性涉及多次运行模型并聚合结果以获得更可靠的答案。该技术通过对同一问题的不同推理路径进行采样并通过多数投票选择最一致的答案来解决 LLM 输出的可变性。
通过生成具有不同温度或采样设置的多个推理路径,然后聚合最终答案,自洽性可以提高复杂推理任务的准确性。它本质上是 LLM 输出的 ensemble 方法。
// Implementation of Section 2.6: Self-consistency
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;
// Run the model 5 times with the same input
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) // Higher temperature for more variation
.build())
.call()
.entity(EmailClassification.class);
// Count results
if (output.classification() == EmailClassification.Classification.IMPORTANT) {
importantCount++;
} else {
notImportantCount++;
}
}
// Determine the final classification by majority vote
String finalClassification = importantCount > notImportantCount ?
"IMPORTANT" : "NOT IMPORTANT";
}
自洽对于高风险决策、复杂的推理任务以及当您需要比单个回答更自信的答案时特别有价值。权衡是由于多次 API 调用而增加计算成本和延迟。
参考:Wang, X. 等人(2022 年)。“自洽性改善了语言模型中的思维链推理。”arXiv:2203.11171。https://arxiv.org/abs/2203.11171
2.7 思想(ToT)之树
Tree of Thoughts (ToT) 是一个高级推理框架,它通过同时探索多个推理路径来扩展 Chain of Thought。它将问题解决视为一个搜索过程,在该过程中,模型生成不同的中间步骤,评估它们的承诺,并探索最有前途的路径。
对于具有多种可能方法的复杂问题,或者当解决方案需要在找到最佳路径之前探索各种替代方案时,此技术特别强大。
最初的 “Prompt Engineering” 指南没有提供 ToT 的实现示例,可能是因为它的复杂性。下面是一个演示核心概念的简化示例。 |
游戏解决 ToT 示例:
// Implementation of Section 2.7: Tree of Thoughts (ToT) - Game solving example
public void pt_tree_of_thoughts_game(ChatClient chatClient) {
// Step 1: Generate multiple initial moves
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();
// Step 2: Evaluate and select the most promising move
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();
// Step 3: Explore future game states from the best move
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();
}
参考:Yao, S. 等人(2023 年)。“思想之树:使用大型语言模型进行刻意解决问题。”arXiv:2305.10601。https://arxiv.org/abs/2305.10601
2.8 自动提示工程
Automatic Prompt Engineering 使用 AI 生成和评估替代提示。这种元技术利用语言模型本身来创建、优化和基准测试不同的提示变体,以找到特定任务的最佳公式。
通过系统地生成和评估提示变化,APE 可以找到比手动工程更有效的提示,尤其是对于复杂的任务。这是一种使用 AI 来提高自身性能的方式。
// Implementation of Section 2.8: Automatic Prompt Engineering
public void pt_automatic_prompt_engineering(ChatClient chatClient) {
// Generate variants of the same request
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) // High temperature for creativity
.build())
.call()
.content();
// Evaluate and select the best variant
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();
}
APE 对于优化生产系统的提示、解决手动提示工程已达到极限的具有挑战性的任务以及系统地大规模提高提示质量特别有价值。
参考:周, Y., et al. (2022).“大型语言模型是人类水平的提示工程师。”arXiv:2211.01910.https://arxiv.org/abs/2211.01910
2.9 代码提示
代码提示是指用于代码相关任务的专用技术。这些技术利用 LLM 理解和生成编程语言的能力,使它们能够编写新代码、解释现有代码、调试问题以及在语言之间进行翻译。
有效的代码提示通常涉及明确的规范、适当的上下文(库、框架、样式指南),有时还包括类似代码的示例。温度设置往往较低 (0.1-0.3) 以获得更具确定性的输出。
// Implementation of Section 2.9.1: Prompts for writing code
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) // Low temperature for deterministic code
.build())
.call()
.content();
}
// Implementation of Section 2.9.2: Prompts for explaining code
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();
}
// Implementation of Section 2.9.3: Prompts for translating code
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. 等人(2021 年)。“评估在代码上训练的大型语言模型。”arXiv:2107.03374。https://arxiv.org/abs/2107.03374
结论
Spring AI 提供了一个优雅的 Java API,用于实现所有主要的提示工程技术。通过将这些技术与 Spring 强大的实体映射和 Fluent API 相结合,开发人员可以使用干净、可维护的代码构建复杂的 AI 驱动的应用程序。
最有效的方法通常涉及组合多种技术 - 例如,使用带有少量镜头示例的系统提示,或将思路链与角色提示一起使用。Spring AI 的灵活 API 使这些组合易于实现。
对于生产应用程序,请记住:
-
具有不同参数(temperature、top-k、top-p)的测试提示
-
考虑使用自洽性进行关键决策
-
利用 Spring AI 的实体映射进行类型安全的响应
-
使用上下文提示提供特定于应用程序的知识
借助这些技术和 Spring AI 强大的抽象,您可以创建强大的 AI 驱动的应用程序,以提供一致、高质量的结果。
引用
-
Brown, TB, et al. (2020 年)。“语言模型是少数机会的学习者。”arXiv:2005.14165。
-
Wei, J. 等人(2022 年)。“在大型语言模型中提示引发推理的思维链。”arXiv:2201.11903。
-
Wang, X. 等人(2022 年)。“自洽性改善了语言模型中的思维链推理。”arXiv:2203.11171。
-
Yao, S. 等人(2023 年)。“思想之树:使用大型语言模型进行刻意解决问题。”arXiv:2305.10601。
-
周, Y., et al. (2022).“大型语言模型是人类水平的提示工程师。”arXiv:2211.01910.
-
Zheng, Z. 等人(2023 年)。“退后一步:在大型语言模型中通过抽象唤起推理。”arXiv:2310.06117。
-
Liu, P. 等人(2021 年)。“什么才是 GPT-3 的好上下文示例?” arXiv:2101.06804。
-
Shanahan, M. 等人(2023 年)。“使用大型语言模型进行角色扮演。”arXiv:2305.16367。
-
Chen, M. 等人(2021 年)。“评估在代码上训练的大型语言模型。”arXiv:2107.03374。