# Repair Agent - 自动化 Bug 修复代理 从 Log Center 获取 Bug,使用 Claude Code CLI 自动修复,支持多轮重试、测试验证、自动提交。 ## 前置条件 - Python 3.12+ - [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) 已安装并登录(终端运行 `claude` 可用) - 目标项目代码已 clone 到本地 ## 快速开始 ### 1. 安装依赖 ```bash cd log_center/repair_agent pip install -r requirements.txt ``` ### 2. 配置环境变量 ```bash cp .env.example .env ``` 编辑 `.env`,必须配置的项: ```bash # Log Center API 地址(默认已配置线上地址) LOG_CENTER_URL=https://qiyuan-log-center-api.airlabs.art # Claude CLI 路径(如果 claude 不在 PATH 中需要指定完整路径) CLAUDE_CLI_PATH=claude CLAUDE_TIMEOUT=1000 # Claude 执行超时(秒) # 项目本地路径(修改为你的实际路径) PATH_RTC_BACKEND=/Users/maidong/Desktop/zyc/qy_gitlab/rtc_backend PATH_RTC_WEB=/Users/maidong/Desktop/zyc/qy_gitlab/rtc_web PATH_AIRHUB_APP=/Users/maidong/Desktop/zyc/qiyuan_gitea/rtc_prd/airhub_app ``` 可选配置: ```bash # Git 自动提交(配置后 --commit 才生效) GITHUB_REPO_RTC_BACKEND=https://gitea.example.com/org/rtc_backend.git GITEA_TOKEN=your_token_here # 安全限制 MAX_RETRY_COUNT=3 # 最大修复轮次 MAX_MODIFIED_LINES=50 # 单次最大修改行数 MAX_MODIFIED_FILES=5 # 单次最大修改文件数 CRITICAL_FILES=payment,auth,security # 禁止修改的核心文件关键词 ``` ### 3. 验证配置 ```bash python -m repair_agent status ``` 输出会显示 Log Center 连接地址、Claude CLI 路径、各项目路径等,确认无误即可。 ## 命令大全 ### 查看待修复 Bug ```bash python -m repair_agent list # 所有项目 python -m repair_agent list -p rtc_backend # 指定项目 ``` ### 修复 Bug ```bash # 修复指定项目的所有待修复 Bug(NEW / PENDING_FIX 状态) python -m repair_agent fix rtc_backend # 修复但不运行测试 python -m repair_agent fix rtc_backend --no-test # 修复并自动提交推送(需配置 Git 仓库地址) python -m repair_agent fix rtc_backend --commit ``` ### 修复单个 Bug ```bash python -m repair_agent fix-one 11 # 按 Bug ID 修复 python -m repair_agent fix-one 11 --no-test # 不运行测试 ``` ### 重试失败的 Bug 对 `FIX_FAILED` 状态的 Bug 重新处理(先分诊判断是否为代码缺陷,再决定修复或标记为无法复现): ```bash python -m repair_agent retry # 所有项目 python -m repair_agent retry -p rtc_backend # 指定项目 python -m repair_agent retry --commit # 修复后自动提交 ``` ### 分析 Bug(不修复) ```bash python -m repair_agent analyze 11 # 只分析,不修改代码 ``` ### 定时守护模式 启动后台守护进程,定时扫描新 Bug 并自动修复: ```bash # 默认每小时扫描一次所有项目 python -m repair_agent watch # 每 30 分钟扫描,只监控指定项目 python -m repair_agent watch -i 1800 -p rtc_backend # 监控多个项目,自动提交 python -m repair_agent watch -p rtc_backend -p rtc_web --commit python -m repair_agent watch -i 60 -c # Ctrl+C 停止 ``` ## 修复流程 ``` 获取 NEW/PENDING_FIX 的 Bug | 状态改为 FIXING | ┌─────v─────┐ │ Claude CLI │ ← 修复代码 + 运行针对性测试 │ 修复代码 │ └─────┬─────┘ | 获取 Git diff | 安全检查(文件数/行数/核心文件) | ┌───v───┐ │ 测试? │──── 跳过测试 ──→ 从 Claude 输出提取验证结果 └───┬───┘ | TestRunner 运行测试 | ┌───v───┐ │ 通过? │── 否 ──→ 回滚代码,进入下一轮(最多 3 轮) └───┬───┘ 最终失败 → FIX_FAILED | FIXED ──→ 上传修复报告(含测试输出) | 自动提交推送(可选) ``` ## Bug 状态流转 | 状态 | 含义 | 触发条件 | |------|------|---------| | `NEW` | 新发现 | 日志上报 | | `FIXING` | 修复中 | 开始修复 | | `FIXED` | 已修复 | 修复成功 + 测试通过 | | `FIX_FAILED` | 修复失败 | 测试不通过 / Claude 执行失败 / 异常终止 | | `CANNOT_REPRODUCE` | 无法复现 | 分诊判定非代码缺陷 | | `PENDING_FIX` | 待修复 | retry 分诊后判定可修复 | ## 修复报告 每轮修复都会上传报告到 Log Center,包含: | 字段 | 内容 | |------|------| | `ai_analysis` | Claude 的完整分析和修复过程 | | `code_diff` | 代码变更 diff | | `test_output` | 测试/验证命令的实际执行输出 | | `test_passed` | 测试是否通过 | | `repair_round` | 第几轮修复 | | `failure_reason` | 失败原因(成功时为空) | ## 架构 ``` repair_agent/ ├── agent/ │ ├── core.py # 核心修复引擎(多轮重试、异常兜底) │ ├── task_manager.py # 与 Log Center API 交互 │ ├── git_manager.py # Git 操作(分支、提交、推送) │ ├── claude_service.py # Claude Code CLI 调用(提示词编排) │ ├── test_runner.py # 测试执行(自动检测 Django/pytest/npm) │ └── scheduler.py # 定时扫描守护进程 ├── config/ │ └── settings.py # 配置管理(pydantic-settings + .env) ├── models/ │ └── bug.py # 数据模型(Bug、RepairReport 等) ├── __main__.py # CLI 入口(typer) ├── .env.example # 环境变量模板 └── requirements.txt # Python 依赖 ``` ## 常见问题 **Q: Bug 卡在 FIXING 状态怎么办?** 流程中已有异常兜底,会自动标记为 `FIX_FAILED`。如果仍有残留,可通过 API 手动重置: ```bash curl -X PUT "https://qiyuan-log-center-api.airlabs.art/api/v1/tasks/{bug_id}/status" \ -H "Content-Type: application/json" \ -d '{"status": "NEW", "message": "手动重置"}' ``` **Q: Claude CLI 超时怎么办?** 调大 `.env` 中的 `CLAUDE_TIMEOUT`(默认 1000 秒)。 **Q: 如何只修复不提交?** 不加 `--commit` 参数即可,默认只修改本地代码不提交。 **Q: watch 模式会不会重复修复同一个 Bug?** 不会。Bug 被拾取后状态改为 `FIXING`,不在 `NEW/PENDING_FIX` 范围内,不会被重复拾取。