实战分享:AI 大模型在日常开发中的应用与展望
本文分享了AI在跨境支付项目中的实际应用经验。项目采用后台模式实现境外钱包扫码境内聚合码支付,相比常规业务新增了商户信息获取和付款信息推送环节。作者将AI融入开发流程,重点展示了AI在功能函数补全(如数据库连接、加解密)、构建脚本生成、条件判断自动续写、结构体联想补全、数据序列化处理以及日志调试等方面的应用效果。通过具体代码示例,说明AI能有效减少样板代码编写、提高开发效率,同时保持代码风格统一。
文章目录
一、需求背景
本次分享的业务场景是:境外用户使用境外钱包扫码境内聚合码进行支付。整体设计采用后台模式,由微信支付受境外钱包委托完成商户信息获取及付款信息推送等环节。与境内常规收单业务相比,额外增加了:
- 微信支付受境外钱包委托向境内机构获取商户信息;
- 微信支付受境外钱包委托推送用户付款信息。
在这一实际项目中,我积极尝试将 AI
大模型融入日常开发流程,探索其在编码、调试、文档化等方面的应用效果。以下总结了我在项目中的经验与思考。
二、思维导图
三、AI 在项目中的实际应用
3.1 功能函数快速补全
在定义好函数签名后,通过对话式提示,AI
可以迅速补全函数内部逻辑。例如数据库连接、加解密函数、日志初始化等。这样能大幅减少样板代码的重复编写,提高专注度。
示例:
func loadViperConfig(localConfigFilePath string) (*AppConfig, error) {}
func InitZapLogger() *zap.Logger {}
func doConnect(user, pass, ip, dbName, port string, maxIdleCoon, maxOpenCoon, maxLifeTime int) (*gorm.DB, error) {}
func SendWeComRobotMessage(url, msg string, retries int) error {}
func TwoPhaseCommit(dbList []*gorm.DB, operation func(*gorm.DB) error) (err error) {}
func AES256GCMDecrypt(base64Data, associatedData, key, nonce string) ([]byte, error) {}
func AESCBCDecrypt(base64Data, base64Key, base64IV string) ([]byte, error) {}
func VerifyWithPublicKey(needSignStr, signature string, pubKey *rsa.PublicKey) error {}
func SignWithPrivateKey(needSignStr string, priKey *rsa.PrivateKey) (string, error) {}
func LoadRSAPrivateKey(privateKeyStr string) (*rsa.PrivateKey, error) {}
func LoadRSAPublicKey(publicKeyStr string) (*rsa.PublicKey, error) {}
func GetServerIP() (ipStr string) {}
func ExtractParamValueFromURL(rawURL, paramKey string) (paramValue string) {}
func RandLetters(n int) string {}
AI
会自动给出完整实现,包括错误处理与返回值。
3.2 构建与脚本自动生成
在编写 Makefile
、Dockerfile
、一次性 Shell/Python
脚本时,AI
能根据需求直接生成较为规范的脚手架,大大缩短准备时间。
示例:
# copilot begin
.PHONY: all clean
TARGET = td2_callback_processor
all: $(TARGET)
$(TARGET):
go mod tidy && go build -o $(TARGET) main.go
clean:
rm -f $(TARGET)
# copilot end
3.3 条件判断与补全
AI
对常见模式的识别能力较强,比如判空、错误检查、切片非空判断等,能够自动续写后续逻辑,减少遗漏。
示例:
func MustGetBusinessRedis(alias string) *redis.Client {
rdb := global.BusinessRedisMap[alias]
// copilot begin
if rdb == nil {
panic(fmt.Sprintf("redis instance %s not found", alias))
}
return rdb
// copilot end
}
func doConnect(host, pass, master string) (*redis.Client, error) {
// copilot begin
// host 值校验
if host == "" {
return nil, fmt.Errorf("host can not be empty")
}
hosts := strings.Split(host, ",")
for i := range hosts {
hosts[i] = strings.TrimSpace(hosts[i])
}
if len(hosts) == 0 {
return nil, fmt.Errorf("hosts can not be empty")
}
// copilot end
}
// err == nil 意味着记录存在
// 信息未发生变更时直接返回,注意传入的管控开始时间或管控结束时间可能为 nil。为空时使用数据库存储的开始和结束时间
// copilot begin
if o.ControlStartTime == nil {
o.ControlStartTime = entityPO.ControlStartTime
}
if o.ControlEndTime == nil {
o.ControlEndTime = entityPO.ControlEndTime
}
// copilot end
3.4 结构体与常量的联想补全
定义结构体、常量或枚举时,AI
能根据上下文联想出常用字段。
示例:
const (
AppRuntimeEnvDev = "dev"
AppRuntimeEnvTest = "test"
AppRuntimeEnvPre = "pre"
AppRuntimeEnvGray = "gray"
AppRuntimeEnvProd = "prod"
)
const (
LogLevelDebug = "debug"
LogLevelInfo = "info"
LogLevelWarn = "warn"
LogLevelError = "error"
LogLevelAll = "all"
)
const (
HeaderWechatPayTimestamp = "Wechatpay-Timestamp"
HeaderWechatPaySignature = "Wechatpay-Signature"
HeaderWechatPaySignatureTestPrefix = "WECHATPAY/SIGNTEST/"
HeaderWechatPayNonce = "Wechatpay-Nonce"
HeaderWechatPaySerial = "Wechatpay-Serial"
)
// 2. 验证必要签名头是否存在
var wechatSerial string
requiredHeaders := []string{
constants.HeaderWechatPayTimestamp,
constants.HeaderWechatPayNonce,
constants.HeaderWechatPaySerial,
constants.HeaderWechatPaySignature,
}
for _, header := range requiredHeaders {
// copilot begin
if headers.Get(header) == "" {
tip = "请求头缺失必要验签字段"
err = fmt.Errorf("missing required header: %s", header)
return
}
if constants.HeaderWechatPaySerial == header {
wechatSerial = headers.Get(header)
}
// copilot end
}
3.5 序列化与反序列化
在处理 JSON
、YAML
、XML
数据时,AI
能自动生成对应的序列化或反序列化代码,尤其适合请求解析和配置文件加载。
示例:
// 5. 解析请求体
var callbackReq request.WechatCallbackRequest
// copilot begin
if err = json.Unmarshal(rawBody, &callbackReq); err != nil {
tip = "解析请求体失败"
err = fmt.Errorf("failed to unmarshal request body: %w", err)
return
}
// copilot end
// 读取 Apollo 服务器配置
var apolloConfig ApolloConfig
if bytes, err := ioutil.ReadFile(apolloConfigFile); err != nil {
return nil, err
} else {
// copilot begin
if err = yaml.Unmarshal(bytes, &apolloConfig); err != nil {
return nil, err
}
// copilot end
}
3.6 日志与调试
AI
可根据上下文选择合适的日志输出,减少思考时间并保持日志风格统一。
示例:
// copilot begin
// 打印配置内容
if configBytes, err := json.MarshalIndent(appConfig, "", "\t"); err != nil {
return nil, err
} else {
log.Printf("====< application configuration content are bleow >====\n%s", string(configBytes))
}
// copilot end
3.7 注释转代码
清晰明确的注释内容,尤其是含有步骤顺序的注释内容,能较好地补全代码。
示例:
// 1. 记录所有请求头信息
for key, values := range headers {
for _, value := range values {
log.Infof("Header %s: %s", key, value)
}
}
3.8 相似函数或逻辑联想补全
紧邻的相似函数或逻辑,有着固定的处理步骤,一般能根据上一段直接补全下一短。
示例:
// -- 查询 APIv3 密钥:F_type = 4
// select F_api3_secret_key from t_wx_sign_key_manage where F_org_id = ? and F_type = 4 and F_expire_time > now() order by F_expire_time desc limit 1;
err = db.Table(c.TableName()).
Where("F_org_id = ? and F_type = 4 and F_expire_time > now()", c.OrgID).
Order("F_expire_time desc").
Limit(1).
Pluck("F_api3_secret_key", &c.Api3SecretKey).Error
if err != nil {
return
}
resultDTO.ApiV3Secret = c.Api3SecretKey
// copilot begin
// -- 查询微信平台证书公钥:F_type = 2
// select F_certificate_serial_no, F_rsa_public_key from t_wx_sign_key_manage where F_org_id = '1502075691' and F_type = 2 and F_expire_time > now() order by F_expire_time desc limit 1;
err = db.Table(c.TableName()).
Where("F_org_id = ? and F_type = 2 and F_expire_time > now()", c.OrgID).
Order("F_expire_time desc").
Limit(1).
Pluck("F_certificate_serial_no, F_rsa_public_key", &c).Error
if err != nil {
return
}
resultDTO.WeChatSerial = c.CertificateSerialNo
resultDTO.WeChatPublicKeyStr = c.RsaPublicKey
// -- 查询商户 API 证书公私钥:F_type = 1
// select F_certificate_serial_no, F_rsa_public_key, F_rsa_private_key from t_wx_sign_key_manage where F_org_id = '1502075691' and F_type = 1 and F_expire_time > now() order by F_expire_time desc limit 1;
err = db.Table(c.TableName()).
Where("F_org_id = ? and F_type = 1 and F_expire_time > now()", c.OrgID).
Order("F_expire_time desc").
Limit(1).
Pluck("F_certificate_serial_no, F_rsa_public_key, F_rsa_private_key", &c).Error
if err != nil {
return
}
resultDTO.MerchantSerial = c.CertificateSerialNo
resultDTO.MerchantPublicKeyStr = c.RsaPublicKey
resultDTO.MerchantPrivateKeyStr = c.RsaPrivateKey
// copilot end
// 加载微信平台证书公钥
certDTO.WeChatPublicKey, err = security.LoadRSAPublicKey(certDTO.WeChatPublicKeyStr)
if err != nil {
return err
}
// copilot begin
// 加载商户 API 证书私钥
certDTO.MerchantPrivateKey, err = security.LoadRSAPrivateKey(certDTO.MerchantPrivateKeyStr)
if err != nil {
return err
}
// 加载商户 API 证书公钥
certDTO.MerchantPublicKey, err = security.LoadRSAPublicKey(certDTO.MerchantPublicKeyStr)
if err != nil {
return err
}
// copilot end
func combineAlias(node, name string) string {
return fmt.Sprintf("%s:%s", node, name)
}
func splitAlias(alias string) (string, string) {
// copilot begin
parts := strings.SplitN(alias, ":", 2)
if len(parts) == 2 {
return parts[0], parts[1]
}
return "", ""
// copilot end
}
lepayUrl := fmt.Sprintf("%s/cgi-bin/lepos_pay_gateway.cgi", global.AppCfg.Lepay.ServerUrl)
// copilot begin
reqObj, err := http.NewRequest("POST", lepayUrl, bytes.NewBuffer(reqBytes))
if err != nil {
tip = "创建请求失败"
return
}
reqObj.Header.Set("Content-Type", "application/json")
client := &http.Client{}
respObj, err := client.Do(reqObj)
if err != nil || respObj.StatusCode != http.StatusOK {
tip = "请求下单失败"
return
}
defer respObj.Body.Close()
respBody, err := ioutil.ReadAll(respObj.Body)
if err != nil {
tip = "读取下单响应失败"
return
}
// copilot end
3.9 数据循环遍历处理
针对切片或是 map
的 for-range
循环,能较好地捕获到用户意图。
示例:
func GetLepayDBList() []*gorm.DB {
var dbList []*gorm.DB
aliases := []string{
// copilot begin
constants.LepayDBNodeLG01,
constants.LepayDBNodeLG02,
constants.LepayDBNodeSH01,
constants.LepayDBNodeSH02,
// copilot end
}
for _, item := range global.AppCfg.DBList {
alias := combineAlias(item.Node, item.Name)
// copilot begin
for _, aliasItem := range aliases {
if alias == aliasItem {
dbList = append(dbList, MustGetBusinessDB(alias))
}
}
// copilot end
}
return dbList
}
3.10 数据格式转换
将 JSON
数据或是 SQL
定义语句直接转换为 Go
结构体,并且提供实体方法。
示例:
type FixedQrCode struct {}
type WeChatCertificate struct {}
type WechatCallbackRequest struct {}
type WXOWQrCodeRequest struct {}
type WXOWOrderRequest struct {}
type WXOWQrCodeResponse struct {}
type WXOWOrderResponse struct {}
四、AI 应用的扩展与思考
除了上述实际体验,AI
在编码中的应用还有许多潜在方向:
4.1 代码审查与质量优化
- 自动检测潜在
BUG
(如空指针风险、未关闭的资源等) - 指出性能隐患与命名不规范问题
4.2 单元测试与用例生成
- 自动生成覆盖率较高的单元测试
- 快速生成边界条件与异常测试用例
4.3 跨语言迁移与代码翻译
- 将核心逻辑从
Go
自动迁移到Python/Java
- 帮助团队降低异构系统之间的迁移成本
4.4 文档与注释自动化
- 自动生成
Swagger/OpenAPI
接口文档 - 基于函数签名生成简洁、规范的注释
4.5 DevOps 与自动化
- 生成
CI/CD Pipeline
脚本(如GitHub Actions
) - 辅助部署、运维脚本的编写
4.6 知识辅助与新人培养
- 通过对话形式解释项目中的关键模块,帮助新人快速熟悉系统
- 自动总结代码调用链,降低上手门槛
五、展望与趋势
- 人机协作边界:
AI
擅长快速生成80%
的基础代码,但最终的20%
仍需开发者结合业务场景做决策 - 隐私与合规性:在金融支付等高敏感场景,必须严格控制
AI
的使用边界,避免泄露关键数据 - 研发流程变革:未来代码评审可能演变为
AI 初审 + 人工把关
,大幅提升研发效率 - 行业趋势:
IDE
与AI
的深度结合将使 对话式编程 成为常态,开发体验与生产力将迎来质的飞跃
六、总结
通过本次项目实践,我深切感受到 AI
大模型在编码中的价值:它能够节省时间、减少低级错误、提升代码一致性。同时,它也引发了我们对研发方式、合规边界与未来趋势的思考。期待未来能进一步探索 “AI + 研发” 的深度结合,真正把人从重复性工作中解放出来,把精力集中在业务创新和架构设计上。
更多推荐
所有评论(0)