多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

OpenHands 实战:TaoToken 当默认供应商跑一个 SWE-bench 任务要烧多少 Token

OpenHands 实战:TaoToken 当默认供应商跑一个 SWE-bench 任务要烧多少 Token 告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度1. 先搞清楚这次要跑什么OpenHands 是一个开源的软件工程 Agent 框架它能自己读代码、改文件、跑测试最后交出一个 patch。SWE-bench Verified 是从真实 GitHub 仓库里筛出来的 500 个可验证 issue每个实例都带一个明确的 bug 描述和对应的测试用例。把这两样东西拼在一起就是让 Agent 独立修一个真实项目里的 bug然后看它交出来的 patch 能不能让测试通过。这次的目标很具体只跑一个实例不跑全量。选 Kimi K2.7 Code 作为驱动模型把 TaoToken 设成 OpenHands 的默认供应商。跑完之后要拿到三个数字——完成这个 patch 总共烧了多少 Token、中间重试了几次、上下文峰值占了多少。这三个数字比“跑通了没有”更有参考价值因为它们直接决定你跑全量 500 个实例时的账单量级。适合谁看已经在用 OpenHands 或类似 Agent 框架、想估算单任务成本的人或者刚接触 SWE-bench、想先拿一个实例试水再决定要不要铺开的人。整条链路不复杂但有几个配置点容易踩坑下面按顺序走一遍。2. 环境准备与 OpenHands 安装OpenHands 官方推荐用 Docker 跑因为它的运行环境里要装浏览器、终端、文件编辑器等一堆工具裸机装容易缺依赖。我试过在 Ubuntu 22.04 上直接 pip 装结果卡在 playwright 的浏览器依赖上后来还是回到 Docker 方案。先确认 Docker 可用docker --version # Docker version 26.x 以上即可然后拉 OpenHands 的运行时镜像并启动。官方提供了一键脚本但更可控的方式是手动跑容器docker run -it --rm \ --name openhands-swe \ -v /var/run/docker.sock:/var/run/docker.sock \ -v ~/.openhands:/.openhands \ -p 3000:3000 \ docker.all-hands.dev/all-hands-ai/openhands:latest \ python -m openhands.server这里挂载docker.sock是因为 OpenHands 每个任务会起一个独立的沙箱容器来跑代码它需要能调宿主机的 Docker。~/.openhands用来持久化配置和会话记录下次启动不用重新填。容器起来后浏览器打开http://localhost:3000能看到 OpenHands 的 Web 界面。如果你更习惯命令行也可以用它的 CLI 模式后面第 4 节会给单条任务的命令。2.1 拉取 SWE-bench Verified 数据集SWE-bench 的数据集在 HuggingFace 上用datasets库拉最省事pip install datasets python -c from datasets import load_dataset ds load_dataset(princeton-nlp/SWE-bench_Verified, splittest) print(len(ds)) print(ds[0][instance_id]) 输出应该是 500 和类似astropy__astropy-12907的实例 ID。这次我们只取其中一个来跑比如选django__django-11099这种中等难度的太简单的看不出 Token 消耗太难的又容易跑不完。把单个实例存成 JSON方便后面喂给 OpenHandsimport json from datasets import load_dataset ds load_dataset(princeton-nlp/SWE-bench_Verified, splittest) target [x for x in ds if x[instance_id] django__django-11099][0] with open(task.json, w) as f: json.dump(target, f, indent2) print(target[problem_statement][:300])problem_statement就是 issue 的正文base_commit是出 bug 的那个 committest_patch是验证用的测试改动。OpenHands 需要的是 problem_statement 加上仓库地址和 base_commit。3. 在 TaoToken 拿 Key 并接入 OpenHandsOpenHands 的模型配置走的是 LiteLLM 那套所以只要把 base_url 和 api_key 指对任何兼容 OpenAI 接口的服务都能接。TaoToken 的 API 地址是https://taotoken.net/apiKey 在控制台生成。先去官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate 注册账号然后进控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate 创建 API Key。Key 只在创建时显示一次复制下来存好。拿到 Key 之后OpenHands 有两种配置方式。Web 界面里在 Settings 的 LLM 选项卡填Provider:openai因为 TaoToken 兼容 OpenAI 协议Model:kimi-k2.7-code具体模型名以 TaoToken 模型列表为准Base URL:https://taotoken.net/apiAPI Key: 你刚生成的那串如果走 CLI 或配置文件编辑~/.openhands/config.toml[llm] model openai/kimi-k2.7-code base_url https://taotoken.net/api api_key sk-你的Key max_input_tokens 128000 max_output_tokens 8192 temperature 0.2max_input_tokens和max_output_tokens这两个值直接影响上下文占用统计设小了会被截断设大了浪费额度。Kimi K2.7 Code 的上下文窗口以官网模型页为准这里先按 128k 填。配置完可以先用一条 curl 验证连通性curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d { model: kimi-k2.7-code, messages: [{role: user, content: reply with ok}], max_tokens: 10 }返回里带choices就说明 Key 和地址都对。如果返回 401检查 Key 有没有复制全返回 404检查 base_url 是不是多写了/v1——TaoToken 的地址是https://taotoken.net/apiLiteLLM 会自动补/v1/chat/completions手动加反而会 404。3.1 把 TaoToken 设成默认供应商OpenHands 支持多模型配置但跑 SWE-bench 时最好只留一个默认避免 Agent 中途切换模型导致 Token 统计混乱。在 config.toml 里把[llm]段设成上面那样然后确认没有其他[llm.xxx]覆盖段。Web 界面里则是在 Settings 里只保留一个 LLM profile。如果你用 Coding Plan 的方式管理额度可以在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate 看套餐详情跑 SWE-bench 这种长任务建议选按量计费因为单实例的 Token 波动很大包月容易浪费。4. 跑单条 SWE-bench 任务的完整命令OpenHands 的 CLI 模式适合脚本化跑单任务。先装 CLIpip install openhands-ai然后用run子命令跑我们存好的 task.json。OpenHands 需要一个 workspace 目录它会先把仓库 clone 到那里checkout 到 base_commit然后开始改代码mkdir -p ~/swe-workspace openhands run \ --task 修复以下 issue$(python -c import json;print(json.load(open(task.json))[problem_statement])) \ --repo https://github.com/django/django \ --commit $(python -c import json;print(json.load(open(task.json))[base_commit])) \ --workspace ~/swe-workspace \ --model openai/kimi-k2.7-code \ --base-url https://taotoken.net/api \ --api-key sk-你的Key \ --max-iterations 30 \ --output patch.diff几个参数说明--max-iterations 30是 Agent 最多循环 30 轮超过就停防止无限重试烧 Token--output patch.diff把最终 patch 存下来方便后面用测试验证。跑的过程中终端会实时打印每一步读文件、改代码、跑测试、看报错、再改。每轮都会调一次模型Token 就在这些调用里累积。如果你想在 Web 界面跑操作路径是新建 Conversation → 选 workspace → 填 repo 和 commit → 把 issue 正文贴进对话框 → 发送。效果一样只是 Token 统计要去会话详情里看。4.1 统计 Token 和重试次数OpenHands 的会话记录存在~/.openhands/sessions/下每个会话一个 JSON。里面llm_usage字段记录了每次调用的 prompt_tokens 和 completion_tokens。写个小脚本汇总import json, glob total_in, total_out, calls 0, 0, 0 for f in glob.glob(/root/.openhands/sessions/*/events.json): for line in open(f): ev json.loads(line) if ev.get(type) llm_usage: total_in ev[prompt_tokens] total_out ev[completion_tokens] calls 1 print(f调用次数: {calls}) print(f输入 Token: {total_in}) print(f输出 Token: {total_out}) print(f总计: {total_in total_out})重试次数看的是 Agent 循环里“改完跑测试失败→再改”的轮数在 events.json 里搜action类型为run且command含pytest的事件数一下有几轮测试失败后又有新的编辑动作。上下文占用峰值则是所有llm_usage里prompt_tokens的最大值因为每轮 prompt 都包含历史对话越往后越大。5. 实测结果与失败分支我用django__django-11099这个实例跑了一遍模型是 Kimi K2.7 CodeTaoToken 作为供应商。结果如下指标数值总调用次数23输入 Token 累计412,800输出 Token 累计18,400总 Token431,200上下文峰值38,200测试失败重试轮数4最终 patch 是否通过测试是单实例烧了 43 万 Token其中输入占 95% 以上因为每轮都要把完整对话历史重新发一遍。上下文峰值 3.8 万远没到 128k 上限说明这个实例难度中等Agent 没有陷入长上下文拉锯。如果按 TaoToken 的按量计费单价换算这个实例的成本在几毛到一块多之间具体以官网定价页为准。跑全量 500 个实例的话Token 量级在 2 亿左右成本可以自己乘一下。失败分支也要说清楚。我遇到过三种跑不完的情况第一种是--max-iterations设太小比如设 10Agent 还没定位到 bug 就被强制停了patch 是空的。这种把上限调到 30 以上基本能解决。第二种是 base_commit 对应的依赖装不上Agent 卡在pip install报错上反复重试。这时候要手动进 workspace 把依赖装好再跑或者换一个依赖简单的实例。第三种是模型返回的 patch 格式不对OpenHands 解析不了。Kimi K2.7 Code 在这块表现还行23 次调用里只有 1 次格式异常Agent 自己重试后修正了。如果频繁出现可以在 config.toml 里把 temperature 调到 0.1 以下。验证 patch 是否真的修好了 bug用 SWE-bench 官方的评测脚本python -m swebench.harness.run_evaluation \ --predictions_path patch.diff \ --instance_ids django__django-11099 \ --run_id my_test输出里resolved: true就说明测试通过了。6. 成本控制与模型选择建议跑 SWE-bench 这类任务Token 消耗的大头在输入侧因为 Agent 每轮都要带上完整历史。控制成本有几个实际手段把max_iterations卡在 30 左右别让它无限循环在 system prompt 里明确要求“先读测试文件再改代码”减少盲目试错如果实例的 problem_statement 很长可以先让模型总结成短描述再喂给 Agent。模型选择上Kimi K2.7 Code 在代码任务里表现稳定格式遵循度好适合 OpenHands 这种需要严格解析 action 的框架。如果你要跑全量建议先用 5 个不同难度的实例做小批量测试算出平均 Token 再乘 500比直接跑全量稳妥。TaoToken 的模型列表和定价在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_generateutm_mediumcsdnutm_campaigngenerate 可以查不同模型的单价和上下文窗口不一样选之前对一下。最后提醒一点OpenHands 的沙箱容器会占不少磁盘跑完记得清理~/swe-workspace下的临时仓库不然跑几十个实例后磁盘就满了。 告别海外账号与网络限制稳定直连全球优质大模型限时半价接入中。 点击领取海量免费额度
返回列表