资讯动态

从零手写 ClaudeCode 实战笔记(1)用 TaoToken 打通 The Agent Loop 智能体循环

发布时间:2026/9/29 20:41:28 来源:尧图企业网站定制
1. 为什么我要从零手写 ClaudeCode 的 Agent LoopClaudeCode 这类编码智能体最近很火但很多人只停留在“用”的层面装好 CLI、敲几句 prompt、看它改代码。真到自己想写一个能读文件、跑测试、看报错的智能体时就卡住了。原因很简单——语言模型本身只能推理文本它碰不到真实世界不能读你的目录、不能执行pytest、不能看 git 状态。没有循环机制每次工具调用的结果都得你手动粘回去你自己就是那个循环。learn-claude-code 这个开源项目把这件事讲得很透它的核心口号是 “One loop Bash is all you need”——一个工具加一个循环就是一个智能体。第一章 The Agent Loop 用不到 50 行代码把“人肉粘结果”这件事自动化了。它遵循的是经典 ReActReasoning and Acting范式让模型边思考边行动推理→行动→观察→再推理逐步解决复杂问题。这篇笔记聚焦第一步用 TaoToken 统一 Key 和 API 通道接入 LLM把 Agent Loop 的「思考—调用 Bash—观察」闭环跑通。适合刚接触 Agent 开发、想动手写第一个循环的读者。我会给出可复制的settings.json骨架、最小循环的验证动作以及我踩过的坑。读完你至少能跑通一个能自己执行 Bash 命令的智能体循环。2. TaoToken 前置准备统一 Key 与 API 通道在写循环之前得先解决“模型从哪来”的问题。learn-claude-code 原版用的是 Anthropic 的 SDK但国内直连和 Key 管理对新手不太友好。我的做法是用 TaoToken 作为统一的 API 通道把 Key、Base URL、模型名集中管理这样后面写代码时只关心循环逻辑不用到处改配置。TaoToken 在这里扮演的角色是“统一入口”你申请一个 Key就能通过兼容的接口调用模型省去每个项目单独配环境变量的麻烦。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api注意这个不带 UTM 参数代码里填这个。你需要先拿到 API Key。登录后进入控制台在 API Keys 页面创建一个新 Key复制保存好——它只显示一次。如果你打算长期做编码类 Agent、频繁调用可以看看 Coding Plan额度更划算只是验证模型对话效果的话用模型对话页面先试几句也行。注意Key 不要硬编码进 Git 仓库。我习惯放在项目根目录的.env里再用.gitignore排除掉。这一步的目标很明确拿到TAOTOKEN_API_KEY记住https://taotoken.net/api这个 Base URL后面settings.json和 Python 代码都要用。3. 可复制配置settings.json 骨架与 .envlearn-claude-code 的目录结构里agents/放各个章节的脚本配置一般放在项目根。我先给你一个settings.json骨架把模型、Base URL、工具定义集中起来。这样循环代码只读配置不写死参数。{ llm: { provider: taotoken, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, model: claude-3-5-sonnet-latest, max_tokens: 8000, system: You are a coding agent. Use the bash tool to inspect files, run tests, and fix errors. Think step by step. }, tools: [ { name: bash, description: Execute a bash command and return its output. Use it to read files, list directories, run tests, and check git status., input_schema: { type: object, properties: { command: { type: string, description: The bash command to execute. } }, required: [command] } } ], loop: { max_iterations: 20, stop_reason: tool_use } }对应的.env文件长这样TAOTOKEN_API_KEYsk-你的真实key然后在 Python 里加载配置。我用python-dotenv读.env用json读settings.jsonimport json import os from dotenv import load_dotenv load_dotenv() with open(settings.json, r, encodingutf-8) as f: config json.load(f) API_KEY os.getenv(config[llm][api_key_env]) BASE_URL config[llm][base_url] MODEL config[llm][model] SYSTEM config[llm][system] TOOLS config[tools] MAX_TOKENS config[llm][max_tokens]这里有个关键点base_url填https://taotoken.net/apiSDK 会自动拼接/v1/messages这类路径。如果你用的是 Anthropic 官方 SDK初始化时传base_url参数即可。from anthropic import Anthropic client Anthropic( api_keyAPI_KEY, base_urlBASE_URL, )配置这一步做完你就有了一个“模型可调用、工具已声明”的环境。接下来写循环本体。4. 最小 Agent Loop思考—调用 Bash—观察Agent Loop 的本质是一个while True退出条件是模型不再调用工具。learn-claude-code 的s01_agent_loop.py用不到 30 行实现了它。我按 ReAct 的思路拆成三段思考LLM 返回、行动执行 Bash、观察把结果塞回消息列表。先定义 Bash 执行函数。这里要小心别让模型执行危险命令教学阶段我加了个简单白名单和超时import subprocess def run_bash(command: str, timeout: int 30) - str: try: result subprocess.run( command, shellTrue, capture_outputTrue, textTrue, timeouttimeout, ) output result.stdout result.stderr return output if output.strip() else (no output) except subprocess.TimeoutExpired: return fError: command timed out after {timeout}s except Exception as e: return fError: {e}然后是核心循环。注意消息列表是累积的每次工具结果都作为user消息追加回去def agent_loop(query: str): messages [{role: user, content: query}] for i in range(config[loop][max_iterations]): response client.messages.create( modelMODEL, systemSYSTEM, messagesmessages, toolsTOOLS, max_tokensMAX_TOKENS, ) messages.append({role: assistant, content: response.content}) if response.stop_reason ! tool_use: print(任务结束模型给出最终回答) for block in response.content: if hasattr(block, text): print(block.text) return results [] for block in response.content: if block.type tool_use: print(f[行动] 执行命令: {block.input[command]}) output run_bash(block.input[command]) print(f[观察] 输出: {output[:200]}...) results.append({ type: tool_result, tool_use_id: block.id, content: output, }) messages.append({role: user, content: results}) print(达到最大迭代次数强制退出。)这段代码里stop_reason ! tool_use就是那个“唯一的退出条件”。模型如果觉得任务完成了就不再调用工具循环结束。ToolUseBlock对象长这样ToolUseBlock( idbash_0, callerNone, input{command: echo \print(Hello, World!)\ hello2.py}, namebash, typetool_use )id是工具调用的唯一标识input里是模型生成的命令name对应我们在settings.json里声明的工具名。把tool_use_id和id对上模型才能把结果和请求关联起来。5. 验证请求跑通第一个智能体循环配置和代码都齐了现在验证。先装依赖pip install anthropic python-dotenv然后写一个入口跑几个经典 prompt。英文 prompt 对 LLM 效果通常更好中文也能用if __name__ __main__: agent_loop(Create a file called hello.py that prints Hello, World!)运行cd learn-claude-code python agents/s01_agent_loop.py你应该能看到类似这样的输出[行动] 执行命令: echo print(Hello, World!) hello.py [观察] 输出: (no output) [行动] 执行命令: cat hello.py [观察] 输出: print(Hello, World!) 任务结束模型给出最终回答 已创建 hello.py内容为 print(Hello, World!)。再试几个 prompt 验证循环的通用性List all Python files in this directory What is the current git branch? Create a directory called test_output and write 3 files in it实测下来List all Python files会触发ls *.py或find . -name *.pygit branch会触发git branch --show-current。每次模型调用工具你都能在终端看到「行动」和「观察」的打印这就是 ReAct 闭环在跑。如果你想先确认模型通道是否正常可以到模型对话页面发一句“你好”看返回是否正常。确认通道没问题再跑循环能省不少排查时间。6. 本篇常见错排查跑不通的时候大概率是下面几个问题。我按踩坑频率排序。报错AuthenticationError或 401Key 没读到或填错。检查.env里变量名是否和settings.json的api_key_env一致load_dotenv()是否在读取前调用。另外确认 Key 没有多余空格。报错ConnectionError或超时Base URL 写错。代码里应该是https://taotoken.net/api不要带 UTM 参数也不要手动加/v1SDK 会自己拼。模型不调用工具直接返回文本检查TOOLS是否正确传给了client.messages.create以及settings.json里input_schema的required是否包含command。工具描述太模糊也会导致模型不用工具把description写清楚。循环停不下来达到 max_iterations模型可能陷入重复调用。检查run_bash返回的内容是否为空或报错模型看到错误会反复尝试。给run_bash加超时和错误捕获返回明确信息。stop_reason一直是tool_use确认你判断的是response.stop_reason不是response.content里的某个字段。另外max_tokens太小可能导致响应被截断设成 8000 比较稳。Bash 命令没权限或路径不对subprocess.run的工作目录是脚本运行目录。如果你在learn-claude-code根目录跑命令就在根目录执行。需要指定目录时在命令里加cd。排障时如果怀疑是 Key 或接入配置问题直接去 API Keys 页面重新生成一个 Key 对比测试接入细节可以翻接入文档里面有各语言 SDK 的 Base URL 填法。7. 下一步把循环接进你的编码工作流跑通这个最小循环后你会发现后面 11 个章节都在这个循环上叠加机制——加文件编辑工具、加多轮规划、加子智能体——但循环本身始终不变。这就是 learn-claude-code 设计的巧妙之处一个退出条件控制整个流程。如果你打算长期做编码类 Agent、频繁调用模型建议把 Key 和额度规划好Coding Plan 对高频场景更合适。日常调试和验证模型行为用模型对话页面快速试 prompt 就行。控制台里可以管理多个 Key方便区分开发和生产。我自己的习惯是每个 Agent 项目单独一个 Key.env不进 Gitsettings.json进 Git 但 Key 用环境变量引用。这样换机器、换通道时只改.env代码一行不动。下一步你可以试着给run_bash加个命令白名单或者把工具从单一 Bash 扩展成读写文件两个工具观察循环怎么处理多个tool_useblock。循环不变工具在变这就是智能体开发的乐趣所在。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑