Spring with AI (3): 定制对话——Prompt模板引入

张开发
2026/4/6 0:28:16 15 分钟阅读

分享文章

Spring with AI (3): 定制对话——Prompt模板引入
1 创建模板先在pom.xml引入验证Starterdependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-validation/artifactId /dependency我们定义一个关于“世界各国地理历史知识”的AI模板也简单明了实体定义package com.junteam.ai.demo.model; import jakarta.validation.constraints.NotBlank; public record ChatQuestion( NotBlank(message 标题不能为空) String title, NotBlank(message 问题不能为空) String question) { }模板文件resources/promptTemplates/questionPromptTemplate.st定义你是一个有用的助手负责回答有关“代码编程题”的问题。 如果你对这个编程语言一无所知或不知道答案请回答“我不知道”。 只给出实现代码。 编程语言是 {title}。 问题是 {question}2 实现逻辑package com.junteam.ai.demo.service.impl; import org.springframework.ai.chat.client.ChatClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import com.junteam.ai.demo.model.ChatAnswer; import com.junteam.ai.demo.model.ChatQuestion; import com.junteam.ai.demo.service.ChatService; Service public class OpenAIChatServiceImpl implements ChatService { private final ChatClient chatClient; public OpenAIChatServiceImpl(ChatClient.Builder chatClientBuilder) { this.chatClient chatClientBuilder.build(); } Value(classpath:/promptTemplates/questionPromptTemplate.st) Resource questionPromptTemplate; SuppressWarnings(null) Override public ChatAnswer ask(ChatQuestion chatQuestion) { var answer chatClient.prompt() .user(userSpec - userSpec .text(questionPromptTemplate) .param(title, chatQuestion.title()) .param(question, chatQuestion.question()) ) .call(); var answerText answer.content(); return new ChatAnswer(chatQuestion.title(), answerText); } }3 运行效果测试用例curl http://localhost:8080/web/ask \ -X POST \ -H Content-Type: application/json \ -d {title: java, question: 给定一个非递减排序的整数数组 nums 和一个目标值 target请编写一个函数返回 target 在数组中出现的第一个位置和最后一个位置下标从 0 开始。​\n - 如果 target 未在数组中出现返回 [-1, -1]​\n - 要求时间复杂度不超过 O(logn)空间复杂度 O(1)。​\n示例​\n 1. 输入nums [5,7,7,8,8,10], target 8 → 输出[3,4]​\n 2. 输入nums [5,7,7,8,8,10], target 6 → 输出[-1,-1]​\n 3. 输入nums [], target 0 → 输出[-1,-1]​\n 4. 输入nums [2,2], target 2 → 输出[0,1]}返回结果为了排版笔者进行了截断{ title:JAVA, answer:java\nclass Solution {\n public int findMin(int[] nums) {\n ... }整理出来结果如下class Solution { public int findMin(int[] nums) { int left 0; int right nums.length - 1; while (left right) { int mid left (right - left) / 2; if (nums[mid] nums[right]) { left mid 1; } else { right mid; } } return nums[left]; } }4 更多补充4.1 基于模板扩展内容再引入RAG之前可以用简单的模板填充、来实现一些扩展内容。比如再加一个langRules/java.txt内容形如- java中尽量使用基本数据、而非封装类型。 - java中尽量使用静态方法实现代码。这样可以再模板可以修改为你是一个有用的助手负责回答有关“代码编程题”的问题。 如果你对这个编程语言一无所知或不知道答案请回答“我不知道”。 如果可能使用规则{rules}。 只给出实现代码。 编程语言是 {title}。 问题是 {question}4.2 大模型选项4.2.1 大模型类型在配置讲解中已经提到不再赘述4.2.2 大模型温度temperature参数是生成策略中的核心参数直接影响输出的随机性与创造性。低Temperature0.3-0.7适用于客服机器人等需要精准回答的场景减少错误信息中Temperature0.7-1.2适合创意写作平衡逻辑性与多样性高Temperature1.2-2.0用于头脑风暴工具激发非常规创意ChatOptions chatOptions ChatOptions.builder() .temperature(0.7) .build(); String answerText chatClient.prompt() .user(question.question()) .options(chatOptions) .call() .content();4.2.3 其他选项topP拣选答案的比例比如.topP(0.8)从排名前80%的结果中拣选topK排除答案的比例比如.topP(0.2)排名后20%的结果排除4.3 格式化例如前面所提的在Prompt中指定输出格式为json、或者只保留java代码。这样可以快速实现热门歌单等json接口另外可以把输出格式就设置为流式这样客户端或网页前端可以使用SSE协议接收结果、逐个Token显示。return chatClient.prompt() .system(systemSpec - systemSpec .text(promptTemplate) .param(title, question.title()) .param(rules, langRules)) .user(question.question()) .stream() // 流式 .content();4.4 响应元数据LLM返回的内容例如OpenAI包含了Token使用相关的数据元数据形如{ token_usage: { completion_tokens: 164, prompt_tokens: 17, total_tokens: 181 }, model_name: gpt-4-turbo, system_fingerprint: fp_76f018034d, finish_reason: stop, logprobs: null }这样可以再代码中获取和记录var responseEntity chatClient.prompt() .system(systemSpec - systemSpec .text(promptTemplate) .param(gameTitle, question.gameTitle()) .param(rules, gameRules)) .user(question.question()) .call() .responseEntity(Answer.class); var response responseEntity.response(); var metadata response.getMetadata(); log.info(metadata.getUsage()); // 获得Token使用量 return responseEntity.entity();

更多文章