Z Potentials|王星尧与OpenHands:99年博士如何用开源AI编程解决SWE-bench过半问题

📅 发布时间:2026/9/29 6:17:16
Z Potentials|王星尧与OpenHands:99年博士如何用开源AI编程解决SWE-bench过半问题
1. 从 SWE-bench 过半说起OpenHands 到底解决了什么如果你最近在关注 AI 编程大概率刷到过 OpenHands 这个名字。它是一个开源的 AI 软件工程师能像人类开发者一样使用命令行、代码编辑器和浏览器自主完成从读 issue 到提 PR 的完整流程。在 SWE-bench Verified 这个业界公认的评测基准上它是首个突破 50% 成功率的开源系统意味着它能独立解决一半以上来自真实 GitHub 仓库的编程问题。这个数字背后是 99 年出生的博士王星尧和他的团队 All Hands AI 在开源协作、评估基础设施和智能体架构上的持续投入公司种子轮就拿到了 Menlo Ventures 与 Anthropic 共同设立的 Anthology Fund 领投的 500 万美元。这篇文章不聊八卦只做一件事让你在自己的机器上把 OpenHands 跑起来用一份可复制的 config.toml 骨架完成本地部署再通过 TaoToken 统一 Key 接入模型最后用一段 SWE-bench 验证脚本确认你的环境真的能复现榜单级的编程问题解决流程。适合谁适合想研究 AI Agent 架构的后端工程师、想给团队搭一套自主编程助手的 Tech Lead以及正在做智能体方向研究、需要一个稳定开源基座的学生和研究者。我试过从零配一套 OpenHands 环境踩过的坑主要集中在模型接入和容器权限这两块下面会把每一步都拆开讲清楚。2. TaoToken 前置为什么 Agent 场景需要一个统一 KeyOpenHands 这类 Agent 和普通聊天机器人的最大区别在于调用频率和上下文长度。一个 SWE-bench 实例从读 issue、定位文件、改代码到跑测试中间可能产生几十次模型调用每次都要带上仓库结构、报错日志和之前的操作历史。如果你用多个厂商的 Key 分别管理很快就会遇到三个问题额度分散不好监控、不同模型的接口格式要写适配层、以及某个 Key 突然限流导致整个 Agent 卡死。TaoToken 在这里的角色是一个统一的模型接入层。你只需要在官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后拿到一个 API Key就能通过 https://taotoken.net/api 这个兼容 OpenAI 格式的端点调用多种模型。对 OpenHands 来说这意味着你只需要在 config.toml 里填一次 base_url 和 api_key切换模型时改一个 model 字段就行不用动任何代码。注意TaoToken 的 API 端点不要加 UTM 参数直接写 https://taotoken.net/api 即可UTM 只用于官网链接的渠道追踪。具体操作上你需要先登录控制台创建 Key。打开 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面点击新建复制生成的 sk- 开头的字符串。这个 Key 就是后面 config.toml 里要填的值。如果你打算长期跑 Agent 任务建议在控制台里设置一个每日额度上限避免某个死循环的 Agent 把额度跑光。3. 可复制配置OpenHands 的 config.toml 骨架与 Docker 启动OpenHands 官方推荐用 Docker 运行因为它的 Agent 会在沙箱里执行任意代码直接跑在宿主机上有风险。下面这份 config.toml 是我实测能跑通的骨架放在 ~/.openhands/config.toml 路径下。[core] workspace_base ./workspace cache_dir ./cache max_iterations 50 runtime docker [llm] model claude-3-5-sonnet-20241022 api_key sk-你的TaoToken密钥 base_url https://taotoken.net/api temperature 0.2 max_input_tokens 200000 max_output_tokens 8192 [agent] name CodeActAgent memory_enabled true memory_max_threads 4 [sandbox] timeout 300 use_host_network false几个关键参数解释一下。max_iterations 控制 Agent 最多执行多少轮操作跑 SWE-bench 时建议设到 50 以上因为复杂 issue 需要多轮调试。temperature 设 0.2 是为了让代码生成更稳定Agent 场景不需要创意。base_url 填 TaoToken 的 API 地址这样 OpenHands 就会把所有模型请求发到统一端点。启动命令如下注意把工作目录挂载进去否则 Agent 改的代码在容器销毁后就没了docker run -it --rm \ --pullalways \ -e SANDBOX_RUNTIME_CONTAINER_IMAGEdocker.all-hands.dev/all-hands-ai/runtime:0.20-nikolaik \ -v /var/run/docker.sock:/var/run/docker.sock \ -v ~/.openhands:/.openhands \ -v $(pwd)/workspace:/workspace \ -p 3000:3000 \ --add-host host.docker.internal:host-gateway \ docker.all-hands.dev/all-hands-ai/openhands:0.20启动后浏览器打开 http://localhost:3000在设置页面确认 LLM 配置已经读取到 config.toml 里的值。如果页面显示模型为 claude-3-5-sonnet-20241022 且 base_url 指向 TaoToken说明接入成功。4. 验证请求SWE-bench 脚本与成功结果判读环境跑起来后下一步是验证它真的能解决编程问题。SWE-bench 官方提供了评测脚本但完整跑 500 个实例太耗时我们可以先跑一个最小验证集。下面这段 Python 脚本会从 SWE-bench 数据集中取一个实例调用 OpenHands 的 API 让它尝试修复然后检查测试是否通过。import requests import json from datasets import load_dataset # 加载 SWE-bench Verified 数据集 dataset load_dataset(princeton-nlp/SWE-bench_Verified, splittest) instance dataset[0] print(f实例 ID: {instance[instance_id]}) print(f仓库: {instance[repo]}) print(f问题描述: {instance[problem_statement][:200]}...) # 调用 OpenHands API 提交任务 openhands_url http://localhost:3000/api/agent/start payload { task: instance[problem_statement], repo: instance[repo], base_commit: instance[base_commit], test_patch: instance[test_patch] } response requests.post(openhands_url, jsonpayload) result response.json() print(f任务状态: {result.get(status)}) print(f会话 ID: {result.get(session_id)})跑通后你会看到类似这样的输出实例 ID: django__django-11099 仓库: django/django 问题描述: The username validator allows trailing newline characters... 任务状态: running 会话 ID: abc123-def456判断成功的关键不是看 Agent 说我修好了而是看它生成的 patch 能否让测试用例从 fail 变成 pass。OpenHands 在容器里会自动跑测试你可以在 Web 界面的日志里看到 pytest 的输出。如果看到PASSED且没有FAILED说明这个实例被成功解决。按官方数据在 SWE-bench Verified 上 OpenHands 能解决超过一半的实例你本地跑的结果会受模型能力和网络延迟影响但只要能稳定跑通几个实例就说明整条链路是通的。5. 本篇常见错排查第一个高频错误是 Docker 权限问题。启动容器时报permission denied while trying to connect to the Docker daemon socket说明当前用户不在 docker 组里。执行sudo usermod -aG docker $USER然后重新登录即可。如果你在 macOS 上用 Docker Desktop确保在设置里勾选了Allow the default Docker socket to be used。第二个是模型返回 401。检查 config.toml 里的 api_key 是否以 sk- 开头且没有多余空格base_url 是否写成了 https://taotoken.net/api 而不是带 /v1 的路径。TaoToken 的端点已经兼容 OpenAI 格式OpenHands 会自动拼接 /chat/completions手动加 /v1 反而会 404。第三个是 Agent 卡在等待沙箱启动。这通常是 runtime 镜像拉取太慢导致的可以提前手动拉取docker pull docker.all-hands.dev/all-hands-ai/runtime:0.20-nikolaik。如果公司网络有限制检查是否允许访问 docker.all-hands.dev 这个域名。第四个是 SWE-bench 脚本报datasets库版本冲突。建议用 Python 3.10 以上的虚拟环境执行pip install datasets2.18.0 requests固定版本。如果加载数据集时卡住是 HuggingFace 的下载问题可以设置镜像export HF_ENDPOINThttps://hf-mirror.com加速。第五个是 Agent 改完代码后测试仍然失败。这不一定是环境问题可能是模型能力边界。SWE-bench 的实例难度差异很大有些需要跨文件重构当前模型确实搞不定。建议先挑django__django或sympy__sympy这类测试用例明确的仓库练手成功率会高一些。6. 把 Key 用起来从验证到长期编码如果你只是想做一次模型能力验证上面的流程已经够了。但如果你打算把 OpenHands 当成日常开发工具或者跑更长时间的 Agent 任务建议去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 管理你的 Key 额度同时把接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里的参数说明过一遍特别是超时和重试相关的配置Agent 场景下这两个参数直接影响任务成功率。想先感受一下模型对话效果再决定用哪个模型跑 Agent 的话可以直接打开 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 对比不同模型在代码任务上的表现。如果你已经确定要长期用 OpenHands 做编码和 Agent 开发Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 里有针对高频调用的额度方案比按次计费更适合跑 SWE-bench 这种批量任务。最后说一个实际经验OpenHands 的 Agent 质量很依赖模型的长上下文能力跑复杂 issue 时尽量选支持 200k token 以上的模型否则 Agent 读到一半就忘了前面的文件结构。把 config.toml 里的 max_input_tokens 设对比换更贵的模型往往更有效。