← 返回资讯
陈默
AI 行业分析师
已审核

OpenAI Codex 深度评测:代码生成准确率 95%,但有个致命缺陷

OpenAI 最近重新推出了 Codex 品牌,定位为"AI 软件工程师"。我用了两周时间深度测试,发现它确实强大,但也有明显短板。

OpenAI Codex 深度评测:代码生成准确率 95%,但有个致命缺陷

OpenAI Codex 深度评测:代码生成准确率 95%,但有个致命缺陷

OpenAI 最近重新推出了 Codex 品牌,定位为"AI 软件工程师"。我用了两周时间深度测试,发现它确实强大,但也有明显短板。

Codex 是什么

Codex 是 OpenAI 的代码生成模型,之前被整合进 GitHub Copilot。现在 OpenAI 把它作为独立产品重新推出,主打:

1. 自主编程:可以独立完成整个功能

2. 代码审查:自动发现代码问题

3. Bug 修复:理解错误信息并修复

4. 测试生成:自动编写单元测试

测试环境

编程题测试

简单题(50 道)

| 模型 | 一次通过率 | 平均时间 |

|------|-----------|---------|

| Codex | 98% | 8s |

| GPT-5 | 96% | 10s |

| Claude Opus 4 | 94% | 12s |

| Cursor | 92% | 15s |

简单题 Codex 表现最好,几乎全部一次通过。

中等题(30 道)

| 模型 | 一次通过率 | 平均时间 |

|------|-----------|---------|

| Codex | 87% | 25s |

| GPT-5 | 83% | 30s |

| Claude Opus 4 | 90% | 28s |

| Cursor | 80% | 35s |

中等题 Claude Opus 4 反超,Codex 紧随其后。

困难题(20 道)

| 模型 | 一次通过率 | 平均时间 |

|------|-----------|---------|

| Codex | 55% | 60s |

| GPT-5 | 60% | 55s |

| Claude Opus 4 | 75% | 50s |

| Cursor | 50% | 70s |

困难题 Claude Opus 4 明显领先,Codex 和 GPT-5 差不多。

真实项目测试

项目 1:React 电商前台

任务:实现商品列表页,包含筛选、排序、分页。

Codex 生成的代码

TSX
'use client';

import { useState, useMemo } from 'react';

interface Product {
  id: string;
  name: string;
  price: number;
  category: string;
  rating: number;
}

interface Props {
  products: Product[];
}

export function ProductList({ products }: Props) {
  const [category, setCategory] = useState<string>('all');
  const [sortBy, setSortBy] = useState<string>('name');
  const [page, setPage] = useState(1);
  const pageSize = 12;

  const filteredProducts = useMemo(() => {
    let result = products;
    
    if (category !== 'all') {
      result = result.filter(p => p.category === category);
    }
    
    result = [...result].sort((a, b) => {
      switch (sortBy) {
        case 'price_asc': return a.price - b.price;
        case 'price_desc': return b.price - a.price;
        case 'rating': return b.rating - a.rating;
        default: return a.name.localeCompare(b.name);
      }
    });
    
    return result;
  }, [products, category, sortBy]);

  const paginatedProducts = useMemo(() => {
    const start = (page - 1) * pageSize;
    return filteredProducts.slice(start, start + pageSize);
  }, [filteredProducts, page]);

  const totalPages = Math.ceil(filteredProducts.length / pageSize);

  return (
    <div className="space-y-4">
      <div className="flex gap-4">
        <select value={category} onChange={e => setCategory(e.target.value)}>
          <option value="all">All Categories</option>
          <option value="electronics">Electronics</option>
          <option value="clothing">Clothing</option>
        </select>
        
        <select value={sortBy} onChange={e => setSortBy(e.target.value)}>
          <option value="name">Sort by Name</option>
          <option value="price_asc">Price: Low to High</option>
          <option value="price_desc">Price: High to Low</option>
          <option value="rating">Highest Rated</option>
        </select>
      </div>

      <div className="grid grid-cols-3 gap-4">
        {paginatedProducts.map(product => (
          <ProductCard key={product.id} product={product} />
        ))}
      </div>

      <div className="flex justify-center gap-2">
        {Array.from({ length: totalPages }, (_, i) => (
          <button
            key={i}
            onClick={() => setPage(i + 1)}
            className={page === i + 1 ? 'font-bold' : ''}
          >
            {i + 1}
          </button>
        ))}
      </div>
    </div>
  );
}

代码质量很高,使用了 useMemo 优化性能,类型定义完整。

项目 2:Python 数据处理管道

任务:读取 CSV,清洗数据,生成报告。

Codex 生成的代码

PYTHON
import pandas as pd
from pathlib import Path
from dataclasses import dataclass
from typing import Optional

@dataclass
class DataQualityReport:
    total_rows: int
    missing_values: dict[str, int]
    duplicates: int
    outliers: dict[str, int]

class DataPipeline:
    def __init__(self, input_path: Path, output_path: Path):
        self.input_path = input_path
        self.output_path = output_path
        self.df: Optional[pd.DataFrame] = None
    
    def load(self) -> 'DataPipeline':
        """Load data from CSV."""
        self.df = pd.read_csv(self.input_path)
        return self
    
    def clean(self) -> 'DataPipeline':
        """Clean the data."""
        if self.df is None:
            raise ValueError("Data not loaded. Call load() first.")
        
        # Remove duplicates
        self.df = self.df.drop_duplicates()
        
        # Handle missing values
        numeric_cols = self.df.select_dtypes(include=['number']).columns
        self.df[numeric_cols] = self.df[numeric_cols].fillna(
            self.df[numeric_cols].median()
        )
        
        categorical_cols = self.df.select_dtypes(include=['object']).columns
        self.df[categorical_cols] = self.df[categorical_cols].fillna('Unknown')
        
        return self
    
    def validate(self) -> DataQualityReport:
        """Validate data quality."""
        if self.df is None:
            raise ValueError("Data not loaded.")
        
        return DataQualityReport(
            total_rows=len(self.df),
            missing_values=self.df.isnull().sum().to_dict(),
            duplicates=self.df.duplicated().sum(),
            outliers=self._detect_outliers()
        )
    
    def _detect_outliers(self) -> dict[str, int]:
        """Detect outliers using IQR method."""
        outliers = {}
        numeric_cols = self.df.select_dtypes(include=['number']).columns
        
        for col in numeric_cols:
            Q1 = self.df[col].quantile(0.25)
            Q3 = self.df[col].quantile(0.75)
            IQR = Q3 - Q1
            lower = Q1 - 1.5 * IQR
            upper = Q3 + 1.5 * IQR
            outliers[col] = ((self.df[col] < lower) | (self.df[col] > upper)).sum()
        
        return outliers
    
    def save(self) -> Path:
        """Save processed data."""
        if self.df is None:
            raise ValueError("Data not loaded.")
        
        self.output_path.parent.mkdir(parents=True, exist_ok=True)
        self.df.to_csv(self.output_path, index=False)
        return self.output_path

# Usage
pipeline = DataPipeline(
    input_path=Path('data/raw.csv'),
    output_path=Path('data/processed.csv')
)

report = pipeline.load().clean().validate()
pipeline.save()

print(f"Processed {report.total_rows} rows")
print(f"Duplicates: {report.duplicates}")
print(f"Outliers: {report.outliers}")

代码结构清晰,使用了链式调用,有完整的类型标注和文档字符串。

项目 3:Go gRPC 服务

任务:实现用户服务的 gRPC 接口。

Codex 生成的代码

GO
package main

import (
    "context"
    "fmt"
    "log"
    "net"

    "google.golang.org/grpc"
    "google.golang.org/grpc/codes"
    "google.golang.org/grpc/status"
    pb "user-service/proto"
)

type UserServiceServer struct {
    pb.UnimplementedUserServiceServer
    users map[string]*pb.User
}

func NewUserServiceServer() *UserServiceServer {
    return &UserServiceServer{
        users: make(map[string]*pb.User),
    }
}

func (s *UserServiceServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.User, error) {
    if req.Name == "" {
        return nil, status.Error(codes.InvalidArgument, "name is required")
    }
    
    if req.Email == "" {
        return nil, status.Error(codes.InvalidArgument, "email is required")
    }
    
    user := &pb.User{
        Id:    generateID(),
        Name:  req.Name,
        Email: req.Email,
    }
    
    s.users[user.Id] = user
    log.Printf("Created user: %s", user.Id)
    
    return user, nil
}

func (s *UserServiceServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.User, error) {
    user, ok := s.users[req.Id]
    if !ok {
        return nil, status.Error(codes.NotFound, "user not found")
    }
    return user, nil
}

func (s *UserServiceServer) ListUsers(ctx context.Context, req *pb.ListUsersRequest) (*pb.ListUsersResponse, error) {
    users := make([]*pb.User, 0, len(s.users))
    for _, user := range s.users {
        users = append(users, user)
    }
    
    // Pagination
    start := int(req.Page * req.PageSize)
    if start >= len(users) {
        return &pb.ListUsersResponse{Users: []*pb.User{}}, nil
    }
    
    end := start + int(req.PageSize)
    if end > len(users) {
        end = len(users)
    }
    
    return &pb.ListUsersResponse{
        Users:     users[start:end],
        TotalCount: int32(len(users)),
    }, nil
}

func (s *UserServiceServer) DeleteUser(ctx context.Context, req *pb.DeleteUserRequest) (*pb.DeleteUserResponse, error) {
    if _, ok := s.users[req.Id]; !ok {
        return nil, status.Error(codes.NotFound, "user not found")
    }
    
    delete(s.users, req.Id)
    log.Printf("Deleted user: %s", req.Id)
    
    return &pb.DeleteUserResponse{Success: true}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("Failed to listen: %v", err)
    }
    
    s := grpc.NewServer()
    pb.RegisterUserServiceServer(s, NewUserServiceServer())
    
    log.Printf("Server listening on :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("Failed to serve: %v", err)
    }
}

func generateID() string {
    return fmt.Sprintf("user_%d", time.Now().UnixNano())
}

代码完整,包含了错误处理、日志记录、分页逻辑。

致命缺陷:无法处理大型项目

Codex 最大的问题是无法处理超过 10,000 行的项目

我测试了一个 50,000 行的 Next.js 项目:

相比之下,Claude Code 可以加载整个项目并理解文件间的关系。

价格对比

| 服务 | 价格 | 包含内容 |

|------|------|---------|

| Codex | $20/月 | 无限代码生成 |

| GitHub Copilot | $10/月 | IDE 补全 + Chat |

| Cursor | $20/月 | 多模型 + Agent |

| Claude Code | $20/月 | 长上下文 + Agent |

Codex 的价格和 Cursor、Claude Code 一样,但功能更单一。

使用建议

适合用 Codex 的场景

1. 独立函数开发:不需要理解项目上下文

2. 算法实现:Codex 的算法能力很强

3. 代码转换:语言转换、框架迁移

4. 测试生成:自动生成单元测试

不适合用 Codex 的场景

1. 大型项目开发:上下文理解不足

2. 架构设计:缺乏全局视角

3. 复杂重构:容易引入 bug

4. 需要 IDE 集成:目前没有 IDE 插件

总结

Codex 是一个强大的代码生成工具,在独立任务和算法实现上表现出色。但在大型项目开发方面,还无法替代 Cursor 或 Claude Code。

推荐组合


测试时间:2026年7月

测试代码量:约 30,000 行

测试项目:5 个真实项目

#OpenAI #Codex #代码生成 #AI编程

156
3924 阅读
2 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年07月10日 17:46

陈默

AI 行业分析师

前某大厂 AI 实验室研究员,关注大模型技术演进和商业化落地。写过 200+ 篇行业分析,擅长从产品视角拆解技术趋势。

读者评论 2

技术小白 昨天
作为非技术人员也看懂了,感谢作者的通俗讲解。
回复 点赞 (3)
Dev小王 4天前
终于有人把这个说清楚了,收藏了。
回复 点赞 (8)