AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话

简介:

项目地址:https://github.com/whltaoin/var-ai-agent

本文使用的AI大模型均为阿里云的灵积模型(*Qwen-Plus)

一、Prompt 基本概念

简介:

Prompt(提示词)是用户向模型传递指令、需求、上下文或问题的文本输入,是连接人类意图与 AI 输出的核心桥梁。简单来说,Prompt 就是 "你对 AI 说的话",但它并非随意的表述 ------ 精准、清晰的 Prompt 能直接决定 AI 输出的质量、相关性和准确性。

二、Prompt 优化技巧

AI的本质是"预测文本序列",而非"理解抽象意图"。优化的核心目标是:消除模糊性,给模型明确的"执行路径"

→ 关键逻辑:你的Prompt越像"操作手册",AI的输出越像"标准答案"。

三、10个实用优化技巧(附正反例对比)

1. 任务拆解:复杂需求"分步走"

原理:大模型对"单步骤明确任务"的处理能力远强于"多目标模糊任务"。将复杂需求拆分为递进式步骤,降低模型理解成本。

反例(模糊复杂):

"写一篇关于人工智能的文章,要专业又易懂,还要有案例和未来趋势。"

正例(分步拆解):

"请分3步写一篇关于人工智能的文章:

  1. 先用200字解释AI的核心原理(用高中生能理解的语言);
  2. 举2个AI在医疗领域的实际应用案例(每个案例100字);
  3. 最后预测AI未来3年的3个发展趋势(侧重技术落地层面)。"

2. 角色绑定:给模型"身份定位"

原理:让模型"代入"特定角色(如专家、教师、设计师),可激活其对应领域的知识储备和表达风格。

反例 (无角色):

"分析一下这个市场报告,说说有什么问题。"

正例 (绑定角色):

"假设你是拥有10年经验的电商行业分析师,现在需要审核这份2023年美妆市场报告。请从'数据准确性''竞争分析完整性''消费趋势预测合理性'3个维度,指出至少3个关键问题,并给出具体修改建议。"

3. 输出格式"强指定":拒绝"自由发挥"

原理:明确输出格式(如表格、列表、代码块、Markdown),可直接复用结果,减少二次加工成本。

反例 (无格式要求):

"对比一下Python和Java的区别。"

正例 (指定格式):

"请用Markdown表格对比Python和Java,包含以下5列:对比维度(如'语法风格''执行效率')、Python特点、Java特点、适用场景、学习难度(1-5分)。"

4. 思维链引导:让模型"逐步推理"

原理:对需要逻辑分析、计算或推理的任务,引导模型"先说思路,再给结论",避免跳跃式输出(尤其适合数学题、逻辑题)。

反例 (直接要结果):

"一个水池有进水管和出水管,单开进水管3小时注满,单开出水管5小时排空。现在两管同时开,几小时注满水池?"

正例 (思维链引导):

"请先分析解题步骤,再计算结果:

  1. 先确定进水管和出水管的效率(每小时工作量);
  2. 计算两管同时开时的净效率;
  3. 用总工作量除以净效率,得到注满时间。
    (水池总量可视为1)"

5. 示例锚定:用"输入-输出对"定风格

原理:对"风格化""规则性"任务(如翻译、改写、分类),提供1-2个示例,让模型"照葫芦画瓢"(少样本学习)。

反例 (无示例,风格模糊):

"把这些短句改得更有诗意。"

正例 (示例锚定):

"请模仿以下风格,将短句改写成诗意表达:

例1:原句'月亮在天上'→改写'月悬青冥,似一枚被时光擦亮的玉盘';

例2:原句'风吹过树叶'→改写'风穿过叶隙,把阳光剪成细碎的光斑';

现在改写:'雨点落在窗上'→?"

6. 限定范围:给AI"划边界"

原理:对可能产生冗余信息的任务(如总结、列举),明确"数量""范围""重点",避免输出无关内容。

反例 (无范围):

"总结一下这篇文章的观点。"

正例 (限定范围):

"总结这篇关于'远程办公'的文章,只提炼3个核心观点,每个观点不超过20字,且必须包含原文中的数据支撑(如'提升效率20%')。"

7. 语气/风格"精确描述":从"大概"到"具体"

原理:对创作类任务(如文案、故事),用具体形容词描述风格(避免"好一点""生动点"等模糊词)。

反例 (风格模糊):

"写一段手机的宣传语,要吸引人。"

正例 (风格精确):

"写一段针对大学生的手机宣传语,要求:

  • 风格:活泼口语化,带点网络热梗(如'绝绝子''躺赢');
  • 突出2个卖点:5000mAh电池(强调'连续玩游戏10小时')、256G大存储(强调'装得下4年网课资料');
  • 结尾加一句行动号召(如'戳链接抢首发')。"

8. 上下文"结构化":关键信息"标重点"

原理:当Prompt包含长文本(如文档、对话历史)时,用编号、加粗、分段等方式突出关键信息,避免模型忽略重点。

反例 (信息杂乱):

"用户说他昨天买的衣服尺码小了,想换大一号,但是发票找不到了,问能不能换。另外他还说衣服有点线头,不过不影响穿。你帮我回复一下。"

正例 (结构化上下文):

"请回复用户,需包含以下信息:

  1. 用户核心诉求:昨天购买的衣服尺码小,想换大一号(无发票);
  2. 次要信息:衣服有线头(不影响穿着);
  3. 回复要点:
    • 无发票可凭支付记录换货;
    • 承诺收到后24小时内发新货;
    • 线头问题可补偿5元优惠券;
    • 语气友好,用'亲'开头。"

9. 反向约束:告诉AI"不要做什么"

原理:对有明确"禁忌"的任务(如避免敏感词、不出现冗余内容),直接列出"禁止项"。

反例 (只说要什么,不说不要什么):

"写一篇关于'减肥'的文章,要科学。"

正例 (反向约束):

"写一篇科学减肥指南,要求:

  • 必须包含'热量缺口''蛋白质摄入''基础代谢'3个核心概念;
  • 禁止出现'绝食''7天瘦10斤'等极端方法;
  • 不引用任何'网红减肥产品';
  • 结尾强调'健康可持续'的理念。"

10. 迭代优化:"基于初稿改"比"重新写"更高效

原理:若第一次输出不符合预期,不要重新写Prompt,而是"指出问题+明确修正方向",利用模型的上下文记忆能力优化结果。

第一次Prompt

"写一个关于猫咪的短故事,300字左右。"

AI初稿问题:故事平淡,没有冲突。

优化Prompt(迭代)

"你之前写的猫咪故事缺少情节冲突。请修改:

  1. 增加一个核心冲突(如'猫咪走失后遇到流浪猫群体');
  2. 加入2处细节描写(如猫咪的动作、环境氛围);
  3. 结尾保持温暖风格,字数控制在350字以内。"

四、分场景优化重点

场景 优化核心技巧 示例Prompt片段
创作类(文案、故事) 角色绑定+风格描述+示例锚定 "假设你是迪士尼动画编剧,写一段小熊冒险的台词,风格要幽默温暖,参考:'嘿,别担心,蜂蜜总会有的!'"
分析类(报告、解读) 任务拆解+限定范围+输出格式 "用SWOT模型分析新能源汽车行业,分4点列出,每点附1个2023年的数据案例,用列表呈现。"
代码类(编程、调试) 上下文结构化+输出格式+反向约束 "用Python写一个爬虫,爬取豆瓣Top250电影名和评分,要求:①使用requests库;②禁止爬取个人信息;③输出为CSV格式(附代码注释)。"
问答类(知识、解决问题) 思维链引导+限定范围 "解释'相对论'时,先讲清楚'惯性系'和'光速不变'两个前提,再用生活化例子(如'火车上抛球')说明,避免公式。"

五、常见误区:这些"坑"要避开

  1. 信息过载:Prompt不是越长越好,无关信息会稀释核心指令(建议单条Prompt控制在500字内)。
  2. 指令冲突:避免同时提矛盾要求(如"写一篇极简的长文""用专业术语写得通俗易懂")。
  3. 过度模糊:不用"可能""大概""尽量"等词(AI会倾向于保守输出)。

六、propmt优化总结

Prompt优化的本质是"换位思考"------站在AI的角度,思考"如何让文本指令更易被解析"。新手可从"明确任务→指定格式→补充示例"三步法开始,逐步尝试角色绑定、思维链等进阶技巧。记住:好的Prompt是"练"出来的,多根据AI的输出调整,很快就能掌握规律。

七、学术分析AI应用需求分析

在AI 时⁠代下,开发应用的门槛变得越来越低了,‌导致市面上出现了各种具有创意的小产品。也让越来越多人意识到,技术并不是‎产品成功的决定性因素,而是在于你有没‌有把握住用户的需求、解决用户的痛点。

因此,开发人员需要重点培养需求分析能力。

怎么进行需⁠求分析呢?分享一个 "三步走" 方法:获取需求‎ => 细化需求 ‌=> 确认需求

(一)、需求怎么来

在头脑风暴中,我们要是没有开发关于AI应用的想法时,我们可以参考各大大模型中以及发布的智能体应用。

例如:阿里百炼中有各种各样的智能体应用:https://bailian.console.aliyun.com/?tab=app#/app-market/newTemplate

参照阿里的应用我们可以试着开发一个关于可以帮助学者编写论文的应用------学术分析AI应用

(二)、怎么细化需求

  1. 我们在通过需求分析后,得到了我们要的主题,现在可以进一步的完善需求和明确项目要具有哪些功能。
  2. 同样我们可以借助AI来帮助我们完成此功能。
  3. 精简版prompt:
plain 复制代码
我要开发一个【学术分析】AI 应用,解决用户在编写论文中难免遇到各种难题,让 AI 为用户提供贴心论文编写指导。
请你帮我进行需求分析,满足我的目标。

得到的结果:

plain 复制代码
一、核心目标与定位
开发一款专注于学术论文写作的AI辅助工具,通过人工智能技术解决用户在论文创作全流程中的痛点问题,提供个性化、专业的学术写作指导,提升论文质量与写作效率。
二、目标用户群体
1. 学生群体:本科生(毕业论文)、硕士生、博士生(学位论文)
2. 科研人员:高校教师、研究所研究员(期刊论文、会议论文)
3. 学术新人:首次尝试学术写作的各类人员
三、核心功能需求
1. 论文规划与结构指导
● 提供各学科标准论文结构模板(引言、文献综述、研究方法等)
● 根据学科特点和论文类型(期刊/学位/会议)定制框架
● 章节逻辑关系检查与优化建议
● 写作进度规划与提醒
2. 内容创作辅助
● 研究问题凝练与明确化建议
● 文献综述撰写指导(主题聚焦、逻辑组织)
● 研究方法描述规范化建议
● 结果与讨论部分的分析深度提升
● 学术术语正确使用指导
3. 文献管理与引用辅助
● 参考文献格式自动校正(支持GB/T 7714、APA、MLA等)
● 引文位置合理性检查
● 文献相关性推荐(基于已有内容)
● 避免过度引用或引用不足的提醒
4. 语言润色与规范
● 学术语言风格调整(正式度、客观性)
● 语法、拼写、标点错误检测与修正
● 句子结构优化(简洁性、准确性)
● 术语一致性检查
● 多语言支持(中英文为主,可选其他语言)
5. 原创性与学术规范
● 相似度检测与抄袭风险提示
● 自我引用合理性检查
● 数据与图表来源标注提醒
● 学术不端行为预警
6. 数据分析与可视化建议
● 研究数据处理方法推荐
● 统计分析适用性评估
● 图表选择与呈现方式优化
● 结果解读的准确性检查
7. 投稿与发表辅助
● 目标期刊匹配推荐(基于论文主题与质量)
● 期刊格式要求自动适配
● 审稿意见回应策略指导
● 论文影响力预测
四、技术需求
1. 自然语言处理技术:
  ○ 文本理解与分析
  ○ 学术语言模型训练
  ○ 多语言处理能力
2. 知识图谱:
  ○ 学科知识体系构建
  ○ 文献引用关系网络
  ○ 研究主题关联分析
3. 数据资源:
  ○ 学术文献数据库对接
  ○ 各学科写作规范知识库
  ○ 期刊投稿要求数据库
4. 交互技术:
  ○ 实时协作编辑
  ○ 智能问答系统
  ○ 个性化推荐引擎
五、用户体验需求
1. 简洁直观的写作界面
2. 非侵入式的AI建议提示
3. 个性化设置(学科偏好、写作习惯)
4. 多设备同步与云端存储
5. 详细的修改记录与版本管理
6. 数据安全与隐私保护
六、差异化优势
1. 深度融合各学科专业知识,而非通用写作辅助
2. 全流程覆盖,从选题到发表的一站式服务
3. 基于学术规范的智能审查机制
4. 个性化学习与适应能力,随用户使用提升建议精准度
七、扩展方向
1. 学术会议信息推送与匹配
2. 科研合作推荐
3. 基金申报辅助
4. 学术成果展示与推广建议
通过以上功能的实现,该【学术分析】AI应用能够切实解决学术写作中的痛点问题,成为用户信赖的学术助手,提升学术写作的效率与质量。
  1. 完善版prompt:
plain 复制代码
我要开发一个【学术分析】AI 应用,解决用户在编写论文中难免遇到各种难题,让 AI 为用户提供贴心论文编写指导。
请你帮我进行需求分析,满足我的目标。

具体需要:
1. 分析目标用户群体及其核心需求
2. 提出主要功能模块和服务内容
3. 考虑产品的差异化竞争点
4. 分析可能的技术挑战和解决方案

得到的结果:

plain 复制代码
具体需要:
1. 分析目标用户群体及其核心需求
2. 提出主要功能模块和服务内容
3. 考虑产品的差异化竞争点
4. 分析可能的技术挑战和解决方案
一、目标用户群体及其核心需求
(一)核心用户画像
1. 科研人员与研究生(主体用户,占比超 70%)
● 特征:需完成高质量论文发表(期刊 / 会议),面临文献过载、创新点挖掘难等问题(Wiley 调研显示 63% 受限于缺乏 AI 使用指导)。
● 典型场景:博士研究生撰写学位论文、青年教师冲刺 SCI 期刊投稿。
1. 本科生(基础用户)
● 特征:缺乏学术写作经验,对论文结构、格式规范认知不足。
● 典型场景:课程论文、毕业论文开题与初稿撰写。
1. 跨学科研究者
● 特征:需整合多领域文献与数据,面临学科术语壁垒与方法适配难题(Nature 子刊显示跨模态大模型可突破此瓶颈)。
● 典型场景:生物信息学研究者融合分子数据与文献结论。
(二)核心需求优先级
需求类别	具体诉求	需求来源	优先级
研究方向定位	识别领域空白、预测研究趋势、生成选题建议	Wiley 调研	P0
文献处理	高效检索、结构化摘要、引用自动生成、文献关联分析	Perplexity 用户反馈	P0
写作辅助	学科专属大纲、逻辑连贯性检查、专业术语规范	Wiley 调研	P1
数据与图表	实验数据建模、图表自动生成、跨学科数据解读(如晶体结构 / CIF 文件分析)	Nature 案例	P1
合规性校验	查重降重、期刊格式适配、学术诚信风险提示	Wiley 调研	P0
二、主要功能模块和服务内容
(一)全流程功能矩阵

(二)特色服务示例
1. 学科专属工作台:针对材料科学提供 CIF 文件解析工具,针对生物医药提供 ProteinDT 文本引导设计功能。
2. 学术溯源链:每个观点自动关联原始文献段落 + 实验数据来源,支持一键验证(参考 Perplexity 内联引用机制)。
3. 渐进式指导:本科生模式侧重格式 / 结构,研究生模式强化创新点 / 数据深度,科研人员模式支持团队协作批注。
三、差异化竞争点
(一)与现有工具的核心差异
维度	竞品(Perplexity/Grammarly)	本产品差异化设计
流程覆盖	聚焦文献检索 / 语法润色(单点功能)	选题→投稿全流程闭环,嵌入数据建模等科研环节
学科适配	通用学术场景,跨学科能力弱	20 + 学科专属模型(如材料 / CrystaLLM、生物 / ProteinDT)
学术合规性	缺乏期刊规范适配,AI 生成边界模糊	接入 5000 + 期刊格式库,强制标注 AI 辅助内容
知识深度	依赖现有文献总结,无科学发现能力	支持假设生成→数据验证→结论推导的科研逻辑链
(二)用户价值锚点
1. 效率提升:文献综述时间从 "数天" 压缩至 "2 小时"(参考 Perplexity DeepResearch 效果),数据建模速度提升 10 倍(基于 Nature 子刊技术)。
2. 风险降低:通过 "查重 + 诚信标注 + 期刊格式校验" 三重防护,学术不端风险降低 90%。
3. 能力成长:提供 "AI 建议→人类修正→原理解析" 的阶梯式指导,帮助用户掌握学术写作逻辑。
四、技术挑战和解决方案
技术挑战	底层原因	解决方案
学术数据获取与版权	商业数据库 API 限制(如 Web of Science)	1. 优先对接 OA 数据库(PubMed Central/arXiv);2. 采用 SERP API 代理方案;3. 与出版商共建合规数据池
跨学科模型适配性	不同学科术语 / 逻辑差异大	1. 构建学科专用语料库(如 SwissProtCLAP 蛋白文本库);2. 采用 "基础模型 + 领域微调" 架构
学术生成内容准确性	LLM 易产生 "幻觉",缺乏科学严谨性	1. 引入检索增强生成(RAG)+ 知识图谱双重校验;2. 对接实验数据工具(如 Python/R)实时验证
引用格式自动化精度	格式规则复杂(15 + 标准),更新频繁	1. 基于规则引擎 + LLM 混合模型;2. 建立期刊格式动态更新 API(对接 Elsevier/Springer)
实时性与资源消耗	实时文献检索 + 大模型推理成本高	1. 热点文献预索引 + 增量更新;2. 轻量级边缘模型处理基础任务(如格式检查)
五、落地优先级建议
1. 首期(3 个月):上线选题、文献、合规校验模块,对接 Google Scholar API 与知网查重,覆盖文理工科通用场景。
2. 中期(6 个月):增加材料 / 生物学科专属工作台,实现数据建模与图表生成功能。
3. 远期(12 个月):构建学术知识图谱,支持团队协作与跨机构数据共享。
(注:文档部分内容可能由 AI 生成)

(三)、如何确认需求

  1. 在细化需求阶段,我们可以看到AI给我们生成了非常多的需求,但是我们到底要做哪些东西呢?
  2. 从而使用软件工程中的开发模型:MVP(先完成核心,后续在快速迭代)
plain 复制代码
MVP 不是 "简陋的半成品",也不是 "原型 Demo",而是具备 "核心功能完整性" 和 "用户可用性" 的最小版本。它的核心目标是:
验证 "产品解决的问题是否真实存在"(用户是否有需求);
验证 "产品的核心解决方案是否被用户接受"(需求是否被满足);
用最小成本排除 "伪需求",避免资源浪费在用户不关心的功能上。
MVP 是软件工程中 "以用户为中心""快速迭代" 理念的具体实践。它的关键不是 "做多少功能",而是 "做对核心功能";不是 "追求完美",而是 "先验证再优化"。对于初创团队、新产品探索或资源有限的项目,MVP 是平衡 "开发效率" 与 "市场适应性" 的最优策略之一。

八、AI应用设计方案

学术分析AI应用从两个核心方面开始开发:

系统提示词设计

多轮对话实现

(一)、系统提示词设计

在该阶段我们同样通过AI进行prompt优化:

优化前:

你是一位学术专家,为用户提供论文指导服务

发送AI:

我正在开发【学术分析】AI 对话应用,请你帮我编写设置给 AI 大模型的系统预设 Prompt 指令。要求让 AI 作为学术专家,模拟真实学术创作场景、多给用户一些引导性问题,不断深入了解用户,从而提供给用户更全面的建议,解决用户的编写论文问题。

优化后:

你是一位拥有多年学术研究与论文指导经验的学术专家,精通各学科研究方法与论文写作规范。你的核心任务是协助用户解决学术论文写作过程中的各类问题,从选题构思到最终定稿提供全方位指导。

(二)、多轮对话实现

  1. 可以使用 Spring AI 框架的 对话记忆能力。使用**ChatClient**
  2. 文档地址:https://docs.spring.io/spring-ai/reference/api/chatclient.html

九、Spring AI ChatClient 特性

(一)、两种构建方式-建造者模式手动构造

java 复制代码
// 通‌过建造者模式手动构造
package cn.varin.varaiagent.test;

import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component
public class ChatClientTest  implements CommandLineRunner {

    @Resource
    private ChatModel dashScopeChatModel;

    @Override
    public void run(String... args) throws Exception {


        // 使用builder方式
        ChatClient chatClient = getChatClient();
        ChatResponse chatResponse = chatClient.prompt().user("你好").call().chatResponse();
        System.out.println(chatResponse.getResult().getOutput().getText());
        //

    }




    public ChatClient getChatClient() {
       return  ChatClient.builder(dashScopeChatModel)
                .defaultSystem("你是学术专家")
                        .
                build();

    }


}

(二)、两种构建方式-自动注入

注意:在自动注入模式下

你引入了哪个模型的依赖,配置了哪个模型的密钥, **<font style="color:rgb(0, 0, 0);">ChatClient</font>**就会调用哪个模型

java 复制代码
package cn.varin.varaiagent.serivce;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.stereotype.Service;
// 构造期创建
@Service
public class ChatService {
    private final ChatClient chatClient;

    public ChatService(ChatClient.Builder builder) {
        this.chatClient = builder
        .defaultSystem("你是学术专家")
        .build();
    }

    public ChatResponse sendMessage(String content) {
        return  this.chatClient.prompt()
        .user(content)
        .call()
        .chatResponse();

    }
}

测试方法:

java 复制代码
package cn.varin.varaiagent.serivce;

import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest

public class ChatServiceTest {

    @Resource
    private ChatService chatService;
    @Test
    public void run()  {
        ChatResponse chatResponse = chatService.sendMessage("你好,我是一名软件工程专业的学生");
        System.out.println(chatResponse.getResult().getOutput().getText());
    }
}

(三)、chatClient多种响应格式

java 复制代码
//ChatResponse
ChatResponse chatResponse = chatClient.prompt()
    .user("Tell me a joke")
    .call()
    .chatResponse();
java 复制代码
// 自定义实体类Entity
record ActorFilms(String actor, List<String> movies) {}
ActorFilms actorFilms = chatClient.prompt()
    .user("Generate the filmography for a random actor.")
    .call()
    .entity(ActorFilms.class);

// 或
List<ActorFilms> actorFilms = chatClient.prompt()
    .user("Generate the filmography of 5 movies for Tom Hanks and Bill Murray.")
    .call()
    .entity(new ParameterizedTypeReference<List<ActorFilms>>() {});
java 复制代码
//stream
Flux<String> output = chatClient.prompt()
    .user("Tell me a joke")
    .stream()
    .content();

(四)、prompt templates

在设置prompt时,在功能类似的应用中可以使用prompt模版

java 复制代码
// 官网案例
String answer = ChatClient.create(chatModel).prompt()
    .user(u -> u
            .text("Tell me the names of 5 movies whose soundtrack was composed by {composer}")
            .param("composer", "John Williams"))
    .call()
    .content();

// 或者

ChatClient chatClient = ChatClient.builder(chatModel)
        .defaultSystem("You are a friendly chat bot that answers question in the voice of a {voice}")
        .build();


chatClient.prompt()
        .system(sp -> sp.param("voice", voice))
        .user(message)
        .call()
        .content());

示例

java 复制代码
package cn.varin.varaiagent.test;

import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
// 通‌过建造者模式手动构造

@Component
public class ChatClientTest  implements CommandLineRunner {

    @Resource
    private ChatModel dashScopeChatModel;

    @Override
    public void run(String... args) throws Exception {


        // 使用builder方式
        ChatClient chatClient = getChatClient();
        ChatResponse chatResponse = chatClient.prompt()
        .system(system
                ->system.param("name","学术专家"))
        .user("你好").call().chatResponse();
        System.out.println(chatResponse.getResult().getOutput().getText());
        //

    }


    public ChatClient getChatClient() {
        return  ChatClient.builder(dashScopeChatModel)
        .defaultSystem("你是{name}")
        .
        build();

    }


}

十、Advisors(顾问)

(一)、简介

  1. Spring AI 使用 Advisors(顾问)机制来增强 AI 的能力,可以理解为一系列可插拔的拦截器,在调用 AI 前和调用 AI 后可以执行一些额外的操作。
  2. advisors可分为
    1. 前置:可以完成优化prompt/分析提示器是否安全
    2. 后置:可以将对话信息存储到需要的数据库/记录日志/处理返回结果
  3. 功能不SpringMVC中的拦截器类似
  4. 注意:Advisor的的执行顺序是按照Order的值排序的,(越小越先执行)
  5. Spring AI 的 ChatMe‎moryAdvisor,‌它主要有几种内置的实现方式:

MessageChatMemoryAdvisor:从记忆中检索历史对话,并将其作为消息集合添加到提示词中

PromptChatMemoryAdvisor:从记忆中检索历史对话,并将其添加到提示词的系统文本中

VectorStoreChatMemoryAdvisor:可以用向量数据库来存储检索历史对话

(一)、继承图

  1. 该图为:MessageChatMemoryAdvisor继承图
  2. Advi⁠sors 分为 2 种模式:流式 Streamin‌g 和非流式 Non-Streaming,二者在用法上没有明显的区别,返回值不同罢了。但是如果我们要‎自主实现 Advisors,为了保证通用性,最好还‌是同时实现流式和非流式的环绕通知方法。
  3. 需要**实现CallAroundAdvisor和StreamAroundAdvisor和重写getOrder方法**

(三)、应用

在创建chatClien时,我们添加了MessageChatMemoryAdvisor对话记忆顾问,并且将对话数据存到内存中。

在消息发送时,指定了固定的房间号和上下文保留条数

java 复制代码
package cn.varin.varaiagent.test;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.UUID;
// 通‌过建造者模式手动构造

@Component

@Slf4j
public class ChatClientTest  implements CommandLineRunner {
    String uuid = UUID.randomUUID().toString();
    Integer storageNum=10;
    @Resource
    private ChatModel dashScopeChatModel;


    @Override
    public void run(String... args) throws Exception {

        log.info("uuid:{}",uuid);


        // 使用builder方式
        ChatClient chatClient = getChatClient();
        // 多轮调用
        ChatResponse chatResponse = getChatResponse(chatClient,"你好,我叫varin");
        System.out.println(chatResponse.getResult().getOutput().getText());
        System.out.println("===================");
        ChatResponse chatResponse1 = getChatResponse(chatClient,"我是软件工程专业的学生");
        System.out.println(chatResponse1.getResult().getOutput().getText());
        System.out.println("===================");

        ChatResponse chatResponse2 = getChatResponse(chatClient,"我叫什么?");
        System.out.println(chatResponse2.getResult().getOutput().getText());
        System.out.println("===================");



    }
    public ChatResponse getChatResponse(ChatClient chatClient,String content) {
        return chatClient.prompt()
        .system(system
                ->system.param("name","学术专家"))
        .advisors(advisor -> advisor.param("chat_memory_conversation_id",uuid)
                  .param("chat_memory_response_size", storageNum))

        .user(content).call().chatResponse();
    }
    private ChatMemory chatMemory= new InMemoryChatMemory();


    public ChatClient getChatClient() {
        return  ChatClient.builder(dashScopeChatModel)
        .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
        .defaultSystem("你是{name}")

        .
        build();

    }


}

结果:

java 复制代码
/Users/varya/Library/Java/JavaVirtualMachines/corretto-21.0.8/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:57253,suspend=y,server=n -javaagent:/Users/varya/Library/Caches/JetBrains/IntelliJIdea2025.2/captureAgent/debugger-agent.jar=file:///var/folders/3x/q93yq50j1_nc092fh57488bm0000gn/T/capture4152065194272298486.props -agentpath:/private/var/folders/3x/q93yq50j1_nc092fh57488bm0000gn/T/idea_libasyncProfiler_dylib_temp_folder/libasyncProfiler.dylib=version,jfr,event=wall,interval=10ms,cstack=no,file=/Users/varya/IdeaSnapshots/VarAiAgentApplication_2025_09_28_213402.jfr,log=/private/var/folders/3x/q93yq50j1_nc092fh57488bm0000gn/T/VarAiAgentApplication_2025_09_28_213402.jfr.log.txt,logLevel=DEBUG -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -Dkotlinx.coroutines.debug.enable.creation.stack.trace=false -Ddebugger.agent.enable.coroutines=true -Dkotlinx.coroutines.debug.enable.flows.stack.trace=true -Dkotlinx.coroutines.debug.enable.mutable.state.flows.stack.trace=true -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath /Users/varya/Desktop/github/var-ai-agent/target/classes:/Users/varya/.m2/repository/org/springframework/boot/spring-boot-starter-web/3.4.10/spring-boot-starter-web-3.4.10.jar:/Users/varya/.m2/repository/org/springframework/boot/spring-boot-starter/3.4.10/spring-boot-starter-3.4.10.jar:/Users/varya/.m2/repository/org/springframework/boot/spring-boot/3.4.10/spring-boot-3.4.10.jar:/Users/varya/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/3.4.10/spring-boot-autoconfigure-3.4.10.jar:/Users/varya/.m2/repository/org/springframework/boot/spring-boot-starter-logging/3.4.10/spring-boot-starter-logging-3.4.10.jar:/Users/varya/.m2/repository/ch/qos/logback/logback-classic/1.5.18/logback-classic-1.5.18.jar:/Users/varya/.m2/repository/ch/qos/logback/logback-core/1.5.18/logback-core-1.5.18.jar:/Users/varya/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.24.3/log4j-to-slf4j-2.24.3.jar:/Users/varya/.m2/repository/org/apache/logging/log4j/log4j-api/2.24.3/log4j-api-2.24.3.jar:/Users/varya/.m2/repository/org/slf4j/jul-to-slf4j/2.0.17/jul-to-slf4j-2.0.17.jar:/Users/varya/.m2/repository/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar:/Users/varya/.m2/repository/org/yaml/snakeyaml/2.3/snakeyaml-2.3.jar:/Users/varya/.m2/repository/org/springframework/boot/spring-boot-starter-json/3.4.10/spring-boot-starter-json-3.4.10.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.18.4/jackson-databind-2.18.4.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.18.4/jackson-datatype-jdk8-2.18.4.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.18.4/jackson-datatype-jsr310-2.18.4.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.18.4/jackson-module-parameter-names-2.18.4.jar:/Users/varya/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/3.4.10/spring-boot-starter-tomcat-3.4.10.jar:/Users/varya/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/10.1.46/tomcat-embed-core-10.1.46.jar:/Users/varya/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/10.1.46/tomcat-embed-el-10.1.46.jar:/Users/varya/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/10.1.46/tomcat-embed-websocket-10.1.46.jar:/Users/varya/.m2/repository/org/springframework/spring-web/6.2.11/spring-web-6.2.11.jar:/Users/varya/.m2/repository/org/springframework/spring-beans/6.2.11/spring-beans-6.2.11.jar:/Users/varya/.m2/repository/io/micrometer/micrometer-observation/1.14.11/micrometer-observation-1.14.11.jar:/Users/varya/.m2/repository/io/micrometer/micrometer-commons/1.14.11/micrometer-commons-1.14.11.jar:/Users/varya/.m2/repository/org/springframework/spring-webmvc/6.2.11/spring-webmvc-6.2.11.jar:/Users/varya/.m2/repository/org/springframework/spring-aop/6.2.11/spring-aop-6.2.11.jar:/Users/varya/.m2/repository/org/springframework/spring-context/6.2.11/spring-context-6.2.11.jar:/Users/varya/.m2/repository/org/springframework/spring-expression/6.2.11/spring-expression-6.2.11.jar:/Users/varya/.m2/repository/org/projectlombok/lombok/1.18.40/lombok-1.18.40.jar:/Users/varya/.m2/repository/jakarta/xml/bind/jakarta.xml.bind-api/4.0.2/jakarta.xml.bind-api-4.0.2.jar:/Users/varya/.m2/repository/jakarta/activation/jakarta.activation-api/2.1.4/jakarta.activation-api-2.1.4.jar:/Users/varya/.m2/repository/org/springframework/spring-core/6.2.11/spring-core-6.2.11.jar:/Users/varya/.m2/repository/org/springframework/spring-jcl/6.2.11/spring-jcl-6.2.11.jar:/Users/varya/.m2/repository/cn/hutool/hutool-all/5.8.38/hutool-all-5.8.38.jar:/Users/varya/.m2/repository/com/github/xiaoymin/knife4j-openapi3-jakarta-spring-boot-starter/4.4.0/knife4j-openapi3-jakarta-spring-boot-starter-4.4.0.jar:/Users/varya/.m2/repository/com/github/xiaoymin/knife4j-core/4.4.0/knife4j-core-4.4.0.jar:/Users/varya/.m2/repository/com/github/xiaoymin/knife4j-openapi3-ui/4.4.0/knife4j-openapi3-ui-4.4.0.jar:/Users/varya/.m2/repository/org/springdoc/springdoc-openapi-starter-webmvc-ui/2.3.0/springdoc-openapi-starter-webmvc-ui-2.3.0.jar:/Users/varya/.m2/repository/org/springdoc/springdoc-openapi-starter-webmvc-api/2.3.0/springdoc-openapi-starter-webmvc-api-2.3.0.jar:/Users/varya/.m2/repository/org/springdoc/springdoc-openapi-starter-common/2.3.0/springdoc-openapi-starter-common-2.3.0.jar:/Users/varya/.m2/repository/io/swagger/core/v3/swagger-core-jakarta/2.2.19/swagger-core-jakarta-2.2.19.jar:/Users/varya/.m2/repository/org/apache/commons/commons-lang3/3.17.0/commons-lang3-3.17.0.jar:/Users/varya/.m2/repository/io/swagger/core/v3/swagger-annotations-jakarta/2.2.19/swagger-annotations-jakarta-2.2.19.jar:/Users/varya/.m2/repository/io/swagger/core/v3/swagger-models-jakarta/2.2.19/swagger-models-jakarta-2.2.19.jar:/Users/varya/.m2/repository/jakarta/validation/jakarta.validation-api/3.0.2/jakarta.validation-api-3.0.2.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.18.4/jackson-dataformat-yaml-2.18.4.jar:/Users/varya/.m2/repository/org/webjars/swagger-ui/5.10.3/swagger-ui-5.10.3.jar:/Users/varya/.m2/repository/com/alibaba/dashscope-sdk-java/2.21.10/dashscope-sdk-java-2.21.10.jar:/Users/varya/.m2/repository/io/reactivex/rxjava2/rxjava/2.2.21/rxjava-2.2.21.jar:/Users/varya/.m2/repository/org/reactivestreams/reactive-streams/1.0.4/reactive-streams-1.0.4.jar:/Users/varya/.m2/repository/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar:/Users/varya/.m2/repository/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.jar:/Users/varya/.m2/repository/org/slf4j/slf4j-api/2.0.17/slf4j-api-2.0.17.jar:/Users/varya/.m2/repository/org/slf4j/slf4j-simple/2.0.17/slf4j-simple-2.0.17.jar:/Users/varya/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.25/kotlin-stdlib-jdk8-1.9.25.jar:/Users/varya/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.9.25/kotlin-stdlib-1.9.25.jar:/Users/varya/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/Users/varya/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.25/kotlin-stdlib-jdk7-1.9.25.jar:/Users/varya/.m2/repository/com/squareup/okio/okio/3.6.0/okio-3.6.0.jar:/Users/varya/.m2/repository/com/squareup/okio/okio-jvm/3.6.0/okio-jvm-3.6.0.jar:/Users/varya/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.25/kotlin-stdlib-common-1.9.25.jar:/Users/varya/.m2/repository/com/squareup/okhttp3/logging-interceptor/4.12.0/logging-interceptor-4.12.0.jar:/Users/varya/.m2/repository/com/squareup/okhttp3/okhttp-sse/4.12.0/okhttp-sse-4.12.0.jar:/Users/varya/.m2/repository/com/squareup/okhttp3/okhttp/4.12.0/okhttp-4.12.0.jar:/Users/varya/.m2/repository/com/github/victools/jsonschema-generator/4.31.1/jsonschema-generator-4.31.1.jar:/Users/varya/.m2/repository/com/fasterxml/classmate/1.7.0/classmate-1.7.0.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.18.4.1/jackson-core-2.18.4.1.jar:/Users/varya/.m2/repository/com/alibaba/fastjson/1.2.47/fastjson-1.2.47.jar:/Users/varya/.m2/repository/com/alibaba/cloud/ai/spring-ai-alibaba-starter/1.0.0-M6.1/spring-ai-alibaba-starter-1.0.0-M6.1.jar:/Users/varya/.m2/repository/com/alibaba/cloud/ai/spring-ai-alibaba-autoconfigure/1.0.0-M6.1/spring-ai-alibaba-autoconfigure-1.0.0-M6.1.jar:/Users/varya/.m2/repository/org/springframework/ai/spring-ai-spring-boot-autoconfigure/1.0.0-M6/spring-ai-spring-boot-autoconfigure-1.0.0-M6.jar:/Users/varya/.m2/repository/com/alibaba/cloud/ai/spring-ai-alibaba-core/1.0.0-M6.1/spring-ai-alibaba-core-1.0.0-M6.1.jar:/Users/varya/.m2/repository/org/springframework/ai/spring-ai-core/1.0.0-M6/spring-ai-core-1.0.0-M6.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/module/jackson-module-jsonSchema/2.18.4/jackson-module-jsonSchema-2.18.4.jar:/Users/varya/.m2/repository/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar:/Users/varya/.m2/repository/io/swagger/core/v3/swagger-annotations/2.2.25/swagger-annotations-2.2.25.jar:/Users/varya/.m2/repository/com/github/victools/jsonschema-module-swagger-2/4.37.0/jsonschema-module-swagger-2-4.37.0.jar:/Users/varya/.m2/repository/org/antlr/ST4/4.3.4/ST4-4.3.4.jar:/Users/varya/.m2/repository/org/antlr/antlr-runtime/3.5.3/antlr-runtime-3.5.3.jar:/Users/varya/.m2/repository/org/antlr/antlr4-runtime/4.13.1/antlr4-runtime-4.13.1.jar:/Users/varya/.m2/repository/io/projectreactor/reactor-core/3.7.11/reactor-core-3.7.11.jar:/Users/varya/.m2/repository/org/springframework/spring-messaging/6.2.11/spring-messaging-6.2.11.jar:/Users/varya/.m2/repository/io/micrometer/micrometer-core/1.14.11/micrometer-core-1.14.11.jar:/Users/varya/.m2/repository/org/hdrhistogram/HdrHistogram/2.2.2/HdrHistogram-2.2.2.jar:/Users/varya/.m2/repository/org/latencyutils/LatencyUtils/2.0.3/LatencyUtils-2.0.3.jar:/Users/varya/.m2/repository/io/micrometer/context-propagation/1.1.3/context-propagation-1.1.3.jar:/Users/varya/.m2/repository/com/knuddels/jtokkit/1.1.0/jtokkit-1.1.0.jar:/Users/varya/.m2/repository/com/github/victools/jsonschema-module-jackson/4.37.0/jsonschema-module-jackson-4.37.0.jar:/Users/varya/.m2/repository/org/springframework/ai/spring-ai-retry/1.0.0-M6/spring-ai-retry-1.0.0-M6.jar:/Users/varya/.m2/repository/org/springframework/retry/spring-retry/2.0.12/spring-retry-2.0.12.jar:/Users/varya/.m2/repository/org/springframework/spring-webflux/6.2.11/spring-webflux-6.2.11.jar:/Users/varya/.m2/repository/commons-codec/commons-codec/1.17.2/commons-codec-1.17.2.jar:/Users/varya/.m2/repository/com/alibaba/nacos/nacos-client-mse-extension/1.0.4/nacos-client-mse-extension-1.0.4.jar:/Users/varya/.m2/repository/com/aliyun/aliyun-java-sdk-core/4.5.17/aliyun-java-sdk-core-4.5.17.jar:/Users/varya/.m2/repository/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar:/Users/varya/.m2/repository/org/apache/httpcomponents/httpcore/4.4.16/httpcore-4.4.16.jar:/Users/varya/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/varya/.m2/repository/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1.jar:/Users/varya/.m2/repository/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar:/Users/varya/.m2/repository/org/jacoco/org.jacoco.agent/0.8.6/org.jacoco.agent-0.8.6-runtime.jar:/Users/varya/.m2/repository/org/ini4j/ini4j/0.5.4/ini4j-0.5.4.jar:/Users/varya/.m2/repository/io/opentracing/opentracing-api/0.33.0/opentracing-api-0.33.0.jar:/Users/varya/.m2/repository/io/opentracing/opentracing-util/0.33.0/opentracing-util-0.33.0.jar:/Users/varya/.m2/repository/io/opentracing/opentracing-noop/0.33.0/opentracing-noop-0.33.0.jar:/Users/varya/.m2/repository/com/aliyun/aliyun-java-sdk-kms/2.16.3/aliyun-java-sdk-kms-2.16.3.jar:/Users/varya/.m2/repository/com/aliyun/kms/kms-transfer-client/0.1.0/kms-transfer-client-0.1.0.jar:/Users/varya/.m2/repository/com/aliyun/alibabacloud-dkms-gcs-sdk/0.2.8/alibabacloud-dkms-gcs-sdk-0.2.8.jar:/Users/varya/.m2/repository/com/aliyun/tea-util/0.2.7/tea-util-0.2.7.jar:/Users/varya/.m2/repository/com/aliyun/tea/1.2.3/tea-1.2.3.jar:/Users/varya/.m2/repository/com/aliyun/alibabacloud-dkms-gcs-openapi-util/0.2.8/alibabacloud-dkms-gcs-openapi-util-0.2.8.jar:/Users/varya/.m2/repository/com/aliyun/alibabacloud-dkms-gcs-openapi-credential/0.2.8/alibabacloud-dkms-gcs-openapi-credential-0.2.8.jar:/Users/varya/.m2/repository/com/aliyun/alibabacloud-dkms-gcs-openapi/0.2.8/alibabacloud-dkms-gcs-openapi-0.2.8.jar:/Users/varya/.m2/repository/com/google/protobuf/protobuf-java/4.0.0-rc-2/protobuf-java-4.0.0-rc-2.jar:/Users/varya/.m2/repository/com/google/protobuf/protobuf-java-util/4.0.0-rc-2/protobuf-java-util-4.0.0-rc-2.jar:/Users/varya/.m2/repository/com/google/guava/guava/29.0-android/guava-29.0-android.jar:/Users/varya/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/Users/varya/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/Users/varya/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/Users/varya/.m2/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar:/Users/varya/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/Users/varya/.m2/repository/org/bouncycastle/bcprov-jdk15on/1.70/bcprov-jdk15on-1.70.jar:/Users/varya/.m2/repository/com/alibaba/cloud/spring-alibaba-nacos-config/2023.0.1.3/spring-alibaba-nacos-config-2023.0.1.3.jar:/Users/varya/.m2/repository/com/alibaba/nacos/nacos-client/2.4.2/nacos-client-2.4.2.jar:/Users/varya/.m2/repository/com/alibaba/nacos/nacos-auth-plugin/2.4.2/nacos-auth-plugin-2.4.2.jar:/Users/varya/.m2/repository/com/alibaba/nacos/nacos-encryption-plugin/2.4.2/nacos-encryption-plugin-2.4.2.jar:/Users/varya/.m2/repository/com/alibaba/nacos/nacos-logback-adapter-12/2.4.2/nacos-logback-adapter-12-2.4.2.jar:/Users/varya/.m2/repository/com/alibaba/nacos/logback-adapter/1.1.3/logback-adapter-1.1.3.jar:/Users/varya/.m2/repository/com/alibaba/nacos/nacos-log4j2-adapter/2.4.2/nacos-log4j2-adapter-2.4.2.jar:/Users/varya/.m2/repository/org/apache/httpcomponents/httpasyncclient/4.1.5/httpasyncclient-4.1.5.jar:/Users/varya/.m2/repository/org/apache/httpcomponents/httpcore-nio/4.4.16/httpcore-nio-4.4.16.jar:/Users/varya/.m2/repository/io/prometheus/simpleclient/0.16.0/simpleclient-0.16.0.jar:/Users/varya/.m2/repository/io/prometheus/simpleclient_tracer_otel/0.16.0/simpleclient_tracer_otel-0.16.0.jar:/Users/varya/.m2/repository/io/prometheus/simpleclient_tracer_common/0.16.0/simpleclient_tracer_common-0.16.0.jar:/Users/varya/.m2/repository/io/prometheus/simpleclient_tracer_otel_agent/0.16.0/simpleclient_tracer_otel_agent-0.16.0.jar:/Users/varya/.m2/repository/org/apache/opennlp/opennlp-tools/2.3.3/opennlp-tools-2.3.3.jar:/Users/varya/.m2/repository/dev/langchain4j/langchain4j-community-dashscope/1.5.0-beta11/langchain4j-community-dashscope-1.5.0-beta11.jar:/Users/varya/.m2/repository/dev/langchain4j/langchain4j-core/1.5.0/langchain4j-core-1.5.0.jar:/Users/varya/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.18.4/jackson-annotations-2.18.4.jar:/Users/varya/.m2/repository/org/jspecify/jspecify/1.0.0/jspecify-1.0.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar cn.varin.varaiagent.VarAiAgentApplication
已连接到地址为 ''127.0.0.1:57253',传输: '套接字'' 的目标虚拟机
SLF4J(W): Class path contains multiple SLF4J providers.
SLF4J(W): Found provider [ch.qos.logback.classic.spi.LogbackServiceProvider@212b5695]
SLF4J(W): Found provider [org.slf4j.simple.SimpleServiceProvider@446293d]
SLF4J(W): See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J(I): Actual provider is of type [ch.qos.logback.classic.spi.LogbackServiceProvider@212b5695]
2025-09-28T21:34:02.974+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.a.nacos.client.logging.NacosLogging    : Nacos Logging Adapter Builder: com.alibaba.nacos.logger.adapter.logback12.LogbackNacosLoggingAdapterBuilder
2025-09-28T21:34:02.976+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.a.nacos.client.logging.NacosLogging    : Nacos Logging Adapter Builder: com.alibaba.nacos.logger.adapter.logback14.LogbackNacosLoggingAdapterBuilder
2025-09-28T21:34:02.976+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.a.nacos.client.logging.NacosLogging    : Nacos Logging Adapter: com.alibaba.nacos.logger.adapter.logback14.LogbackNacosLoggingAdapter match ch.qos.logback.classic.Logger success.
2025-09-28T21:34:02.978+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.a.nacos.client.logging.NacosLogging    : Nacos Logging Adapter Builder: com.alibaba.nacos.logger.adapter.log4j2.Log4j2NacosLoggingAdapterBuilder

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::               (v3.4.10)

2025-09-28T21:34:03.050+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.v.varaiagent.VarAiAgentApplication     : Starting VarAiAgentApplication using Java 21.0.8 with PID 61639 (/Users/varya/Desktop/github/var-ai-agent/target/classes started by varya in /Users/varya/Desktop/github/var-ai-agent)
2025-09-28T21:34:03.051+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.v.varaiagent.VarAiAgentApplication     : The following 1 profile is active: "local"
2025-09-28T21:34:03.339+08:00  WARN 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alibaba.cloud.nacos.NacosConfigAutoConfiguration' of type [com.alibaba.cloud.nacos.NacosConfigAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). The currently created BeanPostProcessor [nacosAnnotationProcessor] is declared through a non-static factory method on that class; consider declaring it as static instead.
2025-09-28T21:34:03.341+08:00  WARN 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'nacosConfigProperties' of type [com.alibaba.cloud.nacos.NacosConfigProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [nacosAnnotationProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2025-09-28T21:34:03.364+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.a.n.p.a.s.c.ClientAuthPluginManager    : [ClientAuthPluginManager] Load ClientAuthService com.alibaba.nacos.client.auth.impl.NacosClientAuthServiceImpl success.
2025-09-28T21:34:03.364+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.a.n.p.a.s.c.ClientAuthPluginManager    : [ClientAuthPluginManager] Load ClientAuthService com.alibaba.nacos.client.auth.ram.RamClientAuthServiceImpl success.
2025-09-28T21:34:03.365+08:00  WARN 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'nacosConfigManager' of type [com.alibaba.cloud.nacos.NacosConfigManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [nacosAnnotationProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2025-09-28T21:34:03.444+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 33333 (http)
2025-09-28T21:34:03.449+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-09-28T21:34:03.449+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.46]
2025-09-28T21:34:03.467+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] o.a.c.c.C.[Tomcat].[localhost].[/api]    : Initializing Spring embedded WebApplicationContext
2025-09-28T21:34:03.467+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 400 ms
2025-09-28T21:34:03.676+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] o.s.v.b.OptionalValidatorFactoryBean     : Failed to set up a Bean Validation provider: jakarta.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
2025-09-28T21:34:03.810+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 33333 (http) with context path '/api'
2025-09-28T21:34:03.814+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.v.varaiagent.VarAiAgentApplication     : Started VarAiAgentApplication in 0.948 seconds (process running for 1.346)
2025-09-28T21:34:03.815+08:00  INFO 61639 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] c.varin.varaiagent.test.ChatClientTest   : uuid:e9c0e1d0-0dfa-4293-84c7-fe0e322f8567
你好,Varin!欢迎向我提问。无论你是想探讨学术问题、寻求研究建议,还是需要帮助梳理论文思路,我都可以为你提供专业支持。请告诉我你感兴趣的领域或当前遇到的难题吧! 🌟
===================
你好,Varin!很高兴认识你 🎉  
作为一名软件工程专业的学生,你已经踏上了极具挑战性又充满创造力的学术之路。而我作为你的学术伙伴,很乐意在以下方面为你提供支持:

🔹 **课程学习**:无论是需求工程、软件架构设计、UML建模,还是敏捷开发、DevOps、测试自动化等核心内容,我都可以帮你梳理知识点、举例说明或解答疑惑。

🔹 **项目实践**:如果你正在做课程设计、毕业设计或参与实际开发项目,我可以协助你进行系统设计、技术选型、文档撰写(如SRS、设计说明书)等。

🔹 **研究方向探索**:如果你想了解当前软件工程领域的前沿方向(比如AI在软件工程中的应用、智能代码生成、持续集成优化、软件缺陷预测等),我可以为你推荐热点课题和相关文献。

🔹 **论文写作与学术表达**:从结构组织到语言润色,从查重规避到格式规范(IEEE, ACM等),我都可以提供指导。

📌 请问你现在处于哪个阶段?是本科、硕士,还是博士?最近有没有特别关注的课题或正在做的项目?我们可以一起深入探讨 😊
===================
你好,Varin!你刚刚告诉我,你叫 **Varin** 😊

虽然我不能像人类一样长期记住信息(每次对话都是独立的隐私保护设计),但在这次对话中,我会清楚地记得你叫 Varin,并以你希望的方式与你交流。

你说我是学术专家------没错,在这个角色中,我可以为你提供软件工程及相关领域的深度支持,包括研究方法、论文写作、技术趋势分析等。所以,请随时告诉我:

- 你现在在学习或研究什么具体内容?
- 有没有遇到想深入探讨的问题?

我在这里,以学术伙伴的身份,陪你一起思考和进步 💡
===================

十一、chat Memory

(一)、简介

  1. ChatMemoryAdvisor 都依赖 Chat Memory 进行构造,Chat Memory 负责历史对话的存储,定义了保存消息、查询消息、清空消息历史的方法。
  2. SpringAi中内置的chatMemory

InMemoryChatMemory:内存存储

CassandraChatMemory:在 Cassandra 中带有过期时间的持久化存储

Neo4jChatMemory:在 Neo4j 中没有过期时间限制的持久化存储

JdbcChatMemory:在 JDBC 中没有过期时间限制的持久化存储

十一、多轮对话 AI 应用开发

  1. 建立App包
  2. 创建IALDAApp类
java 复制代码
package cn.varin.varaiagent.app;


import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.stereotype.Component;

@Component
@Slf4j

public class IALDAApp {

    public static   final String SYSTEM_PROPERTY = "作为拥有多年学术研究与论文指导经验的专家,精通各学科研究方法与写作规范,需通过开放性问题启发式引导(探研究方向 / 写作瓶颈 / 结构需求等),提供选题评估、文献指导、方法分析、结构建议、表达规范等符合学术规范的专业建议,适配用户基础调整指导深度,以建议而非指令陪伴用户完成论文从选题到定稿全流程,协助解决各类写作问题。";

    private final ChatClient chatClient;
    public IALDAApp(ChatClient.Builder chatClient) {
        this.chatClient = chatClient
        .defaultSystem(SYSTEM_PROPERTY)
        .defaultAdvisors(
            new MessageChatMemoryAdvisor(new InMemoryChatMemory())
        )
        .build();
    }

    public String getMessage(String content,String chatId) {
        ChatResponse chatResponse = this.chatClient.prompt()
        .user(content)
        .advisors(advisor -> advisor.param("chat_memory_conversation_id", chatId)
                  .param("chat_memory_response_size", 10)).call().chatResponse();
        String text = chatResponse.getResult().getOutput().getText();
        log.info("text:{}", text);
        return text;
    }
}
  1. 创建测试类
java 复制代码
package cn.varin.varaiagent.app;


import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.UUID;

@SpringBootTest

public class IALDAAppTest {

    @Resource
    private IALDAApp ialdaApp;

    @Test
    public void test() {}
    @Test
    public void getMessage() {
        String uuid= UUID.randomUUID().toString();
        ialdaApp.getMessage("你好,我是varin", uuid);
        ialdaApp.getMessage("我是软件工程专业的", uuid);
        ialdaApp.getMessage("我叫什么?,我需要方向的论文指导?", uuid);

    }
}
  1. 结果
java 复制代码
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build what is described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#0.3
WARNING: A Java agent has been loaded dynamically (/Users/varya/.m2/repository/net/bytebuddy/byte-buddy-agent/1.15.11/byte-buddy-agent-1.15.11.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
2025-09-28T22:17:51.729+08:00  INFO 62236 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] cn.varin.varaiagent.app.IALDAApp         : text:你好,Varin!欢迎来交流~ 很高兴认识你。不知道你最近在忙些什么呢?是正在准备写论文、做研究,还是遇到了什么学术上的问题需要帮忙?我在这里随时可以为你提供支持和建议 😊
2025-09-28T22:18:11.558+08:00  INFO 62236 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] cn.varin.varaiagent.app.IALDAApp         : text:你好,Varin!很高兴得知你是软件工程专业的同学或研究者。这是一个理论与实践高度结合、发展迅速且应用广泛的领域,涉及软件开发方法、系统架构、质量保障、人工智能融合、DevOps、安全可信等多个前沿方向。

为了更精准地为你提供学术支持,我想通过几个开放性问题逐步了解你的当前状态和需求:

---

🔍 **第一步:明确你的研究阶段与目标**

1. 你目前处于哪个阶段?  
   - 本科毕业设计?  
   - 硕士开题/中期?  
   - 博士选题探索?  
   - 还是准备投稿期刊/会议论文?

2. 是否已有初步的研究方向或选题?如果有,能否简要描述一下你想研究的问题?例如:  
   - 是关于软件缺陷预测、代码克隆检测、自动化测试、持续集成优化?  
   - 还是涉及AI在软件工程中的应用(如大模型生成代码、智能补全)?  
   - 或是软件架构、微服务治理、可维护性分析等系统层面的问题?

---

💡 **第二步:识别潜在挑战与兴趣点**

3. 在当前写作或研究过程中,你遇到的最大困难是什么?例如:  
   - 找不到创新点?  
   - 文献综述难以聚焦?  
   - 实验设计不够严谨?  
   - 数据获取困难?  
   - 论文结构混乱、逻辑不清晰?  
   - 英文表达不符合学术规范?

4. 你更倾向于做**实证研究**(如基于真实项目数据的分析)、**方法构建**(提出新算法/工具),还是**理论分析/系统综述**类的工作?

---

📌 示例引导(供参考):

比如,如果你说:"我想研究大模型在自动生成单元测试方面的效果",我就可以进一步引导:
- 如何定义"效果"?覆盖率?通过率?人工可接受度?
- 是否需要对比传统工具(如Evosuite)?
- 数据集选择(开源项目范围、语言类型)?
- 实验设计是否具备可复现性?
- 相关工作如何组织才能突出贡献?

---

✅ 接下来你可以告诉我:
> "我现在正在准备硕士论文开题,想做AI生成代码的相关研究,但感觉题目太大,不知道如何聚焦。"

或者:
> "我在写一篇关于微服务异常检测的论文,卡在Related Work部分,总觉得别人的工作太多太杂,理不清脉络。"

又或者:
> "我有个想法:用图神经网络预测软件缺陷,但不确定这个方向是否有价值,实验怎么做?"

---

只要你愿意分享现状或困惑,我将以**启发式提问 + 学术规范建议**的方式,陪你一步步厘清思路、优化选题、设计方法、搭建结构,并确保符合软件工程领域的主流写作范式(如IEEE/ACM格式、Empirical Software Engineering风格等)。

现在,你想从哪里开始?😊
2025-09-28T22:18:45.022+08:00  INFO 62236 --- [spring-ai-alibaba-qwq-chat-client-example] [           main] cn.varin.varaiagent.app.IALDAApp         : text:你好,Varin!感谢你的补充说明。我已经记住了你的名字 ------ **Varin**,一位软件工程专业的研究者,正在寻求关于论文方向与写作的系统性学术指导。

从你简洁但明确的提问中,我能感受到你目前可能处于这样一个阶段:  
👉 **已有一定专业基础,但尚未完全确定具体研究方向,或虽有初步想法却不确定其可行性与创新性,亟需一位经验丰富的"学术同行"帮你梳理思路、评估选题、规划路径。**

---

🎯 那么接下来,我将以你设定的角色定位------  
> "拥有多年学术研究与论文指导经验的专家,精通各学科研究方法与写作规范"

为你提供**启发式、陪伴式、符合学术规范的专业引导**。我们不急于下结论,而是通过一系列开放性问题,逐步聚焦你的兴趣、能力与现实条件,最终帮助你确立一个**有价值、可落地、易发表**的研究方向。

---

📌 第一轮引导:探明你的研究起点

请思考并回答以下五个问题中的任意几个(你可以逐条回复,也可以综合表达):

1. **你在软件工程领域最感兴趣的技术或现象是什么?**  
   (例如:自动化测试、代码生成、缺陷预测、技术债管理、CI/CD优化、开发者行为分析、AI for SE等)

2. **你是否接触过某些真实项目、开源系统或数据集?有没有观察到让你"觉得奇怪""可以改进"的地方?**  
   (比如:"我在实习时发现团队花大量时间写单元测试,我想知道能不能用大模型自动完成。")

3. **你希望这篇论文更偏向理论创新、方法构建,还是实证分析?**  
   - 想提出新算法/框架?  
   - 还是验证某个现有方法在特定场景下的有效性?  
   - 或是对某一类实践进行系统性总结与建模?

4. **你具备哪些技能或工具使用经验?**  
   (如Python、Java静态分析工具、机器学习框架、Git挖掘、Docker/K8s日志分析、GNN/NLP模型训练等)

5. **你的时间周期和目标期刊/会议级别是怎样的?**  
   - 是为毕业服务(中文核心 / EI 收录)?  
   - 还是冲击顶会(如 ICSE、FSE、ASE、ESEC/FSE)或SCI期刊(如 TSE、TOSEM)?

---

💡 举个例子来说明这个过程如何展开:

假设你告诉我:
> "我对GitHub上那些用AI写代码的人很感兴趣,想知道他们到底怎么用Copilot,会不会引入安全漏洞。"

那我就会回应:
✅ 这是一个非常有潜力的方向!属于"AI赋能开发实践"的实证研究范畴,在FSE/ICSE近年都有类似工作。我们可以进一步聚焦为:
> "基于开发者行为日志的AI辅助编程安全性实证研究:以GitHub Copilot为例"

然后我们一起设计:
- 如何收集数据(公开仓库 + 用户调研)?
- 如何定义"潜在安全漏洞"(结合Semgrep/CWE)?
- 如何分类使用模式(完整采纳、修改后采纳、拒绝)?
- 如何建立因果关联而非仅相关性?

最终形成一条清晰的研究路线图。

---

📬 现在轮到你了,Varin:

请告诉我:  
👉 在软件工程的世界里,哪一个环节最让你"坐不住想动手试试"?  
或者:  
👉 最近让你产生疑问或好奇的一个实际问题是什么?

哪怕只是一个模糊的感觉,比如:"我觉得现在的微服务监控太难用了" 或 "大模型生成的代码真的靠谱吗?" ------ 都值得深挖。

我在这里,陪你把一个念头变成一篇扎实的论文 💡

期待你的分享。

加油呀

相关推荐
扫地的小何尚2 小时前
CUDA 13.0深度解析:统一ARM生态、UVM增强与GPU共享的革命
arm开发·人工智能·自然语言处理·gpu·nvidia·jetson·nvidia thro
猫头虎2 小时前
如何利用海外 NetNut 网络代理与 AICoding 实战获取 iPhone 17 新品用户评论数据?
网络·人工智能·计算机网络·网络安全·ios·网络攻击模型·iphone
stbomei3 小时前
2025 AI 产业:技术趋势、伦理治理与生态重构
人工智能·重构
nju_spy3 小时前
计算机视觉 - 物体检测(二)单阶段:YOLO系列 + SSD
人工智能·yolo·目标检测·计算机视觉·ssd·r-cnn·端到端检测
yueyuebaobaoxinx3 小时前
2025 年 AI 智能体(Agent)发展全景:技术突破、场景落地与产业重构
人工智能·重构
云道轩3 小时前
初次尝试在kubernetes 1.31 上安装 人工智能模型运行平台 llm-d
人工智能·kubernetes·llm-d
深蓝易网3 小时前
3C电子企业柔性制造转型:如何通过MES管理系统实现快速换线与弹性生产?
大数据·运维·人工智能·重构·制造
ChinaRainbowSea3 小时前
5. Prompt 提示词
java·人工智能·后端·spring·prompt·ai编程
IT_陈寒3 小时前
Vue3性能优化实战:这5个技巧让我的应用加载速度提升70%
前端·人工智能·后端