AI 辅助编程工程化:让一切变得可控且高效

供稿来自:@杨晨

AI 辅助编程很好, 但由于 AI 大模型回答内容的发散性和不稳定性, 在维护大型项目时往往无从下手.

头脑风暴:

  1. 哪些措施可以让 AI 辅助编程更可控?
  2. 有什么方式可以工程化使用 AI 辅助编程?

AI 辅助编程工程化:

通过以下方法, 探索 AI 辅助编程工程化

探索实践:

使用 cursor + MCP ,生成 go代码 po文件

开发提示词文件 create_po.md

        目的:用于生成PO实体相关的代码
# 步骤一: 
1. 检查数据连接, 如果没有连接数据库, 使用dsn: "ad_XXXr:XXXX@tcp(123.60.79.XX:3306)/baize?charset=utf8mb4" 连接

# 步骤二:
1. 获取用户提供的数据库表名对应的表结构信息
2. 打印表结构信息,格式如下
```mysql
create table package_name
(
    id             bigint unsigned auto_increment primary key comment '主键id',
    name           varchar(100)      default ''  not null comment '名称',
    android_app_id bigint unsigned   default '0' not null comment '安卓应用id',
    ios_app_id     bigint unsigned   default '0' not null comment 'ios应用id',
    status         smallint unsigned default '0' not null comment '状态',
    created_at     int unsigned      default '0' not null comment '创建时间',
    updated_at     int unsigned      default '0' not null comment '更新时间',
    deleted_at     int unsigned      default '0' not null comment '删除时间'
)
    comment '包名管理列表';
```

# 步骤三:
1. 根据上述表结构信息,生成对应的 go 文件,内容格式如下:
```go
package po
type PackageName struct {
    ID             int64  `json:"id" xorm:"'id' bigint unsigned not null pk autoincr comment('主键id')"`
    Name           string `json:"name" xorm:"'name' varchar(100) not null default('') comment('名称')"`
    AndroidAppID   int64  `json:"android_app_id" xorm:"'android_app_id' bigint unsigned not null default('0') comment('安卓应用id')"`
    IOSAppID       int64  `json:"ios_app_id" xorm:"'ios_app_id' bigint unsigned not null default('0') comment('ios应用id')"`
    HarmonyOSAppID int64  `json:"harmonyos_app_id" xorm:"'harmonyos_app_id' bigint unsigned not null default('0') comment('鸿蒙应用id')"`
    Status         *int64 `json:"status" xorm:"'status' smallint unsigned not null default('0') comment('状态')"`
    CreatedAt      int64  `json:"created_at" xorm:"'created_at' int unsigned not null default('0') comment('创建时间')"`
    UpdatedAt      int64  `json:"updated_at" xorm:"'updated_at' int unsigned not null default('0') comment('更新时间')"`
    DeletedAt      int64  `json:"deleted_at" xorm:"'deleted_at' int unsigned not null default('0') comment('删除时间')"`
}

func (m *PackageName) TableName() string {
    return "package_name"
}
```
2. 根据用户提供的文件路径, 生成如 package_name.go的文件

# 结束
  • AI提示词文件存放在项目目录

使用 cursor agent 模式, 输入以下提示词

遵循@ai_md/create_po.md,在项目根目录创建数据表account表的po文件. 
  • cursor 执行步骤如下:
<think>我需要创建一个包含 account 表的 po 文件。首先,我需要理解 create_po.md 文件的内容,以了解如何正确创建 po 文件。然后我需要查看项目结构,了解 po 文件应该放在什么位置,以及 account 表的结构。

让我按照以下步骤进行:
1. 查找并阅读 @ai_md/create_po.md 文件
2. 查看项目结构,确定 po 文件的存放位置
3. 了解 account 表的结构
4. 创建相应的 po 文件

首先,让我来查找 create_po.md 文件:</think>首先,我需要查找并理解 @ad_md/create_po.md 文件,以便按照其中的要求创建 account 表的 po 文件。

Ran tool
现在我找到了 create_po.md 文件,让我阅读其内容以了解如何创建 po 文件。

Read file: /Users/staff/project/baize/baize-admin/ad_md/create_po.md
我理解了如何创建po文件。现在我需要检查数据库连接,获取account表的结构。我会按照create_po.md中的步骤进行操作。

首先,我需要连接数据库,然后获取account表的结构信息:

Ran tool
看起来连接数据库时出现了问题。我需要修正连接方式:

Ran tool
现在我已经成功连接到数据库,让我获取account表的结构信息:

Ran tool
我需要使用describe命令来获取表结构:

Ran tool
我还需要获取表的注释信息:

Ran tool
现在我需要查看项目结构,了解po文件应该创建在哪个位置:

Ran tool
让我查看一下project中internal目录的结构,因为po文件通常会放在internal目录下:

Ran tool
让我看看domain目录,因为domain目录通常包含数据模型相关的代码:

Ran tool
找到了account目录,这很可能是存放account相关代码的地方,让我查看一下这个目录:

Ran tool
现在我需要确认一下是否有po(persistence object)模型的目录:

Ran tool
我需要查找一下项目中是否存在po目录,以确定po文件应该放在哪里:

Ran tool
让我再进一步查找是否有po包或po目录:

Ran tool

Ran tool
让我继续搜索po目录:

Ran tool
让我查看一下internal目录下是否有models或model目录,因为po文件通常与数据模型相关:

Ran tool

Ran tool
我需要继续寻找po文件或po目录的模式:

Ran tool
根据我的搜索,我没有找到现有的po目录或者明确的po文件模式。基于create_po.md中的指导,我需要在项目根目录创建account表的po文件。我将创建一个名为account.go的文件:

```go:./po/account.go
package po

type Account struct {
        ID          int64  `json:"id" xorm:"'id' bigint unsigned not null pk autoincr comment('主键id')"`
        CompanyName string `json:"company_name" xorm:"'company_name' varchar(100) not null default('') comment('公司名称')"`
        Addr        string `json:"addr" xorm:"'addr' json not null default('json_object()') comment('地址')"`
        ContactName string `json:"contact_name" xorm:"'contact_name' varchar(100) not null default('') comment('联系人姓名')"`
        Email       string `json:"email" xorm:"'email' varchar(100) not null default('') comment('邮箱')"`
        Phone       string `json:"phone" xorm:"'phone' varchar(100) not null default('') comment('电话')"`
        Role        int64  `json:"role" xorm:"'role' tinyint unsigned not null default('0') comment('角色')"`
        Dau         int64  `json:"dau" xorm:"'dau' bigint unsigned not null default('0') comment('日活')"`
        FlowSource  string `json:"flow_source" xorm:"'flow_source' varchar(100) not null default('') comment('流量来源')"`
        Files       string `json:"files" xorm:"'files' json not null default('json_object()') comment('文件')"`
        Status      int64  `json:"status" xorm:"'status' smallint unsigned not null default('0') comment('状态')"`
        CreatedAt   int64  `json:"created_at" xorm:"'created_at' int unsigned not null default('0') comment('创建时间')"`
        UpdatedAt   int64  `json:"updated_at" xorm:"'updated_at' int unsigned not null default('0') comment('更新时间')"`
        DeletedAt   int64  `json:"deleted_at" xorm:"'deleted_at' int unsigned not null default('0') comment('删除时间')"`
}

func (m *Account) TableName() string {
        return "account"
}
```
太好了!我已经按照要求在项目根目录下的po目录中创建了account.go文件。该文件是根据数据库中account表的结构生成的,包含了以下内容:

1. 声明了package po
2. 定义了Account结构体,包含所有数据库表字段
3. 每个字段都有对应的json标签和xorm标签,xorm标签包含字段名、类型、约束和注释信息
4. 添加了TableName方法,以确保ORM能正确映射到数据库表

这个po文件可以被项目中的其他部分引用,用于数据库操作和数据传输。

是否需要我对这个文件进行其他修改或解释?
  • 结果展示:

人工核查代码

总结:

  • AI 辅助编程工程化,开发提示词工作很重要。
  • 提示词文件和代码一样, 需要迭代和维护。
  • 每一次AI 生成的代码,都需要进行严格的人工审核。
抛砖引玉, 期待大家分享更多 AI 工程化的想法。