用 AI 助手生成高适配 sponge 开发框架的业务逻辑代码,轻松提升开发效率!

103 阅读4分钟

背景说明

随着AI技术的普及,使用AI辅助编写代码已成为开发者日常工作的一个重要部分,目前市面上的相关工具种类繁多,功能各异。

Sponge 提供了内置的 AI 助手功能,支持 DeepSeek 和 ChatGPT 两种类型。通过在代码注释中提供提示语,AI 助手可以快速生成与业务逻辑匹配的参考代码,从而显著提升开发效率。

适用场景: 当 sponge 生成的自定义 API 接口缺少业务逻辑代码时,sponge 的 AI 助手可生成业务逻辑参考代码,开发者可基于参考代码进行修改。


使用 sponge AI 助手生成业务逻辑参考代码操作流程比较简单,只需以下几个步骤即可完成:

1. 获取 AI 助手 API Key

首先需要注册 AI 助手账号 (DeepSeekChatGPT),并获取对应的 API Key。如果公司对代码隐私有较高要求,建议在本地部署开源版的 DeepSeek 来进行使用,生成代码速度快,使用R1模型准确率比 ChatGPT 更好一些。


2. 在 Protobuf 文件中定义 AI 提示语

proto 文件的 service 定义下,针对每个 rpc 方法添加注释,这些注释将作为 AI 助手的提示语。提示语应尽可能详细,包含业务逻辑描述和相关技术术语,以帮助 AI 理解需求。

示例代码:

syntax = "proto3";

package api.user.v1;

service Users {
  // 支持手机号码和微信两种方式注册。
  // 如果使用手机号注册,需要检查手机号是否合法,校验码是否匹配;
  // 如果使用微信注册,需使用微信授权的临时票据 code 和 appid、appsecret
  // 从微信平台获取 token 和 openID,并获取用户信息进行注册。
  rpc Register(RegisterRequest) returns (RegisterReply) {}
}

对于 ⓵基于sql创建web服务,可以通过人工在handler目录下代码文件的方法中添加panic("prompt: xxxx")作为AI助手的提示语。


3. 创建服务

在 Sponge 的生成代码页面中选择所需的服务端代码类型:

  • ⓶基于sql创建grpc服务;
  • ⓷基于protobuf创建web服务;
  • ⓸基于protobuf创建grpc服务;
  • ⓹基于protobuf创建grpc网关服务;
  • ⓺基于protobuf创建grpc+http服务。

然后解压生成的代码文件并执行以下命令生成代码:

make proto

4. 生成业务逻辑参考代码

运行以下命令,通过 AI 助手生成业务逻辑参考代码:

  • 使用 DeepSeek:

    sponge assistant generate --type=deepseek --api-key=sk-xxxxxx --dir=.
    
  • 使用 ChatGPT:

    sponge assistant generate --type=chatgpt --api-key=sk-xxxxxx --dir=.
    

生成的参考代码会存储为对应文件夹下的 .assistant 文件(通常在handler或service目录下),表明该代码由 AI 助手生成。

注:如果在.go文件中不删除panic("prompt: xxxx")这一行代码(或直接注释掉),每次执行AI助手生成业务逻辑参考代码命令会再次生成一遍。


5. 验证代码

打开 .assistant 文件,即可查看 AI 助手生成的业务逻辑参考代码。根据实际需求修改或直接使用这些代码,快速完成开发工作,然后把 .assistant 文件删除。

下面是使用DeepSeek R1模型生成的业务参考代码:

func (h *userHandler) Register(ctx context.Context, req *userV1.RegisterRequest) (*userV1.RegisterReply, error) {
    // 参数校验
    err := req.Validate()
    if err != nil {
        logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req), middleware.CtxRequestIDField(ctx))
        return nil, ecode.InvalidParams.Err()
    }

    var userID uint64
    switch req.GetType() {
    case userV1.RegisterType_Phone:
        // 手机号注册
        phone := req.GetPhone()
        if !isValidPhone(phone) {
            return nil, ecode.InvalidParams.ErrMsg("invalid phone format")
        }

        // 验证码校验(示例需要实现verifyCode逻辑)
        valid, err := h.verifyVerificationCode(phone, req.GetCode())
        if err != nil {
            logger.Error("verify code error", logger.Err(err), middleware.CtxRequestIDField(ctx))
            return nil, ecode.InternalServerError.Err()
        }
        if !valid {
            return nil, ecode.InvalidParams.ErrMsg("verification code mismatch")
        }

        // 创建手机用户
        userID, err = h.userDao.CreateByPhone(ctx, phone)
        if err != nil {
            logger.Error("create phone user error", logger.Err(err), middleware.CtxRequestIDField(ctx))
            return nil, ecode.InternalServerError.Err()
        }

    case userV1.RegisterType_Wechat:
        // 微信注册
        openID, err := h.getWechatOpenID(
            req.GetCode(),
            req.GetWechatParams().GetAppid(),
            req.GetWechatParams().GetSecret(),
        )
        if err != nil {
            logger.Error("get wechat openid error", logger.Err(err), middleware.CtxRequestIDField(ctx))
            return nil, ecode.InvalidParams.ErrMsg("wechat authorization failed")
        }

        // 检查是否已存在
        exists, err := h.userDao.ExistsByWechatOpenID(ctx, openID)
        if err != nil {
            logger.Error("check wechat user exists error", logger.Err(err), middleware.CtxRequestIDField(ctx))
            return nil, ecode.InternalServerError.Err()
        }
        if exists {
            return nil, ecode.AlreadyExists.ErrMsg("user already registered")
        }

        // 创建微信用户
        userID, err = h.userDao.CreateByWechat(ctx, openID)
        if err != nil {
            logger.Error("create wechat user error", logger.Err(err), middleware.CtxRequestIDField(ctx))
            return nil, ecode.InternalServerError.Err()
        }

    default:
        return nil, ecode.InvalidParams.ErrMsg("unsupported register type")
    }

    return &userV1.RegisterReply{Id: userID}, nil
}

// 手机号格式校验(示例实现)
func isValidPhone(phone string) bool {
    matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, phone)
    return matched
}

// 验证码校验(需要实现具体逻辑)
func (h *userHandler) verifyVerificationCode(phone, code string) (bool, error) {
    // 示例:从缓存获取验证码进行比对
    // storedCode, err := h.cache.Get(ctx, "sms_code:"+phone)
    // return storedCode == code, nil
    return true, nil // 示例直接返回验证成功
}

// 获取微信OpenID(需要实现具体逻辑)
func (h *userHandler) getWechatOpenID(code, appid, secret string) (string, error) {
    // 示例实现微信接口调用
    /*
    url := fmt.Sprintf(
        "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
        appid, secret, code,
    )
    
    resp, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    var result struct {
        OpenID       string `json:"openid"`
        ErrCode      int    `json:"errcode"`
        ErrMsg       string `json:"errmsg"`
    }
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        return "", err
    }

    if result.ErrCode != 0 {
        return "", fmt.Errorf("wechat error: %s", result.ErrMsg)
    }
    return result.OpenID, nil
    */
    return "mock_openid", nil // 示例返回模拟openid
}

总结

Sponge 内置的 AI 助手通过简单的操作流程,利用注释提示语为开发者生成业务逻辑参考代码,既提升了开发效率,又降低了开发难度。这种灵活的方式为企业开发者提供了更多选择,充分发挥了 AI 技术的优势。


Github仓库 github.com/go-dev-fram…