行业资讯
📅 2026/9/7 7:01:00
learn-claude-code s01:一个 while 循环加 bash,构建 AI 编码代理的最小 Harness 内核
learn-claude-code s01一个 while 循环加 bash构建 AI 编码代理的最小 Harness 内核【免费下载链接】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-the-agent-loop日文版文档展开讲清楚「为什么模型需要一个循环才能真正干活」完整继承原文档的循环机制与五步代码拆解并深入 s01_agent_loop/code.py 与 agents/s01_agent_loop.py 两个可运行实现补齐工具定义、bash 执行层的安全边界、环境变量与运行方式。读完后你可以本地跑通一个 30 行以内的最小 agent 内核并理解stop_reason如何成为整个控制流的唯一开关。问题模型能推理但触不到现实世界原文档开宗明义语言模型可以推理代码但它无法触碰现实世界——读不了文件、跑不了测试、看不到报错。没有循环每次工具调用都要由用户手动执行命令、再把输出复制粘贴回对话用户本人就成了那个循环。用课程 README 的表述s01_agent_loop/README.md你让模型「列出目录文件并运行 XXX.py」它能输出 bash 命令但输出完就停了——不会自己执行也不会基于结果继续推理。每一轮往返中用户都是中间层而 s01 这一章要做的事就是把这个中间层自动化。这正是该仓库的核心命题在第一章的具体化README 强调「Agency 来自模型训练Harness 是承载模型操作环境的载体」而 s01 就是这个载体里最底层的构件——Harness 层的第一个循环即模型与现实世界的第一座桥。解决方案由 stop_reason 驱动的 while 循环原文档给出的方案是一个极简的循环结构-------- ------- --------- | User | --- | LLM | --- | Tool | | prompt | | | | execute | -------- ------ -------- ^ | | tool_result | ---------------- (loop until stop_reason ! tool_use)一个终止条件控制整个流程只要模型还在发起工具调用循环就继续模型停下工具调用循环就结束。用表格概括就是两个信号信号含义循环动作stop_reason tool_use模型举手表态「我需要工具」执行工具 → 回灌结果 → 继续循环stop_reason ! tool_use模型宣布「我做完了」退出循环注意这里没有任何人工编写的分支路由、没有状态机、没有硬编码流程——控制流完全交给模型自身的停止信号。这与仓库反复强调的「Harness 不替模型做决策」一脉相承循环只负责「模型说继续就继续模型说停就停」。机制五步拆解 agent_loop原文档把循环拆成 4 个步骤实际执行 5 个动作下面完整继承其代码骨架并标注每一步在源码中的对应位置。步骤 1用户提问成为第一条消息。messages [{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逐个执行工具调用收集结果。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, })步骤 5把工具结果作为一条新的 user 消息追加回到步骤 2。messages.append({role: user, content: results})组装成完整函数后整个 agent 内核不到 30 行def agent_loop(messages): 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})原文档的结论是整个 agent 由此收进一个函数后续章节全部在这个循环之上叠加机制而循环本身永远不变。仓库的源码注释也印证了这一点——agents/s01_agent_loop.py 的模块 docstring 明确写着「生产级 agent 是在这个循环之上叠加 policy、hooks 与生命周期控制」s01_agent_loop/code.py 的对应表述是「后续章节在循环周围添加 policy、hooks 和 lifecycle controls」。源码纵深循环之外的三块「工程血肉」文档骨架里的run_bash、TOOLS、MODEL都是被略过的细节而真正让这段代码可以跑起来的工程内容都在仓库实现里。这里按源码逐块展开。工具定义只有一个 bash但 Schema 是完整的s01_agent_loop/code.py#L56-L65 中整个工具集只有一个bashTOOLS [{ name: bash, description: Run a shell command., input_schema: { type: object, properties: {command: {type: string}}, required: [command], }, }]这是刻意的最小化设计读文件靠cat、写文件靠echo ... 、找文件靠find——丑陋且易错但这正是下一章 s02 Tool Use 的引入动机「给模型 5 个正式工具会怎样会并行调用吗」。对 s01 而言一个足够通用的工具 一个循环已足以验证 agent 的最小形态。执行层 run_bash安全块、超时与输出截断agents/s01_agent_loop.py#L65-L77 的run_bash展示了这个「裸奔」执行层的防御边界def run_bash(command: str) - str: dangerous [rm -rf /, sudo, shutdown, reboot, /dev/] if any(d in command for d in dangerous): return Error: Dangerous command blocked try: r subprocess.run(command, shellTrue, cwdos.getcwd(), capture_outputTrue, textTrue, timeout120) out (r.stdout r.stderr).strip() return out[:50000] if out else (no output) except subprocess.TimeoutExpired: return Error: Timeout (120s) except (FileNotFoundError, OSError) as e: return fError: {e}三个值得注意的设计危险命令黑名单rm -rf /、sudo、shutdown、reboot、 /dev/一律拦截并返回错误文本。注意被拦截时不抛异常、而是把错误作为工具结果回灌给模型让模型自己看见并调整——这是 harness「把观察交给模型」的典型做法120 秒超时subprocess.run(..., timeout120)超时返回Error: Timeout (120s)防止一条卡死的命令挂住整个循环50000 字符输出截断防止cat一个大文件就撑爆上下文窗口。这些防护只是最粗粒度的一道。README 在「试一试」一节专门给出安全提示该代码执行的是模型生成的 shell 命令建议在临时测试目录中运行而正式的权限控制要到 s03 Permission 才引入。换句话说s01 刻意保持了「最小但可见的护栏」把治理机制留给后续章节。REPL 入口与多轮会话history 的复用s01_agent_loop/code.py#L117-L137 的入口是一个交互式 REPLs01 提示符读取输入q/exit/空行退出每轮把用户输入追加进history后调用agent_loop(history)。这里有一个文档未展开、但对理解循环很重要的细节——agent_loop接收的是累积的history列表而非每次新建的messages因此跨多轮提问时上下文自然延续模型记得之前执行过什么命令、产生过什么结果。循环内部的while True负责「单轮任务内的工具往返」外层的 REPLwhile True负责「会话级多轮」两层循环各司其职。此外还有两处实现细节code.py#L46-L51 通过load_dotenv(overrideTrue)读取 .env.example 中定义的MODEL_ID与可选的ANTHROPIC_BASE_URL用于 Anthropic 兼容的第三方端点且当配置了ANTHROPIC_BASE_URL时会主动pop掉ANTHROPIC_AUTH_TOKEN以避免鉴权头冲突系统提示词则是一行code.py#L54SYSTEM fYou are a coding agent at {os.getcwd()}. Use bash to solve tasks. Act, dont explain.把当前工作目录注入系统提示、并要求「直接行动、别解释」让模型知道自己在哪个环境里操作 bash——这就是 harness 给模型的第一份「世界知识」。变更点这一章往空白里填了什么原文档用一张 Before/After 表总结了 s01 相对空白起点的四个构件ComponentBeforeAfterAgent loop(none)while True stop_reasonTools(none)bash(one tool)Messages(none)Accumulating listControl flow(none)stop_reason ! tool_use这四个构件——循环、工具、累积消息列表、以 stop_reason 为判据的控制流——就是后续 16 个章节的全部地基。仓库 agents/ 目录下的s02s12各脚本都是在此内核上增量叠加的变体这一章的agent_loop函数签名与结构在它们中保持不变。试跑环境准备与运行以下命令均基于当前仓库内容整理依赖见 requirements.txtanthropic0.25.0、python-dotenv1.0.0、pyyaml6.0。首次运行准备pip install -r requirements.txt cp .env.example .env # 编辑 .env填入 ANTHROPIC_API_KEY 与 MODEL_ID.env.example 中MODEL_ID的默认示例值为claude-sonnet-4-6同时列出了若干 Anthropic 兼容第三方端点的ANTHROPIC_BASE_URLMODEL_ID组合MiniMax、GLM、Kimi、DeepSeek 等可按自己的供应商取消注释。运行python s01_agent_loop/code.py原文档「試してみる」一节给出的另一等价入口运行 agents 目录下的教学版脚本cd learn-claude-code python agents/s01_agent_loop.py两个文件功能一致agents/下是逐章教学脚本的聚合目录s01_agent_loop/下是带三语 README 与配图的正文章节目录。原文档建议的四个验证 prompt完整继承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观察要点来自章节 README留意模型什么时候会调用工具循环继续与什么时候不调用循环结束。安全提醒同样继承自 README模型生成的 shell 命令会被直接执行请在临时测试目录中运行避免影响项目文件。另外仓库的测试 tests/test_agents_smoke.py 对agents/目录下所有脚本含 s01做py_compile冒烟校验可作为快速验证脚本语法完整性的依据。小结循环不变机制叠加s01 交付的是一个可独立运行的最小 agent harness 内核一个while True循环、一个 bash 工具、一个不断累积的消息列表以及stop_reason ! tool_use这一唯一的终止判据。模型负责决定是否调工具、调哪个harness 负责执行调用工具并把结果作为新消息追加——这个分工是后续所有章节的共同前提。顺着仓库的章节脉络接下来是 s02 Tool Use从 1 个工具到 5 个正式工具、并行调用与竞态问题以及 s03 Permission决定什么命令可以运行两者都直接建立在本章这个不变的循环之上。更多三语章节说明可对照 s01_agent_loop/README.md、README.zh.md 与 README.ja.md。【免费下载链接】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),仅供参考