learn-claude-code 全解:17 节 Harness 工程课,从一行 while True 长出来的 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 把「Agent 产品 = 模型 + Agent Harness」拆成 17 节可独立运行的工程课:模型负责决策,Harness 负责手、眼和边界。本文按能力递进的路径,带你看清这门课的核心机制与跑通方式。
🚪 场景切入:先想明白谁在开车
你大概率见过这样的「Agent」:一个拖拽画布,节点里塞着 LLM 调用,节点之间用 if-else 和箭头连出流程。说白了,那是用胶水粘出来的流水线,LLM 只是其中一个会补全文本的节点——换个说法,这是经典符号 AI 的老把戏刷了层新漆。真正能自主干活的系统长什么样?DeepMind 的 DQN 只用一个神经网络接原始像素,就在 7 款 Atari 游戏上超过既有算法——没有决策树,没有手写规则。智能是训练出来的,不是代码拼出来的。
所以分工很清楚:模型是司机,Harness 是车。Agent = 模型 + Harness。司机决定方向盘往哪打,车提供轮子、油门、刹车、后视镜。模型做决策,Harness 执行;模型推理,Harness 喂上下文。
learn-claude-code 做的就是造车:它把 Claude Code 这类 coding agent 剥成最小部件,用 17 个可单独运行的 Python 文件(s01~s17 的 code.py)从零组装一遍。每节只在循环上加一个 Harness 机制,所以你能亲眼看着这辆车从骨架长到整车。
🔧 从 s01 到 s17:能力递进路线
下面不按课程编号讲,按「这个机制解决什么问题」跳着走。
问题:谁来决定什么时候停
s01 的全部核心,就是一个循环。唯一的工具是 bash,system prompt 只有一句 "Act, don't explain.":
def agent_loop(messages): while True: response = client.messages.create( model=MODEL, system=SYSTEM, messages=messages, tools=TOOLS, max_tokens=8000) messages.append({"role": "assistant", "content": response.content}) if response.stop_reason != "tool_use": return模型说停就停,代码只负责执行工具的请求。bash 执行器里还埋着第一层边界:危险命令黑名单、120 秒超时、输出截断到 5 万字符——这三条就是权限治理的雏形。
问题:加工具要不要重写循环
s02 的答法很干脆:把硬编码的 bash 调用换成一张分派表,新工具注册进字典就完事,循环骨架一个字符没动:
output = TOOL_HANDLERSblock.name工具从 1 个扩到 5 个(读、写、编辑、glob)。这里有个容易踩的坑:所有文件类工具都先过一道 safe_path 检查,路径解析后一旦逃出工作区直接抛异常——权限边界嵌在工具实现里,成本极低。
问题:给自由之前先画边界
s03 把 s01 那个粗糙黑名单升级成三道串联的门,工具执行前先过权限流水线:
def check_permission(block): if block.name == "bash": reason = check_deny_list(block.input.get("command", "")) if reason: return False reason = check_rules(block.name, block.input) if reason: decision = ask_user(block.name, block.input, reason) if decision == "deny": return False第一道是黑名单,第二道是规则匹配,命中就弹窗问你允许还是拒绝。先定边界,再给自由——顺序反了就是事故。
问题:多步任务怎么不跑偏
无计划的 Agent 是走一步看一步。s05 给循环加了一个 todo_write 工具:TodoManager 管一份最多 20 条的计划清单,模型每 3 轮不动它就被注入一条提醒。计划是 Harness 的纪律,不是模型的自觉。
问题:上下文总会溢出,怎么办
对话越滚越长,token 账单和注意力一起爆炸。s08 的解法是一条四级压缩管道,在每次 LLM 调用之前先跑:
def prepare(self, messages, active_request): messages = self.tool_result_budget(messages) messages = self.snip_compact(messages) messages = self.micro_compact(messages) if self.estimate_chars(messages) > self.CONTEXT_CHAR_LIMIT: messages = self.compact_history(messages, active_request) return messages顺序很讲究:先把超大工具结果落盘,再把中段历史归档到磁盘,然后截短旧工具输出,全都不够才舍得让模型摘要整段历史。该记的记,该忘的忘,先省便宜的再上贵的。
问题:一个人干不完怎么办
s13 引入常驻队友:任务写成文件落在磁盘,带依赖关系和状态;认领用文件锁做原子操作,防止两个 agent 抢同一个任务:
def claim_task(task_id, owner="agent"): with task_store_lock(): task = get_task(task_id) if task.status != "pending": return f"Task {task_id} is {task.status}, cannot claim" cwd, error = task_worktree_cwd(task)每个任务还会绑一个独立的 git worktree 目录,队友各干各的互不踩线。队友之间走邮箱目录传消息。多 Agent 协作的地基就是这三样:原子认领、任务绑定的工作目录、共享的任务文件。
问题:模型说「我做完了」,能信吗
worker 不调工具、说想停,不等于目标达成。s17 的做法是派一个没有工具的独立评审员读整段对话,对着目标条件给裁决:
response = self.client.messages.create( model=self.model, system=("You are an independent completion evaluator. " "You have no tools. ..."), messages=[{"role": "user", "content": prompt}], max_tokens=self.max_tokens)不达标就把「还缺什么」回灌给 worker 继续干;评审员判定不可行,或连续挡了 8 轮,就交还控制权给用户。该不该结束,由目标说了算,而不是由模型的疲倦感说了算。
17 个机制散讲完了。s15 把它们全部收进一个文件:记忆、团队事件、MCP 工具、定时任务汇入同一个循环,用一组显式常量管理运行时预算——机制很多,循环只有一个。
🗺️ 能力分层地图:17 节归纳为 4 层
| 层级 | 覆盖机制 | 你获得的能力 | 练手建议 |
|---|---|---|---|
| L1 能动 | 循环(s01)、工具分派(s02)、权限(s03)、钩子(s04) | 最小可运行 Agent | 改 s01 的 system prompt 换个性格,看循环是否依旧稳 |
| L2 能干复杂活 | 计划(s05)、子 Agent(s06)、按需知识(s07)、上下文压缩(s08) | 多步任务不失忆 | 往 s02 分派表里注册一个自己的工具,验证循环不用动 |
| L3 能记能长跑 | 记忆(s09)、任务图(s10)、后台任务(s11)、定时(s12) | 跨会话、长时间运行 | 用 s10 的磁盘任务图给队友留工作,跑两次验证可恢复 |
| L4 能协作能收尾 | 团队(s13)、MCP(s14)、整合(s15)、工作流(s16)、目标门控(s17) | 多 Agent 交付闭环 | 给 s17 喂一个可验证目标(比如测试全绿),观察门控拦截 |
🚀 三步跑通 learn-claude-code
依赖只有三个包:anthropic、python-dotenv、pyyaml,后者服务于协议和配置文件解析。装好即可:
pip install -r requirements.txt配置 .env(从 .env.example 复制),三个字段:
| 字段 | 必填 | 说明 |
|---|---|---|
| ANTHROPIC_API_KEY | 是 | API Key |
| MODEL_ID | 是 | 默认示例 claude-sonnet-4-6 |
| ANTHROPIC_BASE_URL | 否 | 兼容端点,可换 MiniMax、GLM、Kimi、DeepSeek |
.env.example 里内建了这几家兼容提供方的对照表——课程从第一天就默认模型层可替换,这正是「Harness 与模型解耦」的注脚。然后挑三站开跑:
python s01_agent_loop/code.py # 最小循环,看 bash 工具怎么被驱动 python s08_context_compact/code.py # 四级压缩 python s17_goal_loop/code.py "/goal pytest tests exits with code 0" # 目标门控仓库还带一个从根目录课程自动抽取内容的 Web 阅读平台(web/),以及 tests/ 下的 13 个离线测试文件——想核对某个机制的行为,跑对应测试比真调模型便宜得多。
一句提醒:仓库里的 docs/ 和 agents/ 是旧 12 节版的过渡保留,编号与现行 17 节错位——旧 s09~s12 的四个团队话题收敛进了现行 s13,而权限、钩子、记忆、定时、MCP、整合、工作流、目标门控这八节是新版才有的,别拿旧链接对号入座。
收尾
智能在模型里,工程在 Harness 里——车造得好,司机开得快。至于 skills/ 目录里那份技能文件怎么说来着:模型早就知道怎么当 Agent,你的工作是别挡路。
留一个问题给你:如果你的 Agent 不是 coding,Harness 的「手」和「眼」分别是什么?想深入某节,直接从 s01_agent_loop/ 的 README 和 code.py 读起就行。
【免费下载链接】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),仅供参考