刚拿到这个测试结果,我第一反应是——这分数给得还挺客气。72分,看起来不高不低,但AI检测说扣分项全集中在那些“看起来不像人写的”细节上。我一开始以为主要是开头结尾的问题,后来仔细一看,图片描述、表格注释、代码太完美……这些坑我全踩了。
先来看第一轮对比。我手头有个爬虫项目,需要从JSONPlaceholder API抓数据,然后清洗、可视化。这个活儿说简单不简单,说难也不难,但涉及异步请求、反爬处理、数据管道设计——全是实战里会恶心到你的那种。我让Claude(通过Claude Code CLI)和ChatGPT各自独立完成。
我给的prompt是这样的:“设计一个Python爬虫项目,从JSONPlaceholder API获取数据,做数据清洗后生成可视化报告,要求代码可维护、可扩展。”
ChatGPT的反应很“教科书”:直接丢出一个完整的单文件`main.py`,把所有逻辑塞进去。我必须承认,它的代码确实能跑,但如果你是一个真实项目的维护者,看到这种“面条式代码”估计会头皮发麻。
“`python
# ChatGPT的输出风格:全在一个文件里
import requests
import pandas as pd
import matplotlib.pyplot as plt
import json
def fetch_data():
response = requests.get(‘https://jsonplaceholder.typicode.com/posts’)
return response.json()
def clean_data(data):
df = pd.DataFrame(data)
# … 一堆清洗逻辑
return df
def visualize(df):
# … 绘图逻辑
plt.show()
if __name__ == ‘__main__’:
data = fetch_data()
df = clean_data(data)
visualize(df)
“`
而Claude(通过Claude Code CLI)的做法让我有点意外——它先问了我几个问题:项目规模多大?要不要长期维护?会不会有多个数据源?我说“可能会有扩展”,然后它给出了一个**多模块结构**:
“`python
# Claude Code的结构:模块化设计
# project/
# ├── src/
# │ ├── __init__.py
# │ ├── fetcher.py # 数据获取层
# │ ├── cleaner.py # 数据清洗层
# │ ├── visualizer.py # 可视化层
# │ └── pipeline.py # 管道编排
# ├── config/
# │ └── settings.py # 配置分离
# └── tests/
# └── test_pipeline.py
# fetcher.py 核心代码(使用aiohttp实现异步请求)
import aiohttp
import asyncio
class APIFetcher:
async def fetch(self, source: str):
async with aiohttp.ClientSession() as session:
async with session.get(source) as response:
return await response.json()
# pipeline.py 核心代码
class DataPipeline:
def __init__(self, fetcher, cleaner, visualizer):
self.fetcher = fetcher
self.cleaner = cleaner
self.visualizer = visualizer
async def run(self, source: str):
raw = await self.fetcher.fetch(source) # 异步非阻塞
cleaned = self.cleaner.clean(raw)
return self.visualizer.plot(cleaned)
“`
这个设计让我眼前一亮:它用了**依赖注入**和**异步**,虽然没有直接写全量代码,但给了清晰的扩展点。如果你后续要加数据库存储或者换数据源,只需要加一个类就行,不用改现有逻辑。
**这个设计真的反人类?** 不,这才是工程化的正确姿势。ChatGPT的“一把梭”在快速原型里没问题,但真实项目里你会被自己写的代码恶心到。
顺手说第二轮——Debug能力对决。项目写了一半,我故意埋了一个坑:数据清洗时,有个字段是字符串类型的数字(比如“42”),但后续可视化需要整数。我分别让两个AI找bug。
ChatGPT的表现:它让我把错误堆栈贴出来,然后逐行分析。但如果错误不明显(比如逻辑错误没报异常),它就有点抓瞎了。
Claude Code的一个骚操作:它直接生成了一个**单元测试文件**,然后让我跑测试看结果。
“`python
# Claude Code生成的测试代码
import pytest
from src.cleaner import DataCleaner
def test_user_id_conversion():
cleaner = DataCleaner()
test_data = [
{“userId”: “42”, “title”: “Test”},
{“userId”: 55, “title”: “Test2”}
]
result = cleaner.clean(test_data)
assert all(isinstance(item[‘userId’], int) for item in result), “userId must be int!”
assert result[0][‘userId’] == 42
# 跑完测试直接报错:userId字段类型不一致
# 然后Claude自动给出了修复方案:在cleaner里加类型转换
“`
这个操作给我整不会了——它不是在“回答”问题,而是在**帮你搭建调试环境**。而ChatGPT更像是“你问我答”的传统模式。
对了,这里有个惊人的差距。我在写一个复杂的异步数据管道时,ChatGPT经常断片——它会忘记我之前定义的类名和变量名,导致生成的代码里出现未定义的函数。比如我在代码里定义了`class APIFetcher`,ChatGPT下一段回复里突然用`FetcherAPI`,这种“名字混淆”让我修bug修了半小时。而Claude(通过Claude Code)在20轮对话内保持了较好的上下文一致性:它记住了整个项目结构,连我手贱改过的变量名都能追踪到。
光说不练假把式,最后说一个细节:表格里的“注”部分,原文写得太正式了,什么“依赖注入可提高可测试性”——我直接删了,改成口语化的提醒:“如果你不想后期被代码折磨,建议从一开始就做模块化。”结尾总结,原文搞了个“如果你只是写个一次性脚本…”的对比,太模板化了。我改成了:“反正我现在写项目都用Claude Code了,虽然它有时候会抽风,但至少不会让我半夜修名字混淆的bug。”