系列Java工程师转 AI Agent 3 个月学习计划作者宸丶一28 岁 Java 程序员今日目标从项目想法收敛出一个边界清楚的 Agent MVP并验证它是否真的可用个人格言代码改不改变世界我不知道但先让我准时下班。前言Day 29本来只做设计最后把 MVP 跑起来了Day 28我刚把后续路线校准清楚长期目标仍然是Java / Spring AI 企业 Agent 实战短期先用 Python 做一个最小闭环再理解、重构、逐步把主导权拿回来。所以 Day 29 的原计划其实是选 MVP、写边界、写验收、准备 Vibe Coding 上下文。但今天时间比较充裕我没有停在“规划完成”而是把第一版离线 Python CLI 直接做出来并完成了两轮验收。这次做的不是网页不是聊天界面也不是“万能 Java Agent”而是一个小到可以验证、又足够接近真实开发场景的工具Java 单元测试草稿助手输入一个 Java 文件和方法名输出 JUnit 5 Mockito 测试草稿。最后的验收评分是92 分。不过比 92 分更值得记录的是我亲自经历了一次“需求收敛 → AI 生成 → 真实验证 → 发现缺陷 → 补负向测试”的工程闭环。学习目标把“做 Java 代码助手”收敛为一个可验证的 MVP理解 CLI 为什么是合适的第一步使用 Vibe Coding 生成真实可运行的第一版用成功与失败路径验证工程边界为后续 Java / Spring AI 重构保留清晰模块边界一、先对齐主计划Python MVP 不是终点当前主线仍然没有变我最终要走的是 Java / Spring AI 方向的企业 Agent 实战。Python MVP 的定位是一个更快进入真实问题的入口Python MVP跑通最小闭环理解模块与调用链Java / Spring AI 重构提高自己手写和设计比例因此今天不是为了“用 AI 快速拼个 Demo”而是为后面真正的工程化学习准备一个可运行参照物。我最终选择的 MVP 是为指定 Java 方法生成单元测试草稿。它比“做一个万能代码助手”更适合作为第一步因为它的输入、输出和验收都比较明确项目MVP 定义目标用户想快速获得测试思路与测试骨架的 Java 开发者输入一个本地.java文件 一个或多个方法名处理校验文件 → 定位方法 → 识别构造函数 → 生成草稿 → 校验结构输出JUnit 5 Mockito 测试草稿成功标准生成草稿或落盘成功返回 exit0失败策略非 Java 文件、文件不存在、方法不存在时立即失败不重试二、CLI 不是“模拟软件”而是最轻量的真实产品入口我一开始把 Python CLI 理解成“控制台可运行的 Demo”后来进一步理解它不是模拟软件而是一个真实的软件形态只是交互入口是命令行而不是网页和按钮。例如# 生成草稿到 stdoutpython-magent_cli fixtures/Calc.javaadddiv# 直接写到指定输出目录python-magent_cli--outputgenerated fixtures/Calc.javaadddiv背后的链路是用户参数 ↓ 文件与扩展名校验 ↓ Java 方法定位 ↓ 构造函数依赖识别 ↓ JUnit 测试草稿生成 ↓ 基础 Java 结构校验 ↓ stdout / 安全文件输出这很像一个离线、确定性的简版 Dify 工作流每个步骤都像一个职责明确的节点。后面如果接入 LLM 或 Spring AI重点可以增强“测试计划”和“测试草稿生成”节点但文件校验、输出保护、错误处理、结果验证这些工程骨架不应该被替代。三、我给 AI 的提示词只公开约束不公开完整上下文这次我没有直接把完整原始 Prompt 放出来。一方面里面有学习上下文和个人协作表达另一方面真正值得复用的不是某一句“魔法提示词”而是它包含的约束结构。下面是脱敏后的 Prompt 骨架实现一个离线 Python CLI - 输入指定 Java 文件与方法名 - 输出JUnit 5 Mockito 单元测试草稿 - 不接网络或 LLM API - 不扫描整个仓库 - 不修改输入文件 - 输入非法或方法不存在时立即失败不重试 - 至少验证成功生成、方法不存在、非 Java 文件拒绝第一轮生成的记录显示初始构建过程大约用了9 分钟。当然真正的项目时间不只包括“AI 生成”后面还有阅读、验收、发现问题、修复、再验收。这也是我今天最大的感受Vibe Coding 让“第一版”来得很快但不能替代“证明第一版正确”。四、第一轮验收能跑不代表能交付第一版 CLI 很快就跑通了三条核心路径路径结果合法.java文件 存在方法成功生成草稿exit0方法不存在明确报错exit3无半成品输出非.java文件明确拒绝exit2无测试输出但是验收时发现两个不能忽略的问题问题 1package和import顺序错了生成的 Java 文件一开始类似import...;packagecom.example.demo;Java 的正确顺序必须是packagecom.example.demo;import...;这个问题说明“输出看起来像 Java”不代表它已经满足 Java 编译单元的基本规则。问题 2默认假设被测类有无参构造函数示例类实际只有publicCalc(intseed)但草稿里却直接生成subjectnewCalc();所以第二轮修复明确要求识别构造函数参数原生类型生成占位值引用类型生成Mock字段。例如修复后会生成类似MockprivatePricingGatewaypricingGateway;MockprivateOrderRepositoryorderRepository;BeforeEachvoidsetUp(){Stringregiontodo-value;subjectnewOrderService(pricingGateway,orderRepository,region);}另外还补了--output目录不存在时可以创建但目标文件已经存在时必须拒绝覆盖避免误改他人的测试文件。五、最有价值的插曲测试绿了校验器却漏检了第二轮验收后我本来以为package → import问题已经结束。但继续核查时发现生成器虽然已经修好结构校验器却仍可能把下面这种非法内容当成合法importjava.util.List;packagedemo;原因不是 Java 知识不够而是校验器的实现只看到了第一个import就停止继续寻找后面是否还有package。于是验证不能只保留“正确示例通过”还要加入反例校验样例期望结果package → import通过import → package拒绝两个package声明拒绝这次让我真正理解了一句话正向测试证明“能做”负向测试证明“不会悄悄放过不该做的事”。对后面的 Agent 项目也是一样不能只测试工具调用成功还要测试非法输入、权限拒绝、覆盖文件、部分失败和不安全输出。六、Vibe Coding 里的“括号打架”今天还有一个让我觉得很有意思的小插曲。在 Vibe Coding 的过程中AI 为了修正文案和代码表达出现了一句类似“引号打架改一下写法。”我第一反应是哈哈这不就是“括号打架”吗上图已经做了脱敏处理移除了原始对话顶部信息只保留与本次学习有关的技术反馈片段。这件小事其实很真实。做 Agent / Vibe Coding 时很多“奇怪报错”不是业务逻辑打架而是Markdown 代码块和普通文本混在一起Python 字符串、Shell 引号、Java 字符串多层嵌套Windows 路径反斜杠与转义规则碰撞注释里的引号、模板里的占位符互相干扰。看起来只是“括号打架”实际提醒我给 AI 的上下文和约束也是一种工程输入。输入不清楚输出就容易在边缘处出问题。七、最终验证结果最终实际执行python tests/verify.py python-mcompileall-qagent_cli tests结果四条端到端路径全部通过Python 语法检查通过。验证项最终结果合法 Java 文件 存在方法exit0生成测试草稿方法不存在exit3stderr 说明缺失方法stdout 无半成品非 Java 文件exit2拒绝处理--output输出目录生成目标文件目标已存在时 exit5拒绝覆盖源文件保护输入文件哈希前后一致未被修改Java 基础结构package/import 顺序、重复 package、括号平衡均有检查这里也要诚实说明当前 MVP 的边界当前环境没有javac没有做真实编译级验证示例依赖不是完整业务项目生成的是可审阅、可继续补全的测试草稿不是承诺一次就能在真实项目中mvn test通过的最终测试。八、今日收获知识层面理解 CLI 是真实产品入口不是模拟工具理解 Agent 工作流可以先用确定性规则跑通再引入 LLM明确 Python MVP 与 Java / Spring AI 重构的衔接方式。工程层面MVP 的重点不是“功能多”而是边界清楚、可验证输出文件必须有隔离与拒绝覆盖策略fail-fast 不是一句口号需要落实到错误码、stdout/stderr 和测试路径测试既要有正向样例也要有负向样例。学习方式层面今天我没有手写完整业务代码但并不是把任务交给 AI 就结束了。我真正做的是确定范围、限制 AI 行为、提出验收、检查结果、发现漏洞、要求修复、再验证。Vibe Coding 用来加速实现不用来跳过学习。九、留给读者的 4 个问题1. 你会把“生成了代码”当作完成还是把“通过可解释的验收”当作完成提示可以从成功路径、失败路径、不变量和真实运行结果几个角度思考。2. 一个 MVP 最该先砍掉什么功能提示不一定是“最难的功能”也可能是让输入、输出和验收边界突然变模糊的功能。3. 为什么要为“本来不该出现的错误”写测试提示想想import → package这种反例。如果没有它测试全绿是否真的能证明规则被守住4. 未来把这个 Python CLI 重构为 Java / Spring AI 时哪些模块不该被 LLM 替代提示可以关注输入校验、文件权限、输出隔离、审计、错误码和结果验证。十、明日计划今天时间充裕提前完成了原本 Day 30 的“最小实现 基础验收”。但学习 Day 不跳过明天仍然是Day 30主题调整为理解与重构准备。沿着cli → parser → generator → verify阅读真实调用链解释每个模块的输入、输出和失败行为区分哪些边界要在 Java / Spring AI 版保持稳定设计显式的TestPlan把“解析”“测试规划”“草稿生成”进一步拆开为后续接入 LLM 制定最小增量路线不急着扩功能。小小腾老师评分维度得分评价MVP 需求与范围收敛19/20输入、输出、非目标与安全边界明确CLI 工作流实现20/20控制台到文件输出形成真实闭环验收与错误处理20/20四条路径、退出码、拒绝覆盖和输入保护均已验证Vibe Coding 使用方式18/20能快速生成也能根据验收持续修复工程理解与复盘15/20已掌握结构校验与负向测试AST 与真实 Java 编译仍待深化总分92 / 100优秀老师说今天最大的成果不是“AI 帮你写了一个 CLI”而是你完成了一次标准工程闭环需求收敛 → 实现 → 验收 → 缺陷修复 → 负向测试防回归。后面我们会把这条 Python 工作流读懂、拆开再逐步迁移到你真正的 Java / Spring AI 主线。