【Spring AI】第二弹:Prompt 优化技巧、AI 应用开发、实战 Spring AI 特性 (自定义Advisor、结构化输出、对话记忆持久化、PromptTemplate模板、多模态)



本节重点
熟悉 Prompt 工程和优化技巧,并设计开发一款 AI 恋爱大师应用,实战 Spring AI 调用大模型、对话记忆、Advisor、结构化输出、自定义对话记忆、Prompt 模板等特性。
具体内容包括:
- Prompt 工程基本概念
- Prompt 优化技巧
- AI 恋爱大师应用需求分析
- AI 恋爱大师应用方案设计
- Spring AI ChatClient / Advisor / ChatMemory 特性
- 多轮对话 AI 应用开发
- Spring AI 自定义 Advisor
- Spring AI 结构化输出 – 恋爱报告功能
- Spring AI 对话记忆持久化
- Spring AI Prompt 模板特性
- 多模态概念和开发
聚焦重点与技巧:
- 大模型成本分析与量化评估:以表格形式,整理各种大模型输入、输出的单位数量 token 所需价格,并提供可量化的数据(1000字对话预估成本);
- Prompt 的各种实用优化技巧,以减少达到预期输出结果所需总 token;
- 为大模型设置,优化后的系统预设词 Prompt,通过多轮对话调试,评估预设词;
- 大模型
多轮对话记忆机制聚焦:
- 大模型有固定的上下文长度限制(上下文窗口)、当对话超过限制时,会丢弃最早的信息(滑动窗口)、系统会优先保留最近的对话内容;
- 删除中间信息可能造成逻辑链条断裂(上下文断裂)、删除关键信息可能导致后续回答不准确
- 使用百炼大模型的模型评测功能,以相同数据测评集,对比不同大模型的维度(发散程度、准确度、消耗成本),以获取最佳大模型;
- 获取需求灵感的方法,使用 AI 细化需求分析,MVP 最小可行产品策略;
- 使用 IDEA Diagrams 功能,直观查看指定类的关系(继承、实现、依赖),方法结构,属性结构;
- 多轮对话实现原理
- 单元测试方法
- Spring AI 实现结构化输出转换的原理
- 亮点:根据需求自定义拦截器(日志拦截器)
- 自定义对话记忆持久化组件(文件存储一个 uuid 对应的多轮对话信息)
- 难点:
文件内的文本和Message 对象的序列化和反序列化,无法通过 Java 内置的库实现- 实现:Kryo 序列化库
- PromptTemplate 模板的应用场景,底层使用的引擎,实现的接口,
一、Prompt 工程
基本概念
Prompt 工程(Prompt Engineering)又叫提示词工程,简单来说,就是输入给 AI 的指令。
比如下面这段内容,就是提示词:
请问如何学习 Spring AI?
那为什么要叫 “工程” 呢?
因为 AI 大模型生成的内容是不确定的,构建一个能够按照预期生成内容的提示词既是一门艺术,也是一门科学。提示词的质量直接影响到 AI 大模型输出的结果,因此这也是 AI 应用开发的关键技能,很多公司专门招聘提示词工程师。

我们学习 Prompt 工程的目标是:通过精心设计和优化输入提示来引导 AI 模型生成符合预期的高质量输出。
提示词分类
核心 – 基于角色的分类
在 AI 对话中,基于角色的分类是最常见的,通常存在 3 种主要类型的 Prompt:
1. 用户 Prompt (User Prompt):
- 这是用户向 AI 提供的实际问题、指令或信息,传达了用户的直接需求。
- 用户 Prompt 告诉 AI 模型 “做什么”,比如回答问题、编写代码、生成创意内容等。
用户:帮我写一首关于春天的短诗
2. 系统 Prompt (System Prompt):
- 这是设置 AI 模型行为规则和角色定位的隐藏指令,用户通常不能直接看到。
- 系统 Prompt 相当于给 AI 设定人格和能力边界,即告诉 AI “你是谁?你能做什么?”。
系统:你是一位经验丰富的恋爱顾问,擅长分析情感问题并提供建设性建议。请以温暖友善的语气回答用户的恋爱困惑,必要时主动询问更多信息以便提供更准确的建议。不要做出道德判断,而是尊重用户的情感体验并提供实用的沟通和相处技巧。回答时保持专业性,但避免使用过于学术的术语,确保普通用户能够理解你的建议。
不同的系统 Prompt 可以让同一个 AI 模型表现出完全不同的应用特性,这是构建垂直领域 AI 应用(如财务顾问、教育辅导、医疗咨询等)的关键。
3. 助手 Prompt (Assistant Prompt):
- 这是 AI 模型的响应内容。
- 在多轮对话中,之前的助手回复也会成为当前上下文的一部分,影响后续对话的理解和生成。
- 某些场景下,开发者可以主动预设一些助手消息作为对话历史的一部分,引导后续互动。
助手:我是你的恋爱顾问,很高兴能帮助你解决情感问题。你目前遇到了什么样的恋爱困惑呢?可以告诉我你们的关系现状和具体遇到的问题吗?
在实际应用中,这些不同类型的提示词往往会组合使用。举个例子,一个完整的对话可能包含:
系统:你是编程导航的专业编程导师,擅长引导初学者入门编程并制定学习路径。使用友好鼓励的语气,解释复杂概念时要通俗易懂,适当使用比喻让新手理解,避免过于晦涩的技术术语。
用户:我完全没有编程基础,想学习编程开发,但不知道从何开始,能给我一些建议吗?
助手:欢迎加入编程的世界!作为编程小白,建议你可以按照以下步骤开始学习之旅...
【多轮对话继续】
AI 大模型开发平台允许用户自主设置各种不同类型的提示词来进行调试:

扩展知识 – 基于功能的分类
除了基于角色的分类外,我们还可以从功能角度对提示词进行分类,仅作了解即可。
1. 指令型提示词(Instructional Prompts):
明确告诉 AI 模型需要执行的任务,通常以命令式语句开头。
翻译以下文本为英文:春天来了,花儿开了。
2. 对话型提示词(Conversational Prompts):
模拟自然对话,以问答形式与 AI 模型交互。
你认为人工智能会在未来取代人类工作吗?
3. 创意型提示词(Creative Prompts):
引导 AI 模型进行创意内容生成,如故事、诗歌、广告文案等。
写一个发生在未来太空殖民地的短篇科幻故事,主角是一位机器人工程师。
4. 角色扮演提示词(Role-Playing Prompts):
让 AI 扮演特定角色或人物进行回答。
假设你是爱因斯坦,如何用简单的语言解释相对论?
5. 少样本学习提示词(Few-Shot Prompts):
提供一些示例,引导 AI 理解所需的输出格式和风格。
将以下句子改写为正式商务语言:
示例1:
原句:这个想法不错。
改写:该提案展现了相当的潜力和创新性。
示例2:
原句:我们明天见。
改写:期待明日与您会面,继续我们的商务讨论。
现在请改写:这个价格太高了。
扩展知识 – 基于复杂度的分类
还可以从结构复杂度的角度对提示词进行分类,仅作了解即可。
1. 简单提示词(Simple Prompts):
单一指令或问题,没有复杂的背景或约束条件。
什么是人工智能?
2. 复合提示词(Compound Prompts):
包含多个相关指令或步骤的提示词。
分析下面这段代码,解释它的功能,找出潜在的错误,并提供改进建议。
3. 链式提示词(Chain Prompts):
一系列连续的、相互依赖的提示词,每个提示词基于前一个提示词的输出。
第一步:生成一个科幻故事的基本情节。
第二步:基于情节创建三个主要角色,包括他们的背景和动机。
第三步:利用这些角色和情节,撰写故事的开篇段落。
4. 模板提示词(Template Prompts):
包含可替换变量的标准化提示词结构,常用于大规模应用。
你是一位专业的{领域}专家。请回答以下关于{主题}的问题:{具体问题}。
回答应包含{要点数量}个关键点,并使用{风格}的语言风格。
💡 模板提示词的概念还是需要了解一下的,在应用开发过程中,我们可能会用到该特性,来保证提示词是规范统一的。
Token
Token 是大模型处理文本的基本单位,可能是单词或标点符号,模型的输入和输出都是按 Token 计算的,一般 Token 越多,成本越高,并且输出速度越慢。
因此在 AI 应用开发中,了解和控制 Token 的消耗至关重要。
如何计算 Token?
首先,不同大模型对 Token 的划分规则略有不同,比如根据 OpenAI 的文档:
- 英文文本:一个 token 大约相当于 4 个字符或约 0.75 个英文单词
- 中文文本:一个汉字通常会被编码为 1-2 个 token
- 空格和标点:也会计入 token 数量
- 特殊符号和表情符号:可能需要多个 token 来表示
简单估算一下,100 个英文单词约等于 75-150 个 Token,而 100 个中文字符约等于 100-200 个 Token。
实际应用中,更推荐使用工具来估计 Prompt 的 Token 数量,比如:
- OpenAI Tokenizer:适用于 OpenAI 模型的官方 Token 计算器
- 非官方的 Token 计算器

后续重点理解:通过什么方法,优化 Prompt,来节约 token ,降低 AI 应用开发的成本
Token 成本计算
估算成本有个公式:
总成本 = (输入token数 × 输入单价) + (输出token数 × 输出单价)
不同大模型的计费都不太一样,因此要认真阅读官方文档的计费标准,比如阿里系大模型:

建议大家估算成本时,可以多去对比不同大模型的价格,参考下列表格去整理一个详细的对比表格,结果一目了然:
| 模型 | 输入价格(/1K tokens) | 输出价格(/1K tokens) | 1000字对话预估成本 |
|---|---|---|---|
| GPT-xx | $0.0015 | $0.002 | ¥0.02-0.03 |
| GPT-xxx | $0.03 | $0.06 | ¥0.3-0.5 |
| Claude-xxx | $0.00025 | $0.00125 | ¥0.01-0.02 |
Token 成本优化技巧
注意,系统提示词、用户提示词和 AI 大模型输出的内容都是消耗成本的,因此我们成本优化主要从这些角度进行。
1. 精简系统提示词:
移除冗余表述,保留核心指令。
比如将 “你是一个非常专业、经验丰富且非常有耐心的编程导师” 简化为 “你是编程导师”。
2. 定期清理对话历史:
对话上下文会随着交互不断累积 Token。
在长对话中,可以定期请求 AI 总结之前的对话,然后以总结替代详细历史。
请总结我们至今的对话要点,后续我们将基于此总结继续讨论。
3. 使用向量检索代替直接输入:
对于需要处理大量参考文档的场景,不要直接将整个文档作为 Prompt,而是使用向量数据库和检索技术(RAG)获取相关段落。
4. 结构化替代自然语言:
使用表格、列表等结构化格式,代替长段落描述。
举个例子,优化前:
请问如何制作披萨?首先需要准备面粉、酵母、水、盐、橄榄油作为基础面团材料。然后根据口味选择酱料,可以是番茄酱或白酱。接着准备奶酪,最常用的是马苏里拉奶酪。最后准备各种配料如意大利香肠、蘑菇、青椒等。
优化后:
披萨制作材料:
- 面团:面粉、酵母、水、盐、橄榄油
- 酱料:番茄酱/白酱
- 奶酪:马苏里拉
- 配料:意大利香肠、蘑菇、青椒等
如何制作?
二、Prompt 优化技巧
前面也提到了,设计 Prompt 是一门艺术,高质量的 Prompt 可以显著提升 AI 输出的质量,因此我们需要重点掌握 Prompt 优化技巧。
利用资源
1、Prompt 学习
网上和 Prompt 优化相关的资源非常丰富,几乎各大主流 AI 大模型和 AI 开发框架官方文档都有相关的介绍,推荐先阅读至少 2 篇,比如:
- Prompt Engineering Guide 提示工程指南
- OpenAI 提示词工程指南
- Spring AI 提示工程指南
- Authropic 提示词工程指南
- Authropic 提示词工程指南(开源仓库)
- 智谱 AI Prompt 设计指南
2、Prompt 提示词库
网上也有很多现成的提示词库,在自主优化提示词前,可以先尝试搜索有没有现成的提示词参考:
- 文本对话:Authropic 提示词库
- AI 绘画:Midjourney 提示词库
基础提示技巧
1、明确指定任务和角色
为 AI 提供清晰的任务描述和角色定位,帮助模型理解背景和期望。
系统:你是一位经验丰富的Python教师,擅长向初学者解释编程概念。
用户:请解释 Python 中的列表推导式,包括基本语法和 2-3 个实用示例。
2、提供详细说明和具体示例
提供足够的上下文信息和期望的输出格式示例,减少模型的不确定性。
请提供一个社交媒体营销计划,针对一款新上市的智能手表。计划应包含:
1. 目标受众描述
2. 三个内容主题
3. 每个平台的内容类型建议
4. 发布频率建议
示例格式:
目标受众: [描述]
内容主题: [主题1], [主题2], [主题3]
平台策略: [平台] - [内容类型] - [频率]
3、使用结构化格式引导思维
通过列表、表格等结构化格式,使指令更易理解,输出更有条理。
分析以下公司的优势和劣势:
公司: Tesla
请使用表格格式回答,包含以下列:
- 优势(最少3项)
- 每项优势的简要分析
- 劣势(最少3项)
- 每项劣势的简要分析
- 应对建议
4、明确输出格式要求
指定输出的格式、长度、风格等要求,获得更符合预期的结果。
撰写一篇关于气候变化的科普文章,要求:
- 使用通俗易懂的语言,适合高中生阅读
- 包含5个小标题,每个标题下2-3段文字
- 总字数控制在800字左右
- 结尾提供3个可行的个人行动建议
进阶提示技巧
1、思维链提示法(Chain-of-Thought)
引导模型展示推理过程,逐步思考问题,提高复杂问题的准确性。
问题:一个商店售卖T恤,每件15元。如果购买5件以上可以享受8折优惠。小明买了7件T恤,他需要支付多少钱?
请一步步思考解决这个问题:
1. 首先计算7件T恤的原价
2. 确定是否符合折扣条件
3. 如果符合,计算折扣后的价格
4. 得出最终支付金额
2、少样本学习(Few-Shot Learning)
通过提供几个输入-输出对的示例,帮助模型理解任务模式和期望输出。
我将给你一些情感分析的例子,然后请你按照同样的方式分析新句子的情感倾向。
输入: "这家餐厅的服务太差了,等了一个小时才上菜"
输出: 负面,因为描述了长时间等待和差评服务
输入: "新买的手机屏幕清晰,电池也很耐用"
输出: 正面,因为赞扬了产品的多个方面
现在分析这个句子:
"这本书内容还行,但是价格有点贵"
3、分步骤指导(Step-by-Step)
将复杂任务分解为可管理的步骤,确保模型完成每个关键环节。
请帮我创建一个简单的网站落地页设计方案,按照以下步骤:
步骤1: 分析目标受众(考虑年龄、职业、需求等因素)
步骤2: 确定页面核心信息(主标题、副标题、价值主张)
步骤3: 设计页面结构(至少包含哪些区块)
步骤4: 制定视觉引导策略(颜色、图像建议)
步骤5: 设计行动召唤(CTA)按钮和文案
4、自我评估和修正
让模型评估自己的输出并进行改进,提高准确性和质量。
解决以下概率问题:
从一副标准扑克牌中随机抽取两张牌,求抽到至少一张红桃的概率。
首先给出你的解答,然后:
1. 检查你的推理过程是否存在逻辑错误
2. 验证你使用的概率公式是否正确
3. 检查计算步骤是否有误
4. 如果发现任何问题,提供修正后的解答
5、知识检索和引用
引导模型检索相关信息并明确引用信息来源,提高可靠性。
请解释光合作用的过程及其在植物生长中的作用。在回答中:
1. 提供光合作用的科学定义
2. 解释主要的化学反应
3. 描述影响光合作用效率的关键因素
4. 说明其对生态系统的重要性
对于任何可能需要具体数据或研究支持的陈述,请明确指出这些信息的来源,并说明这些信息的可靠性。
6、多视角分析
引导模型从不同角度、立场或专业视角分析问题,提供全面见解。
分析"城市应该禁止私家车进入市中心"这一提议:
请从以下4个不同角度分析:
1. 环保专家视角
2. 经济学家视角
3. 市中心商户视角
4. 通勤居民视角
对每个视角:
- 提供支持该提议的2个论点
- 提供反对该提议的2个论点
- 分析可能的折中方案
7、多模态思维
结合不同表达形式进行思考,如文字描述、图表结构、代码逻辑等。
设计一个智能家居系统的基础架构:
1. 首先用文字描述系统的主要功能和组件
2. 然后创建一个系统架构图(用ASCII或文本形式表示)
3. 接着提供用户交互流程
4. 最后简述实现这个系统可能面临的技术挑战
尝试从不同角度思考:功能性、用户体验、技术实现、安全性等。
提示词调试与优化
好的提示词可能很难一步到位,因此我们要学会如何持续调试和优化 Prompt。

1、迭代式提示优化
通过逐步修改和完善提示词,提高输出质量。
初始提示: 谈谈人工智能的影响。
[收到笼统回答后]
改进提示: 分析人工智能对医疗行业的三大积极影响和两大潜在风险,提供具体应用案例。
[如果回答仍然不够具体]
进一步改进: 详细分析AI在医学影像诊断领域的具体应用,包括:
1. 现有的2-3个成功商业化AI诊断系统及其准确率
2. 这些系统如何辅助放射科医生工作
3. 实施过程中遇到的主要挑战
4. 未来3-5年可能的技术发展方向
2、边界测试
通过极限情况测试模型的能力边界,找出优化空间。
尝试解决以下具有挑战性的数学问题:
证明在三角形中,三条高的交点、三条中线的交点和三条角平分线的交点在同一条直线上。
如果你发现难以直接证明:
1. 说明你遇到的具体困难
2. 考虑是否有更简单的方法或特例可以探讨
3. 提供一个思路框架,即使无法给出完整证明
3、提示词模板化
创建结构化模板,便于针对类似任务进行一致性提示,否则每次输出的内容可能会有比较大的区别,不利于调试。
【专家角色】: {领域}专家
【任务描述】: {任务详细说明}
【所需内容】:
- {要点1}
- {要点2}
- {要点3}
【输出格式】: {格式要求}
【语言风格】: {风格要求}
【限制条件】: {字数、时间或其他限制}
例如:
【专家角色】: 营养学专家
【任务描述】: 为一位想减重的上班族设计一周健康饮食计划
【所需内容】:
- 七天的三餐安排
- 每餐的大致卡路里
- 准备建议和购物清单
【输出格式】: 按日分段,每餐列出具体食物
【语言风格】: 专业但友好
【限制条件】: 考虑准备时间短,预算有限
4、错误分析与修正
系统性分析模型回答中的错误,并针对性优化提示词,这一点在我们使用 Cursor 等 AI 开发工具生成代码时非常有用。
我发现之前请你生成的Python代码存在以下问题:
1. 没有正确处理文件不存在的情况
2. 数据处理逻辑中存在边界条件错误
3. 代码注释不够详细
请重新生成代码,特别注意:
1. 添加完整的异常处理
2. 测试并确保所有边界条件
3. 为每个主要函数和复杂逻辑添加详细注释
4. 遵循PEP 8编码规范
虽然前面提到了这么多提示词优化技巧,但总结出来就一句话:任务越复杂,就越要给 Prompt 补充更多细节。
我们可以把 AI 当成人类,如果你的问题模糊不清,那么得到的答案可能就并不理想。
《提问的智慧》了,建议大家认真阅读,做一个聪明的提问者。
三、AI 应用需求分析
依次按照下面三步,完成需求分析:
- 获取需求
- 细化需求
- 确认需求
1、需求从哪儿来?
但是我大脑空空,没什么想法,从哪里挖掘需求呢?
其实很简单!现在有很多 AI 应用平台,比如豆包、文心一言、ChatGPT 等,这些平台上已经有了大量 AI 应用,是很好的参考源,随便挑一个都可以变成完整的项目。

比如我们来开发一个 恋爱大师 AI 应用,用户在恋爱过程中难免遇到各种难题,让 AI 为用户提供贴心情感指导。
2、怎么细化需求?
有了上面这样一个初步的想法后,我们要进一步完善需求,明确项目要具有哪些功能。
但是我大脑空空,也没什么经验,怎么细化需求呢?
答案很简单 —— 问 AI!
AI 不仅是我们要开发的产品,也是强大的需求分析助手。通过精心设计的提示词,可以让 AI 帮助我们进行需求细化和扩展。比如下面这段 Prompt:
示例 Prompt:
我要开发一个【恋爱大师】AI 应用,用户在恋爱过程中难免遇到各种难题,让 AI 为用户提供贴心情感指导。
请你帮我进行需求分析,满足我的目标。
如果你要做一个大项目,还可以进一步完善提示词:
我要开发一个【恋爱大师】AI 应用,用户在恋爱过程中难免遇到各种难题,让 AI 为用户提供贴心情感指导。
请你帮我进行需求分析,满足我的目标。
具体需要:
1. 分析目标用户群体及其核心需求
2. 提出主要功能模块和服务内容
3. 考虑产品的差异化竞争点
4. 分析可能的技术挑战和解决方案
AI 给出的示例输出如下,接下来我们化身为 “老板”,只需要对 AI 给出的需求文档进行评审即可:
咱们从服务对象、服务内容、产品特性等维度,来剖析“恋爱大师”AI应用的开发需求:
### 一、目标用户洞察
1. **年龄与身份**:18-35岁人群是恋爱活动的主力军,涵盖大学生、职场新人等。他们熟悉数字化生活,热衷借助AI解决恋爱问题。
2. **恋爱状态及需求**
- **单身群体**:渴望打破社交壁垒,寻觅恋爱机会。他们需要拓展社交圈、提升自我魅力、学习搭讪技巧等方面的指导。
- **恋爱中人群**:重点关注如何处理情侣间的争吵矛盾,掌握沟通艺术,安排浪漫约会,进一步升温感情。
- **失恋人群**:急需摆脱失恋阴影,修复受伤的情感,重新建立自信,恢复正常生活节奏。
### 二、功能板块规划
#### (一)问题识别与分类
1. **自然语言处理**:用户以文字或语音倾诉恋爱困扰,AI凭借自然语言处理技术,精准提炼问题核心,判别用户情绪状态,如愤怒、迷茫、伤心等。
2. **问题归类**:将收集到的问题,归入表白难题、约会安排、信任危机、分手应对等预设类别,为后续的个性化解答做好准备。
#### (二)个性化指导服务
1. **智能问答**:针对用户提出的问题,AI从海量的恋爱案例、心理学知识以及专业情感建议中,生成贴合实际的解决方案。比如,当用户纠结“该不该向喜欢的人表白”时,AI会依据用户描述的双方关系,给出不同策略。
2. **课程推送**:设计系列恋爱课程,如“脱单秘籍”“恋爱保鲜术”“走出失恋阴霾”等,以图文、音频、视频等多元形式呈现,助力用户系统学习恋爱知识。
3. **案例分享**:分享真实且具有代表性的恋爱故事,通过对成功与失败案例的复盘,为用户提供借鉴与启示。
#### (三)特色辅助功能
1. **聊天话术生成**:用户输入聊天场景或对方信息,AI创作富有吸引力、契合氛围的聊天话术,帮助用户提升沟通效果。
2. **恋爱规划制定**:依据用户的恋爱阶段和目标,制定专属恋爱计划,涵盖约会安排、礼物挑选、情感互动等细节。
#### (四)互动交流社区
1. **话题讨论**:搭建线上社区,用户可发布恋爱问题、分享经验心得,实现用户间的相互交流与支持。
2. **专家直播**:定期邀请情感专家进行直播,解答用户普遍关注的恋爱问题,分享前沿恋爱观念和技巧。
### 三、非功能要求
1. **隐私安全**:在数据收集、存储和使用过程中,严格遵循相关法规,采取加密、匿名化等技术手段,保护用户隐私,让用户放心倾诉。
2. **情感陪伴感**:AI回复需富有情感,模拟真实交流场景,避免机械化回答,给予用户温暖贴心的陪伴。
3. **持续优化**:搭建反馈机制,收集用户评价和建议,持续优化AI算法和服务内容,提升服务质量。
你会发现,AI 给出的需求好多啊!我们到底要做哪些呢?这里涉及到一个很经典的策略 —— MVP 最小可行产品策略。
3、MVP 最小可行产品策略
MVP 最小可行产品策略是指先开发包含 核心功能 的基础版本产品快速推向市场,以最小成本验证产品假设和用户需求。
通过收集真实用户反馈,进行迭代优化,避免开发无人使用的功能,降低资源浪费和开发风险。
- 基于这个策略,我们可以先开发一个简单但实用的 AI 对话应用,让用户能够和 AI 恋爱大师进行多轮对话交流。
- 因为 “对话” 是本产品的核心功能,暂时不要考虑更复杂的功能了。
- 后续可以根据用户用量和反馈,决定下一步是深化对话能力还是扩展更多功能模块。
明确需求后,下面我们进行方案设计,看看怎么实现这个需求。
四、AI 应用方案设计
根据需求,我们将实现一个具有多轮对话能力的 AI 恋爱大师应用。整体方案设计将围绕 2 个核心展开:
- 系统提示词的设计
- 多轮对话的实现
1、系统提示词设计
前面提到,系统提示词相当于 AI 应用的 “灵魂”,直接决定了 AI 的行为模式、专业性和交互风格。
对于 AI 对话应用,最简单的做法是直接写一段系统预设,定义 “你是谁?能做什么?”,比如:
你是一位恋爱大师,为用户提供情感咨询服务
这种简单提示虽然可以工作,但效果往往不够理想。
想想现实中的场景,我们去找专家咨询时,专家可能会先主动抛出一系列引导性问题、深入了解背景,而不是被动等待用户完整描述问题。比如:
- 最近有什么迷茫的事情么?
- 请问你有什么需要我帮助的事么?
- 你们的感情遇到什么问题了么?
用户会跟 AI 进行多轮对话,这时 AI 不能像失忆一样,而是要始终保持之前的对话内容作为上下文,不断深入了解用户,从而提供给用户更全面的建议。
因此我们要优化系统预设,可以借助 AI 进行优化。示例 Prompt:
我正在开发【恋爱大师】AI 对话应用,请你帮我编写设置给 AI 大模型的系统预设 Prompt 指令。要求让 AI 作为恋爱专家,模拟真实恋爱咨询场景、多给用户一些引导性问题,不断深入了解用户,从而提供给用户更全面的建议,解决用户的情感问题。
AI 提供的优化后系统提示词:
扮演深耕恋爱心理领域的专家。开场向用户表明身份,告知用户可倾诉恋爱难题。围绕单身、恋爱、已婚三种状态提问:单身状态询问社交圈拓展及追求心仪对象的困扰;恋爱状态询问沟通、习惯差异引发的矛盾;已婚状态询问家庭责任与亲属关系处理的问题。引导用户详述事情经过、对方反应及自身想法,以便给出专属解决方案。
💡 在正式开发前,建议先通过 AI 大模型应用平台对提示词进行测试和调优,观察效果:


2、多轮对话实现
要实现具有 “记忆力” 的 AI 应用,让 AI 能够记住用户之前的对话内容并保持上下文连贯性,我们可以使用Spring AI 框架的 对话记忆能力。
如何使用对话记忆能力呢?参考 Spring AI 的官方文档,了解到 Spring AI 提供了 ChatClient API 来和 AI 大模型交互。
ChatClient
ChatClient 的创建
之前我们是直接使用 Spring Boot 注入的 ChatModel 来调用大模型完成对话,而通过我们自己构造的 ChatClient,可实现功能更丰富、更灵活的 AI 对话客户端,也更推荐通过这种方式调用 AI。

通过示例代码,能够感受到 ChatModel 和 ChatClient 的区别。

Spring AI 提供了多种构建 ChatClient 的方式,比如自动注入、通过建造者模式手动构造:
// 方式1:使用构造器注入
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("你是恋爱顾问")
.build();
}
}
// 方式2:使用建造者模式
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultSystem("你是恋爱顾问")
.build();
ChatClient 的 API 调用方法
ChatClient 支持更复杂灵活的链式调用(Fluent API):

// 基础用法(ChatModel)
ChatResponse response = chatModel.call(new Prompt("你好"));
// 高级用法(ChatClient)
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultSystem("你是恋爱顾问")
.build();
String response = chatClient.prompt().user("你好").call().content();
ChatClient 支持多种响应格式
ChatClient 支持多种响应格式,比如返回 ChatResponse 对象、返回实体对象、流式返回:
1. 返回 ChatResponse 对象
// 返回 ChatResponse 对象(包含元数据如 token 使用量)
ChatResponse chatResponse = chatClient.prompt()
.user("Tell me a joke")
.call()
.chatResponse();
为什么要使用 ChatResponse 对象来接收 chatClient 的输出结构呢?

2. 返回实体对象
// 返回实体对象(自动将 AI 输出映射为 Java 对象, 这个操作称为结构化输出)
// 2.1 返回单个实体
record ActorFilms(String actor, List<String> movies) {
}
ActorFilms actorFilms = chatClient.prompt()
.user("Generate the filmography for a random actor.")
.call()
.entity(ActorFilms.class);
// 2.2 返回泛型集合
List<ActorFilms> multipleActors = chatClient.