告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度1. 用 OpenHands 修一个真实回归测试失败OpenHands 是一个开源的软件工程 Agent能自己读仓库、跑命令、改代码、再跑测试把「定位失败断言 → 改实现 → 测试通过」这条链路走完。这篇要做的是拿一个带回归测试失败的 Python 仓库让 OpenHands 在 TaoToken 提供的 LLM 后端上跑通整个修复闭环最后交付三样东西修复 diff、测试输出记录、OpenHands 配置片段。适合谁看已经在用 OpenHands 或准备上手、手里有 Python 项目、想让 Agent 帮忙处理测试回归的人。前置条件不复杂——Python 3.10、DockerOpenHands 官方推荐用容器跑、一个能用的 LLM Key。我这次把 TaoToken 设成默认供应商Base URL 填https://taotoken.net/api模型走 Claude 系因为 OpenHands 对 Anthropic 格式的工具调用支持比较稳。先说清楚目标产物长什么样免得跑完不知道算不算成功一份git diff显示 Agent 改了哪个文件、哪几行一段 pytest 输出从FAILED变成passed一段 OpenHands 的 LLM 配置能直接复制进config.toml。下面按「准备仓库 → 拿 Key → 配 OpenHands → 跑闭环 → 验证与排障」的顺序走。中途会踩的坑我也会标出来。2. 准备一个带回归失败的 Python 仓库为了让过程可复现我造了一个最小仓库结构如下regression-demo/ ├── calc/ │ ├── __init__.py │ └── stats.py ├── tests/ │ └── test_stats.py └── pyproject.tomlcalc/stats.py里有个求中位数的函数被一次「优化」改坏了# calc/stats.py def median(nums): if not nums: raise ValueError(empty) s sorted(nums) n len(s) # 回归点偶数长度时取了下标 n//2正确应为中间两数平均 return s[n // 2]测试文件里有一条针对偶数长度的断言# tests/test_stats.py import pytest from calc.stats import median def test_median_odd(): assert median([3, 1, 2]) 2 def test_median_even(): assert median([1, 2, 3, 4]) 2.5 def test_median_empty(): with pytest.raises(ValueError): median([])本地先跑一遍确认失败cd regression-demo python -m pytest -q预期输出类似.F. [100%] FAILED tests/test_stats.py::test_median_even - assert 3 2.5 1 failed, 2 passed in 0.12s这条test_median_even就是回归失败点。注意test_median_odd和test_median_empty是绿的Agent 不能为了修偶数把奇数逻辑改坏——这是后面验证的重点。提示仓库里最好有pyproject.toml或requirements.txtOpenHands 会据此装依赖。没有的话它可能反复试错浪费 token。3. 在官网拿 Key 并确认额度打开 TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate注册后在控制台创建 API Key。控制台入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerateKey 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate。拿到 Key 后先别急着塞进 OpenHands用 curl 验一下通不通export TAOTOKEN_API_KEYsk-你的key curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: reply with ok}] }返回里能看到content字段就说明 Key 和 Base URL 都对。如果返回 401多半是 Key 复制时带了空格返回 404检查路径是不是写成了/v1/messages之外的东西。TaoToken 的 API 根地址是https://taotoken.net/apiAnthropic 兼容端点在它下面拼/v1/messages。模型名以官网文档为准不同时间可选的模型会变。文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate选模型前扫一眼当前支持的列表。4. 把 TaoToken 接进 OpenHands 的 LLM 配置OpenHands 的 LLM 配置写在~/.openhands/config.toml旧版本可能是config.toml在项目根目录。核心是把 provider 指到 Anthropic 兼容模式base_url 指向 TaoToken。# ~/.openhands/config.toml [llm] model claude-sonnet-4-20250514 api_key sk-你的key base_url https://taotoken.net/api api_version 2023-06-01 # 控制单次任务成本避免 Agent 无限重试 max_input_tokens 60000 max_output_tokens 8192 temperature 0.2如果你用环境变量而不是写死在文件里更推荐避免 Key 进 gitexport LLM_MODELclaude-sonnet-4-20250514 export LLM_API_KEY$TAOTOKEN_API_KEY export LLM_BASE_URLhttps://taotoken.net/api export LLM_API_VERSION2023-06-01OpenHands 读取环境变量的优先级高于配置文件两者都设时以环境变量为准。启动命令docker run -it --rm \ -e LLM_MODEL \ -e LLM_API_KEY \ -e LLM_BASE_URL \ -e LLM_API_VERSION \ -v /var/run/docker.sock:/var/run/docker.sock \ -v ~/.openhands:/.openhands \ -v $(pwd)/regression-demo:/workspace/regression-demo \ -p 3000:3000 \ docker.all-hands.dev/all-hands-ai/openhands:latest挂载regression-demo到容器/workspace下Agent 就能直接操作这个仓库。启动后浏览器开http://localhost:3000在设置里确认 LLM 那一栏显示的是你填的 base_url不是默认的官方地址。注意temperature别设太高修 bug 这种任务 0.1–0.3 比较稳太高容易改出花活。5. 跑通「定位失败 → 改实现 → 测试通过」闭环在 OpenHands 对话框里给一个明确任务别只说「修一下测试」仓库在 /workspace/regression-demo。 先运行 python -m pytest -q 复现失败。 定位失败断言对应的实现问题只修改 calc/stats.py。 修改后重新运行完整测试确保三条测试全部通过。 最后输出 git diff 和 pytest 结果。Agent 的执行轨迹大致是跑python -m pytest -q读到test_median_even失败打开calc/stats.py看到return s[n // 2]判断偶数长度应取中间两数平均改成def median(nums): if not nums: raise ValueError(empty) s sorted(nums) n len(s) if n % 2 1: return s[n // 2] return (s[n // 2 - 1] s[n // 2]) / 2重跑测试三条全绿输出 diff。修复后的 diff 长这样diff --git a/calc/stats.py b/calc/stats.py index 3f1a2b0..9c4d5e1 100644 --- a/calc/stats.py b/calc/stats.py -1,7 1,10 def median(nums): if not nums: raise ValueError(empty) s sorted(nums) n len(s) - return s[n // 2] if n % 2 1: return s[n // 2] return (s[n // 2 - 1] s[n // 2]) / 2测试输出记录... [100%] 3 passed in 0.09s到这里闭环就成了。关键验证点有两个一是test_median_even从红变绿二是test_median_odd和test_median_empty没被改坏。如果 Agent 图省事把测试断言改了比如把2.5改成3那是作弊不是修复——你要在 diff 里盯住tests/目录有没有被动过。6. 失败分支与成本、模型选择跑不通的情况我遇到过几种对应处理方式Agent 反复重试同一命令。多半是依赖没装好容器里缺 pytest。让它先pip install -e .或pip install pytest或者在任务描述里直接写明「先安装依赖」。改了实现但测试还是红。检查是不是改了tests/里的断言来「凑绿」。在任务里加一句「禁止修改 tests 目录」能挡掉大部分偷懒行为。401 / 404。401 查 Key 有没有多余空格、额度是否耗尽404 查 base_url 是不是漏了/api或路径拼错。这两个错误和 OpenHands 本身无关先用第 3 节的 curl 单独验证。上下文超限。大仓库一次读太多文件会顶到max_input_tokens。把任务拆小一次只让它处理一个失败测试比一口气修十个稳。成本方面修这种单文件回归一次任务通常几万 input token 加几千 output token具体单价以官网为准。模型选择上Claude 系在工具调用和长上下文上比较适合 OpenHands 这类 Agent 场景如果只是简单断言修复用更便宜的模型也能过但复杂仓库建议留足上下文预算。TaoToken 的模型列表和计费在文档页能查到选之前对一下当前可用型号。最后留个实用习惯每次让 Agent 修完别只看它说「通过了」自己再跑一遍python -m pytest -q并git diff扫一眼改动范围。Agent 的输出是线索不是结论。 告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度