ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring AI 提示词模板:{变量} 参数化 + few-shot,一条提示词反复用

Spring AI 提示词模板:{变量} 参数化 + few-shot,一条提示词反复用 Spring AI 提示词模板{变量} 参数化 few-shot一条提示词反复用作者鱼宵 Spring AI 实战精通营 · 第 2 篇上周拿第 1 课那个翻译接口改需求产品说同一句话要能翻商务版、口语版、文艺版。我的第一反应是再写两个接口把system()里的提示词复制三遍、改两个字。写到第三个风格时我自己都烦了——提示词骨架一个字没动就风格两个字不一样凭什么复制三遍这就是第 2 课要收拾的事把写死的提示词改造成带{变量}的模板骨架写死一次、参数按次填顺手再玩个 few-shot——不讲规则直接甩 3 个输入→输出示例让模型自己照着样例说话。代码全在仓库lesson-02/目录里clone 下来照着命令重跑一遍十分钟你手里就有两个翻译接口。一、核心原理提示词不是写死的字符串是带坑的表格1. 一次请求 一张对话记录表先把底层概念掰清楚Message消息是发给模型的最小单位每条消息就两个属性——谁说的role 说了什么content。模型不是读一整段话而是捧着一本对话记录本一行一行往下看角色内容system“你是专业中英翻译助手只输出译文” ← 员工守则user“把【今天天气真不错】翻译成商务正式风格的英文” ← 这一次的问题assistant“The weather is quite pleasant today.” ← 模型回话下一轮进表system()必须放在user()前面——顺序就是记录本上的先后模型按行读写反了它就先答题再读守则。2. 参数化模板合同为什么不用每次重写公司的劳动合同不会来一个人重写一份都是一份模板写死甲方、乙方、岗位____新人入职就把三个空填上。提示词模板一个思路模板 把下面这句话翻译成英文译文风格要【{style}】{question} 填值 style商务正式, question今天天气真不错 成品 把下面这句话翻译成英文译文风格要【商务正式】今天天气真不错对照两种写法一眼看出差别写法代码问题错误字符串拼接风格是 style 句子是 question又臭又长引号转义全靠自己擦屁股正确模板填坑.user(u - u.text(...{style}...).param(style, style))骨架复用按名字填值这里埋了本课最大的一个坑直接.user(...{question}...)传字符串占位符不会被替换——模板引擎只在 lambda 小括号模式u - u.text(...).param(...)里才启动。你老老实实把模板写进text()、把值交给param()坑才会被填上。两边名字还得逐字符一致{Question}和question大小写对不上坑就原样留在句子里发给模型模型当场懵。3. few-shot教新人不写 SOP甩 3 份优秀聊天记录few-shot少样本提示不写一堆规则直接在 system 里塞 2~3 个输入→输出对照示例模型自己归纳规律并模仿。给 0 个示例叫 zero-shot第 1 课就是给几个示例就是 few-shot。对比zero-shot讲规则few-shot给样例写法system 里写你是客服翻译语气简短客气system 里塞 3 条用户xxx / 翻译yyy适合规则说得清的任务风格类、格式类任务你说不清客服口吻是几个字成本输入短示例常驻每次请求token 略涨类比带新人教客服新人与其写 500 字 SOP不如甩 3 份优秀聊天记录让他照着聊——他自己就悟到要短、要客气。大模型吃这套第四节实测给你看证据。二、动手十分钟跑通两个翻译接口环境Windows JDK 17 Maven 3.9会RestController就行。第 1 步30 秒检查环境。java-version# 期望 True[bool][Environment]::GetEnvironmentVariable(DEEPSEEK_API_KEY)# 期望 TrueGet-NetTCPConnection-LocalPort 8094-State Listen-ErrorAction SilentlyContinue# 无输出端口空闲第 2 步编译 启动。cd spring-ai-journey\lesson-02$env:JAVA_HOMEC:\Program Files\Java\jdk-17# Maven 必须跑在 JDK 17 上mvn clean install-DskipTests# 结尾看到 BUILD SUCCESSmvn spring-boot:run# 看到 Tomcat started on port 8094 即成功第 3 步调两个接口中文参数先 URL 编码。[Console]::OutputEncoding[System.Text.Encoding]::GetEncoding(936)# 防控制台中文乱码# 接口一参数化模板question style 两个变量$q[uri]::EscapeDataString(今天天气真不错)$s[uri]::EscapeDataString(商务正式)Invoke-RestMethodhttp://localhost:8094/translate?question$qstyle$s# 接口二few-shot只传 question风格靠 system 里的示例带出来$q2[uri]::EscapeDataString(我想买两件衬衫)Invoke-RestMethodhttp://localhost:8094/translate-fewshot?question$q2浏览器直接开http://localhost:8094/translate?question你好style商务正式也行浏览器会自动编码中文。三、关键代码两个接口逐行拆解工程还是标准 Spring Boot 项目真正要看的就两处yml 配置和那个控制器。第一段application.yml——只改端口和 token 上限。server:port:8094# 端口按课程分配表spring-ai 系列 lesson-02 8094spring:ai:openai:base-url:${LLM_BASE_URL:https://api.deepseek.com}# 环境变量优先默认 DeepSeekapi-key:${DEEPSEEK_API_KEY}# Key 只从环境变量读文件里永远没有明文chat:options:model:${LLM_MODEL:deepseek-chat}# 模型名默认 deepseek-chatmax-tokens:400# 翻译输出比一问一答略长教学控成本temperature:0.7# 温度 0.7翻译要稳但不死板配置套路和第 1 课一模一样——这就是 yml 自动装配的好处加新课不改配置习惯就动了port和max-tokens两个数。第二段ChatClientTemplateDemo.java——本课主菜完整可运行。packagecom.springai.lesson02;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;/** * 第 2 课核心翻译助手控制器。 * 两个接口 * /translate —— 参数化模板模板里写 {question}/{style} 占位运行时 .param() 填值 * /translate-fewshot —— few-shotsystem 里塞 3 个中英对照示例让模型模仿风格 */RestControllerpublicclassChatClientTemplateDemo{/** ChatClient 实例和第 1 课一样Builder 由 starter 自动装配零手写模型代码 */privatefinalChatClientchatClient;publicChatClientTemplateDemo(ChatClient.Builderbuilder){this.chatClientbuilder.build();}/** * 接口一参数化模板翻译。 * GET /translate?question今天天气真不错style商务正式 * 重点看 .user(u - u.text(...{question}...).param(...)) 这段 * text() 里放模板占位符 {question}/{style} 不会原样发给模型填完才发 * param() 按名字填坑名字必须和模板里的占位符逐字符一致。 */GetMapping(/translate)publicStringtranslate(RequestParam(question)Stringquestion,RequestParam(valuestyle,defaultValue日常口语)Stringstyle){returnchatClient.prompt()// system人设——只给译文别啰嗦.system(你是专业中英翻译助手。只输出英文译文本身不要解释、不要加引号、不要多余的话。)// user带变量的模板运行时填 question 和 style.user(u-u.text(把下面这句话翻译成英文译文风格要【{style}】\n{question}).param(style,style).param(question,question)).call().content();}/** * 接口二few-shot给示例让模型模仿。 * GET /translate-fewshot?question我想买两件衬衫 * system 里写死 3 个中文→英文对照示例客服场景的简短客气口吻 * user 只放真正要翻的那句话尾巴故意留个翻译让模型顺着示例续写。 */GetMapping(/translate-fewshot)publicStringtranslateFewShot(RequestParam(question)Stringquestion){returnchatClient.prompt()// system人设 3 个示例示例就是模型的模仿对象.system(你是外贸客服的中英翻译。下面是翻译示例请严格模仿示例的简短客气语气只输出英文译文\n示例1\n用户早上好\n翻译Good morning!\n示例2\n用户这件商品包邮吗\n翻译Is shipping free for this item?\n示例3\n用户麻烦帮我退一下货谢谢\n翻译Id like to return this, please. Thank you.)// user只留 {question} 一个坑尾巴的翻译引导模型续写.user(u-u.text(用户{question}\n翻译).param(question,question)).call().content();}}这段代码讲了三件事u - u.text(...)进了 user 的小括号模式第 1 课是直接传字符串本课要填变量所以得进 lambda{style}、{question}是占位符不是发给模型的原文defaultValue 日常口语让 style 不传也能跑。第三段Lesson02Application.java——启动类三行。packagecom.springai.lesson02;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;/** * 第 2 课启动类。启动后访问 * GET http://localhost:8094/translate?question今天天气真不错style商务正式 * GET http://localhost:8094/translate-fewshot?question我想买两件衬衫 */SpringBootApplicationpublicclassLesson02Application{publicstaticvoidmain(String[]args){SpringApplication.run(Lesson02Application.class,args);}}四、实测输出同一个模板换个填法就换个风格以下是 2026-10-05 本机真实运行DeepSeek端口 8094HTTP 200。先调 /translatequestion 不变style 换两次# style商务正式 HTTP 200 The weather is quite pleasant today. # style古代诗人李白风格 HTTP 200 The weather today is truly fine.模板里的{style}真的被填进去了——商务版用了 “quite pleasant” 这种书面词李白版明显凝练。风格有影响但不会天翻地覆temperature 0.7 下模型偏稳妥面试时别吹成换个词就脱胎换骨。再调 /translate-fewshot只传 question看模型怎么模仿示例# question我想买两件衬衫 HTTP 200 Id like to buy two shirts. # question请问什么时候发货 HTTP 200 When will this be shipped?看第一句——Id like to buy two shirts.用了Id like to...开头这正是 system 里示例 3Id like to return this, please的句式。你没写要用 I’d like to 开头这条规则模型自己从三个示例里学去了。这就是 few-shot 的力量风格类任务甩样例比讲规则准。排查提示回答里如果残留{question}字样说明 param 的 key 和模板占位名对不上大小写/拼写两边逐字符核对即可。五、挑战题改参数看看会怎样⭐不传 style浏览器里只开http://localhost:8094/translate?question你好style 参数故意不给——看模型用了什么风格回答。答案就在源码ChatClientTemplateDemo.java的方法参数上跑出来才知道默认值真的生效。⭐⭐不用小括号模式把/translate里的.user(u - u.text(...).param(...))改回.user(把下面这句话翻译成英文译文风格要【商务正式】今天天气真不错)——再进一步试试.user(...{question}...)带占位符但不加 param()。看{question}会不会被替换。这题的答案藏在踩坑节里跑一遍你这辈子都忘不了。⭐⭐示例换成法语把 system 里 3 个示例改成中译法用户早上好 / 翻译Bonjour! 这种user 还是中文——验证模型会不会照猫画虎吐出法语。看你改完示例后它学歪还是学对。六、生产环境进阶三个加分项1. 提示词和代码分离。模板骨架抽到application.yml或常量类里Controller 只负责填变量。提示词改起来不用动代码、不用重新编译产品提需求改一段 yml 就行。2. few-shot 示例算 token 账。示例是常驻输入每次调用都陪着你的问题一起发给模型——示例太多既加钱又可能稀释重点。2~3 个高质量示例性价比最高别贪多。3. 占位符命名即契约。{style}在模板里写一次、param(style, ...)在代码里填一次两边靠字符串名字绑死。建议占位符名和业务参数名保持一致加个常量类集中管理别散落在 Controller 里手写。七、面试回答模板面试官一次 ChatClient 请求到底发给模型几段东西一句话不是一整段字符串是一条消息列表Message List。展开说每条消息 角色system/user/assistant 内容system()是员工守则放在最前user()是这一轮问题call()把整本记录本发给模型。顺序就是记录本上的先后system 必须在 user 前面。指向本课第一节追问提示词模板的变量怎么填为什么我直接 user(“…{x}…”) 不替换一句话填变量必须走 lambda 小括号模式user(u - u.text(...{x}...).param(x, v))。展开说text()里写模板、param()按名字填坑直接给字符串不走模板引擎占位符原样发出去。param 的 key 和占位名逐字符一致大小写不同就填不上。指向本课第三节追问few-shot 和 zero-shot 怎么选一句话规则说得清用 zero-shot风格/格式类说不清规则的任务用 few-shot 给 2~3 个示例。展开说示例是模型的模仿对象必须和目标任务同分布示例常驻输入会涨 token2~3 个性价比最高。本课实测给三个客服示例后模型自己学会了用Id like to...开头。指向本课第四节八、总结表坑现象解法占位名和 param 对不上句子里残留{question}原样发给模型两边名字逐字符一致区分大小写直接 user(字符串带占位符)变量不替换坑留在句子里走 lambda 小括号模式 text()param()few-shot 示例跑题模型学歪成别的风格示例必须和目标任务同分布示例堆太多输入 token 涨钱、重点被稀释控制在 2~3 个高质量示例中文 URL 参数乱码浏览器/curl 直接带中文乱码[uri]::EscapeDataString()编码端口占用Port 8094 already in useGet-NetTCPConnection -LocalPort 8094查占用九、关于这个系列本文是「Java 后端实战精通营」系列第 2 篇原则实战驱动、由浅到深、面试向每篇文章的结论都可以亲手验证。Spring AI 实战精通营10 课https://gitee.com/j67mk2/spring-ai-journey本文对应源码位置lesson-02/内含ChatClientTemplateDemo双接口——参数化模板 few-shot配application.yml端口 8094系列文章一览按发布顺序篇主题1Spring AI 初体验配好 yml 就能聊ChatClient 四步链式调用2Spring AI 提示词模板{变量} 参数化 few-shot一条提示词反复用3Spring AI 结构化输出entity() 把模型回答解析成 JavaBean别再手撕 JSON4Spring AI 工具调用Tool 让大模型自己查订单查库存5Spring AI 流式输出Flux SSE 打字机回答不再干等三秒6Spring AI 多模态给大模型一双眼睛图片它也能看懂7Spring AI 向量检索本地 ONNX 嵌入文本秒变坐标知识库零成本起步8Spring AI RAG 问答助手回答带引用AI 不再睁眼说瞎话9Spring AI Advisor 编排记忆 工具 RAG 三合一一个接口全搞定10Spring AI 企业智能客服RAG 工具 记忆 流式 兜底十课收官下一篇预告《Spring AI 结构化输出entity() 把模型回答解析成 JavaBean别再手撕 JSON》——本课翻出来的是一坨英文译文人看得懂但程序没法拿它算钱下一课上主菜.entity(Order.class)一句话让模型直接吐一个 Java 对象商品清单、数量、总价自动装进 Order。跑完有任何报错把终端输出发评论区一起排查。标签建议SpringAI、提示词工程、few-shot摘要建议≤256 字第 1 课的提示词是写死在代码里的字符串改个风格就得复制三遍。本文把它改造成带 {变量} 的参数化模板——text() 写模板、param() 按名填值骨架复用再塞 3 个输入输出示例玩 few-shot实测模型自己学会了 I’d like to 开头。逐行拆解 lambda 小括号模式这个新手坑附 3 道挑战题与面试回答模板源码在 gitee lesson-02 可 clone 直接跑。
返回列表