我的VB Coding之路 - AI编码实战演进

一、背景:我们为什么要使用AI编码?

1.1. 行业与业务背景

从23年开始,随着基础大模型的突破,主流代码工具的迭代周期越来越快,这些工具的创新持续推动整个研发效能提升。

从最初的编译器代码补全、到Github Copilot代码助手、再到Cursor/Trae AI编程工具、再到Claude Code/OpenCode AI 编程代理工具,一直都在极大的提升编码效率。

而我们的业务场景,和绝大多数团队面临的挑战一致:金融系统承载资金的扭转、业务形态的多样化、需求迭代频繁、代码腐化风险高、团队协作密度大,如何提升编码效率、保证代码质量、降低长期维护成本,是我们使用AI工具的目标之一。

1.2 演进历程总览

  1. 入门期:从编译器补全到Github Copilot 单个方法/函数的生成
  2. 探索期:Cursor/OpenCode Agent Coding全功能级代码生成
  3. 成熟期:Rules约束体系搭建,建立AI的"项目规范"
  4. 深水区:SDD(规格驱动开发)的深度实践与边界探索

本文将详细分享下我的使用历程、实践经验,希望能给大家有所启发

二、第一阶段:入门期------代码智能补全与单方法改写

这是我接触AI编码的起点,核心是基于Github Copilot / 通义灵码 的代码智能补全能力,解决局部代码的编写与优化问题。

2.1 核心使用场景

主要在两个高频场景使用,也是所有人最容易上手的AI编码场景:

场景1:标准化代码自动补全

针对对象构建、模型转换等重复度极高的CRUD代码,通过少量代码引导,或者写好注释,让AI完成全量补全,示例如下:

java 复制代码
// 开发者输入:构建商品卡片注释
// AI自动补全以下代码
public List<ItemCardVO> buildItemCards(List<ContentEntity> entities) {
    List<ItemCardVO> result = new ArrayList<>();
    for (ContentEntity entity : entities) {
        ItemCardVO itemCard = new ItemCardVO();
        itemCard.setItemId(entity.getItemId());
        itemCard.setItemTitle(entity.getTitle());
        itemCard.setItemImg(entity.getPicUrl());
        result.add(itemCard);
    }
    return result;
}

场景2:单方法重构与优化

针对冗长、可读性差的历史方法,通过AI完成代码精简、规范对齐、逻辑优化,示例如下:

java 复制代码
// 原始代码(冗长难读,冗余校验)
public String getDiscountText(Long finalPrice, Long nnPrice) {
    if (finalPrice == null || nnPrice == null) {
        return "";
    }
    if (finalPrice <= nnPrice) {
        return "";
    }
    Long discount = finalPrice - nnPrice;
    if (discount <= 0) {
        return "";
    }
    String discountYuan = String.valueOf(discount / 100.0);
    return discountYuan + "元";
}

// AI重构后(简洁优雅,规范统一,边界清晰)
public String getDiscountText(Long finalPrice, Long nnPrice) {
    if (finalPrice == null || nnPrice == null || finalPrice <= nnPrice) {
        return "";
    }
    Money discount = Money.ofFen(finalPrice).subtract(Money.ofFen(nnPrice));
    if (discount.getCent() <= 0) {
        return "";
    }
    return String.format("%s元", discount.getYuan());
}

2.2 收益

  • 效率提升:在日常项目中,代码补全在对象构建、模型转换场景减少40%-50%的键盘输入;单方法重构速度提升50%。
  • 体验优化:大幅减少API文档查找时间,避免拼写错误、语法错误等低级问题,让大家更聚焦于业务逻辑本身。
  • 当年2023年使用的时候,实属惊艳

2.3 暴露的核心问题

这个阶段的能力,本质是"局部优化",很快就遇到了无法突破的瓶颈:

  1. 能力边界局限:仅能完成单个方法或代码片段的生成,无法理解整体业务逻辑,更无法处理跨类、跨模块的完整需求。
  2. 上下文缺失:不了解项目的架构规范、代码风格、团队约定,生成的代码往往和存量代码格格不入。

三、第二阶段:探索期------Cursor/OpenCode全功能生成

在24年到到现在,由于生成式大模型的发展,以及Cursor/Trae、Claude Code/OpenCode等编程工具的出现。

我们希望AI不仅能帮我们完成'局部优化',而是让AI从"补全代码"升级为"实现完整功能",也就是Agent Coding模式。

3.1 核心落地方法

我们基于Cursor + Sonnet4.5/GPT模型,通过对话,构造不同的Prompt,给AI明确的需求、背景、实现要求、技术细节约束,让AI一次性生成完整的模块代码。

Prompt描述

plaintext 复制代码
需求:用户查账记账功能
背景:
- 业务背景 要详细描述

实现要求:
1. 实现/manualAdjust接口方法和请求参数类
2. 查询账户、计算余额、更新账户、插入流水
3. 测试功能

具体细节:
1. 用 DemoAccountMapper 查询条件:user_no = "stk_" + 企业ID product_second_type_code = "0101"
2. post_balance = pre_balance - change_balance
3. 如果 post_balance < 0,记录错误日志并跳过此用户,后续所有步骤直接跳过
4. 更新 demo_user_account 表:balance = post_balance
5. 等等

请生成完整的代码。

AI生成的完整代码示例

基于上述Prompt,AI可一次性生成全链路代码,覆盖接入层、服务层、数据层等全流程:

java 复制代码
// 1. 接入层实现
@GetMapping("/manualRepairOrder")
public CommonResult<Object> testGetOrderListForPageQuery(
        @RequestParam(value = "orderNo", required = false) String orderNo) {
    manualRepairOrder(Arrays.asList(orderNo));
    return CommonResult.success();
}

// 2. service层实现
private void manualRepairOrder(List<String> testOrderList) {
    if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(testOrderList)) {
        for(String orderNo : testOrderList) {

            OrderRecordListQueryPO queryPo = new OrderRecordListQueryPO();
            queryPo.setOrderNo(orderNo);
            queryPo.setStatusList(Arrays.asList(OrderStatusEnum.SUCCESS.getValue().intValue(), OrderStatusEnum.PROCESSING.getValue().intValue()));
            // 示例产品线A
            queryPo.setProductSecondCode("1234");

            PageHelper.startPage(1, 1);
            PageInfo<OrderRecordPO> pageInfo = new PageInfo<>(orderRecordRepository.getOrderListForPageQuery(queryPo));
            log.info("[订单修复]查询订单返回,订单号:{},结果:{}", orderNo, JSON.toJSONString(pageInfo));

            if(org.apache.commons.collections4.CollectionUtils.isEmpty(pageInfo.getList())) {
                continue;
            }

            OrderRecordPO orderRecordPO = pageInfo.getList().get(0);
            repairOneOrder(orderRecordPO);
        }
        return;
    }

    int pageNum = 1;
    int pageSize = 20;
    while (true) {
        OrderRecordListQueryPO queryPo = new OrderRecordListQueryPO();
        queryPo.setStatusList(Arrays.asList(OrderStatusEnum.SUCCESS.getValue().intValue(), OrderStatusEnum.PROCESSING.getValue().intValue()));
        // 示例产品线A
        queryPo.setProductSecondCode("1234");

        PageHelper.startPage(pageNum, pageSize);
        PageInfo<OrderRecordPO> pageInfo = new PageInfo<>(orderRecordRepository.getOrderListForPageQuery(queryPo));
        log.info("[订单修复]查询订单返回,pageNum:{}, pageSize:{}, 结果:{}", pageNum, pageSize, JSON.toJSONString(pageInfo));

        if(org.apache.commons.collections4.CollectionUtils.isEmpty(pageInfo.getList())) {
            break;
        }

        for(OrderRecordPO orderRecordPO : pageInfo.getList()) {
            repairOneOrder(orderRecordPO);
        }

        pageNum++;
        try {
            TimeUnit.MILLISECONDS.sleep(50);
        } catch (InterruptedException e) {
            log.error("修数时线程休眠异常", e);
        }
    }
}

3.2 落地收益

Agent Coding实现了开发效率的阶跃式提升,通过Prompt驱动的自动代码生成,替代了传统的全手动编写,虽然Prompt设计需要额外投入时间,但综合开发效率仍有非常显著的提升。

3.3 快速暴露的致命问题

在后续的需求迭代中,这套模式的问题快速暴露,甚至带来了更高的维护成本,核心集中在3个方面:

问题1:代码延续性极差

同一个业务场景显然都能实现,示例如下:

java 复制代码
// 第一次生成(简洁风格)
private String buildDiscountText(Money discount) {
    return String.format("省%s元", discount.getYuan());
}

// 第二次生成(冗长风格)
private String buildDiscountText(Money discount) {
    BigDecimal yuan = BigDecimal.valueOf(discount.getCent())
        .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
    String yuanStr = yuan.stripTrailingZeros().toPlainString();
    return "省" + yuanStr + "元";
}

直接影响:同一个项目内,类似功能的实现方式五花八门,代码腐化速度极快,长期维护成本指数级上升。

问题2:代码风格与团队规范严重脱节

AI不了解项目沉淀的代码规范、架构模式、命名约定,生成的代码和存量代码风格不一致,每次都需要人工大量修改,反而增加了工作量。

问题3:AI不理解业务,生成的代码不符合要求

受限于AI上下文大小,AI在编写老项目的时候,并不理解代码背后的具体业务。

  • 一些同学,可能把详细的业务全部喂给AI,导致可能自己写代码反而更快
  • 一些同学,可能简单描述下,生成的代码需要大量修改,甚至推倒重做

本质上是每一个窗口,就是一个'干净'的上下文,AI并不清楚每一行代码背后的业务逻辑、整个项目的背后业务。

3.4 根因分析

这些问题的本质,不是AI能力不足(AI上限极高、天才型选手 ),而是我们没有给AI建立项目专属的上下文和约束

  1. 没有统一的项目规范:AI不知道项目的代码风格、架构模式、命名规范;
  2. 没有沉淀的领域知识:AI不了解业务的特定术语、设计模式、边界规则;
  3. 没有可复用的历史经验:每次生成都是"零基础",无法从历史代码和最佳实践中学习。

基于这个根因,因此我逐渐进入了第三个阶段:通过Rules约束、AGENT业务描述、给AI建立一套完整的"项目规范"。

四、第三阶段:成熟期------Rules约束、建立AI的"项目规范"

这个阶段的核心目标,是把团队的项目规范、架构模式、领域知识,背后业务,通过标准化的Rules文件固化下来,让AI的所有生成行为,都在这套规则的约束内执行。 (注意:受限于上下文,rules不是越多越好,尽量保证在500行以内)

4.1 核心Rules文件内容示例

1. 代码风格/编程规范

python 复制代码
# 编程规范
## 命名风格
- 类名:UpperCamelCase;抽象类以 Abstract/Base 开头;异常类以 Exception 结尾;测试类以 Test 结尾
- 方法名/参数/变量:lowerCamelCase;常量:UPPER_SNAKE_CASE
- 枚举类名加 Enum 后缀,成员全大写下划线分隔;POJO 布尔字段不加 is 前缀
- 领域模型:xxxDO(数据对象)/ xxxDTO(传输对象)/ xxxVO(展示对象),禁用 xxxPOJO
- Service/DAO 方法前缀:get(单个)/ list(多个)/ count(统计)/ save/insert(插入)/ remove/delete(删除)/ update(修改)
## 常量
- 禁止魔法值直接出现在代码中,必须先定义常量
- long/Long 赋值使用大写 L:Long cnt = 25L;
## 注释
- 类、类属性、类方法必须用 /** */ Javadoc 规范,禁用 // 替代
- 方法内部单行注释用 //,多行用 /* */,与代码对齐
- 所有枚举字段必须有注释说明用途
- 所有抽象方法(含接口方法)Javadoc 需说明功能、参数、返回值、异常
## OOP
- 使用 "constant".equals(obj) 或 Objects.equals(a, b),防止 NPE
- POJO 类属性必须使用包装类型;RPC 返回值和参数必须使用包装类型;局部变量推荐基本类型
- 构造方法禁止包含业务逻辑,初始化逻辑放 init() 方法
## 集合
- 禁止在 foreach 中 remove/add,使用 Iterator 操作
- 去重操作优先使用 Set,而非 List.contains() 遍历
- Collections.EMPTY_LIST 仅作标志,不可 add/get
- 集合相关的尽量使用apache相关的API, 禁止使用hutool的任何API
## 并发
- 线程必须通过线程池管理,禁止显式 new Thread()
- 线程池必须用 ThreadPoolExecutor 创建,禁止 Executors 工厂方法(防 OOM)
- 多资源加锁保持一致顺序,遵循"一锁、二判、三更新、四释放"原则
## 异常处理
- 可预检查的异常(NPE、越界等)用条件判断规避,不用 try-catch
- 禁止用异常做流程/条件控制
- catch 后必须处理或向上抛出,禁止空 catch
- 级联调用 a.getB().getC() 需防 NPE;推荐使用 Optional
## 代码质量(强制)
- 方法不超过 80 行,绝对不超过 100 行
- 禁止:重复代码、过大类、过长参数列;每个函数只做一件事
- 不依赖 SNAPSHOT 包(无特殊情况)
- 金额统一用 BigDecimal(String) 构造,禁用 BigDecimal.equals() 比较金额
- DB/后端交互金额单位为分,前端展示为元
- 除非特殊情况,不能在代码里面直接写org.apache.commons.collections4.CollectionUtils.xxx, 应该直接引入import xxx
## 安全与稳定性
- 对前端入参"低信任",后端必须独立校验
- 涉及个人数据接口必须有鉴权,敏感数据按加解密规范处理
- 接口调用必须配置合理超时时间,不使用框架默认值
- Redis 操作做好异常处理,避免抖动影响主链路
- 对三方回调保持"低信任",考虑不回调、多回调、错误回调场景
- 资金出入链路:仅明确终态错误码才可做终态处理,否则查询接口或等回调

2. 项目结构规范

每个项目特有的,会用最优秀的模型初始化,让AI理解这个项目是做什么业务的,解决什么问题的

以示例管理台为例

markdown 复制代码
# Project Context

## Purpose
XFP金融业务管理后台系统(xfp-A-console),为星辰科技集团提供统一的金融信贷管理接口服务。系统主要面向运营人员、财务人员、风控人员等内部用户,提供产品配置、订单管理、额度管理、结算管理、资产处理等金融业务的完整管理功能。

核心目标:
- 提供金融产品(计划A、计划B、计划C等)的全生命周期管理
- 支持多渠道、多角色的业务操作和数据权限控制
- 实现与集团内部多个金融系统的集成和协调

## Tech Stack

### 核心框架
- Java 1.8
- Spring Boot 2.2.6.RELEASE
- Maven 多模块项目

### 星辰科技内部框架
- nova-boot-parent 2.10.1.RELEASE(星辰科技统一 Spring Boot 基础框架)
- StarRPC 2.10.1.RELEASE(gRPC 框架,用于服务间 RPC 通信)
- nova-jaf-monitor-starter(监控组件)

### 数据访问层
- MyBatis Plus 3.4.2
- MyBatis Spring Boot Starter 2.1.3
- PageHelper 1.3.0(分页插件)

### 中间件与配置
- Apollo(配置中心,支持多环境配置动态更新)
- Redis(多数据源配置:ARedis, stringARedis)
- Redisson(分布式锁)
- Kafka(多源生产者和消费者,用于日志审计、保单通知等)
- RabbitMQ(消息队列)

### 工具库
- Hutool 5.8.25(Java 工具库)
- Lombok 1.18.20(代码生成)
- EasyExcel 3.1.0(Excel 导入导出)
- Guava(Google 工具库)

### API 文档
- Swagger2
- Knife4j(Swagger UI 增强)

### 测试
- Groovy(用于测试脚本,test 模块包含 148 个 .groovy 文件)

## Project Conventions

### 代码风格
- 包命名:`cn.startech.xfp.finance.console.{module}`
- 命名规范:
  - Controller 层:XxxController
  - Service 层:XxxService/XxxServiceImpl
  - BO(Business Object):XxxBO
  - VO(View Object):XxxVO
  - Req/Rsp:XxxReq/XxxRsp
  - Enum:XxxEnum
- 注释要求:使用中文注释,包含业务说明和关键逻辑说明
- 日志规范:使用 Slf4j,关键操作记录入参和结果
- 常量管理:统一在 common 模块的 constant 包下定义

### 架构模式
采用分层架构,Maven 多模块设计:

```text
xfp-finance-console (父工程)

├── xfp-finance-console-common      # 公共模块(常量、枚举、工具类)
├── xfp-finance-console-dal         # 数据访问层(Mapper、Entity)
├── xfp-finance-console-facade      # 对外接口层(RPC 接口定义)
├── xfp-finance-console-provider    # 服务提供者(Controller、启动类)
├── xfp-finance-console-integration # 集成层(调用外部服务)
├── xfp-finance-console-service     # 业务服务层(Service 实现)
└── xfp-finance-console-test        # 测试模块(Groovy 测试)
```

**关键架构决策**:
- Web 层与 Service 层使用 BO 对象传递数据,避免直接使用 VO 或 Entity
- RPC 服务使用 StarRPC (gRPC) 框架,扫描指定包下的服务实现
- 使用 Apollo 配置中心管理多环境配置,配置命名空间:application, business, overdueSmsConf, rolePrivilegeConf 等
- 多数据源 Redis:financeRedis 使用 Jackson 序列化,stringFinanceRedis 使用 String 序列化
- 统一异常处理:使用 FinanceServiceException 和 BizResult 枚举

### 测试策略
- 使用 Groovy 编写测试用例(test 模块)
- 单元测试覆盖核心业务逻辑
- 集成测试验证外部服务调用
- 测试环境使用独立的 Apollo 配置和数据库

### Git 工作流
- 主分支:main/master
- 开发流程:功能分支 → 提测 → 合并主干
- 提交信息:简洁描述变更内容,关联 JIRA/禅道任务编号
- 版本号管理:使用日期版本号(如 20251222_01)

## Domain Context

### 业务领域
**核心业务模块**:
1. **产品管理(catalog)**:金融产品配置,包括计划A、计划B、计划C等产品的参数配置
2. **订单管理(workflow)**:订单全生命周期管理(申请、审批、处理、结算)
3. **额度管理(limitcenter)**:用户额度申请、审批、调整
4. **结算管理(settlement)**:结算计划、结算记录、逾期管理、催收
5. **账户管理(profile)**:个人账户、企业账户、员工管理、角色权限
6. **渠道管理(gateway)**:渠道配置、渠道关系管理
7. **保障管理(coverage)**:场景保障单的创建、变更、处理
8. **资产处理(archive)**:逾期资产的处理流程
9. **方案中心(planhub)**:产品方案的特殊业务逻辑
10. **账务管理(ledger)**:账单生成、账单查询
11. **签章管理(stamp)**:电子印章和合同签章
12. **运营管理(campaign)**:活动和权益配置

**关键业务概念**:
- 二级产品分类:计划A(PLAN_ALPHA)、计划B(PLAN_BETA)、计划C(PLAN_GAMMA)、计划D(PLAN_DELTA)
- 产品状态:启用(ENABLE)、禁用(DISABLE)、草稿(DRAFT)
- 用户类型:运营用户、场景用户A(SCENARIO_USER_A)、门店用户、渠道用户
- 角色体系:超级管理员、业务超级管理员、贷后主管、门店用户、渠道用户、催收专员等

**数据权限**:
- 基于角色的权限控制(RBAC)
- 渠道级数据隔离:不同渠道用户只能看到自己渠道的数据
- 操作审计:关键操作记录到 Kafka(sec_xfp_finance_log_audit)

## Important Constraints

### 技术约束
- Java 版本固定为 1.8,不可升级到更高版本(公司标准)
- 必须使用星辰科技内部框架(nova-boot、StarRPC)
- 配置必须通过 Apollo 配置中心管理,禁止硬编码
- 敏感操作必须记录审计日志到 Kafka
- 文件上传限制:最大 100MB

### 业务约束
- 金融产品配置变更需要经过审批流程
- 涉及金额计算必须使用 BigDecimal,禁止使用 float/double
- 订单状态流转必须符合状态机规则
- 数据权限必须严格校验,防止越权访问
- 逾期数据涉及催收业务,需特别关注合规性

### 监管约束
- 用户隐私数据(手机号、身份证号等)必须脱敏展示
- 金融数据保留期限不少于 5 年
- 操作日志必须完整记录,支持审计追溯

## External Dependencies

### 内部服务(通过 StarRPC RPC 调用)
- **nova-finance-aurora**:产品方案服务(facade: 20251110_01)
- **nova-finance-orbit**:场景方案服务(facade: 20251222_01)
- **nova-finance-harbor**:结算服务(facade: 20251222_01)
- **nova-finance-vector**:额度服务(facade: 20251222_01)
- **nova-finance-pulse**:订单服务(facade: 20251211_01)
- **nova-finance-anchor**:协议服务(facade: 20251201_01)
- **nova-finance-shield**:策略服务(facade: 20251201_01)
- **nova-finance-atlas**:资产服务(facade: 20251223_01)
- **xfp-finance-profile**:账户服务(facade: 20251119_01)
- **xfp-finance-mosaic**:保障服务
- **xfp-finance-breeze**:运营服务(facade: 20240801_01)
- **xfp-finance-insight**:数据服务(facade: 20251204_01)

### 基础设施
- **Apollo 配置中心**:http://10.0.0.1:8080(本地开发环境)
- **Redis**:ci-resource-id: redis.xfp-novafinance-core-api
- **Kafka**:
  - 生产者主题:sec_xfp_finance_console_svc_log_audit(日志审计)、demo_operate_record_topic(业务事件)
  - 消费者主题:demo_async_notify_topic(异步通知)
- **RabbitMQ**:ci-resource-id: rabbitmq.finance_msg_queue
- **Maven 私服**:https://maven.startech.work/repository/

### 第三方服务
- **OSS 文件存储**:用于文件上传和下载(通过 EnableObjectStorageClient 启用)
- **短信服务**:通过 MessageFacadeService 调用
- **OCR 服务**:用于证件识别

### 运行时依赖
- 服务端口:8093
- 数据库:通过 Apollo 配置,支持多环境(DEV/STG/PRE/PRD)
- MyBatis Mapper 扫描路径:cn.startech.xfp.finance.console.dal
- SOA Provider 扫描包:cn.startech.xfp.finance.console.service.core.rpc, cn.startech.xfp.finance.console.web.core.*.rpc

3. 功能实现规范 (按需)

主要给AI一个模板,一个合格优秀的功能应该怎么实现

plaintext 复制代码
# 功能实现规范
## 数据服务层
- 必须实现 Service 接口
- 使用 @Component 注解
- 调用下游服务,必须在integration
示例:
```java
@Component
public class AConfigServiceImpl implements AConfigService {
    @Override
    public BasePageRsp<GuaranteeBlacklistDetailRsp> pageGuaranteeBlacklist(GuaranteeBlacklistListReq req) {
        // 实现逻辑
    }
}
```

## 接入层
xxxxx

4. 主/子AGENT

因为模型问答越后面token越贵,AI也会变得越来越'智障',因此建议使用子agent来减少主agent的消耗,让AI一直保持'聪明'状态。

markdown 复制代码
---
description: 智能使用子agent:明确何时需要、何时不需要及如何传递上下文
alwaysApply: true
---

# 子Agent智能使用规则

## 核心原则

**基于任务复杂度、并行性和专业性智能决策是否使用子agent。** 避免过度拆分导致上下文丢失,也避免主会话承载过重任务。

## 决策标准

### 必须使用子agent

| 场景 | 子agent类型 | 判断标准 |
|-----|------------|---------|
| 大范围代码探索 | `explore` | 不熟悉代码库 / 搜索多目录 / 理解整体架构 |
| 并行独立任务 | 多个并行 | 互不依赖的模块 / 可同时进行的探索或测试 |
| 专项能力 | `shell/browser-use` | 复杂git操作 / 浏览器测试 / 隔离实验 |
| 超大任务 | `generalPurpose` | >100次工具调用 / >10个文件 / 完整模块开发 |

### 主agent直接处理

**代码修改**:1-5个已知文件、单个方法/类、已定位bug、配置调整
**搜索查询**:精确匹配类名/方法名、已知文件查找、特定错误消息
**验证检查**:linter错误、命名规范、git状态
**简单任务**:2-4步顺序操作、<10次工具调用

### 紧密上下文优先原则

**需要紧密上下文时,主agent保持连续性**:
- 迭代调试(记住上次错误和尝试)
- 基于前一步结果立即决策
- 用户交互式指导
- 步骤间强依赖

**示例**:修改代码 → 检查linter → 修复错误(主agent连续执行)

## 快速决策检查表

启动子agent前检查(任一项"是"则考虑子agent):
- [ ] 涉及>5个文件或>5步操作?
- [ ] 需要大范围搜索或代码探索?
- [ ] 需要专项能力(shell/browser/隔离环境)?
- [ ] 有多个独立任务可并行?
- [ ] 步骤松耦合且不需立即基于上一步决策?

**全部"否"** → 主agent直接处理

## 信息传递规范

### Prompt结构模板

```text
任务目标:[一句话描述]

背景:项目类型 / 相关目录 / 已知信息

具体要求:

1. [步骤1]
2. [步骤2]

预期返回:

## [标题1]

- [信息项]

## [标题2]

- [信息项]
```

### 必需信息清单

- [ ] 任务具体目标(不是笼统的"分析")
- [ ] 背景信息(项目结构、技术栈)
- [ ] 范围限定(目录、文件、关键词)
- [ ] 预期输出格式
- [ ] 约束条件(只读/可写)

### 避免信息丢失

**子agent返回后**:
- 主agent明确总结关键发现
- 启动下一子agent时完整传递前序结果

## 典型案例

### 案例1: 简单功能(主agent)

**任务**:UserController添加查询余额接口

**执行**:并行读取3个文件 → 添加方法 → 检查linter

**原因**:已知文件、简单关联、<10次调用

### 案例2: 线上bug(混合)

**执行**:
1. `explore`子agent:查询日志,返回错误摘要/文件位置/调用链
2. `explore`子agent:定位代码,返回片段/依赖/修复建议
3. 主agent:基于建议执行修改
4. `shell`子agent:提交MR

**原因**:1-2需探索、3需上下文、4是独立操作

### 案例3: 大型功能(多子agent)

**任务**:权限管理系统

**执行**:
1. 并行2个`explore`:探索现有代码 + 数据库结构
2. 主agent:PLAN模式设计方案
3. 并行3个`generalPurpose`:后端模块 + 拦截器 + 测试
4. 主agent:审查集成

## 子agent类型选择

| 类型 | 适用场景 | 传递重点 |
|-----|---------|---------|
| `explore` | 代码探索、搜索 | 关键词、目录、探索深度 |
| `generalPurpose` | 复杂多步骤 | 完整需求、约束、预期 |
| `shell` | Git、命令 | 具体命令、错误处理 |
| `browser-use` | 浏览器测试 | 场景、交互步骤 |

## 常见错误

**❌ 过度拆分**:修改端口 → 启动子agent读 → 启动子agent改
**✅ 正确**:主agent直接读取并修改

**❌ 上下文断裂**:子agent1找路径 → 主agent未保存 → 子agent2不知道
**✅ 正确**:子agent1返回后主agent总结 → 传递给子agent2

**❌ 类型错误**:探索代码用generalPurpose
**✅ 正确**:探索用explore(专门优化)

## EXECUTE模式决策

**简单计划**(2-4步、文件明确、紧密关联)→ 主agent
**复杂计划**(>5步、大范围、并行任务)→ 子agent

## 平衡原则

1. 简单任务 → 主agent(避免过度工程)
2. 复杂探索 → explore子agent(专业优化)
3. 并行任务 → 多子agent(提高效率)
4. 超大任务 → generalPurpose子agent(避免上下文爆炸)
5. 紧密上下文 → 主agent连续(减少信息丢失)

**记住**:子agent是工具不是目的,目标是高效完成任务。

4.2 落地收益

  • 所有生成的代码都遵循统一的命名规范 (基本不存在,两个一样的提示词生成的代码千差万别)
  • 项目结构清晰,模块划分明确
  • 代码风格保持一致
  • 代码实现时间从1天降低到2~3小时(需要人工检查、收尾)

4.3 依旧存在的问题

虽然Rules带来了显著改善,但仍存在一些问题

  1. 需求理解不够深入:AI仍然是基于技术方案/Prompt"翻译"成代码,对业务语义理解有限。如果业务描述不够清晰,方向还是会走偏
  2. 文档滞后:代码变更后,AGENT文档更新容易遗漏
  3. 依赖关系管理:对于复杂的模块依赖关系,多服务情况,AI处理不够智能

五、第四阶段:深水区------SDD(规格驱动开发)的深度实践

今年初,开始初步尝试SDD(Specification Driven Development,规格驱动开发),当时使用的是OpenSpec框架。

5.1 什么是SDD

SDD 是一种以"规范为先"的软件开发范式。其核心理念是:在让 AI 编写任何代码之前,必须先定义结构化的规格说明文档(Specification)。

  • 单一真理源:规格文档被视为整个开发流程的唯一准则,驱动后续的设计、实现、测试和部署。
  • 流程闭环:它将模糊的自然语言想法通过结构化流程转化为清晰的需求和任务,最终由 AI 生成可验证的高质量代码。

也就是,之前程序员开发是面向代码,现在SDD开发是面向规格文档 (有点像plan模式的大号版本)

就像30年前,大家开发是面向汇编,现在开发是面向编程语言,未来可能是规格文档?

5.2 使用流程

  • openspec init 创建项目的"宪法"文件。它包含项目的技术栈、编码准则和愿景。这是 AI 每次生成代码前必须遵循的全局约束
  • /opsx:propose 创建一个预案 (创建4-5个文件)
  • /opsx:apply 执行预案,严格执行task任务
  • /opsx:archive 归档预案,确保长期可维护性

5.3 带来的收益

代码层面:

  • 所有代码都严格遵循规格说明,消除了理解偏差 (甚至可以在心中忘记有代码这一个东西,永远面向文档)
  • 不同开发者实现相同规格,代码风格完全一致
  • 代码变更时,必须先更新规格,保证文档与代码同步

业务层面:

  • 产品、开发、测试对需求的理解高度一致。因为必须要有文档,才能实施。
  • 减少了需求理解偏差导致的返工

测试覆盖:

  • 自动生成的测试用例覆盖了所有正常和异常流程
  • 测试用例与规格说明一一对应,确保完整性
  • 边界条件和异常场景都有明确的测试用例

文档层面:

  • 规格说明就是最准确的文档
  • 任何变更都先更新规格,再同步代码
  • 新人通过阅读规格说明就能快速理解功能

5.4 SDD的问题与挑战

问题1:规格编写门槛高,非常重,新手写不好,投入产出比低

  • 新手往往写不好规格,过于技术化或过于模糊
  • 不合格的规格对后面的代码实现影响

影响: 对于简单需求,写规格的时间甚至超过直接写代码。

问题 2:SDD工具链不成熟,老项目集成困难,新老代码混杂,维护成本高

我们的代码库已经有大量历史代码,SDD更适合从零开始的新项目

  • 历史代码缺乏规格说明,无法纳入SDD体系
  • 新老代码风格混杂,维护成本反而增加
  • 可能一部分人用SDD,一部分人用传统方式,协作困难

问题 3:学习成本高

  • 写出合格的第一份规格说明,平均需要3-5次迭代,非常的麻烦
  • 写完一份合格的提案,可能代码已经写完了

因此大家可以去实践尝试,理解SDD的思维,但暂时不建议大家使用。

六、总结与展望

AI Coding 从来不是来替代后端工程师的,而是在编码阶段来释放我们的生产力。它能帮我们摆脱重复的工作,让我们有更多的时间和精力,聚焦于业务理解、架构设计、业务创新与技术难点上面。

可以预见的是,未来随着基础模型的突破、上下文的增强、工具的创新,可能以上都不再是问题。

最后希望本篇文章可以给大家有所启发,找到适合自己的 AI 编码方式,谢谢大家。

ps. 以上部分内容由AI生成

七、附录

参考
https://mp.weixin.qq.com/s/aHAJxvrwobUKsPZ3w7GnYw

https://mp.weixin.qq.com/s/W6-e-uSPcGCqQAXxx_PDgA

https://github.com/Fission-AI/OpenSpec

https://github.com/anomalyco/opencode