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),仅供参考

相关新闻

从板级到云端:空调嵌入式通信协议选型与调试指南

从板级到云端:空调嵌入式通信协议选型与调试指南

做空调产品开发,真正需要花大量时间调通的往往不是压缩机控制或者风机 PWM,而是“通信”。从主板上读一个温湿度传感器,是 IC 还是 SPI;室内机和室外机之间走什么总线;MCU 跟 Wi-Fi 模组之间用什么接口;数据…

2026/10/27 11:42:27 阅读更多 →
MediaCrawler 多平台自媒体爬虫:环境搭建、CDP 模式、命令行参数与数据存储全解析

MediaCrawler 多平台自媒体爬虫:环境搭建、CDP 模式、命令行参数与数据存储全解析

MediaCrawler 多平台自媒体爬虫:环境搭建、CDP 模式、命令行参数与数据存储全解析 【免费下载链接】MediaCrawler 小红书笔记 | 评论爬虫、抖音视频 | 评论爬虫、快手视频 | 评论爬虫、B 站视频 | 评论爬虫、微博帖子 | 评论爬虫、百度贴吧帖…

2026/10/29 0:01:55 阅读更多 →
空调控制器通信协议全解析:从I2C到MQTT的实战指南

空调控制器通信协议全解析:从I2C到MQTT的实战指南

做空调控制器的嵌入式开发,很容易遇到一个现象:单板功能调试没问题,传感器数据也能读到,但联调时室内机、室外机、线控器和云端 APP 就是对不上。问题往往不在某一个芯片,而在通信协议这一层没有打通。这次我们就把空调…

2026/10/25 22:21:10 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/28 23:48:14 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/28 7:28:00 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/28 9:02:11 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/28 22:10:30 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/28 9:00:54 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/28 7:29:02 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 16:58:40 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 9:01:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 19:25:09 阅读更多 →