
1. 长任务 Agent 为什么总在“跑一半”时崩掉如果你正在做需要跑几十分钟甚至更久的 Agent大概率遇到过这种场景任务跑到第 40 分钟容器卡死网络抖了一下模型上下文爆了用户暂停后回来发现状态全丢。你打开日志发现所有东西都塞在一个进程里——模型循环、工具调用、文件系统、代码执行、会话状态全在一个容器里纠缠。这个容器一旦出问题整个任务就废了。Anthropic 在 Managed Agents 的设计里把这个问题讲得很透长任务 Agent 不应该被设计成一个不能失败、不能迁移、不能调试的“宠物容器”而应该拆成 brain、hands、session 三类稳定接口。brain 是 Claude 与 harness负责推理和决策hands 是沙箱、工具和外部执行环境负责真正干活session 是可持久化的事件日志负责记住发生过什么。这三层解耦之后模型、工具、沙箱和状态日志可以独立演进失败从灾难变成普通事件。这篇文章面向需要跑长任务 Agent 的开发者我会先讲清楚 brain/hands/session 三层解耦到底解决了什么问题然后给出可复制的 TaoToken 统一 Key/API 配置片段Base URL 指向https://taotoken.net/api最后演示一次长任务会话的验证动作发起请求、观察 session 状态与 hands 执行结果确认解耦后各层可独立替换与恢复。如果你正在用 Claude Code、Cline、Codex 这类工具跑长任务或者自己在搭 Agent 运行时这篇可以直接跟着操作。核心检索词先明确Anthropic Managed Agents 是一套把长任务 Agent 拆成 brain、hands、session 三层接口的运行时架构它能做什么让 Agent 失败后可恢复、执行环境可替换、凭据不落沙箱、启动延迟大幅降低。适合谁需要跑长任务、多人协作、企业权限环境的 Agent 开发者。2. 单容器架构的坑与 TaoToken 统一 Key 前置2.1 单容器为什么在长任务里必然出问题很多团队做 Agent 时最初会把所有东西放进同一个运行环境。这样做开发很快因为文件修改是本地 syscall工具接口也不用跨服务设计。但一旦 Agent 开始处理长任务这种架构就会暴露三个硬伤。第一状态和容器绑定。容器一旦失败session 可能丢失容器卡住工程师不得不进容器调试容器里如果还存着用户数据和凭据调试本身又会变成安全问题。第二上下文窗口被当成状态存储。很多人把上下文问题理解为“模型上下文窗口不够长”于是用压缩、摘要、裁剪、memory 文件等策略。这些方法有用但都有不可逆风险——你今天丢掉的一段日志可能正是明天排查失败需要的关键证据。第三启动延迟被环境初始化拖死。在旧设计里每个 brain 都绑定一个容器即使任务一开始并不需要执行代码也要先 provision 容器、克隆仓库、启动进程、取事件用户会感觉启动很慢。Anthropic 的解法是让 harness 离开容器。容器不再承载整个 Agent而只是一个可以被调用的执行工具。brain 通过类似execute(name, input) - string的接口调用 hand。如果 hand 死了brain 收到的是工具错误可以重新 provision 一个。session 则做成 Claude 上下文窗口之外的持久事件日志harness 每次执行都写入事件失败后新 harness 可以通过wake(sessionId)恢复用getSession或getEvents获取历史再从最后事件继续。2.2 TaoToken 统一 Key 通道解决什么在落地这套架构时一个很现实的问题是brain 层要调用模型hands 层可能也要调用模型或工具session 层要做事件记录和恢复。如果每个环节都各自管一套 Key、各自配 Base URL长任务跑到一半换环境时Key 和端点的不一致会直接导致 401 或连接失败。TaoToken 在这里的作用是提供统一 Key 通道。你只需要一个 API KeyBase URL 统一指向https://taotoken.net/apibrain、hands、session 三层都可以复用同一套凭据配置。官网入口是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endAPI 端点不加 UTM 参数直接写https://taotoken.net/api。这样做的好处是当 hands 层需要独立替换执行环境时不需要重新分发 Key当 session 层恢复后新建 harness 时模型调用配置可以直接从环境变量读取不用改代码。对于长任务 Agent 来说配置的稳定性本身就是可恢复性的一部分。2.3 三层解耦后的性能与安全收益Anthropic 文章里提到一个很实际的性能收益TTFT也就是从接受任务到产生第一个响应 token 的时间。brain 和 hands 解耦后推理可以先开始只有当任务真正需要文件系统、shell 或其它执行环境时brain 才通过工具调用去 provision hand。文章称这让 p50 TTFT 下降约 60%p95 下降超过 90%。安全上旧架构里 Claude 生成的代码可能和凭据在同一个容器中运行如果 prompt injection 诱导 Claude 读取环境变量token 就可能泄露。Managed Agents 的结构性修复是生成代码运行的 sandbox 不应能接触凭据。一种模式是把授权和资源绑定比如 Git token 只在初始化 repo 时用于配置 remote另一种是把 OAuth token 放在 sandbox 外部的 vault通过 MCP proxy 代为调用外部服务。3. 可复制的 TaoToken 配置片段与三层接口落地这一节给出可以直接复制到项目里的配置。核心原则是Base URL 统一指向https://taotoken.net/apiKey 从环境变量读取brain、hands、session 三层共享同一套模型接入配置。3.1 环境变量与 settings 配置先设置环境变量这是所有层共享的基础export TAOTOKEN_API_KEYsk-你的TaoToken密钥 export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用的是 Claude Code可以在项目根目录的.claude/settings.json里写入{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }注意这里的三件套必须写全Base URL 是https://taotoken.net/apiKey 是你的 TaoToken 密钥Model ID 按你实际使用的模型填写。Cline 的 MCP 配置也是同样的三件套逻辑在 MCP Server 配置里把 Base URL 和 Key 指向 TaoToken。3.2 brain 层配置模型循环与 harnessbrain 层负责推理和决策它的配置重点是模型端点和超时。下面是一个 Python 示例用 OpenAI 兼容接口调用import os from openai import OpenAI client OpenAI( base_urlos.environ[TAOTOKEN_BASE_URL], api_keyos.environ[TAOTOKEN_API_KEY], ) def brain_step(session_id: str, user_input: str) - str: resp client.chat.completions.create( modelclaude-sonnet-4-20250514, messages[ {role: system, content: 你是长任务 Agent 的 brain负责决策下一步调用哪个 hand。}, {role: user, content: user_input}, ], timeout120, ) return resp.choices[0].message.content这里的关键是base_url和api_key都从环境变量读取这样当 hands 层换环境、session 层恢复时brain 层不需要改任何代码。3.3 hands 层配置沙箱与工具执行接口hands 层是可替换的执行环境。它的接口设计应该像execute(name, input) - string失败时返回工具错误而不是让整个进程崩溃import subprocess def execute(name: str, input_data: str) - str: try: if name shell: result subprocess.run( input_data, shellTrue, capture_outputTrue, textTrue, timeout300 ) return result.stdout or result.stderr elif name read_file: with open(input_data, r) as f: return f.read() else: return funknown hand: {name} except subprocess.TimeoutExpired: return ERROR: hand timeout, can be reprovisioned except Exception as e: return fERROR: {type(e).__name__}: {e}注意 hands 层不持有长期凭据。如果某个工具需要调用外部服务应该通过 MCP proxy 或 vault 代理而不是把 token 塞进环境变量。3.4 session 层配置事件日志与恢复session 层是 append-only 的事件日志。每次 brain 决策、hands 执行、错误发生都写入事件import json import time import uuid class SessionLog: def __init__(self, path: str): self.path path def append(self, session_id: str, event_type: str, payload: dict): event { event_id: str(uuid.uuid4()), session_id: session_id, type: event_type, payload: payload, ts: time.time(), } with open(self.path, a) as f: f.write(json.dumps(event, ensure_asciiFalse) \n) def get_events(self, session_id: str): events [] with open(self.path, r) as f: for line in f: e json.loads(line) if e[session_id] session_id: events.append(e) return events恢复时新 harness 调用get_events(session_id)拿到历史从最后一条事件继续而不是把所有历史塞进 prompt。4. 验证一次长任务会话请求、session 状态与 hands 结果配置写完之后必须验证三层是否真的解耦。下面是一次完整的验证动作。4.1 发起请求并观察 brain 决策先构造一个需要多步执行的长任务比如“读取项目里的 README.md统计行数然后写入 result.txt”。调用 brain 层session_id sess- str(uuid.uuid4()) log SessionLog(session_events.jsonl) log.append(session_id, user_input, {text: 读取 README.md 统计行数并写入 result.txt}) decision brain_step(session_id, 读取 README.md 统计行数并写入 result.txt) log.append(session_id, brain_decision, {output: decision}) print(brain 决策:, decision)预期结果是 brain 返回一个工具调用意图比如execute(read_file, README.md)。这一步只发生模型推理不涉及容器 provision所以 TTFT 应该很快。4.2 执行 hands 并记录结果拿到 brain 的决策后调用 hands 层执行hand_result execute(read_file, README.md) log.append(session_id, hand_result, {name: read_file, output: hand_result}) print(hands 结果长度:, len(hand_result))如果 hands 层超时或失败返回的是ERROR: ...字符串brain 收到后可以决定重试或换环境。这就是“失败从灾难变成普通事件”的具体体现。4.3 模拟 hands 崩溃后恢复这是验证解耦最关键的一步。假设 hands 容器在任务中途挂了我们直接丢弃当前 hands重新创建一个然后从 session 恢复events log.get_events(session_id) last_event events[-1] print(最后事件类型:, last_event[type]) if last_event[type] hand_result: next_input f上一步 hands 返回: {last_event[payload][output][:200]}请继续下一步 next_decision brain_step(session_id, next_input) log.append(session_id, brain_decision, {output: next_decision}) print(恢复后 brain 决策:, next_decision)实测下来只要 session 日志完整新的 harness 可以无缝接上不需要重新跑前面的步骤。这就是 session 不等于上下文窗口的价值完整历史在事件日志里当前 prompt 只放这一步需要的内容。4.4 确认三层可独立替换验证完成后你可以做三个独立替换测试把 brain 的 Model ID 换掉hands 层不用改把 hands 从本地 shell 换成远程 MCP 工具brain 和 session 不用改把 session 从本地 JSONL 换成数据库brain 和 hands 不用改。三个测试都通过说明三层接口真正解耦了。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth长任务 Agent 跑起来之后最常见的报错集中在接入层。下面按真实报错逐个排查。5.1 401 Unauthorized报错原文通常是Error code: 401 - {error: {message: Invalid API key}}。原因有三个Key 没设置、Key 写错、Base URL 和 Key 不匹配。排查步骤先确认echo $TAOTOKEN_API_KEY有值再确认echo $TAOTOKEN_BASE_URL输出https://taotoken.net/api最后检查 settings.json 里的ANTHROPIC_API_KEY是否和实际 Key 一致。注意 Base URL 不要多加/v1或结尾斜杠直接写https://taotoken.net/api。5.2 local proxy failed报错原文类似local proxy failed: connection refused或proxy error: cannot connect to upstream。这类报错通常出现在工具配置了本地代理但代理没启动或者 Base URL 被错误地指向了本地地址。排查检查环境变量里有没有残留的HTTP_PROXY、HTTPS_PROXY如果有就 unset确认ANTHROPIC_BASE_URL是https://taotoken.net/api而不是http://localhost:xxxx。5.3 reading choices 报错报错原文类似Error reading choices: list index out of range或reading choices。这通常说明返回体不是标准的 OpenAI 兼容格式可能是 Base URL 指错了端点或者 Model ID 写错导致返回了错误页。排查先用 curl 直接测端点curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:claude-sonnet-4-20250514,messages:[{role:user,content:hi}]}如果返回里有choices字段说明端点正常问题在代码里的解析逻辑如果没有检查 Model ID 是否拼写正确。5.4 OAuth 相关报错报错原文类似OAuth token expired或invalid_grant。如果你用的是 Claude Code 或 Codex 的 OAuth 流程注意 OAuth token 和 API Key 是两套东西。长任务 Agent 建议用 API Key 而不是 OAuth token因为 OAuth token 会过期恢复 session 时可能正好过期。Codex 的auth.json里如果同时有 OAuth 和 API Key 配置优先走 API Key。三件套再确认一遍Base URLhttps://taotoken.net/api、Key 从环境变量读、Model ID 写全。5.5 session 恢复后重复执行如果恢复后发现 hands 重复执行了同一步检查 session 日志的 append 时机。正确做法是先 append 事件再执行还是先执行再 append取决于你的幂等设计。建议在事件里加event_id恢复时按event_id去重。6. 长任务 Agent 的接入入口与下一步把 brain、hands、session 三层拆开之后你会发现 Agent 平台的建设重点不再是“堆更多工具”而是设计稳定接口和持久状态。brain 可以随模型能力提升替换 harnesshands 可以连接容器、MCP 工具、远程环境甚至不同执行设备session 作为 durable event log 支撑恢复、审计和回放。如果你要开始接入按场景选入口排障和接入配置问题直接看 API Keys 和接入文档先把 Base URLhttps://taotoken.net/api和 Key 跑通想先验证模型返回是否符合预期用模型对话快速测一轮如果是长期编码或 Agent 场景需要稳定跑长任务走 Coding Plan 更合适。具体入口模型对话验证https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewriteCoding Plan 长期编码https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite控制台https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteClaude Code Anthropic 接入https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite最后给一个实操建议先把 session 日志跑通再优化 brain 和 hands。因为长任务 Agent 最怕的不是模型不够聪明而是跑到一半状态丢了。session 是那个让你敢让 Agent 跑长任务的底气。