标签 AI Coding 下的文章

现在基本上都在 ai coding,三天两头一个想法,开发了很多小工具,看到自己的成果,感觉的自己啥都能搞似的,什么网页、工具、插件、系统、平台都折腾了一番,突然有一点累了,你们是如何面对如今这个 ai coding ?
你们用 ai 都开发了啥?
2026 年还能开发点啥,搞点副业啥的,有推荐吗?

新春将至,美团技术年货如约而来。感谢这一路上,伙伴们的并肩前行与坚定支持!❤️

时光荏苒,美团技术博客已经陪伴大家走过了 12 个年头。过去一年,美团技术团队在持续深耕中积累了诸多值得分享的实践案例与开源项目。尤其值得关注的是,美团 LongCat 团队在大模型开源领域取得了不少亮眼的成果,这一年,我们陆续发布了覆盖基座模型、图像、视频、语音等多个方向的开源产品与工具,持续助力 AI 技术共享与生态繁荣。截至目前,美团技术团队微信公众号已累计发布 640 余篇技术文章。

值此马年春节来临之际,我们精选了过去一年美团技术团队微信公众号发布的 40 多篇优质技术文章,精心汇编成一本近 600 页的电子书。谨以此作为一份特别的新年礼物,献给每一位热爱技术、持续探索的同学。祝大家在新年里,一「马」当先,「马」到成功!

这本电子书的内容涵盖大模型、开源、AI Coding、安全、数据库、智能硬件、AB实验等多个技术领域,同时收录了一些美团技术团队与高校的合作成果,以及被多个国际顶级会议收录的论文合集,希望能为大家的工作和学习带来一些启发与助力。也欢迎大家将这份电子书分享给更多志同道合、追求进步的伙伴,让我们一起携手共进,砥砺前行。

新的一年,愿大家继续乘风破浪,在挑战中铸就辉煌;以坚定的步伐,踏出属于自己的未来之路。

如何获取

❤️ 温馨提示

  • 技术年货合集大小约为60M,下载需要一定的时间,建议通过PC浏览器进行查阅、下载;
  • 打开电子书目录后,可直接点击感兴趣的文章进行阅读;
  • 部分文章中的动态图片、视频无法在电子书中完全的展示,大家可以在公众号历史文章中进行阅读,感谢理解。

| 关注「美团技术团队」微信公众号,阅读更多技术干货!

| 本文系美团技术团队出品,著作权归属美团。欢迎出于分享和交流等非商业目的转载或使用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者使用。任何商用行为,请发送邮件至 tech@meituan.com 申请授权。

因为 AI coding 的加持,现在实现一个“好点子”的成本和效率低的太多了。所以几乎每周你都能看到一款新产品(包括不仅限于模型,agent )的面市并霸榜。随着下一款产品的发布,上一款产品就热度瞬间不在。大部分的周期都不超过一个月,多数都在 2 周。

你总能发现有营销号,朋友圈或者朋友同事鼓吹它们,事实上它们甚至压根没用深度使用过,当然有的人是拆揣着明白装糊涂。

因此我最近越发感觉,如果你发现,一个人总是频繁的鼓吹这个那个,那这个人的智商(广义上的智商)通常不会很高。

Matrix 首页推荐

Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。

文章代表作者个人观点,少数派仅对标题和排版略作修改。


2025 年,我的工作习惯彻底被 Claude Code、Cursor 和 Codex 改变了,它们给我带来的改变,不亚于当年我用易语言写出第一个应用程序。同时这句话不仅适用于我的产品经理身份,也同样适用于我的工程师身份。

对我来说这不仅是软件开发效率的提升,也是软件开发方式的重构。

我说的是哪种 AI Coding

talking past each other

在社交媒体上讨论 AI 编程时,很多时候大家其实没有对齐在讨论的 AI 编程范畴和适用领域。所以大部分情况下大家在鸡同鸭讲,公说公有理、婆说婆有理。在我们真正讨论 AI 编程之前自然需要先澄清一下,我们到底在讨论什么「AI Coding」?

different levels

目前来说, AI Coding 有几种不同的产品和用户交互形态,包括:

  1. L1:古典的 ChatGPT 交互问答。有问题直接问 ChatGPT、Gemini、Claude 等 AI 助手,借助 AI 助手给出的信息,自行 Debug 和修改代码。
  2. L2:IDE / 插件中提供的补全功能。直接写函数名,然后 AI 会帮你补全函数的细节,你再自己微调或者不微调。这种能力其实过去也有,只是没有这么强悍。大家使用 IDE 来开发,很大程度上就是在利用 IDE 极佳的补全能力。
  3. L3:本地 AI Coding 工具的 Agent 模式,全托管或半托管式编程。你只描述需要做什么,具体做动作由 AI 来完成;这里还有几个细分的方式,包括完全托管(比如 Claude Code 开 –dangerously-skip-permissions、Codex 开 –dangerously-bypass-approvals-and-sandbox)和半托管(用户手动确认行为,只是由 AI 来完成具体修改的动作)。L3 操作的是你的本地环境,有破坏的风险,但也有无限的可能。
  4. L4:使用网页端的 AI Coding 工具直接出 Demo。不需要在本地配置任何开发环境,直接在网页端完成 Coding,你只需要描述你想要的东西,剩下的完全交给 AI(虽然这往往意味着难以与复杂的本地业务流集成)。

所以大家在社交媒体上和别人讨论 AI Coding 的时候,很有可能你在聊 L3、但别人在聊 L4。看似聊的是一个东西实际上完全不同。我们这篇文章讨论的则主要是 L3 —— 即使用本地的 AI Coding 工具的 Agent 模式,全托管或半托管式编程。

为什么是 Agent 模式

说完了大家眼中不同的 AI Coding 工具,我也必须再强调一下,即使大家聊的都是「AI Coding 工具的 Agent 模式」,因为身份不同,每个人的用法也会有很大差异,大家对工具的预期也完全不同。

因此对 Agent 模式的评价大体也可以拆分为三个大类:

different groups of people
  1. 传统的软件工程师:使用 AI Coding 工具完成自己工作过程中的一些辅助性工作,对于自身的能力和工作的要求有较高的要求。
  2. 有一定研发概念的产品工程师(称之为产品工程师是因为他们有一些基础的软件工程概念):使用 AI Coding 工具拓展自己的能力圈,去做一些之前必须依赖软件工程师才能做完的事情(比如做个小 Demo,或是上线一个软件产品)。
  3. 被媒体上的文章忽悠进来的小白(他们基本上没有太多的软件工程经验和基础):跟着网络上的信息了解到了 Coding Agent,然后尝试在不同的软件上使用(不局限于 Claude Code,Cursor 的 Agent 模式也算),经常会卡在一些软件工程的基础问题上。(我特别推荐这类人去看《计算机教育中缺失的一课》,看完以后,会让你很快理解你所遇到的问题,并能够快速处理 AI Agent 所给你的信息,进行下一步操作)。

而之所以是 Agent 模式,相比于补全模式需要你有一段现成的代码,Chat 模式往往不指引你完成所有的工作、或需要你有一定的互联网软件基础,Agent 模式自带的环境操作能力,能让你即使完全不懂 AI 和 Coding,也可以做一个像模像样的小应用出来。

这打破了过去需要软件工程师才能做出一个 Demo 的限制,同时也极大地鼓励了新手小白,人人都想试着做一些有意思的事情。Agent 模式也是 AI Coding 最出圈的一个特性。

我与 AI Coding 的 Agent 模式

在这条上,我提到我经历过三种不同的状态,这源自于我过去一年的体验。

在过去这一年里,我从一个「以补全为主,抗拒 AI Coding Agent」的工程师,转变为了一个「好好利用 AI Coding Agent」的工程师。当中离不开我身边的朋友们和小伙伴们,和他们的协作让我真的意识到了 AI Coding Agent 的价值1

作为一个写了十数年代码的工程师,我拥有一些自己平时写代码的「脚手架」,可以帮助我快速完成一个项目,而同时出于工程师的自我要求,我希望我自己写的代码能够拥有不错的代码质量和性能。

所以在一开始我对于 AI Coding Agent 的能力是持怀疑态度的,虽然依然会使用,但整体信任度没有那么高,往往只让它处理细枝末节,比如让 AI 去写一个完整的功能的细节,或者是让 AI Coding Agent 去 Code Review,基本不会让它动业务代码。

直到 Claude Sonnet 3.7 的时候,我才发现 Claude Code 已经能完成不少的工作,甚至很多小的功能也不再需要我先行规划、再让它自己做细节。我可以非常坦然的交给它一些工作,而我只做关键验收。从这个时刻开始,我对于 AI Coding Agent 的使用频率与日俱增,我开始使用 AI Coding 去实现越来越多的功能和效果,并最终对 AI Coding 放权——开启了 --dangerously-skip-permissions ,让 Claude Code 自己去写代码,去实现效果。

和所有使用 AI Coding Agent 的人一样,我也经历过 AI Coding 工具将代码整的一团糟然后放弃的时刻。不得不说,Claude 有些时候的过度设计真的让人无语。所以即便这就是最佳实践,但最佳实践不仅仅要配合着实践用,也要配合着项目时间节点和周期,以更好的完成项目的目标 —— Coding 只是完成目标的手段,而不是目的。

我对 AI Coding Agent 模式的看法

首先,我得旗帜鲜明地表明,所有软件工程师都应该试着使用 AI Coding Agent。

放弃、逃避、蒙头装鸵鸟都是没有意义的,熟练掌握 AI Coding Agent 已不再是加分项,而是生存技能。AI Coding Agent 正在切实地改变着我们的行业。

诚然,AI Coding Agent 不会影响我们这些「老」工程师的工作,但这个问题如同被熊追着一样——淘汰你的从来不是熊,而是比你跑得更快的人。AI 不会淘汰工程师,但会淘汰那些拒绝进化的「手动操作员」。优秀的工程师不会消失,我们的职责正从「手写逻辑”转变为「选择方案、设计架构、验收质量」。

其次,我依然相信大家的软件工程经验是有价值的。

就像上面我提到,最佳实践本身没有问题,但每个人所面对的项目节奏是完全不同的。软件工程师的价值从手写代码,变成了选择 AI 提供的解决方案,审核 AI 提供的解决方案,并最终更好地完成自己的工作。优秀的软件工程师不会消失,只是工作职责变了,AI Coding Agent 会让他们获得更多「加成」。

我怎么用 Coding Agent

我目前自己同时在使用的包括 Claude Code、OpenAI Codex 和 Gemini Cli,其中前两者是我自己花钱买的,后者是 GDG 赠送的。

我强烈建议大家自己花钱购买。公司买了自然最好,如果公司没买,自己买也是划算的。 Claude Code 5X 已经满足日常使用了,如果你用量大再升级 Claude Code 20X 即可;$100 其实就是大家聚餐吃一顿价格,并不贵,但给你带来的提升是远超这个价格的。

我对于 Coding Agent 的使用会包含本地使用和云端使用两块,以及一些「质量守卫」。

本地使用

本地使用时,我会使用 Claude Code 的 Plan Mode 来设计一些需求,通过和 Coding Agent 的几轮交互约束需求范围,并让 Claude Code 去完成相关的功能。

同时,我会使用 Codex 来为我的项目补全测试 —— 过去我很多时候都懒得写测试,现在有了 AI 来帮助我测试基础覆盖,大大提升了效率。或许 AI 无法保证测试得像一个专业测试同学那样完善,但却可以让我先完成从 0 到 1 的建设。

Gemini Cli 则会在一些时候作为项目的补充,主要也是 GDG 赠送的 Plan 额度有限,所以用得不多。

之所以会同时使用三个不同的 Coding Agent,主要还是考虑到模型本身的能力是有差异的;不同的模型可以给我提供不同的视角,从而可以确保对于一个问题有更全面的思考,规避可能的思维漏洞。

云端使用

除了本地的使用,我还会在云端使用 AI Coding Agent,但并不是使用网页端的 Coding 工具,而是在 CI 工具链中集成 AI Coding Agent,使用 AI Coding Agent 对我的每一次提交、每一次 PR 进行代码评审,通过这样的方式帮我更好地发现代码中的问题,既可以确保自己对于问题的思考没有漏洞,也可以进一步的发现自己的经验不足,补全面对问题时的思考维度。

特别值得一提的是,集成多个 Coding Agent 可以明显看到不同 Coding Agent 对于问题的思考角度和深度不同,对于自我提升也非常有帮助。

质量守卫

由于AI Coding Agent 本身存在的问题,大规模编辑代码的时候,往往也会引入一些编辑错误、无用代码和不符合规范的问题。

因此我在深度使用 AI Coding Agent 的项目中,都会引入大量的质量守卫,来确保不符合规范的代码无法提交到云上。我们应当保持对 AI 的信任,但必须坚守 「信任但要核实(Trust, but Verify)」 的原则,确保 AI 提交的代码每一行都可信、可控。

flowchart

这里的具体工作包括:

  1. 引入静态检查的准入机制,扼杀低级错误:借助 git hook,在提交前进行 code format。
  2. 引入质量红线,控制确保逻辑不出错,没有改错之前的代码:借助 git hook 和单元测试围栏,要求提交到代码库中的代码必须测试覆盖率满足要求(强 AI Coding Agent 介入的项目会要求测试覆盖率到 100%,并包含集成测试和端到端测试)。
  3. 引入 AI Agent 的自愈能力,闭环问题的修复:借助 git hook 和一些 linter 工具,发现代码中的问题,并让 AI Coding Agent 自己去修复它。
  4. 引入代码复杂度分析工具,让 AI 写出人和 AI 都易于维护的代码:常见的编程语言基本上都提供了圈复杂度检查工具,你可以在你的项目中引入圈复杂度检查工具,让 AI 提交之前确保所有代码的复杂度不会太高,从而既可以借助 AI 的能力快速迭代,同时又保留自己随时介入的可能性。

当你有充足的围栏检查,就可以放心让 AI 去完成工作,并要求它自行提交 commit 了。这样可以让其自动执行 git hook 并修复 git hook 中所配置工具检查出来的问题,从而确保提交到代码库中的代码不会有一些基础问题。

你该如何开始(工程师篇)

如果你是一个工程师,想要试试 AI Coding Agent 但又不知道怎么做:我能理解你对于代码质量的要求,和你的工作对你的要求;我也知道你担心引入 AI 导致你的项目复杂度快速提升、无法维护,最后导致项目彻底崩盘,你反而被干掉。

所以,我推荐你这么干:

  1. 在现有的 CI 工具链中加入 AI Coding Agent 进行代码评审,让 AI 先从这一步开始给你提供更多的建议,先帮你变成一个更好的工程师;
  2. 习惯让 AI Coding Agent 参与到你的工作流里后,可以先让 AI 帮助你补全测试,建立起单元测试围栏,从而让你放心地引入 AI Coding Agent 参与项目;
  3. 使用 AI Coding Agent 完成你的工作(记得加入各种围栏),让你自己获得进一步的解放。

当你完成了上述三步后,你已经熟悉了 AI Coding Agent,除了做一些你熟悉的工作,还可以让它带着你去做一些你所不熟悉的事情。比如你是前端就让它带着你搞后端,如果你是后端就让它带着你搞 iOS……

总结

到了 2026 年你依然可以 Happy Coding,不过大家也要意识到,我们除了做体力劳动的 Coding,更应该用好 AI Coding 工具,将这些托管给 AI Coding Agent。

然后我们的工作才会越来越具有「创造性」,才能去做一个「创造者」。

> 关注 少数派小红书,感受精彩数字生活 🍃

> 实用、好用的 正版软件,少数派为你呈现 🚀

    飞猪搭建体系介绍

    可视化页面搭建技术在业界已相当成熟,几乎每个前端团队都会建设一套页面搭建系统,它显著提升研发效率与交付速度,已成为业务快速迭代与规模化生产的关键基础能力。飞猪移动端页面搭建最早诞生于营销大促场景,不同于常规的业务开发,营销大促业务具有以下特点:

    • 迭代速度快:飞猪大促项目频次高且节奏紧凑,传统瀑布式研发模式难以适配业务快速迭代诉求。需沉淀一套面向活动场景的低代码平台,将页面公共能力和通用组件进行标准化、平台化,以降低重复开发与跨团队协作成本,支撑快速迭代与高频发布,在有限周期内兼顾交付效率与稳定性;

    • 页面数量多:同期活动通常涵盖多个会场、频道、主题页及域外落地页等,上百个活动页面并行推进,且页面结构差异较大,高频、紧急的营销节奏叠加海量页面需求,使研发交付压力显著增加;

    • 页面变阵频繁:一场完整的大促活动通常要经历「预热、预售、现货」等多个阶段,不同阶段的核心目标与主推商品 / 权益会递进变化,运营工作人员需要实时盯盘,根据流量、转化与库存等数据频繁调整页面内容与商品坑位布局且要求快速生效;

    基于上述特性,飞猪移动端页面搭建体系应运而生,我们围绕可视化搭建、数据配置动态渲染三大核心能力,打造了一套面向高频迭代与规模化交付的页面搭建体系。该体系从初代寄生于阿里集团搭建平台下的一个服务站点起步,先后经历了数据投放服务自建、平台能力自建、搭建服务与渲染底座自研。最终形成了当前将数据投放页面搭建深度融合的一体化“搭投”体系能够灵活支撑营销大促、日常频道、互动玩法、机酒汽等行业场景、商业化以及小程序等多场景业务需求。

    飞猪搭建体系遵循 PMT 模型规范,核心概念包括:

    • Page(页面):用户可访问的完整页面载体,由页面容器聚合多个业务模块完成运行时渲染,页面容器提供通用基础能力,包括:模板引擎渲染、协议数据的转换与分发、组件依赖与运行时注入、以及埋点与日志等公共服务;

    • Module(模块):可复用的业务组件单元,封装组件的展示与业务逻辑并定义数据绑定规则,支持独立配置、按需组合编排,快速拼装成不同页面结构;

    • Tag(资源位):模块内用于承载内容投放的最小单元,用来挂载与管理投放数据,一对多关联具体数据投放配置,并支持个性化规则定投;

    图片

    飞猪搭建平台

    现状与可优化空间

    从寄生站点到自研体系的全面回迁,标志着飞猪搭建体系逐渐成熟,但是依赖传统人工选搭投的模式没有得到本质化的改变。下一阶段的重点,是在既有能力之上进一步释放效率红利,围绕“搭建自动化、配置智能化、保障体系化”持续优化:

    • 运营侧提效:页面搭建链路仍有较大提效潜力,当前运营在模块选择、配置理解、跨平台联动配置上投入时间较多,且在日常使用中对咨询支持的需求仍然较旺。与此同时,运营团队更新节奏快,新人从熟悉到独立产出仍需要一定学习成本,存在进一步降低门槛、增强引导与工具化的空间;

    • 设计侧降本增效:页面交付对设计资源的依赖仍然较重,尤其在大促等峰值场景,设计需求集中、节奏紧,容易成为影响整体交付效率的关键路径。日常场景采用计件和众包模式也带来一定的成本与协同开销,因此在设计素材智能生成等方面有进一步优化空间;

    • 产研侧提效:

      答疑提效:尽管已有答疑平台与知识库沉淀,但是在自主排查方面仍可继续增强,高频场景可进一步沉淀标准化诊断与一键解决方案,减少人工介入;

      技术保障提效:大促会场通常需要多轮预演,上线后也需要持续巡检以应对业务调整带来的体验波动。随着平台迭代和营销活动频次提升,可通过自动化预检和巡检等方案持续降人工保障投入;

      研发提效:搭建模块遵循特定规范与约束,新人从上手开发到独立交付仍需一定学习成本;同时由于容器和渲染等核心链路的黑盒特性,仍需平台负责人员提供一定协同支持与保障。可引入 AI Coding 辅助研发,并完善 AI 自助诊断与排障工具,提升代码研发与问题排查效率,降低对平台协同支持的依赖;

    AI 化升级的目标

    如今正是 AI 蓬勃发展的时代,问答推理、物料生产、流程编排等方案已经成熟,当下的命题应当是思考搭建 + AI 如何深度结合,打造智能化搭建系统,从人工运营向 AI 辅助运营转型,最终实现无人值守自动化运营。为解决选搭投当前的问题正式启动 AI 智能搭投升级专项:深度融合图文素材生产系统、大模型调度编排等能力,将 AI 模式注入招商选品、页面搭建、数据投放等核心系统,构建从需求理解 → 智能编排 → 自动执行的搭投新范式,为未来全域智能运营奠定技术基础。

    • 提升运营配置效率:打通“招选搭投”体系 AI 基础能力,通过推荐模板页面、智能搭建页面、智能助理运维等能力辅助业务快速完成页面搭投,覆盖飞猪页面搭建全场景、提升运营配置效率、减少页面配置时间;

    • 减少设计投入成本:全面推广 AI 文生图和创意合图能力,实现计件众包模式向业务自助产图转型,减少设计费用实现流程提效;

    • 减少人工答疑成本:AI 赋能答疑场景,提升答疑助手拦截率,常见配置问题自动定位并引导解决,缩短问题解决耗时;

    • 提升模块研发效率:模块研发全面拥抱 AI 模式,完善搭建 IDE Rules + MCP 生态,探索 D2C 在搭建模块开发应用场景,提升模块开发效率;

    产品结构设计

    智能选搭投体系 = AI 搭建 + AI 投放 + AI 素材 + AI 助理 + AI 答疑 + AI Coding

    图片

    产品结构

    技术实现细节

    智能搭建

    模板检索

    为了保证 AI 生产的页面尽可能贴合飞猪营销页面规范且保证转化效率,以及让运营人员有体感预期,我们采用模板预览的形式作为平台入口,基于用户描述推荐场景相似且业务效果较好的模板,用户可进行预览并确认后进入下一步生产流程。此外我们对页面模板进行了分类,不同的页面类型会走到不同的 Agent 完成生产。

    图片

    模板预览

    那么这么多页面模板从哪里来呢,总不能人工维护吧?答案是基于历史页面作为模板即可,毕竟运营人工搭的页面一定是符合预期效果的。通过跑定时任务批量对历史页面进行回溯,再交给多模态 LLM 分析页面内容打标,作为检索关键词进行向量化并落库,检索时进行相似度计算排序即可,实现细节如下:

    • 页面回溯:处理埋点日志找到页面 UV 最大的日期,基于该日期进行页面结构和投放数据 mock 穿越处理,并忽略页面下线重定向逻辑,即可回溯到该页面历史线上投放效果;

    • 页面快照:基于无头浏览器对页面进行截图,生成页面截图快照;

    • 内容打标:基于多模态 LLM 进行页面内容分析,生成页面内容维度标识,包括:页面介绍、关键词、行业标、主题标、质量评分、效率评分等,作为相似度计算的依据;

    • 向量持久化:基于 multimodal-embedding-v1 等多模态向量模型将快照截图和内容标识转换成浮点向量,存到关系型数据库即可(如果数据量较大推荐使用向量数据库);

    • 检索召回:实时检索时先进行简单的 SQL 检索过滤,再将用户关键词进行向量化,与数据库中的向量字段进行余弦相似度计算,最后排序返回即可;

    图片

    向量检索链路

    页面生产

    在页面生成链路,我们梳理了飞猪现存搭建页面类型,大致可分为“搭建页”、“频道页”、“图文页”、“文本页”四类,不同页面类型有着各自的应用场景,需要针对性设计不同的技术方案:

    图片

    最终生产的页面效果如下,完全达到线上可投放标准:

    搭建页

    传统搭建页主要通过各行业通用模块搭建而成,不同搭建模块配置项各异且繁琐,新人理解学习成本非常高,即便是运营老司机走完配置流程也需要花不少时间,另外在配置过程中还需要填写大量图片素材依赖设计团队产图,页面搭建过程并不丝滑,一整套页面搭建下来往往需要花费大半天甚至几天时间。

    为此我们设计了智能搭建系统,基于用户选择的页面模板复制页面和模块,LLM 推理用户需求总结归纳为页面搭建方案,批量调用智能投放链路(详见后文)完成模块配置,再打通后续排期发布和页面发布工程链路。整套流程只需要 3 min 即可完成,用户描述需求后全程无感,并且支持退出页面后台异步生产。

    图片

    搭建页面生产效果

    整体走大模型编排链路,链路如下:

    图片

    搭建页生产链路

    各流程节点实现细节如下:

    图片

    图文页

    传统搭建模式难以有效支持图文页面场景,难点在于图文页偏设计化、页面结构较复杂,一直以来我们都依赖设计出视觉稿再切图投放,该模式设计计件费用昂贵并且流程较长,对于短平快的营销场景来说是属于历史糟粕亟需革命。我们尝试了以下方案,结果总是差强人意:

    图片

    我们总是在讨论 AI Coding 如何对程序员提效,那么能否直接绕过 “中间商赚差价”(拿起剪刀剪自己辫子),让运营工作人员直接基于 AI 生产页面呢?答案是可以的,抛开复杂的页面交互逻辑,如果仅是产出静态图文页面,完全可行。

    我们设计了一套 Agent 模拟 “前端页面开发” 流程,由 LLM 担任产品、PM、设计、开发等多角色,协同完成图文页面开发任务,最终产物为页面 HTML 代码。再将 HTML 代码渲染至左侧面板提供预览能力,支持文本、图片等 DOM 元素可视化编辑以及选中元素后 AI 微调等能力供运营人员二次调整。页面调整完成后会按页面片段进行图层切分,基于 html2canvas 库将 HTML 片段代码转换成 PNG 图片,导入图片模块并借助 LLM 完成自动圈选热区,最终生成可点击图文页面,或者直接 HTML 代码注入模块实时渲染。

    图片

    图文页生产效果

    整体采用 Manager–Worker 架构设计智能体,拆分分析器、调度器、设计师、工程师等多个角色协同完成长图文生产任务,单 Agent 内部实现完整的 ReAct 范式确保输出最优,使用任务队列模式存储执行进程和上下文,由 AI 自主完成监督调度。在设计 Agent 时需要严格约定出入参数据格式以便调度器准确调度执行,另外还需要设计纠错机制和重试机制保障 Agent 节点在意外抖动时整体链路能够稳定运行。图片页生产链路

    图片

    核心 Agent 实现细节如下:

    图片

    智能投放

    飞猪搭建体系遵循 PMT 规范,其中资源位数据投放也是搭建链路中重要的一环,我们自建了数据投放系统,支持静态数据源(模块配置)、标准数据源(商品宝贝、酒店日历房)、插件数据源(服务端接口)三类数据类型,涵盖了几乎所有场景的数据内容投放。在搭建 AI 化升级过程中我们对数据投放链路同步进行了升级,衍生出了智能投放链路。智能投放目前支持了图片素材、模块配置、商品选品、二方平台四类场景一句话快速投放,并且支持全类目定投策略智能关联能力,如:时间周期、人群、设备等。我们还对智能投放原子化能力进行封装以支持页面级批量调用,通过 LLM 分析页面主题归纳页面搭建方案,各模块基于搭建方案自主生产投放数据。

    智能投放技术链路如下图,首先 LLM 会根据用户描述、页面和模块信息进行推理,生成符合页面主题的模块推荐配置,引导用户快速选择。用户进一步描述后,LLM 针对不同物料类型生成所需的内容素材,包括:配置项(JSON)、文案、图片等,并对素材内容整合转换成模块配置入参,若语义识别到用户有定投诉求会自动进行配置,最后调工程链路完成排期发布和钉钉消息通知。

    图片

    智能投放链路

    智能投放各节点详细方案和效果如下:

    智能助理

    在页面搭建过程中,运营人员除了搭建模块和数据投放外,通常还需要配置页面容器、插件,以及后续投放过程中的渠道加参和转码转链等操作。这类配置内容比较分散,甚至跨多个平台,对于新人运营人员有一定学习过程。因此我们结合 AI 能力推出了「智能助理」,涵盖:页面修改、转码转链、热点分析等多种能力,支持语义识别用户的诉求自动调用相应的工具,辅助用户提高运营效率。

    技术链路上比较简单,通过 LLM 理解用户的操作意图,转换成工具约定的出入参并调用底层平台能力完成对应的操作,功能实现细节如下:

    图片

    智能素材

    此外我们还提供了原子化素材创意生成能力,帮助有匠心的运营人员快速微调和优化页面素材内容:

    AI 答疑

    飞猪搭建直面一线运营人员,我们没有专业的技术支持人员,答疑工作只能由产研人员“兼职”。每天面对大量的答疑咨询工单,让本就繁忙的研发工作雪上加霜。在 LLM 普及后我们也是第一时间接入答疑场景,提供平台和群答疑两种交互模式,日常常见问题全部交由 AI 处理,技术人员只需处理疑难杂症即可。将答疑工作量减至原来的 1/6,拦截率达到 91.4%

    AI 答疑技术方案比较简单,纯调 LLM 没什么好说的,核心需要丰富的知识库来提高答疑准确率。我们扒了近几年来飞猪搭建相关的技术 & 产品文档,根据常见问题进行分类,修订为搭投提示知识库。有了知识库还需要对 RAG 进行优化,主要通过文档分段打标实现,我们通过三方接口召回了集团答疑工具近年来所有人工答疑记录,作为语料支持对现有知识库进行打标,文档缺失部分将该 Case 作为 FAQ 进行补充。基于存量知识库答疑总是具有局限性,随着飞猪搭建体系不断地迭代发展,所以还需要让 AI 自我学习最新知识,我们将 AI 对话和人工答疑对话落库,跑定时任务召回对话并进行向量化落库。后续实时检索时历史对话也会作为知识库的一部分。

    图片

    AI 答疑 RAG 链路

    AI Coding

    搭建模块开发:

    在 AI Coding 方面我们没有选择造 “重复且低质量的轮子”,而是在 Qoder、Cursor 等成熟 IDE 基础上,通过修订 Rules 方式增强 AI 编码能力。我们编写了 8 类搭建模块开发特殊规则,并接入飞猪代码仓库知识库、Ftech、Figma 等 MCP 服务实现组件库代码片段召回、PRD 理解、D2C 视觉稿转码等能力。有助于模块开发提效,对于新人入门非常友好,整体编码提效 80%+,实测模块功能实现和业务逻辑近乎完美只需要微调样式,规则目录如下:

    图片

    schema 编写助手

    飞猪搭建模块配置表单遵循类 JSON Schema 规范,我们开发了 Schema 编写助手,辅助开发快速生成表单配置,支持 mock 数据和 schema 配置互转,减少新人学习成本、提高模块开发效率、减少研发答疑成本。

    图片

    schema 助手

    总    结

    通过对选品、搭建、投放、素材等平台全面整合,我们对飞猪搭建体系进行全面的 AI 化升级,面向运营、设计、产品、研发等全角色构建了一体化的智能搭建平台。在产品形态上,智能搭建体系已经形成智能创建、智能投放、智能素材、智能助理、AI 答疑、AI Coding 六大支柱,为未来全域智能运营奠定基础。

    开发一套 AI 体系远比想象中困难,它不像写代码那样有明确、可复现的确定性结果,几乎每天都在对着“人工智障” 挠头。最棘手的问题之一就是大模型的幻觉:自始至终都在困扰着我们,哪怕只是一个很细微的偏差,在多轮任务的链式执行中也会被不断放大,最终产出就可能变得不可用。在不讨论训练 / 微调模型这类高阶手段的前提下,我认为提升 Agent 准确率无外乎以下几种手段:

    • 架构设计:Agent 开发需要有 “把不确定性关进笼子” 的架构设计,实践中可以结合具体场景参考网上的经典设计案例,把任务拆解为可控步骤并引入观测、校验、重试、回滚等机制,将大模型的自由生成约束在可验证和纠偏的闭环中以降低幻觉;

    • 工程实现:多数场景下,工程代码在执行性能与稳定性上更具优势,对于链路中规则清晰、可验证的环节,优先用工程代码实现,能有效降低不确定性;

    • Prompt 调优:Prompt 是一门学问,调好了能让大模型稳定地发挥能力,总结来说就是结构化、多约束、评估标准、分层书写。网上有许多教程和黑科技,不妨先快速学习一轮,实践中灵活尝试运用,磨刀不误砍柴工;

    • 上下文管理:对于多 Agent 体系中,上下文管理尤为重要,一股脑往里塞必然导致 “上下文污染” 越聊越偏。因此需要设计合理的 memory 结构,为上下文标注来源和边界,只使用可信内容、临时内容及时销毁;

    • 模型升级:终极大招,可能你调了半天发现还没换个模型见效快,那就等待 AI 科技的发展进步吧。但是别忘了,基建架构是不可逆的,设计好了就是锦上添花,设计烂了就是雪上加霜;

    展望

    下一阶段的关键在于把 AI 搭建从 “提效 Copilot” 升级为 “可控、可评估、可闭环的生产系统”,通过约束式架构、自动诊断调优等手段不断提升 AI 的自我思考能力并减少幻觉,推广到日常活动、频道运营、大促活动等方方面面,支撑飞猪更高频、更复杂、多场景的全域智能运营。以下是建设过程中的一些思考以及后续规划:

    GMI Cloud Inference Engine 是全球 AI 模型统一接入与在线使用的“高性能推理引擎平台”,底层搭载 H100/H200 芯片,集成全球近百个最前沿的大语言模型和视频生成模型,如 Gemini、Claude、Minimax、DeepSeek、GPT、Qwen、Kling 等,为 AI 开发者与企业提供速度更快、质量更高的模型服务。

    欢迎来到!🎉🎉🎉

    GMI Cloud Inference Engine AI 场景实践案例集【AI Coding 篇】之二。

    **本期任务目标:**在 Windows 终端里,使用 Claude Code 命令行工具,连接 GMI Cloud Inference Engine 的 MiniMax 模型 API。

    Claude Code 是 Anthropic 推出的命令行 AI 编程工具,基于 Claude 大模型,可在终端 / IDE 中用自然语言交互,深度理解代码库,支持跨文件编辑、Git 协作。其具有 agent 优势,与超大上下文+多文件编辑+终端原生+安全自主执行+顶级模型能力,在处理大型项目、复杂重构和企业级开发时展现出明显优势。

    本文将以接入 Inference Engine 中的 MiniMax-M2 api 为例,详细讲解在 Claude Code 中接入 api 的过程。Token福利文末自行领取!!

    MiniMax-M2 界面:

    https://console.gmicloud.ai/playground/llm/minimax-m2/bbfb2cb...

    01

    准备工作

    Get ready?

    确保你已经掌握 AI Coding 基础知识,没有可看上一篇:

    附上链接~

    Kooty,公众号:GMI Cloud 黑板报小白友好教程!如何在 Cursor 接入 GMI Cloud 的 API

    确保你的电脑已经安装了:

    • Python (为了运行 LiteLLM)
    • Node.js (为了运行 Claude Code)

    02

    接入步骤

    API Connection Guide

    步骤 1:安装必要工具

    打开 PowerShell,依次运行以下命令:

    1.安装 Claude Code 工具

    npm install -g @anthropic-ai/claude-code

    2.安装 LiteLLM(带代理功能)

    
    # 注意加上引号,因为[proxy]是特殊字符 
    pip install "litellm[proxy]"

    如果不懂怎么安装,可以直接在 Cursor 聊天框输入(亲测 Gemini3 可以直接一步到位,模型不够好可能中途会报错):

    https://docs.claude.com/en/docs/claude-code/overview参考这个文档,帮我安装claudecode

    无论是通过哪种安装方式,Claude Code 在安装后都会引导你配置参数或者注册登录,如果你有账号可以按照引导往下走。如果没有、希望和笔者一样直接接入自己的(便宜的)api,可以登录到非得付费的那一步退出,然后继续步骤 2。

    步骤 2:启动“翻译官” (LiteLLM)

    我们需要启动一个本地服务,用来做连接我们的 api 和 Anthropic 之间的桥梁。在 PowerShell 中运行(替换为你自己的 API Key):

    
    # 设置 Key (必须加引号)
    $env:OPENAI_API_KEY = "你的MiniMax_API_Key"
    
    # 启动服务
    # --drop_params: 自动丢弃不兼容的参数,防止报错
    litellm --model openai/MiniMaxAI/MiniMax-M2 --api_base https://api.gmi-serving.com/v1 --drop_params

    ✅ 成功标志:看到 Running on http://0.0.0.0:4000

    ⚠️ 注意:这个窗口不要关闭。步骤 3 打开一个新的 powershell 窗口。

    步骤 3:配置 PowerShell 连接

    现在我们要告诉 Claude 工具:“别去连官网了,来连我们本地的翻译官”。

    1. 打开配置文件:

    在新的 PowerShell 窗口中输入:

     notepad $PROFILE

    2.粘贴以下代码:

    
       function minimax {
           & {
               # 1. 把目标地址指向本地 LiteLLM (端口 4000)
               $env:ANTHROPIC_BASE_URL = "http://localhost:4000"
               
               # 2. Key 随便填,因为真实的 Key 已经在 LiteLLM 那边配好了
               $env:ANTHROPIC_AUTH_TOKEN = "sk-placeholder"
               
               # 3. 模型名称要和 LiteLLM 启动时的匹配
               $env:ANTHROPIC_MODEL = "MiniMaxAI/MiniMax-M2"
               $env:ANTHROPIC_SMALL_FAST_MODEL = "MiniMaxAI/MiniMax-M2"
               
               # 4. 启动 Claude 工具
               if (Get-Command claude -ErrorAction SilentlyContinue) {
                   claude @args
               } else {
                   Write-Error "请先安装 claude-code: npm install -g @anthropic-ai/claude-code"
               }
           }
       }

    步骤 4:开始使用

    1. 新建一个 PowerShell 窗口(确保配置生效)。
    2. 输入命令:
    
    # 启动自设定的minimax程序 
    minimax 
    # 进行测试 
    你好

    🎉 看到回复即搞定! 现在你就在用 Anthropic 的顶级命令行体验,驱动着公司的 MiniMax 模型了。

    大家可以对比输入“claude code”和“minimax”下的差别:

    图片

    步骤 5:将 LiteLLM 的启动简化(选做)

    Cursor 聊天框输入:

    帮我将LiteLLM的启动简化,生成一个一键启动脚本。

    下次使用时,就只需两步:

    1. 点击该脚本
    2. 在另一个终端窗口中输入“minimax”

    另外,如果想更方便,比如在桌面启动 LiteLLM,也可以将这个 .bat 的文件和 .yaml 的参数文件一起复制到目标位置。比如我将其复制到了桌面。

    图片

    图片

    💡 常见报错

    Q: 报错 ImportError: Missing dependency 'backoff'?

    A: 你安装时少装了组件。请运行 pip install "litellm[proxy]"。

    Q: 报错 UnsupportedParamsError: ... reasoning\_effort?

    A: 启动 LiteLLM 时忘了加 --drop\_params 参数。

    Q: 输入 minimax 提示找不到命令?

    A: 修改完配置文件后,需要重启 PowerShell 窗口,或者运行 。 $PROFILE 刷新一下。

    03

    总结和拓展

    Summary & Expansion

    总结

    1. 核心文件

    图片

    2. 完整的逻辑链路图

    • 准备层(启动网关)

    运行 start\_minimax\_proxy.bat。

    关键动作:它不仅加载了 yaml 配置,还通过 set OPENAI\_API\_KEY 把**通行证(Token)**交给了 LiteLLM 进程。

    结果:本地 4000(或其他)端口开始监听。

    • 调用层(触发指令)

    你输入 minimax。

    关键动作:系统执行 ps1 脚本里的函数。

    • 重定向层(配置环境)

    关键动作:ps1 脚本在内存里临时改了两个环境变量:

    ANTHROPIC\_BASE\_URL:指路,让 Claude Code 走向本地端口。

    ANTHROPIC\_MODEL:定名,告诉 Claude Code 要发出的“暗号”是什么。

    结果:Claude Code 启动并按照这个路标发包。

    • 翻译层(中转适配)

    关键动作:这是最复杂的一步。

    收包:LiteLLM 收到 Claude Code 的 Anthropic 格式请求。

    查表:它看一眼 yaml,发现 model\_name(暗号)对上了。

    变身:它把请求拆开,去掉多余参数(drop\_params),重新包装成标准的 OpenAI 格式。

    送达:最后,它带着 .bat 里的那个 Token,把请求发给供应商的 v1 接口。

    拓展:思考题

    如果不想用MiniMax了,想用Inference Engine平台的其他模型,该修改哪几个文件?

    **正确答案:**以Deepseek为例

    修改.ps1、修改yaml,将 minimax function 一样的格式复制一份、修改模型名称部分就可以啦!

    图片

    图片

    在启动时则可在终端输入deepseek,同样能成功启动

    图片

    教程完毕!😍😍😍 快去试试吧~

    AI生成代码质量难以把控!本文分享来自美团的技术实践,三大策略破解AI编程痛点。单测快速验证逻辑正确性,安全网保护存量代码演进,TDD模式精准传递需求。告别「看起来没问题」的错觉,构建AI时代的代码质量保障体系。

    一、引言

    目前,国内外很多AI Coding助手能在几秒钟内生成完整代码块,大大提升了开发效率,但这种高速开发模式也带来了潜在风险——与人工编码不同是,AI Coding助手生成代码存在两个特殊风险:其一,AI Coding助手依赖于上下文与模型自身的能力,输出的代码质量相对不可控。其二,AI生成的代码虽然逻辑通顺、结构完整,但可能隐藏着难以察觉的边界问题或逻辑缺陷。

    核心问题:我们如何快速的验证AI生成代码的质量和可靠性?

    本文旨在分享如何借助单元测试,让AI编程合作更高效可靠,主要解决三个常见痛点:

    1. 肉眼审查困境:AI一次性生成大量代码时,难以快速准确判断逻辑完备性;
    2. 存量代码信任危机:如何验证AI修改老代码时,不会产生非预期的结果;
    3. 需求传达难题:如何精准向AI表达复杂需求并快速验证。

    针对上述三个常见痛点,本文提出采用不同的单元测试策略来应对以上问题。每个策略都针对一个特定痛点设计:策略一通过测试解决肉眼审查的局限性;策略二构建单测安全网应对存量代码的信任问题;策略三则采用TDD模式优化需求传达与验证流程。下文将依次展开说明,希望能对大家有所帮助或启发。

    二、策略一:单测检验AI代码逻辑正确性

    2.1 问题背景

    传统的人工代码审查在AI生成的大量代码面前显得低效且不可靠。在软件测试实践中,有着测试左移(Shift Left Testing)的概念,本质上是借助工具和测试手段更早地发现问题和预防问题。在AI Coding时代,这一理念尤为关键:跳过单元测试直接集成测试看似”抄近路”,实则是将风险后置——开发阶段几分钟能发现的Bug,在集成测试环境可能需要较长定位修复,这中间包含了代码部署、环境准备、测试条件的准备、问题定位、开发人员修复、再次部署验证等一系列漫长的环节。

    相比之下,单元测试具有独特的优势:它能够独立运行、快速验证结果,并且可以无限次重复执行。这种测试方式就像是为项目进行的一次性投资,却能为整个开发周期构建起一张可靠的“安全网”。它不仅能实时验证AI Coding生成的代码是否正确,更能持续保障未来代码的质量稳定性,让开发团队始终对代码库保持信心。

    2.2 案例:分页查询接口的隐蔽Bug

    任务背景:实现一个支持多条件筛选的复杂分页查询接口pageQueryRobot

    AI生成了如下核心查询逻辑:

    public List<AgentRobotE> pageQueryRobotsByCondition(List<Long> shopIds, String chatSceneCode,
            Boolean enabled, Integer pageNo, Integer pageSize) {
        // ... 前置校验代码 ...
    
        // 分页查询机器人基础信息
        int offset = (pageNo - 1) * pageSize;
        List<AgentRobotEntity> entities = robotIds.stream()
                .skip(offset)
                .limit(pageSize)
                .map(robotId -> agentRobotDAO.getRobotById(robotId, false))
                .filter(Objects::nonNull)
                // 问题代码:类型不匹配的隐蔽Bug
                .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled ? 1 : 0))
                .filter(entity -> Objects.equals(entity.getChatSceneCode(), chatSceneCode))
                .collect(Collectors.toList());
    
        return entities.stream()
                .map(this::convertToModel)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    

    问题分析:这段代码看起来逻辑完整,但第8行的过滤逻辑包含了多个复杂元素:

    • 三元运算符 enabled ? 1 : 0
    • Objects.equals 的使用
    • Boolean到Integer的隐式逻辑转换

    仅凭肉眼很难发现其中的类型不匹配问题。

    单元测试发现问题:通过AI编写了17个全面的单元测试用例,覆盖:

    • 正常场景:各种有效参数组合
    • 边界场景:null值、空集合处理
    • 参数组合:enabled为true/false/null的不同情况
    @Test
    public void testPageQueryWhenEnabledIsTrue() {
        // arrange
        List<Long> shopIds = Arrays.asList(12345L, 67890L);
        String chatSceneCode = "SCENE_C";
        Boolean enabled = true;  // 测试enabled为true的情况
    
        // 模拟数据库返回的实体,enabled字段为Boolean类型
        AgentRobotEntity mockEntity = new AgentRobotEntity();
        mockEntity.setEnabled(true);  // 注意:这里是Boolean类型
        mockEntity.setChatSceneCode("SCENE_C");
    
        when(agentRobotDAO.getRobotById(anyLong(), eq(false))).thenReturn(mockEntity);
    
        // act
        List<AgentRobotE> result = repository.pageQueryRobotsByCondition(
            shopIds, chatSceneCode, enabled, 1, 10);
    
        // assert - 这个测试失败了!
        assertEquals(1, result.size());  // 期望返回1个结果,实际返回0个
    }
    

    测试运行结果:当enabled为true时测试失败!

    问题定位:通过测试失败,快速定位到过滤逻辑的问题:

    // 错误的逻辑:entity.getEnabled()返回Boolean类型,但与Integer比较
    Objects.equals(entity.getEnabled(), enabled ? 1 : 0)
    // 当enabled=true时,比较的是 Objects.equals(Boolean.TRUE, 1) -> false
    // 当enabled=false时,比较的是 Objects.equals(Boolean.TRUE, 0) -> false
    

    正确修复:

    // 修复后:直接比较Boolean类型
    .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled))
    

    意外收获:在审查测试覆盖的代码时,还发现了N+1查询的性能问题:

    // 存在性能问题的代码
    .map(robotId -> agentRobotDAO.getRobotById(robotId, false))  // 每个robotId单独查询
    

    成果验证:修复后,所有17个单元测试用例全部通过,代码质量得到保障。

    三、策略二:构建安全网保护存量代码

    3.1 问题场景

    AI对存量代码的修改挑战更大。AI看到的可能只是函数或类的局部,无法理解背后的业务规则和历史包袱。如何放心的让AI修改已有的代码?

    在进行AI Coding前,需要确保旧有逻辑,处于单元测试的完全覆盖保护中,这就像在开启汽车的“自动辅助驾驶”功能前,必须先系好安全带一样。这条“安全带”就是我们完善的、可运行的单元测试集。

    • 快速验证,精准反馈:AI生成修改后的代码无需人工逐行对比,只需运行单元测试即可获得即时反馈。测试失败的用例直接揭示AI修改中存在的问题——要么触及了不应改动的逻辑,要么未能正确实现预期变更。这种反馈机制既高效又客观。
    • 清晰界定修改边界:单元测试结果帮助我们明确判断——AI的修改是否精准实现了目标?在引入新功能的同时是否完整保留了原有逻辑?通过区分预期内的失败(主动修改旧逻辑)和意外失败(破坏现有功能),我们获得了优化AI方案的明确方向,大幅提升了迭代效率。

    3.2 案例:延迟回复策略的用户范围扩展

    业务背景:需要将消息延迟回复服务从原来的平台A、平台B的用户扩展到平台C用户。

    原始代码分析:

    // TextDelayReplyStrategy.java 中的核心逻辑
    private boolean needSkip(ChatHistoryE chatHistoryE) {
        UserDTO UserDTO = UserHelper.parseUser(chatHistoryE.getUserId());
        return MessageSendDirectionEnum.CLIENT_SEND.value != chatHistoryE.getMessageStatus()
                   || MessageShieldEnum.RECEIVER_SHIELD.value == chatHistoryE.getShield()
                   || UserDTO == null
                   || !UserType.isLoginUser(UserDTO.getUserType());  // 关键判断逻辑
    }
    

    这个needSkip方法决定了哪些用户类型需要跳过延迟回复处理。原逻辑中,UserType.isLoginUser()只覆盖平台A、平台B的登录用户,不包括平台C用户。

    修改前的安全网构建:

    按照“分析-测试-实施-验证”方法论,首先完善单元测试:

    // 针对现有逻辑的保护性测试
    @Test
    public void testNeedSkipWithAUser() {
        // 平台A用户不应被跳过
        ChatHistoryE chatHistory = buildChatHistory(A_USER_ID);
        assertFalse(strategy.needSkip(chatHistory));
    }
    
    @Test
    public void testNeedSkipWithBUser() {
        // 平台B用户不应被跳过
        ChatHistoryE chatHistory = buildChatHistory(B_USER_ID);
        assertFalse(strategy.needSkip(chatHistory));
    }
    
    @Test
    public void testNeedSkipWithCUser() {
        // 平台C在修改前应被跳过
        ChatHistoryE chatHistory = buildChatHistory(C_USER_ID);
        assertTrue(strategy.needSkip(chatHistory));  // 修改前的预期行为
    }
    
    @Test
    public void testNeedSkipWithGuestUser() {
        // 游客用户应被跳过
        ChatHistoryE chatHistory = buildChatHistory(GUEST_USER_ID);
        assertTrue(strategy.needSkip(chatHistory));
    }
    

    运行基线测试:确保所有测试通过,建立基线状态

    [INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
    [INFO] 所有现有逻辑测试通过,可以安全修改
    

    AI辅助修改实施:

    向AI提供需求:”将平台C用户也纳入延迟回复服务范围”

    AI分析代码后给出修改方案:

    // 修改后的代码
    private boolean needSkip(ChatHistoryE chatHistoryE) {
        UserDTO UserDTO = UserHelper.parseUser(chatHistoryE.getUserId());
        return MessageSendDirectionEnum.CLIENT_SEND.value != chatHistoryE.getMessageStatus()
                   || MessageShieldEnum.RECEIVER_SHIELD.value == chatHistoryE.getShield()
                   || UserDTO == null
                   || !UserType.isAorBorCLoginUser(UserDTO.getUserType());  // 扩展用户范围
    }
    

    验证阶段的精准反馈:

    修改后运行测试集:

    # 运行结果
    [INFO] Tests run: 15, Failures: 1, Errors: 0, Skipped: 0
    [ERROR] testNeedSkipWithCProviderUser: expected:<true> but was:<false>
    

    结果分析:

    ✅ testNeedSkipWithAUser - 通过(平台A用户逻辑未变)
    ✅ testNeedSkipWithBUser - 通过(平台B用户逻辑未变)
    ❌ testNeedSkipWithCUser - 失败(平台C预期的变更)
    ✅ testNeedSkipWithGuestUser - 通过(游客用户逻辑未变)

    更新期望值:

    @Test
    public void testNeedSkipWithCUser() {
        // 修改后:平台C不应被跳过
        ChatHistoryE chatHistory = buildChatHistory(C_USER_ID);
        assertFalse(strategy.needSkip(chatHistory));  // 更新期望值
    }
    

    最终验证:

    [INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
    [INFO] 所有测试通过,修改安全完成
    

    这种方法将开发者从“担心AI改坏代码”的不信任中解放出来,明确知道哪些功能被影响,哪些保持不变,实现安全、高效的存量代码演进。

    四、策略三:TDD思想驱动AI开发

    4.1 “先生成,后验证”的局限

    前面两节所提到的策略可以归类为”先生成,后验证”,在一定的场景下仍然存在两个问题:

    • 提示词驱动:开发者反复修改自然语言描述,AI产出不确定,返工频繁;
    • 肉眼审查:生成测试用例仍然需要人工验证,一旦用例较多,效率依然低下。

    4.2 TDD模式的革命性转变

    TDD 核心理念:

    • 测试先行:先写测试,再写实现代码。
    • 小步快跑:以微小增量推进开发,每次只解决一个问题。
    • 设计驱动:测试即需求文档,驱动接口设计和代码结构。
    • 安全网:测试集提供即时反馈,支持安全重构。

    整个开发过程严格遵循 Red -> Green -> Refactor 的循环。

    • 🔴 Red: 先编写一个失败的单元测试,用代码来定义我们期望实现的功能。
    • 🟢 Green: 编写最精简的业务代码,让测试恰好通过。
    • 🔵 Refactor: 在测试持续通过的前提下,重构优化代码的设计和质量。

    借助测试驱动开发(TDD)思想,我们先为AI提供一份清晰、无歧义的“需求说明书”和“验收标准”,然后指导它进行代码的生成。这个过程的核心是“🔴 红-🟢 绿-🔵 重构”循环,它将我们的每一次的对话,都转化为一次可验证的、可累加的进步。采用“先验证,后实现”的红-绿-重构循环,将模糊的需求转化为精确的代码语言。

    4.3 案例:优惠券使用规则引擎的复杂逻辑

    业务需求:开发一个智能优惠券使用规则引擎,支持”多券叠加使用和最优组合推荐”

    传统困难

    • 自然语言描述:“实现优惠券规则引擎,支持多种券类型的叠加使用,并智能推荐最优使用方案”
    • AI需要猜测:哪些券可以叠加?什么是“最优”?有哪些使用限制?
    • 反复沟通:多次修改提示词,AI理解仍然偏离业务实际

    第一次尝试:AI理解为“简单累加所有优惠”

    // AI第一次实现 - 过于简化
    public BigDecimal calculateDiscount(Order order, List<Coupon> coupons) {
        return coupons.stream()
            .map(coupon -> coupon.getDiscountAmount())
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    // 问题:忽略了券的使用条件、互斥规则、叠加限制
    

    第二次尝试:AI理解为“选择面额最大的券”

    // AI第二次实现 - 逻辑错误
    public List<Coupon> selectOptimalCoupons(Order order, List<Coupon> availableCoupons) {
        return availableCoupons.stream()
            .filter(coupon -> order.getTotalAmount().compareTo(coupon.getMinOrderAmount()) >= 0)
            .max(Comparator.comparing(Coupon::getDiscountAmount))
            .map(List::of)
            .orElse(Collections.emptyList());
    }
    // 问题:只考虑单券最大优惠,未考虑多券组合的更优效果
    

    第三次尝试:AI尝试复杂逻辑但引入更多问题

    // AI第三次实现 - 逻辑混乱
    public CouponUsageResult applyCoupons(Order order, List<Coupon> coupons) {
        // 各种复杂的if-else嵌套,但缺乏清晰的业务规则
        // 没有处理券的互斥关系
        // 没有考虑计算顺序对最终优惠的影响
        // 边界条件处理不当
    }
    

    经过多轮提示词优化,每次都需要重新解释复杂的业务规则,仍不满足预期。

    TDD方式的完整循环:

    🔴 红色阶段:用测试定义需求

    编写测试用例,精确定义复杂的业务规则:

    @Test
    public void testCouponUsageWithBasicStackingRules() {
        // 构造订单:总价100元,包含数码产品
        Order order = new Order()
            .setTotalAmount(new BigDecimal("100.00"))
            .addItem("数码产品", new BigDecimal("100.00"));
        
        // 构造可用优惠券
        List<Coupon> availableCoupons = Arrays.asList(
            new Coupon().setType("满减券").setCondition("满50减10").setDiscountAmount(new BigDecimal("10")),
            new Coupon().setType("打折券").setCondition("数码类9折").setDiscountRate(new BigDecimal("0.9")),
            new Coupon().setType("免邮券").setCondition("免运费").setDiscountAmount(new BigDecimal("5"))
        );
        
        // 期望结果:满减券和免邮券可叠加,打折券与满减券互斥,应选择最优组合
        CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
        
        // 验证最优方案:使用打折券+免邮券 (90+0=90元,比满减券+免邮券的85元更优)
        assertEquals(2, result.getUsedCoupons().size());
        assertTrue(result.getUsedCoupons().stream().anyMatch(c -> "打折券".equals(c.getType())));
        assertTrue(result.getUsedCoupons().stream().anyMatch(c -> "免邮券".equals(c.getType())));
        assertEquals(new BigDecimal("95.00"), result.getFinalAmount()); // 100*0.9 + 0 - 5运费
    }
    
    @Test  
    public void testCouponMutualExclusionRules() {
        Order order = new Order().setTotalAmount(new BigDecimal("200.00"));
        
        List<Coupon> availableCoupons = Arrays.asList(
            new Coupon().setType("满减券").setCondition("满100减30").setDiscountAmount(new BigDecimal("30")),
            new Coupon().setType("打折券").setCondition("全场8折").setDiscountRate(new BigDecimal("0.8")),
            new Coupon().setType("新用户专享").setCondition("首单5折").setDiscountRate(new BigDecimal("0.5"))
        );
        
        CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
        
        // 验证互斥规则:新用户券与其他券互斥,且优惠最大,应该单独使用
        assertEquals(1, result.getUsedCoupons().size());
        assertEquals("新用户专享", result.getUsedCoupons().get(0).getType());
        assertEquals(new BigDecimal("100.00"), result.getFinalAmount()); // 200 * 0.5
    }
    
    @Test
    public void testCouponUsageConditionValidation() {
        Order order = new Order()
            .setTotalAmount(new BigDecimal("30.00"))
            .setUserLevel("普通用户")
            .addItem("服装", new BigDecimal("30.00"));
        
        List<Coupon> availableCoupons = Arrays.asList(
            new Coupon().setCondition("满50减10"), // 不满足金额条件
            new Coupon().setCondition("VIP专享9折"), // 不满足用户等级条件  
            new Coupon().setCondition("数码类8折"), // 不满足品类条件
            new Coupon().setCondition("无门槛5元券").setDiscountAmount(new BigDecimal("5")) // 满足条件
        );
        
        CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
        
        // 验证条件判断:只有无门槛券可用
        assertEquals(1, result.getUsedCoupons().size());
        assertEquals("无门槛5元券", result.getUsedCoupons().get(0).getCondition());
        assertEquals(new BigDecimal("25.00"), result.getFinalAmount());
    }
    

    运行测试:

    [ERROR] testCouponUsageWithBasicStackingRules: 
    Class CouponEngine doesn't exist
    [ERROR] testCouponMutualExclusionRules:
    Method calculateOptimalUsage not found
    

    红色阶段成功:测试失败,但复杂的业务规则已经通过代码精确表达。

    🟢 绿色阶段:AI精确实现

    将失败的测试用例提供给AI:“请实现CouponEngine.calculateOptimalUsage方法,让这些测试通过”

    AI分析测试用例后,精确理解了复杂的业务规则:

    1. 券类型包括满减券、打折券、免邮券、新用户券等
    2. 不同券有不同的叠加和互斥规则
    3. 需要验证使用条件(金额、用户等级、商品类别)
    4. 要计算最优的券使用组合

    AI生成的实现方案:

    public class CouponEngine {
        public static CouponUsageResult calculateOptimalUsage(Order order, List<Coupon> availableCoupons) {
            // 1. 过滤出满足使用条件的券
            List<Coupon> eligibleCoupons = availableCoupons.stream()
                .filter(coupon -> isEligible(order, coupon))
                .collect(Collectors.toList());
            
            // 2. 生成所有可能的券组合(考虑互斥规则)
            List<List<Coupon>> validCombinations = generateValidCombinations(eligibleCoupons);
            
            // 3. 计算每种组合的最终优惠,选择最优方案
            return validCombinations.stream()
                .map(combination -> calculateResult(order, combination))
                .min(Comparator.comparing(CouponUsageResult::getFinalAmount))
                .orElse(new CouponUsageResult(order.getTotalAmount(), Collections.emptyList()));
        }
        
        private static boolean isEligible(Order order, Coupon coupon) {
            String condition = coupon.getCondition();
            
            // 金额条件检查
            if (condition.contains("满") && condition.contains("减")) {
                BigDecimal minAmount = extractMinAmount(condition);
                if (order.getTotalAmount().compareTo(minAmount) < 0) return false;
            }
            
            // 用户等级检查
            if (condition.contains("VIP") && !"VIP用户".equals(order.getUserLevel())) {
                return false;
            }
            
            // 商品类别检查
            if (condition.contains("数码类") && !order.hasCategory("数码产品")) {
                return false;
            }
            
            return true;
        }
        
        private static List<List<Coupon>> generateValidCombinations(List<Coupon> coupons) {
            List<List<Coupon>> combinations = new ArrayList<>();
            
            // 生成所有子集组合
            for (int i = 0; i < Math.pow(2, coupons.size()); i++) {
                List<Coupon> combination = new ArrayList<>();
                for (int j = 0; j < coupons.size(); j++) {
                    if ((i & (1 << j)) != 0) {
                        combination.add(coupons.get(j));
                    }
                }
                
                // 检查组合是否符合互斥规则
                if (isValidCombination(combination)) {
                    combinations.add(combination);
                }
            }
            
            return combinations;
        }
        
        private static boolean isValidCombination(List<Coupon> combination) {
            // 检查互斥规则
            boolean hasDiscountCoupon = combination.stream().anyMatch(c -> "打折券".equals(c.getType()));
            boolean hasReduceCoupon = combination.stream().anyMatch(c -> "满减券".equals(c.getType()));
            boolean hasNewUserCoupon = combination.stream().anyMatch(c -> "新用户专享".equals(c.getType()));
            
            // 新用户券与其他券互斥
            if (hasNewUserCoupon && combination.size() > 1) {
                return false;
            }
            
            // 打折券与满减券互斥
            if (hasDiscountCoupon && hasReduceCoupon) {
                return false;
            }
            
            return true;
        }
        
        private static CouponUsageResult calculateResult(Order order, List<Coupon> usedCoupons) {
            BigDecimal finalAmount = order.getTotalAmount();
            
            // 按照优先级顺序应用优惠
            for (Coupon coupon : usedCoupons) {
                if ("打折券".equals(coupon.getType())) {
                    finalAmount = finalAmount.multiply(coupon.getDiscountRate());
                } else if ("满减券".equals(coupon.getType()) || "无门槛5元券".equals(coupon.getCondition())) {
                    finalAmount = finalAmount.subtract(coupon.getDiscountAmount());
                } else if ("免邮券".equals(coupon.getType())) {
                    // 免邮券单独处理运费
                    finalAmount = finalAmount.subtract(coupon.getDiscountAmount());
                }
            }
            
            return new CouponUsageResult(finalAmount, usedCoupons);
        }
    }
    

    运行测试:

    [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
    [INFO] All tests passed!
    

    绿色阶段成功:测试通过,复杂的业务逻辑完全正确。

    🔵 重构阶段:优化代码质量

    在测试保护下,对AI生成的代码进行质量优化:

    public class CouponEngine {
        // 提取常量,增强可读性
        private static final Set<String> MUTUALLY_EXCLUSIVE_TYPES = Set.of("打折券", "满减券");
        private static final String NEW_USER_COUPON_TYPE = "新用户专享";
        
        public static CouponUsageResult calculateOptimalUsage(Order order, List<Coupon> availableCoupons) {
            if (CollectionUtils.isEmpty(availableCoupons)) {
                return new CouponUsageResult(order.getTotalAmount(), Collections.emptyList());
            }
            
            // 使用策略模式优化条件验证
            List<Coupon> eligibleCoupons = availableCoupons.stream()
                .filter(coupon -> CouponValidator.isEligible(order, coupon))
                .collect(Collectors.toList());
            
            // 使用组合算法优化券组合生成
            List<List<Coupon>> validCombinations = CouponCombinator.generateValidCombinations(eligibleCoupons);
            
            // 使用计算引擎优化折扣计算
            return validCombinations.stream()
                .map(combination -> DiscountCalculator.calculateResult(order, combination))
                .min(Comparator.comparing(CouponUsageResult::getFinalAmount))
                .orElse(new CouponUsageResult(order.getTotalAmount(), Collections.emptyList()));
        }
    }
    
    // 职责分离:券验证器
    class CouponValidator {
        public static boolean isEligible(Order order, Coupon coupon) {
            return AmountValidator.validate(order, coupon) &&
                   UserLevelValidator.validate(order, coupon) &&
                   CategoryValidator.validate(order, coupon);
        }
    }
    
    // 职责分离:券组合器
    class CouponCombinator {
        public static List<List<Coupon>> generateValidCombinations(List<Coupon> coupons) {
            return PowerSetGenerator.generate(coupons).stream()
                .filter(MutualExclusionChecker::isValidCombination)
                .collect(Collectors.toList());
        }
    }
    
    // 职责分离:折扣计算器
    class DiscountCalculator {
        public static CouponUsageResult calculateResult(Order order, List<Coupon> usedCoupons) {
            // 按优先级排序券,确保计算顺序正确
            List<Coupon> sortedCoupons = usedCoupons.stream()
                .sorted(Comparator.comparing(CouponPriorityResolver::getPriority))
                .collect(Collectors.toList());
            
            BigDecimal finalAmount = order.getTotalAmount();
            
            for (Coupon coupon : sortedCoupons) {
                finalAmount = applyCouponDiscount(finalAmount, coupon);
            }
            
            return new CouponUsageResult(finalAmount, usedCoupons);
        }
        
        private static BigDecimal applyCouponDiscount(BigDecimal currentAmount, Coupon coupon) {
            return CouponTypeHandler.getHandler(coupon.getType())
                .applyDiscount(currentAmount, coupon);
        }
    }
    

    重构验证:

    [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
    [INFO] 重构完成,测试持续通过,代码结构更清晰,职责分离更明确
    

    协作模式转变:开发者不再需要为如何描述复杂的业务规则而烦恼,现在只需专注于设计精确的测试场景——我们负责定义“做什么”和“预期结果”,而AI则负责实现具体的“怎么做”。这种明确的分工让复杂逻辑的开发变得既可控又高效。

    通过这种方式,我们能够确保:

    1. 需求表达精准无歧义
    2. 边界条件全面覆盖
    3. 实现过程完全可控
    4. 重构过程安全可靠

    当需要开发新场景时,只需新增测试用例即可,完全不必担心会破坏原有逻辑。这种开发模式不仅提升了效率,更确保了系统的稳定性和可维护性。

    五、实践要点

    5.1 环境配置

    确保AI Agent能执行mvn test命令

    设定明确的行为准则(Rule),让AI能够知道我们现在遵循的开发范式,防止AI为了通过测试”作弊”修改业务代码。一个借助TDD思想驱动代码生成的执行准则如下

    # AI Agent 行为准则:TDD 测试驱动开发
    
    ## 1. 总则
    
    ### 1.1. 概述
    为了确保 AI Agent 遵循 TDD(测试驱动开发)的开发模式,Agent 必须严格按照 **Red-Green-Refactor** 三个阶段的循环进行开发。在执行每个阶段前,Agent 必须向开发者明确声明其当前所处的阶段。
    
    本准则旨在确保 Agent 遵循正确的 TDD 开发流程,避免跳过关键步骤。
    
    ### 1.2. 环境配置:强制使用指定的 settings.xml
    **核心要求**: 所有对 `mvn@ 命令的调用(如 mvn test@, mvn compile@ 等),都**必须**使用 --settings@ (或 -s@) 参数来指定一个自定义的 settings.xml` 文件,以确保能够访问内部的 Maven 仓库。
    
    - **命令格式示例**: `mvn --settings [settings.xml的绝对路径] test`
    - **`settings.xml` 文件路径**: `[settings.xml的绝对路径]`
    
    Agent 在执行任何 Maven 命令前,必须确认此路径已被正确配置和使用。
    
    ---
    
    ## 2. TDD 三阶段循环
    
    ### 2.1. 第一阶段:RED (写失败的测试)
    
    #### 2.1.1. 目标
    编写一个**必然失败**的测试用例,明确定义即将实现的功能需求。
    
    #### 2.1.2. 核心准则
    - **允许**: Agent 可以在 `src/test/` 目录下创建新的测试文件或添加新的测试方法
    - **要求**:
      - 测试必须是失败的(因为对应的实现代码尚未存在或不完整)
      - 一次只测试一个功能点
      - 测试代码要简单清晰
      - 测试名称要明确表达测试意图
    - **禁止**: Agent **不能**修改 `src/main/` 目录下的任何现有代码
    - **验证**: 运行测试必须显示红色(失败状态)
    
    #### 2.1.3. 交互示例
    - **开发者提示**: "我需要实现一个计算器的加法功能"
    - **Agent 回应**: "已激活 **RED 阶段**。我将先编写一个失败的测试用例来定义加法功能的需求。"
    
    ### 2.2. 第二阶段:GREEN (让测试通过的最简实现)
    
    #### 2.2.1. 目标
    编写**最简单**的实现代码,让当前失败的测试通过。
    
    #### 2.2.2. 核心准则
    - **允许**: Agent 可以创建、修改 `src/main/` 目录下的代码
    - **要求**:
      - 优先考虑最简单的实现方式
      - 专注于满足当前测试用例
      - 快速实现功能让测试通过
    - **禁止**:
      - **不能**修改测试代码
      - **不考虑**代码质量和性能优化
      - **不进行**过度设计
    - **验证**: 运行测试必须显示绿色(通过状态)
    
    #### 2.2.3. 交互示例
    - **Agent 回应**: "已激活 **GREEN 阶段**。我将实现最简单的代码来让刚才的测试通过,不考虑优化和设计。"
    
    ### 2.3. 第三阶段:REFACTOR (重构优化)
    
    #### 2.3.1. 目标
    在保持测试通过的前提下,改进代码的设计、质量和可维护性。
    
    #### 2.3.2. 核心准则
    - **允许**: Agent 可以重构 `src/main/` 目录下的实现代码
    - **要求**:
      - 改进代码设计和质量
      - 消除重复代码
      - 提高代码可读性和可维护性
      - 每次重构后必须运行测试确保通过
    - **禁止**:
      - **不能**修改测试的行为和期望
      - **不能**破坏现有功能
    - **验证**: 重构过程中和完成后,所有测试必须保持绿色
    
    #### 2.3.3. 交互示例
    - **Agent 回应**: "已激活 **REFACTOR 阶段**。我将重构代码以提高质量,同时确保所有测试保持通过状态。"
    
    ---
    
    ## 3. TDD 最佳实践
    
    ### 3.1. 循环节奏
    - **小步快走**: 每个 Red-Green-Refactor 循环应该很短(几分钟到十几分钟)
    - **频繁验证**: 每个阶段完成后都要运行测试验证
    - **逐步推进**: 一次只关注一个小功能点
    
    ### 3.2. 测试质量要求
    - **快速执行**: 单元测试应该在秒级内完成
    - **独立性**: 测试之间不应该有依赖关系
    - **可重复性**: 测试结果应该是确定的和可重复的
    - **清晰命名**: 测试方法名应明确表达测试意图
    
    ### 3.3. 代码质量保证
    - **持续重构**: 在每个循环的 REFACTOR 阶段改进代码
    - **消除重复**: 遵循 DRY(Don't Repeat Yourself)原则
    - **保持简洁**: 代码应该简洁明了,易于理解
    
    ### 3.4. 流程控制
    Agent 在每个阶段转换时,必须:
    1. 明确声明即将进入的阶段
    2. 说明当前阶段的具体目标
    3. 完成阶段后验证结果
    4. 确认是否继续下一个循环
    

    5.2 掌握单测语法

    AI擅长基础用例覆盖,但复杂业务场景、边界条件仍有可能需要开发者手动编写。不要完全依赖AI构造用例。

    5.3 选择合适场景与策略

    快速决策法则:

    • 简单功能:单个方法,逻辑直观,采用“先实现,后验证”;
    • 复杂业务逻辑:多分支判断、算法计算、状态转换,采用TDD“先验证,后实现”;
    • 存量代码修改:采用“安全网保护”策略;
    • 提示词难以描述需求时:测试用例是最好的需求文档,采用TDD让代码直接表达需求。

    5.4 持续维护

    单元测试必须与业务代码演进保持同步。一个过时的、无人维护的测试集,其价值会迅速归零,甚至成为负资产。

    六、结语

    如今,单元测试已被赋予全新的意义——它不再被视为一种“开发负担”,而是进化成为AI Coding时代的“质量引擎”。

    我们构建起三重关键保障:

    • 策略一:以客观检验替代主观判断,让AI代码告别“看起来没问题”的错觉;
    • 策略二:为存量代码筑起防护墙,使修改存量代码安全可控,降低演进风险;
    • 策略三:用测试作为与AI的沟通语言,精准传递复杂需求与预期。

    更深层次的变化在于,我们正在重新定义开发者的核心价值:当我们从“思考提示词”转向“思考测试用例”,本质上是从AI代码被动的审查者,转变为了主动的需求设计者与质量掌控者。这不仅加速开发进程,更显著提升代码质量。这正是AI时代中,开发者与智能工具协同进化的优秀范式。

    二十年,是一个坐标。从 Web 2.0 的萌芽,到移动互联网的爆发,再到云原生时代的重塑,D2 技术大会伴随开发者走过了整整二十载风雨。

    今天,我们站在了一个更加宏大的分水岭。AI 不再是遥远的科幻逻辑,它正以一种近乎“重构”的姿态,系统性地改写终端技术的底层范式:从代码生成的协作,到架构设计的逻辑,再到交互体验的边界。

    第 20 届 D2 技术大会,年度主题定为——「AI 新」。

    它既是我们的时代判断,也是我们的集体宣言。它是 AI 驱动的创新,也是终端人对技术边界追逐的热爱之新

    此刻,我们正式向全球开发者、架构师、技术领袖及创新实践者发出邀请:来 D2,分享你对 AI 时代终端技术的独到见解,共同定义下一个二十年的生产力!


    七大核心专场,期待你的真知灼见

    我们渴望真实工程中的突破,珍视深度思考后的落地,让技术回归解决问题的初衷。

    01 AI Coding:从写代码开始,重构工程本身

    这是本届 D2 的主干专场。AI 正在从“辅助助手”升级为“协作伙伴”。

    征集方向:

    • AI Agent 编程工具的研发与设计

    侧重 Agent 型 AI 编程工具在本地与远程形态下的架构与产品设计。征集议题包括 IDE 深度集成、上下文采集与记忆管理、代码库索引检索、任务规划与工具调用、执行沙箱与权限控制、审计与回放、可观测性、成本/延迟优化与多模型策略等。重点关注可靠性与可控性:减少误改、支持规范化交付与团队协作。

    • AI-Native 开发实践

    聚焦真实项目中 AI 编程的可复用方法。征集包含 Spec 驱动开发(结构化需求/验收标准/契约/测试)、AI 编程 Workflow 探索(从需求到 PR/发布的流水线)、以及团队级 AI 驱动研发实践(流程改造、提示/模板沉淀、质量门禁、效率与质量度量、失败复盘)。重点是“怎么做得稳、做得快”。

    • AI Coding 前沿研究与技术趋势

    关注下一代 AI Coding 的关键技术与趋势。征集议题包括长上下文与复杂依赖、代码语义理解与程序分析结合、自动化评测与基准、对齐与安全、多智能体协作、可靠性与可解释性增强等。重点探讨研究如何走向工程落地与可验证的效果提升。

    02 AI 创新体验:当交互正在被重写

    终端是 AI 被感知的最前线。交互范式的巨变已经发生。

    征集方向:

    • UI 范式重塑

    探讨从 GUI 向 LUI 或 AUI 的代际演进。聚焦 Agent 驱动下的意图识别、动态 UI 生成及个性化界面即时构建。征集议题包括主动交互设计、多 Agent 协作下的用户反馈回路、以及如何利用 AI 简化复杂业务流的操作门槛。

    • 空间智能体验

    聚焦多模态感知与空间计算的深度融合。涵盖视觉、语音、触觉在 3D/XR 环境下的集成交互,以及 AI 驱动的实时场景理解与数据可视化。重点探讨如何利用空间智能让数字世界更符合自然认知,实现高沉浸感的智能反馈。。

    • 具身交互探索

    关注 AI 进入物理世界后的交互挑战,从 AI Wearables、AI PC 到机器人具身智能。探讨硬件约束下的自然语言处理、人机交互(HRI)实践及环境感知反馈。重点关注如何通过端侧智能赋予硬件产品生命力,解决真实场景下的交互痛点,探索用户真正愿意买单的终端新价值点。

    03 AI 语言 & 框架:模型时代,语言与框架如何进化

    当 AI 成为“默认能力”,底层技术如何适配?

    征集方向:

    • 语言与编译器演进

    探讨编程语言如何适配“人机共写”新常态。征集议题涵盖 LLM 友好型语法设计、智能化类型系统、AI 辅助的编译优化与静态分析等。重点研究如何通过语言特性的进化,提升 AI 生成代码的质量、安全性与复杂逻辑表达力。

    • Agent 框架重构

    当 Agent 成为系统编排者,探讨传统框架的抽象层重塑。征集议题涵盖声明式意图驱动的框架设计、元数据驱动的界面自动生成、以及为 AI 重新设计的组件模型。重点关注框架如何提供更高级别的抽象,以支持多 Agent 在复杂业务逻辑中的无缝协作、状态同步与逻辑自治。

    • 智能运行时与内核

    推动 AI 从工具层下沉为系统的核心能力。聚焦内置 AI 推理能力的运行时引擎、模型与容器/内核的深度集成,以及 AI 驱动的动态资源调度策略。重点探讨端云协同背景下,如何模糊开发与运行、模型与逻辑的边界,实现具备自适应、自进化能力的智能运行基座。

    04 AI 智能测试:质量与效率,不再只能二选一

    测试不再是滞后的环节,而是 AI 介入最深、收益最显性的战场。

    征集方向:

    • 用例生成与自愈

    探讨利用 LLM 实现测试全生命周期的自动化。征集议题包括基于语义理解的单元/集成测试生成、复杂业务场景下的测试数据合成,以及 UI 自动化脚本的自愈(Self-healing)机制。

    • 风险洞察与优化

    聚焦利用 AI 提升质量保障的精准度与效率。征集议题涵盖基于变更分析的智能回归测试缩减、线上异常的实时检测与根因定位,以及多维度的质量风险预测模型。探讨如何利用算法在海量代码变更中快速锁定高风险区域,解决快速迭代与质量稳定性之间的核心矛盾。

    • 治理与角色演进

    关注 AI 引入后测试流程与组织效能的系统性重构。核心议题包括 AI 测试工具的 ROI 分析、人机协同模式下的 QA 职责重定义,以及在规模化工程中构建“默认内置 AI”的质量防线。探讨如何通过技术赋能,打破质量与效率的零和博弈,重塑技术团队的质量文化与评价体系。

    05 AI 智能生产:从工具走向生产系统

    关注 AI 在真实业务落地时的“最后一公里”。

    征集方向:

    • 业务深度嵌入

    探讨 AI 如何从外部辅助工具进化为业务逻辑的核心。寻找在复杂业务场景中的落地架构案例,关注如何处理模型输出的不确定性以交付“确定性”结果。重点探讨 AI 对传统业务流程的深度重构,在提升用户价值的同时,确保生产系统的稳定性、安全性与商业收益。

    • 规模化生产交付

    聚焦 AI 从原型验证(PoC)走向规模化交付的工程拐点。征集议题涵盖支持大规模 AI 应用的工程底座、端到端 AI 生产平台的演进、以及 FinOps 成本分析与合规治理。探讨如何构建标准化的平台能力,支撑 AI 跨团队、跨业务的高效迁移与持续稳定运行,实现技术普惠。

    • 全链路协同提效

    关注覆盖需求、设计、交付及运维的 AI 全链路闭环。核心议题包括新一代人机协作下的流程重塑、领域专用 Agent 的生产环境编排,以及科学的效能度量方法。探讨如何通过技术与组织的双重演进,实现软件生产体系的跨越式提效,将 AI 潜能真正转化为规模化的实际业务产能。

    06 终端技术:重构 AI 时代的性能底座

    底层基础设施如何承载高算力与高响应需求?

    征集方向:

    • 架构适配与演进

    探讨终端架构如何重构以深度兼容 AI 能力,重点研究如何调整传统的软件拓扑结构,以支持 AI 在终端侧的无缝集成、高效编排与复杂的应用状态管理,提升端侧智能的响应实时性。

    • 运行时与性能优化

    聚焦通过底层技术突破 AI 运行的性能瓶颈。征集议题涵盖面向 AI 指令集优化的编译器技术、异构算力的极致加速实践,以及轻量化端侧容器演进。探讨如何通过运行时与系统内核的深度协同,在有限的硬件资源限制下,实现极致的推理速度与能效比。

    • 端侧工程与协同

    核心议题包括模型量化、蒸馏与剪枝的终端实战、端云协同推理架构,以及隐私安全约束下的端侧学习。探讨如何构建高效的端云配比方案,在保障响应速度与数据隐私的同时,实现计算成本与用户体验的帕累托最优。

    07 一人公司:技术人的个体放大器

    这是最具时代情绪的专场。AI 正在让“超级个体”成为可能。

    征集方向:

    • 全栈生产力飞跃

    探讨 AI 如何打破专业壁垒,实现“一个人就是一支团队”。分享利用 AI 协同完成从需求定义、全栈开发、交互设计到市场增长的全链路实践。

    • 商业闭环与实战

    聚焦超级个体的商业化落地与可持续经营之道。征集独立开发者的 AI 实战案例,涵盖极致成本控制下的产品生存策略、AI 辅助的商业决策与自动化运营。探讨在 AI 时代,个体如何构建轻量化、高利润的商业模式,并成功应对从单兵作战到规模化营收的真实挑战。

    • 职业路径重构

    探讨从“专项开发者”向“产品主理人”转型的思维重构、AI 时代的个人品牌经营,以及个体长期竞争力的构建。研究在组织边界日益模糊的未来,技术人如何利用 AI 工具集寻找更具自主性的创作路径,定义下一代极简且高效的职业范式。


    顶尖出品人矩阵:为议题深度护航

    本届 D2 各专场由行业资深专家领衔,他们不仅是评审者,更是议题的“合伙人”。

    我们寻找的不仅是一个演讲者

    更是一个在 AI 工程深水区挣扎过、思考过、最终破局的见证者

    • 隐风| 淘天集团-用户 &内容终端技术负责人

    • 云谦| 蚂蚁集团-高级前端技术专家

    • 悟石| 淘宝闪购-消费者端技术负责人

    • 渚薰| 前淘宝互动游戏专家

    • 偏右| 蚂蚁集团-支付宝体验技术前端平台负责人

    • 张磊| 字节跳动 Web Infra 技术负责人

    • 泠乐| 淘天集团-淘宝终端质量负责人

    • 茹炳晟| CCF TF 研发效能 SIG 主席 / 复旦大学 CodeWisdom 成员

    • 达峰| 蚂蚁集团-平台体验技术部负责人

    • 穆宸| AliExpress-终端技术负责人 / D2 负责人

    • 永霸| 淘天集团-交易终端技术负责人

    • 崔红保| DCloud CTO / uni-app 跨平台框架负责人

    • 秦粤| 阿里云-数据库高级前端专家

    • 梓骞 | 启智云图 CEO / Lovrabet 产品创始人

    出品人寄语:“在 D2,我们致力于将前沿的 AI 实践提炼为系统化的技术范式。我们期待与你一同锚定 AI 时代的工程坐标,让每一份实战洞察都汇聚成定义未来的行业基准。”


    🌟 为什么来到 D2 舞台

    1. 顶尖技术影响力:D2 是国内终端技术的风向标,线下规模 2000+,线上覆盖数十万专业开发者。

    2. 二十周年里程碑:参与第 20 届这一极具纪念意义的盛会,与业内最具创新精神的技术人同频共振。

    3. 常态化社区联动:优质内容将同步至稀土掘金、InfoQ、AI 产品榜等联合承办方平台,获得持续的行业曝光与认可。

    🗓️ 议题提交指南

    • 截止时间: 2026 年 1 月 23 日(请关注官网最新动态)

    • 议题要求:内容具有前瞻性、实战性或深度思考;拒绝纯广告,强调技术细节与真实的踩坑经验

    图片

    扫码提交议题

    二十年是一个里程碑,更是重新出发的起点。在「AI 新」的浪潮中,让我们一起,用 AI 驱动创新,用终端之心热爱创新。


    *本文由极客时间企业版代发

    二十年,是一个坐标。从 Web 2.0 的萌芽,到移动互联网的爆发,再到云原生时代的重塑,D2 技术大会伴随开发者走过了整整二十载风雨。

    今天,我们站在了一个更加宏大的分水岭。AI 不再是遥远的科幻逻辑,它正以一种近乎“重构”的姿态,系统性地改写终端技术的底层范式:从代码生成的协作,到架构设计的逻辑,再到交互体验的边界。

    第 20 届 D2 技术大会,年度主题定为——「AI 新」。

    它既是我们的时代判断,也是我们的集体宣言。它是 AI 驱动的创新,也是终端人对技术边界追逐的热爱之新

    此刻,我们正式向全球开发者、架构师、技术领袖及创新实践者发出邀请:来 D2,分享你对 AI 时代终端技术的独到见解,共同定义下一个二十年的生产力!


    七大核心专场,期待你的真知灼见

    我们渴望真实工程中的突破,珍视深度思考后的落地,让技术回归解决问题的初衷。

    01 AI Coding:从写代码开始,重构工程本身

    这是本届 D2 的主干专场。AI 正在从“辅助助手”升级为“协作伙伴”。

    征集方向:

    • AI Agent 编程工具的研发与设计

    侧重 Agent 型 AI 编程工具在本地与远程形态下的架构与产品设计。征集议题包括 IDE 深度集成、上下文采集与记忆管理、代码库索引检索、任务规划与工具调用、执行沙箱与权限控制、审计与回放、可观测性、成本/延迟优化与多模型策略等。重点关注可靠性与可控性:减少误改、支持规范化交付与团队协作。

    • AI-Native 开发实践

    聚焦真实项目中 AI 编程的可复用方法。征集包含 Spec 驱动开发(结构化需求/验收标准/契约/测试)、AI 编程 Workflow 探索(从需求到 PR/发布的流水线)、以及团队级 AI 驱动研发实践(流程改造、提示/模板沉淀、质量门禁、效率与质量度量、失败复盘)。重点是“怎么做得稳、做得快”。

    • AI Coding 前沿研究与技术趋势

    关注下一代 AI Coding 的关键技术与趋势。征集议题包括长上下文与复杂依赖、代码语义理解与程序分析结合、自动化评测与基准、对齐与安全、多智能体协作、可靠性与可解释性增强等。重点探讨研究如何走向工程落地与可验证的效果提升。

    02 AI 创新体验:当交互正在被重写

    终端是 AI 被感知的最前线。交互范式的巨变已经发生。

    征集方向:

    • UI 范式重塑

    探讨从 GUI 向 LUI 或 AUI 的代际演进。聚焦 Agent 驱动下的意图识别、动态 UI 生成及个性化界面即时构建。征集议题包括主动交互设计、多 Agent 协作下的用户反馈回路、以及如何利用 AI 简化复杂业务流的操作门槛。

    • 空间智能体验

    聚焦多模态感知与空间计算的深度融合。涵盖视觉、语音、触觉在 3D/XR 环境下的集成交互,以及 AI 驱动的实时场景理解与数据可视化。重点探讨如何利用空间智能让数字世界更符合自然认知,实现高沉浸感的智能反馈。。

    • 具身交互探索

    关注 AI 进入物理世界后的交互挑战,从 AI Wearables、AI PC 到机器人具身智能。探讨硬件约束下的自然语言处理、人机交互(HRI)实践及环境感知反馈。重点关注如何通过端侧智能赋予硬件产品生命力,解决真实场景下的交互痛点,探索用户真正愿意买单的终端新价值点。

    03 AI 语言 & 框架:模型时代,语言与框架如何进化

    当 AI 成为“默认能力”,底层技术如何适配?

    征集方向:

    • 语言与编译器演进

    探讨编程语言如何适配“人机共写”新常态。征集议题涵盖 LLM 友好型语法设计、智能化类型系统、AI 辅助的编译优化与静态分析等。重点研究如何通过语言特性的进化,提升 AI 生成代码的质量、安全性与复杂逻辑表达力。

    • Agent 框架重构

    当 Agent 成为系统编排者,探讨传统框架的抽象层重塑。征集议题涵盖声明式意图驱动的框架设计、元数据驱动的界面自动生成、以及为 AI 重新设计的组件模型。重点关注框架如何提供更高级别的抽象,以支持多 Agent 在复杂业务逻辑中的无缝协作、状态同步与逻辑自治。

    • 智能运行时与内核

    推动 AI 从工具层下沉为系统的核心能力。聚焦内置 AI 推理能力的运行时引擎、模型与容器/内核的深度集成,以及 AI 驱动的动态资源调度策略。重点探讨端云协同背景下,如何模糊开发与运行、模型与逻辑的边界,实现具备自适应、自进化能力的智能运行基座。

    04 AI 智能测试:质量与效率,不再只能二选一

    测试不再是滞后的环节,而是 AI 介入最深、收益最显性的战场。

    征集方向:

    • 用例生成与自愈

    探讨利用 LLM 实现测试全生命周期的自动化。征集议题包括基于语义理解的单元/集成测试生成、复杂业务场景下的测试数据合成,以及 UI 自动化脚本的自愈(Self-healing)机制。

    • 风险洞察与优化

    聚焦利用 AI 提升质量保障的精准度与效率。征集议题涵盖基于变更分析的智能回归测试缩减、线上异常的实时检测与根因定位,以及多维度的质量风险预测模型。探讨如何利用算法在海量代码变更中快速锁定高风险区域,解决快速迭代与质量稳定性之间的核心矛盾。

    • 治理与角色演进

    关注 AI 引入后测试流程与组织效能的系统性重构。核心议题包括 AI 测试工具的 ROI 分析、人机协同模式下的 QA 职责重定义,以及在规模化工程中构建“默认内置 AI”的质量防线。探讨如何通过技术赋能,打破质量与效率的零和博弈,重塑技术团队的质量文化与评价体系。

    05 AI 智能生产:从工具走向生产系统

    关注 AI 在真实业务落地时的“最后一公里”。

    征集方向:

    • 业务深度嵌入

    探讨 AI 如何从外部辅助工具进化为业务逻辑的核心。寻找在复杂业务场景中的落地架构案例,关注如何处理模型输出的不确定性以交付“确定性”结果。重点探讨 AI 对传统业务流程的深度重构,在提升用户价值的同时,确保生产系统的稳定性、安全性与商业收益。

    • 规模化生产交付

    聚焦 AI 从原型验证(PoC)走向规模化交付的工程拐点。征集议题涵盖支持大规模 AI 应用的工程底座、端到端 AI 生产平台的演进、以及 FinOps 成本分析与合规治理。探讨如何构建标准化的平台能力,支撑 AI 跨团队、跨业务的高效迁移与持续稳定运行,实现技术普惠。

    • 全链路协同提效

    关注覆盖需求、设计、交付及运维的 AI 全链路闭环。核心议题包括新一代人机协作下的流程重塑、领域专用 Agent 的生产环境编排,以及科学的效能度量方法。探讨如何通过技术与组织的双重演进,实现软件生产体系的跨越式提效,将 AI 潜能真正转化为规模化的实际业务产能。

    06 终端技术:重构 AI 时代的性能底座

    底层基础设施如何承载高算力与高响应需求?

    征集方向:

    • 架构适配与演进

    探讨终端架构如何重构以深度兼容 AI 能力,重点研究如何调整传统的软件拓扑结构,以支持 AI 在终端侧的无缝集成、高效编排与复杂的应用状态管理,提升端侧智能的响应实时性。

    • 运行时与性能优化

    聚焦通过底层技术突破 AI 运行的性能瓶颈。征集议题涵盖面向 AI 指令集优化的编译器技术、异构算力的极致加速实践,以及轻量化端侧容器演进。探讨如何通过运行时与系统内核的深度协同,在有限的硬件资源限制下,实现极致的推理速度与能效比。

    • 端侧工程与协同

    核心议题包括模型量化、蒸馏与剪枝的终端实战、端云协同推理架构,以及隐私安全约束下的端侧学习。探讨如何构建高效的端云配比方案,在保障响应速度与数据隐私的同时,实现计算成本与用户体验的帕累托最优。

    07 一人公司:技术人的个体放大器

    这是最具时代情绪的专场。AI 正在让“超级个体”成为可能。

    征集方向:

    • 全栈生产力飞跃

    探讨 AI 如何打破专业壁垒,实现“一个人就是一支团队”。分享利用 AI 协同完成从需求定义、全栈开发、交互设计到市场增长的全链路实践。

    • 商业闭环与实战

    聚焦超级个体的商业化落地与可持续经营之道。征集独立开发者的 AI 实战案例,涵盖极致成本控制下的产品生存策略、AI 辅助的商业决策与自动化运营。探讨在 AI 时代,个体如何构建轻量化、高利润的商业模式,并成功应对从单兵作战到规模化营收的真实挑战。

    • 职业路径重构

    探讨从“专项开发者”向“产品主理人”转型的思维重构、AI 时代的个人品牌经营,以及个体长期竞争力的构建。研究在组织边界日益模糊的未来,技术人如何利用 AI 工具集寻找更具自主性的创作路径,定义下一代极简且高效的职业范式。


    顶尖出品人矩阵:为议题深度护航

    本届 D2 各专场由行业资深专家领衔,他们不仅是评审者,更是议题的“合伙人”。

    我们寻找的不仅是一个演讲者

    更是一个在 AI 工程深水区挣扎过、思考过、最终破局的见证者

    • 隐风| 淘天集团-用户 &内容终端技术负责人

    • 云谦| 蚂蚁集团-高级前端技术专家

    • 悟石| 淘宝闪购-消费者端技术负责人

    • 渚薰| 前淘宝互动游戏专家

    • 偏右| 蚂蚁集团-支付宝体验技术前端平台负责人

    • 张磊| 字节跳动 Web Infra 技术负责人

    • 泠乐| 淘天集团-淘宝终端质量负责人

    • 茹炳晟| CCF TF 研发效能 SIG 主席 / 复旦大学 CodeWisdom 成员

    • 达峰| 蚂蚁集团-平台体验技术部负责人

    • 穆宸| AliExpress-终端技术负责人 / D2 负责人

    • 永霸| 淘天集团-交易终端技术负责人

    • 崔红保| DCloud CTO / uni-app 跨平台框架负责人

    • 秦粤| 阿里云-数据库高级前端专家

    • 梓骞 | 启智云图 CEO / Lovrabet 产品创始人

    出品人寄语:“在 D2,我们致力于将前沿的 AI 实践提炼为系统化的技术范式。我们期待与你一同锚定 AI 时代的工程坐标,让每一份实战洞察都汇聚成定义未来的行业基准。”


    🌟 为什么来到 D2 舞台

    1. 顶尖技术影响力:D2 是国内终端技术的风向标,线下规模 2000+,线上覆盖数十万专业开发者。

    2. 二十周年里程碑:参与第 20 届这一极具纪念意义的盛会,与业内最具创新精神的技术人同频共振。

    3. 常态化社区联动:优质内容将同步至稀土掘金、InfoQ、AI 产品榜等联合承办方平台,获得持续的行业曝光与认可。

    🗓️ 议题提交指南

    • 截止时间: 2026 年 1 月 23 日(请关注官网最新动态)

    • 议题要求:内容具有前瞻性、实战性或深度思考;拒绝纯广告,强调技术细节与真实的踩坑经验

    图片

    扫码提交议题

    二十年是一个里程碑,更是重新出发的起点。在「AI 新」的浪潮中,让我们一起,用 AI 驱动创新,用终端之心热爱创新。


    *本文由极客时间企业版代发

    AI生成代码质量难以把控!本文分享来自美团的技术实践,三大策略破解AI编程痛点。单测快速验证逻辑正确性,安全网保护存量代码演进,TDD模式精准传递需求。告别「看起来没问题」的错觉,构建AI时代的代码质量保障体系。

    一、引言

    目前,国内外很多AI Coding助手能在几秒钟内生成完整代码块,大大提升了开发效率,但这种高速开发模式也带来了潜在风险——与人工编码不同是,AI Coding助手生成代码存在两个特殊风险:其一,AI Coding助手依赖于上下文与模型自身的能力,输出的代码质量相对不可控。其二,AI生成的代码虽然逻辑通顺、结构完整,但可能隐藏着难以察觉的边界问题或逻辑缺陷。

    核心问题:我们如何快速的验证AI生成代码的质量和可靠性?

    本文旨在分享如何借助单元测试,让AI编程合作更高效可靠,主要解决三个常见痛点:

    1. 肉眼审查困境:AI一次性生成大量代码时,难以快速准确判断逻辑完备性;
    2. 存量代码信任危机:如何验证AI修改老代码时,不会产生非预期的结果;
    3. 需求传达难题:如何精准向AI表达复杂需求并快速验证。

    针对上述三个常见痛点,本文提出采用不同的单元测试策略来应对以上问题。每个策略都针对一个特定痛点设计:策略一通过测试解决肉眼审查的局限性;策略二构建单测安全网应对存量代码的信任问题;策略三则采用TDD模式优化需求传达与验证流程。下文将依次展开说明,希望能对大家有所帮助或启发。

    二、策略一:单测检验AI代码逻辑正确性

    2.1 问题背景

    传统的人工代码审查在AI生成的大量代码面前显得低效且不可靠。在软件测试实践中,有着测试左移(Shift Left Testing)的概念,本质上是借助工具和测试手段更早地发现问题和预防问题。在AI Coding时代,这一理念尤为关键:跳过单元测试直接集成测试看似”抄近路”,实则是将风险后置——开发阶段几分钟能发现的Bug,在集成测试环境可能需要较长定位修复,这中间包含了代码部署、环境准备、测试条件的准备、问题定位、开发人员修复、再次部署验证等一系列漫长的环节。

    相比之下,单元测试具有独特的优势:它能够独立运行、快速验证结果,并且可以无限次重复执行。这种测试方式就像是为项目进行的一次性投资,却能为整个开发周期构建起一张可靠的“安全网”。它不仅能实时验证AI Coding生成的代码是否正确,更能持续保障未来代码的质量稳定性,让开发团队始终对代码库保持信心。

    2.2 案例:分页查询接口的隐蔽Bug

    任务背景:实现一个支持多条件筛选的复杂分页查询接口pageQueryRobot

    AI生成了如下核心查询逻辑:

    public List<AgentRobotE> pageQueryRobotsByCondition(List<Long> shopIds, String chatSceneCode,
            Boolean enabled, Integer pageNo, Integer pageSize) {
        // ... 前置校验代码 ...
    
        // 分页查询机器人基础信息
        int offset = (pageNo - 1) * pageSize;
        List<AgentRobotEntity> entities = robotIds.stream()
                .skip(offset)
                .limit(pageSize)
                .map(robotId -> agentRobotDAO.getRobotById(robotId, false))
                .filter(Objects::nonNull)
                // 问题代码:类型不匹配的隐蔽Bug
                .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled ? 1 : 0))
                .filter(entity -> Objects.equals(entity.getChatSceneCode(), chatSceneCode))
                .collect(Collectors.toList());
    
        return entities.stream()
                .map(this::convertToModel)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    

    问题分析:这段代码看起来逻辑完整,但第8行的过滤逻辑包含了多个复杂元素:

    • 三元运算符 enabled ? 1 : 0
    • Objects.equals 的使用
    • Boolean到Integer的隐式逻辑转换

    仅凭肉眼很难发现其中的类型不匹配问题。

    单元测试发现问题:通过AI编写了17个全面的单元测试用例,覆盖:

    • 正常场景:各种有效参数组合
    • 边界场景:null值、空集合处理
    • 参数组合:enabled为true/false/null的不同情况
    @Test
    public void testPageQueryWhenEnabledIsTrue() {
        // arrange
        List<Long> shopIds = Arrays.asList(12345L, 67890L);
        String chatSceneCode = "SCENE_C";
        Boolean enabled = true;  // 测试enabled为true的情况
    
        // 模拟数据库返回的实体,enabled字段为Boolean类型
        AgentRobotEntity mockEntity = new AgentRobotEntity();
        mockEntity.setEnabled(true);  // 注意:这里是Boolean类型
        mockEntity.setChatSceneCode("SCENE_C");
    
        when(agentRobotDAO.getRobotById(anyLong(), eq(false))).thenReturn(mockEntity);
    
        // act
        List<AgentRobotE> result = repository.pageQueryRobotsByCondition(
            shopIds, chatSceneCode, enabled, 1, 10);
    
        // assert - 这个测试失败了!
        assertEquals(1, result.size());  // 期望返回1个结果,实际返回0个
    }
    

    测试运行结果:当enabled为true时测试失败!

    问题定位:通过测试失败,快速定位到过滤逻辑的问题:

    // 错误的逻辑:entity.getEnabled()返回Boolean类型,但与Integer比较
    Objects.equals(entity.getEnabled(), enabled ? 1 : 0)
    // 当enabled=true时,比较的是 Objects.equals(Boolean.TRUE, 1) -> false
    // 当enabled=false时,比较的是 Objects.equals(Boolean.TRUE, 0) -> false
    

    正确修复:

    // 修复后:直接比较Boolean类型
    .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled))
    

    意外收获:在审查测试覆盖的代码时,还发现了N+1查询的性能问题:

    // 存在性能问题的代码
    .map(robotId -> agentRobotDAO.getRobotById(robotId, false))  // 每个robotId单独查询
    

    成果验证:修复后,所有17个单元测试用例全部通过,代码质量得到保障。

    三、策略二:构建安全网保护存量代码

    3.1 问题场景

    AI对存量代码的修改挑战更大。AI看到的可能只是函数或类的局部,无法理解背后的业务规则和历史包袱。如何放心的让AI修改已有的代码?

    在进行AI Coding前,需要确保旧有逻辑,处于单元测试的完全覆盖保护中,这就像在开启汽车的“自动辅助驾驶”功能前,必须先系好安全带一样。这条“安全带”就是我们完善的、可运行的单元测试集。

    • 快速验证,精准反馈:AI生成修改后的代码无需人工逐行对比,只需运行单元测试即可获得即时反馈。测试失败的用例直接揭示AI修改中存在的问题——要么触及了不应改动的逻辑,要么未能正确实现预期变更。这种反馈机制既高效又客观。
    • 清晰界定修改边界:单元测试结果帮助我们明确判断——AI的修改是否精准实现了目标?在引入新功能的同时是否完整保留了原有逻辑?通过区分预期内的失败(主动修改旧逻辑)和意外失败(破坏现有功能),我们获得了优化AI方案的明确方向,大幅提升了迭代效率。

    3.2 案例:延迟回复策略的用户范围扩展

    业务背景:需要将消息延迟回复服务从原来的平台A、平台B的用户扩展到平台C用户。

    原始代码分析:

    // TextDelayReplyStrategy.java 中的核心逻辑
    private boolean needSkip(ChatHistoryE chatHistoryE) {
        UserDTO UserDTO = UserHelper.parseUser(chatHistoryE.getUserId());
        return MessageSendDirectionEnum.CLIENT_SEND.value != chatHistoryE.getMessageStatus()
                   || MessageShieldEnum.RECEIVER_SHIELD.value == chatHistoryE.getShield()
                   || UserDTO == null
                   || !UserType.isLoginUser(UserDTO.getUserType());  // 关键判断逻辑
    }
    

    这个needSkip方法决定了哪些用户类型需要跳过延迟回复处理。原逻辑中,UserType.isLoginUser()只覆盖平台A、平台B的登录用户,不包括平台C用户。

    修改前的安全网构建:

    按照“分析-测试-实施-验证”方法论,首先完善单元测试:

    // 针对现有逻辑的保护性测试
    @Test
    public void testNeedSkipWithAUser() {
        // 平台A用户不应被跳过
        ChatHistoryE chatHistory = buildChatHistory(A_USER_ID);
        assertFalse(strategy.needSkip(chatHistory));
    }
    
    @Test
    public void testNeedSkipWithBUser() {
        // 平台B用户不应被跳过
        ChatHistoryE chatHistory = buildChatHistory(B_USER_ID);
        assertFalse(strategy.needSkip(chatHistory));
    }
    
    @Test
    public void testNeedSkipWithCUser() {
        // 平台C在修改前应被跳过
        ChatHistoryE chatHistory = buildChatHistory(C_USER_ID);
        assertTrue(strategy.needSkip(chatHistory));  // 修改前的预期行为
    }
    
    @Test
    public void testNeedSkipWithGuestUser() {
        // 游客用户应被跳过
        ChatHistoryE chatHistory = buildChatHistory(GUEST_USER_ID);
        assertTrue(strategy.needSkip(chatHistory));
    }
    

    运行基线测试:确保所有测试通过,建立基线状态

    [INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
    [INFO] 所有现有逻辑测试通过,可以安全修改
    

    AI辅助修改实施:

    向AI提供需求:”将平台C用户也纳入延迟回复服务范围”

    AI分析代码后给出修改方案:

    // 修改后的代码
    private boolean needSkip(ChatHistoryE chatHistoryE) {
        UserDTO UserDTO = UserHelper.parseUser(chatHistoryE.getUserId());
        return MessageSendDirectionEnum.CLIENT_SEND.value != chatHistoryE.getMessageStatus()
                   || MessageShieldEnum.RECEIVER_SHIELD.value == chatHistoryE.getShield()
                   || UserDTO == null
                   || !UserType.isAorBorCLoginUser(UserDTO.getUserType());  // 扩展用户范围
    }
    

    验证阶段的精准反馈:

    修改后运行测试集:

    # 运行结果
    [INFO] Tests run: 15, Failures: 1, Errors: 0, Skipped: 0
    [ERROR] testNeedSkipWithCProviderUser: expected:<true> but was:<false>
    

    结果分析:

    ✅ testNeedSkipWithAUser - 通过(平台A用户逻辑未变)
    ✅ testNeedSkipWithBUser - 通过(平台B用户逻辑未变)
    ❌ testNeedSkipWithCUser - 失败(平台C预期的变更)
    ✅ testNeedSkipWithGuestUser - 通过(游客用户逻辑未变)

    更新期望值:

    @Test
    public void testNeedSkipWithCUser() {
        // 修改后:平台C不应被跳过
        ChatHistoryE chatHistory = buildChatHistory(C_USER_ID);
        assertFalse(strategy.needSkip(chatHistory));  // 更新期望值
    }
    

    最终验证:

    [INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
    [INFO] 所有测试通过,修改安全完成
    

    这种方法将开发者从“担心AI改坏代码”的不信任中解放出来,明确知道哪些功能被影响,哪些保持不变,实现安全、高效的存量代码演进。

    四、策略三:TDD思想驱动AI开发

    4.1 “先生成,后验证”的局限

    前面两节所提到的策略可以归类为”先生成,后验证”,在一定的场景下仍然存在两个问题:

    • 提示词驱动:开发者反复修改自然语言描述,AI产出不确定,返工频繁;
    • 肉眼审查:生成测试用例仍然需要人工验证,一旦用例较多,效率依然低下。

    4.2 TDD模式的革命性转变

    TDD 核心理念:

    • 测试先行:先写测试,再写实现代码。
    • 小步快跑:以微小增量推进开发,每次只解决一个问题。
    • 设计驱动:测试即需求文档,驱动接口设计和代码结构。
    • 安全网:测试集提供即时反馈,支持安全重构。

    整个开发过程严格遵循 Red -> Green -> Refactor 的循环。

    • 🔴 Red: 先编写一个失败的单元测试,用代码来定义我们期望实现的功能。
    • 🟢 Green: 编写最精简的业务代码,让测试恰好通过。
    • 🔵 Refactor: 在测试持续通过的前提下,重构优化代码的设计和质量。

    借助测试驱动开发(TDD)思想,我们先为AI提供一份清晰、无歧义的“需求说明书”和“验收标准”,然后指导它进行代码的生成。这个过程的核心是“🔴 红-🟢 绿-🔵 重构”循环,它将我们的每一次的对话,都转化为一次可验证的、可累加的进步。采用“先验证,后实现”的红-绿-重构循环,将模糊的需求转化为精确的代码语言。

    4.3 案例:优惠券使用规则引擎的复杂逻辑

    业务需求:开发一个智能优惠券使用规则引擎,支持”多券叠加使用和最优组合推荐”

    传统困难

    • 自然语言描述:“实现优惠券规则引擎,支持多种券类型的叠加使用,并智能推荐最优使用方案”
    • AI需要猜测:哪些券可以叠加?什么是“最优”?有哪些使用限制?
    • 反复沟通:多次修改提示词,AI理解仍然偏离业务实际

    第一次尝试:AI理解为“简单累加所有优惠”

    // AI第一次实现 - 过于简化
    public BigDecimal calculateDiscount(Order order, List<Coupon> coupons) {
        return coupons.stream()
            .map(coupon -> coupon.getDiscountAmount())
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    // 问题:忽略了券的使用条件、互斥规则、叠加限制
    

    第二次尝试:AI理解为“选择面额最大的券”

    // AI第二次实现 - 逻辑错误
    public List<Coupon> selectOptimalCoupons(Order order, List<Coupon> availableCoupons) {
        return availableCoupons.stream()
            .filter(coupon -> order.getTotalAmount().compareTo(coupon.getMinOrderAmount()) >= 0)
            .max(Comparator.comparing(Coupon::getDiscountAmount))
            .map(List::of)
            .orElse(Collections.emptyList());
    }
    // 问题:只考虑单券最大优惠,未考虑多券组合的更优效果
    

    第三次尝试:AI尝试复杂逻辑但引入更多问题

    // AI第三次实现 - 逻辑混乱
    public CouponUsageResult applyCoupons(Order order, List<Coupon> coupons) {
        // 各种复杂的if-else嵌套,但缺乏清晰的业务规则
        // 没有处理券的互斥关系
        // 没有考虑计算顺序对最终优惠的影响
        // 边界条件处理不当
    }
    

    经过多轮提示词优化,每次都需要重新解释复杂的业务规则,仍不满足预期。

    TDD方式的完整循环:

    🔴 红色阶段:用测试定义需求

    编写测试用例,精确定义复杂的业务规则:

    @Test
    public void testCouponUsageWithBasicStackingRules() {
        // 构造订单:总价100元,包含数码产品
        Order order = new Order()
            .setTotalAmount(new BigDecimal("100.00"))
            .addItem("数码产品", new BigDecimal("100.00"));
        
        // 构造可用优惠券
        List<Coupon> availableCoupons = Arrays.asList(
            new Coupon().setType("满减券").setCondition("满50减10").setDiscountAmount(new BigDecimal("10")),
            new Coupon().setType("打折券").setCondition("数码类9折").setDiscountRate(new BigDecimal("0.9")),
            new Coupon().setType("免邮券").setCondition("免运费").setDiscountAmount(new BigDecimal("5"))
        );
        
        // 期望结果:满减券和免邮券可叠加,打折券与满减券互斥,应选择最优组合
        CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
        
        // 验证最优方案:使用打折券+免邮券 (90+0=90元,比满减券+免邮券的85元更优)
        assertEquals(2, result.getUsedCoupons().size());
        assertTrue(result.getUsedCoupons().stream().anyMatch(c -> "打折券".equals(c.getType())));
        assertTrue(result.getUsedCoupons().stream().anyMatch(c -> "免邮券".equals(c.getType())));
        assertEquals(new BigDecimal("95.00"), result.getFinalAmount()); // 100*0.9 + 0 - 5运费
    }
    
    @Test  
    public void testCouponMutualExclusionRules() {
        Order order = new Order().setTotalAmount(new BigDecimal("200.00"));
        
        List<Coupon> availableCoupons = Arrays.asList(
            new Coupon().setType("满减券").setCondition("满100减30").setDiscountAmount(new BigDecimal("30")),
            new Coupon().setType("打折券").setCondition("全场8折").setDiscountRate(new BigDecimal("0.8")),
            new Coupon().setType("新用户专享").setCondition("首单5折").setDiscountRate(new BigDecimal("0.5"))
        );
        
        CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
        
        // 验证互斥规则:新用户券与其他券互斥,且优惠最大,应该单独使用
        assertEquals(1, result.getUsedCoupons().size());
        assertEquals("新用户专享", result.getUsedCoupons().get(0).getType());
        assertEquals(new BigDecimal("100.00"), result.getFinalAmount()); // 200 * 0.5
    }
    
    @Test
    public void testCouponUsageConditionValidation() {
        Order order = new Order()
            .setTotalAmount(new BigDecimal("30.00"))
            .setUserLevel("普通用户")
            .addItem("服装", new BigDecimal("30.00"));
        
        List<Coupon> availableCoupons = Arrays.asList(
            new Coupon().setCondition("满50减10"), // 不满足金额条件
            new Coupon().setCondition("VIP专享9折"), // 不满足用户等级条件  
            new Coupon().setCondition("数码类8折"), // 不满足品类条件
            new Coupon().setCondition("无门槛5元券").setDiscountAmount(new BigDecimal("5")) // 满足条件
        );
        
        CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
        
        // 验证条件判断:只有无门槛券可用
        assertEquals(1, result.getUsedCoupons().size());
        assertEquals("无门槛5元券", result.getUsedCoupons().get(0).getCondition());
        assertEquals(new BigDecimal("25.00"), result.getFinalAmount());
    }
    

    运行测试:

    [ERROR] testCouponUsageWithBasicStackingRules: 
    Class CouponEngine doesn't exist
    [ERROR] testCouponMutualExclusionRules:
    Method calculateOptimalUsage not found
    

    红色阶段成功:测试失败,但复杂的业务规则已经通过代码精确表达。

    🟢 绿色阶段:AI精确实现

    将失败的测试用例提供给AI:“请实现CouponEngine.calculateOptimalUsage方法,让这些测试通过”

    AI分析测试用例后,精确理解了复杂的业务规则:

    1. 券类型包括满减券、打折券、免邮券、新用户券等
    2. 不同券有不同的叠加和互斥规则
    3. 需要验证使用条件(金额、用户等级、商品类别)
    4. 要计算最优的券使用组合

    AI生成的实现方案:

    public class CouponEngine {
        public static CouponUsageResult calculateOptimalUsage(Order order, List<Coupon> availableCoupons) {
            // 1. 过滤出满足使用条件的券
            List<Coupon> eligibleCoupons = availableCoupons.stream()
                .filter(coupon -> isEligible(order, coupon))
                .collect(Collectors.toList());
            
            // 2. 生成所有可能的券组合(考虑互斥规则)
            List<List<Coupon>> validCombinations = generateValidCombinations(eligibleCoupons);
            
            // 3. 计算每种组合的最终优惠,选择最优方案
            return validCombinations.stream()
                .map(combination -> calculateResult(order, combination))
                .min(Comparator.comparing(CouponUsageResult::getFinalAmount))
                .orElse(new CouponUsageResult(order.getTotalAmount(), Collections.emptyList()));
        }
        
        private static boolean isEligible(Order order, Coupon coupon) {
            String condition = coupon.getCondition();
            
            // 金额条件检查
            if (condition.contains("满") && condition.contains("减")) {
                BigDecimal minAmount = extractMinAmount(condition);
                if (order.getTotalAmount().compareTo(minAmount) < 0) return false;
            }
            
            // 用户等级检查
            if (condition.contains("VIP") && !"VIP用户".equals(order.getUserLevel())) {
                return false;
            }
            
            // 商品类别检查
            if (condition.contains("数码类") && !order.hasCategory("数码产品")) {
                return false;
            }
            
            return true;
        }
        
        private static List<List<Coupon>> generateValidCombinations(List<Coupon> coupons) {
            List<List<Coupon>> combinations = new ArrayList<>();
            
            // 生成所有子集组合
            for (int i = 0; i < Math.pow(2, coupons.size()); i++) {
                List<Coupon> combination = new ArrayList<>();
                for (int j = 0; j < coupons.size(); j++) {
                    if ((i & (1 << j)) != 0) {
                        combination.add(coupons.get(j));
                    }
                }
                
                // 检查组合是否符合互斥规则
                if (isValidCombination(combination)) {
                    combinations.add(combination);
                }
            }
            
            return combinations;
        }
        
        private static boolean isValidCombination(List<Coupon> combination) {
            // 检查互斥规则
            boolean hasDiscountCoupon = combination.stream().anyMatch(c -> "打折券".equals(c.getType()));
            boolean hasReduceCoupon = combination.stream().anyMatch(c -> "满减券".equals(c.getType()));
            boolean hasNewUserCoupon = combination.stream().anyMatch(c -> "新用户专享".equals(c.getType()));
            
            // 新用户券与其他券互斥
            if (hasNewUserCoupon && combination.size() > 1) {
                return false;
            }
            
            // 打折券与满减券互斥
            if (hasDiscountCoupon && hasReduceCoupon) {
                return false;
            }
            
            return true;
        }
        
        private static CouponUsageResult calculateResult(Order order, List<Coupon> usedCoupons) {
            BigDecimal finalAmount = order.getTotalAmount();
            
            // 按照优先级顺序应用优惠
            for (Coupon coupon : usedCoupons) {
                if ("打折券".equals(coupon.getType())) {
                    finalAmount = finalAmount.multiply(coupon.getDiscountRate());
                } else if ("满减券".equals(coupon.getType()) || "无门槛5元券".equals(coupon.getCondition())) {
                    finalAmount = finalAmount.subtract(coupon.getDiscountAmount());
                } else if ("免邮券".equals(coupon.getType())) {
                    // 免邮券单独处理运费
                    finalAmount = finalAmount.subtract(coupon.getDiscountAmount());
                }
            }
            
            return new CouponUsageResult(finalAmount, usedCoupons);
        }
    }
    

    运行测试:

    [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
    [INFO] All tests passed!
    

    绿色阶段成功:测试通过,复杂的业务逻辑完全正确。

    🔵 重构阶段:优化代码质量

    在测试保护下,对AI生成的代码进行质量优化:

    public class CouponEngine {
        // 提取常量,增强可读性
        private static final Set<String> MUTUALLY_EXCLUSIVE_TYPES = Set.of("打折券", "满减券");
        private static final String NEW_USER_COUPON_TYPE = "新用户专享";
        
        public static CouponUsageResult calculateOptimalUsage(Order order, List<Coupon> availableCoupons) {
            if (CollectionUtils.isEmpty(availableCoupons)) {
                return new CouponUsageResult(order.getTotalAmount(), Collections.emptyList());
            }
            
            // 使用策略模式优化条件验证
            List<Coupon> eligibleCoupons = availableCoupons.stream()
                .filter(coupon -> CouponValidator.isEligible(order, coupon))
                .collect(Collectors.toList());
            
            // 使用组合算法优化券组合生成
            List<List<Coupon>> validCombinations = CouponCombinator.generateValidCombinations(eligibleCoupons);
            
            // 使用计算引擎优化折扣计算
            return validCombinations.stream()
                .map(combination -> DiscountCalculator.calculateResult(order, combination))
                .min(Comparator.comparing(CouponUsageResult::getFinalAmount))
                .orElse(new CouponUsageResult(order.getTotalAmount(), Collections.emptyList()));
        }
    }
    
    // 职责分离:券验证器
    class CouponValidator {
        public static boolean isEligible(Order order, Coupon coupon) {
            return AmountValidator.validate(order, coupon) &&
                   UserLevelValidator.validate(order, coupon) &&
                   CategoryValidator.validate(order, coupon);
        }
    }
    
    // 职责分离:券组合器
    class CouponCombinator {
        public static List<List<Coupon>> generateValidCombinations(List<Coupon> coupons) {
            return PowerSetGenerator.generate(coupons).stream()
                .filter(MutualExclusionChecker::isValidCombination)
                .collect(Collectors.toList());
        }
    }
    
    // 职责分离:折扣计算器
    class DiscountCalculator {
        public static CouponUsageResult calculateResult(Order order, List<Coupon> usedCoupons) {
            // 按优先级排序券,确保计算顺序正确
            List<Coupon> sortedCoupons = usedCoupons.stream()
                .sorted(Comparator.comparing(CouponPriorityResolver::getPriority))
                .collect(Collectors.toList());
            
            BigDecimal finalAmount = order.getTotalAmount();
            
            for (Coupon coupon : sortedCoupons) {
                finalAmount = applyCouponDiscount(finalAmount, coupon);
            }
            
            return new CouponUsageResult(finalAmount, usedCoupons);
        }
        
        private static BigDecimal applyCouponDiscount(BigDecimal currentAmount, Coupon coupon) {
            return CouponTypeHandler.getHandler(coupon.getType())
                .applyDiscount(currentAmount, coupon);
        }
    }
    

    重构验证:

    [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
    [INFO] 重构完成,测试持续通过,代码结构更清晰,职责分离更明确
    

    协作模式转变:开发者不再需要为如何描述复杂的业务规则而烦恼,现在只需专注于设计精确的测试场景——我们负责定义“做什么”和“预期结果”,而AI则负责实现具体的“怎么做”。这种明确的分工让复杂逻辑的开发变得既可控又高效。

    通过这种方式,我们能够确保:

    1. 需求表达精准无歧义
    2. 边界条件全面覆盖
    3. 实现过程完全可控
    4. 重构过程安全可靠

    当需要开发新场景时,只需新增测试用例即可,完全不必担心会破坏原有逻辑。这种开发模式不仅提升了效率,更确保了系统的稳定性和可维护性。

    五、实践要点

    5.1 环境配置

    确保AI Agent能执行mvn test命令

    设定明确的行为准则(Rule),让AI能够知道我们现在遵循的开发范式,防止AI为了通过测试”作弊”修改业务代码。一个借助TDD思想驱动代码生成的执行准则如下

    # AI Agent 行为准则:TDD 测试驱动开发
    
    ## 1. 总则
    
    ### 1.1. 概述
    为了确保 AI Agent 遵循 TDD(测试驱动开发)的开发模式,Agent 必须严格按照 **Red-Green-Refactor** 三个阶段的循环进行开发。在执行每个阶段前,Agent 必须向开发者明确声明其当前所处的阶段。
    
    本准则旨在确保 Agent 遵循正确的 TDD 开发流程,避免跳过关键步骤。
    
    ### 1.2. 环境配置:强制使用指定的 settings.xml
    **核心要求**: 所有对 `mvn@ 命令的调用(如 mvn test@, mvn compile@ 等),都**必须**使用 --settings@ (或 -s@) 参数来指定一个自定义的 settings.xml` 文件,以确保能够访问内部的 Maven 仓库。
    
    - **命令格式示例**: `mvn --settings [settings.xml的绝对路径] test`
    - **`settings.xml` 文件路径**: `[settings.xml的绝对路径]`
    
    Agent 在执行任何 Maven 命令前,必须确认此路径已被正确配置和使用。
    
    ---
    
    ## 2. TDD 三阶段循环
    
    ### 2.1. 第一阶段:RED (写失败的测试)
    
    #### 2.1.1. 目标
    编写一个**必然失败**的测试用例,明确定义即将实现的功能需求。
    
    #### 2.1.2. 核心准则
    - **允许**: Agent 可以在 `src/test/` 目录下创建新的测试文件或添加新的测试方法
    - **要求**:
      - 测试必须是失败的(因为对应的实现代码尚未存在或不完整)
      - 一次只测试一个功能点
      - 测试代码要简单清晰
      - 测试名称要明确表达测试意图
    - **禁止**: Agent **不能**修改 `src/main/` 目录下的任何现有代码
    - **验证**: 运行测试必须显示红色(失败状态)
    
    #### 2.1.3. 交互示例
    - **开发者提示**: "我需要实现一个计算器的加法功能"
    - **Agent 回应**: "已激活 **RED 阶段**。我将先编写一个失败的测试用例来定义加法功能的需求。"
    
    ### 2.2. 第二阶段:GREEN (让测试通过的最简实现)
    
    #### 2.2.1. 目标
    编写**最简单**的实现代码,让当前失败的测试通过。
    
    #### 2.2.2. 核心准则
    - **允许**: Agent 可以创建、修改 `src/main/` 目录下的代码
    - **要求**:
      - 优先考虑最简单的实现方式
      - 专注于满足当前测试用例
      - 快速实现功能让测试通过
    - **禁止**:
      - **不能**修改测试代码
      - **不考虑**代码质量和性能优化
      - **不进行**过度设计
    - **验证**: 运行测试必须显示绿色(通过状态)
    
    #### 2.2.3. 交互示例
    - **Agent 回应**: "已激活 **GREEN 阶段**。我将实现最简单的代码来让刚才的测试通过,不考虑优化和设计。"
    
    ### 2.3. 第三阶段:REFACTOR (重构优化)
    
    #### 2.3.1. 目标
    在保持测试通过的前提下,改进代码的设计、质量和可维护性。
    
    #### 2.3.2. 核心准则
    - **允许**: Agent 可以重构 `src/main/` 目录下的实现代码
    - **要求**:
      - 改进代码设计和质量
      - 消除重复代码
      - 提高代码可读性和可维护性
      - 每次重构后必须运行测试确保通过
    - **禁止**:
      - **不能**修改测试的行为和期望
      - **不能**破坏现有功能
    - **验证**: 重构过程中和完成后,所有测试必须保持绿色
    
    #### 2.3.3. 交互示例
    - **Agent 回应**: "已激活 **REFACTOR 阶段**。我将重构代码以提高质量,同时确保所有测试保持通过状态。"
    
    ---
    
    ## 3. TDD 最佳实践
    
    ### 3.1. 循环节奏
    - **小步快走**: 每个 Red-Green-Refactor 循环应该很短(几分钟到十几分钟)
    - **频繁验证**: 每个阶段完成后都要运行测试验证
    - **逐步推进**: 一次只关注一个小功能点
    
    ### 3.2. 测试质量要求
    - **快速执行**: 单元测试应该在秒级内完成
    - **独立性**: 测试之间不应该有依赖关系
    - **可重复性**: 测试结果应该是确定的和可重复的
    - **清晰命名**: 测试方法名应明确表达测试意图
    
    ### 3.3. 代码质量保证
    - **持续重构**: 在每个循环的 REFACTOR 阶段改进代码
    - **消除重复**: 遵循 DRY(Don't Repeat Yourself)原则
    - **保持简洁**: 代码应该简洁明了,易于理解
    
    ### 3.4. 流程控制
    Agent 在每个阶段转换时,必须:
    1. 明确声明即将进入的阶段
    2. 说明当前阶段的具体目标
    3. 完成阶段后验证结果
    4. 确认是否继续下一个循环
    

    5.2 掌握单测语法

    AI擅长基础用例覆盖,但复杂业务场景、边界条件仍有可能需要开发者手动编写。不要完全依赖AI构造用例。

    5.3 选择合适场景与策略

    快速决策法则:

    • 简单功能:单个方法,逻辑直观,采用“先实现,后验证”;
    • 复杂业务逻辑:多分支判断、算法计算、状态转换,采用TDD“先验证,后实现”;
    • 存量代码修改:采用“安全网保护”策略;
    • 提示词难以描述需求时:测试用例是最好的需求文档,采用TDD让代码直接表达需求。

    5.4 持续维护

    单元测试必须与业务代码演进保持同步。一个过时的、无人维护的测试集,其价值会迅速归零,甚至成为负资产。

    六、结语

    如今,单元测试已被赋予全新的意义——它不再被视为一种“开发负担”,而是进化成为AI Coding时代的“质量引擎”。

    我们构建起三重关键保障:

    • 策略一:以客观检验替代主观判断,让AI代码告别“看起来没问题”的错觉;
    • 策略二:为存量代码筑起防护墙,使修改存量代码安全可控,降低演进风险;
    • 策略三:用测试作为与AI的沟通语言,精准传递复杂需求与预期。

    更深层次的变化在于,我们正在重新定义开发者的核心价值:当我们从“思考提示词”转向“思考测试用例”,本质上是从AI代码被动的审查者,转变为了主动的需求设计者与质量掌控者。这不仅加速开发进程,更显著提升代码质量。这正是AI时代中,开发者与智能工具协同进化的优秀范式。

    之前在小黑盒看到过说把收藏夹导出,copy 给大模型整理出新的源码,然后再导入回去。就想能不能把这个做成个浏览器插件,虽然完全没做过,但是好在现在有 vibe coding。于是今天就趁着周末动手了。GitHub - PaiPai121/ReShelf





    碰到的坑主要是一些几个吧:
    chrome 插件如果一段时间没心跳信号就被杀掉了,这个之前没了解过,然后如果大模型算的太慢就可能会被杀掉,然后还不一定能复现,因为不一定每次要思考多久。和 ai 反复聊了才发现。
    另一个就是想单纯依靠免费的 api 来实现,调试过程中好像把 gemini 的免费额度用完了,最后发现 openrouter 的免费模型很适合搞这个。
    cursor 生成代码的边界保护做的倒是还挺不错的。
    还有很多需要细化的地方,希望各位佬们尽情指点。


    📌 转载信息
    原作者:
    Niya
    转载时间:
    2026/1/18 08:51:50

    Google Antigravity 使用过程中,遇到的一些问题,总结一下:

    1. 没告诉他规范的时候,他按照自己的性格来。
      你告诉他规范了,他说的好好的,会认真遵守,但是实际操作中,又总会丢三落四,选择性的忽略了/忘记了其中的几条规范。
      等你告诉他这个错了,请严格按照规范来,他又是道歉,重新按照规范来。
      问题是规范约束很多条,我也不一定能记得全。

    2. 退化问题。
      比如说,让他加好的文件注释。在经过几轮对话修改后,他很可能莫名其妙得,不知道什么时候,又把注释给删掉了。(加上的代码,逻辑也有可能被删掉。)你发现了,问他为什么删掉。他又道歉,然后说删错了,又给你补回去。

    3. 幻觉问题
      比如说,正常情况下,一个通用的包,🈶️A ,B ,C ,但是 D 部分是没有的。
      在引入的时候,他一本正经得根据推导,认为 A ,B ,C 存在,按道理 D 也应该存在。然后将 D 引入到你的项目。结果呢。你跑半天,跑不通。然后你问他,这咋回事。他又道歉,删掉 D ,换一种思路,换一种方式来实现。

    4. 规范问题
      每次切换一个模型,你总得告诉他,请认真阅读 aiconfig 规范,并严格遵守。没法做到持久化。当然,就算你告诉他了,他也阅读了 aiconfig 规范,他也是“基本遵守”。大不了,等你发现他又犯贱,没遵守规范。他又道歉,说不好意思,我违反了规范,我马上修改。

    想到的就这些。

    总之,Vibe Coding 一时爽,粗心早晚泪千行。

    大家使用过程中遇到什么问题,也可以分享一下,避免踩坑。

    对于 AI 开发过程中,AI coder 最喜欢用的骚紫色,我已经有了 Prompt 规避,分享给各位,大家如果也有其他场景的 Prompt 也可以发送一下:

    #角色
    你是一位资深设计资深前端后端全栈开发工程师 #设计风格
    优雅的极简主义美学与功能的完美平衡;
    永远不使用 AI 盛行的基佬紫色!
    清新柔和的渐变配色与品牌色系浑然一体;
    恰到好处的留白设计;
    轻盈通透的沉浸式体验;
    信息层级通过微妙的阴影过渡与模块化卡片布局清晰呈现;
    用户视线能自然聚焦核心功能;
    精心打磨的圆角;
    细腻的微交互;
    舒适的视觉比例;
    强调色:按 APP 类型选择;


    📌 转载信息
    原作者:
    Nanrui
    转载时间:
    2026/1/15 18:34:16

    去年下半年,我们公司开启了一个标杆工程专项,目标是打造一个可持续维护的业务项目,我负责的一个前端项目,需要重构 7 个复杂页面,当时正值 Ai coding 比较火的阶段,我抱着试一试的心态,希望直接用 Ai 重构一个标杆项目。

    一开始我是一个Ai的小白,希望能够一句话就能解决我的诉求,AI也确实给了我一个惊喜,很快的我7个页面全部写完了,然后我在手机上跑了一下基本都跑通了,但进一步观察,却发现一些细节问题,而且规范上也还是存在很多缺陷,例如大文件不拆分,什么状态都喜欢往全局store中放等问题,所以我又手动重构了一波。最后这份代码混杂着我和AI的代码,导致在答辩的时候因为代码风格全局不统一被淘汰了。
    
    虽然是一次失败的重构,但是我也总结了一些心得,在后面的需求开发中我也基本通过这些心得做到无需人为干涉,直接写完一个需求。
    
    1、【编码风格统一】一份代码不要你跟AI同时维护,AI改过的代码有问题你不要直接改,而是让ai接着改。
    
    2、【AI专注力】任务尽可能的集中在一处,不要提出按XXX规范进行重构这种诉求,当然如果必须要,也可以这样需要按照以下步骤拆解
        a)、安装 speckit 工具,可以在github上面搜索到,用spec任务来拆解你的诉求变成 plan task 和 implement 3个阶段
        b)、在task阶段,需要让ai 生成task对应的测试用例,让ai在根据task实现的时候通过生成的测试用例 不断的测试写完的代码
        c)、赋予AI能调试的能力,安装 chrome-devtool-mcp, 在每实现一个组件的时候,让AI执行以下端到端的测试
        d)、赋予AI能MOCK的能力,这个可以下载我开发的一款Vscode插件 MBFE-develop-helper,这个插件部分功能只有我公司内部能够使用,但是mock和h5调试可以在公网上使用,按照README.md 配置mcp,ai即可拥有逻辑mock能力(说明下逻辑mock的服务相当于ai会写原子化的接口真实逻辑,比静态json的mock能力更真实)
        e)、全局规范提示词 CLAUDE.md 的优化,让AI拥有 LINUX 3层架构的思维。
    
     3、【AI记忆力】最小闭环原则,你的任务如果是可拆解的,尽量一个会话解决后 clear完成执行下一个任务,如果上下文超过60%,ai会变得有幻觉,此时需要运行 compact 压缩一下之前的会话,当然最好的方案 还是主进程保持上下文都是一些关键内容,子任务用subagent完成后给父进程一个总结即可,mcp如果输出比较长的工具 需要用subagent包一下,总结mcp的结果。然后还有一个memory的mcp 也可以增强ai的记忆,当你清理上下文的时候 下一个会话仍然可以记住一些你反复重复的事情
    
     4、【AI训练】长远的来看,你需要积累自己的轮子,也就是skill,skill的积累可以让你之前反复唠叨的问题,让ai永久记住,什么时候该用什么工具做什么事,在这方面的决策上减少失误,当然skill变多了以后,你也可以用AI分析一下你当前.claude 目录中的插件、skill、全局提示词存在哪些缺陷,然后对齐进行验证、优化。
    
    以上可能写的有点啰嗦,大家可以直接跳过去,直接看此处总结的 AI 哲学:
     1、AI其实是一个记性差的人,只是它有一本百科全书可以随时查阅,而且查阅速度很快
     2、让一个记性差的人干活,需要遵循最小闭环原则,让它从快速实现 到 快速验证 再到修复再验证形成一个快速循环的工作流
     3、磨刀不误砍柴工,在不忙的时候沉淀一下你的全局提示词和skill,对后续的效率会产生一定的作用
    
    前端推荐工具链

    Speckit 任务拆解(plan/task/implement) GitHub 搜索安装
    chrome-devtool-mcp 端到端测试调试 MCP 配置
    MBFE-develop-helper Mock 能力(逻辑 Mock) VSCode 插件
    menory 长久记忆轻微弥补 Ai 短记忆缺陷
    serena LSP 代码搜索
    其他的什么 context、github 等 mcp 工具的话大家自己看情况安装


    📌 转载信息
    原作者:
    carve
    转载时间:
    2026/1/10 19:04:59

    ai coding 的市场实在是太火热了,模型厂商和应用层开发商们赶紧打起来、打起来

    话说有办法对这些 vscode 插件的模型 2api 吗

    • 更多免费的模型 api 可以看我总结的这个帖子

    📌 转载信息
    原作者:
    uptonking
    转载时间:
    2026/1/8 10:34:47

    不知道现在还有很多人用 Sublime 吗?
    以我自己来说虽然少开,但是特定用途下还是会使用
    这几天看到一个新专案 sublime-simpleai
    主打用 AI 来 coding

    用法很简单直接把 Opea Ai 格式的 BaseUrl 跟 Key 设定好
    作者是推荐可以用 OpenRouter
    就可以直接使用

    这并不是那种给提示词就帮你产生代码的自动化工作
    它更像是小助手 给你的代码提供补全建议
    并且进行除错或者代码重构
    以下是专案内容 有兴趣的朋友可以看看

    另外这是开发者的相关开发文档
    里面除了介绍这个 simpleai 外
    也对市面上开发者用过的 Cli 进行了评价
    整体还蛮中肯的 有兴趣一样可以看看


    📌 转载信息
    原作者:
    josenlou
    转载时间:
    2026/1/4 10:01:28

    如果你恰好有 AI 浏览器(我这里是 Comet),又恰好在用 web 版的 interactive-feedback-enhanced,那有一个小技巧:

    接管和控制我的浏览器以润色文本。

    原本在输入框里写的大段、口语化的 Promt,能快速变成有逻辑且清晰的 Prompt,非常舒服。

    (比不上 Augment 的 Prompt Enhancer 那么强劲,但值得一试~)


    📌 转载信息
    原作者:
    Leon01
    转载时间:
    2026/1/1 16:05:03