OpenHands 实战:TaoToken Key 跑通 SWE-bench Verified 并输出 Token 明细
告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度1. 先把目标定清楚让 OpenHands 跑 10 个 issue 并吐出 Token 明细OpenHands 是一个开源的软件工程 Agent 框架能自己读仓库、改代码、跑测试适合拿来做 SWE-bench 这类真实 issue 修复任务。SWE-bench Verified 是从 SWE-bench 里筛出来的一批人工确认过、描述清晰、可复现的 issue 集合常被用来衡量 Agent 在真实仓库上的修复能力。这篇要干的事很具体用 TaoToken 提供的 Key 作为模型供应商让 OpenHands 在复现脚本里跑 10 个指定 issue最后输出每个实例的 Token 明细表并给出可重跑的命令。适合谁看已经装过 OpenHands、想接第三方模型供应商、又需要按实例统计 Token 消耗的人。如果你只是想让 Agent 随便改个 demo 仓库这篇的配置会显得偏重但只要你关心「每个 issue 花了多少 Token、能不能复现」下面的步骤就是照着抄。需要提前说明一点本文不含任何排行分数也不对 SWE-bench Verified 的榜单做评测。我们只关心流程能不能跑通、Token 明细能不能按实例拆出来。模型价格、上下文长度、并发限制这些以 TaoToken 官网当时页面为准我不在这里写死数字。整体链路是OpenHands 负责调度 Agent 循环TaoToken 提供兼容 OpenAI 接口的模型服务Base URL 填https://taotoken.net/api注意不要加/v1Key 在官网创建。跑完后从 OpenHands 的运行日志里抽出每个实例的 prompt/completion Token汇总成表。2. 环境准备与 OpenHands 安装2.1 基础依赖我试过在 Ubuntu 22.04 和 macOS 上跑Python 3.11 比较稳。先建一个独立虚拟环境避免和系统包打架python3.11 -m venv openhands-env source openhands-env/bin/activate pip install --upgrade pipOpenHands 官方推荐用 Docker 跑运行时因为 Agent 执行代码需要隔离环境。确认 Docker 可用docker --version docker ps如果docker ps报权限错误把当前用户加进 docker 组再重新登录。这一步不做的话后面 Agent 执行 shell 命令会失败。2.2 安装 OpenHandspip install openhands-ai装完后验证命令是否存在openhands --help能打印出子命令列表就说明装好了。版本号建议记一下不同版本配置字段名可能略有差异pip show openhands-ai | grep Version2.3 拉取 SWE-bench Verified 的实例清单SWE-bench 官方仓库里有数据集加载脚本。我们不需要全量只要挑 10 个指定 issue。先装数据集依赖pip install datasets然后用一段脚本把 Verified 里的实例 ID 打出来方便你挑from datasets import load_dataset ds load_dataset(princeton-nlp/SWE-bench_Verified, splittest) for i, row in enumerate(ds): if i 20: break print(row[instance_id], |, row[repo], |, row[base_commit][:8])instance_id形如django__django-11099这就是后面要传给 OpenHands 的标识。挑 10 个你熟悉的仓库记到一个文本文件里一行一个django__django-11099 sympy__sympy-20590 ...2.4 准备复现脚本骨架我们要的是「跑 10 个 issue 输出 Token 明细」所以脚本要循环调用 OpenHands并把每次运行的日志单独存。先建目录mkdir -p swe_runs/logs mkdir -p swe_runs/reports实例清单存成swe_runs/instances.txt。后面所有命令都基于这个目录结构。3. TaoToken 接入与 OpenHands 配置3.1 创建 Key 并确认 Base URL到 TaoToken 官网创建 API Keyhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 。创建后复制那串 Key只显示一次丢了就重新建。关键配置点OpenHands 里模型供应商的 Base URL 填https://taotoken.net/api不要加/v1。很多兼容 OpenAI 的服务会把版本段写进路径但这里按官方给的写法来加了/v1反而会 404。API 根地址是 https://taotoken.net/api 。3.2 用环境变量注入配置OpenHands 支持通过环境变量指定 LLM。最省事的方式是写一个.env文件放在swe_runs/下export LLM_API_KEY你的TaoToken Key export LLM_BASE_URLhttps://taotoken.net/api export LLM_MODEL你选用的模型名然后source swe_runs/.env。模型名以 TaoToken 官网模型列表为准不同模型在 Agent 循环里的表现和成本差别很大建议先用一个中等价位的跑通流程再换更强的模型做正式复现。3.3 写 OpenHands 的配置文件OpenHands 读取config.toml。在swe_runs/下建一个[core] workspace_base ./workspace max_iterations 30 [llm] model 你选用的模型名 api_key env:LLM_API_KEY base_url https://taotoken.net/apimax_iterations控制 Agent 最多循环多少轮太小会中途放弃太大会烧 Token。跑 SWE-bench 这类任务20 到 40 之间比较常见先设 30 观察。3.4 验证连通性在正式跑 10 个之前先做一次最小连通测试确认 Key 和 Base URL 没问题curl -s https://taotoken.net/api/models \ -H Authorization: Bearer $LLM_API_KEY | head -c 500能返回模型列表 JSON 就说明鉴权通过。如果返回 401检查 Key 是否复制完整返回 404检查 Base URL 是不是多写了/v1。这一步排掉后面省很多事。4. 跑通 10 个 issue 并输出 Token 明细4.1 循环调用脚本下面这段脚本按实例清单逐个跑每个实例的日志单独落盘。OpenHands 的 CLI 参数在不同版本略有差异核心是传入实例对应的仓库和 commit。实际使用时按你本地openhands --help的输出对齐参数名#!/usr/bin/env bash set -euo pipefail source swe_runs/.env export OPENHANDS_CONFIGswe_runs/config.toml while read -r instance_id; do [ -z $instance_id ] continue echo Running $instance_id openhands run \ --task $instance_id \ --config $OPENHANDS_CONFIG \ swe_runs/logs/${instance_id}.log 21 || { echo FAILED: $instance_id | tee -a swe_runs/logs/failures.txt } done swe_runs/instances.txt把这段存成swe_runs/run_all.sh加执行权限chmod x swe_runs/run_all.sh ./swe_runs/run_all.sh4.2 从日志里抽 Token 明细OpenHands 每次 LLM 调用会在日志里记录 usage 字段包含 prompt_tokens 和 completion_tokens。写一个解析脚本把每个实例的 Token 累加import json import re from pathlib import Path log_dir Path(swe_runs/logs) rows [] for log_file in sorted(log_dir.glob(*.log)): instance_id log_file.stem prompt_total 0 completion_total 0 calls 0 for line in log_file.read_text(errorsignore).splitlines(): match re.search(r\{.*usage.*\}, line) if not match: continue try: payload json.loads(match.group(0)) except json.JSONDecodeError: continue usage payload.get(usage, {}) prompt_total usage.get(prompt_tokens, 0) completion_total usage.get(completion_tokens, 0) calls 1 rows.append({ instance_id: instance_id, llm_calls: calls, prompt_tokens: prompt_total, completion_tokens: completion_total, total_tokens: prompt_total completion_total, }) with open(swe_runs/reports/token_detail.json, w) as f: json.dump(rows, f, indent2, ensure_asciiFalse) print(f{instance_id:40}{calls:8}{prompt:12}{completion:12}{total:12}) for r in rows: print(f{r[instance_id]:40}{r[llm_calls]:8}{r[prompt_tokens]:12} f{r[completion_tokens]:12}{r[total_tokens]:12})存成swe_runs/parse_tokens.py后运行python swe_runs/parse_tokens.py4.3 生成 Markdown 明细表把 JSON 转成表格方便贴进报告import json rows json.load(open(swe_runs/reports/token_detail.json)) lines [ | instance_id | llm_calls | prompt_tokens | completion_tokens | total_tokens |, | --- | ---: | ---: | ---: | ---: |, ] for r in rows: lines.append( f| {r[instance_id]} | {r[llm_calls]} | {r[prompt_tokens]} f| {r[completion_tokens]} | {r[total_tokens]} | ) open(swe_runs/reports/token_detail.md, w).write(\n.join(lines)) print(\n.join(lines))跑完你会得到一张按实例拆分的表每个 issue 花了多少次 LLM 调用、多少 prompt/completion Token 一目了然。4.4 重跑命令单个实例重跑直接source swe_runs/.env openhands run --task django__django-11099 --config swe_runs/config.toml \ swe_runs/logs/django__django-11099.log 21 python swe_runs/parse_tokens.py全部重跑就是再执行一次./swe_runs/run_all.sh日志会覆盖Token 表重新生成。想保留历史把logs/和reports/按时间戳改名再跑。5. 可验证结果、失败分支与成本控制5.1 怎么判断跑通了三个可验证信号swe_runs/logs/下每个实例都有非空日志token_detail.json里 10 条记录的llm_calls都大于 0token_detail.md表格里 total_tokens 列没有全零行。满足这三条说明 OpenHands 确实通过 TaoToken 调用了模型并且 Token 被正确统计。5.2 常见失败分支401 鉴权失败Key 没 source 进环境或者复制时带了空格。重新source swe_runs/.env并echo $LLM_API_KEY确认。404 路径错误Base URL 写成了https://taotoken.net/api/v1。改回https://taotoken.net/api。Agent 中途卡死max_iterations太小或者模型在某个工具调用上反复失败。把日志里最后一次工具调用找出来看是不是命令超时。适当调大迭代数或换一个工具调用更稳的模型。Token 统计为零日志格式和正则不匹配。先grep usage swe_runs/logs/某个实例.log看实际长什么样再调整正则。5.3 成本与模型选择Token 消耗主要取决于三件事issue 复杂度、Agent 迭代上限、模型本身的输出长度。SWE-bench 的 issue 往往要读多个文件、跑测试、反复修改prompt Token 会随上下文累积快速上涨。想控成本可以先把max_iterations压到 15 跑一遍看基线再逐步放开。模型选择上TaoToken 官网会列出可用模型和对应计费方式具体价格、上下文窗口、速率限制以官网当时页面为准。我的建议是流程验证阶段用便宜模型确认链路通正式复现再用能力更强的模型这样不会在调试配置时就把预算烧掉。需要长期批量跑的话可以看看 Coding Plan 这类方案是否更适合你的用量。配置和 Key 管理入口都在官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end API 根地址固定是 https://taotoken.net/api 。把这两个记牢Base URL 不加/v1剩下的就是按实例循环、按日志抽 Token、按表核对跑几次就顺了。 告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度