第4章 百花齐放的AI代码生成工具:选择最适合你的智能编程助手

在前三章中,我们深入探索了ChatGPT和GitHub Copilot这两款明星产品,了解了它们如何改变编程方式。然而,AI编程助手的生态系统远不止于此。自2023年以来,全球范围内涌现出数十款AI代码生成工具,它们各有特色:有的免费开源,有的深度集成特定云平台,有的擅长安全审查,有的则在多语言支持上表现突出。本章将带你逐一认识这些工具,并通过实战案例展示它们的使用方法,帮助你在不同场景下选择最合适的助手。

4.1 工具概览:为什么需要多种AI编程助手?

在开始详细介绍之前,先思考一个问题:既然已经有了ChatGPT和Copilot,为什么还需要其他工具?

答案在于场景多样性专业化需求。ChatGPT作为通用对话模型,在代码生成上表现出色,但它的设计初衷并非专注于编程,因此在某些编程特定任务上不如专用工具。GitHub Copilot虽然深度集成IDE,但它是付费服务,且在某些语言或框架上的表现不如一些针对特定领域优化的工具。

不同工具的优势领域:

  • ChatGPT:通用性强,适合讨论需求、设计方案、解释代码、生成示例。
  • New Bing:结合搜索引擎,能提供最新的API文档和实时信息。
  • Bard (Gemini):谷歌出品,与谷歌生态(如Colab、GCP)集成良好。
  • Claude:注重安全性和伦理,适合处理敏感代码。
  • CodeGeeX:国产免费,支持多种语言,适合个人开发者和小团队。
  • Amazon CodeWhisperer:深度集成AWS,适合云开发场景。

了解这些工具的特点,我们就能根据项目需求灵活选用,甚至组合使用,达到1+1>2的效果。

4.2 ChatGPT:全能型选手的进阶玩法

我们在第2章已经详细介绍了ChatGPT在编程中的应用,这里不再重复基础,而是展示一些进阶用法,包括生成完整工具、代码转换、添加注释、漏洞修复等实战案例。

4.2.1 生成完整代码:文件加密工具

假设我们需要一个简单的文件加密工具,使用AES算法对文件进行加密和解密。我们可以向ChatGPT提出需求,让它生成完整的Python脚本。

提示词示例

请用Python编写一个命令行文件加密工具,使用AES-256加密算法,支持加密和解密文件。需要以下功能:
1. 接受命令行参数:--encrypt <输入文件> <输出文件> 或 --decrypt <输入文件> <输出文件>
2. 使用密码派生密钥(PBKDF2)
3. 加密时生成随机IV,并与密文一起保存(例如IV放在文件开头)
4. 使用pycryptodome库
5. 包含错误处理
6. 代码风格规范,添加详细注释

ChatGPT生成的代码可能如下(我们稍作整理,确保符合Allman风格和驼峰命名):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
FileEncryptor - 使用AES-256加密文件的命令行工具
"""

import os
import sys
import argparse
import hashlib
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes

class FileEncryptor:
    """
    文件加密器,提供加密和解密功能
    """
    
    def __init__(self, password: str):
        """
        初始化加密器,从密码派生密钥
        
        Parameters:
            password (str): 用户提供的密码
        """
        
        self.password = password
        self.key = self._DeriveKey(password)
        
    def _DeriveKey(self, password: str, salt: bytes = None) -> bytes:
        """
        使用PBKDF2从密码派生密钥
        
        Parameters:
            password (str): 密码
            salt (bytes, optional): 盐值,如果为None则生成随机盐
            
        Returns:
            bytes: 派生出的32字节密钥
        """
        
        if salt is None:
            salt = get_random_bytes(16)
            
        // PBKDF2参数:密码、盐、迭代次数、密钥长度、哈希算法
        key = PBKDF2(password, salt, dkLen = 32, count = 100000, hmac_hash_module = hashlib.sha256)
        return key
        
    def EncryptFile(self, inputPath: str, outputPath: str) -> bool:
        """
        加密文件
        
        Parameters:
            inputPath (str): 输入文件路径
            outputPath (str): 输出文件路径
            
        Returns:
            bool: 成功返回True
        """
        
        try:
            // 生成随机盐和IV
            salt = get_random_bytes(16)
            iv = get_random_bytes(16)
            
            // 从密码和盐派生密钥
            key = PBKDF2(self.password, salt, dkLen = 32, count = 100000)
            
            // 创建AES cipher
            cipher = AES.new(key, AES.MODE_CBC, iv)
            
            // 读取输入文件
            with open(inputPath, 'rb') as fIn:
                plaintext = fIn.read()
                
            // PKCS7填充
            padLength = 16 - (len(plaintext) % 16)
            plaintext += bytes([padLength]) * padLength
            
            // 加密
            ciphertext = cipher.encrypt(plaintext)
            
            // 写入输出文件:盐 + IV + 密文
            with open(outputPath, 'wb') as fOut:
                fOut.write(salt)
                fOut.write(iv)
                fOut.write(ciphertext)
                
            print(f"加密成功: {outputPath}")
            return True
            
        except Exception as e:
            print(f"加密失败: {e}")
            return False
            
    def DecryptFile(self, inputPath: str, outputPath: str) -> bool:
        """
        解密文件
        
        Parameters:
            inputPath (str): 输入文件路径
            outputPath (str): 输出文件路径
            
        Returns:
            bool: 成功返回True
        """
        
        try:
            // 读取输入文件
            with open(inputPath, 'rb') as fIn:
                salt = fIn.read(16)
                iv = fIn.read(16)
                ciphertext = fIn.read()
                
            // 从密码和盐派生密钥
            key = PBKDF2(self.password, salt, dkLen = 32, count = 100000)
            
            // 创建AES cipher
            cipher = AES.new(key, AES.MODE_CBC, iv)
            
            // 解密
            plaintextPadded = cipher.decrypt(ciphertext)
            
            // 去除PKCS7填充
            padLength = plaintextPadded[-1]
            plaintext = plaintextPadded[:-padLength]
            
            // 写入输出文件
            with open(outputPath, 'wb') as fOut:
                fOut.write(plaintext)
                
            print(f"解密成功: {outputPath}")
            return True
            
        except Exception as e:
            print(f"解密失败: {e}")
            return False


def main():
    """主函数,解析命令行参数并执行加密或解密"""
    
    parser = argparse.ArgumentParser(description = "文件加密工具 (AES-256)")
    group = parser.add_mutually_exclusive_group(required = True)
    group.add_argument("--encrypt", nargs = 2, metavar = ("INPUT", "OUTPUT"),
                       help = "加密文件:输入文件 输出文件")
    group.add_argument("--decrypt", nargs = 2, metavar = ("INPUT", "OUTPUT"),
                       help = "解密文件:输入文件 输出文件")
    
    parser.add_argument("--password", required = True,
                       help = "加密密码")
    
    args = parser.parse_args()
    
    encryptor = FileEncryptor(args.password)
    
    if args.encrypt:
        inputFile, outputFile = args.encrypt
        encryptor.EncryptFile(inputFile, outputFile)
    elif args.decrypt:
        inputFile, outputFile = args.decrypt
        encryptor.DecryptFile(inputFile, outputFile)


if __name__ == "__main__":
    main()

这段代码可以直接在VS Code或VS 2022中运行(需安装pycryptodome)。ChatGPT生成的代码结构清晰,包含了错误处理,符合要求。

4.2.2 代码转换:C++到Python

假设你有一段C++代码需要转换为Python。向ChatGPT提问:“请将以下C++代码转换为Python,保持功能一致。”

C++代码示例(计算字符串中单词频率):

#include <iostream>
#include <string>
#include <map>
#include <sstream>

std::map<std::string, int> CountWords(const std::string& text) 
{
    std::map<std::string, int> freq;
    std::istringstream iss(text);
    std::string word;
    while (iss >> word) 
    {
        freq[word]++;
    }
    return freq;
}

ChatGPT转换后的Python代码:

from collections import Counter

def CountWords(text: str) -> dict:
    """
    统计字符串中每个单词出现的次数
    
    Parameters:
        text (str): 输入文本
        
    Returns:
        dict: 单词到次数的映射
    """
    
    words = text.split()
    return dict(Counter(words))

简洁高效,利用了Python的Counter。

4.2.3 为代码添加注释

我们经常接手没有注释的代码,阅读起来非常痛苦。ChatGPT可以帮我们添加注释。例如,将上面C++代码发给ChatGPT,要求“为这段代码添加详细的注释”。它会返回带注释的版本:

#include <iostream>
#include <string>
#include <map>
#include <sstream>

/**
 * 统计字符串中每个单词的出现次数
 * 
 * @param text 输入的字符串,单词由空格分隔
 * @return 一个map,键为单词,值为该单词在文本中出现的次数
 */
std::map<std::string, int> CountWords(const std::string& text) 
{
    // 创建一个map用于存储单词频率
    std::map<std::string, int> freq;
    
    // 使用istringstream将字符串分割为单词
    std::istringstream iss(text);
    std::string word;
    
    // 循环读取每个单词
    while (iss >> word) 
    {
        // 增加该单词的计数
        freq[word]++;
    }
    
    // 返回频率map
    return freq;
}

4.2.4 检查和修补代码漏洞

将一段可能有漏洞的代码(如SQL注入风险)发给ChatGPT,要求检查漏洞并提供修复方案。例如:

def GetUserData(userId):
    query = f"SELECT * FROM users WHERE id = {userId}"
    cursor.execute(query)
    return cursor.fetchall()

ChatGPT会指出SQL注入风险,并提供参数化查询的修复:

def GetUserData(userId):
    query = "SELECT * FROM users WHERE id = %s"
    cursor.execute(query, (userId,))
    return cursor.fetchall()

4.3 New Bing:搜索引擎与AI的融合

New Bing(现更名为Microsoft Copilot in Bing)结合了搜索引擎和GPT-4,能够获取最新信息。在编程中,这意味着它可以提供最新的库文档、API用法,甚至查找错误信息的最新解决方案。

4.3.1 New Bing编程辅助特点

  • 实时信息:当需要查询某个库的最新版本、函数用法时,New Bing可以搜索并给出带来源的答案。
  • 代码调试:遇到编译错误或运行时错误,将错误信息贴给New Bing,它能搜索相关解决方案。
  • 最佳实践:询问“2025年推荐的Python日志库”时,New Bing能结合最新文章给出建议。

4.3.2 实例:用New Bing查找代码错误

假设我们在编译C++代码时遇到以下错误:

undefined reference to `ssl::SSL_CTX_new(ssl::method const*)'

将错误信息发给New Bing,它会搜索并提供可能的原因和解决方案,例如缺少链接库、需要包含特定头文件等。它会给出类似以下的回答:

“这个错误通常表示链接器找不到OpenSSL库中的SSL_CTX_new函数。解决方法:在编译时添加-lssl -lcrypto选项。例如:g++ main.cpp -o app -lssl -lcrypto。如果已经添加,可能是OpenSSL版本不兼容,建议检查安装版本。”

这种基于实时搜索的能力,让New Bing在处理特定技术问题时比通用ChatGPT更有效。

4.4 Bard (Gemini):谷歌的AI编程助手

Bard是谷歌基于LaMDA和后来升级的Gemini系列模型的AI助手,与谷歌生态紧密集成。它可以直接在Google Colab中运行代码,并支持多种编程语言。

4.4.1 Bard编程能力概述

  • 多语言支持:Gemini模型对Python、JavaScript、Java等主流语言支持良好。
  • Colab集成:在Bard中生成Python代码后,可以直接导出到Google Colab运行。
  • 谷歌生态:对Google Cloud Platform(GCP)相关的代码生成有优势,例如调用Cloud Storage API、BigQuery等。

4.4.2 实例:生成数据可视化代码

假设我们需要用Python生成一个漂亮的折线图,展示某公司近几年的收入。向Bard提问:“请用Python生成一个折线图,展示2019-2025年某公司的收入数据,使用matplotlib,并添加标题、坐标轴标签和图例。”

Bard生成的代码示例:

import matplotlib.pyplot as plt

def PlotRevenue(years, revenues, companyName = "示例公司"):
    """
    绘制收入折线图
    
    Parameters:
        years (list): 年份列表
        revenues (list): 对应年份的收入列表
        companyName (str): 公司名称,用于图例
    """
    
    plt.figure(figsize = (10, 6))
    plt.plot(years, revenues, marker = 'o', linestyle = '-', linewidth = 2, markersize = 8, label = companyName)
    
    plt.title(f"{companyName} 2019-2025年收入趋势", fontsize = 16)
    plt.xlabel("年份", fontsize = 12)
    plt.ylabel("收入 (百万美元)", fontsize = 12)
    plt.grid(True, linestyle = '--', alpha = 0.7)
    plt.legend()
    plt.xticks(years)
    
    // 在数据点上标注数值
    for i, (year, revenue) in enumerate(zip(years, revenues)):
        plt.annotate(f"{revenue}", (year, revenue), textcoords = "offset points", xytext = (0, 10), ha = 'center')
        
    plt.tight_layout()
    plt.show()


if __name__ == "__main__":
    years = [2019, 2020, 2021, 2022, 2023, 2024, 2025]
    revenues = [120, 135, 150, 175, 190, 210, 240]
    PlotRevenue(years, revenues, "某科技公司")

这段代码风格符合Allman风格,函数和变量采用驼峰命名,可直接在VS Code中运行(需安装matplotlib)。

4.5 Claude:注重安全的AI助手

Claude是Anthropic公司开发的AI助手,强调安全、可靠和伦理。在编程领域,Claude擅长代码审查、安全漏洞检测,并能给出详尽的解释。

4.5.1 Claude的特点

  • 安全优先:Claude在训练中大量使用宪法AI(Constitutional AI),使其回答更符合伦理和安全准则。对于可能产生危险代码的请求,Claude会谨慎处理。
  • 长上下文:Claude 3系列支持高达200K的上下文窗口,适合处理大型代码库。
  • 细致解释:Claude倾向于详细解释代码原理和潜在问题。

4.5.2 实例:用Claude审查代码安全性

将一段可能不安全的Python代码发给Claude,要求审查。例如:

import subprocess

def RunCommand(userInput):
    command = "ls -l " + userInput
    subprocess.call(command, shell=True)

Claude会指出使用shell=True和字符串拼接可能导致的命令注入漏洞,并提供修复建议,例如使用subprocess.run的参数列表形式,避免shell=True。

4.6 CodeGeeX:国产免费的开源选择

CodeGeeX是由智谱AI开发的免费开源AI编程助手,支持多种语言,提供VS Code和JetBrains插件。它被视为GitHub Copilot的免费替代品。

4.6.1 CodeGeeX简介与安装

CodeGeeX基于多语言代码生成模型,支持Python、Java、C++、JavaScript等十几种语言。其核心功能包括代码补全、生成、翻译、注释生成等。

安装:在VS Code中搜索“CodeGeeX”并安装。安装后需要登录(可使用GitHub账号或手机号),之后即可使用。

4.6.2 代码补全实例

在VS Code中编写Python代码,输入注释,CodeGeeX会自动补全。

# 计算斐波那契数列的第n项,使用递归
def Fibonacci(n):

输入到此处,CodeGeeX会弹出建议:

def Fibonacci(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return Fibonacci(n - 1) + Fibonacci(n - 2)

4.6.3 漏洞修复与优化

CodeGeeX也提供代码优化建议。例如,针对上述递归函数,CodeGeeX可能会建议使用迭代或记忆化来优化性能。在编辑器中选中代码,右键选择“CodeGeeX: 优化代码”,它会生成优化版本:

def Fibonacci(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
        
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b

4.6.4 代码转换

CodeGeeX支持代码翻译。例如,将上述Python版本的Fibonacci转换为C++。选中代码,选择“CodeGeeX: 翻译代码”,它会生成C++版本:

#include <iostream>

int Fibonacci(int n)
{
    if (n <= 0)
    {
        return 0;
    }
    else if (n == 1)
    {
        return 1;
    }
    
    int a = 0;
    int b = 1;
    for (int i = 2; i <= n; i++)
    {
        int temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

代码采用Allman风格(左大括号换行),符合C++习惯。

4.6.5 解答任何问题

CodeGeeX的侧边栏有一个聊天窗口,可以像ChatGPT一样提问。例如询问“如何在Python中读取CSV文件”,它会给出代码示例和解释。

4.7 Amazon CodeWhisperer:云厂商的IDE集成方案

Amazon CodeWhisperer是亚马逊推出的AI编程助手,深度集成AWS服务,对云开发场景尤其友好。它提供个人免费版和专业版。

4.7.1 CodeWhisperer简介与安装

CodeWhisperer支持多种IDE,包括VS Code、IntelliJ IDEA、AWS Cloud9等。它的特色在于能够根据注释生成AWS服务的代码,例如S3、DynamoDB、Lambda函数的代码。

安装:在VS Code中搜索“AWS Toolkit”并安装,该工具包包含CodeWhisperer。安装后需要登录AWS账户(免费版无需支付)。

4.7.2 注册与配置

安装后,点击VS Code左侧的AWS图标,选择“Connect to AWS”并按照提示登录。可以选择使用AWS Builder ID(免费)或IAM身份。

4.7.3 代码生成与补全实例

在编写AWS相关代码时,CodeWhisperer能提供高度相关的建议。例如,当我们想将文件上传到S3时,输入注释:

# 上传本地文件到S3桶
def UploadToS3(bucketName, filePath, objectKey):

CodeWhisperer可能会生成以下代码(使用boto3库):

import boto3

def UploadToS3(bucketName, filePath, objectKey):
    """
    上传文件到S3桶
    
    Parameters:
        bucketName (str): S3桶名称
        filePath (str): 本地文件路径
        objectKey (str): S3中的对象键
    """
    
    s3 = boto3.client('s3')
    try:
        s3.upload_file(filePath, bucketName, objectKey)
        print(f"文件 {filePath} 已上传到 s3://{bucketName}/{objectKey}")
        return True
    except Exception as e:
        print(f"上传失败: {e}")
        return False

这段代码包含了异常处理和成功提示,非常实用。

另一个例子:生成DynamoDB查询代码。

# 从DynamoDB表中根据用户ID查询用户信息
def GetUserById(tableName, userId):

CodeWhisperer建议:

import boto3
from boto3.dynamodb.conditions import Key

def GetUserById(tableName, userId):
    """
    根据用户ID从DynamoDB查询用户
    
    Parameters:
        tableName (str): DynamoDB表名
        userId (str): 用户ID
        
    Returns:
        dict: 用户信息,如果未找到则返回None
    """
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table(tableName)
    
    try:
        response = table.get_item(Key = {'userId': userId})
        return response.get('Item')
    except Exception as e:
        print(f"查询失败: {e}")
        return None

CodeWhisperer甚至能根据常见AWS最佳实践自动加入重试逻辑,但在这个简单示例中,它生成了基础代码。

4.8 工具对比与选型建议

面对众多工具,如何选择?下表总结了各工具的特点:

工具 优点 缺点 适用场景
ChatGPT 通用性强,能讨论设计、解释代码 需要手动复制代码,无IDE集成 需求分析、方案设计、学习
New Bing 实时信息,能联网搜索 无IDE集成,需手动操作 查找最新文档、调试错误
Bard (Gemini) 与谷歌生态集成,支持Colab 部分地区访问受限 数据科学、GCP开发
Claude 安全性高,长上下文 注册门槛较高 安全审查、处理大型代码库
CodeGeeX 免费开源,IDE插件 部分功能不如Copilot成熟 个人开发者、小团队
Amazon CodeWhisperer 免费,深度集成AWS 对非AWS场景帮助一般 AWS云开发

实际工作中,可以组合使用多种工具。例如:

  • 用ChatGPT讨论整体架构,用CodeGeeX在IDE中生成代码。
  • 在AWS项目中使用CodeWhisperer快速生成S3、Lambda代码。
  • 遇到编译错误时,用New Bing搜索解决方案。
  • 对生成的代码用Claude进行安全审查。

4.9 本章小结

本章我们探索了ChatGPT之外的五款AI代码生成工具:New Bing、Bard、Claude、CodeGeeX和Amazon CodeWhisperer。每个工具都有其独特的优势和适用场景。通过丰富的代码实例,我们看到了它们如何生成完整工具、转换代码、审查漏洞、集成云服务等。

AI编程助手的生态正在快速进化,新的工具不断涌现,现有工具也在持续升级。作为开发者,我们不需要固守某一个工具,而应该保持开放心态,根据任务需求灵活选用最合适的助手,从而最大化生产力。

在下一章,我们将深入探讨如何将这些工具整合到实际项目开发流程中,从需求到部署,实现全流程的智能化辅助。敬请期待。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐