智能体实战:构建一个像RepairAgent一样能自主修复代码的LLM代理

发布时间:2026/7/5 22:47:56

智能体实战:构建一个像RepairAgent一样能自主修复代码的LLM代理 1. 从零理解RepairAgent什么是能自主修Bug的LLM代理第一次听说能自动修Bug的AI时我的反应和大多数程序员一样这不就是高级点的静态代码检查工具吗直到亲眼看到RepairAgent在Defects4J数据集上修复了164个Bug包括39个前人未解决的难题才意识到这次真的不一样。这就像给GPT-3.5装上了程序员的瑞士军刀让它不仅能诊断问题还能亲自操刀手术。传统基于LLM的代码修复就像个一问一答的客服你喂给它错误代码和测试用例它返回修复建议。这种方式有两个致命伤一是缺乏上下文感知二是修复过程不可控。而RepairAgent的创新在于引入了工具调用机制——想象你带实习生debug不仅要告诉他哪里错了还要给他权限去查日志、改配置、跑测试。这个权限就是14种精心设计的工具包括代码显微镜read_range/extract_method查看任意文件的指定行或方法实现语义搜索引擎search_code_base用代码特征而非纯文本匹配进行搜索安全沙盒write_fix在隔离环境应用补丁并自动回滚失败的修改最精妙的是动态提示工程。不同于固定prompt模板RepairAgent的提示词像手术室里的实时监护仪会随着修复进程动态更新当前状态检查/修复/验证、已收集信息、剩余尝试次数等。这就让LLM像主治医师一样能根据患者体征调整治疗方案。2. 解剖修复智能体三大核心模块设计精要2.1 工具链设计给LLM装上程序员工具箱设计工具链时团队深度观察了人类开发者的debug行为。比如当看到NullPointerException时我们通常会定位异常堆栈对应run_fault_localization工具查看相关变量定义read_range搜索相似处理逻辑search_code_base修改后立即验证write_fixrun_testsRepairAgent的14种工具覆盖了完整工作流其中有几个设计亮点抗幻觉搜索find_similar_api_calls工具能阻止LLM发明不存在的API。比如搜索快速排序时会自动关联到代码库中的quickSort方法结构化补丁write_fix要求补丁以特定JSON格式提交支持多文件协同修改。就像Git提交时同时修改Controller、Service和DAO层状态安全锁control类工具确保必须现有假设才能进入修复阶段避免盲目修改# 工具调用示例定位并修复空指针异常 { command: express_hypothesis, params: { hypothesis: 可能未对userInput参数做非空校验 } }2.2 状态机协调像老司机一样的决策流程想象新手debug时常陷入的困境还没看懂问题就开始改代码或者在错误的方向钻牛角尖。RepairAgent通过三状态有限状态机规避这些问题Understand the bug诊断间可用工具代码阅读、测试执行、故障定位出口条件必须提出明确假设如登录失败是因为密码加密算法不一致Collect information资料室可用工具代码搜索、相似API查找典型操作查找同类异常处理代码或相关函数调用链Try to fix手术室可用工具代码生成、补丁应用安全机制每次修改自动生成恢复点这种设计强制LLM遵循科学debug流程。实测显示状态机能将无效修复尝试减少63%因为LLM必须像医生写病历一样先记录诊断依据才能开处方。2.3 动态提示工程让LLM保持思维在线静态prompt的最大问题是会遗忘上下文。RepairAgent的提示词包含7个动态部分其中最关键是状态描述像GPS导航一样提醒LLM当前阶段和目标收集信息看板以Markdown表格形式汇总已获取的代码片段、测试结果等执行历史记录最近5次工具调用及结果避免循环操作| 循环次数 | 执行工具 | 关键发现 | |----------|-------------------|------------------------------| | 1 | run_fault_localization | NullPointerException UserService.java:42 | | 2 | read_range | 未对inputParam做null检查 | | 3 | search_code_base | 找到5处类似参数校验代码 |这种设计产生了有趣的涌现能力当测试再次失败时LLM会主动对比当前失败模式与历史记录像侦探一样发现这两个失败案例都发生在用户名为空时。3. 实战构建用GPT-3.5打造你的修复代理3.1 最小可行工具链搭建不必一开始就实现全部14种工具。我从这四个核心工具起步就能处理80%的简单Bug代码阅读器Python实现示例def read_range(file_path, start_line, end_line): with open(file_path) as f: return .join(f.readlines()[start_line-1:end_line])语义搜索器用AST解析代替纯文本匹配识别出所有调用特定方法的代码块补丁验证器利用docker创建隔离环境应用补丁后运行测试套件假设记录仪强制LLM在修复前格式化输出假设原因如{hypothesis: Timeout错误可能源于未设置数据库连接池大小}3.2 状态机实现技巧用枚举类定义三种状态并通过装饰器实现状态校验from enum import Enum, auto class AgentState(Enum): DIAGNOSING auto() RESEARCHING auto() FIXING auto() def state_guard(allowed_states): def decorator(func): def wrapper(self, *args, **kwargs): if self.current_state not in allowed_states: raise ValueError(f该操作仅允许在{allowed_states}状态执行) return func(self, *args, **kwargs) return wrapper return decorator这样当LLM试图在诊断阶段直接调用代码生成工具时会收到明确错误提示generate_method_body工具仅在FIXING状态可用。3.3 提示词模板设计我的动态提示包含这些必选部分以Python异常修复为例# 角色 你是有10年经验的Python调试专家正在修复{bug_type}异常 # 当前状态 {state_description} (剩余尝试次数{remaining_attempts}) # 已收集信息 {collected_info_table} # 可用工具 {available_tools_list} # 最后操作 {last_command_result} # 输出格式要求 {thoughts: 分析过程, command: {name: tool_name, params: {...}}}关键技巧是在collected_info_table中使用对比展示。比如当LLM尝试过两种修复方案时并列显示它们的测试结果尝试方案A增加超时时间 → 测试失败连接泄漏 尝试方案B缩小事务范围 → 测试通过但性能下降50%4. 避坑指南从论文到实践的三个关键挑战4.1 工具可靠性陷阱初期我的代理经常卡死因为没处理这些边界情况文件路径解析用户输入../models/User.py需要标准化为绝对路径编码问题GBK编码的Java文件导致read_range崩溃长上下文截断提取的方法超过GPT-3.5的token限制解决方案是给每个工具添加预处理层def safe_read_range(file_path, start_line, end_line): normalized_path os.path.abspath(file_path) with open(normalized_path, encodingutf-8, errorsignore) as f: lines f.readlines() end_line min(end_line, len(lines)) # 防止越界 excerpt lines[start_line-1:end_line] return \n.join(excerpt)[:8000] # 硬截断避免token超标4.2 状态震荡问题在早期版本中LLM经常在收集信息和尝试修复状态间来回切换像无头苍蝇。通过引入状态停留奖励机制解决连续在同一状态完成3次有效操作后工具调用成功率提升15%。更有效的方案是扩展状态定义class EnhancedState(AgentState): DIAGNOSING {description: 正在分析堆栈跟踪, min_duration: 2} RESEARCHING {description: 搜索相似修复模式, min_duration: 3} FIXING {description: 实施修复方案, allow_rollback: True}4.3 成本控制策略在AWS g4dn.xlarge实例上测试时发现主要成本来自GPT-3.5 API调用每次循环1次请求测试环境部署每次write_fix启动docker容器优化方案本地缓存对read_range/search_code_base的结果建立LRU缓存批量测试累积多个补丁后统一验证早期终止当连续3次修复使问题恶化时自动停止实测这些优化能将平均修复成本从$1.2降至$0.35同时保持85%的原有效果。

相关新闻