前言
2025年对我来说挺特别的。3月份开始调研一个 Go 微服务项目的技术方案,7月正式写代码,10月中旬系统上线,11月中旬第一个版本封版。8个月时间,把一个微服务项目从零到一做完了。
这个项目成了我探索 AI 辅助开发的试验场。整个开发过程中,我尝试了各种 AI 编程助手和对话工具,浏览器里永远开着几个 AI Chat 标签页。这种开发方式确实让我效率提升不少,也让我突破了一些之前觉得做不到的事情。
今天想聊聊这一年 AI 怎么改变了我的开发方式,顺便分享一些技术实践中的干货。
一、项目背景与技术选型
这个 Go 微服务项目用了 CloudWeGo 生态:Kitex 做 RPC 框架,Hertz 做 HTTP 网关,Thrift 定义接口,PostgreSQL 存数据,Google Wire 做依赖注入。
说实话,刚开始压力挺大的:
- CloudWeGo 生态的框架都不熟,得从头学
- 微服务架构的复杂设计模式要理解并实践
- 代码质量和系统稳定性都得保证
- 时间还特别紧,从调研到上线就几个月
这时候 AI 成了我的"外脑"。
二、AI 如何改变了我的学习方式
2.1 学新框架的效率提升
以前学新框架,得看一堆官方文档、教程文章,还得跑示例代码。有了 AI 之后,这个过程快了很多。
比如学 Kitex 的服务注册与发现,我直接问 AI,它就能给出代码示例和配置说明,还会提醒哪些地方容易踩坑。几小时就能理解以前需要几天才能搞懂的东西。
举个实际例子,我问 AI 怎么在 Kitex 中处理业务错误,它告诉我要用 BizStatusError:
go
// 定义错误码
type ErrNo struct {
Code int32
Msg string
}
var (
ErrUserNotFound = &ErrNo{Code: 100001, Msg: "用户不存在"}
ErrInvalidPassword = &ErrNo{Code: 100002, Msg: "密码错误"}
)
// 转换为 Kitex 可识别的错误
func ToKitexError(err *ErrNo) error {
return kerrors.NewBizStatusError(err.Code, err.Msg)
}
更关键的是,AI 还提醒我必须配置 TTHeader MetaHandler,否则错误信息传不过去:
go
// 客户端配置
client.WithMetaHandler(transmeta.ClientTTHeaderHandler)
// 服务端配置
server.WithMetaHandler(transmeta.ServerTTHeaderHandler)
这个坑如果靠自己摸索,可能要踩好几天。
2.2 架构设计的思路拓展
项目采用了星型拓扑的微服务架构:
sql
┌─────────────┐
│ Client │
└──────┬──────┘
│ HTTP
┌──────▼──────┐
│ Gateway │ (Hertz)
│ :8080 │
└──────┬──────┘
│ Thrift RPC
┌───────────────┼───────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Identity │ │ User │ │ Order │
│ Service │ │ Service │ │ Service │
└─────────────┘ └─────────────┘ └─────────────┘
这个架构是我和 AI 反复讨论后确定的。我把业务需求描述给 AI,它给出了几种拓扑方案的对比分析,最终我选择了星型拓扑:
- 网关是唯一入口,所有鉴权在网关层完成
- RPC 服务之间不互相调用,避免循环依赖
- 调试简单、链路清晰、容易扩展
AI 不是替我做决策,而是帮我理清思路,让我能更快地做出判断。
三、AI 辅助编码的实际体验
3.1 快速原型验证
要实现新功能时,我先让 AI 生成一个基础代码框架,然后按项目规范调整优化。
比如 RPC 服务的分层架构,AI 帮我生成了基础模板:
go
// Handler 层:参数校验 + 调用业务逻辑
func (s *IdentityServiceImpl) Login(ctx context.Context, req *identity.LoginRequest) (*identity.LoginResponse, error) {
if err := validateLoginRequest(req); err != nil {
return nil, errno.ToKitexError(errno.ErrInvalidParam)
}
return s.logic.Login(ctx, req)
}
// Logic 层:核心业务逻辑
func (l *AuthLogic) Login(ctx context.Context, req *identity.LoginRequest) (*identity.LoginResponse, error) {
user, err := l.dal.GetUserByEmail(ctx, req.Email)
if err != nil {
return nil, err
}
if !l.verifyPassword(req.Password, user.PasswordHash) {
return nil, errno.ErrInvalidCredentials
}
token, err := l.generateToken(user)
// ...
}
// DAL 层:数据访问
func (d *UserDAL) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user models.User
err := d.db.WithContext(ctx).Where("email = ?", email).First(&user).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errno.ErrUserNotFound
}
return &user, err
}
这个模板我拿来稍作修改就能用,省了不少重复工作。
3.2 重构建议
项目中期重构早期代码时,AI 能识别出问题,给出重构建议。
比如它发现我的代码里有大量 N+1 查询问题:
go
// AI 指出的问题代码
for _, userID := range userIDs {
user, _ := dal.GetUserByID(ctx, userID)
users = append(users, user)
}
// AI 建议的优化方案
users, _ := dal.GetUsersByIDs(ctx, userIDs)
func (d *UserDAL) GetUsersByIDs(ctx context.Context, ids []int64) ([]*models.User, error) {
var users []*models.User
err := d.db.WithContext(ctx).Where("id IN ?", ids).Find(&users).Error
return users, err
}
还有 DTO 和 Model 之间的转换代码重复率很高,AI 建议我抽象成通用工具:
go
// 通用指针转换
func PtrToValue[T any](ptr *T, defaultVal T) T {
if ptr == nil {
return defaultVal
}
return *ptr
}
func ValueToPtr[T any](val T) *T {
return &val
}
这个工具库后来成了项目里广泛使用的基础设施。
3.3 踩坑时的救命稻草
用 Docker 部署时遇到一个诡异问题:服务之间能通信,但生成的预签名 URL 客户端访问不了。
我把问题描述给 AI,它很快定位到原因:对象存储在容器内部用的是内部域名,生成的 URL 带的也是内部域名,外部自然访问不了。
解决方案是双端点配置:
go
type StorageConfig struct {
Endpoint string // 内部端点,容器间通信用
PublicEndpoint string // 公共端点,生成预签名 URL 用
}
这种问题如果靠自己排查,可能要花半天甚至更久。
四、AI 辅助的边界与局限
用了一年 AI 辅助开发,我也发现了它的局限性。
4.1 不能完全理解业务上下文
AI 生成的代码经常需要根据项目实际情况调整。比如 Wire 依赖注入,AI 给的示例是这样的:
go
// AI 生成的示例(有问题)
func NewUserDAL() (*UserDAL, error) {
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, err
}
return &UserDAL{db: db}, nil
}
问题在于每个 DAL 都会创建新的数据库连接,连接池根本没用上。正确做法是数据库初始化放到 config 层:
go
// 正确写法
func NewDatabase(cfg *Config) (*gorm.DB, func(), error) {
db, err := gorm.Open(postgres.Open(cfg.DSN), &gorm.Config{})
if err != nil {
return nil, nil, err
}
cleanup := func() {
sqlDB, _ := db.DB()
sqlDB.Close()
}
return db, cleanup, nil
}
var ProviderSet = wire.NewSet(
config.NewDatabase,
dal.NewUserDAL, // 接收 *gorm.DB 作为参数
// ...
)
4.2 需要严格审查和测试
AI 生成的代码不能直接用,必须审查。我会让 AI 帮忙检查:
- 错误处理有没有遗漏
- 有没有并发安全问题
- 代码风格符不符合规范
- 有没有性能优化的空间
然后再写测试验证。AI 能根据代码逻辑自动生成测试用例,覆盖各种边界情况,这个功能我用得很多。
五、意外的收获:从使用者到贡献者
学习 CloudWeGo 生态时,我发现了一些可以改进的地方。以前可能就算了,但有了 AI 帮忙理解源码和写 PR,我真的去提交了改进建议。
社区贡献:
- obs-opentelemetry #66:关于 OpenTelemetry 集成的问题讨论
- jwt #26:JWT 中间件的改进建议
从"使用者"变成"贡献者",这是我之前没想过的事情。AI 降低了参与开源的门槛。
开源教程项目:
我把项目中的经验整理成了一个开源项目 cloudwego-microservice-demo,包含:
- 完整的项目结构
- Wire 依赖注入示例
- 错误处理最佳实践
- Docker 部署配置
AI 在这个过程中帮我梳理知识点、优化文档结构、生成示例代码。
六、一些思考
6.1 AI 是放大器,不是替代品
这一年下来,我最深的体会是:AI 不是要替代开发者,而是放大开发者的能力。
它能处理重复性工作,让我专注在更有价值的创造性工作上。同时提供即时的知识支持,大大降低了技术学习的门槛。
但决策还是得自己做,代码还是得自己审,架构还是得自己把控。
6.2 形成自己的工作流
我现在的工作流大概是:
- 遇到新技术/新需求,先问 AI 了解概念和最佳实践
- 让 AI 生成代码框架,自己调整细节
- 提交前让 AI 做 code review
- 遇到 bug 时描述问题,让 AI 帮忙分析
- 写文档时让 AI 帮忙梳理结构
这种"人机协作"的模式,让我的效率提升了不少。
七、总结
回顾这一年,AI 工具确实给我的开发工作带来了很大变化:
效率提升:
- 学新框架的时间大幅缩短
- 问题排查更快
- 重复性代码工作减少
能力突破:
- 成功完成了复杂的微服务架构项目
- 从"使用者"变成了"贡献者"
- 技术栈扩展了不少(Go、CloudWeGo、Docker、分布式系统)
思维方式改变:
- 遇到问题先问 AI 成了习惯
- 知识获取和问题解决更高效
- 敢于尝试以前觉得太难的事情
最重要的是,AI 让我能突破原本的能力上限。它不只是提高了工作效率,还改变了我的学习方式和思维方式。
写在最后
如果你还没试过 AI 辅助开发,可以从这几步开始:
- 选一个适合你的 AI 编程助手
- 从简单的代码补全和问题咨询开始
- 逐步尝试更复杂的任务,比如代码重构、架构设计
- 形成自己的 AI 工作流
- 持续学习和优化,找到最适合你的方式
记住,AI 是工具,你才是创造者。善用 AI,让它成为你技术成长的加速器。
2025,一起拥抱 Vibe Coding!
如果你在 Go 微服务开发或 AI 辅助编程方面有什么想法,欢迎评论区交流!