让 AI 帮我把项目升到 Spring Boot 3:它扛了体力活,也埋了几个坑
让 AI 帮我把项目升到 Spring Boot 3:它扛了体力活,也埋了几个坑我们组有个内部服务,一直跑在 Spring Boot 2 上 2.x 早就停止开源免费维护了,安全扫描隔三岔五报一堆依赖漏洞,升级这件事拖了很久,终于排到了我头上 这次我决定全程拉着 AI 一起干 前后大概用了一周多(中间还穿插着别的需求),最后顺利上线 回头看,AI 确实帮我扛了大部分体力活,但也有几个坑是它挖的,或者至少是它没提醒我的 这篇把过程和教训记下来,给同样准备升级的同学参考 先声明:下面说的都是我们这个项目的情况,每个项目的依赖和历史包袱不一样,具体以 Spring 官方的迁移指南为准 一开始我问 AI:“把这个项目从 Spring Boot 2 升到 3,需要改什么?”它给了一份清单,大方向没错:Java 版本要 17 以上、javax 包要换成 jakarta、Spring Security 的配置写法变了,等等

2026-10-14鱼鱼
什么是 AI Agent?从 ReAct 循环讲起
什么是 AI Agent?从 ReAct 循环讲起最近一年,“Agent”这个词几乎出现在每一篇 AI 文章里 但很多人写了半天 Agent,其实只是把一个大模型接口包了层壳 这篇文章从最小的模型出发,讲清楚 Agent 到底是什么,以及它的核心运行机制——ReAct 循环 读完之后,你应该能回答三个问题:Agent 和普通聊天有什么本质区别?一个 Agent 的每一步到底在发生什么?怎样用几十行代码搭出一个能跑的最小 Agent,并知道它会在哪里出问题? ReAct 循环:思考 → 行动 → 观察,直到给出最终答案 早期使用大模型,基本是“一问一答”:把问题写进提示词,模型返回一段文字 这种方式对写文案、翻译、解释概念很好用,但一遇到下面这些需求就力不从心:

2026-10-14鱼鱼
Agent 的 Token 账单怎么省:Prompt Caching、上下文瘦身与模型分级
Agent 的 Token 账单怎么省:Prompt Caching、上下文瘦身与模型分级做 Agent 的人,大概都经历过这么一个时刻:功能调通了,效果也还行,兴冲冲地跑了一批真实任务,然后打开账单页面,沉默了 同样是调用大模型,Agent 为什么比普通聊天贵这么多?钱都花在哪了?能不能在不明显影响效果的前提下省下来?这篇文章想把这笔账算清楚,再聊几种我觉得性价比最高的省钱办法 先声明一下:各家模型的价格和缓存规则变得很快,文中涉及的具体规则,以我写作时(2026 年 10 月)看到的官方文档为准,你落地之前最好再核对一遍 思路是通用的,数字请以官方为准 图片来源:Negative Space / StockSnap(CC0 1.0) 普通聊天,一问一答,输入的就是你的问题加上一些历史

2026-10-14鱼鱼
给 Agent 设超时和步数预算:别让它无限跑
给 Agent 设超时和步数预算:别让它无限跑第一次把 Agent 接到真实仓库时,我犯过一个很土的错:只盯着“它能不能做完”,没盯着“它最多能跑多久、最多能走几步” 结果某次工具调用卡在外部接口,它一边重试一边换策略,token 和墙钟时间一起烧,最后我手动杀掉,现场还一堆半成品文件 从那以后,我把超时和步数预算当成和权限同级的安全项 不是为了虐待 Agent,而是承认:自动化一旦没有硬上限,失败模式会从“报错”变成“悄悄耗尽” Agent 的轨迹很会制造希望:每一步都有日志,每一步都像在进步 可进步不等于收敛 常见假象包括: 同一类错误换着措辞重试 在几个文件间来回改,测试始终红 搜索范围越扩越大,上下文越来越脏

2026-10-14鱼鱼
用 AI 写周报和站会更新:我留下的几条「别丢人」规矩
用 AI 写周报和站会更新:我留下的几条「别丢人」规矩周报和站会更新,我以前最烦:明明一周干了不少事,一提笔就变成「推进了若干事项」「持续跟进中」 后来我开始扔给 AI 起草,效率是上来了,但笑不出来的次数也多了——它会帮你把话说得更像在汇报,却不一定更像在讲真话 这篇文章记我怎么用 AI 写周报/站会,以及几条「别丢人」的硬规矩 不是教大家写漂亮,是教大家少踩那种听起来很满、一问就空的坑 站会更新通常就三五行:昨天做了啥、今天打算啥、有没有卡点 周报稍长一点,但本质一样——用事实把进度钉住 这类文字格式固定、重复度高,很适合让 AI 从 git log、PR 列表、issue 评论里先拼一版草稿 我自己的流程很土: 先导出本周相关 commit / PR 标题(或自己列子弹)

2026-10-15鱼鱼
Java中的协程(虚拟线程)探究
Java中的协程(虚拟线程)探究在Java最新的LTS版本 21中,终于实装了协程这一特性 当然,在这些诸如python、golang等轻量级语言中被称为协程的东西,在Java中有个全新的代号——虚拟线程,为了将协程与线程做区分,在Java21中,原Thread被称之为平台线程 下文中,将统一使用线程/协程的方式称呼 我们都知道,Java中引入了线程的概念,区别于系统中的进程 作为并发执行的最小单元,在一定的条件下,使用多个线程同时运作可以有效提高程序的运转效率 而线程这一能力源于系统本身而并非JVM 之所以说是在一定条件下,是因为受限于机器配置情况(CPU的运作机制、核心数),线程的同时运作并不能线性的提升运行性能,单个cpu并不能同时处理多线程任务,实际的运作方式是基于时间片分片,各个线程抢占式执行代码,这样能减少一些无效的io等待(例如网络io、磁盘io实际是会阻塞等待io结果),同时在多核心场景下也能有效利用cpu
![Java中的协程(虚拟线程)探究]()
2024-10-28鱼鱼
AI 补全和整段生成,我什么时候用哪种
AI 补全和整段生成,我什么时候用哪种用 AI 写代码久了,我会下意识把它分成两种节奏:一种是编辑器里那个“跟着你敲”的补全;另一种是对话框里“给我写一整段 / 一整文件”的生成 表面上都是 AI 在写,体感完全不一样 补全像有人在旁边帮你把下一句顺出来;整段生成像你把需求扔出去,过一会儿收回来一份成品 我早期几乎只用后者,觉得效率高;后来越写越觉得:很多时候,补全才是更省心的那一个 这篇就聊聊我现在怎么选 补全的好处很直观——上下文就在光标周围,你刚写的函数名、变量名、注释,它都能“看见” 你按 tab 接受一行,再敲两下,它继续跟 这种节奏很接近自己写,只是手变快了一点 我特别喜欢在这些场景用补全: 写样板代码:DTO 字段、简单的 getter/mapper、重复的校验

2026-10-14鱼鱼
Agent 的重试与换路:失败了再试一次,还是换条路?
Agent 的重试与换路:失败了再试一次,还是换条路?做 Agent 的人,迟早会碰到同一个设计题:工具调用失败了,下一步是原地再试,还是换个策略? 听起来像工程里的重试策略老话题,放到 Agent 里却更别扭——因为失败的原因经常不是“网络抖了一下”,而是“这条路根本走不通”,或者“模型把错误理解歪了,越重试越执着” 我踩过两边的坑:该重试时太早放弃,任务脆;该换路时死磕重试,账单和日志一起爆炸,最后还是失败 这篇整理一下我现在怎么做判断 不是所有失败都该一视同仁 我大致分成四类: 瞬时故障:超时、限流、连接重置 特征是:同一请求,过一会儿可能就好 输入问题:参数缺了、格式不对、路径不存在 特征是:原样再发,几乎必败 权限/策略拒绝:没权限、被安全策略拦住

2026-10-14鱼鱼
让 AI 起变量名和函数名,我留下的几条品味规矩
让 AI 起变量名和函数名,我留下的几条品味规矩命名一直是我写代码时最磨蹭的环节之一 名字起糊了,后面读代码的人(包括一个月后的我)会一直付税 AI 很擅长甩出一串候选名,也很容易甩出看起来专业、读起来空洞的名字 这篇文章记我让它起名时留下的几条规矩——不是语法规范全文,是品味上的取舍 我愿意让 AI 起名,前提是: 我已经能用一句话说明“这个东西在业务里干什么” 我要的是 3–5 个候选,不是一个“最佳答案” 最终选定权在我,尤其是会进公共 API、表字段、事件名的那些 一上来就说“给个好名字”,它常会给你 handleUserData、processInfo、manageService 这类语法正确但语义稀释的词 候选机模式能逼它发散,也逼我比较

2026-10-14鱼鱼
第一次用 AI 改 bug 的真实节奏
第一次用 AI 改 bug 的真实节奏第一次认真用 AI 改 bug,不是那种“帮我写个排序”的玩具题,是线上真出了问题:某个接口偶发超时,日志里只有一句 Read timed out,复现不稳 我那会儿把堆栈和一段相关代码扔给 AI,它很快给了一版“优化建议”——加超时、加重试、换连接池参数 看起来很专业,我差点就合进去了 后来自己又翻了半小时才发现:真正的原因是下游在高峰时返回了一个空 body,客户端按固定 schema 去解析,偶发抛异常,异常被上层吞掉,最终表现为超时 AI 那套建议能“缓解症状”,但治不了病,还可能把问题藏得更深 这篇文章想写的,是我后来慢慢摸出来的一套节奏:怎么描述现象、给什么上下文、什么时候该自己看代码

2026-10-14鱼鱼
让 AI 解释陌生代码:我怎么听出它在「圆场」
让 AI 解释陌生代码:我怎么听出它在「圆场」接手陌生模块时,我常会把一段代码丢给 AI,问:「这是在干什么?」它几乎总能讲出一套流畅的故事 问题是——流畅不等于正确,更不等于它真读懂了约束 我越来越在意一种说话方式:它在「圆场」 表面在解释,实际在把不确定的地方用顺滑的因果糊过去 这篇文章记我怎么听、怎么追问、什么时候该停 写给同样会在「哇它好懂」和「等等它是不是编的」之间来回横跳的人 我遇到过的圆场,大概有几类: 因果补全:代码里没写为什么,它给你编一个听起来合理的「因为……所以……」 命名联想:函数叫 refreshCache,它就按「刷新缓存」的教科书含义讲,不管仓库里这个词早就变味 忽略例外路径:主路径讲得很漂亮,catch、降级、兼容分支一笔带过

2026-10-15鱼鱼
Spring源码解析(1) 基于SSM看Spring的使用和Spring启动监听
Spring源码解析(1) 基于SSM看Spring的使用和Spring启动监听查看源码的顺序就见仁见智了,比较普遍的做法是从IoC入手,了解容器注入的每一个环节,掌握大致的流程 由于使用的是Spring,所以在这里我们引入比较古老的xml配置文件进行bean的配置,首先定义一个bean: 配置描述bean的xml,核心只有一行: 这样一来就可以使用BeanFactory这个容器来注入bean并使用了: 本来有封装好的XmlBeanFactory,这一类现在已经被弃用了,所以采用了他的父类DefaultListableBeanFactory;当然,也可以使用更加方便和常用的ApplicationContext: 当然从xml文件读取bean的配置只是其中一种目前用的不多的加载方式,还有基于包扫描等加载bean的方法,此处仅为理解IoC的基本使用

2020-08-04鱼鱼