SWE-bench 都 80% 了,AI 真能修 Bug?我拿 3 个真实场景测了 5 个

SWE-bench 都 80% 了,AI 真能修 Bug?我拿 3 个真实场景测了 5 个

最近刷掘金看到 Cursor 官方搞了个模型 PK 的功能,评论区一堆人在争”Opus 强还是 GPT 强”。说实话,我之前也只看 benchmark 选模型,直到上周我在生产环境踩了一个坑——Claude 和 GPT 对同一个 Bug 给出了完全相反的修法,其中一个差点让我上线 P0 故障。

这件事让我意识到:SWE-bench 80% 和”能修你的 Bug”是两回事。

于是我花了两天,拿 3 个从实际项目里扒出来的典型 Bug,喂给 5 个主流模型,记录下每个模型的表现。结果挺有意思的。

场景 Opus 4.6 GPT-5.3 Gemini 3.1 Pro Qwen3-Max DeepSeek V3 React 状态竞态 ✅ 一次过 ⚠️ 修对了但多余 ✅ 一次过 ❌ 改错方向 ⚠️ 能跑但有隐患 SQL 慢查询优化 ✅ 最优解 ✅ 正确 ⚠️ 漏了边界 ✅ 正确 ✅ 正确 async 死锁排查 ✅ 精准定位 ✅ 正确 ❌ 误诊 ⚠️ 方向对细节错 ✅ 正确
总分
3/3
2.5/3
1.5/3
1.5/3
2.5/3

没错,SWE-bench 上差 0.2% 的模型,真实场景能差出一条街。

先说下我的测试环境:

  • 每个模型用相同的 system prompt:"你是一个高级软件工程师,请分析并修复以下代码中的 bug"
  • 直接调 API,不用 IDE 包装,排除工具链干扰
  • temperature 统一 0,避免随机性
  • 每个场景跑 3 次取最佳结果

API 调用这块,我是用的 OpenAI 兼容接口统一测的,一个 base_url 切所有模型,省得每家单独搞 SDK:

from openai import OpenAI client = OpenAI( api_key="sk-xxx", base_url="https://api.ofox.ai/v1" # 兼容 OpenAI 协议 ) models = [ "anthropic/claude-opus-4-6", "openai/gpt-5.3", "google/gemini-3.1-pro", "qwen/qwen3-max", "deepseek/deepseek-v3" ] for model in models: resp = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": "你是一个高级软件工程师,请分析并修复以下代码中的 bug。"}, {"role": "user", "content": bug_code} ], temperature=0 ) print(f" {'='*50}") print(f"模型: {model}") print(resp.choices[0].message.content) 

这是我在生产环境里真实遇到的问题。一个搜索组件,用户快速输入时,旧请求的结果可能覆盖新请求:

function SearchResults({ query }) `) .then(res => res.json()) .then(data => setResults(data)); }, [query]); return <ResultList items={results} />; } 

经典 race condition——用户输入 “react”,依次触发 “r”、”re”、”rea”、”reac”、”react” 五个请求,但网络不保证顺序返回。如果 “reac” 的结果比 “react” 晚到,就会覆盖正确结果。

Opus 4.6:✅ 教科书级

直接用 AbortController + cleanup 函数,干净利落:

useEffect(() => { const controller = new AbortController(); fetch(`/api/search?q=${query}`, { signal: controller.signal }) .then(res => res.json()) .then(data => setResults(data)) .catch(err => ); return () => controller.abort(); }, [query]); 

没多余的废话,一次到位。

GPT-5.3:⚠️ 正确但过度设计

GPT 不仅加了 AbortController,还额外包了一层 debounce + loading state + error boundary。代码量直接翻了三倍。功能上没问题,但说实话,一个简单的 race condition 修复,你给我整 40 行?

Gemini 3.1 Pro:✅ 换了个思路

useRef 记录请求序号,只接受最新一次:

useEffect(() =>cursor 教程 { const requestId = ++requestIdRef.current; fetch(`/api/search?q=${query}`) .then(res => res.json()) .then(data => }); }, [query]); 

思路不同但同样有效,而且不会取消已经发出的请求,某些场景下反而更省资源。

Qwen3-Max:❌ 方向跑偏

给了一个 setTimeout + clearTimeout 的 debounce 方案。这不是修 race condition,这是回避问题——如果用户就是快速输入后停了,最后一个请求仍然可能被更早的慢请求覆盖。

DeepSeek V3:⚠️ 能用但有坑

用了 let cancelled = false 的 closure 方案,方向对但没处理 fetch 错误的情况,生产环境直接用会有隐患。

这个来自我们项目的真实场景。一个统计接口跑了 8 秒,DBA 已经甩脸子了:

SELECT u.name, COUNT(o.id) as order_count, SUM(o.amount) as total_amount FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.created_at >= '2026-01-01' AND o.status IN ('paid', 'shipped', 'completed') GROUP BY u.id, u.name HAVING COUNT(o.id) > 5 ORDER BY total_amount DESC LIMIT 20; 

问题:orders 表 2000 万行,created_at 有索引但 status 没有,执行计划显示全表扫描。

这轮差距不大,Opus 给了最完整的方案——建复合索引 (created_at, status, user_id, amount) 覆盖查询,并且建议把 WHERE 条件里的 LEFT JOIN 改成 INNER JOIN(因为 WHERE 条件已经过滤了 NULL)。其他模型基本都能给出正确的索引建议,只有 Gemini 漏掉了 amount 字段导致无法 covering index。

这个 Bug 最阴间,我排查了大半天才找到原因:

import asyncio class ConnectionPool: def __init__(self, size=5): self._semaphore = asyncio.Semaphore(size) self._connections = [] async def acquire(self): await self._semaphore.acquire() if not self._connections: conn = await self._create_connection() return conn return self._connections.pop() async def release(self, conn): self._connections.append(conn) self._semaphore.release() async def execute(self, query): conn = await self.acquire() try: result = await conn.execute(query) # 如果这里抛异常... await self.release(conn) return result except Exception: await self.release(conn) raise async def batch_execute(self, queries): tasks = [self.execute(q) for q in queries] return await asyncio.gather(*tasks) 

看出来了吗?当 batch_execute 传入的 queries 数量超过 pool size(5)时,asyncio.gather 会同时启动所有 task。前 5 个 task 拿到 semaphore,后面的卡在 acquire 等待。但如果前面的 task 在 conn.execute 时抛异常,虽然 release 了 semaphore,但连接可能已经坏了。更狠的是——如果 _create_connection 本身也需要 pool 里的连接(比如要先查配置),直接死锁。

Opus 4.6:✅ 一眼看穿

精准指出了三个问题:

  1. execute 没用 try/finally,异常路径可能泄漏 semaphore
  2. batch_execute 的并发量可能超过 pool size,应该用 asyncio.Semaphoreasyncio.TaskGroup 限制
  3. 连接异常后应该丢弃而不是放回池里

给出的修复代码直接可用。

GPT-5.3:✅ 找到了核心问题

定位到了 try/finally 和连接泄漏问题,但漏掉了 batch_execute 的并发超限。

Gemini 3.1 Pro:❌ 误诊了

认为问题出在 Semaphore 的实现上,建议换成 asyncio.Queue。方向完全错了,Semaphore 本身没问题,是使用方式有问题。

Qwen3-Max:⚠️ 半对半错

找到了 try/finally 问题,但建议的修复里把 release 放在 finally 的同时没处理坏连接,相当于把坏连接放回了池子。

DeepSeek V3:✅ 意外惊喜

不仅找到了核心问题,还额外指出了 _connections 列表在并发场景下不是线程安全的(虽然 asyncio 是单线程的,但如果未来改成多线程就会出事)。思考得很全面。

测试过程中遇到几个坑:

  1. Gemini 的输出格式不稳定:同样的 prompt,有时候给完整代码,有时候只给 diff,有时候先分析一大段再给代码。做自动化测试的话需要额外处理。
  2. Qwen3-Max 的中文理解很强,但代码上下文推理弱一些:如果 prompt 用中文描述 Bug,Qwen 的分析部分写得很好,但修出来的代码容易有小瑕疵。
  3. DeepSeek V3 性价比真高:2.5/3 的成绩,但 API 价格只有 Opus 的 1/10 不到。日常开发用 DeepSeek 打底、关键修复切 Opus,是目前我觉得最划算的组合。
  4. 统一 API 接口真的省事:之前每个模型单独调,光是 SDK 依赖就装了一堆,现在改成 OpenAI 兼容协议统一调用,切模型就改个 model 参数的事。

SWE-bench 80% 听着很猛,但真实 Bug 的复杂度远超基准测试。我的建议:

  • 复杂逻辑 Bug(竞态、死锁、内存泄漏):上 Opus 4.6,一次到位的感觉确实不一样
  • 日常代码生成和简单 Bug:DeepSeek V3 够用,性价比拉满
  • SQL 和数据相关:各家差距不大,选便宜的就行
  • 前端 UI Bug:Gemini 的思路经常有惊喜,值得试试

别迷信单一模型,多模型切换才是正解。毕竟现在切模型的成本几乎为零——改个 model 字符串就完事了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:Ai探索者,转载请注明出处:https://javaforall.net/288648.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午1:29
下一篇 2026年3月18日 下午1:29


相关推荐

关注全栈程序员社区公众号