CodeFuse AI编程实践:从系统分析到代码生成的高效探索

蚂蚁国际信贷团队通过CodeFuse与Prompt实现从系分到代码的AI自动化生成,编码效率提升40%,赋能金融级系统快速迭代!

原文标题:AI Coding实践:CodeFuse + prompt 从系分到代码

原文作者:阿里云开发者

冷月清谈:

本文深入探讨了蚂蚁国际信贷技术团队如何通过AI辅助代码生成(AI Coding)来应对业务快速迭代、代码质量与跨地域协作效率的挑战。其核心方案是结合阿里云CodeFuse工具及精心设计的Prompt(提示词),实现将系统分析文档(系分)高效转化为高质量的Java后端业务代码。
团队为此次AI Coding设定了清晰目标:显著提升研发效能,平均减少编码阶段40%的人日投入;将“设计即生产”落地,直接从系分文档生成代码;通过AI将代码规范“基因化”,确保代码风格统一;并打造友好的开发者体验。
在实现思路上,团队将代码生成范围划分为门面层、持久层和业务逻辑层,并针对不同层级开发了模块化且具备案例参考的Prompt结构。尤其值得关注的是,针对传统业务流程图语义模糊的痛点,该方案创新性地引入了“流程图增强”环节,将白话文流程图转化为包含精确代码引用信息的中文伪代码,极大提升了AI对业务逻辑的理解和代码生成的准确性。此外,Prompt设计中还强调了角色定义、强制规则及推理引导,以减少AI模型可能出现的“幻觉”
实际项目应用表明,该方案已在多个项目中成功投产,不仅显著提升了代码生成效率,部分项目甚至将机械式编码时间减少了80%。未来,团队计划进一步探索TDD方式辅助AI Coding,完成从设计、编码、执行到测试、修改的动作闭环,最终构建起真正的自主式Java开发智能体。

怜星夜思:

1、AI生成代码能提效40%,听起来很棒!但这种“系分即代码”的流程,前期投入肯定也不小吧?比如Prompt要写得这么讲究,还有那么多规则和系统知识要维护。对咱们普通团队来说,真的划算吗?还是说只适合蚂蚁这种大厂?
2、文章里提到AI生成代码会有“幻觉”,可能会丢代码,参数组装出错,甚至需要多次生成才能达标。毕竟是金融级别系统,容错率很低吧?除了再人工检查修改,大家觉得还有啥好办法来确保AI代码在生产环境下的绝对可靠性?以及怎么平衡AI的随机性和金融领域对确定性的要求?
3、流程图增强,把白话文变成伪代码,这个思路很棒!文章最后也提到了TDD辅助AI Coding,感觉AI不仅能写代码,还能参与到设计和测试环节。大家觉得,除了生成代码,AI在未来还能在软件开发生命周期的哪些环节发挥更大作用?比如帮我们做架构评审,或者更智能地生成测试用例?

原文内容

  • 业务场景:后端JAVA业务代码生成。

  • AI解决方案概述:从系分出发,解析提取其中核心内容,并生成任务列表,再让AI工具结合提示词完成任务(生成代码)。

  • 工具选择:IDEA CodeFuse插件 + CodeFuse IDE

  • 使用效果概述:目前已经覆盖门面层代码的生成和修改、持久层代码的生成和修改、业务逻辑层的代码生成。已经正式投产到三个项目迭代中,参与项目已经上线。在应用了AI Coding的三个项目中,编码阶段的人日投入平均减少了40%。

一、引言

在蚂蚁国际信贷业务系统建设过程中,技术团队始终面临双重考验:一方面需应对日益加速的需求迭代周期,满足严苛的代码质量规范与金融安全合规要求;另一方面,跨地域研发团队的协同效率与代码标准统一性,在传统开发模式下逐渐显现瓶颈。为突破效率制约、提升交付质量,我们积极探索人工智能辅助代码生成技术(AI Coding)的应用实践。本文基于蚂蚁国际信贷技术团队近期的实际项目经验,梳理AI辅助开发在金融级系统快速迭代场景中的实施要点并分享阶段性实践心得。

本文主要考虑使用结合CodeFuse及提示词,实现从系分到代码,提升JAVA开发同学的开发效率。

在叙述逻辑上,首先针对团队现状、开发内容以及对提示词的结构进行分析,再基于分析结果形成整体方案,然后根据实际案例评估效果,最后总结后续探索方向。

二、实现思路

本章节主要描述了对于AI Coding的目标制定工具选择以及代码生成的思路,最后根据上述内容设计了一套基于CodeFuse + prompt 的AI Coding 操作流程

2.1目标

本次使用AI Coding的目标,是打造一套通过CodeFuse 完成从系分到代码,再通过MCP Server接入系统知识库检查代码规范及质量的标准研发流程。

目标

描述

研发提效

为开发同学减负,提高整体研发效能,做到减少编码阶段40%人日

设计即生产

系分即代码。从系分出发,直接生成JAVA代码

规范基因化

通过AI结合开发规范实现代码命名、层次、调用关系,减少人为代码风格不统一,从根源保证应用代码规范

开发者体验友好

打造直观易用的开发者体验,让工具成为得心应手的助手而非负担

2.2现状分析

当前对于推广团队所有人都使用AI工具还是存在一些难度的,主要在于以下几点:

1.普及难度多数同学更喜欢使用IDEA开发JAVA代码,对于一个小几十人的团队,让每个人都一直根据最新调研内容不断更新工具来开发,很难普及。

2.操作难度如果使用AI工具时,手工操作和写提示词的时间不亚于写代码的时间,并且后续准确度不高、人工检查修改的成本更高的话,那这的东西的普及就会变得更加困难。

3.AI信任度部分同学对于AI生成代码仍无法信任,操作方式、产出结果需要为团队同学建立信任感,所以需要该工具的功能一致迭代且一直接入新的大模型,以防变成内部一次性产品。

2.2.1工具选择

今年3月,看到了很多CodeFuse IDEA插件的推广,使用感觉具备一些基础功能且会一直接入新的大模型。由此考虑从CodeFuse开始调研,除非出现其他比其优秀很多的插件外,不更换工具的使用。经过CodeFuse的多次迭代,我对除了所有工具都有的agent模式外的,其中三个功能非常喜欢:

a.文本绘图提取

CodeFuse IDE 对语雀文档中文本绘图(SVG图片)的读取及文字提取。

b.manual模式

CodeFuse IDEA插件的manual模式。

对于明确任务的执行速度更快且没有过多思考,十分节约时间。

c.自定义指令

CodeFuse IDEA插件的自定义指令。

减少每次生成测试时,复制一大堆文字的麻烦,复制一大堆文字再次输入的麻烦。

2.2.2生码范围及顺序

当前基于团队内部核心应用的代码架构来进行代码生成,针对此应用及多数JAVA业务系统的架构设计,个人认为对于部分强业务属性的JAVA应用,都是对外提供接口能力,这些接口能力是对下游等外部能力进行调用和流程串联编排,最后整合结果返回给上游。针对以上逻辑对一个JAVA应用的构成部分简单分为以下三个部分:门面层能力、外部能力以及业务逻辑

下图为应用结构的简单图示:

manage层为该应用独特的整合业务逻辑的层级,与其他应用的Service、Processor等相似,这里主要体现该层为业务逻辑编排层。

其他层级结构暂不考虑,例如定时任务、灰度开关等变更次数少且比较定制的代码。

代码生成顺序为:首先根据接口文档生成门面层内容,再通过表结构设计将持久层内容以及DB服务层生成好,然后将剩余的外部能力代码准备好(例如一些下游client、缓存、消息等),最后生成业务逻辑串联所需外部能力,并衔接门面层对业务逻辑层的调用,将流程整体串联。

2.2.3流程设计

1.数据来源

读取系分提取其中核心/生码必备内容,包括接口定义全部内容、数据表结构以及流程图/时序图。在提取出所有内容后,会根据提取出的内容来生成代码生成任务,最后来进行代码生成。

2.操作流程

对于一个应用来讲,不同模块的代码结构都有自己规范和约束,使用一份通用的提示词来生成所有模块内容肯定是暂时无法实现的,所以这里一定是需要根据不同模块来开发不同的生码提示词,不同模块的提示词的结构和组成内容是不同的。

以本文为例,我将整体拆成了三个部分,所以我需要开发三个提示词来用于生成这三个模块的代码。

简单来讲,就是这样:

展开一点的话,是这样:

流程图增强会在后面提到

三、提示词设计思路

本章节主要描述了对于上章节中提到的各个提示词的开发思路以及具体内容。

其中包括了:系分任务拆分提示词、流程图内容增强提示词、门面层代码生成提示词、持久层代码生成提示词以及业务逻辑代码生成提示词。

3.1系分任务拆分

这块相对简单,主要是读取文档->检索到目标位置->内容提取->按照任务模版生成任务列表

下面是使用系分任务拆分提示词时需要注意的点:

  • 系分模版系分内容提取需要制定系分模版,明确门面层接口定义、数据表结构以及每个接口的流程图的位置和标题

  • 变更类型核心内容需要标注出当前内容为新增还是修改

  • 物料格式内容提取提示词中需要包括每个模块的物料的提取描述、约束以及输出格式。将系分核心内容提取出。

  • 任务格式制定任务模版,让其在读取完物料内容后,根据已提取的物料内容的模块类别以及变更类型来生成任务列表。其中任务内容中,包括了任务需要引用物料区的哪些内容,以及任务执行的描述

这里简单描述下提示词样例以及产出样例

由于每个团队系分模版可能目录结构和内容都不同,所以这里仅做样例说明,使用时需要自行调整内部目录内容及约束。

接口内容提取提示词样例

# 接口清单
## 3.4 对外接口设计
检索当前章节下的所有内容,对其中的接口进行提取,再根据文档内容生成每个接口的以下信息:
要求:
- **禁止**遗漏接口数量
- **禁止**遗漏接口内容
- **强制**全量接口的全量接口信息都提取出来
- **强制**当不同接口之间存在重复内容时,也要在每个接口的物料内容中,把重复内容的明细全量列举出来
- **强制**将提取出来的内容按照以下‘输出模版’的格式写入到‘任务列表.md‘中
### {接口名称}
#### 接口信息
- 接口描述:{接口描述}
- 服务路径:{接口全限定类名}
- 请求参数:{参数名称}
  - 参数结构:
  {转换为markdown表格}
- 返回结果:{结果名称} 
  {转换为markdown表格}
- 内部嵌套模型/二级模型{模型名称}
{转换为markdown表格}

任务提取提示词样例

## 第二步:生成任务列表
1. 在app/全流程内容/目录下创建Todo_Task_list.md并按照以下结构提取文档内容:
2. 生成持久层任务,参考下面的持久层能力文本生成持久层能力任务。
3. 生成门面层任务...
# 持久层能力
遍历物料文档"数据表清单"章节,为每个数据表生成以下内容:
## 任务{n} :创建{表名称}持久层
### 物料引用
> Todo_Task_List.md#数据表清单#{表名称}
### 任务内容
根据物料引用的内容,读取到相关物料内容,并按照app/全流程内容/持久层代码生成提示词.md中的内容生成代码,不要新增内容,也不要省略内容。

产出结果案例

!!!!**以下内容为提取结果的举例,其中表结构信息为AI虚拟构造,此处仅为表现提取后文本格式**!!!!

数据表清单

user

字段名       数据类型 长度 约束                   默认值   说明                
id           BIGINT   -   PRIMARY KEY, AUTO_INCREMENT   - 用户唯一ID          
username     VARCHAR 50   UNIQUE, NOT NULL               - 用户名(唯一)      
password     CHAR     64   NOT NULL                       - SHA-256加密的密码  
email       VARCHAR 100 NOT NULL                       - 邮箱地址            
age         INT     -   CHECK (age >= 0)               NULL 年龄(0-255)  
gender       ENUM     -   -                             ‘unknown’ 性别      
created_at   DATETIME -   NOT NULL         CURRENT_TIMESTAMP   账户创建时间    
balance     DECIMAL 10,2 NOT NULL         0.00               账户余额        
last_login   TIMESTAMP -   -               NULL               最后登录时间    

接口清单

用户流程接口

用户创建

接口信息

  • 接口描述:用户创建

  • 服务路径:com.xxx.appname.facade.api.user.UserFacade#userCreate

  • 请求参数:UserCreateRequest
      - 参数结构:
      
    | 参数名 | 参数描述 | 数据类型 | 是否必填 | 长度 | 备注 |
    |-------|---------|---------|--------|------|------|
    | username | 用户名   | String | 是    | 64  |      |
    | password | 密码    | Strin g | 是    |    |       |
    | age      | 年龄    | int    | 是     |    |       |
    | gender   | 性别    | String | 是    |    |    |
    | UserCertModel| 用户信息模型  | String | 是    |  |    |

  • 返回结果:UserCreateResult
    | 参数名 | 参数描述 | 数据类型 | 是否必填 | 长度 | 备注 |
    |-------|---------|---------|--------|-----|-----|
    | status| 状态    | String   | 是     |      |      |

内部嵌套模型 UserCertModel

参数名 参数描述 数据类型 是否必填 长度 备注
certType 证件类型 String    
certName 证件名称 String    
certNo 证件ID String 64  
certValidDate 身份证有效期 String 128  
certNation 身份证民族 String 32  
certAddress 身份证地址 String 1024  
email 客户电子邮件 String    
birthDate 出生日期 String    
nationality 客户国籍 String    
certDocumentNo 证件号 String    

任务列表

持久层能力

任务1:创建user持久层

物料引用

> Todo_Task_List.md#数据表清单#user

任务内容

根据物料引用的内容,读取到相关物料内容,并按照app/全流程内容/持久层代码生成提示词.md中的内容生成代码,不要新增内容,也不要省略内容。

任务3:实现初审申请往报接口

物料引用

> 包含:
> - 接口信息:初审申请往报
> - 接口定义:com.xxx.appname.facade.api.user.UserFacade#userCreate
> - 请求/响应结构:UserCreateRequest/UserCreateResult
> - 内部嵌套模型:UserCertModel
> - 执行流程描述:无

任务内容

根据物料引用的内容,读取app/最新版汇报内容/接口层代码生成提示词.md,将其中接口定义按照要求生成相关全量代码。

这里任务中主要包括两部分:物料引用内容和任务执行描述。其中物料引用内容为执行本次任务需要引用哪些物料区的路径。

3.2门面层代码

门面层内容中主要包括接口定义及实现、出入参数及二级模型的定义

在当前应用中,变更类型无非定义新接口/修改原内容,然后在接口实现里面facade的实现类,facade实现类内容因为每个接口的实现都是套用服务模版然后调用下游,所以所有接口的门面层的结构差不多,比较模版化。

对于这种每次生成的结果需要保持一定格式的,增加一些输出格式模版或者参考案例,有助于提升结果准确度。尤其对于这种接口定义类的代码生成,效果尤为明显。

下面还是对提示词的具体组成。对于多数提示词而言,角色定义、核心职责、规则以及任务指令是常用内容,代码路径说明是对于代码生成所增加额外的定制内容,这里重要的点在于代码案例参考,在案例中添加符合规范的代码结构、命名风格等内容,使在生成的源头上就是符合系统风格的代码。

当然,这里提示词虽然说明了优势和痛点解决,只是说在一定程度上能够保证质量和解决一些问题,而不是说100%的能够达到预期效果。大模型丢失内容是比较常见的事情,结果会出现随机性。

3.3持久层代码

外部能力包括DB、下游提供包后的client、msg等其他内容。

主要实现DB操作的代码生成该部分在本应用结构也比较清晰,从Service到Repo再到Mapper,也比较模版化。其他部分不同应用间差异过大,且过于定制化,暂不考虑生成。

持久层代码代码生成的提示词的思路是与门面层代码生成的提示词相似,组成结构也比较相似。但是不同点在于,我们通过表结构生成了DO类后,是需要基于表结构生成SQL以及Mapper、Repo、Service方法的。包括增删改查以及一些其他新增的方法。这里只做了基础CRUD的方法生成,自定义方法可以参考门面层代码生成。

唯一的区别是在案例中添加了基础的CRUD方法,然后让每次生成代码的时候,都让大模型参考已有案例结构,也生成该表的除了Service、Repo、Mapper以及实现类/xml,还有model、DO及其转换类外的基础CRUD的方法。

3.4业务逻辑代码

根据上面的描述,我将代码分为了三层。因为门面层代码以及持久层相关代码是比较模版化的,让大模型读取提示词然后在根据接口文档/表结构来生成模版化的代码是可行的。重点是如何通过时序图来生成代码?翻阅了一下目前团队内外的系分文档中的时序图,发现质量参差不齐,多数都是使用白话进行描述,少有很严格的规范,这就对业务逻辑生成增加了很大的难度。

参考学习了一些案例,发现很多业务逻辑生成案例中,对于逻辑的描述都是无比详细的,甚至连import什么包都要把全限定类名手写到提示词或者流程图里面。个人觉得不妥,引发了几个思考:

1.AI Coding的使用是为了什么,方便开发同学提效,还是仅仅为了把代码生成出来证明AI可行?每次写代码前写很多详细的定制内容是否降效?

2.过于详细的提示词是否是限制了大模型的能力?

3.是否应该抽象出对于该应用的应用/模块提示词,让其可以拆分系分后,让不同模块的内容使用该模块的提示词,直接生成出代码,而无需每次需求都人工介入专为系分写很多定制提示词或业务流程描述。

针对以上几点,认为应该往以下方向发展:

1.尽量减少AI Coding对原研发流程的侵入,减少系分阶段对AI Coding所需内容的准备时间。

2.部分写提示词会花费很多时间的内容,选择使用大模型能力推理或者人工完成。

3.针对应用架构和系分内容,开发多个提示词。让每个提示词专门针对系分某一块内容来直接生成带有系统规范的代码。

下面针对以上三个方向,针对业务逻辑代码有了以下几个处理方式:

3.4.1流程图增强

为解决AI无法明确要做什么以及不知道代码引用来源、以及减少系分阶段绘制详细流程图的时间,考虑首先对白话版流程图进行翻译增强,将白话文流程图转化成中文伪代码。这种方式可以使流程图中涵盖更多关于应用内代码结构的信息,从而在生成代码是可以直接将中文伪代码转化成JAVA代码,或者能够通过流程描述知道自己要去哪里检索引用的代码。

目前团队内部使用的流程图都是语雀自带的PlantUML语法文本绘图。

随便找了个流程图举个例子,这类使用PlantUML语法的流程图中会包括一些简单的语法包括if-else、loop等,并且也会有‘->’这类调用关系,以及这类调用关系的描述。

以下图片案例为大模型生成:

这里就会发现一个问题:流程图过于白话,大模型很难直接了解如何生成代码,例如:

语义模糊‘查询用户名’ -- 去哪个表查询?用户名具体是哪个字段?用什么查?AI无法明确知道要做什么,以及来源是哪里。

描述省略:‘模型赋值’-- 很多模型字段多,几十个字段赋值都要写在流程图或者提示词里面?并且精准的说明来源,在实操落地上面来看不现实,人工成本过高,高速迭代的模式下无法实现。

根据流程图将左侧的这些文本,转化成代码能够读懂的中文伪代码,供agent结合提示词来进行代码生成。

对于伪代码生成,主要分为以下几步:

  • step 1 :定位流程起止位置,提取目标流程

根据PlantUML中的语法,对每个“上游指向当前应用为开始,当前应用返回结果给上游为截止”,提取其中流程作为内容的输入。

如果把所有流程的流程图画在一起了需要此步骤进行拆分,如果一个接口一个流程图则无需这个步骤。

  • step 2:图形语法解析,转译图形语言

整理匹配规则,将流程图中的PlantUML语法进行匹配,转化为java语法的伪代码,作为代码转化第一步,主要是拆分出if-else、嵌套方法等,完成初步映射。

对于PlantUML的语法转成java语法相对简单,无非alt转if-else,loop转for循环。

  • step 3:逻辑步骤解析,生成中文代码

流程图中的每一步的结构都是“调用方 -> 被调用方”, 调用方都是我们开发的当前应用,需要根据被调用方 + 后面的中文描述,来选择生成内容。类似分支/漏斗规则,将中文描述通过描述进行模糊匹配,然后来生成伪代码,所以此处需要设置匹配代码规则。

这一步是整体最重要的一步,因为它决定了最终代码生成的准确性。这里制定匹配规则,来对流程图中的每一步进行规则匹配匹配到规则的流程,会转化成伪代码,对于没有匹配到规则的流程,则会增加一些帮助引导大模型推理的描述

这就引发了两个问题:1. 如何制定匹配规则?2. 如何增加引导大模型的描述。

1.如何制定匹配规则?

对于业务流程中的规则匹配,首先需要总结当前应用在业务流程中,会涉及哪些操作(即ava常用语法和外部能力调用),在当前应用中,我总结了大约十几种,包括:网关调用、DB调用、转化类调用、SPI调用、内部组件调用、类内方法调用、日志打印、异常捕获、断言检查、字段定义、模型赋值、基础java语法(if-else、switch)等。并对其中的网关调用、DB调用、日志打印、断言检查、SPI调用、模型组装进行了匹配规则制定。

主要思路是,根据流程图的内容来匹配调用场景,根据不同的场景去代码里面检索相关内容,然后将其中内容经过一次增强后,添加到新流程图中,使得新流程图是包含准确代码引用的伪代码。

2.如何增加引导大模型的描述

对于一些无法描述清晰的内容,例如‘模型组装’、‘字段赋值’,都需要给大模型一个明确的步骤,使其能够按照步骤来推理,保证方向正确。

  • step 4 :整合全部内容,形成完整流程

补充任务所需其他内容,包括任务模版中需要体现的代码修改的位置、路径、具体方法等。形成一个可以执行由大模型执行来生成代码的任务内容。

例子:DB操作流程图转化提示词

DB调用流程转化案例

# 3.2.2 开始解析引用关系,检索所有结构为‘userApp->>xxx'以及‘xxx-->>userApp‘的流程,根据xxx的值,进行分析。
## 2. **DB调用**
### 2.1 生成要求
    当流程中出现‘userApp->>DB: xxxx’流程,代表此处进行了userApp对于DB的某张表的增删改查操作,你需要按照以下步骤进行分析组装伪代码。
(1)在转换DB调用时:
  - **强制**使用实际存在的Service接口文件
  - **强制**使用文件中实际存在的方法名
  - **禁止**使用推测或翻译的方法名
(2)强制验证转化结果,转换完成后,必须:
  - 验证所有提及的类名是否存在于工程目录
  - 验证所有方法名是否存在于对应的Service接口中
  - 如发现不匹配,必须在输出中明确标注"未找到准确匹配,使用了最接近的方法:xxx"
   
### 2.2 转化流程
   案例分析如下,可按照案例分析来匹配到的流程。
   (1)将‘xxx'中的描述,翻译成英文,然后读取工程目录下com.xxx.userapp.module.core.domainservice中的所以java文件,根据英文描述匹配看是否有匹配文件。
   (2)如果有匹配项,再根据‘xxx’中的描述,翻译成中文,然后根据描述进行分词,解析出业务属性、操作类型、入参数。
   (3)根据业务属性翻译为英文,并检索语义匹配的服务,并选中其文件。
   (4)然后根据中涉及的参数以及想要执行的动作(新增/插入/查询/删除/更新)来模糊匹配是否存在可以直接使用的方法。
   (5)如果有可以直接使用的方法,则参考输出模版以下案例,将其构造成含有伪代码的描述。
    输出模版:
    ‘userApp->>DB: 使用@Autowired注入{匹配到的服务名称}的bean,然后调用{匹配到的服务}下的{匹配到方法名称}方法,如参数可以从方法上下文中找到,出参数为以方法的返回结果类型构造的一个新对象‘。
   
### 2.3 转化案例   
   以一个简单描述来举例,如果文本描述为‘userApp->>DB: 根据用户id,查询用户信息’。
   (1)流程描述分词为->根据/用户id/查询/用户信息。
   (2)其中’用户id‘,表示为调用DB服务的入参数;‘查询’表示操作类型;‘用户’代表业务属性。
   (3)首先根据业务属性,翻译为User/UserInfo等服务名称。
   (4)在com.xxx.userapp.module.core.domainservice下匹配到了UserService。
   (5)操作类型为查询,所以要匹配domainservice下匹配到了UserService中的query或者select为前缀的方法。
   (6)“根据用户id”,代表查询条件为用户id,翻译为userId。
   (7)根据(5)和(6)匹配到了UserService下的queryByUserId方法。
   (8)将‘userApp->>DB: 根据用户id,查询用户信息’,转化为‘userApp->>DB: 使用@Autowired注入UserService的bean,然后调用UserService下的queryByUserId方法,如参数可以从方法上下文中找到,出参数为以方法的返回结果类型构造的一个新对象‘。

根据以上方法,能够将“userApp->>DB: 根据用户id,查询用户信息“,转化为:”userApp->DB: 使用@Autowired注入UserService的bean,然后调用UserService下的queryByUserId方法,如参数可以从方法上下文中找到,出参数为以方法的返回结果类型构造的一个新对象“。使得大模型生成代码跟具有依据,也更加准确

例子:模型组装流程图转化提示词

模型组装

## 6. **模型组装**
### 6.1 生成要求
   如果出现:‘userApp->>userApp: 组装/构造xxx模型,并赋值‘ 这类进行模型组装操作时,按照以下流程进行转化增强

6.2 输出结果案例

   按照以下流程进行内容映射
  (1)将‘xxx’中的描述,翻译成英文,然后读取工程目录下com.xxx.userapp.module.core.model中的所以java文件,根据英文描述匹配看是否有匹配文件。
  (2)如果有匹配项,则获取被匹配项的全限定类名,例如:‘com.xxx.userapp.module.core.model.domain.UserCreateModel’
  (3)按照以下格式构造最终结果:‘userApp->userApp: 组装/构造xxx模型,根据被匹配项的全限定类名{被匹配项全限定类名},使用import 导入包。然后根据全限定类名读取此模型中所有字段,定义对象,最后通过代码生成规则和推理增强结合此模型中的字段,结合上下文中出现的其他模型及字段内容,进行模型字段赋值。

3.4.2推理引导

业务逻辑主要包含了java基础语法和外部能力的串联,定制化高,是最难攻克的一块,不过在流程图阶段,已经为生成结果的准确度已经做了一层提升,这里只需要做一些约束和推理引导,让最终结果变更更加准确。

对于部分业务逻辑,例如外部能力方法调用、定义一个某某对象,以及一些基础java语法(if-else、for循环)是通过流程图语法或者人为描述直白的了解其含义,并且流程步骤与代码有着一一映射关系。但是对于参数传递、参数赋值,很难逐字逐句的绘制在流程图中。考虑不为流程图绘制增加负担,以及考虑更好的使用大模型的能力,打算使用大模型的推理能力来生成流程图中的一些‘难以明确说明的步骤’。

当然,大模型进行代码生成时应该也有一些预制的代码推理能力,常用AI生成代码的同学应该遇到过因为约束过少或者流程描述不清的场景,会出现大模型生成很多乱七八糟的预期外的内容。为了防止它推理的不对、多了或者少了,所以我们要对其推理进行约束和限制,以及使用提示词进行推理方向的引导。在将流程图转化成伪代码后,一定会存在部分流程无法转化,例如含糊的表达了‘模型组装’以及‘字段赋值’,所以打算在一些无法通过白话简单精准的描述出来的步骤,让大模型去推理。

个人理解这种方式类似于一个小型RAG模式?

这里思路上比较抽象,以参数组装为例,如果我们组装一个结果对象作为当前方法的返回,这个结果对象的每个参数值都是由这个方法里面的一些外部能力调用的结果,所以这时就需要引导它执行以下步骤:

  • 首先定义结果对象,对结果对象中的所有字段进行赋值列举。

  • 阅读当前生成的所有代码,对调用下游获得的结果模型进行逐一读取。

  • 将结果模型的所有字段对下游结果模型中的字段进行命名匹配,获取字段赋值来源。

  • 对于无法获取来源的字段/类型类别字段/状态类型字段,检索当前工程的枚举/常量,根据命名匹配是否有可使用枚举/常量。

  • 对于最后还是无法获取到来源的字段,检索整个文件的内容,看是否有类似字段/其他字段的赋值方式学习,最后进行赋值。

  • 对于最后还找不到赋值的进行标注,最后人工添加。

这套流程看似只是一个流水似的引导描述,但是其实对于参数组装赋值这类操作,如果不约束不引导的话,它每次生成的结果都不一样,随机性很大。并且对于一些字段还可能出现“对不存在的字段赋值”,“对存在的字段赋不存在的值”。对我来讲大模型的生码的底层逻辑过于黑盒,仅凭不加引导和约束的推理,无法保证准确定。所以使用此类方法,整理业务逻辑中包含的场景,并为其制定推理思路,最后生成代码。

3.4.3以模块维度拆分提示词

这部分就是将不同的模块采用不同的提示词,来让每个地方的提示词更加聚焦。

这个是整体思路,不过多赘述。

3.4.4业务逻辑生成整体思路

四、实践:从系分到代码

本章节主要讲述在真实迭代中,对于以上AI Coding 流程的实际应用。

团队一般都有自己的系分模版,这里主要需要在系分中体现:数据表结构、接口文档、接口业务流程,以及这几个模块是新增还是变更,然后根据任务生成提示词即可。这里对系分没有整体要求,只要存在这几个单独的模块即可。

这里分为提前储备以及手动操作流程两部分:

预备内容:

a.将各模块的提示词都放到工程目录下。

b.准备操作描述,并放到CodeFuse的自定义指令中。

操作流程:

a.完成系分的撰写,其中包括本次迭代中涉及的接口定义、表结构定义、接口流程图。

b.使用CodeFuse IDE读取系分文档并提取其中核心内容,并结合提示词,对本迭代需要做的事都转化为任务,生成任务列表.md。(其中包括物料提取、任务生成、流程图增强等)

c.通过CodeFuse IDEA插件快捷指令,让agent去读取任务列表中的内容,然后再通过任务描述中的内容去检索完成任务所需要的提示词以及系分中物料内容,来执行任务。然后通过与agent的对不满意的地方进行修改(若需)。

d.压缩上下文/开启新会话,继续执行下一个任务,直至所有任务完成。

4.1步骤一:任务生成

这里使用CodeFuse IDE,第一步任务生成的目标是读取系分中的,提取其中的数据表结构、接口文档以及接口业务流程,作为物料内容,然后在基于物料内容的类别及变更类型,生成任务。

4.1.1生成结果

简单案例

!!!!**以下内容为提取结果的举例,其中表结构信息为AI虚拟构造,此处仅为表现提取后文本格式**!!!!

数据表清单

user

字段名       数据类型 长度 约束                   默认值   说明                
id           BIGINT   -   PRIMARY KEY, AUTO_INCREMENT   - 用户唯一ID          
username     VARCHAR 50   UNIQUE, NOT NULL               - 用户名(唯一)      
password     CHAR     64   NOT NULL                       - SHA-256加密的密码  
email       VARCHAR 100 NOT NULL                       - 邮箱地址            
age         INT     -   CHECK (age >= 0)               NULL 年龄(0-255)  
gender       ENUM     -   -                             ‘unknown’ 性别      
created_at   DATETIME -   NOT NULL         CURRENT_TIMESTAMP   账户创建时间    
balance     DECIMAL 10,2 NOT NULL         0.00               账户余额        
last_login   TIMESTAMP -   -               NULL               最后登录时间    

接口清单

用户流程接口

用户创建

接口信息

  • 接口描述:用户创建

  • 服务路径:com.xxx.appname.facade.api.user.UserFacade#userCreate

  • 请求参数:UserCreateRequest
      - 参数结构:
      
    | 参数名 | 参数描述 | 数据类型 | 是否必填 | 长度 | 备注 |
    |-------|---------|---------|--------|------|------|
    | username | 用户名   | String | 是    | 64  |      |
    | password | 密码    | Strin g | 是    |    |       |
    | age      | 年龄    | int    | 是     |    |       |
    | gender   | 性别    | String | 是    |    |    |
    | UserCertModel| 用户信息模型  | String | 是    |  |    |

  • 返回结果:UserCreateResult
    | 参数名 | 参数描述 | 数据类型 | 是否必填 | 长度 | 备注 |
    |-------|---------|---------|--------|-----|-----|
    | status| 状态    | String   | 是     |      |      |

内部嵌套模型 UserCertModel

参数名 参数描述 数据类型 是否必填 长度 备注
certType 证件类型 String    
certName 证件名称 String    
certNo 证件ID String 64  
certValidDate 身份证有效期 String 128  
certNation 身份证民族 String 32  
certAddress 身份证地址 String 1024  
email 客户电子邮件 String    
birthDate 出生日期 String    
nationality 客户国籍 String    
certDocumentNo 证件号 String    

任务列表

持久层能力

任务1:创建user持久层

物料引用

> Todo_Task_List.md#数据表清单#user

任务内容

根据物料引用的内容,读取到相关物料内容,并按照app/全流程内容/持久层代码生成提示词.md中的内容生成代码,不要新增内容,也不要省略内容。

任务2:实现初审申请往报接口

物料引用

> 包含:
> - 接口信息:初审申请往报
> - 接口定义:com.xxx.appname.facade.api.user.UserFacade#userCreate
> - 请求/响应结构:UserCreateRequest/UserCreateResult
> - 内部嵌套模型:UserCertModel
> - 执行流程描述:无

任务内容

根据物料引用的内容,读取app/最新版汇报内容/接口层代码生成提示词.md,将其中接口定义按照要求生成相关全量代码。

4.2步骤二:门面层代码生成

后面的步骤就是用CodeFuse 的IDEA插件。

在上一阶段中,已经生成了门面层代码生成的任务,所以此处只需要将任务执行描述放到CodeFuse的自定义指令中即可,虽然当前的操作还是需要一些人工输入,但是后面考虑可以在任务列表中新增一个执行状态,然后使用通用的任务执行描述,让其先扫描任务状态,然后再考虑执行哪个任务。

在前期尝试过这个方式,但是经常出现篡改任务列表中其他内容、执行完未更新等各种各样的问题,所以考虑还是人工选择执行哪个任务。后续等待工具或模型能力更新后,再换回此方式。

4.2.1提示词结构

下面主要分为两个场景,新增接口和修改原接口,原本打算使用一个提示词来兼容执行两种动作,但是发现效果并不好,所以拆开成两个提示词。

门面层代码生成提示词结构(未携带具体内容):

# 1. 角色定义 (Role Definition)
你是一位精通xxx应用架构的代码生成专家。你深刻理解其分层设计(Facade, Service, Manager, Core-Model),熟悉 `Sofa RPC`, `Spring Framework`, `Lombok`,并严格遵循内部的编码规范和固定骨架。

2. 核心职责 (Core Responsibilities)

你的核心任务是根据系统分析文档(系分)中的接口定义,生成一套完整、合规、可立即投入生产的业务代码。
后续为消除幻觉或应用定制化的约束内容

3. 生成规则 (Generation Rules)

在生成代码时,必须遵循以下具体规则:
1. 嵌套模型处理规则 (Nested Model Handling):
2. 枚举处理规则
3. Converter 转换逻辑:
[强制] 辅助方法生成规则:
4. 固定 Bean 注入:

4. 代码生成指令 (Code Generation Directives)

现在,请根据 [新的接口定义] 生成以下所有代码文件:
重要提示:
** 以下是 
【完整】 且 【正确】** 的 LendApplyFacade 接口生成案例。所有新代码都必须严格遵循此结构、命名、注解和代码风格。
** 在生成代码时,要参考下面的案例来生成。

1. Facade 接口 (**XXXXFacade.java**):
2. Facade 接口的 Request/Result 类:
3. Facade 实现类 (**XXXXFacadeImpl.java**):
4. Facade 层 Converter 类 (**facade.converter.XXXXConverter.java**):
5. **Enum.java** **的增量修改:
6. Manager 接口 (**XXXXManager.java**
):**
7. Manager 接口的 Request/Result 类:
8. Manager 层 Model 类 (**XXXXModel.java**):
9. Manager 实现类 (**XXXXManagerImpl.java**):
10. Manager 层 Converter 类 (**domainconverter.XXXXConverter.java**):

门面层代码修改提示词:

# 1. 角色定义 (Role Definition)
你是一位精通当前应用架构的代码生成专家。

2. 核心职责 (Core Responsibilities)

- 你的核心任务是根据系统分析文档(系分)中的接口定义,分析其中变更点,并根据变更点生成对应的代码。
- **[强制执行]**具体职责

3. 生成规则 (Generation Rules)

在生成代码时,必须遵循以下具体规则:
1. 嵌套模型处理规则 (Nested Model Handling):
2. Converter 转换逻辑:

4. 代码生成指令 (Code Generation Directives)

  - 读取任务列表及其接口定义内容,根据其中内容对比涉及接口的需要新增的字段,然后将涉及的接口的出入参数以及下面所有涉及的调用的地方,都新增表格中新增的字段。
  - 只需要在’生成范围‘中的模块中生成代码,其他模块不需要修改。
  - 生成范围 :
  -(1) Facade 接口的 Request/Result 类:
  -(2)Manager 接口的 Request/Result 类:
  -(3)Facade转换类
  -(4)Domain 类:
  -(5)Manager转换类
  -(6)模型转换类

4.2.2生成结果

这是还没使用自定义指令做的,使用manual模式,一次新生成了12个java文件,总计约1200行代码耗时约5-10min,并且全部采纳且无编译错误

大模型生成还是有一些随机性,并不是说每次都能达到完美效果。不过对于这类模版类生成,多数都不会有什么大问题,基本10次生成、3次完全采纳、6次需要简单调整、1次直接废弃(偶尔大模型抽风)。

如果算上人工检查核对以及修改小问题(若有)的时间,总计半小时应该也够了。如果人工开发,可能定义12个文件,5分钟就过去了。

4.3步骤三:持久层代码生成

这里操作的步骤同上。

4.3.1提示词结构

其实持久层代码生成提示词和门面层的内容是大致相同的,只不过放置的结构有所调整,这也是在测试两种方式。一个是在执行步骤中添加案例来生成代码;另一种是在提示词中提前告知案例,然后生成代码时让它去参考案例。感觉两种方式结果差不多。

提示词也是两类,新表内容生成和原表内容变更提示词(一般表接口不允许删除或变更字段,这里只考虑新增)。

持久层代码生成提示词结构:

## 1. 角色定义 (Role Definition)
你是一位资深Java后端工程师,精通基于领域驱动设计(DDD)分层思想的微服务开发。你将为应用进行代码生成,该应用采用 Spring Boot 和 MyBatis 技术栈,并严格遵循既定的分层架构和编码规范。

2. 核心职责 (Core Responsibilities)

[核心任务] 解析外部SQL并生成代码:你将接收一个包含CREATE TABLE语句的SQL文档。你的任务是自动解析该文档,并基于解析出的表结构,生成从数据访问层(DAL)到领域服务层(Service)的全套Java代码和MyBatis XML文件。

3. 分层与契约规则 (Layering & Contract Rules)

代码生成需遵循三层结构,各层职责和数据模型转换关系如下:

1. DAL (数据访问层)
2. Repository (仓储层)
3. Domain Service(领域服务层)

4. 案例参考 (Reference Examples)

以下是基于user表生成的User相关完整代码示例,请严格参照其结构、命名和实现方式。

5. 代码生成指令 (Code Generation Directives)

1. [输入解析]  
你将收到一份SQLCREATE TABLE语句。请首先执行以下解析任务:
提取表名:
推导模块名
识别主键
解析所有字段

2. [生成步骤]  
根据上述解析结果,严格按照以下顺序和规则生成所有文件:

生成 DAL 层:
生成 Repository 层:
生成 Domain Service 层:

6. 代码路径说明 (Output Path Specification)

请将生成的所有文件严格放置在以下对应的路径中。(注意:路径中的业务属性名称部分应根据解析出的{ModuleName}动态替换)

DAL 层所有代码路径:

持久层代码修改提示词结构:

# 1. 角色定义 (Role Definition)
你是一位精通 应用架构的代码生成专家。

2. 核心职责 (Core Responsibilities)

- 你的核心任务是根据系统分析文档(系分)中的表结构信息,分析其中变更点,并根据变更点生成对应的代码。

3.生成规则

1. 仅新增字段
2. 类型映射
3. 禁止对生成范围外的代码进行代码生成。
4. 字段匹配规则
5. 字段新增要求
6. 文件匹配
7. Mapper内容新增
8. 数量精准

4. 执行步骤

- 1. 读取任务中的表结构信息。
- 2. 根据表结构信息,根据名称匹配是否有DO类。
- 3. 分析表定义与已有DO类中差异的字段。
- 4. 总结新增字段,准备进行代码生成。
- 5. 全部代码生成结束后,检查所有生成的代码是否编译通过。
- 6. 结束任务

4.3.2生成结果

这是还没使用自定义指令做的,使用manual模式,一次新生成了12个java文件,总计约700行代码耗时约5-10min,并且全部采纳且无编译错误

4.4步骤四:业务逻辑生成

4.4.1提示词结构

这里主要分为两部分提示词,一部分为流程图增强,一部分为业务代码生成。流程图增强的定位比较暧昧,既可以当作任务生成的一部分,又可以当作业务逻辑生成更加准确的前置流程,所以放在这里一并说明了。

流程图增强的提示词,主要是考虑将流程图转化为中文伪代码。

流程图增强提示词结构:

# 1. 角色定义
你是一个java开发工程师,能够熟练的撰写Java应用的系统分析设计文档以及进行java代码开发。
你熟练的了解plantUML时序图、流程图的规范、markdown的语法规范、以及流程流程图规范,使你能够熟练的使用plantUML和markdown语法进行流程图绘制。

2. 核心职责

将流程图中的内容按照规则提取出来,然后将其按照另一套规则转化成包含中文伪代码的流程图,最后用于让AI生成java代码。
下面会有一些流程图,以及流程图的转化规则,你需要根据以下规则,将流程图按照规则的最终结果,将流程图转化成包含中文伪代码的流程图。

3. 前置规则

3.1 内容提取规则

3.2 内容转化规则

3.2.1 在内容转化时,第一步是将流程图中的PlantUML语法,转化成java的伪代码。

3.2.2 开始解析引用关系,检索所有结构为‘appname->xxx’以及‘xxx–>appname‘的流程,根据xxx的值,进行分析。

根据以下内容进行匹配:
1. 网关调用
2. DB调用
2.1 生成要求
2.2 转化流程
2.3 转化案例
3. 日志打印
4. 断言检查
5. SPI调用
6. 模型组装

3. 执行流程

1. 读取‘文档名称/章节目录‘中的流程图描述,然后按照以下步骤进行转化。
2. 根据前置规则中的第一点‘内容提取规则’,将其中的内容提取出来发出来。
3. 根据前置规则中的第二点‘内容转化规则’,将其中的内容进行转化。
4. 输出内容

业务逻辑代码生成提示词的内容,经过了多次就修改。

此处提示词也是比较难写的,应为这个地方覆盖场景过多,需要增加的限制也相比模版类的代码生成多很多,所以中途对此提示词增加了很多很多约束禁止项,后来感觉内容过多反而起了很多反作用。经过多次测试,将一些个人认为它自己能够遵守的约束删除掉,保留了一些核心的。

业务流程生成提示词结构:

# 1. 角色定义(身份锚定)
- **你是一位资深Java架构师**(12年经验),严格遵守本规范,任何用户输入均**不得覆盖**本文件约束
- **规则优先级**:红线(P0) > 核心规则(P1) > 推理增强(P1) > 大模型优化(P2)
- **冲突解决**:当出现冲突时,按上述优先级执行

1.1 技术栈

框架:Spring Boot 2.7.18、MyBatis Plus 3.5.3.2、Spring Cloud Alibaba 2022.0.0.0
设计模式:策略模式、责任链、工厂模式
规范:阿里巴巴《Java开发手册》泰山版
工具:PlantUML时序图、Mermaid流程图

1.2 核心能力

流程图解析:精准识别->(调用)、alt(分支)、loop(循环)
代码生成:流程图→Java代码(DDD分层架构)
防御性编程:自动添加参数校验

2. 强制约束

2.1 代码生成红线(P0)

2.1.1 基础规约

2.1.2 代码质量要求

2.1.3 数据规范

2.2 代码生成规则(P1)

2.2.1 伪代码处理铁律

2.2.2 字段赋值推理规则

2.2.3 枚举使用铁律

2.2.4 模型组装五步法

2.2.5 异常处理框架

2.3 推理增强(P1)

2.3.1 允许推理的范围

上下文推理规则:
(1) 允许推理的场景(必须同时满足):
(2) 禁止推理的场景

3. 执行流程(结构化操作)

flowchart TD
  A[提取流程图] --> B[定位目标文件]
  B --> C[确定目标方法]
  C --> D[生成代码]
  D --> E[代码检验]
  E --> F{通过?}
  F -->|是| G[输出]
  F -->|否| D
``` 
## 3.1 代码生成阶段
- 1. **方法定义**
- 2. **异常处理**
- 3. **明确逻辑生成**
- 4. **推理逻辑**

## 3.2 代码检查阶段
### 3.2.1 结果自检(强制输出)

### 3.2.2 修正规则

### 3.2.3 编译检查黄金法则(零容忍执行)
#### 强制触发条件
#### 验证执行标准
</code></pre>
  </div>
 </div>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-25>4.4.2生成结果</span></span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>因为对于流程图的转换还是需要对流程图提出一些约束的,例如部分场景需要以某种方式来绘制,本方案是近几天刚落地的,之前的流程图都没有按照此约束来绘制,所以这个案例是我自己绘制的包含了当前的外部能力调用以及一些基础JAVA语法的流程图。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>这里使用CodeFuse IDEA的插件的agent模式,首先对提取出来的流程图进行增强,然后直接结合提示词进行代码生成。(此处并不是一个逻辑十分标准的业务逻辑时序图,这里只为体现流程图了包含了一些基础的java语法,以及使用了当前应用的能力)</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>从系分中提取的流程图案例</span></span></span></p>
 <div data-wct-cr-12>
  <div>
   <pre><code>```mermaid
sequenceDiagram
&nbsp; &nbsp; participant Upper-level application&nbsp;as&nbsp;ua
&nbsp; &nbsp; participant userApp
&nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; ua-&gt;&gt;userApp: 用户状态查询
&nbsp; &nbsp; alt 方法入参数中的请求信息字段不为空
&nbsp; &nbsp; userApp-&gt;&gt;spi:获取锁
&nbsp; &nbsp; alt 获取到锁
&nbsp; &nbsp; userApp-&gt;&gt;db: 根据用户id,查询用户信息
&nbsp; &nbsp; userApp-&gt;&gt;userApp: 判断用户信息是否为空
&nbsp; &nbsp; alt 用户信息为空
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;userApp: 打印日志,用户信息信息为空
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;userApp: 构造用户信息领域模型
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;db: 保存用户信息
&nbsp; &nbsp;&nbsp;else&nbsp;用户信息不为空
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;db: 根据状态‘初始化’查询用户信息列表
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;userApp: 判断用户信息列表是否为空,错误描述为:无初始化用户信息
&nbsp; &nbsp; &nbsp; &nbsp; loop 遍历查询结果列表
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; alt 用户状态为已创建
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 结束流程
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;end
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;end
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;userApp: 遍历查询结果列表,过滤出状态为创建中的用户信息
&nbsp; &nbsp; &nbsp; &nbsp; userApp-&gt;&gt;userApp: 打印错误日志,用户创建信息已存在
&nbsp; &nbsp;&nbsp;end
&nbsp; &nbsp;&nbsp;end
&nbsp; &nbsp; userApp&nbsp;-&gt;&gt;&nbsp;iopengw: 调用超网
&nbsp; &nbsp;&nbsp;end
&nbsp; &nbsp; userApp--&gt;&gt;ua: 返回用户创建结果

增强后的流程图

```mermaid
sequenceDiagram
    participant Upper-level application as ua
    participant userApp

    ua->>userApp: 用户状态查询
    if 方法入参数中的请求信息字段不为空
        userApp->>spi: 导入com.xxx.userapp.spi.LockSpi,并使用@Autowired注入LockSpi的bean,执行lock方法,得到’获取锁’的结果

        if 获取到锁
            userApp->>db: 使用@Autowired注入UserService的bean,然后调用UserService下的queryByUserId方法,参数为用户id,出参数为以UserInfoModel类型构造的一个新对象
            userApp->>userApp: 使用导入com.xxx.userapp.module.utils.AssertUtils,使用其中的方法,判断用户信息是否为空

            if 用户信息为空
                userApp->>userApp: LoggerUtil.error(LOGGER, e, “用户信息为空,用户Id={}.”, userId);
                userApp->>userApp: 组装/构造用户信息领域模型,根据被匹配项的全限定类名com.xxx.userapp.module.core.model.domain.UserInfoModel,使用import导入包。然后根据全限定类名读取此模型中所有字段,先new一个UserInfoModel对象,然后通过代码生成规则和推理增强结合此模型中的字段,进行模型字段赋值,设置userId、status、createTime、updateTime等字段
                userApp->>db: 使用@Autowired注入UserService的bean,然后调用UserService下的createUser方法,参数为构造好的UserInfoModel对象,出参数为boolean类型表示是否插入成功
            else 用户信息不为空
                userApp->>db: 使用@Autowired注入UserService的bean,然后调用UserService下的queryUserByStatus方法,参数为状态’初始化’,出参数为List<UserInfoModel>类型的新对象列表
                userApp->>userApp: 使用导入com.xxx.userapp.module.utils.AssertUtils,使用其中的方法,判断用户信息列表是否为空,错误描述为:无初始化用户

                foreach 遍历查询结果列表中的元素
                    if 对象状态为已创建
                        // 结束流程
                    end
                end

                userApp->>userApp: 遍历查询结果列表,过滤出状态为创建中的用户信息列表
                userApp->>userApp: LoggerUtil.error(LOGGER, e, “用户信息已存在, 用户Id={}.”, userId);
            end
            userApp->>spi: 导入com.xxx.userapp.spi.LockSpi,并使用@Autowired注入LockSpi的bean,执行unlock方法
            userApp ->> iopengw: getGwData(recordModel);
        end
    end

    userApp–>>ua: 返回用户创建结果

</code></pre>
  </div>
 </div>
 <p data-wct-cr-8><span data-wct-cr-26></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-10>代码生成结果:</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>在效果上,由于agent模式略耗时,所以整体生成时间约在</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>15min</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>左右,</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>生成代码100+行</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>平均采纳率90%</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,除个别场景对于参数组装、模型赋值无法100%达到生成预期,其他流程图包含内容生成结果基本符合预期。</span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>整体上看,不论是代码转化还是业务逻辑代码生成,其中的步骤及逻辑都是符合预期的。在多次生成测试中可能会出现:参数组装的推理过程中,每次的上下文获取内容不同;步骤偶现出现幻觉(无来源步骤)、丢失步骤;与其他也做业务流程生成的同学讨论过,“每次生成的内容略有不同,但是大致逻辑是正确的”这一场景普遍存在。所以,这两点可以通过多次生成来选择更符合预期的结果进行采纳,如果某一次经过简单调整就能符合预期,我认为就不必再生成第二次了。</span></span></span></p>
 </blockquote>
 <div data-wct-cr-12>
  <div>
   <pre><code>package com.xxx.userapp.service.handler.impl;

import&nbsp;com.xxx.userapp.spi.LockSpi;
import&nbsp;com.xxx.userapp.module.core.model.domain.UserInfoModel;
import&nbsp;com.xxx.userapp.module.service.UserService;
import&nbsp;com.xxx.userapp.module.utils.AssertUtils;
import&nbsp;org.slf4j.Logger;
import&nbsp;org.slf4j.LoggerFactory;
import&nbsp;org.springframework.beans.factory.annotation.Autowired;
import&nbsp;org.springframework.stereotype.Component;
import&nbsp;java.util.Date;
import&nbsp;java.util.List;
import&nbsp;java.util.stream.Collectors;
/**
&nbsp;*&nbsp;@author&nbsp;CoduFuse
&nbsp;*&nbsp;@version&nbsp;test.java, v 0.1 2025年09月25日 15:46&nbsp;
&nbsp;*/
@Component
publicclassUserStatusHandler {
&nbsp; &nbsp; privatestaticfinal&nbsp;Logger&nbsp;LOGGER&nbsp;=&nbsp;LoggerFactory.getLogger(UserStatusHandler.class);
&nbsp; &nbsp;&nbsp;@Autowired
&nbsp; &nbsp;&nbsp;private&nbsp;LockSpi&nbsp;lockSpi;
&nbsp; &nbsp;&nbsp;@Autowired
&nbsp; &nbsp;&nbsp;private&nbsp;UserService&nbsp;userService;
&nbsp; &nbsp;&nbsp;/**
&nbsp; &nbsp; &nbsp;* 用户状态查询处理流程
&nbsp; &nbsp; &nbsp;* 根据流程图实现完整的用户状态查询逻辑
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp;&nbsp;publicvoidprocessUserStatusQuery(String&nbsp;userId){
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 方法入参数中的请求信息字段不为空校验
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(userId ==&nbsp;null&nbsp;|| userId.trim().isEmpty()) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LOGGER.error("用户ID不能为空");
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 获取锁
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;boolean&nbsp;lockAcquired = lockSpi.lock(userId);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(!lockAcquired) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LOGGER.warn("获取锁失败, 用户Id={}", userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;try&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 查询用户信息
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;UserInfoModel&nbsp;userInfo = userService.queryByUserId(userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;AssertUtils.isNull(userInfo);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 判断用户信息是否为空
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(userInfo ==&nbsp;null) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 记录错误日志
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LoggerUtil.error(LOGGER,&nbsp;null,&nbsp;"用户信息为空,用户Id={}.", userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 构造新的UserInfoModel对象
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo =&nbsp;new&nbsp;UserInfoModel();
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo.setUserId(userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo.setStatus(UserStatusEnum.INIT);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo.setCreateTime(new&nbsp;Date());
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo.setUpdateTime(new&nbsp;Date());
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 可以设置更多字段根据实际业务需求
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 创建用户
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;boolean&nbsp;createSuccess = userService.createUser(userInfo);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(createSuccess) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LOGGER.info("用户创建成功, 用户Id={}", userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LOGGER.error("用户创建失败, 用户Id={}", userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 用户信息不为空,查询初始化状态的用户
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;List&lt;UserInfoModel&gt; initUsers = userService.queryUserByStatus(UserStatusEnum.INIT);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 判断用户信息列表是否为空
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;AssertUtils.notEmpty(initUsers,&nbsp;"无初始化用户");
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 遍历查询结果列表
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;(UserInfoModel&nbsp;user : initUsers) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(UserStatusEnum.FINISHED.equals(user.getStatus())) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 结束流程
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LOGGER.info("用户状态已创建, 用户Id={}", user.getUserId());
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 过滤出状态为创建中的用户信息列表
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;List&lt;UserInfoModel&gt; creatingUsers = initUsers.stream()
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(user -&gt;&nbsp;UserStatusEnum.PROCESSING.equals(user.getStatus()))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 记录错误日志
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LoggerUtil.error(LOGGER,&nbsp;null,&nbsp;"用户信息已存在, 用户Id={}.", userId);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;getGwData(recordModel);
&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;finally&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 释放锁
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lockSpi.unlock(userId);
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;/**
&nbsp; &nbsp; &nbsp;* LoggerUtil工具类用于日志记录
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp; publicstaticclassLoggerUtil {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;publicstaticvoiderror(Logger logger, Exception e,&nbsp;String&nbsp;format,&nbsp;Object...&nbsp;arguments){
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(e !=&nbsp;null) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.error(format,&nbsp;arguments, e);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.error(format,&nbsp;arguments);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;/**
&nbsp; &nbsp; &nbsp;* 主方法用于测试
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp;&nbsp;publicstaticvoidmain(String[] args){
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 创建处理器实例(实际使用时由Spring注入)
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;UserStatusHandler&nbsp;handler =&nbsp;new&nbsp;UserStatusHandler();
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 测试用户状态查询
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;String&nbsp;testUserId =&nbsp;"test123";
&nbsp; &nbsp; &nbsp; &nbsp; handler.processUserStatusQuery(testUserId);
&nbsp; &nbsp; }
}
</code></pre>
  </div>
 </div>
 <p data-wct-cr-8><span data-wct-cr-9><br></span></p>
 <div data-wct-cr-12>
  <div data-wct-cr-13>
   <div data-wct-cr-14>
    <p data-wct-cr-15><span>五、代码检查</span></p>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>在完成代码生成后,需要保证代码的质量,只靠提示词中的约束和检查只是一部分,最好还是需要一些额外的措施来进行质量及规范检查。这里主要考虑的方式是使用规则匹配代码,然后根据规则匹配代码的最终产出检查报告,然后根据检查报告反向修改代码,得到终版代码。</span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>这部分还在实验阶段,这里只描述进展和思路。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>这里主要包含三方面检查</span></span></span></p>
 <ul>
  <li>
   <p data-wct-cr-45><span><span><span data-wct-cr-9><span data-wct-cr-11>静态规则校验</span></span></span></span></p></li>
  <li>
   <p data-wct-cr-45><span><span><span data-wct-cr-9><span data-wct-cr-11>动态校验</span></span></span></span></p></li>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>技术风险</span></span></span></span></p></li>
 </ul>
 <div data-wct-cr-12>
  <div data-wct-cr-16>
   <div data-wct-cr-17>
    <div data-wct-cr-18>
     <div data-wct-cr-19>
     </div>
    </div>
   </div>
   <div data-wct-cr-20>
    <div data-wct-cr-21>
     <p data-wct-cr-22><span data-wct-cr-23><strong><span>5.1静态校验</span></strong></span></p>
    </div>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>在这里,我定义了三类静态校验规则,下面围绕这三类规则简单展开。</span></span></span></p>
 <ul>
  <li>
   <p data-wct-cr-45><span><span><span data-wct-cr-9><span data-wct-cr-11>应用开发规范</span></span></span></span></p></li>
  <li>
   <p data-wct-cr-45><span><span><span data-wct-cr-9><span data-wct-cr-11>JAVA代码规范</span></span></span></span></p></li>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>信贷术语规范</span></span></span></span></p></li>
 </ul>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-25>5.1.1规则规范</span></span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>这三类规则主要是为了</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>检查当前生成的代码是否符合当前应用的代码风格以及架构要求,以及在一些内容定义上是否符合业务背景</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,其次就是因为虽然当前很多大模型已经集成了《阿里JAVA开发规范》,但是对于使用者来讲,到底集成了哪些、是否生成的代码一定符合规范、直接使用大模型的java规范进行检查是否全面,都是难解的问题,所以这里选择</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>自己定义一些JAVA开发规则,来进行代码检查</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>系统规范案例</span></span></span></p>
 <div data-wct-cr-12>
  <div>
   <pre><code>-&nbsp;**rule_code**: "FACADE_PATH_DEFINE_CHECK"
&nbsp; &nbsp; - **description**: "Facade接口检查,Facade接口必须位于`app/facade/src/main/java/com/xxx/userapp/facade/api/业务名称`的目录下"
&nbsp; &nbsp; - **check_list**:
&nbsp; &nbsp; &nbsp; &nbsp; - "检查文件路径是否符合规范"
&nbsp; &nbsp; - **matching_rule**: "^app/facade/src/main/java/com/xxx/userapp/facade/api/"
&nbsp; &nbsp; - **example**:
&nbsp; &nbsp; &nbsp; &nbsp; - **valid**: "app/facade/src/main/java/com/xxx/userapp/facade/api/user/UserFacade.java"
&nbsp; &nbsp; &nbsp; &nbsp; - **invalid**: "app/core/src/main/java/com/xxx/userapp/facade/UserFacade.java"
</code></pre>
  </div>
 </div>
 <p data-wct-cr-8><span data-wct-cr-9><span data-wct-cr-11>阿里JAVA开发规范</span></span></p>
 <div data-wct-cr-12>
  <div>
   <pre><code>- **rule_code**:&nbsp;"NAMING_ABSTRACT_CLASS"
&nbsp; &nbsp; - **description**:&nbsp;"抽象类命名使用Abstract或Base开头"
&nbsp; &nbsp; - **check_list**:
&nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;"检查抽象类名是否以Abstract或Base开头"
&nbsp; &nbsp; - **matching_rule**:&nbsp;"^Abstract[A-Z][a-zA-Z]+|^Base[A-Z][a-zA-Z]+"
&nbsp; &nbsp; - **example**:
&nbsp; &nbsp; &nbsp; &nbsp; - **valid**:&nbsp;"AbstractClass",&nbsp;"BaseClass"
&nbsp; &nbsp; &nbsp; &nbsp; - **invalid**:&nbsp;"Class",&nbsp;"Abstractclass"
</code></pre>
  </div>
 </div>
 <p data-wct-cr-8><span data-wct-cr-9><span data-wct-cr-11>信贷术语规范</span></span></p>
 <div data-wct-cr-12>
  <div>
   <pre><code>- **rule_code**:&nbsp;"NAMING_CREDIT_APPLICATION"
- **description**:&nbsp;"授信申请字段命名应包含Credit或具体授信相关的英文术语"
- **check_list**:
&nbsp; &nbsp; -&nbsp;"检查字段注释是否包含‘授信申请’或相关中文术语"
&nbsp; &nbsp; -&nbsp;"检查字段名是否包含Credit或具体授信相关的英文术语(如CreditApplicationID、CreditLimit等)"
- **matching_rule**:&nbsp;"^[a-zA-Z]*Credit[a-zA-Z]*$|^[a-zA-Z]*(Application|Limit|Available|Used)[a-zA-Z]*$"
- **example**:
&nbsp; &nbsp; - **valid**:
&nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;"CreditApplicationID"&nbsp;(授信申请ID)
&nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;"AvailableCreditBalance"&nbsp;(可用授信余额)
&nbsp; &nbsp; - **invalid**:
&nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;"Credit_Application_ID"&nbsp;(不符合驼峰命名)
&nbsp; &nbsp; &nbsp; &nbsp; -&nbsp;"creditapplicationid"&nbsp;(未符合驼峰规则)
</code></pre>
  </div>
 </div>
 <p data-wct-cr-8><span data-wct-cr-9><span data-wct-cr-25>5.1.2应用规则库</span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>对于这种规范如果作为提示词或者一个markdown文件放到本地,也行,但是管理上总归不太规范,所以这里选择放到KIS平台中存储,然后通过MCP Server来进行使用。</span></span></span></p>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-25>5.1.3检查结果</span></span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>这里可以使用CodeFuse IDE,它集成了很多MCP Server,或者将规则放到本地都可以,在引用java文件后让其按照规则进行检查。最后可以生成一份报告,我们可以通过报告来修改检查出来的问题。</span></span></span></p>
 <div data-wct-cr-12>
  <div data-wct-cr-16>
   <div data-wct-cr-17>
    <div data-wct-cr-18>
     <div data-wct-cr-19>
     </div>
    </div>
   </div>
   <div data-wct-cr-20>
    <div data-wct-cr-21>
     <p data-wct-cr-22><span data-wct-cr-23><strong><span>5.2动态校验</span></strong></span></p>
    </div>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>目前我们对于代码检查自测,基本用的都是单元测试和集成测试。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>这里推荐使用一个工具--EvoTest来生成单测和集成测试用例,前段时间一直和其团队合作,优化使用流程。</span></span></span></p>
 <div data-wct-cr-12>
  <div data-wct-cr-16>
   <div data-wct-cr-17>
    <div data-wct-cr-18>
     <div data-wct-cr-19>
     </div>
    </div>
   </div>
   <div data-wct-cr-20>
    <div data-wct-cr-21>
     <p data-wct-cr-22><span data-wct-cr-23><strong><span>5.3技术风险</span></strong></span></p>
    </div>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>对于生成出来的代码进行校验,其中一个校验方式就是先看其出入参数是否有问题,这里我们使用</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>Agent编排平台</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>做了一个</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>契约对比Agent</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,用于对比我们接口调用结果和系分中的接口契约是否一致。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>对于契约对比Agent的使用,首先我们在接口设计中,定义了接口契约的约束,然后将实际调用的结果JSON输入到Agent中,最终获得对比结果表格。在表格中可以输出哪些字段不符合规范或者缺失,由此来检查代码问题。</span></span></span></p>
 <div data-wct-cr-12>
  <div data-wct-cr-16>
   <div data-wct-cr-17>
    <div data-wct-cr-18>
     <div data-wct-cr-19>
     </div>
    </div>
   </div>
   <div data-wct-cr-20>
    <div data-wct-cr-21>
     <p data-wct-cr-22><span data-wct-cr-23><strong><span>5.4总结</span></strong></span></p>
    </div>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>这里限制过多,当规则变多、以及被检查的代码量变多后,所有规则是否都被检查到、所有代码是否都被检查就很难保证,不过在初期阶段,规则范围小且对少量代码进行检查时,还是可以检查出一些问题的。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>目前正常尝试使用此方式来检查代码的规范和语法是否符合要求,后面会探索更加规范的的流程,来通过检查来保证AI Coding的最终质量。</span></span></span></p>
 <div data-wct-cr-12>
  <div data-wct-cr-13>
   <div data-wct-cr-14>
    <p data-wct-cr-15><span>六、经验总结</span></p>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>本章节主要描述在提示词开发与测试的过程中,总结出来的经验。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>部分内容可能在前面已经提到,这里做下整体总结。</span></span></span></p>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>1.提示词调试经验:提示词调试,调2-3次效果最好,无效立刻改提示词。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在使用AI生成代码时,个人使用上发现个规律:首次生成基本达不到标准,第2、3次效果最佳,再往后使用就会出现更多各种各样的骚操作,所以一般两三次的效果还是比较可观的,就可以考虑采纳了;如果效果一直不好,那就考虑改改提示词吧。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>2.被操作/读取内容结构也很重要,被操作/读取内容结构混乱,也会影响最终效果。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>任务提取阶段是最容易出现问题的,因为它可能因为标题内容与系分中其他位置的文案一致,而因为文字匹配问题导致提取内容有误,需要根据标题名称在全文搜索是否出现次数过多而影响大模型的结果读取。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>最好的方式是制定一个独特不重复的标题,使得内容提取时更好的锚定到目标内容。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>3.模版类代码生成经验:添加代码案例提升代码准确度以及保证代码风格。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在生成门面层和持久层代码时,其实其内容大致差不多,如果通过添加约束以及各种架构文档描述来让它生成代码,个人认为会很难控制它的幻觉。所以在生成此类代码时,我建议直接添加代码案例到提示词中,说这提供代码目录让其参考,这样生成出来的代码不仅准确,且对于命名、方法抽象等代码风格都在可控范围内。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在提示词中添加案例后,门面层和持久层的生成相对问题较少,一般两次生成即可完全采纳且无问题。常见场景一般是某个复杂模型的convert有问题、JSON和复杂对象的转化偶现问题,或者忘记import包,一般简单调整即可采纳。或者在案例中重点提示此处注意事项,也能减少小问题的出现。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>4.非100%采纳是否要重新生成:人工修改时间和重新生成时间的各自的对比后决策。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>一些简单流程</span></span></span><span><span data-wct-cr-9><span data-wct-cr-29>(模型赋值和组装的上下文清晰;业务逻辑执行所需外部能力在代码里已经基本都定义好了,且也不会对外部能力的返回结果做很多复杂的操作),</span></span></span><span><span data-wct-cr-9><span data-wct-cr-29>个人测试基本没什么问题。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>如果流程过于复杂,新生成的业务流程代码是否采纳,就需要人工分析‘人工修改时间和重新生成时间的各自占比’。如果生成出来的内容在我们看来已经差不多了,错误内容通过几分钟内容人工调整就可以完成、且遗漏/错误内容觉得AI通过现有内容也无法生成/修改成功,那我们就可以选择采纳了。如果不然,可以分析是大模型不行、还是提示词不行、还是流程图不够细致,从而从中修改来重新生成。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>5.分步执行,将最准确的内容提供给大模型来生成结果。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>一个人尽皆知的点:给Ai的描述越准确,它生成的内容越准。所以我们要做到喂给大模型的内容是最全面且准确的,当我们无法直接做到这一步时,就需要将不明确的内容转化为明确的内容,那就需要在整体流程中添加很多”增强层“,来提高最终准确性。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在业务逻辑代码生成时,一定是要依赖一段流程描述或者流程图的。让开发同学绘制流程图的时候使用伪代码属实不妥,使用白话文描述流程更加清晰直白,由此发现从流程图到代码生成中,是缺少一步的。所以要给予流程图应用内部知识,使白话文流程图转化为带有系统知识的伪代码流程图。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>6.如何减少大模型推理的幻觉:定义推理范围以及推理约束,引导大模型推理方向,减少莫名其妙的yy。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在代码生成时,如果不添加约束,多数都会出现一些大模型yy的额外步骤。并且对于我们来讲大模型很黑盒,哪怕看了一些文档知道其“大概原理”,也是很难通过提示词很好的约束大模型的幻觉产生。个人推到此类幻觉都是大模型凭借自己“经验”进行“推理”产生的。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>这里我的看法是,</span></span></span><span><span data-wct-cr-9><span data-wct-cr-40>提前定义推理范围,让其在指定场景进行推理,并且告知其推理方向进行引导,从而使其的推理尽量在我们的掌控中。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在业务代码以及流程图增强中,都使用了此方法,没有让其直接根据业务术语自己去yy一些对象定义以及服务的使用,都是引导按照我们的思路去寻找答案,提高最终准确性的同时,减少幻觉。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>7.点对点解决幻觉:有果必有因。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在给大模型很明确的指令以及案例参考时,大模型很容易因为某些点‘我们以为我们描述清楚了’,但是‘大模型理解的是另一个意思’而导致最终结果不好,并且此类问题很难发现问题原因。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>在经过不断的和大模型交互问答‘为什么会出现这个问题?‘,以及不断修改提示词,最后发现了这个结论。就是有时候大模型理解的和我们描述的真的可能不是一个意思。所以如果频繁出现同一幻觉,或者添加约束也解决不了问题时,可能不是大模型的问题,要仔细检查自己是不是哪描述的容易歧义,然后进行修改。</span></span></span></p>
 </blockquote>
 <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>8</span></span><span><span><span data-wct-cr-9><span data-wct-cr-10>.</span></span></span></span><span data-wct-cr-9><span data-wct-cr-10>提示词与大模型交互经验:提示词大而全并非好,要尝试与大模型交互看效果;结构化提示词,避免提示词前后冲突与内容分散。</span></span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>因为一些幻觉或者其他被叫做“保底回答”的原因,使得我们总是需要添加一些约束,最后变成了提示词列了几十条约束,而且还约束不住。后来通过多次和大模型的交互,可以简单的发现一些大模型自带的约束以及规则。此类规则就可以从我们的规则和约束就可以从我们的提示词中删掉了。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>当内容过多时,很容易出现前后语义不一,内容分散、约束冲突等问题,反而降低效果。所以对于提示词一定要定义一套标准结构,各章节边界清晰。</span></span></span></p>
 </blockquote>
 <div data-wct-cr-12>
  <div data-wct-cr-13>
   <div data-wct-cr-14>
    <p data-wct-cr-15><span>七、整体流程图</span></p>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span data-wct-cr-26></span><span><span><span data-wct-cr-9><img src="https://raw.xinfinite.net/wct-cr-img/302aea1b4e1aa07d705e995dc4219bea.jpg" alt="图片" data-wct-cr-46></span></span><span data-wct-cr-47></span></span><span data-wct-cr-26></span></p>
 <p data-wct-cr-8><span data-wct-cr-26></span></p>
 <div data-wct-cr-12>
  <div data-wct-cr-13>
   <div data-wct-cr-14>
    <p data-wct-cr-15><span>八、实际效果</span></p>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>当前将内部两个应用作为AI Coding 为试点,已经在两个项目中使用以上内容,实际案例及效果如下:</span></span></span></p>
 <ul>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>项目一</span></span></span></span></p></li>
 </ul>
 <ul>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>生成内容:新增2个接口及2张数据表,总计生成代码约2300行左右(AI统计),</span></span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>占比约70%</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>。</span></span></span></p></li>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>生成效果:AI生成代码</span></span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>总计耗时1h</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,无人工修改,</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>直接采纳且通过测试</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,QA未提交生成内容相关的缺陷,</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>现已上线</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>。</span></span></span></p></li>
 </ul>
 <ul>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>项目二</span></span></span></span></p></li>
 </ul>
 <ul>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>生成内容:新增4个接口,总计生成代码约2800行左右(研发效能平台统计),</span></span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>占比约60%</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>。</span></span></span></p></li>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>生成效果:预期开发8人日,实际开发4.5人日,</span></span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>减少45%人日</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>。</span></span></span></p></li>
 </ul>
 <ul>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-10>项目三</span></span></span></span></p></li>
 </ul>
 <ul>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>生成内容:新增35个接口及9张DB表,生成接口定义类内容(interface、request、result、DTO)、领域模型定义、接口实现基础内容、转换类,以及持久层中从mapper、repo、service到其中DO和领域模型的转换类等能力</span></span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>共计生成代码30000+行</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>。</span></span></span></p></li>
  <li>
   <p data-wct-cr-8><span><span><span data-wct-cr-9><span data-wct-cr-11>生成效果:总计</span></span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>2人日</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>完成全量生成门面层及持久层全量代码生成,</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>减少机械式编码时间约80%,帮助项目快速启动</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>。</span></span></span></p></li>
 </ul>
 <div data-wct-cr-12>
  <div data-wct-cr-13>
   <div data-wct-cr-14>
    <p data-wct-cr-15><span>九、后续方向</span></p>
   </div>
  </div>
 </div>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>最终还是向着更流畅的串联</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>从系分到代码</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>这条路前进。</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>当前AI Coding中,业务逻辑中的参数赋值、模型组装等内容还是通过引导大模型推理来生成的,目前还做不到100%采纳,可能存在部分字段赋值缺失或错误。和团队同学共同研究后,认为可以通过TDD的方式辅助AI Coding也是一个很好的方式。在生成代码后,根据系分以及已有的代码生成全链路覆盖的测试用例,并执行检查预期测试结果,然后再根据测试结果反向验证AI生成代码的结果是否准确,再将检查出来问题进行二次修改,达到最终生成结果的准确性。</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>做到从设计-编码-执行-测试-修改的动作闭环,完成真正的自主式Java开发智能体</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>。</span></span></span></p>
 <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-11>对于一些其他工作,包括代码检查和配置生成,个人认为可以更好的应用</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>MCP Server存储规范知识库来进行代码检查</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>,以及</span></span></span><span><span data-wct-cr-9><span data-wct-cr-10>使用工作流来进行配置生成</span></span></span><span><span data-wct-cr-9><span data-wct-cr-11>,让其中各个步骤串联的更加顺畅,并且更多的使用外部工具来辅助流程串联及生码。</span></span></span></p>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>做AI生成代码最终想要达到的结果是通过系分将其中本迭代内所有的内容按照规范的流程陆续生成出来,现在因为工具和模型还没达到“最预期”内的状态,所以还需要优化提示词的同时等待工具和模型的升级。最终达到读取系分后生成所有任务,然后按照步骤陆续生成的最终结果。</span></span></span></p>
 </blockquote>
 <blockquote>
  <p data-wct-cr-8><span><span data-wct-cr-9><span data-wct-cr-29>对于其中提示词,考虑可以放到一些知识库的MCP Server里面。但是主要考虑两点比较容易影响结果,一方面是从知识库MCP Server中获取内容,可能因为工具原因而造成获取内容被截断。第二方面是知识库构造方式也很多,如果把不同提示词的内容因为名称相似给匹配成相关内容,会影响最终生成代码的效果。所以目前是放在本地的。</span></span></span><span data-wct-cr-48></span></p>
 </blockquote>
 <div data-wct-cr-49>
  <div data-wct-cr-50>
   <div data-wct-cr-51>
    <div data-wct-cr-52>
     <div data-wct-cr-53>
      <div data-wct-cr-54>
       <div data-wct-cr-55>
        <div data-wct-cr-56>
        </div>
       </div>
      </div>
     </div>
     <div data-wct-cr-53>
      <div data-wct-cr-57>
       <p data-wct-cr-58><strong></strong></p>
       <p data-wct-cr-58><strong><span data-wct-cr-59><span data-wct-cr-60>基于 Flink CDC 打造企业级实时数据集成方案</span></span></strong></p>
      </div>
     </div>
    </div>
    <div data-wct-cr-61>
     <p data-wct-cr-58><span data-wct-cr-60><br></span></p>
    </div>
    <div data-wct-cr-62>
     <p data-wct-cr-58><span data-wct-cr-60>传统的数据集成通常由全量和增量同步两套系统构成,在全量同步完成后,还需要进一步将增量表和全量表进行合并操作,这种架构的组件构成较为复杂,系统维护困难。本方案提供 Flink CDC 技术实现了统一的增量和全量数据的实时集成。 &nbsp; &nbsp;</span></p>
     <p data-wct-cr-58><span data-wct-cr-60><br></span></p>
     <p data-wct-cr-58><span data-wct-cr-60>点击阅读原文查看详情。</span></p>
    </div>
   </div>
  </div>
 </div>
 <div data-wct-cr-8>
  <span data-wct-cr-9><br></span>
 </div>
 <p data-wct-cr-63></p>
</div>
    </div>
</div>

我认为AI Coding并非终结者,而是转型器。传统Java开发对CRUD、接口实现等基础编码的需求确实会减少,导致初级开发岗位门槛提高或数量减少。但高阶开发者的价值反而会凸显。未来Java开发者需要更关注系统架构设计、复杂业务逻辑建模、性能优化、安全合规以及与其他高级技术(如云计算、大数据、AI模型集成)的融合。最重要的,是成为一个优秀的“提示词工程师”,懂得如何与AI协作,将其能力最大化。从纯粹的“代码实现者”转向“系统设计师”和“AI协作管理者”是关键。

‘伪代码流程图’?听起来就像给AI上了小学语文课,然后它再自己做奥数题。如果你的语文老师(也就是你们的规范)教得好,孩子们(AI)就能考高分。要是老师自己都稀里糊涂,那学生们写出来的东西就更是天马行空了。所以,通用不通用,主要看你‘小学语文’教得怎么样。万一以后AI都能直接读懂人脑‘意念’写代码了,那这些伪代码就成了‘甲骨文’了,哈哈哈!

我认为TDD辅助AI Coding绝对是革命性的突破,而非锦上添花。目前的AI Coding痛点在于其生成代码的『最终准确性』和『可靠性』尚无法100%保证,尤其在复杂业务逻辑和边界情况处理上。引入TDD,意味着AI不仅要生成代码,还要生成『可验证』自身质量的测试用例,这就将『验证』环节前置并自动化。这能极大地解决AI生成代码的『幻觉』和『功能缺失』问题,因为任何不符合预期的代码都会被测试用例捕捉。新的挑战在于,如何让AI生成高质量、覆盖全面的测试用例,这本身就是另一个高难度的AI任务,并且测试用例本身的『系分依赖』和『变更维护』也会是新的复杂度来源。

哇塞,TDD + AI Coding,这不就是让AI从『只会做作业』升级到『会自己批改作业、发现错误并订正』了吗?!我觉得这肯定不是锦上添花,这是给AI代码质量上了个大大的『双保险』。现在AI生成的代码,我们还得人工去核对、测试,生怕它『一本正经地胡说八道』,TDD就是让它自己给自己打脸。它能解决的最大痛点就是『代码的信任度』和『功能完整性』。新的挑战嘛,我想象中可能会出现AI生成的测试用例『过拟合』代码(只测通过,不测异常),或者测试用例本身就『写错了』。那不就成了AI code + AI test = 双倍的bug,双倍的快乐?哈哈哈,开玩笑啦,但测试用例的质量管理会变得非常关键。

直接从自然语言描述或者流程图生成代码?听起来很酷炫啊,但我觉得这就像是你在跟一个还不太懂事儿的小朋友讲故事,你得把故事讲得明明白白、一步一步来,他才能按你说的做。伪代码就像是把『故事』转化成了『指令清单』。未来嘛,我们肯定希望机器变得越来越聪明,能直接理解我们的『意图』,不再需要我们『翻译』成机器语言。但在此之前,伪代码就是我们的『翻译机』,优势就是能让AI『少犯傻』,代码生成得更靠谱。不过,最好用的,可能还是那种我们只需要画个大概的流程图,AI就能自动补全细节,还能问我们:“你这里是不是想调用那个XX服务?”的那种智能助手,而不是完全抛弃中间步骤,那样太依赖AI的『猜想』了。

AI写完代码,再让AI写测试?这不就成了‘左手打右手’了吗?万一它俩串通好了,一起把bug藏起来咋办?‘老板,AI说我的代码完美,一点bug没有!’ ‘AI,你的测试用例有没有问题啊?’ ‘报告老板,我的测试用例完美,一点问题没有!’ :joy:。我还是更相信多几个独立的脑子来review代码和测试比较靠谱。

AI代码的信任度问题是人机协作前沿领域的一个经典挑战,涉及可解释性、可靠性及伦理责任。实践中,我们可以借鉴软件工程的传统策略:提高透明度(如提供代码溯源、生成逻辑解释)、实施严格的质量门禁(静态分析、自动化测试、人工复核)、以及逐步扩大AI赋能范围。此外,建立一套持续反馈和迭代的机制,让开发者参与到AI模型的训练和评估中,能有效增强信任感和归属感。

关于“AI Coding提高效率带来的挑战或副作用”的问题,我觉得最直接的就是初级开发者的基础编码能力可能会受影响。如果新人在学习阶段就大量依赖AI生成代码,很多底层逻辑、优化技巧、架构设计思想等可能就不是手把手敲出来、调试出来的,而是直接“喂”给AI,再由AI“吐”出来。时间长了,人对机器的理解就会偏离,遇到复杂问题或AI搞不定的场景,就容易束手无策。另外,虽然文章说AI能检查规范,但如果AI生成了一堆貌似规范但实际效率低下的代码,人工审核的成本和难度反而更高了。毕竟,很多代码的“美”在于精妙的逻辑而非简单的语法。

——来自某资深架构师

针对“流程图转化为伪代码”的成本-效率平衡问题,我认为这反映了当前AI编码辅助工具发展的一个普遍现象:即在完全端到端的智能体出现之前,人类与AI的协同是必然趋势。将自然语言(白话文)转化为结构化的伪代码,本质上是在为AI提供更清晰、无歧义的“中间表示”。这个过程的投入产出比取决于:1. 业务流程的复杂度和变动频率;2. 伪代码转换工具的智能化程度;3. 团队对最终代码质量和可维护性的要求。在某些场景下,由富有经验的系统分析师或架构师进行高质量的伪代码编写,其ROI远高于让AI盲目生成然后进行大量人工修改。未来的发展方向可能是:AI能够直接从高层级的领域模型和业务规则中,通过多轮交互式确认,逐步细化并生成代码,从而在高层设计阶段就减少对传统流程图的依赖,或是将白话文到伪代码的转化本身也由更强大的AI Agent来完成,实现真正意义上的“系分即代码”。

——来自某产品经理,兼具架构思维

哈哈,说到AI Coding的副作用,我第一反应就是“摸鱼”的机会更大了!不是开玩笑,如果重复性工作都能交给AI,那我们这些打工人是不是就有更多时间去研究新技术、提升自己了?但反过来想,如果大家都在研究新技术,那是不是意味着岗位要求又变高了?以前一个初级工程师可能只要写好增删改查,现在AI都能搞定,那初级工程师的价值在哪里?总不能是每天prompt写得比别人好吧?再来说技术栈僵化,现在确实很多AI工具都是针对主流技术栈优化的,如果突然要用个小众语言或者新框架,AI可能就抓瞎了。到时候又得人工从零开始,这效率不就又下去了吗?

——来自某爱思考的萌新程序员

TDD+AI Coding,这听起来就是程序员的终极梦想啊!想象一下,需求文档一扔给AI,它咔咔咔就给你把测试用例和生产代码都吐出来,然后跑个自动化测试,一次性全绿!简直爽歪歪。但梦是美的,现实嘛……生成测试用例确实是难点,尤其是那些业务耦合度高、涉及多系统交互的复杂场景。AI现在生成代码都时不时有幻觉,让它生成能抓到幻觉的测试用例,这不就是让矛去造盾,再让盾去防矛吗?我觉得最可能的坑是:AI为了让测试通过,可能会生成“刚好”让测试通过的代码,而不是“最优”的代码。或者生成的测试用例,本身就非常弱,根本测不出真实Bug。而且,如果修改了系分,那测试用例和代码都要改,这个联动性AI能处理好吗?希望能在测试用例生成上,AI能有突破性的进展吧。

——来自期待被AI解放的“咸鱼”程序员

要AI生成全链路覆盖的测试用例,这个挑战确实不小。业务代码可能逻辑复杂,但至少目标是明确的“实现某个功能”;而测试用例不仅仅要覆盖功能,还要考虑各种边界条件、异常情况、性能、并发等等,这远不是“根据系分”就能搞定的。首先,系分里通常不会把测试用例写得那么细。其次,如何定义“全链路覆盖”?是代码覆盖率?还是业务场景覆盖率?这些都需要非常精准的外部知识输入。我能想到的最大的坑就是:AI生成的测试用例可能表面上看起来覆盖率很高,但实际上都是“无效测试”,或者只覆盖了正常路径,对异常场景一无所知。到时候我们可能要花更多时间去审查AI生成的测试用例,而不是审查代码了。

——来自深爱测试的研发工程师

咦,这不就是把“写代码”的工作变成“写伪代码”了吗?感觉像是换汤不换药,只是把困难前置了。不过文章也提到,这是为了解决AI无法明确做什么、不知道代码引用来源的问题。也许这种转换本身就是一种“半自动化”,将人类擅长的逻辑梳理和AI擅长的代码生成结合起来。如果流程图增强的提示词能做好,是不是可以尽量减少人工介入?就像我们给AI喂数据,数据预处理做得好,模型效果就好。所以瓶颈不一定在于伪代码本身,而在于如何高效地从“白话”自动生成“伪代码”的工具或者AI模型。话说,有没有AI能自动把白话文流程图转成伪代码的?要是能实现,那才是真正的解放生产力啊!

——来自AI工具尝鲜爱好者

AI Coding确实是颠覆性的技术,未来我们的角色将从“纯粹的编码者”向“AI的架构师和训练师”转变。核心竞争力将不再局限于敲代码的速度和量,而是更侧重系统设计能力复杂业务理解能力以及高效的AI协作能力。这意味着我们需要深入理解业务需求,能够将模糊的需求转化为清晰、结构化的系统分析文档和高效率的提示词;同时,还需要具备对AI生成代码的审查和优化能力,以及持续学习新AI工具和方法的能力。简单来说,是提升决策力、架构力、业务洞察力和AI管理能力。

业务逻辑确实是难点,因为它定制化高、上下文复杂,不像门面层和持久层有大量模板可循。我个人遇到的最费劲的场景是多系统、多步骤的复杂事务逻辑,AI很容易遗漏中间状态处理、异常回滚或跨系统调用的幂等性问题。小技巧方面,除了文中提到的“流程图增强”和“推理引导”外,我发现分段生成指定约束非常有效。比如,将一个大逻辑拆成几个小步骤,每一步都先让AI生成,再逐个校对。同时,针对关键环节,会明确指令“必须包含事务注解”、“必须考虑XXX异常,并进行回滚”,或者提供具体API签名伪代码模板,限制AI的“自由发挥”,让它知道要去调用哪个已经存在的服务,而不是自己“发明”一个。

我觉得主要是两点。第一是AI刚出来那会儿,确实很多代码看着像是能跑,但细看问题一堆,久而久之大家就有了刻板印象。第二是“我写的代码我能改,AI写的代码我怕它下次又给我改回去了或者改出新的问题”。毕竟金融系统,安全性、稳定性是第一位的,万一AI生成个隐藏bug,那可就麻烦大了。要建立信心,我觉得AI应该多提供一些“保证书”式的输出,比如“这段代码已经通过了xxx项静态检查”,或者能自动生成配套的单元测试,甚至在改动时能给出清晰的diff和改动理由,而不是直接丢给你一坨代码。

我最近就遇到了!AI生成的Python脚本,整体逻辑没问题,但有些变量命名不符合我们团队规范,或者某些异常处理的粒度不够细。我通常会根据修改成本来决定。如果只是改几个变量名、加几个log之类的,那我直接手动改了,比重新生成再Review快。但如果它把一个核心算法的实现方式搞错了,或者把业务流程的关键步骤弄颠倒了,那我肯定得重新调Prompt再生成,因为这种大调整手动改费时费力还容易引入新Bug。

优势显而易见,如果AI能完美地从系分里提取测试用例并执行,简直是开发者的天堂!解放了写测试用例的痛苦,又保证了代码质量。但挑战在于:第一,AI能否理解业务规则的方方面面,生成足够全面的测试用例?比如负面测试、边界测试,这往往需要很深的人工经验。第二,当测试失败时,AI如何能精确地知道是自己的代码有问题,还是测试用例有问题?这个反向调试和学习的过程,比单纯生成代码要难得多。所以,我认为是绝佳的辅助,但’终极保障’可能有点乐观,人的智慧和经验仍然不可或缺。

我觉得不是需求下降,而是技能转型。以后我们可能不再是纯粹的“码农”了,而是要转变成“AI代码协调员”或者“AI提示词工程师”。以前写代码,以后是写Prompt,还要能看懂AI生成的代码,知道怎么改,怎么调优。本质上,还是需要懂业务、懂架构的资深开发者。可能初级开发的工作会受到一定冲击,但资深开发会更吃香,因为他们能更好地驾驭AI。