多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

从Vibe Coding到Harness Engineering:驾驭AI编程的工程化实践

从Vibe Coding到Harness Engineering:驾驭AI编程的工程化实践 1. 从“AI写代码我喝咖啡”到“Harness Engineering”一个真实的心态转变大概从去年开始我身边不少朋友包括我自己都陷入了一种奇妙的“AI编程蜜月期”。具体表现就是打开某个AI编程助手输入一段模糊的需求描述然后满怀期待地按下回车看着一行行代码像变魔术一样生成出来。那一刻感觉就像拥有了一个不知疲倦、无所不能的编程伙伴。我们美其名曰“Vibe Coding”——一种跟着感觉走让AI驱动自己则在一旁享受咖啡的“氛围感编程”。起初这感觉棒极了生产力似乎得到了指数级提升一些重复性的样板代码、简单的CRUD接口、甚至是一些基础的数据处理脚本都能在几秒钟内搞定。然而这种“美好”并没有持续太久。很快现实就给了我们一记重拳。我接手了一个由AI辅助快速搭建的后台管理系统项目前期用AI生成代码的速度确实惊人一周就搭出了框架和几十个接口。但当我需要修改一个通用的数据验证逻辑时问题出现了。我发现在五个不同的服务模块里相似但不完全相同的验证代码散落在各处有的是AI根据模糊提示生成的有的是后来手动补的。更糟糕的是当我想为整个系统添加一个统一的审计日志功能时发现由于初期缺乏统一的工程约束各个模块的异常处理、日志打印方式五花八门侵入式地添加功能几乎意味着推倒重来。那个下午我喝掉的咖啡比代码行数还多但全都用来调试和修补了所谓的“咖啡时间”变成了“焦头烂额时间”。正是这次惨痛的经历让我彻底反思“Vibe Coding”的局限性。它本质上是一种“探索式”、“草稿式”的编程高度依赖即时反馈和灵光一现但严重缺乏可持续性、可维护性和系统性。代码能跑起来只是最基础的第一步如何让代码在三个月、三年后还能被清晰地理解、安全地修改、高效地扩展这才是工程的核心。于是我的关注点从“如何让AI更快地吐出代码”转向了“如何像驾驭Harness烈马一样去驾驭AI的代码生成能力使其符合工程化的轨道”。这就是“Harness Engineering”理念的萌芽不是取代AI而是建立一套规则、流程和最佳实践将AI强大的生成能力“ harness驾驭、利用”到严谨的软件工程体系中确保产出物的质量、一致性和可维护性。简单来说就是从“AI写我看”的被动状态转变为“我定义规则AI在规则内高效执行”的主动管控状态。这不仅仅是工具使用的升级更是一次开发者思维模式的根本性转变。2. “Vibe Coding”翻车现场那些AI不会告诉你的坑在深入探讨如何驾驭AI之前我们有必要先认清“纯Vibe Coding”模式下那些高频的翻车点。这些坑往往在项目初期被速度所掩盖但在中后期会集中爆发成为项目的“债务”。2.1 架构一致性缺失与“代码沼泽”AI擅长根据单次提示生成局部最优解但它没有系统级架构的视野。当你分别对AI说“给我生成一个用户注册的API”和“给我生成一个商品发布的API”时它可能会给出两套风格迥异的代码。目录结构混乱一个可能把控制器、服务、模型放在同一个文件里如果早期提示不明确另一个可能遵循了分层架构但命名规范不统一。设计模式混用这个模块用了工厂模式那个模块用了简单的静态方法缺乏统一的原则。依赖管理随意不同时间生成的代码可能引入了不同版本的同名库或者循环依赖悄然形成。最终项目会变成一个看似能运行但内部结构盘根错节、难以理解的“代码沼泽”。任何新的需求都像在沼泽里跋涉每一步都可能陷入意想不到的深坑。2.2 上下文缺失与“幽灵逻辑”AI生成的代码基于它训练数据中的模式但它并不理解你项目的具体业务上下文和特殊约束。业务规则遗漏比如你的业务规定“VIP用户折扣不能与促销券叠加”但AI在生成订单计算逻辑时很可能遗漏这条特殊规则因为它不在通用电商模式里。安全隐患AI可能会生成一个直接将用户输入拼接进SQL查询的字符串如果训练数据中有旧教程而不会主动采用参数化查询来防止SQL注入。它也不会自动意识到某个接口返回的数据中包含了不该暴露给当前用户的敏感字段如密码哈希、内部ID。非功能性需求无视性能、可观测性日志、监控、国际化这些“非功能性需求”AI在单次生成中几乎不会主动考虑。你需要反复、精确地提示否则生成的代码就是“裸奔”状态。这些缺失的上下文逻辑就像“幽灵”平时看不见一旦触发就会导致数据错误、安全漏洞或系统崩溃。2.3 可测试性差与“黑盒回归”“Vibe Coding”下催生的代码往往不是为了被测试而生的。高耦合AI容易生成高度耦合的代码比如在控制器里直接写死数据库查询这使得单元测试极其困难你必须启动整个数据库环境。缺乏接口抽象直接依赖具体实现而不是接口导致测试时无法方便地注入Mock对象。副作用不明确一段生成的函数可能默默地修改了全局状态、发送了邮件或调用了外部API但这些副作用在代码审查时很难一眼看出。这样的代码库每次修改都让人提心吊胆因为你不知道会不会引起意想不到的回归错误。测试覆盖率低调试成本极高。2.4 知识蒸发与“巴士因子”风险当项目大量依赖AI生成的、缺乏充分注释和文档的代码时一个更隐蔽的风险是“知识蒸发”。只有最初的提示词可能还很简略记录了当时的一点意图后续的维护者包括三个月后的你自己根本无从理解“为什么这段代码要这么写”。这导致了极高的“巴士因子”即有多少关键成员被巴士撞了项目会陷入瘫痪。项目高度依赖少数几个“记得”当时生成上下文的人人员变动对项目是致命打击。3. Harness Engineering 核心四柱为AI编程套上缰绳认识到问题就需要构建解决方案。Harness Engineering 不是某个具体工具而是一套方法论体系我将其总结为四个核心支柱如同马车的四个轮子共同支撑起可控、高效的AI辅助开发。3.1 支柱一精准化的提示工程Prompt Engineering这是驾驭AI的“缰绳”本身。我们要从“漫谈”转向“结构化指令”。角色设定Role Playing在提示词开头就为AI设定明确的角色。例如“你是一个经验丰富的Java后端架构师特别擅长设计可扩展、高并发的Spring Boot微服务。请遵循阿里巴巴Java开发规范。” 这能将AI的思维模式锚定在专业领域内。上下文注入Context Injection不要指望AI读心。将必要的上下文作为系统提示词或对话历史固定下来。这包括项目技术栈Spring Boot 3.1.5, JDK 17, MyBatis-Plus, MySQL 8.0。架构规范我们采用DDD领域驱动设计分层架构interfaces控制器, application应用服务, domain领域层, infrastructure基础设施层。代码规范使用Lombok减少样板代码使用MapStruct进行对象映射日志必须用SLF4J API异常使用自定义的业务异常类。关键业务规则摘要例如订单状态流转规则为待支付-已支付-已发货-已完成。仅支持单向流转。任务分解与链式思考Chain-of-Thought对于复杂任务不要用一个提示词解决所有问题。将其分解并引导AI逐步思考。例如“首先请为‘用户订单取消’这个业务场景设计领域模型包括主要的实体、值对象和领域服务接口。”“基于上面的模型现在生成Order实体类的Java代码包含状态字段和cancel()方法该方法需包含状态校验和领域事件发布逻辑。”“最后生成调用该领域服务的Application Service层代码并处理可能的异常。”示例驱动Few-Shot Learning提供一两个你项目中已有的、符合标准的代码示例告诉AI“请按照这个风格和模式生成”。这是最直接有效的风格对齐方式。提示将你反复使用的角色、上下文、规范保存为AI助手的“自定义指令”或“系统提示”这样每次新对话都自带约束事半功倍。3.2 支柱二前置且固化的工程约束Engineering Constraints在AI动手之前我们就应该把“轨道”铺好。这些约束是项目的地基。项目脚手架与模板不要从零开始。使用像Spring Initializr、Create-React-App、Vite等官方脚手架初始化项目或者建立内部的项目模板仓库。这确保了基础依赖、目录结构、基础配置是统一且正确的。AI应该在已有的、正确的结构上填充内容而不是创建结构。代码规范与静态检查在项目初期就集成Checkstyle、PMD、SonarLint、ESLint、Prettier等工具。并将配置文件如.eslintrc.js,.prettierrc,checkstyle.xml提交到仓库。在CI/CD流水线中强制执行这些检查。这样即使AI生成的代码风格有偏差也会在合并前被自动纠正或拦截。统一的依赖管理使用Maven BOM或Gradle的platform插件来统一管理所有第三方库的版本避免冲突。在pom.xml或build.gradle中明确定义AI生成的代码在引入新依赖时会引用这些已定义的版本。API契约先行对于前后端协作采用OpenAPI/Swagger规范先定义API接口。工具可以基于契约自动生成Controller接口骨架和DTO类。AI的任务是去实现这个预定义契约的内部逻辑而不是发明新的、不一致的接口。3.3 支柱三面向AI的代码设计与评审AI-Oriented Design Review我们的设计模式和评审流程需要适应“人机协作”的新模式。设计模式的应用有意识地使用那些能让代码更清晰、更易于被AI理解和续写的模式。例如策略模式将可能变化的算法如不同的折扣计算、支付方式抽象出来。你可以让AI“生成一个新的策略类来实现微信支付”而无需改动主流程。模板方法模式定义好算法的骨架。让AI去填充具体的步骤实现。清晰的模块边界通过包package、模块module强制划分边界降低耦合。给AI的提示词就可以非常明确“在com.example.order.domain包下生成一个Order实体”。代码评审的转变评审重点从“语法是否正确”转向“意图是否对齐”和“约束是否遵守”。审查提示词将生成代码所用的关键提示词作为评审的一部分。这能帮助评审者理解代码的生成上下文和预期目标。审查一致性这段新生成的代码在命名规范、异常处理、日志打印、事务管理等方面是否与项目现有模式一致审查“为什么”对于复杂的逻辑要求开发者或记录补充注释说明“为什么采用这种实现方式考虑了哪些业务约束或边界条件”。这对抗“知识蒸发”至关重要。自动化审查增强除了静态检查可以集成像Semgrep这样的定制化规则引擎来检查项目特定的安全模式或不良实践例如是否在所有数据库操作中都使用了公司的加密工具类。3.4 支柱四持续验证与反馈闭环Validation Feedback Loop生成代码不是终点而是起点。必须建立快速的验证机制。测试驱动开发TDD的变体可以尝试“提示驱动开发”。先编写测试用例描述期望行为然后将测试用例和需求一起作为提示词给AI让它生成通过测试的实现。这能确保代码满足功能需求。即时单元测试生成与执行利用AI本身如ChatGPT的Code Interpreter模式或Cursor的测试生成功能为生成的代码快速创建单元测试。并立即在本地运行验证基本逻辑。集成测试沙盒对于涉及多个服务的代码拥有一个快速启动的集成测试环境如使用Testcontainers至关重要。在代码提交前能自动验证其与其他组件的集成情况。性能与安全扫描将性能基准测试如JMeter脚本和安全扫描如OWASP ZAP、依赖漏洞扫描集成到CI流水线中。AI生成的代码必须通过这些关卡才能上线。4. 实战演练一个“Harness Engineering”工作流示例让我们以一个具体的场景来串联上述四个支柱“为一个电商系统添加‘商品库存预占’功能”。第0步确立约束支柱二项目已基于Spring Boot模板创建目录结构清晰集成了Lombok、MapStruct、MyBatis-Plus。pom.xml中通过dependencyManagement统一管理版本。代码规范已配置Checkstyle。第1步精准提示与设计支柱一 支柱三我们不直接说“生成库存预占代码”。而是准备一个结构化的提示角色你是一位资深Java后端工程师熟悉DDD和Spring Boot。 上下文本项目是电商系统采用DDD四层架构。已有Product商品和Inventory库存聚合根。Inventory包含totalStock总库存和availableStock可用库存字段。 技术栈Spring Boot 3.1.5, MyBatis-Plus 3.5.0, 使用Transactional管理事务。 业务规则1. 用户下单时预占库存减少availableStock。2. 订单支付成功后扣减totalStock和availableStock。3. 订单取消时释放预占恢复availableStock。4. 预占需防止超卖availableStock不能为负。 任务请遵循以下步骤思考并生成代码 1. 设计一个InventoryLock值对象包含orderId, skuId, lockedQuantity, statusPRE_LOCKED/ CONFIRMED/ RELEASED等字段。 2. 在Inventory聚合根内添加一个preLockStock(Long orderId, String skuId, Integer quantity)方法实现预占逻辑。需检查可用库存更新availableStock并创建一个新的InventoryLock记录状态为PRE_LOCKED添加到库存的锁记录列表中。 3. 生成对应的InventoryLockMapper接口MyBatis-Plus。 4. 在infrastructure层生成InventoryLockRepositoryImpl实现保存锁记录的方法。 5. 在application层生成InventoryAppService中的preLockInventory方法它调用领域服务并处理InventoryStockNotEnoughException。 请确保代码符合项目已有的Checkstyle规范使用Lombok注解并为复杂逻辑添加简要注释。第2步AI生成与初步审查将上述提示输入AI助手如Cursor、Claude或本地部署的代码大模型。获得生成的代码后进行快速审查架构对齐检查生成的类是否放在了正确的包domain,infrastructure,application下。一致性检查命名风格如preLockStockvspre_lock_stock、异常处理方式是否与项目一致逻辑审查重点审查Inventory.preLockStock方法中的库存检查if (this.availableStock quantity) {...}是否严谨事务注解Transactional是否加在了正确的Service层第3步补充验证与反馈支柱四生成单元测试对AI说“请为上面生成的Inventory.preLockStock方法编写一个JUnit 5单元测试覆盖库存充足、库存不足、并发预占使用RepeatedTest的场景。” 然后运行这些测试。集成验证在本地启动数据库Testcontainers编写一个简单的集成测试调用InventoryAppService.preLockInventory验证数据库中的库存和锁记录是否正确更新。安全与性能考虑思考这个预占操作是否需要在接口层做防重提交预占记录是否需要定时清理过期数据将这些思考作为新的提示词让AI协助生成防重令牌校验或定时任务骨架代码。第4步提交与CI/CD将经过审查和测试的代码、以及新增的测试用例一同提交。CI流水线会自动运行代码风格检查Checkstyle。单元测试包括刚生成的测试。集成测试如果配置了。依赖漏洞扫描。构建打包。只有通过所有关卡代码才能被合并。至此一个功能完整、符合工程规范、经过验证的“库存预占”模块就通过“Harness Engineering”流程被可靠地构建出来了。5. 进阶思考工具链整合与未来展望Harness Engineering 的理念最终需要落实到工具链上形成流畅的工作流。IDE深度集成未来的IDE插件不仅能补全代码更能理解项目上下文。例如在编写Service方法时插件能自动建议符合项目规范的异常处理模板在创建新实体时能基于项目已有的BaseEntity自动生成字段。自定义AI代理AI Agent你可以构建一个专属于你团队或项目的AI Agent。这个Agent的“系统提示”里内置了项目的所有规范、架构图、API文档和最佳实践案例。开发者只需用自然语言描述需求Agent就能在严格的约束下生成高度可用的代码片段甚至生成配套的测试和提交信息。提示词版本管理与共享团队可以建立一个内部的“高效提示词库”将针对常见场景如“生成一个分页查询Service”、“生成一个消息事件处理器”验证过的、高质量的提示词共享出来提升整个团队的AI使用水位。从“代码生成”到“系统生成”随着多模态和智能体技术的发展AI可能不仅能生成代码还能根据架构图生成部署脚本K8s YAML, Terraform、根据接口定义生成API文档和前端组件代码。Harness Engineering 的范围也将扩大到整个软件生命周期需要建立跨阶段的、统一的约束和契约。我个人最深的一点体会是Harness Engineering 的本质是将开发者从重复的、低层次的编码劳动中解放出来但将我们的核心价值提升到了更高维度——架构设计、约束定义、质量把控和复杂问题拆解。我们不再是“写代码的人”而是“设计系统并确保AI能正确构建它的人”。咖啡终于可以真正悠闲地喝但喝咖啡时我们思考的不再是某个语法细节而是如何设计一个更优雅、更健壮的领域模型以及如何用最精确的“咒语”提示词来指挥我们的AI伙伴将它实现。这个过程比单纯的“Vibe Coding”要有挑战得多但也充满了创造力和掌控感的乐趣。
返回列表