无题
APR-MCTS原理
核心数据结构
Node节点结构
1 | class Node: |
在expand(node: Node)函数中,每次调用LLM生成修复补丁时,LLM的回复通常包含两部分:反思(reflection)和补丁(patch),通过extract_reflection_from_response(response)函数,从LLM的回复中提取反思内容(即motivation),通常是补丁代码前面的解释或思考,创建子节点时,将提取到的反思内容赋值给child.motivation。
self.patch_diffs用于保存每个节点(Node)在扩展时生成的补丁(patch)与原始代码之间的差异信息(diff)。每次生成并验证一个补丁后,会通过 framework.validate_patch获取该补丁的 git diff(即代码变更内容),并将其存入 self.patch_diffs。这样可以方便后续分析、记录和展示每个补丁的具体修改细节。
Bug状态表示
每个节点包含一个Bug对象,记录:
- 项目信息、bug ID、bug类型(SL/SH/SF)
- 源代码、掩码代码、测试代码
- 失败测试、错误信息等
1 | class Bug(object): |
MCTS四个核心步骤
Selection(选择阶段)
1 | def select_node(node: Node): |
使用**UCB(Upper Confidence Bound)**公式选择节点:
1 | def get_best_child(node: Node): |
Expansion(扩展阶段)
1 | def expand(node: Node): |
Simulation(模拟阶段)
跳过了传统的模拟阶段,直接使用LLM的反馈作为评估:
1 | # skip simulating |
Backpropagation(反向传播)
1 | def back_propagate(node): |
奖励机制设计
补丁验证结果
PASS: 补丁通过所有测试 → 终止搜索FAIL: 测试失败但可编译 → 继续搜索ERROR: 编译错误 → 奖励-1
LLM评分
使用专门的奖励模型对补丁质量打分(0-100分):
1 | def get_reward(bug: Bug, wrong_patch, reflection): |
搜索策略
- 每次扩展生成
branch个候选补丁(默认4个) - 最大扩展数
max_expansion限制子节点数量 - 最大rollout数
max_rollout限制搜索轮次
支持的Bug类型
从defects4j.sh中的分类逻辑可以看出,系统根据Git差异将bug分为4种类型:
1 | SINGLE_LINE="SL SH SF" # 单行修复 |
分类标准:
- 文件数量 > 2 →
OT(Other) - 行变更 < 2 →
SL(Single Line) - 同一函数内连续变更 →
SH(Single Hunk) - 同一函数内非连续变更 →
SF(Single Function) - 跨多个函数变更 →
OT(Other)
不同的模式在应用代码patch时有区别:
- SF模式(Single Function):补丁是一个完整的函数替换
- 非SF模式:使用模板填空的方式,将补丁填入到
>>> [ INFILL ] <<<标记位置
Prompt
Patch生成
主要包含以下几个核心部分:
**系统角色定义 **
- “You are an automated program repair tool. Please do not use language features beyond java 1.4, such as foreach and generics <>.”
问题描述
- Single Line:
- 描述:
"The following code contains a buggy line that has been removed." - 包含带有
>>> [ INFILL ] <<<标记的掩码代码 - 显示被移除的原始错误行
- 描述:
- Single Hunk:
- 描述:
"The following code contains a buggy hunk that has been removed." - 包含带有
>>> [ INFILL ] <<<标记的掩码代码块 - 显示被移除的原始错误代码块
- 描述:
- Single Function:
- 描述:
"The following code contains a bug" - 直接显示包含bug的完整函数代码
- 描述:
- Single Line:
**代码上下文 **
bug.masked_code // 掩码后的代码(SL/SH) bug.code // 完整代码(SF) bug.buggy_lines // 原始错误行/块1
2
3
4
5
6
- **测试用例 **
- ```python
Test cases look like:
bug.extract_test_code // 提取的相关测试方法代码
错误信息
The code fails with the following test error: bug.failing_tests // 失败的测试错误信息
推理指导
- “Before you give the final answer, let’s think step by step. You need to explain where bug happens and how your answer can avoid it.”
输出格式要求
- SL模式:
"please provide the correct line at the infill location, only single line is allowed""your answer must be different from [原始错误行]""your answer should begin with ```java"
- SH模式:
"please provide the correct hunk at the infill location, only single hunk is allowed"- 类似SL的格式要求
- SF模式:
"please provide the correct function, starting with ```java"
- SL模式:
约束条件
- 必须与原始错误代码不同
- 必须以特定格式开始(```java)
- 只能修改指定范围的代码
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ZWN's blog!
评论




