diff options
| author | sillylaird <sillyfanboy@gmail.com> | 2026-09-03 00:33:59 +0000 |
|---|---|---|
| committer | sillylaird <sillyfanboy@gmail.com> | 2026-09-03 00:33:59 +0000 |
| commit | 898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch) | |
| tree | 85c6ee5ad58b860144551184d4cf86b560c62b91 /.agents/skills/kaggle-learner/references/knowledge/nlp/konwinski-prize-2025-comparison.md | |
| download | www-898b52edcb47bcb3e9d6106e74ca73e74ea01e70.tar.gz www-898b52edcb47bcb3e9d6106e74ca73e74ea01e70.zip | |
Diffstat (limited to '')
| -rw-r--r-- | .agents/skills/kaggle-learner/references/knowledge/nlp/konwinski-prize-2025-comparison.md | 1337 |
1 files changed, 1337 insertions, 0 deletions
diff --git a/.agents/skills/kaggle-learner/references/knowledge/nlp/konwinski-prize-2025-comparison.md b/.agents/skills/kaggle-learner/references/knowledge/nlp/konwinski-prize-2025-comparison.md new file mode 100644 index 0000000..df0ef11 --- /dev/null +++ b/.agents/skills/kaggle-learner/references/knowledge/nlp/konwinski-prize-2025-comparison.md @@ -0,0 +1,1337 @@ +# Konwinski Prize 2025 前排方案对比学习 + +> **竞赛**: Konwinski Prize 2025 - AI GitHub Issue Resolver +> +> **研究重点**: 1st Place vs 5th Place 技术方案对比 +> +> **更新日期**: 2026-01-25 + +--- + +## 目录 + +1. [竞赛概览](#竞赛概览) +2. [前排方案对比表](#前排方案对比表) +3. [1st Place 方案深度解析](#1st-place-方案深度解析) +4. [5th Place 方案深度解析](#5th-place-方案深度解析) +5. [核心技术对比](#核心技术对比) +6. [可复用代码模板](#可复用代码模板) +7. [关键经验教训](#关键经验教训) + +--- + +## 竞赛概览 + +### 竞赛基本信息 + +| 项目 | 内容 | +|------|------| +| **竞赛名称** | Konwinski Prize 2025 | +| **主办方** | Andy Konwinski (Databricks 联合创始人) | +| **总奖金** | $1,225,000+ | +| **最高奖金** | $1,000,000 (90% 成功率,尚未触发) | +| **Round 1 首奖** | $50,000 | +| **参与团队** | 616 个团队 | +| **竞赛时间** | 2024年12月 - 2025年7月 | + +### 任务定义 + +**目标**: 构建 AI Agent,自动修复 GitHub 真实项目中的 bug + +**挑战**: +- 测试集完全隐藏(提交后收集) +- 无数据泄露(contamination-free) +- 严格评分机制 +- 仅允许使用开源模型 + +### 评分机制 + +```python +# 评分公式(简化版) +score = num_correct - C * num_wrong + +# 其中 C 是错误修复的惩罚系数(通常较大) +# skip 仅有轻微惩罚 +``` + +**关键洞察**: +- 错误修复 → 重罚 +- 跳过 → 轻罚 +- **策略**: 宁可跳过,不要出错 + +--- + +## 前排方案对比表 + +### 排名和成绩 + +| 排名 | 参与者 | 成功率 | 核心策略 | 关键技术 | +|------|--------|--------|----------|----------| +| **1st** | Eduardo Rocha de Andrade | **7.5%** | Prompt Engineering + F2P Testing | • Fail-to-Pass 测试<br>• 保守提交策略<br>• 精心设计的 prompt | +| **5th** | Anonymous (Ambrosm?) | ~5% | Regex Traceback Analysis | • 正则提取 traceback<br>• 精确定位错误<br>• 上下文优化 | +| **6th** | quan16369 | 0.8% | Select-Patch-Verify-Choose | • 多次验证<br>• 指数大小惩罚<br>• 严格过滤 | + +### 核心差异概览 + +| 维度 | 1st Place | 5th Place | 6th Place | +|------|-----------|-----------|-----------| +| **测试验证** | ✅ F2P 测试(关键) | ✅ F2P 测试 | ❌ 仅 LLM 验证 | +| **错误定位** | Prompt Engineering | Regex Traceback | LLM Select | +| **补丁选择** | 保守策略 | 保守策略 | 规则评分 | +| **提交策略** | 仅高置信度 | 仅高置信度 | 相对宽松 | +| **上下文使用** | 全面的 issue 分析 | 精准的 traceback | 全代码树 | + +--- + +## 1st Place 方案深度解析 + +### 核心理念 + +> **"质量 > 数量,客观测试 > 主观判断"** + +### 架构设计 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 1st Place 完整流程 │ +└─────────────────────────────────────────────────────────┘ + +输入: GitHub Issue + 代码库 + │ + ▼ +┌──────────────────┐ +│ 1. Issue 分析 │ • 提取关键信息 +│ │ • 理解问题本质 +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ 2. F2P 测试生成 │ ⭐ 核心创新 +│ │ • 测试必须在原代码失败 +└────────┬─────────┘ • 测试必须在补丁后通过 + │ + ▼ +┌──────────────────┐ +│ 3. 补丁生成 │ • 基于测试指导 +│ │ • 多个候选方案 +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ 4. F2P 测试验证 │ • 客观验证 +│ │ • 确保修复有效 +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ 5. 保守决策 │ • 仅高置信度提交 +│ │ • 宁可跳过 +└──────────────────┘ +``` + +### 关键技术 1: F2P (Fail-to-Pass) 测试 + +**定义**: 生成在原始代码上失败、在修复后通过的测试用例 + +**实现流程**: + +```python +def generate_f2p_test(issue: str, code_context: str, model) -> str: + """ + 生成 Fail-to-Pass 测试 + + Args: + issue: GitHub issue 描述 + code_context: 相关代码上下文 + model: LLM 模型 + + Returns: + test_code: F2P 测试代码 + """ + prompt = f""" +你是一个测试工程师。根据以下 GitHub Issue,生成一个单元测试: + +GitHub Issue: +{issue} + +相关代码: +{code_context} + +要求: +1. 测试必须在当前(有 bug 的)代码上 FAIL +2. 测试必须在修复 bug 后 PASS +3. 测试应该最小化,专注于特定 bug +4. 使用 pytest 框架 + +返回完整的测试代码。 +""" + + test_code = model.generate(prompt) + return test_code + + +def validate_f2p_test( + test_code: str, + original_code: str, + patched_code: str +) -> bool: + """ + 验证 F2P 测试的有效性 + + Returns: + True 如果测试是有效的 F2P 测试 + """ + # 1. 在原始代码上运行测试(应该 FAIL) + original_result = run_test(test_code, original_code) + if original_result.status != "FAIL": + return False # 测试在原代码上没有失败! + + # 2. 在补丁后代码上运行测试(应该 PASS) + patched_result = run_test(test_code, patched_code) + if patched_result.status != "PASS": + return False # 测试在补丁后没有通过! + + return True +``` + +**F2P 测试的优势**: + +1. **客观验证**: 不依赖 LLM 主观判断 +2. **Bug 复现**: 确保 bug 真实存在 +3. **修复确认**: 确保补丁真正修复了问题 +4. **回归预防**: 防止补丁引入新问题 + +### 关键技术 2: 保守提交策略 + +```python +def should_submit_patch( + patch: str, + f2p_test_result: dict, + confidence_metrics: dict +) -> bool: + """ + 保守的提交决策 + + 只有在所有条件都满足时才提交 + """ + # 条件 1: F2P 测试必须通过 + if not f2p_test_result['valid_f2p']: + return False + + # 条件 2: 补丁必须成功应用 + if not f2p_test_result['applied_successfully']: + return False + + # 条件 3: 补丁大小必须合理 + if len(patch) > 500: # 字符数限制 + return False + + # 条件 4: 修改的文件数量有限 + if f2p_test_result['files_modified'] > 2: + return False + + # 条件 5: 高置信度 + if confidence_metrics['score'] < 0.9: + return False + + # 所有条件满足 → 提交 + return True +``` + +### 关键技术 3: Prompt Engineering + +**Issue 分析 Prompt**: + +```python +ISSUE_ANALYSIS_PROMPT = """ +你是一个资深的软件工程师和调试专家。 + +任务:分析以下 GitHub Issue,提取关键信息 + +GitHub Issue: +{issue} + +请提供: +1. 问题类型(bug/feature/性能/安全等) +2. 错误消息(如果有) +3. Traceback 信息(如果有) +4. 复现步骤 +5. 期望行为 +6. 相关文件或模块 +7. 可能的根本原因 + +以结构化的 JSON 格式返回。 +""" +``` + +**补丁生成 Prompt**: + +```python +PATCH_GENERATION_PROMPT = """ +你是一个代码修复专家。 + +任务:根据以下信息生成修复补丁 + +GitHub Issue: +{issue} + +F2P 测试: +{f2p_test} + +相关代码: +{code} + +要求: +1. 生成最小化的补丁 +2. 只修改必要的代码 +3. 确保补丁能让 F2P 测试通过 +4. 不要添加不必要的功能 +5. 使用 git diff 格式 + +返回补丁代码。 +""" +``` + +--- + +## 5th Place 方案深度解析 + +### 核心理念 + +> **"精确的错误定位 + 有效的上下文"** + +### 架构设计 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 5th Place 完整流程 │ +└─────────────────────────────────────────────────────────┘ + +输入: GitHub Issue + 代码库 + │ + ▼ +┌──────────────────┐ +│ 1. Traceback │ ⭐ 核心创新 +│ 提取 │ • 正则表达式匹配 +└────────┬─────────┘ • 提取错误位置 + │ + ▼ +┌──────────────────┐ +│ 2. 精确定位 │ • 文件级别 +│ │ • 行级别 +└────────┬─────────┘ • 函数级别 + │ + ▼ +┌──────────────────┐ +│ 3. 上下文收集 │ • 仅相关代码 +│ │ • 减少噪音 +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ 4. F2P 测试生成 │ • 基于定位结果 +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ 5. 目标化补丁 │ • 精准修复 +│ │ • 最小化修改 +└────────┬─────────┘ + │ + ▼ +┌──────────────────┐ +│ 6. 测试验证 │ • F2P 验证 +└──────────────────┘ +``` + +### 关键技术: Regex Traceback 分析 + +**完整的 Traceback 提取器**: + +```python +import re +from typing import Dict, List, Optional, Tuple +from dataclasses import dataclass + + +@dataclass +class TracebackInfo: + """Traceback 信息结构""" + files: List[str] + lines: List[int] + functions: List[str] + error_types: List[str] + error_messages: List[str] + raw_traceback: str + + +class TracebackExtractor: + """使用正则表达式提取 Traceback 信息""" + + # Python Traceback 模式 + PATTERNS = { + 'traceback_header': r'Traceback \(most recent call last\):', + 'frame': r' File "([^"]+)", line (\d+), in (\w+)', + 'error': r'(\w*Error):\s*(.+)', + 'assertion': r'AssertionError:\s*(.+)', + 'exception_in': r'Exception in (\w+) (.+)', + } + + def __init__(self): + # 编译正则表达式 + self.compiled_patterns = { + name: re.compile(pattern) + for name, pattern in self.PATTERNS.items() + } + + def extract(self, issue_text: str) -> Optional[TracebackInfo]: + """ + 从 issue 文本中提取 traceback 信息 + + Args: + issue_text: GitHub issue 的完整文本 + + Returns: + TracebackInfo 对象,如果没有找到 traceback 则返回 None + """ + # 1. 检查是否有 traceback + if not self.compiled_patterns['traceback_header'].search(issue_text): + return None + + # 2. 提取帧信息 + frames = self.compiled_patterns['frame'].findall(issue_text) + files = [frame[0] for frame in frames] + lines = [int(frame[1]) for frame in frames] + functions = [frame[2] for frame in frames] + + # 3. 提取错误信息 + error_match = self.compiled_patterns['error'].search(issue_text) + if error_match: + error_types = [error_match.group(1)] + error_messages = [error_match.group(2)] + else: + # 尝试匹配 AssertionError + assertion_match = self.compiled_patterns['assertion'].search(issue_text) + if assertion_match: + error_types = ['AssertionError'] + error_messages = [assertion_match.group(1)] + else: + error_types = [] + error_messages = [] + + # 4. 提取原始 traceback 文本 + traceback_match = re.search( + r'(Traceback \(most recent call last\):.*?)(?=\n\n|\Z)', + issue_text, + flags=re.DOTALL + ) + raw_traceback = traceback_match.group(1) if traceback_match else "" + + return TracebackInfo( + files=files, + lines=lines, + functions=functions, + error_types=error_types, + error_messages=error_messages, + raw_traceback=raw_traceback + ) + + def prioritize_files( + self, + traceback: TracebackInfo, + all_files: List[str] + ) -> List[str]: + """ + 根据 traceback 优先排序文件 + + Args: + traceback: 提取的 traceback 信息 + all_files: 代码库中所有文件的列表 + + Returns: + 优先排序后的文件列表 + """ + prioritized = [] + + # 优先级 1: traceback 中直接提到的文件 + for tb_file in traceback.files: + # 标准化路径 + normalized = tb_file.replace('/', '.') + if normalized in all_files: + prioritized.append((normalized, 1.0)) + # 尝试部分匹配 + elif any(tb_file in f or f in tb_file for f in all_files): + match = next(f for f in all_files if tb_file in f or f in tb_file) + prioritized.append((match, 0.9)) + + # 优先级 2: 同目录下的文件 + if traceback.files: + tb_dir = '/'.join(traceback.files[0].split('/')[:-1]) + for f in all_files: + if f.startswith(tb_dir) and f not in [p[0] for p in prioritized]: + prioritized.append((f, 0.7)) + + # 优先级 3: 相关测试文件 + for f in all_files: + if 'test' in f.lower() and f not in [p[0] for p in prioritized]: + prioritized.append((f, 0.5)) + + # 按优先级排序 + prioritized.sort(key=lambda x: x[1], reverse=True) + + return [p[0] for p in prioritized] + + def get_context_lines( + self, + traceback: TracebackInfo, + file_content: str, + context_window: int = 10 + ) -> str: + """ + 获取错误行周围的上下文 + + Args: + traceback: Traceback 信息 + file_content: 文件内容 + context_window: 上下文行数 + + Returns: + 上下文代码字符串 + """ + if not traceback.lines: + return file_content[:500] # 默认返回前 500 字符 + + lines = file_content.split('\n') + error_line = traceback.lines[0] + + # 提取上下文 + start = max(0, error_line - context_window) + end = min(len(lines), error_line + context_window + 1) + + context_lines = lines[start:end] + + # 添加行号 + context_with_line_numbers = [ + f"{i+1:4d}: {line}" + for i, line in enumerate(context_lines, start=start) + ] + + # 标记错误行 + if error_line - start < len(context_with_line_numbers): + idx = error_line - start + context_with_line_numbers[idx] = f">>> {context_with_line_numbers[idx]}" + + return '\n'.join(context_with_line_numbers) +``` + +**使用示例**: + +```python +# 初始化 +extractor = TracebackExtractor() + +# 从 issue 中提取 traceback +issue_text = """ +When I run the model, I get this error: + +Traceback (most recent call last): + File "train.py", line 42, in train_loop + loss = model(batch) + File "model.py", line 156, in __call__ + outputs = self.layer(inputs) +TypeError: Layer.__call__() got an unexpected keyword argument 'training' + +This happens when I use the new layer type. +""" + +traceback = extractor.extract(issue_text) + +if traceback: + print(f"Error Type: {traceback.error_types}") + print(f"Error Message: {traceback.error_messages}") + print(f"Files: {traceback.files}") + print(f"Lines: {traceback.lines}") + print(f"Functions: {traceback.functions}") + + # 优先排序文件 + all_files = ['model.py', 'train.py', 'utils.py', 'test_model.py'] + prioritized = extractor.prioritize_files(traceback, all_files) + print(f"Prioritized files: {prioritized}") + + # 获取上下文 + model_code = read_file('model.py') + context = extractor.get_context_lines(traceback, model_code) + print(f"Context:\n{context}") +``` + +### 基于 Traceback 的补丁生成 + +```python +def generate_traceback_aware_patch( + issue: str, + traceback: TracebackInfo, + code_context: str, + model +) -> str: + """ + 基于 traceback 信息生成精准的补丁 + + Args: + issue: GitHub issue + traceback: 提取的 traceback 信息 + code_context: 错误行周围的代码上下文 + model: LLM 模型 + + Returns: + patch: 生成的补丁 + """ + prompt = f""" +你是一个代码修复专家。 + +Bug 报告: +{issue} + +错误位置信息: +- 文件: {traceback.files[0] if traceback.files else 'Unknown'} +- 行号: {traceback.lines[0] if traceback.lines else 'Unknown'} +- 函数: {traceback.functions[0] if traceback.functions else 'Unknown'} +- 错误类型: {traceback.error_types[0] if traceback.error_types else 'Unknown'} +- 错误消息: {traceback.error_messages[0] if traceback.error_messages else 'Unknown'} + +错误行周围的代码: +{code_context} + +任务: +1. 分析错误的根本原因 +2. 生成最小的修复补丁 +3. 只修改必要的代码 +4. 使用 git diff 格式 + +返回补丁代码。 +""" + + patch = model.generate(prompt) + return patch +``` + +--- + +## 核心技术对比 + +### 对比维度分析 + +| 技术维度 | 1st Place | 5th Place | 优势分析 | +|---------|-----------|-----------|----------| +| **错误定位** | Prompt Engineering + 全面分析 | Regex Traceback 提取 | 5th 更精确,1st 更全面 | +| **测试验证** | F2P 测试 | F2P 测试 | 两者都使用(关键) | +| **上下文管理** | 全面 issue 分析 | 精准 traceback 定位 | 5th 更高效 | +| **补丁生成** | 多候选 + 精心 prompt | 目标化 + 精准定位 | 5th 更聚焦 | +| **提交策略** | 极度保守 | 保守 | 1st 更保守 | +| **适用场景** | 复杂、多文件问题 | 明确 traceback 错误 | 各有优势 | + +### F2P 测试 vs Traceback 分析 + +#### F2P 测试(1st Place 核心优势) + +**优势**: +1. ✅ **客观验证**: 不依赖 LLM 主观判断 +2. ✅ **Bug 复现**: 确保问题真实存在 +3. ✅ **修复确认**: 确保补丁有效 +4. ✅ **通用性强**: 适用于所有类型的 bug + +**劣势**: +1. ❌ **生成困难**: 需要高质量的 prompt +2. ❌ **计算成本**: 需要运行测试 +3. ❌ **测试质量**: 可能生成不完整或错误的测试 + +**最佳适用场景**: +- 需要高置信度的场景 +- 没有 traceback 的 bug 报告 +- 功能性 bug(非错误消息) + +#### Traceback 分析(5th Place 核心优势) + +**优势**: +1. ✅ **精确定位**: 直接指向错误位置 +2. ✅ **高效**: 减少不必要的上下文 +3. ✅ **明确信息**: 错误类型和消息清晰 +4. ✅ **上下文优化**: 只关注相关代码 + +**劣势**: +1. ❌ **依赖 traceback**: 不是所有 bug 都有 +2. ❌ **正则脆弱**: 可能漏掉非标准格式 +3. ❌ **表面症状**: 可能不是根本原因 + +**最佳适用场景**: +- 有明确 traceback 的错误 +- 单文件或局部问题 +- 需要快速定位的场景 + +#### 组合策略(最优方案) + +```python +def combined_strategy(issue: str, codebase: dict) -> Optional[str]: + """ + 组合 F2P 测试和 Traceback 分析 + + 结合两者的优势 + """ + # 1. 尝试提取 traceback + traceback = extract_traceback(issue) + + # 2. 根据是否有 traceback 选择策略 + if traceback: + # 使用 traceback 精确定位 + relevant_files = traceback.prioritize_files(codebase.keys()) + context = get_traceback_context(traceback, codebase) + else: + # 使用全面的 issue 分析 + relevant_files = analyze_issue(issue, codebase) + context = get_full_context(issue, codebase) + + # 3. 生成 F2P 测试(两种情况都需要) + f2p_test = generate_f2p_test(issue, context) + + # 4. 生成补丁 + patch = generate_patch(issue, f2p_test, context) + + # 5. 验证 + if validate_f2p_test(f2p_test, patch): + return patch + else: + return None +``` + +--- + +## 可复用代码模板 + +### Template 1: 完整的 F2P 测试流程(1st Place 风格) + +```python +from typing import Optional, Dict, Any +import subprocess +import tempfile +import os + + +class F2PTestGenerator: + """Fail-to-Pass 测试生成器""" + + def __init__(self, model): + self.model = model + + def generate(self, issue: str, code_context: str) -> str: + """生成 F2P 测试""" + prompt = f""" +根据以下 GitHub Issue 生成一个单元测试: + +Issue: +{issue} + +相关代码: +{code_context} + +要求: +1. 测试必须在当前(有 bug 的)代码上 FAIL +2. 测试必须在修复 bug 后 PASS +3. 使用 pytest 框架 +4. 测试应该最小化且专注于特定 bug + +返回完整的测试代码。 +""" + return self.model.generate(prompt) + + def validate( + self, + test_code: str, + original_code: str, + patched_code: str + ) -> Dict[str, Any]: + """验证 F2P 测试的有效性""" + results = { + 'valid_f2p': False, + 'original_result': None, + 'patched_result': None, + 'error': None + } + + try: + # 1. 在原始代码上运行(应该 FAIL) + results['original_result'] = self._run_test( + test_code, original_code + ) + + if results['original_result']['status'] != 'FAIL': + results['error'] = "Test did not fail on original code" + return results + + # 2. 在补丁后代码上运行(应该 PASS) + results['patched_result'] = self._run_test( + test_code, patched_code + ) + + if results['patched_result']['status'] != 'PASS': + results['error'] = "Test did not pass on patched code" + return results + + # 3. 测试有效 + results['valid_f2p'] = True + return results + + except Exception as e: + results['error'] = str(e) + return results + + def _run_test(self, test_code: str, code: str) -> Dict[str, Any]: + """运行测试并返回结果""" + with tempfile.TemporaryDirectory() as tmpdir: + # 写入测试文件 + test_file = os.path.join(tmpdir, 'test_fix.py') + with open(test_file, 'w') as f: + f.write(test_code) + f.write('\n\n') + f.write(code) + + # 运行测试 + result = subprocess.run( + ['pytest', test_file, '-v'], + capture_output=True, + text=True, + timeout=10 + ) + + return { + 'status': 'PASS' if result.returncode == 0 else 'FAIL', + 'stdout': result.stdout, + 'stderr': result.stderr + } + + +# 使用示例 +def solve_issue_with_f2p( + issue: str, + codebase: Dict[str, str], + model +) -> Optional[str]: + """ + 使用 F2P 测试解决问题 + """ + # 1. 生成测试 + test_gen = F2PTestGenerator(model) + test_code = test_gen.generate(issue, codebase) + + # 2. 生成补丁 + patch = generate_patch(issue, test_code, codebase, model) + + # 3. 验证 + validation = test_gen.validate( + test_code, + codebase, + apply_patch(codebase, patch) + ) + + # 4. 返回结果 + if validation['valid_f2p']: + return patch + else: + return None +``` + +### Template 2: Traceback 分析器(5th Place 风格) + +```python +import re +from typing import Optional, List, Tuple +from dataclasses import dataclass + + +@dataclass +class TracebackInfo: + """Traceback 信息""" + files: List[str] + lines: List[int] + functions: List[str] + error_type: Optional[str] + error_message: Optional[str] + full_traceback: str + + +class TracebackAnalyzer: + """Traceback 分析器""" + + def __init__(self): + self.patterns = { + 'header': re.compile(r'Traceback \(most recent call last\):'), + 'frame': re.compile(r' File "([^"]+)", line (\d+), in (\w+)'), + 'error': re.compile(r'(\w*Error):\s*(.+)'), + } + + def extract(self, text: str) -> Optional[TracebackInfo]: + """从文本中提取 traceback""" + if not self.patterns['header'].search(text): + return None + + # 提取帧 + frames = self.patterns['frame'].findall(text) + + # 提取错误 + error_match = self.patterns['error'].search(text) + error_type = error_match.group(1) if error_match else None + error_message = error_match.group(2) if error_match else None + + # 提取完整 traceback + tb_match = re.search( + r'(Traceback \(most recent call last\):.*?)(?=\n\n|\Z)', + text, + flags=re.DOTALL + ) + full_traceback = tb_match.group(1) if tb_match else "" + + return TracebackInfo( + files=[f[0] for f in frames], + lines=[int(f[1]) for f in frames], + functions=[f[2] for f in frames], + error_type=error_type, + error_message=error_message, + full_traceback=full_traceback + ) + + def get_error_location(self, traceback: TracebackInfo) -> Tuple[str, int]: + """获取错误位置(文件,行号)""" + if traceback.files and traceback.lines: + return (traceback.files[0], traceback.lines[0]) + return (None, None) + + def get_context( + self, + traceback: TracebackInfo, + file_content: str, + window: int = 5 + ) -> str: + """获取错误行周围的上下文""" + if not traceback.lines: + return file_content[:500] + + lines = file_content.split('\n') + error_line = traceback.lines[0] + + start = max(0, error_line - window) + end = min(len(lines), error_line + window + 1) + + context = lines[start:end] + return '\n'.join( + f"{i+1:4d}: {line}" + for i, line in enumerate(context, start=start) + ) + + +# 使用示例 +def solve_issue_with_traceback( + issue: str, + codebase: Dict[str, str], + model +) -> Optional[str]: + """ + 使用 Traceback 分析解决问题 + """ + # 1. 提取 traceback + analyzer = TracebackAnalyzer() + traceback = analyzer.extract(issue) + + if not traceback: + # 回退到其他方法 + return solve_issue_without_traceback(issue, codebase, model) + + # 2. 获取错误位置 + file_path, line_no = analyzer.get_error_location(traceback) + + # 3. 获取上下文 + if file_path in codebase: + context = analyzer.get_context( + traceback, + codebase[file_path] + ) + else: + return None + + # 4. 生成补丁 + prompt = f""" +修复以下错误: + +Issue: {issue} + +错误位置: {file_path}:{line_no} +错误类型: {traceback.error_type} +错误消息: {traceback.error_message} + +上下文代码: +{context} + +生成最小化的修复补丁(git diff 格式)。 +""" + patch = model.generate(prompt) + + # 5. 验证(仍然需要 F2P 测试) + # ... + + return patch +``` + +### Template 3: 组合策略(最优方案) + +```python +class HybridIssueSolver: + """ + 组合 F2P 测试和 Traceback 分析的混合策略 + + 结合 1st Place 和 5th Place 的优势 + """ + + def __init__(self, model): + self.model = model + self.traceback_analyzer = TracebackAnalyzer() + self.f2p_generator = F2PTestGenerator(model) + + def solve( + self, + issue: str, + codebase: Dict[str, str] + ) -> Optional[str]: + """ + 主解决流程 + """ + # 1. 尝试提取 traceback + traceback = self.traceback_analyzer.extract(issue) + + # 2. 根据情况选择策略 + if traceback: + return self._solve_with_traceback(issue, traceback, codebase) + else: + return self._solve_with_f2p(issue, codebase) + + def _solve_with_traceback( + self, + issue: str, + traceback: TracebackInfo, + codebase: Dict[str, str] + ) -> Optional[str]: + """ + 使用 traceback 精准定位 + """ + # 1. 获取错误位置 + file_path, line_no = self.traceback_analyzer.get_error_location(traceback) + + # 2. 获取精准上下文 + if file_path and file_path in codebase: + context = self.traceback_analyzer.get_context( + traceback, + codebase[file_path] + ) + else: + return None + + # 3. 生成 F2P 测试(即使有 traceback 也要测试) + test_code = self.f2p_generator.generate(issue, context) + + # 4. 生成补丁 + patch = self._generate_traceback_aware_patch( + issue, traceback, context, test_code + ) + + # 5. 验证 + validation = self.f2p_generator.validate( + test_code, + codebase[file_path], + apply_patch(codebase[file_path], patch) + ) + + return patch if validation['valid_f2p'] else None + + def _solve_with_f2p( + self, + issue: str, + codebase: Dict[str, str] + ) -> Optional[str]: + """ + 使用纯 F2P 测试策略(1st Place 方法) + """ + # 1. 全面分析 issue + context = self._analyze_issue(issue, codebase) + + # 2. 生成 F2P 测试 + test_code = self.f2p_generator.generate(issue, context) + + # 3. 生成补丁 + patch = self._generate_patch(issue, test_code, context) + + # 4. 验证 + # ... (验证逻辑) + + return patch + + def _generate_traceback_aware_patch( + self, + issue: str, + traceback: TracebackInfo, + context: str, + test_code: str + ) -> str: + """生成基于 traceback 的精准补丁""" + prompt = f""" +修复以下错误: + +Issue: {issue} +错误类型: {traceback.error_type} +错误消息: {traceback.error_message} + +上下文: +{context} + +F2P 测试: +{test_code} + +生成最小化修复补丁(git diff 格式)。 +""" + return self.model.generate(prompt) + + def _generate_patch( + self, + issue: str, + test_code: str, + context: str + ) -> str: + """生成常规补丁""" + prompt = f""" +修复以下 bug: + +Issue: +{issue} + +测试用例: +{test_code} + +代码上下文: +{context} + +生成修复补丁(git diff 格式)。 +""" + return self.model.generate(prompt) +``` + +--- + +## 关键经验教训 + +### 从排名差异中学到的 + +#### 1. F2P 测试是成功的必要条件 + +**证据**: +- 1st Place: 使用 F2P → 7.5% +- 5th Place: 使用 F2P → ~5% +- 6th Place: 无 F2P → 0.8% + +**结论**: +> **没有 F2P 测试,不可能获得好成绩** + +#### 2. Traceback 分析提供显著优势 + +**分析**: +- 5th Place 的 traceback 分析使其在 6th Place 基础上提升了 ~4.2% +- 精准的上下文管理减少了 LLM 幻觉 +- 更高效的 token 使用 + +**建议**: +> **有 traceback 一定要用,没有也要尝试提取** + +#### 3. 保守策略是明智的 + +**证据**: +- 所有前排方案都采用保守提交策略 +- 错误修复的惩罚远大于跳过 + +**实践**: +```python +# 保守的阈值设置 +CONFIDENCE_THRESHOLD = 0.9 +MAX_PATCH_SIZE = 500 +MAX_FILES_MODIFIED = 2 + +def should_submit(patch, validation_result): + return ( + validation_result['valid_f2p'] and + len(patch) < MAX_PATCH_SIZE and + validation_result['confidence'] > CONFIDENCE_THRESHOLD + ) +``` + +### 实施建议 + +#### 优先级 1: 实现 F2P 测试 + +```python +# 最小化的 F2P 实现 +def minimal_f2p(issue, code, model): + # 1. 生成测试 + test = generate_test(issue, code, model) + + # 2. 验证测试 + if not test_fails_on_original(test, code): + return None # 测试无效 + + # 3. 生成补丁 + patch = generate_patch(issue, test, code, model) + + # 4. 验证补丁 + if not test_passes_on_patched(test, patch, code): + return None # 补丁无效 + + return patch +``` + +#### 优先级 2: 添加 Traceback 分析 + +```python +# 最小化的 Traceback 实现 +def minimal_traceback_analysis(issue): + import re + + # 提取文件和行号 + pattern = r'File "([^"]+)", line (\d+)' + matches = re.findall(pattern, issue) + + if matches: + return { + 'file': matches[0][0], + 'line': int(matches[0][1]), + 'has_traceback': True + } + + return {'has_traceback': False} +``` + +#### 优先级 3: 采用保守策略 + +```python +# 保守的提交决策 +def conservative_submit(patch, validation): + # 多重检查 + checks = [ + validation['valid_f2p'], + len(patch) < 500, + validation['confidence'] > 0.9, + validation['files_modified'] <= 2 + ] + + # 所有检查通过才提交 + return all(checks) +``` + +### 技术栈建议 + +#### 模型选择 + +| 任务 | 推荐模型 | 原因 | +|------|----------|------| +| 补丁生成 | Qwen2.5-Coder-32B | 代码生成能力强 | +| 测试生成 | Qwen2.5-Coder-32B | 理解测试逻辑 | +| 验证 | Qwen2.5-Coder-32B | 一致性好 | +| Traceback 分析 | 规则(不需要模型) | 精确且快速 | + +#### 性能优化 + +```python +# 并行处理 +from concurrent.futures import ThreadPoolExecutor + +def parallel_verify(patches, issue, model, num_workers=4): + """并行验证多个补丁""" + with ThreadPoolExecutor(max_workers=num_workers) as executor: + futures = [ + executor.submit(verify_patch, patch, issue, model) + for patch in patches + ] + results = [f.result() for f in futures] + return results +``` + +### 常见陷阱 + +#### ❌ 陷阱 1: 信任单次验证 + +```python +# 错误:单次验证 +if verify(patch) == "Yes": + submit(patch) # 可能是幻觉 + +# 正确:多次验证 +verifications = [verify(patch) for _ in range(5)] +if sum(v == "Yes" for v in verifications) >= 4: + submit(patch) +``` + +#### ❌ 陷阱 2: 忽略补丁大小 + +```python +# 错误:不考虑大小 +if is_valid_patch(patch): + submit(patch) # 可能提交巨大补丁 + +# 正确:考虑大小 +if is_valid_patch(patch) and len(patch) < 500: + submit(patch) +``` + +#### ❌ 陷阱 3: 没有测试就提交 + +```python +# 错误:没有测试 +if llm_says_good(patch): + submit(patch) + +# 正确:必须有测试 +if test_fails_on_original(test, code) and test_passes_on_patched(test, patch, code): + submit(patch) +``` + +--- + +## 总结 + +### 核心要点 + +1. **F2P 测试是关键**: 所有前排方案都使用 +2. **Traceback 分析提供优势**: 5th Place 的核心创新 +3. **保守策略获胜**: 质量远比数量重要 +4. **组合策略最优**: 结合两种方法的效果最好 + +### 实施路线图 + +**阶段 1: 基础** +- 实现 F2P 测试生成和验证 +- 实现保守提交策略 + +**阶段 2: 优化** +- 添加 Traceback 分析 +- 实现多次验证 +- 添加大小惩罚 + +**阶段 3: 精进** +- 优化 prompt +- 并行处理 +- 性能优化 + +### 最终建议 + +> **"从 6th Place 的基础架构开始,添加 5th Place 的 traceback 分析,最终实现 1st Place 的 F2P 测试和保守策略"** + +--- + +**文档版本**: 1.0 +**最后更新**: 2026-01-25 +**参考来源**: +- Kaggle Konwinski Prize 竞赛页面 +- 6th Place 开源代码: https://github.com/quan16369/Kaggle-Konwinski-Prize-6th-Place-Solution- +- 策略指南: https://github.com/raymyers/konwinski-prize-strategy-guide +- SWE-bench: https://www.swebench.com/ |
