ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

learn-claude-code s01 解析:一个 while 循环 + 单一 Bash 工具如何构成最小 Agent 内核

2026/9/5 23:16:35 拓冰建站 浏览量
learn-claude-code s01 解析:一个 while 循环 + 单一 Bash 工具如何构成最小 Agent 内核 learn-claude-code s01 解析一个 while 循环 单一 Bash 工具如何构成最小 Agent 内核【免费下载链接】learn-claude-codeBash is all you need - A nano claude code–like 「agent harness」, built from 0 to 1项目地址: https://gitcode.com/GitHub_Trending/an/learn-claude-code本文基于 learn-claude-code 仓库的 s01 章节Agent Loop / Agent 循环拆解一个工具 一个循环 一个 Agent这一最小 Agent 内核的完整实现从stop_reason驱动的控制流设计到messages累积式消息列表再到 agents/s01_agent_loop.py 中工具执行的安全护栏细节。读完本文你将能够独立复现并运行这个不到 30 行的 Agent 循环并理解后续 11 个章节的机制是如何叠加在它之上的。问题没有循环的模型碰不到真实世界语言模型能推理代码但它碰不到真实世界——不能读文件、跑测试、看报错。你问它帮我读取目录下有哪些文件并执行 XXX.py它能输出一条 bash 命令但输出完了就停了它不会自己跑这条命令也不会看到结果后继续推理。于是你只能手动执行一遍把输出粘贴回对话框让它接着干下一个命令出来你再跑一遍、再贴回去。每一个来回你自己就是那个循环。s01 章节要做的事情就是把这层人肉中间件自动化。解决方案一个退出条件控制整个流程s01 的答案是一个while True循环整个控制流只依赖一个退出条件-------- ------- --------- | User | --- | LLM | --- | Tool | | prompt | | | | execute | -------- ------ -------- ^ | | tool_result | ---------------- (loop until stop_reason ! tool_use)循环持续运行直到模型不再调用工具。整个过程只由两个信号驱动信号含义循环动作stop_reason tool_use模型举手说我要用工具执行 → 结果喂回去 → 继续循环stop_reason ! tool_use模型说我做完了退出循环这里体现了 harness 工程的核心分工模型负责决策要不要调工具、调哪个harness 负责执行调用工具、把结果作为新消息追加回去。循环本身没有任何智能它只是把模型的每一次举手变成真实世界的动作并把动作结果送回模型的视野。工作原理把循环翻译成代码文档将循环拆成 4 个步骤逐一实现。第 1 步用户 prompt 作为第一条消息进入累积式消息列表。messages.append({role: user, content: query})第 2 步将消息和工具定义一起发给 LLM。response client.messages.create( modelMODEL, systemSYSTEM, messagesmessages, toolsTOOLS, max_tokens8000, )第 3 步追加助手响应然后检查stop_reason——如果模型没有调用工具直接返回。messages.append({role: assistant, content: response.content}) if response.stop_reason ! tool_use: return第 4 步执行每个工具调用收集结果作为一条 user 消息追加回到第 2 步。results [] for block in response.content: if block.type tool_use: output run_bash(block.input[command]) results.append({ type: tool_result, tool_use_id: block.id, content: output, }) messages.append({role: user, content: results})组装为一个完整函数def agent_loop(query): messages [{role: user, content: query}] while True: response client.messages.create( modelMODEL, systemSYSTEM, messagesmessages, toolsTOOLS, max_tokens8000, ) messages.append({role: assistant, content: response.content}) if response.stop_reason ! tool_use: return results [] for block in response.content: if block.type tool_use: output run_bash(block.input[command]) results.append({ type: tool_result, tool_use_id: block.id, content: output, }) messages.append({role: user, content: results})不到 30 行这就是整个 Agent。后面 11 个章节工具扩展、权限、hooks、TodoWrite、子 Agent、技能加载、上下文压缩、任务系统、后台任务、Agent 团队、工作树隔离全部在这个循环上叠加机制——循环本身始终不变。源码纵深agents/s01_agent_loop.py 的实现细节文档给出的是最小骨架仓库中的可运行实现补充了让它真正跑起来的工程细节。System prompt给模型一个工作目录。源码中 system prompt 直接注入当前工作目录并要求行动而非解释SYSTEM fYou are a coding agent at {os.getcwd()}. Use bash to solve tasks. Act, dont explain.把os.getcwd()写进 system prompt模型才知道我在哪里Act, dont explain则压缩了模型的闲聊倾向让它直接产出工具调用。工具定义只有一个 bash。s01 的工具池刻意最小化——读文件用cat、写文件用echo ... 、找文件用find丑但够用这正是 s01单一工具论断的体现TOOLS [{ name: bash, description: Run a shell command., input_schema: { type: object, properties: {command: {type: string}}, required: [command], }, }]run_bash循环中唯一的手。agents/s01_agent_loop.py#L65-L77 中的执行函数包含几道关键护栏这些在文档骨架里是隐藏变量危险命令黑名单rm -rf /、sudo、shutdown、reboot、 /dev/命中即返回Error: Dangerous command blocked不真正执行。这是最原始的字符串匹配式防护——仓库在 s03 章节会把它升级为完整的权限系统120 秒超时subprocess.run(..., timeout120)超时返回Error: Timeout (120s)防止一条sleep 9999把循环永久挂起输出截断到 50000 字符out[:50000]防止cat一个大文件把消息列表撑爆。空输出统一替换为(no output)让模型拿到明确信号而不是空字符串。值得强调的是这些错误并没有抛出异常中断循环而是作为普通字符串返回给模型。从源码结构看这是有意的——模型读到Error: Timeout (120s)后可以自己决定换个方式重试错误处理被纳入了推理循环本身。多轮 REPL 入口。agents/s01_agent_loop.py#L104-L120 的__main__维护一个跨轮次的history列表每条用户输入追加为 user 消息后调用agent_loop(history)循环结束后从history[-1]取出模型最后一段 text 打印出来。这意味着多个问题之间上下文是延续的——agent_loop每次返回时messages里已经沉淀了完整的提问—工具调用—结果轨迹。环境适配细节。源码通过load_dotenv(overrideTrue)加载配置若设置了ANTHROPIC_BASE_URL会主动清除ANTHROPIC_AUTH_TOKEN以避免鉴权头冲突agents/s01_agent_loop.py#L44-L52同时包含一组readline绑定修复 macOS libedit 下 UTF-8 退格问题。仓库当前 track 的对应实现在 s01_agent_loop/code.py逻辑一致入口提示语为s01 输入q、exit或空行退出。变更内容s01 到底加入了什么组件之前之后Agent loop(无)while True stop_reasonTools(无)bash(单一工具)Messages(无)累积式消息列表Control flow(无)stop_reason ! tool_use试一试运行 s01安全提示代码会执行模型生成的 shell 命令建议在一个临时测试目录中运行避免影响你的项目文件。仓库在 s03 章节才加入真正的权限控制。准备首次运行pip install -r requirements.txt cp .env.example .env # 编辑 .env填入 ANTHROPIC_API_KEY 和 MODEL_IDrequirements.txt 只依赖anthropic、python-dotenv、pyyaml三个包。从 .env.example 看ANTHROPIC_API_KEY与MODEL_ID为必填项默认MODEL_IDclaude-sonnet-4-6ANTHROPIC_BASE_URL为可选项可指向任意 Anthropic 兼容的提供方端点。运行legacy 12 课 trackcd learn-claude-code python agents/s01_agent_loop.py仓库当前主推的 17 课 track 中同一章节的可运行版本是python s01_agent_loop/code.py试试这些 prompt英文 prompt 对 LLM 效果更好也可以用中文Create a file called hello.py that prints Hello, World!List all Python files in this directoryWhat is the current git branch?Create a directory called test_output and write 3 files in it观察重点模型什么时候调用工具循环继续什么时候不调用循环结束以 prompt 1 为例仓库的 Web 模拟场景 web/src/data/scenarios/s01.json 完整记录了预期轨迹模型先发出echo print(Hello, World!) hello.py创建文件bash 返回空输出表示成功看到结果后继续推理再发一条cat hello.py验证内容最后以一段纯文本回复收尾——此时stop_reason ! tool_use循环终止。这正是创建—验证—收尾两段式工具调用在循环内的真实形态。小结与接下来s01 交付了一个可运行的最小 harness 内核while Truestop_reason 累积式消息列表 单一 bash 工具。它不是智能本身而是让模型持续行动的最小运行框架。局限也很直白——模型手里只有 bash读文件要cat、写文件要echo ... 、找文件要find又丑又容易出错且危险命令防护只是字符串匹配。下一章 s02 Tool Use 会回答这些问题给它 5 个真正的工具会发生什么模型会不会一次调用多个工具几个工具同时跑会不会互相踩而无论工具池怎么扩展s01 的这个循环一行都不会变。【免费下载链接】learn-claude-codeBash is all you need - A nano claude code–like 「agent harness」, built from 0 to 1项目地址: https://gitcode.com/GitHub_Trending/an/learn-claude-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考