
在生成式AI浪潮下,淘特导购技术团队系统性地探索了AI辅助编程的落地路径。我们的实践历程从初期的代码智能补全起步,经历了Agent Coding的试炼,随后引入Rules约束以规范AI行为,并最终探索了前沿的SDD(规格驱动开发) 模式——以自然语言规格(spec.md)为唯一真理源,自动生成代码、测试与文档,旨在实现设计先行、内建可测试性与文档永续。实践表明,SDD理念先进但落地存在高门槛、工具链不成熟、与历史代码集成困难等挑战。因此,团队当前采用融合策略:以轻量级技术方案模板为输入 + Rules严格约束 + Agent Coding高效实现 + AI自动汇总架构文档,形成了一套兼顾规范性、开发效率与长期可维护性的最佳实践。

背景
1.1 业务背景
生成式AI技术的范式突破正驱动智能开发工具进入超线性演进阶段,主流代码生成工具的迭代周期已从季度级压缩至周级。淘特导购系统承载着商品推荐、会场投放、活动营销等多样化业务场景,技术团队长期面临需求迭代频繁、代码腐化加速及高协同度的挑战。在此背景下,我们开始尝试将AI技术深度融入日常开发流程,探索从传统编码到AI辅助编程的效能提升之路。
1.2 AI编程工具的引入
2024年初,团队开始系统性引入AI编程工具,期望在提升开发效率的同时保障代码质量。我们首先接触了阿里内部的Aone Copilot及其代码智能补全功能,随后逐步尝试了Agentic Coding、基于Rules的约束编码以及SDD(Specification Driven Development)等多种模式。本文将详细复盘这段探索历程、分享实践经验并展望AI编程的未来。

代码智能补全与单方法改写
2.1 初识AI编程
场景1:代码自动补全
在对象构建、模型转换等模板化代码编写中,AI补全能显著减少重复性输入。
// 开发者输入:
public List<ItemCardVO> buildItemCards(List<ContentEntity> entities) {
List<ItemCardVO> result = new ArrayList<>();
// AI自动补全以下代码
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能快速将冗长、难读的代码重构为简洁优雅的形式。
// 原始代码(冗长难读)
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 初步收益
- 效率提升:在对象构建、模型转换等场景中,代码补全减少了70-80%的键盘输入;单方法重构速度提升约50%。
- 体验优化:减少了查阅API文档的时间,避免了拼写与语法错误,让开发者更聚焦于业务逻辑本身。
2.3 遇到的问题
此阶段也暴露了明显短板:
- 局限于局部:只能优化单个方法或片段,无法理解整体业务逻辑与架构。
- 缺乏上下文:不了解项目的特定架构规范和代码风格。
- 无法应对复杂需求:对于需要跨多个类、模块协作的复杂功能无能为力。

Agentic Coding的探索与挑战
3.1 Agentic Coding的尝试
为解决上述问题,我们开始尝试Agentic Coding模式:通过编写详细的提示词(Prompt),让AI一次性实现完整功能。我们使用Aone Copilot搭配Qwen3-coder模型。
典型的Prompt结构:
需求:实现NN页面红包模块
背景:
- 需要展示用户可用的红包列表
- 红包按门槛从小到大排序
实现要求:
1. 创建数据服务类 NnRedPacketDataService,查询用户红包
2. 创建模块VO NnRedPacketVO,包含红包列表、总金额等字段
3. 创建模块构建器 NnRedPacketModuleBuilder,组装数据
技术细节:
- 数据服务需要实现 DataService<List<FundQueryDTO>> 接口
- 数据服务实现类需要依赖FpProvider,并执行红包查询,参数请参考已有实现
- 模块构建器需要继承 BaseModuleBuilder<NnRedPacketVO>
- 使用 @Component 注解标记为Spring Bean
- 遵循项目代码规范
请生成完整的代码。
AI生成的代码示例(节选):
// 1. 数据服务
@Component
public class NnRedPacketDataService implements DataService<List<FundQueryDTO>> {
@Autowired
private FpProvider fpProvider;
@Override
public List<FundQueryDTO> execute(InvocationContext context, JSONObject req) {
// 从配置获取红包池ID
String poolIds = req.getString("nnRedPacketPoolIds");
List<Long> fundPoolIds = Arrays.stream(poolIds.split(","))
.map(Long::parseLong)
.collect(Collectors.toList());
// 查询用户红包
return fpProvider.queryUserFundBuyPoolId(
context,
fundPoolIds,
customRuleId,
securityCode
);
}
}
// ... 模块VO和构建器代码
3.2 显著的效率提升
Agentic Coding通过提示词驱动的自动代码生成,替代了大量手动编码工作。尽管设计Prompt需要额外时间,但综合效率提升显著。
3.3 快速暴露的问题
在后续迭代中,我们发现了严重问题:
问题1:代码延续性差
同一业务,不同时间生成的代码风格迥异。
// 第一次生成(简洁风格)
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:团队协同性差
不同开发者编写的Prompt质量差异大,导致生成的代码质量参差不齐。
3.4 原因分析
根本原因在于:AI缺乏项目特定的上下文和约束。
- 没有项目规范:不了解代码风格、架构模式、命名规范。
- 没有领域知识:不熟悉淘特导购业务的特定术语与设计模式。
- 没有历史经验:每次都是“零基础”生成,无法从历史代码中学习。
这促使我们思考:必须为AI建立“项目规范”和“领域知识”体系。

Rules约束 - 建立AI的“项目规范”
4.1 引入Rules文件
我们开始尝试用Rules文件约束AI行为,将项目规范、架构模式、领域知识固化下来。
Rules文件体系:
.aone_copilot/
├── rules/
│ ├── code-style.aonerule # 代码风格规范
│ ├── project-structure.aonerule # 项目结构规范
│ └── features.aonerule # 功能实现规范
└── tech/
├── xx秒杀-技术方案.md # 具体需求的技术方案
└── xx红包模块-技术方案.md
4.2 Rules文件内容示例
代码风格规范 (code-style.aonerule) 节选:
# 代码风格规范
## Java代码规范
- 类名使用大驼峰命名法(PascalCase)
- 方法名和变量名使用小驼峰命名法(camelCase)
## 空值判断
- 集合判空统一使用:CollectionUtils.isEmpty() 或 isNotEmpty()
- 字符串判空统一使用:StringUtils.isBlank() 或 isNotBlank()
## 日志规范
- 使用 LogUtil 工具类记录日志
- 错误日志格式:LogUtil.error("类名, 方法名, 错误描述, 关键参数={}", param, exception)
项目结构规范节选:
明确包结构、分层和命名规范,例如数据服务统一命名为[业务名]DataService,并需实现特定的DataService<T>接口,这属于典型的Java后端服务设计约束。
功能实现规范节选:
对数据服务层、模块构建器等核心组件的实现模板进行严格定义,确保生成的代码符合Spring框架的Bean管理约定和项目架构。
4.3 技术方案模板
为每个需求创建轻量级技术方案文档,明确定义需要生成的代码结构。
## 业务定义
NN红包模块用于展示用户在NN业务场景下可用的红包列表。
## 模块领域对象
| 对象含义 | 实现方案 | 属性及类型 |
|---------|---------|-----------|
| NN红包模块VO | 新增 | 1. redPacketList:List<RedPacketItem><br>2. totalAmount:String<br>3. expandText:String |
...(数据服务、构建器定义)
4.4 显著改善的效果
引入Rules后效果明显:
- 代码一致性:所有生成代码遵循统一规范,结构清晰,风格一致。
- 开发效率:技术方案填写时间从2小时降至20分钟;代码实现时间从1天大幅缩减至2小时(含人工收尾)。
- 团队协作:技术方案成为共同语言,Code Review效率提升50%,新人上手时间从1周减至2天。
4.5 依然存在的问题
- 需求理解不够深:AI仍是基于技术方案的“翻译”,对业务语义理解有限。
- 测试质量不稳:生成的单元测试用例通过率和覆盖度需人工把关。
- 文档易滞后:代码变更后,文档更新容易遗漏。
- 依赖管理不优雅:对复杂模块依赖关系的处理不够理想。
这些问题推动我们探索更规范、可延续的编码模式。

SDD探索 - 规格驱动开发
5.1 SDD的引入
近期,我们开始尝试SDD(规格驱动开发),使用了Spec Kit工具链。
SDD核心理念:
- 规格是唯一真理源:所有代码、测试、文档均从规格生成,实现文档永不过期。
- 设计先于实现:先用自然语言描述“做什么”(规格),再生成“怎么做”(代码)。
- 可测试性内建:规格中明确定义测试用例,自动生成完整单元测试。
5.2 Speckit执行流程
我们主要使用 iflow/qwen + qwen3 coder plus + spec kit 工具组合。
5.2.1 环境准备与文件体系
├── .specify/ # 宪章、脚本、模板
├── specs/ # 规格目录
│ └── 001-nn-redpacket-module/
│ ├── checklists/requirements.md
│ ├── contracts/api-contract.md
│ ├── data-model.md
│ ├── plan.md
│ ├── quickstart.md
│ ├── research.md
│ └── spec.md # 核心规格文件
└── req/ # 原始需求
5.2.2 speckit.constitution — 制定项目宪章
生成全局性的 constitution.md,规定核心原则(模块化、阿里巴巴开发标准、质量保证等)、安全合规和开发工作流程。
5.2.3 speckit.specify — 编写规格说明
在独立分支中创建 spec.md 等文件。以NN红包模块为例,规格需明确定义功能需求(FR)、非功能需求(NFR)及具体的测试用例(TC),描述语言需极度精确以避免AI理解歧义。
# NN红包模块规格说明
## 功能需求
### FR-1: 红包数据获取
**描述:** 系统应该能够查询用户在当前NN业务场景下可用的红包
**输入:** userId, fundPoolIds, customRuleId, securityCode
**处理逻辑:**
1. 调用FpProvider.queryUserFundBuyPoolId()查询红包
2. 过滤条件:状态=2(可使用)、未过期、门槛<=配置阈值
**输出:** 符合条件的红包列表
...
## 测试用例
### TC-1: 正常流程 - 有可用红包
**前置条件:** 用户有2个可用红包
**预期结果:** VO不为null,redPacketList包含2个红包,totalAmount计算正确
5.2.4 speckit.plan — 制定实施计划 & speckit.tasks — 任务分解
生成 data-model.md、api-contract.md、plan.md 及 task.md,将规格分解为可执行任务。
5.2.5 speckit.implement — 实现代码
AI根据规格自动生成数据服务、模块构建器及完整的单元测试。生成的代码严格引用规格中的需求编号(如// 过滤可用红包(按规格FR-1的过滤条件)),且单元测试与规格中的测试用例(TC)一一对应,确保了极高的可追溯性。
@Component
public class NnRedPacketDataService implements DataService<List<FundQueryDTO>> {
@Override
public List<FundQueryDTO> execute(InvocationContext context, JSONObject businessReq) {
// ... 获取配置
List<FundQueryDTO> funds = fpProvider.queryUserFundBuyPoolId(...);
// 过滤可用红包(按规格FR-1的过滤条件)
Long amountThreshold = businessReq.getLong("amountThreshold", 2000L);
return funds.stream()
.filter(fund -> fund.getPayStatus() == 2) // 可使用状态
.filter(fund -> isNotExpired(fund)) // 未过期
.filter(fund -> fund.getAmountThreshold() <= amountThreshold)
.collect(Collectors.toList());
}
}
生成的单元测试同样严谨,严格验证规格中定义的各类场景。
@Test
public void testBuild_ThresholdExceeded_ShouldReturnNull() {
// 对应规格 TC-2: 边界条件 - 红包门槛超限
// Mock:门槛25元,超过配置的20元(2000分)
when(dataService.execute(any(), any())).thenReturn(Collections.emptyList());
// 执行与验证
NnRedPacketVO result = builder.doBuild(context);
assertNull(result); // 按规格预期结果
}
5.3 SDD带来的改进
- 一致性显著提升:代码严格遵循规格,消除理解偏差;产品、开发、测试理解高度一致。
- 可测试性大幅提升:自动生成覆盖所有正常、异常流程的测试用例,Mock规范,断言准确。
- 可维护性显著改善:规格即最新文档;变更影响清晰;代码结构清晰,注释完整。
- 团队协作效率提升:规格成为统一语言,新人上手更快。
5.4 SDD的问题与挑战
- 规格编写门槛高:需要较强的抽象和文档能力,简单需求可能“写规格比写代码还慢”。
- Spec Kit工具链不成熟:规格解析可能不准确、代码生成质量不稳定、增量更新困难。
- 与现有代码库集成困难:更适合绿地开发,历史代码缺乏规格,导致新老风格混杂。
- 学习成本高:团队成员需要时间适应,老员工接受度存疑。
5.5 SDD适用场景分析
- 适合:全新项目/模块、高复杂度核心业务、多人协作大型需求、质量要求极高的场景。
- 不适合:简单工具函数、快速验证的实验性功能、一次性临时需求、对存量代码的小修小改。

当前最佳实践 - Rules + Agentic Coding + AI文档汇总
6.1 融合各阶段优势
核心思路:用Rules约束AI行为,用轻量技术方案指导实现,用Agentic Coding快速迭代,用AI自动汇总维护文档同步。
6.2 技术方案模板优化
采用比SDD更轻量、比纯Prompt更规范的技术方案模板,聚焦“做什么”,将“怎么做”交给受Rules约束的AI。
# [需求名称]-技术方案
## 业务定义
[1-2句话]
## 模块领域对象
| 对象含义 | 实现方案 | 属性及类型 |
|---------|---------|-----------|
| [对象名] | 新增/修改 | 1. 字段1:类型 - 说明 |
...
特点:编写时间约30分钟,有明确结构约束,实现细节由AI填充。
6.3 AI文档汇总机制
让AI在每次需求开发后,自动分析代码并更新“整体架构与业务逻辑文档”,解决文档滞后问题。
6.3.1 文档汇总流程
完成开发 → 提交AI:“将本次代码逻辑汇总到架构文档” → AI分析代码 → AI更新文档
Prompt示例:
请分析刚完成的NN红包模块代码(NnRedPacketDataService.java等),将其业务逻辑汇总到“NN业务整体架构与逻辑文档.md”中,确保:
1. 描述模块核心功能和业务价值。
2. 说明数据流转过程。
3. 列出关键业务规则和判断逻辑。
4. 保持与现有文档风格一致。
6.3.2 AI汇总效果示例
AI生成的文档片段结构清晰,精准提炼了业务逻辑、数据流转和关键代码位置,例如在处理JSONObject和集合操作时,其模式符合通用的数据库/中间件交互规范。
### 3.2 NN红包模块
#### 3.2.1 功能说明
用于在NN频道展示用户可用红包列表,提升转化率。
#### 3.2.2 数据流转
用户请求 → NnRedPacketDataService (调用FpProvider,过滤状态=2、未过期、门槛<=20元的红包)
↓
NnRedPacketModuleBuilder (排序:NN专属优先,门槛从小到大 → 构建VO)
#### 3.2.3 关键逻辑
1. 红包过滤规则:payStatus=2, 时间在有效期内,amountThreshold<=配置值。
2. 排序规则:专属红包优先,其次按门槛升序。
3. 总金额计算:对availableAmount求和并转换单位。
#### 3.2.4 代码位置
- 数据服务:`dataservice/impl/nn/NnRedPacketDataService.java`
- 模块构建器:`module/nn/NnRedPacketModuleBuilder.java`
- 模块VO:`domain/module/nn/NnRedPacketVO.java`

思考总结
淘特导购团队的AI编码实践是一个持续的演进过程:
- 初期探索验证了AI的潜力,也暴露出缺乏规范的问题。
- Agentic Coding提升了实现完整性,但延续性和一致性不足。
- Rules约束有效解决了规范与架构一致性问题,成为当前主实践。
- SDD尝试理念先进,揭示了未来方向,但落地仍需工具链和流程的完善。
我们坚信AI规范化编程是未来。团队正在持续探索:完善工具链、优化流程整合、降低学习成本、持续迭代Rules。通过不断实践,我们定能找到更优的AI辅助编程模式,在提升开发效率的同时,保障软件系统的长期代码质量与可维护性。