Skip to content

SWEBenchV2

PyPI version python uv Ruff tests code-quality license PRs contributors

一個創新的 SWE-Bench 替代方案,專注於測量 AI 模型與真實開發者編程模式的相似度,而非簡單的對錯判斷。

其他語言版本: English | 中文

🚀 概述

傳統的基準測試如 SWE-Bench 專注於測試模型是否能正確解決預定義問題。SWEBenchV2 採用了不同的方法:它測量 AI 模型的編程風格和決策與已經審核和批准代碼變更的經驗開發者的相似程度。

核心理念

我們不問「模型得到了正確答案嗎?」,而是問「模型的方法與有經驗的開發者實際做法有多相似?」

這種方法假設已合併的拉取請求代表了有經驗開發者對於「正確」實現變更方式的共識。通過將模型輸出與這些真實世界的解決方案進行比較,我們不僅可以評估正確性,還可以評估編程風格、問題解決方法和對專案慣例的遵循。

🎯 主要功能

  • 🔍 真實世界數據:從實際已合併的拉取請求中提取訓練數據
  • 📊 模式匹配:專注於與開發者模式的相似性,而非簡單的對錯判斷
  • 📋 全面分析:捕獲修改前後的代碼狀態、PR 上下文和元數據
  • 🔗 GitHub 整合:無縫連接任何 GitHub 儲存庫
  • ⚡ 高性能異步處理:使用 asyncio.gather() 多層並發處理,實現最大化速度
  • 🚦 智能速率限制:內建 GitHub API 速率限制管理,配合 semaphore 並發控制
  • ⚙️ 靈活配置:針對不同使用情況的可配置提取參數
  • 📚 完整文檔:所有函數都包含詳細的 Google 風格文檔字符串,包含參數類型和返回值說明

📊 工作原理

  1. 數據提取:掃描 GitHub 儲存庫中已合併的拉取請求
  2. 內容捕獲:記錄所有修改文件的修改前後狀態
  3. 上下文保存:維護 PR 標題、描述和元數據
  4. 數據集生成:創建適用於 LLM 評估的結構化訓練數據
  5. 基準創建:提供問題-上下文-答案三元組用於模型測試

數據結構

每個提取的 PR 都成為一個基準項目,包含:

  • 問題:PR 標題和描述(需要解決的問題)
  • 上下文:修改文件的修改前狀態和文件名
  • 期望答案:修改文件的修改後狀態(「正確」的解決方案)

🛠️ 安裝

先決條件

  • Python 3.10 或更高版本
  • uv 用於依賴管理
  • GitHub API 令牌(用於訪問儲存庫)

設置

  1. 克隆儲存庫:
git clone https://github.com/Mai0313/SWEBenchV2.git
cd SWEBenchV2
  1. 安裝依賴:
uv sync
  1. 安裝為套件(用於 CLI 使用):
uv pip install -e .
  1. 設置您的 GitHub 令牌:
export GITHUB_TOKEN="your_github_token_here"

📖 使用方法

CLI 使用(推薦)

安裝套件後,您可以直接使用 swebenchv2 命令:

# 基本使用 - 從儲存庫提取 PR
swebenchv2 --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 使用自定義參數
swebenchv2 --repo_url="https://github.com/Mai0313/SWEBenchV2" --max_page=5 --per_page=50

# 使用同步模式
swebenchv2 main --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 使用異步模式(對大型儲存庫更快)
swebenchv2 a_main --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 提取的數據將保存到 ./data/{owner}/{repo}/log_{timestamp}.json

Python 庫使用

from swebenchv2.datamodule.github import GitHubPRExtractor

# 初始化提取器
extractor = GitHubPRExtractor(
    repo_url="https://github.com/owner_name/repository_name",
    max_page=10,  # 限制提取頁面數
    per_page=50,  # 每頁 PR 數量
)

# 提取所有 PR 數據 - 現在包含完整的文檔字符串
result = extractor.extract_all_pr_data(save_json=True)
print(f"從 {result.repository} 提取了 {result.total_prs} 個 PR")

# 所有方法現在都包含詳細文檔
# 提取前檢查速率限制
rate_limit = extractor.get_rate_limit()  # 返回包含剩餘調用信息的 RateLimit
print(f"剩餘請求數:{rate_limit.rate.remaining}")

# 獲取特定 PR 文件,包含完整文檔
merged_prs = extractor.get_merged_prs()  # 返回帶分頁的 list[PullRequest]
for pr in merged_prs[:3]:
    files = extractor.get_pr_files(pr.number)  # 返回修改文件的 list[FileData]
    print(f"PR #{pr.number} 修改了 {len(files)} 個文件")

替代執行方法

您可以通過多種不同方式運行工具:

# 方法 1:直接 CLI(pip install -e . 後)
swebenchv2 --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 方法 2:使用 poethepoet 任務
poe main --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 方法 3:直接 Python 模組執行
python src/swebenchv2/cli.py --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 方法 4:使用 uv run 與 cli 入口點
uv run cli --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 方法 5:使用 uv run 與 swebenchv2 入口點
uv run swebenchv2 --repo_url="https://github.com/Mai0313/SWEBenchV2"

# 提取的數據將保存到 ./data/{owner}/{repo}/log_{timestamp}.json

高級配置

extractor = GitHubPRExtractor(
    repo_url="https://github.com/your_org/your_repo",
    max_page=5,  # 限制為前 5 頁
    per_page=100,  # 每頁 100 個 PR
    token="your_token",  # 可選:直接設置令牌
)

# 提取前檢查速率限制
rate_limit = extractor.get_rate_limit()
print(f"剩餘請求數:{rate_limit.rate.remaining}")

# 為特定 PR 提取數據
merged_prs = extractor.get_merged_prs()
for pr in merged_prs[:5]:  # 處理前 5 個 PR
    pr_data = extractor.extract_pr_data(pr)
    print(f"已為 PR #{pr.number} 提取數據:{pr.title}")

異步使用

對於大型儲存庫,使用經過優化的並發處理異步版本可獲得更好的性能:

import asyncio
from swebenchv2.datamodule.github import AsyncGitHubPRExtractor


async def extract_data():
    extractor = AsyncGitHubPRExtractor(
        repo_url="https://github.com/your_org/your_repo", max_page=5, per_page=100
    )

    # 使用多層並發的異步提取
    # - 文件內容獲取:並發檢索修改前後內容
    # - PR 處理:使用 semaphore 控制的並發文件處理
    # - 批量處理:跨儲存庫的並發 PR 提取
    result = await extractor.extract_all_pr_data(save_json=True)
    print(f"使用高速異步處理提取了 {result.total_prs} 個 PR")
    return result


# 運行異步提取
result = asyncio.run(extract_data())

性能優勢

異步實現提供了顯著的性能改進:

  • 並發文件處理:使用 asyncio.gather() 同時獲取修改前後的內容
  • 並行 PR 處理:多個 PR 在 semaphore 控制的限制下並行處理
  • 批量 API 優化:通過智能並行操作減少總執行時間
  • 資源效率:對網絡資源和 API 速率限制的最佳利用

觀察到的性能改進示例:

  • 大型儲存庫:相比同步實現,提取速度提升 3-5 倍
  • 中型儲存庫:通過並發處理實現 2-3 倍的速度提升
  • 通過智能批處理更好地利用 API 速率限制

📁 輸出格式

提取的數據以 JSON 格式保存,結構如下:

{
  "repository": "Mai0313/SWEBenchV2",
  "extracted_at": "2024-01-01T12:00:00",
  "total_prs": 100,
  "prs": [
    {
      "pr_info": {
        "number": 123,
        "title": "Fix bug in authentication",
        "body": "This PR fixes the authentication issue...",
        "merged_at": "2024-01-01T10:00:00Z"
      },
      "question": "PR #123: Fix bug in authentication\nDescription:\nThis PR fixes...",
      "files": [
        {
          "filename": "src/auth.py",
          "status": "modified",
          "before_edit": "# Original code...",
          "after_edit": "# Modified code...",
          "additions": 5,
          "deletions": 2
        }
      ]
    }
  ]
}

� 配置

環境變量

變量 描述 默認值
GITHUB_TOKEN GitHub API 令牌 無(私有儲存庫需要)
GITHUB_API_BASE_URL 自定義 GitHub API URL https://api.github.com

速率限制

工具自動處理 GitHub API 速率限制:

  • 🔍 監控剩餘請求數
  • ⏳ 達到限制時自動等待
  • 📝 提供關於速率限制狀態的詳細日誌

🤖 與 LLM 一起使用

提取的數據設計為與語言模型無縫配合:

# 示例:使用提取的數據測試模型
for pr_data in result.prs:
    question = pr_data.question
    context = {"files": {file.filename: file.before_edit for file in pr_data.files}}
    expected_answer = {file.filename: file.after_edit for file in pr_data.files}

    # 發送給您的 LLM 並比較相似度
    model_response = your_llm.generate(question, context)
    similarity_score = calculate_similarity(model_response, expected_answer)

🗂️ 項目結構

├── src/
│   └── swebenchv2/
│       ├── cli.py                # 包含文檔化入口點的 CLI 介面
│       ├── datamodule/
│       │   └── github.py         # 包含完整文檔字符串的主要提取邏輯
│       └── typings/
│           ├── models.py         # 包含文檔化保存方法的數據模型
│           ├── prs.py           # 拉取請求類型和枚舉
│           └── limit.py         # 包含狀態檢查的速率限制處理
├── tests/                        # 全面測試套件
├── data/                         # 提取數據的輸出目錄
├── pyproject.toml               # 包含 CLI 入口點的項目配置
└── README.md                    # 此文件

核心函數文檔

所有核心函數現在都包含完整的 Google 風格文檔字符串:

CLI 函數 (cli.py)

  • SWEBench.main() - 包含完整文檔的同步 PR 提取
  • SWEBench.a_main() - 包含性能說明的異步 PR 提取
  • SWEBench.__call__() - 可調用介面文檔
  • main() - 包含 Fire 整合詳情的 CLI 入口點

GitHub 整合 (github.py)

  • GitHubPRExtractor.get_rate_limit() - 包含返回類型信息的速率限制檢查
  • GitHubPRExtractor.get_merged_prs() - 包含分頁詳情的 PR 獲取
  • GitHubPRExtractor.get_pr_files() - 包含元數據處理的文件提取
  • GitHubPRExtractor.get_file_content() - 包含 SHA 處理的內容檢索
  • GitHubPRExtractor.extract_pr_data() - 單個 PR 處理文檔
  • GitHubPRExtractor.extract_all_pr_data() - 完整提取編排

異步版本 - 所有異步方法都包含並發和性能文檔

數據模型 (models.py)

  • ExtractionResult.save_log() - 包含時間戳組織的 JSON 導出
  • ExtractionResult.a_save_log() - 異步文件操作文檔

速率限制 (limit.py)

  • RateLimit.is_rate_limited() - 包含布爾邏輯的 API 配額檢查

🔬 評估方法

與專注於二元正確性的傳統基準不同,SWEBenchV2 評估:

  1. 代碼相似性:生成的代碼與批准的解決方案有多相似?
  2. 風格一致性:模型是否遵循項目的編程約定?
  3. 問題解決方法:模型是否像經驗豐富的開發者一樣處理問題?
  4. 上下文意識:模型是否適當考慮了現有代碼庫模式?

🤝 貢獻

歡迎貢獻!您可以通過以下方式幫助:

  1. 分叉儲存庫
  2. 創建功能分支git checkout -b feature-name
  3. 進行更改並添加測試
  4. 提交拉取請求

更多詳情請參閱我們的貢獻指南

📊 使用案例

  • 模型評估:評估 AI 模型與真實開發者模式的匹配程度
  • 訓練數據生成:從真實儲存庫創建現實的編程數據集
  • 代碼風格分析:研究不同項目的編程模式
  • 開發者行為研究:分析有經驗的開發者如何解決問題

🙏 致謝

  • 靈感來自原始的 SWE-Bench 項目
  • 基於真實開發者共識代表質量標準的原則
  • 為 AI 輔助軟件開發時代而設計

📄 許可證

本項目根據 MIT 許可證授權 - 詳情請參閱 LICENSE 文件。


**為 AI 和軟件開發社區用 ❤️ 製作** [報告錯誤](https://github.com/Mai0313/SWEBenchV2/issues) • [請求功能](https://github.com/Mai0313/SWEBenchV2/issues) • [文檔](https://mai0313.github.io/SWEBenchV2/)