
1. 从一次“跑偏”的调试说起Agent Loop 到底在循环什么刚上手 Claude Code 那阵子我最困惑的不是怎么写 prompt而是它凭什么能自己读文件、跑命令、改代码还能在出错后换个思路重试。后来把 learn-claude-code 那套课程啃完才意识到自己一直在盯着“模型”看而真正决定体验的是外面那层壳——Harness。先把几个词说清楚不然后面全是雾。Claude Code 是一个跑在终端里的编码 Agent它能读写文件、执行 shell、调用工具适合刚接触 Agent 开发、想搞懂底层机制的开发者。Agent Loop 是它的心跳一个 while 循环反复把对话发给模型、拿回响应、判断要不要调工具、把工具结果塞回对话直到模型说“我不需要工具了”。Tool Use 是模型伸向真实世界的手模型本身只能吐文字是工具让它能碰文件系统和命令行。Subagent 是把一段子任务丢给一个独立上下文的小 Agent 去跑跑完只把摘要交回来避免过程噪声污染主对话。Harness 则是把上面这些串起来的那套环境与调度代码——模型是大脑Harness 是身体加环境。我踩过的第一个坑是把 Agent 想得太玄。其实剥开看核心循环短得能背下来while True: response client.messages.create(model, system, messages, tools) messages.append({role: assistant, content: response.content}) if response.stop_reason ! tool_use: return results execute_tools(response.content) messages.append({role: user, content: results})十二节课加的所有机制——规划、子 Agent、技能加载、上下文压缩、任务持久化、后台任务、团队协作、协议、自治、worktree 隔离——全都是在这个循环的外围做文章。工具从 1 个长到 16 个线程从 1 个长到 N 个状态从内存扩展到磁盘但循环本身一行没改。这就是 Harness Engineering 的核心不改模型改环境。这篇复盘我按“问题—机制—怎么验证”来写每个概念都配一个能跑的最小动作。你不需要先装一堆东西跟着敲就能看到 Agent Loop 的行为变化。下面先从接入环境讲起因为不管概念多清楚Key 配不对循环根本转不起来。2. 前置准备把 TaoToken 接进 Claude Code 的 Harness概念懂了得先让循环转起来。Claude Code 默认走 Anthropic 官方接口但很多刚上手的开发者卡在账号和额度上。我现在的做法是把它接到 TaoToken 的兼容端点上Base URL 换成https://taotoken.net/api其余调用方式不变。这样 Harness 那套循环逻辑完全不用动只是把请求发到了另一个地址。这里要强调一个认知接入端点属于 Harness 的“环境配置”层跟 Agent Loop 本身是解耦的。你换端点循环照跑你换模型 ID循环照跑。理解这一点后面调 Subagent、调工具都不会被“我是不是得改代码”绊住。先拿 Key。打开 https://taotoken.net/api-keys 登录后创建一个 API Key复制出来。注意别把它提交到 git我一般放环境变量里。export TAOTOKEN_API_KEYsk-你的key然后配置 Claude Code 的接入。Claude Code 读的是环境变量或 settings 文件最直接的方式是设这两个export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY$TAOTOKEN_API_KEY如果你用的是 Claude Code 的 settings.json可以写成这样路径通常在~/.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的key } }模型 ID 这块Claude Code 默认会用一个 Claude 系列模型名。如果你在 TaoToken 控制台看到可用的模型列表把 Model ID 填成对应的那个即可。三件套记牢Base URL、Key、Model ID缺一个循环就报错。配完先别急着跑复杂任务用一句最简单的对话验证连通claude -p 用一句话说明什么是 Agent Loop如果返回了正常文字说明 Harness 的请求链路通了。这一步看着简单但它验证的是最外层端点可达、Key 有效、模型能响应。等这一步稳了再去折腾工具和 Subagent排障范围会小很多。我建议把这个验证动作固定成习惯。每次换环境、换 Key、升级 Claude Code 之后先跑这一句。它花不了几秒但能帮你把“是接入问题还是逻辑问题”一刀切开。很多新手一上来就跑复杂任务报错了不知道是 Key 错了还是工具配置错了白白耗时间。3. 可复制的 Harness 配置Tool Use 与 Subagent 拆分连通之后进入正题。这一节给你两份能直接抄的配置一份是 Tool Use 的工具声明与 dispatch一份是 Subagent 的拆分示例。它们对应课程里 s02 和 s04 两课的核心机制。先说 Tool Use。模型本身不能读文件你得把工具“介绍”给它并在本地准备一个 dispatch map 把工具名路由到执行函数。工具声明长这样{ name: read_file, description: 读取指定路径的文件内容返回文本, input_schema: { type: object, properties: { path: { type: string, description: 相对于工作目录的文件路径 } }, required: [path] } }dispatch map 就是一张字典工具名对到函数TOOL_HANDLERS { read_file: handle_read_file, write_file: handle_write_file, run_bash: handle_run_bash, } def execute_tools(content_blocks): results [] for block in content_blocks: if block.type ! tool_use: continue handler TOOL_HANDLERS.get(block.name) if handler is None: results.append({ type: tool_result, tool_use_id: block.id, content: f未知工具: {block.name}, is_error: True, }) continue output handler(**block.input) results.append({ type: tool_result, tool_use_id: block.id, content: output, }) return results这里有个关键点循环永远不认识具体工具它只认 dispatch map。你加一个新工具改的是 map 和声明循环一行不动。这就是为什么课程说“工具从 1 个长到 16 个循环没变”。再说 Subagent。主 Agent 跑复杂任务时子任务的过程会塞满上下文噪声越积越多。Subagent 的做法是开一个全新的 messages 列表让子 Agent 在自己的上下文里跑完只把摘要返回给父级def run_subagent(task_prompt, max_turns30): sub_messages [{role: user, content: task_prompt}] for _ in range(max_turns): response client.messages.create( modelMODEL_ID, systemSUBAGENT_SYSTEM, messagessub_messages, toolsSUBAGENT_TOOLS, ) sub_messages.append({role: assistant, content: response.content}) if response.stop_reason ! tool_use: break results execute_tools(response.content) sub_messages.append({role: user, content: results}) return extract_summary(sub_messages)注意sub_messages是全新的跟父级的 messages 完全隔离。子 Agent 跑完父级只拿到一段摘要文本中间几十轮的工具调用和报错全被挡在外面。课程里给子 Agent 设了 30 轮上限防止它失控空转这个安全上限值得抄。把这两份配置放一起看你会发现它们共享同一个循环骨架区别只在 messages 的来源和工具集。Harness 的模块化就体现在这循环是地基工具和 Subagent 是上面搭的房间。4. 逐步验证 Agent Loop 行为从 stop_reason 看循环怎么转配置抄完得验证循环真的按预期在转。最有效的观察点是stop_reason。它是循环的“红绿灯”等于tool_use就继续转等于end_turn就退出。我试过用一个最小任务来观察让 Agent 读一个文件并统计行数。你可以在项目里建个demo.txt随便写几行然后跑claude -p 读取 demo.txt告诉我它有多少行在 Harness 里加一行日志把每轮的 stop_reason 打出来print(f[loop] turn{turn}, stop_reason{response.stop_reason})你会看到类似这样的序列[loop] turn1, stop_reasontool_use [loop] turn2, stop_reasonend_turn第一轮模型决定调read_file循环执行工具、把结果塞回 messages第二轮模型拿到文件内容直接给出答案stop_reason 变成end_turn循环退出。整个过程两轮干净利落。再试一个会触发多轮工具的任务比如“找出项目里所有 .py 文件统计总行数”。你会看到 stop_reason 连续几次都是tool_use因为模型要先列目录、再逐个读文件、最后汇总。每一轮工具结果都追加到 messages 尾部模型下一轮就能看到。这里有个容易忽略的细节工具结果是以role: user的身份塞回去的。也就是说对话里 assistant 说“我要调工具”user 回“这是工具结果”模型再基于这个结果继续。理解这个角色交替你就理解了循环为什么能一直转下去。验证 Subagent 的隔离性可以对比上下文长度。跑一个复杂任务先不用 Subagent观察 messages 增长再换成 Subagent 版本父级 messages 只多了摘要那一条。这个对比很直观能让你真正体会到“独立上下文”省下了什么。5. 常见报错排查401、local proxy failed 与 reading choices配 Harness 的过程里报错基本集中在接入层。我把踩过的几个整理出来对照着查能省不少时间。401 Unauthorized最常见。九成是 Key 没设对或没生效。先确认环境变量真的导进去了echo $ANTHROPIC_API_KEY如果输出为空说明当前 shell 没读到。注意export只在当前会话有效换个终端就没了建议写进 shell 配置文件。还有一种情况是 Key 复制时带了空格或换行重新复制一遍。Base URL 也要检查https://taotoken.net/api结尾不要多加斜杠。local proxy failed / connection refused这个报错通常出现在你本地配了转发但没启动或者端口写错。如果你没主动配本地转发检查一下是不是残留了旧的ANTHROPIC_BASE_URL指向了localhost。清掉重设unset ANTHROPIC_BASE_URL export ANTHROPIC_BASE_URLhttps://taotoken.net/apireading choices / 响应解析失败这类报错说明请求发出去了但返回的结构跟预期对不上。常见原因是 Model ID 填错或者端点返回了错误页而不是 JSON。先用 curl 直接打一下端点看返回体curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $ANTHROPIC_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:你的Model ID,max_tokens:64,messages:[{role:user,content:hi}]}如果返回的是 HTML 或错误 JSON问题在接入层如果返回正常但 Claude Code 还报错检查 Model ID 是否跟控制台一致。OAuth 相关报错如果你之前登录过官方账号本地可能残留了 OAuth 凭证跟 API Key 模式冲突。清掉凭证缓存再试或者显式用 API Key 模式启动。排查顺序我总结成一句话先 curl 验端点再 echo 验 Key最后看 Model ID。三步走完接入层的问题基本都能定位。6. 把学习笔记落成可跑通的最小实践回到开头那句话Agent 等于模型加 Harness模型提供智能Harness 提供表达智能的空间。十二节课教的全是 Harness循环从未改变。你现在手里有了接入配置、工具 dispatch、Subagent 拆分和验证方法最小实践就齐了。我的建议是别贪多先把 s01 到 s04 跑通一个能读文件的循环、一套 dispatch map、一个 TodoManager、一个 Subagent。这四个跑顺了后面 s05 到 s12 的压缩、持久化、团队协作都是在这个骨架上加房间理解成本会低很多。如果你想把长期编码任务和 Agent 实验固定下来可以看看 Coding Plan把额度和模型配置一次理顺https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。想直接对着模型验证循环行为用模型对话页最快https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite Key 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。最后留一个我常用的调试习惯每次改完 Harness先跑那句claude -p 用一句话说明什么是 Agent Loop。它通了再上复杂任务。循环转不转一句话就知道。