ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenClaw + claude code + codex 自动修复 Bug Agent 完整方案:从 401 报错到跑通全流程

OpenClaw + claude code + codex 自动修复 Bug Agent 完整方案:从 401 报错到跑通全流程 1. 为什么你的 Bug Agent 总卡在 401 和 local proxy failedOpenClaw 编排 claude code 与 codex 做自动修复 Bug Agent本质是把「读报错 → 定位 → 改代码 → 跑测试 → 提 PR」串成一条流水线。听起来很顺但真正动手时十个人里有八个会先撞在鉴权上claude 报 401codex 报 local proxy failed或者日志里出现reading choices这种让人摸不着头脑的字段错误。这些报错跟你的 Agent 逻辑没关系全是 endpoint 和 auth.json 没配对。我先把这套方案能做什么讲清楚它适合已经有一个能跑测试的代码仓库、想让 Agent 自动处理简单到中等复杂度 Bug 的开发者。你不需要重写整个工程只需要把三个工具的分工定好——OpenClaw 当调度器管状态和重试claude code 负责读代码、定位根因、评审补丁codex 负责按约束生成 unified diff 并执行修改。三者通过统一的 Base URL 和 Key 走同一个入口才能避免一半请求通、一半请求 401 的割裂状态。核心检索词先摆出来OpenClaw 自动修复 Bug Agent 的完整链路卡点集中在鉴权配置和 endpoint 一致性。claude code 和 codex 各自读不同的环境变量如果你只配了一个另一个必然报错。而 local proxy failed 通常是本地起了代理进程但端口没对上或者 auth.json 里的 base_url 指向了一个不存在的本地地址。这篇会按「先解决鉴权 → 再跑通单次修复 → 最后接 GitHub 自动开 PR」的顺序写。每一步都给可复制的配置片段你照着改路径和 Key 就能用。下面先从最容易被忽略的前置准备讲起把 endpoint 和 auth.json 一次配对。2. TaoToken 前置统一 endpoint 与 auth.json 配置2.1 为什么需要统一入口claude code 默认读ANTHROPIC_API_KEY和ANTHROPIC_BASE_URLcodex 默认读OPENAI_API_KEY和OPENAI_BASE_URL。两个工具的环境变量名不同但如果你让它们各自指向不同的服务地址就会出现一个通、一个 401 的情况。更麻烦的是OpenClaw 在调度时会把两个工具的调用混在同一个进程里环境变量互相覆盖最后谁也跑不起来。解决办法是让 claude code 和 codex 都走同一个 Base URLKey 也用同一套。TaoToken 的 API 入口是https://taotoken.net/api这个地址同时兼容 Anthropic 和 OpenAI 两种协议格式。你只需要在环境变量里把两个工具的 base_url 都指向它Key 用同一个就能消除鉴权分裂。2.2 环境变量配置先建一个.env.agent文件把所有 Key 和地址写进去# .env.agent export TAOTOKEN_API_KEYsk-your-taotoken-key export TAOTOKEN_BASE_URLhttps://taotoken.net/api # claude code 读这两个 export ANTHROPIC_API_KEY$TAOTOKEN_API_KEY export ANTHROPIC_BASE_URL$TAOTOKEN_BASE_URL # codex 读这两个 export OPENAI_API_KEY$TAOTOKEN_API_KEY export OPENAI_BASE_URL$TAOTOKEN_BASE_URL # GitHub 相关 export GITHUB_TOKENghp_your_github_token export GITHUB_REPOowner/repo-name加载方式source .env.agent这里有个坑如果你之前已经 export 过ANTHROPIC_API_KEYsource 不会覆盖已有的值。先unset ANTHROPIC_API_KEY OPENAI_API_KEY再 source确保新值生效。2.3 auth.json 配置codex 除了读环境变量还会读~/.codex/auth.json。如果这个文件存在且内容跟环境变量冲突codex 会优先用 auth.json 里的值导致你改了环境变量却不生效。所以要么删掉 auth.json要么把它改成跟环境变量一致{ OPENAI_API_KEY: sk-your-taotoken-key, OPENAI_BASE_URL: https://taotoken.net/api }路径确认~/.codex/auth.json。如果你用的是项目级配置路径可能是./.codex/auth.json两个都检查一遍。claude code 的配置文件在~/.claude/settings.json如果里面有apiKeyHelper或baseUrl字段也要改成一致{ baseUrl: https://taotoken.net/api, apiKey: sk-your-taotoken-key }2.4 验证配置是否生效配完之后别急着跑 Agent先单独验证两个工具能不能通# 验证 claude code claude --print --prompt reply with OK --model claude-sonnet-4-20250514 # 验证 codex codex --approval-mode suggest --prompt reply with OK如果 claude 返回 OK 而 codex 报 401说明 codex 的 auth.json 没改对。如果两个都报 local proxy failed检查是不是本地起了代理进程占用了端口或者ANTHROPIC_BASE_URL被其他配置覆盖了。3. 可复制配置OpenClaw 编排与工具层设置3.1 OpenClaw 的 settings.yamlOpenClaw 的编排配置放在config/settings.yaml核心是把 fixer 策略和工具参数写清楚agent: name: bugfix-agent max_concurrent_fixes: 2 fix_timeout_seconds: 600 max_retries: 3 fixers: strategy: ensemble claude: enabled: true model: claude-sonnet-4-20250514 max_tokens: 16000 temperature: 0.1 timeout: 300 cli_args: - --allowedTools - Edit,Read,Write,Bash(pytest:*),Bash(git:diff*),Grep,Glob codex: enabled: true model: o4-mini timeout: 300 approval_mode: full-auto ensemble: mode: cascade verifier: run_tests: true run_lint: true test_command: pytest -x --timeout120 lint_command: ruff check . min_confidence: 0.6 github: repo: ${GITHUB_REPO} token: ${GITHUB_TOKEN} labels_to_watch: - bug - auto-fix base_branch: main pr_branch_prefix: auto-fix/ auto_merge: false这里strategy: ensemble配合mode: cascade的意思是先用 claude code 修如果测试没过或置信度低于 0.6再用 codex 修一遍。这样既利用了 claude 的代码理解能力又用 codex 的稳定输出兜底。3.2 claude code 的 CLAUDE.md在项目根目录放一个CLAUDE.md让 claude code 知道修复规则# CLAUDE.md ## 修复原则 1. 最小改动只改跟 bug 直接相关的代码 2. 保持风格遵循现有代码的命名和缩进 3. 必须加测试每次修复附带一个回归测试 4. 不重构不修改无关代码 ## 提交格式 fix(scope): description [#issue-number] ## 常用命令 - 跑测试pytest -x - 代码检查ruff check .3.3 codex 的 codex.mdcodex 读项目根目录的codex.md# codex.md ## Role You are a bug-fixing agent. Fix only the reported bug with minimal changes. ## Rules 1. Read the bug report carefully 2. Find the root cause 3. Apply the minimal fix 4. Add or update tests 5. Ensure all tests pass 6. Do NOT refactor unrelated code ## Commands - Run tests: pytest -x - Lint: ruff check .3.4 工具层的 Base URL 注入OpenClaw 在调用 claude code 和 codex 时需要把 Base URL 传进去。在src/fixers/claude_fixer.py里import os env { **os.environ, ANTHROPIC_API_KEY: os.getenv(TAOTOKEN_API_KEY, ), ANTHROPIC_BASE_URL: os.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api), } process await asyncio.create_subprocess_exec( claude, --print, --output-format, json, --model, self.model, --prompt, prompt, cwdstr(self.work_dir), stdoutasyncio.subprocess.PIPE, stderrasyncio.subprocess.PIPE, envenv, )codex 那边同理env { **os.environ, OPENAI_API_KEY: os.getenv(TAOTOKEN_API_KEY, ), OPENAI_BASE_URL: os.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api), }关键点两个 fixer 都用TAOTOKEN_API_KEY和TAOTOKEN_BASE_URL作为唯一来源避免环境变量分裂。4. 验证请求从读取报错到提交修复的完整链路4.1 准备一个带 Bug 的测试仓库建一个最小 Python 项目故意留一个除零 Bug# math_utils.py def calculate_average(total, count): return total / count# test_math_utils.py from math_utils import calculate_average def test_average_normal(): assert calculate_average(10, 2) 5 def test_average_zero_count(): assert calculate_average(10, 0) 0跑一下pytest -x第二个测试会失败报ZeroDivisionError。这就是我们要让 Agent 自动修的 Bug。4.2 手动触发单次修复先不接 GitHub直接用 OpenClaw 的 CLI 触发python -m src.main --issue 1 --local-repo ./test-repoAgent 的执行流程第一步claude code 读math_utils.py和test_math_utils.py定位到calculate_average缺少count 0的判断。它输出一个 JSON 格式的修复计划{ hypotheses: [count 为 0 时未做边界检查], suspect_files: [math_utils.py], fix_plan: [ {file: math_utils.py, change: 添加 count 0 时返回 0 的分支} ] }第二步codex 根据修复计划生成 unified diffdiff --git a/math_utils.py b/math_utils.py --- a/math_utils.py b/math_utils.py -1,2 1,4 def calculate_average(total, count): if count 0: return 0 return total / count第三步OpenClaw 用git apply把 diff 应用到工作目录。第四步跑pytest -x两个测试都通过。第五步claude code 评审 diff确认改动最小、没有引入新问题输出approve: true。4.3 验证成功结果修复完成后检查三件事# 1. 测试是否通过 pytest -x # 输出2 passed in 0.01s # 2. diff 是否符合预期 git diff # 应该只看到 math_utils.py 的两行新增 # 3. 评审结论 cat logs/agent.log | grep review # 输出review approvetrue confidence0.85如果这三步都过了说明从读取报错到提交修复的链路已经跑通。接下来接 GitHub让 Agent 自动开 PR。4.4 接 GitHub 自动开 PR在config/settings.yaml里把github.repo改成你的仓库然后python -m src.main --issue 42 --githubAgent 会从 GitHub 拉取 issue #42 的描述和报错日志在本地 clone 仓库创建分支auto-fix/issue-42执行修复流程提交并推送分支用gh pr create开 PRPR 描述里包含根因、修复方式、测试结果PR 创建成功后issue 上会自动加一条评论附上 PR 链接。5. 本篇常见错排查401、local proxy failed、reading choices5.1 401 Unauthorized报错原文Error: 401 Unauthorized {error: {message: Invalid API key, type: authentication_error}}原因claude code 或 codex 读到的 Key 是空的或者 Key 跟 Base URL 不匹配。排查步骤# 1. 确认环境变量已加载 echo $ANTHROPIC_API_KEY echo $OPENAI_API_KEY # 两个应该输出同一个 Key # 2. 确认 Base URL 一致 echo $ANTHROPIC_BASE_URL echo $OPENAI_BASE_URL # 两个应该都是 https://taotoken.net/api # 3. 检查 auth.json 是否覆盖了环境变量 cat ~/.codex/auth.json # 如果里面的 Key 跟环境变量不一致改成一致或删掉如果环境变量都对但还报 401检查是不是 shell 的 profile 文件里又 export 了一遍旧 Key。用env | grep -i api_key看所有相关的变量。5.2 local proxy failed报错原文Error: local proxy failed: connection refused原因本地起了代理进程但端口没对上或者代理进程已经挂了。排查步骤# 1. 检查是否有代理进程在跑 ps aux | grep -i proxy # 2. 检查端口占用 lsof -i :8080 lsof -i :3000 # 3. 如果不需要代理清掉相关环境变量 unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxy如果你确实需要本地代理做请求转发确认代理进程的监听端口跟ANTHROPIC_BASE_URL里的端口一致。但更简单的做法是直接用https://taotoken.net/api作为 Base URL不走本地代理。5.3 reading choices 报错报错原文TypeError: Cannot read properties of undefined (reading choices)原因codex 收到的响应格式跟它预期的不一样。codex 期望 OpenAI 格式的响应包含choices字段但实际收到的是 Anthropic 格式包含content字段或者收到的是错误响应。排查步骤# 1. 确认 codex 的 Base URL 指向 OpenAI 兼容端点 echo $OPENAI_BASE_URL # 应该是 https://taotoken.net/api # 2. 手动发一个请求看响应格式 curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $OPENAI_API_KEY \ -H Content-Type: application/json \ -d {model:o4-mini,messages:[{role:user,content:hi}]} \ | head -c 500如果响应里没有choices字段说明请求打到了错误的端点。检查OPENAI_BASE_URL是否被拼成了https://taotoken.net/api/v1这种多一层路径的形式。正确的做法是 Base URL 只写到/api让 SDK 自己拼/v1/chat/completions。5.4 OAuth 相关报错报错原文Error: OAuth token expired原因claude code 之前用 OAuth 登录过本地缓存了过期的 token优先于 API Key 使用。排查步骤# 1. 清掉 OAuth 缓存 rm -rf ~/.claude/oauth rm -rf ~/.config/claude # 2. 确认 settings.json 里没有 oauth 相关字段 cat ~/.claude/settings.json # 3. 重新用 API Key 模式 export ANTHROPIC_API_KEY$TAOTOKEN_API_KEY5.5 三件套检查清单每次遇到鉴权报错按这个清单过一遍检查项claude codecodexBase URLANTHROPIC_BASE_URLOPENAI_BASE_URLKeyANTHROPIC_API_KEYOPENAI_API_KEYModel IDclaude-sonnet-4-20250514o4-mini配置文件~/.claude/settings.json~/.codex/auth.json三件套Base URL Key Model ID必须同时正确缺一个就会报错。Model ID 写错会报 404Key 写错报 401Base URL 写错报连接失败。6. 语义一致 CTA把链路跑通后继续扩展链路跑通之后你可以把 Agent 接到更多触发源上。比如 GitHub Actions 里加一个 job当 issue 被打上auto-fix标签时自动触发修复或者接 Sentry webhook当新错误出现时自动开 PR。如果你在配 endpoint 或 auth.json 时遇到问题可以直接用模型对话验证 Key 是否可用确认鉴权没问题再回去跑 Agent。长期做编码和 Agent 编排的话Coding Plan 能省掉每次手动配 Key 的麻烦。所有接入细节和配置模板都在接入文档里照着改路径就能用。最后留一个实用技巧把TAOTOKEN_BASE_URL和TAOTOKEN_API_KEY写进 shell 的 profile 文件~/.bashrc或~/.zshrc这样每次开新终端都自动加载不用重复 source。但记得把ANTHROPIC_API_KEY和OPENAI_API_KEY的 export 也写进去指向同一个 Key避免环境变量分裂。
返回列表