AI工具知识库

Claude vs ChatGPT:写代码谁更靠谱?

先说结论:如果你要写复杂的代码逻辑,Claude确实更靠谱一些;但如果是快速原型或者简单脚本,ChatGPT的速度优势明显。

这个结论是我用3个真实编程任务测出来的。上周末闲着没事,我决定做个对比测试,看看这两个AI到底谁更适合写代码。

测试环境很简单:同样的任务,同样的提示词,分别让Claude 3.5和ChatGPT-4o生成代码,然后看运行结果。

测试任务1:写一个Python爬虫(简单任务)

任务描述:抓取豆瓣电影Top250的电影名称、评分、评价人数,保存到CSV文件。

我给两个AI的提示词完全一样:

"写一个Python爬虫,抓取豆瓣电影Top250(https://movie.douban.com/top250),提取电影名称、评分、评价人数,保存到CSV。需要处理分页(共10页),添加请求头避免被封,包含异常处理。"

ChatGPT的代码:

import requests
from bs4 import BeautifulSoup
import csv
import time

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

movies = []
for page in range(10):
    url = f'https://movie.douban.com/top250?start={page*25}'
    try:
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')

        for item in soup.find_all('div', class_='item'):
            title = item.find('span', class_='title').text
            rating = item.find('span', class_='rating_num').text
            people = item.find('div', class_='star').find_all('span')[-1].text
            movies.append([title, rating, people])

        time.sleep(1)
    except Exception as e:
        print(f'Error: {e}')

with open('movies.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['电影名称', '评分', '评价人数'])
    writer.writerows(movies)

Claude的代码:

import requests
from bs4 import BeautifulSoup
import csv
import time
from typing import List, Dict

def fetch_page(url: str, headers: dict) -> str:
    """获取页面内容"""
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        return response.text
    except requests.RequestException as e:
        print(f"请求失败: {e}")
        return None

def parse_movies(html: str) -> List[Dict]:
    """解析电影信息"""
    soup = BeautifulSoup(html, 'html.parser')
    movies = []

    for item in soup.select('ol.grid_view > li'):
        try:
            title = item.select_one('.title').get_text()
            rating = item.select_one('.rating_num').get_text()
            people_text = item.select_one('.star span:last-child').get_text()
            people = people_text.replace('人评价', '').strip()

            movies.append({
                'title': title,
                'rating': float(rating),
                'people': people
            })
        except AttributeError as e:
            print(f"解析错误: {e}")
            continue

    return movies

def main():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }

    all_movies = []
    base_url = 'https://movie.douban.com/top250'

    for page in range(10):
        url = f'{base_url}?start={page * 25}'
        print(f"正在抓取第 {page + 1} 页...")

        html = fetch_page(url, headers)
        if html:
            movies = parse_movies(html)
            all_movies.extend(movies)
            time.sleep(1)  # 避免请求过快

    # 保存到CSV
    with open('douban_top250.csv', 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=['title', 'rating', 'people'])
        writer.writeheader()
        writer.writerows(all_movies)

    print(f"完成!共抓取 {len(all_movies)} 部电影")

if __name__ == '__main__':
    main()

运行结果:

我的评价:这个任务比较简单,两个AI都能完成。但Claude的代码明显更"工程化",有函数拆分、类型注解、错误处理。ChatGPT的代码更"脚本化",适合一次性使用。

如果你只是临时抓个数据,ChatGPT够用了。但如果这代码要给团队用,或者后续要维护,Claude的版本更合适。

测试任务2:调试一段React代码(中等难度)

任务描述:我有一段React代码,点击按钮后状态更新了,但页面没有重新渲染。让AI帮我找出问题并修复。

这是有问题的代码:

function TodoList() {
    const [todos, setTodos] = useState([
        { id: 1, text: '学习React', done: false }
    ]);

    const toggleTodo = (id) => {
        const todo = todos.find(t => t.id === id);
        todo.done = !todo.done;  // 问题在这里
        setTodos(todos);
    };

    return (
        <div>
            {todos.map(todo => (
                <div key={todo.id} onClick={() => toggleTodo(todo.id)}>
                    {todo.text} - {todo.done ? '已完成' : '未完成'}
                </div>
            ))}
        </div>
    );
}

ChatGPT的回答:

"问题在于你直接修改了原数组中的对象,React检测不到变化。应该创建新数组:"

const toggleTodo = (id) => {
    setTodos(todos.map(todo =>
        todo.id === id ? { ...todo, done: !todo.done } : todo
    ));
};

Claude的回答:

"这是React中常见的状态不可变性问题。你直接修改了对象属性(todo.done = !todo.done),然后传入了同一个数组引用,React的浅比较认为状态没变,所以不会重新渲染。

有两种修复方式:

方式1(推荐):使用map创建新数组"

const toggleTodo = (id) => {
    setTodos(prevTodos =>
        prevTodos.map(todo =>
            todo.id === id ? { ...todo, done: !todo.done } : todo
        )
    );
};

方式2:使用immer库(适合复杂状态)"

import { produce } from 'immer';

const toggleTodo = (id) => {
    setTodos(produce(draft => {
        const todo = draft.find(t => t.id === id);
        if (todo) todo.done = !todo.done;
    }));
};

运行结果:两个方案都能解决问题。

我的评价:ChatGPT直接给了解决方案,快速有效。但Claude不仅给了方案,还解释了为什么会出现这个问题(React的浅比较机制),并且提供了两种不同的解决思路。

如果你只是想快速修bug,ChatGPT够用。但如果你想理解原理,或者需要在多个方案中选择,Claude的回答更有价值。

测试任务3:重构一个复杂函数(高难度)

任务描述:有一个处理订单的函数,逻辑很乱,嵌套了5层if-else,让AI帮我重构。

原始代码大概长这样(简化版):

function processOrder(order) {
    if (order.status === 'pending') {
        if (order.paymentMethod === 'credit_card') {
            if (order.amount > 1000) {
                if (order.user.vipLevel >= 3) {
                    // 处理逻辑1
                } else {
                    // 处理逻辑2
                }
            } else {
                // 处理逻辑3
            }
        } else if (order.paymentMethod === 'alipay') {
            // 更多嵌套...
        }
    } else if (order.status === 'paid') {
        // 又是一堆嵌套...
    }
    // 还有更多...
}

ChatGPT的重构方案:把嵌套的if-else改成了提前return(guard clauses),代码扁平了很多。

Claude的重构方案:除了提前return,还建议我:

  1. 把不同的支付方式拆成独立的处理函数
  2. 用策略模式(Strategy Pattern)管理不同的订单状态
  3. 把业务规则(比如"VIP3以上且金额>1000")抽取成独立的判断函数

Claude还给了一个完整的重构示例,代码量比原来多了一些,但可读性和可维护性提升了一大截。

我的评价:这个任务最能体现两个AI的差异。ChatGPT的重构"够用",解决了最明显的问题。但Claude的重构更"专业",考虑到了后续的扩展性和维护性。

如果你是在写一次性脚本,ChatGPT的方案就够了。但如果这是个要长期维护的项目,Claude的方案更值得采纳。

测试过程中的一个意外

在测试任务2的时候,我发现了一个有意思的现象:Claude会主动指出代码中的潜在问题

比如在那段React代码里,除了主要的bug,Claude还提醒我:"你的key用的是todo.id,如果后续支持删除功能,可能会有性能问题,建议用uuid或者其他唯一标识。"

ChatGPT就没有这个"多嘴"的习惯,你问什么它答什么,不会主动扩展。

这个特点是好是坏,取决于你的需求。如果你只想快速解决问题,ChatGPT的"专注"更高效。但如果你想学习或者避免踩坑,Claude的"多嘴"反而是优点。

一些具体的使用感受

代码风格:

响应速度:

错误处理:

解释能力:

所以到底选哪个?

说实话,没有绝对的答案,看你的使用场景

选ChatGPT的情况:

选Claude的情况:

我个人的做法是:两个都用。简单任务用ChatGPT快速搞定,复杂任务用Claude仔细打磨。有时候我还会让两个AI都生成一遍,然后取长补短。

一个小争议

测试完之后,我把结果发到了技术群里。有个同事提出了一个观点:"Claude生成的代码太'过度设计'了,很多时候用不上那么复杂的模式。"

这个观点我部分同意。确实,如果你只是写个小工具,Claude的"工程化"思维有时候会显得有点重。但反过来说,如果你是在做一个要长期维护的项目,这种"过度设计"反而能省下后续的重构成本。

所以这不是谁对谁错的问题,而是你的项目处于什么阶段。MVP阶段追求速度,用ChatGPT;产品成熟期追求稳定,用Claude。

最后

这次测试只是我个人的体验,不代表绝对的结论。AI工具更新很快,说不定过几个月,ChatGPT和Claude的差距就缩小了,或者出现了新的竞争者。

但有一点是确定的:AI写代码已经是现实了,而且会越来越好。与其纠结用哪个工具,不如多想想怎么把这些工具用好。

毕竟,工具只是工具,真正重要的是你的思路和判断。