背景说明
随着AI技术的普及,使用AI辅助编写代码已成为开发者日常工作的一个重要部分,目前市面上的相关工具种类繁多,功能各异。
Sponge 提供了内置的 AI 助手功能,支持 DeepSeek 和 ChatGPT 两种类型。通过在代码注释中提供提示语,AI 助手可以快速生成与业务逻辑匹配的参考代码,从而显著提升开发效率。
适用场景: 当 sponge 生成的自定义 API 接口缺少业务逻辑代码时,sponge 的 AI 助手可生成业务逻辑参考代码,开发者可基于参考代码进行修改。
使用 sponge AI 助手生成业务逻辑参考代码操作流程比较简单,只需以下几个步骤即可完成:
1. 获取 AI 助手 API Key
首先需要注册 AI 助手账号 (DeepSeek 或 ChatGPT),并获取对应的 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…