导读 :同一个大模型,有人问出"专家级"的回答,有人只得到"正确的废话"。差别不在模型,在提问的方式。这篇文章用大白话讲透提示词工程最核心的三板斧技巧------角色设定、Few-shot、思维链。
01 · 先讲个扎心的事实
上个月我让两个同事用同一个大模型 API 写接口文档。
A 同事的 prompt 是:*"帮我写接口文档。"*
B 同事的 prompt 是:*"你是资深后端架构师,熟悉 RESTful 规范。请为下面的接口写文档,包含:请求参数说明、响应码、异常场景。接口信息:......"*
结果你猜怎么着?A 拿到一份"看起来像那么回事但没法用"的泛泛而谈;B 拿到一份可以直接贴进 Wiki 的规范文档。
模型是同一个模型,变的只是提问方式。 这个"提问方式",就是 Prompt Engineering(提示词工程)。
网上把提示词工程吹得很玄,什么"魔法咒语""驯服 AI 的密码"。拆开看,核心就三板斧:
-
角色设定(Role Prompting)------告诉 AI 它是谁
-
Few-shot(少样本示例)------给 AI 看几个例子
-
思维链(CoT,Chain-of-Thought)------让 AI 把思路写出来
这三招单独用都有用,组合起来效果翻倍。下面挨个讲。
02 · 先建立直觉:大模型是个"戏精"
在动手之前,先建立一个直觉,后面所有技巧都好理解了。
大模型本质上是个"根据前文续写"的机器。你给它一段文字,它按照训练时学到的规律,接着往下写。它没有数据库,也没有"查一下资料再回答"的能力------它只有根据上文续写的本能。
所以,你的 prompt 就是剧本,它只是个照着剧本演的演员。
-
剧本里写"你是医生",它就切换到医生的说话方式
-
剧本里给了三个问答示例,它就有样学样模仿那种格式
-
剧本里说"先一步步算",它就会把计算过程写出来
三板斧的本质,就是给剧本加人设、加示范、加解题思路。就这么简单。
03 · 第一板斧:角色设定
原理:让 AI 切换到"对的频道"
模型在训练时见过海量的文本:有医生写的、律师写的、客服写的、程序员写的。它们的说话方式、专业术语、思考习惯完全不同。
角色设定做的事,就是帮模型切换到对应的频道。
★
打个比方。一个新员工入职,你让他"以客服身份回客户消息"和"以总监身份点评方案",他输出的东西完全不一样。AI 也是一样,角色就是它的"岗位说明书"。
对比一下
同一个问题,两种问法:
❌ 普通问法:
"解释一下什么是 RAG?"
→ 回答:RAG 是检索增强生成(Retrieval-Augmented Generation),是一种......
✅ 角色设定:
"你是一位有 15 年经验的 Java 架构师,习惯用大白话解释技术,回答先给结论再讲原理。
请解释:什么是 RAG?"
→ 回答:一句话:RAG 就是"先查资料,再回答"。
原理是......落地到 Spring AI 里,你只需要......(自动带上了技术人的视角)
后者明显"懂行"得多------它默认你知道上下文,直接讲重点,而不是从幼儿园水平开始科普。
Spring AI 怎么写
String answer = chatClient.prompt()
.system("你是一位有 15 年经验的 Java 架构师,"
+ "习惯用大白话解释技术,回答先给结论,再讲原理。")
.user("解释一下 RAG 是什么?")
.call()
.content();
system() 就是角色设定,和 OpenAI 的 system message 一一对应。角色描述写得越具体,效果越明显------"资深架构师"不如"有 15 年经验、带过 50 人团队、擅长用类比讲技术的架构师"。
三个实用要点
-
角色 + 约束一起写:顺手规定"回答不超过 200 字""不要用专业黑话",省得后面反复纠正
-
角色要贴任务:写代码用"资深工程师",写文案用"公众号主编",别混着来
-
可以多层叠加:*"你是项目经理,同时扮演评审专家,指出方案的风险"*------一个 prompt 里可以同时给多个视角
04 · 第二板斧:Few-shot(少样本示例)
原理:AI 是"模仿型选手"
Few-shot 翻译过来叫"少样本学习",学术上叫上下文学习(In-Context Learning) 。意思很直白:给模型看几个"输入→输出"的例子,它就能照着这个套路干活。
为什么有效?因为模型是统计机器,示例就是它的"条件反射触发器"------看到两个"评价→情感"的例子,它就知道接下来要输出"情感"而不是别的。
★
类比:带实习生,讲十遍规则不如甩给他三个做好的样例。规则他记不住,样例他看一眼就会。
对比一下
同样是情感分析:
❌ 只讲规则:
"请判断下面这条评论的情感倾向:东西不错,就是发货有点慢"
✅ 给足示例:
"请判断评论的情感倾向。
示例1:太喜欢这个产品了 → 积极
示例2:服务太差,拉黑 → 消极
示例3:一般般吧,能用 → 中性
现在判断:东西不错,就是发货有点慢"
注意,加了示例之后,模型连"输出格式"都学会了------它知道答案就是"积极/消极/中性"三个词,不会给你写一段小作文。
Spring AI 怎么写
最朴素的方式,直接把示例写进 prompt:
String answer = chatClient.prompt("""
把用户评价归类为【好评】【中评】【差评】。
示例1:
评价:快递晚了两天,但包装很仔细。
类别:中评
示例2:
评价:客服当晚就解决了我的问题,效率超高!
类别:好评
现在请归类:
评价:货不对板,申请退款也没人理。
类别:
""")
.call()
.content();
// 输出:差评
示例多了之后,建议用 PromptTemplate 管理,还能动态遍历示例列表:
String template = """
你是情感分析助手。参考示例给评论分类:
{{#each examples}}
评论:{{this.text}}
情感:{{this.sentiment}}
{{/each}}
评论:{{review}}
情感:
""";
PromptTemplate pt = new PromptTemplate(template);
Prompt prompt = pt.create(Map.of(
"examples", List.of(
Map.of("text", "太喜欢这个产品了", "sentiment", "积极"),
Map.of("text", "服务一般,不会再来了", "sentiment", "消极")),
"review", "东西不错,就是发货有点慢"
));
String result = chatClient.prompt(prompt).call().content();
{``{``#each}} 是 Spring AI 模板引擎(StTemplateRenderer)的遍历语法,示例列表用 Java 的 List<Map> 直接传进去就行。
三个实用要点
-
示例的质量 > 数量:2~3 个好例子胜过 10 个随意例子。每个例子都要能代表一类典型情况
-
把"边界情况"也放进去:比如情感分析,加一条"一般般吧 → 中性"的例子,模型就不容易把中性硬归成两极
-
负例也有用:在示例里顺手标注"这不是退换货问题,属于咨询",能帮模型学会区分
05 · 第三板斧:思维链(CoT)
原理:让 AI 把"草稿纸"亮出来
思维链(Chain-of-Thought)是 2022 年 Google 一篇论文提出的,现在已经是提示词工程里含金量最高的一招。
核心思想一句话:别让模型直接给答案,让它先把推理过程写出来。
为什么分步写就能更准?因为大模型的推理有个特点:它的"思考"发生在生成文字的过程中。你让它直接给答案,它靠"直觉"答题,容易出错
★
打个比方:直接问是"心算",思维链是"列竖式"。心算高手也会栽在复杂题上,但列竖式几乎不会错。
两种用法
① Zero-shot CoT:什么都不用准备,加一句话
在问题后面追加"请一步步思考后再回答",立刻生效:
String answer = chatClient.prompt()
.user("一个笼子里有鸡和兔,共 35 个头、94 只脚,各有几只?"
+ "请一步步思考,最后给出结论。")
.call()
.content();
模型会输出类似:
设鸡 x 只,兔 y 只:
x + y = 35
2x + 4y = 94
由 x = 35 - y,代入得 2(35-y) + 4y = 94
70 + 2y = 94,y = 12
所以兔 12 只,鸡 23 只。
② Few-shot CoT:示例里带上推理过程
比 Zero-shot 更强。示例里展示"怎么一步步想",模型就会照抄这个思考模式:
String template = """
解答下面应用题,每道题都要写出完整的推理步骤。
示例:小明买了 3 个苹果和 2 个梨,共花 17 元;苹果 3 元一个,梨多少钱?
解:苹果总价 = 3 × 3 = 9 元
梨的总价 = 17 - 9 = 8 元
梨的单价 = 8 ÷ 2 = 4 元
答案:4 元。
题目:{{question}}
""";
PromptTemplate pt = new PromptTemplate(template);
Prompt prompt = pt.create(Map.of("question", "学校买来 5 个篮球和 4 个足球,共 620 元;篮球 60 元一个,足球多少钱?"));
String answer = chatClient.prompt(prompt)
.options(ChatOptions.builder().temperature(0.2).build()) // 推理任务调低温度,输出更稳定
.call()
.content();
注意那个 .temperature(0.2)------推理类任务把温度调低,模型就不容易"放飞自我"瞎编过程。
一个提醒
思维链不是万能的。简单问题("今天天气怎么样")加"一步步思考"纯属浪费 token,还可能把简单的说复杂。判断题、分类题、简单问答,直接用;数学题、逻辑推理、多条件决策,才上 CoT。
06 · 三板斧合体:一个能直接抄的工单分类 Demo
单招练完,看看组合拳的威力。下面这个例子同时用了三招:
-
角色设定:资深客服主管,管住了说话方式和专业度
-
Few-shot:两个示例定义了"分类标准"和"输出口径"
-
思维链:规定了处理流程(先分类 → 再评级 → 后总结 → 给建议)
-
再加一个 :结构化输出
.entity(),直接把结果映射成 Java 对象// 目标类型:一个 record 就够
public record Ticket(
String category, // 问题分类
String level, // 紧急程度
String summary, // 一句话摘要
String suggestion) // 处理建议
{}@RestController
public class TicketController {private final ChatClient chatClient; public TicketController(ChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/ticket") public Ticket handle(@RequestParam String feedback) { return chatClient.prompt() .system(""" 你是资深客服主管,负责给用户反馈分类。 分类标准参考两个例子: 例1:用户说「登录失败三次,账号被锁」→ 账号问题 / 紧急 例2:用户问「会员一年多少钱」→ 咨询 / 普通 处理流程:先定分类 → 再评紧急程度 → 概括问题 → 给出处理建议。 只输出 JSON,不要任何多余文字。 """) .user(feedback) .call() .entity(Ticket.class); }}
请求 GET /ticket?feedback=页面一直转圈打不开,急死人了,返回的就是一个标准的 Java 对象:
{
"category": "系统故障",
"level": "紧急",
"summary": "页面无法加载",
"suggestion": "优先排查服务可用性,同步安抚用户"
}
整个过程中模型做了分类、评级、摘要、建议四件事,你的业务代码一行解析都不用写。这就是组合拳的威力:角色管语气,示例管格式,思维链管过程,结构化输出管结果。
07 · 三板斧之外的几个旋钮
把三板斧练熟之后,还有几个"旋钮"值得知道,它们和上一期聊的 LLM 原理直接挂钩:
| 旋钮 | 作用 | 一句话建议 |
|---|---|---|
temperature |
控制回答的随机性(0~2) | 事实问答调低(0.2~0.4),创意写作调高(0.8~1) |
topP |
核采样,控制候选词范围 | 一般和 temperature 二选一调,别两个都动 |
maxTokens |
限制回答长度 | 顺手设上,防止模型长篇大论烧钱 |
| 输出格式约束 | JSON / JSON Schema | 配合 .entity() 用,直接拿到 Java 对象 |
这些参数为什么这么调,背后的道理就在 LLM 原理那篇文章里(Softmax 之后怎么采样、温度怎么改变概率分布)。建议串起来看。
08 · 写在最后
很多人把提示词工程当成"魔法咒语",到处收藏口诀。其实拆穿了就是一句话:
把话说清楚,把场景说具体,把要求说完整。
-
告诉它"你是谁"(角色)
-
告诉它"照什么样子做"(Few-shot)
-
告诉它"按什么步骤想"(思维链)
说明 :本文由作者撰写,仅供学习交流,代码基于 Spring AI 2.0 / Spring Boot 4 编写。
下一期聊聊 大模型的API调用方式------这也是我们 AI Agent 学习路线的下一站。想继续的学习的点个【赞】和【推荐】让主编知道!顺手点个【关注】,感谢各位!