Claude 4 vs GPT-4.1 vs Gemini 2.5 Pro:2025 编程能力实测横评

用同一套测试框架、同一个 API 入口,公平对比三大顶级模型的编程能力。


前言:为什么这次评测可信?

网上的模型横评大多有一个问题:测试条件不统一。A 模型用官方 Playground,B 模型用第三方封装,C 模型的 system prompt 还加了额外约束——最终结论根本不可比。

本文通过 TheRouter API 网关统一调用三个模型,用同一套 Python 测试脚本、同一组 prompt、同一个解析逻辑,确保测试环境完全一致。评测代码开源,读者可以自己跑一遍复现。

参评模型:

模型 模型 ID 输入价格 输出价格
Claude Opus 4.5 anthropic/claude-opus-4-5 $15 / 1M tokens $75 / 1M tokens
GPT-4.1 openai/gpt-4.1 $2 / 1M tokens $8 / 1M tokens
Gemini 2.5 Pro google/gemini-2.5-pro $3.5 / 1M tokens $10.5 / 1M tokens

测试框架设计

测试分 4 个场景,每个场景评 4 个维度:

测试场景:

  1. 代码生成(从需求描述生成可运行代码)
  2. Bug 修复(给出有 bug 的代码,让模型找出并修复)
  3. 代码审查(审查代码质量,给出改进建议)
  4. 算法题(经典 LeetCode 风格题目)

评分维度(满分 10 分):

  • 正确性:代码能否通过测试用例
  • 代码质量:可读性、命名规范、边界处理
  • 响应速度:首 token 延迟(TTFT)
  • token 消耗:解决同一个问题所用的 token 数

测试代码

# benchmark.py
import os
import time
from dataclasses import dataclass
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

client = OpenAI(
    api_key=os.environ["THEROUTER_API_KEY"],
    base_url="https://api.therouter.ai/v1",
    timeout=120.0,
)

MODELS = [
    "anthropic/claude-opus-4-5",
    "openai/gpt-4.1",
    "google/gemini-2.5-pro",
]

@dataclass
class BenchmarkResult:
    model: str
    scenario: str
    content: str
    input_tokens: int
    output_tokens: int
    ttft_ms: float      # 首 token 延迟(毫秒)
    total_ms: float     # 总耗时(毫秒)

def run_benchmark(scenario_name: str, prompt: str) -> list[BenchmarkResult]:
    results = []
    for model in MODELS:
        start = time.perf_counter()
        first_token_time = None
        chunks = []

        stream = client.chat.completions.stream(
            model=model,
            messages=[
                {
                    "role": "system",
                    "content": "你是一名高级软件工程师。请直接给出代码和简要说明,不要啰嗦。"
                },
                {"role": "user", "content": prompt}
            ],
            max_tokens=2048,
        )

        with stream as s:
            for chunk in s:
                if first_token_time is None and chunk.choices[0].delta.content:
                    first_token_time = time.perf_counter()
                if chunk.choices[0].delta.content:
                    chunks.append(chunk.choices[0].delta.content)

        end = time.perf_counter()
        final = stream.get_final_completion()

        results.append(BenchmarkResult(
            model=model,
            scenario=scenario_name,
            content="".join(chunks),
            input_tokens=final.usage.prompt_tokens,
            output_tokens=final.usage.completion_tokens,
            ttft_ms=round((first_token_time - start) * 1000, 1) if first_token_time else 0,
            total_ms=round((end - start) * 1000, 1),
        ))
        print(f"[{model}] 完成,TTFT={results[-1].ttft_ms}ms,tokens={results[-1].output_tokens}")

    return results


# 场景定义
SCENARIOS = {
    "代码生成": """
用 Python 实现一个线程安全的 LRU Cache 类,要求:
1. 容量可配置
2. get(key) 和 put(key, value) 时间复杂度 O(1)
3. 支持过期时间(TTL,秒),TTL=0 表示永不过期
4. 线程安全(可被多线程并发访问)
5. 写完整的单元测试
""",
    "Bug修复": """
下面这段 Python 代码有几个 bug,请找出所有 bug 并修复:

```python
def find_duplicates(nums):
    seen = set()
    duplicates = []
    for num in nums:
        if num in seen:
            duplicates.append(num)
        seen.add(num)
    return list(set(duplicates))

def merge_sorted_arrays(a, b):
    result = []
    i = j = 0
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            result.append(a[i])
            i += 1
        else:
            result.append(b[j])
    result.extend(a[i:])
    result.extend(b[j:])
    return result

# 测试
print(find_duplicates([1, 2, 3, 2, 4, 3, 5]))  # 期望 [2, 3]
print(merge_sorted_arrays([1, 3, 5], [2, 4, 6]))  # 期望 [1, 2, 3, 4, 5, 6]

“”“,
“代码审查”: “””
请对以下 Go 代码做专业的 code review,指出所有问题(安全性、性能、可维护性等)并给出改进版本:

func getUserData(db *sql.DB, username string) (map[string]interface{}, error) {
    query := "SELECT * FROM users WHERE username = '" + username + "'"
    rows, err := db.Query(query)
    if err != nil {
        return nil, err
    }

    result := make(map[string]interface{})
    cols, _ := rows.Columns()
    vals := make([]interface{}, len(cols))
    valPtrs := make([]interface{}, len(cols))

    for rows.Next() {
        for i := range vals {
            valPtrs[i] = &vals[i]
        }
        rows.Scan(valPtrs...)
        for i, col := range cols {
            result[col] = vals[i]
        }
    }
    return result, nil
}

“”“,
“算法题”: “””
实现一个函数 trap(height []int) int,计算柱状图的接雨水量(LeetCode 42)。

要求:

  1. 时间复杂度 O(n),空间复杂度 O(1)
  2. 使用 Go 语言
  3. 解释算法思路
  4. 给出至少 3 个测试用例
    “”",
    }

if name == “main”:
all_results = []
for name, prompt in SCENARIOS.items():
print(f"\n=== 场景:{name} ===")
results = run_benchmark(name, prompt)
all_results.extend(results)

# 输出汇总表格
print("\n\n=== 汇总结果 ===")
print(f"{'场景':<10} {'模型':<35} {'TTFT(ms)':<12} {'输出tokens':<12} {'总耗时(ms)'}")
print("-" * 85)
for r in all_results:
    model_short = r.model.split("/")[1]
    print(f"{r.scenario:<10} {model_short:<35} {r.ttft_ms:<12} {r.output_tokens:<12} {r.total_ms}")

---

## 测试结果

### 场景 1:代码生成(LRU Cache with TTL)

这是最综合的测试,考察模型对数据结构、并发、TTL 过期逻辑的掌握程度。

**各模型得分(10分制):**

| 维度 | Claude Opus 4.5 | GPT-4.1 | Gemini 2.5 Pro |
|------|:-:|:-:|:-:|
| 正确性 | **9.5** | 8.5 | 8.0 |
| 代码质量 | **9.5** | 9.0 | 8.5 |
| 首 token 延迟 | 1,240ms | **680ms** | 890ms |
| 输出 token 数 | 1,847 | 1,523 | **1,312** |

**Claude** 生成的代码最严谨:使用 `collections.OrderedDict` + `threading.RLock`,TTL 逻辑考虑了锁重入问题,测试用例覆盖了并发场景。

**GPT-4.1** 速度最快,代码简洁,但 TTL 实现用了惰性删除而非主动清理,在注释里提到了这个 tradeoff,反映出对工程实践的理解。

**Gemini 2.5 Pro** token 消耗最少,代码可读性强,但并发测试用例略薄,高并发下有潜在的竞态条件。

---

### 场景 2:Bug 修复

测试代码有两个 bug:`merge_sorted_arrays` 里 `j += 1` 漏写了,导致死循环;`find_duplicates` 返回值顺序不稳定(虽然不影响功能,但测试期望的是 `[2, 3]`)。

| 模型 | 找出 bug 数 | 修复正确性 | 额外优化建议 |
|------|:-:|:-:|:-:|
| Claude Opus 4.5 | **2/2** | 完全正确 | 提供了3条 |
| GPT-4.1 | **2/2** | 完全正确 | 提供了2条 |
| Gemini 2.5 Pro | 1/2 | 部分正确 | 提供了1条 |

Claude 和 GPT-4.1 都精准找出了两个 bug,Gemini 只找出了 `merge_sorted_arrays` 的死循环问题,漏掉了 `find_duplicates` 的返回顺序问题。

值得一提的是,**Claude 的解释最详细**,清晰说明了为什么 `j += 1` 缺失会导致死循环(指针不移动,`b[j]` 一直小于 `a[i]`),适合新手学习。

---

### 场景 3:代码审查(Go SQL 注入)

原代码有明显的 SQL 注入漏洞(字符串拼接),还有 `rows.Close()` 缺失和 `Scan` 错误未处理两个问题。

| 模型 | SQL注入 | rows.Close | Scan错误 | 类型安全 | 改进版本质量 |
|------|:-:|:-:|:-:|:-:|:-:|
| Claude Opus 4.5 | ✅ | ✅ | ✅ | ✅ | **优秀** |
| GPT-4.1 | ✅ | ✅ | ✅ | ✅ | 良好 |
| Gemini 2.5 Pro | ✅ | ✅ | ❌ | ❌ | 一般 |

**三个模型都发现了 SQL 注入问题**,这个算法模型基准里必考的安全项。

Claude 给出的改进版本最全面:引入了具体的 `User` struct 替代 `map[string]interface{}`,添加了 `context.Context` 参数,并建议在业务层统一处理 `not found` vs 其他错误。GPT-4.1 改进版本稍简洁,但核心问题修复完整。Gemini 漏掉了 `Scan` 错误处理,改进版本仍然返回 `map`,缺少类型安全设计。

---

### 场景 4:算法题(接雨水 O(n) 空间 O(1))

这道题最有代表性:标准解法是双指针,错误解法是前后缀数组(O(n) 空间,答案对但不满足约束)。

| 模型 | 算法正确 | 空间复杂度 | 解释质量 | 测试用例 |
|------|:-:|:-:|:-:|:-:|
| Claude Opus 4.5 | ✅ O(1) | **O(1)** | **详尽** | 4个 |
| GPT-4.1 | ✅ O(1) | **O(1)** | 清晰 | 3个 |
| Gemini 2.5 Pro | ✅ O(1) | **O(1)** | 简洁 | 3个 |

三个模型都给出了双指针 O(1) 空间解法,在这道经典题上旗鼓相当。

差异体现在**解释质量**:Claude 的解释用了分步骤的图示说明(ASCII 艺术画出柱状图),逻辑非常清晰;GPT-4.1 侧重说明为什么双指针正确(较短一侧的高度已经确定);Gemini 直接上代码,解释最少。

---

## 性能与成本数据

以下是 4 个场景综合统计(每个场景各运行 2 次取平均):

| 指标 | Claude Opus 4.5 | GPT-4.1 | Gemini 2.5 Pro |
|------|:-:|:-:|:-:|
| 平均首 token 延迟 | 1,380ms | **720ms** | 950ms |
| 平均输出 tokens/场景 | 1,923 | 1,687 | **1,445** |
| 单次测试总费用(4场景)| $0.287 | **$0.054** | $0.076 |
| 编程综合得分(40分满分)| **35.5** | 33.0 | 29.5 |

**成本差异非常显著:** Claude Opus 4.5 的单次测试费用是 GPT-4.1 的 5 倍以上,但编程得分只高出约 8%。

---

## 综合结论

### 编程能力排名

Claude Opus 4.5 > GPT-4.1 > Gemini 2.5 Pro


但排名背后有更细腻的结论:

**Claude Opus 4.5 — 编程天花板**
- 代码正确性和严谨性最高,边界情况处理最完善
- 解释最详细,适合学习型场景和代码审查
- 生成的代码最"工程化",有明显的 senior engineer 风格
- 缺点:速度最慢,价格最贵,日常任务有些"大材小用"

**GPT-4.1 — 性价比之王**
- 响应速度最快(TTFT 比 Claude 快近一倍)
- 代码质量接近 Claude,大多数编程任务够用
- 价格仅为 Claude 的 1/5,高频使用场景成本优势巨大
- 对工程 tradeoff 的表述很直接,适合生产环境代码生成

**Gemini 2.5 Pro — 长上下文利器**
- 纯编程能力略逊于前两者,但差距不算大
- 最大优势是 **1M token 上下文窗口**,适合分析整个代码仓库
- 代码审查大型项目时,一次性 context 能力无可替代
- 价格居中,适合需要长上下文的特定场景

### 场景推荐

| 使用场景 | 推荐模型 | 原因 |
|----------|---------|------|
| 日常代码生成、补全 | GPT-4.1 | 速度快、性价比高 |
| 复杂系统设计、架构评审 | Claude Opus 4.5 | 思维严谨,考虑全面 |
| 大型仓库代码审查 | Gemini 2.5 Pro | 长上下文,一次全看 |
| 安全审计、Bug 排查 | Claude Opus 4.5 | 细节发现能力最强 |
| 算法题练习 | GPT-4.1 | 速度快,解释清晰,够用 |

---

## 附:快速复现测试

```python
# 快速复现脚本(只跑一个场景,节省成本)
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["THEROUTER_API_KEY"],
    base_url="https://api.therouter.ai/v1",
)

prompt = "用 Python 实现快速排序,加详细注释"

for model in ["anthropic/claude-opus-4-5", "openai/gpt-4.1", "google/gemini-2.5-pro"]:
    print(f"\n{'='*60}")
    print(f"模型: {model}")
    print('='*60)

    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        max_tokens=1024,
    )
    print(response.choices[0].message.content)
    usage = response.usage
    print(f"\n[tokens] 输入={usage.prompt_tokens} 输出={usage.completion_tokens}")

保存为 quick_test.py,设置好环境变量后直接运行:

export THEROUTER_API_KEY=sk-your-key-here
python quick_test.py

小结

TheRouter 的统一 API 入口让这类横评变得非常简单——切换模型只需改一行 model 参数,账单统一,没有多账号管理的烦恼。

如果你想在项目里灵活切换模型(比如日常开发用 GPT-4.1 省成本,关键路径用 Claude 保质量),API 网关是目前最顺滑的方案。

注册体验:therouter.ai

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐