learn-claude-code agent-builder 技能详解:从"模型即智能体"哲学到最小 Agent 脚手架的完整构建方法论
本篇围绕 learn-claude-code 仓库中的 agent-builder 技能文件 展开,系统讲解该技能定义的核心设计哲学(模型即智能体,代码只是挽具)、"能力/知识/上下文"三要素设计法与渐进式复杂度分级,并结合仓库内配套的参考实现(约 80 行的最小 Agent、工具模板、子智能体隔离模式、项目脚手架脚本)把方法论落成可直接运行的代码,帮助读者掌握为任意领域从零设计 AI Agent 的完整流程。
一、agent-builder 技能的定位与触发条件
agent-builder 是 learn-claude-code 仓库 skills/ 目录下的一个技能包(Skill),与 pdf、code-review 等技能并列。与面向单一操作手册的其他技能不同,它本身是一份"设计 Agent 的元技能":当你需要创建一个智能体、理解 Agent 架构、或者为业务/研究/运营/创意类任务构建自主系统时,该技能即被触发。
从 SKILL.md 的 frontmatter 可以看到其声明的适用场景:
---
name: agent-builder
description: |
Design and build AI agents for any domain. Use when users:
(1) ask to "create an agent", "build an assistant", or "design an AI system"
(2) want to understand agent architecture, agentic patterns, or autonomous AI
(3) need help with capabilities, subagents, planning, or skill mechanisms
(4) ask about Claude Code, Cursor, or similar agent internals
(5) want to build agents for business, research, creative, or operational tasks
Keywords: agent, assistant, autonomous, workflow, tool use, multi-step, orchestration
---
技能包的目录结构为"文档 + 参考实现 + 脚手架脚本"三件套:
skills/agent-builder/
SKILL.md # 技能主体:哲学 + 设计方法 + 反模式
references/
agent-philosophy.md # 理论深潜:为什么 Agent 是这样工作的
minimal-agent.py # 完整可运行的最小 Agent(~80 行)
tool-templates.py # 能力(工具)定义与实现模板
subagent-pattern.py # 子智能体上下文隔离模式
scripts/
init_agent.py # 生成新 Agent 项目的脚手架
值得注意的是,这份技能本身就是 learn-claude-code 课程教过的"技能按需加载"机制的实例——仓库中 s07_skill_loading 章节(遗留编号见 agents/s05_skill_loading.py 的 SkillLoader 实现)演示了"系统提示只放技能元数据(约 100 token/技能)、正文按需通过 tool_result 注入"的两层加载策略;agent-builder 正是这一机制在"教人设计 Agent"这一主题上的落地。
二、核心哲学:模型已经是智能体,代码只需"让开"
SKILL.md 开篇即给出整份技能的主张:
The model already knows how to be an agent. Your job is to get out of the way.
技能认为,一个 Agent 并不是复杂的工程,而是一个"邀请模型去行动"的简单循环:
LOOP:
Model sees: context + available capabilities
Model decides: act or respond
If act: execute capability, add result, continue
If respond: return to user
"就这样。魔法不在代码里——魔法在模型里。你的代码只是提供了机会。"
这个循环与 learn-claude-code 全课程的"核心模式"完全一致。README 中给出的通用 Agent 模式是:
def agent_loop(messages):
while True:
response = client.messages.create(
model=MODEL, system=SYSTEM,
messages=messages, tools=TOOLS,
)
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 = TOOL_HANDLERSblock.name
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output,
})
messages.append({"role": "user", "content": results})
关键判定就是 stop_reason:只要模型还在请求工具(stop_reason == "tool_use"),就执行工具、把 tool_result 追加回消息列表、继续循环;模型停止调用工具时,循环结束、返回文本。这个实现可以直接在 s01_agent_loop/code.py 中找到,其中 agent_loop 函数(约 L85-L113)只依赖一个 bash 工具就把"一个循环 + 一个工具 = 一个 Agent"跑了起来。
配套的 agent-philosophy.md 把这一哲学扩展为完整的"harness 工程"论述,核心论断包括:
- Agent 是模型,不是代码。 剥掉所有框架和架构模式,剩下的只有"循环 + 模型 + 行动的邀请"。"The code is the harness. The model is the agent. These are not interchangeable."(代码是挽具,模型是智能体,两者不可互换。)
- 提示词管道不是智能。 用 if-else 分支、节点图、硬编码路由把 LLM API 调用串起来,产出的不是 Agent,而是"一个 LLM 被塞进文本补全节点的鲁布·戈德堡机器"。能动性(agency)是被训练出来的,不是被代码编排出来的。
- 挽具的构成公式:
Harness = Tools + Knowledge + Observation + Action Interfaces + Permissions,即工具(Agent 的手)、知识(Agent 的专业领域)、上下文(Agent 的记忆)、权限(Agent 的边界)。 - 约束使能而非限制:"同一时刻只有一个任务 in_progress"强制顺序聚焦,"只读子智能体"防止误改文件——好的约束是防止模型迷路,而不是微观管理它的方法。
- 驾驶舱比喻:模型是驾驶员,挽具是载具。编码 Agent 的载具是 IDE、终端与文件系统;农场 Agent 的载具是传感器、灌溉控制与气象数据。"驾驶员是通用的,载具是专用的"——harness 工程师的工作是为特定领域造最好的车。
三、三要素设计法:能力、知识、上下文
SKILL.md 把一个 Agent 拆解为三个正交要素,每个要素都附带一条明确的设计原则。
3.1 Capabilities(它能做什么)
原子化动作:search、read、create、send、query、modify。
设计原则:从 3-5 个能力起步,只有当 Agent 反复因为"缺少某个能力"而失败时才添加新能力。
这条原则在仓库的参考实现中有精确对应。tool-templates.py 给出了五个可直接复制的能力模板,覆盖绝大多数编码任务:
| 工具 | 作用 | 关键实现要点 |
|---|---|---|
bash |
执行 shell 命令 | 危险命令黑名单、60 秒超时、输出截断到 50KB |
read_file |
读取文件内容 | 工作区内安全路径解析、可选行数上限、50KB 截断 |
write_file |
写文件 | 自动创建父目录、返回写入字节数确认 |
edit_file |
精确文本替换 | 精确匹配(非正则)、只替换第一处、未命中时报错 |
TodoWrite |
维护任务清单 | 每项含 content/status/activeForm,状态枚举 pending/in_progress/completed |
其中 edit_file 的"外科手术式"替换值得注意——tool-templates.py 中 run_edit_file(L225-L246)要求 old_text 必须精确命中,且 content.replace(old_text, new_text, 1) 只替换第一处,避免模型一次性重写整份文件带来的副作用。
每个工具都由"定义 + 实现"两半组成:JSON Schema 定义给模型看(说明它能做什么、参数长什么样),Python 函数负责执行。模板文件最后给出的 dispatcher 模式(L253-L271)把扩展成本压到最低:
def execute_tool(name: str, args: dict) -> str:
"""
Dispatch tool call to implementation.
1. Add definition to TOOLS list
2. Add implementation function
3. Add case to this dispatcher
"""
if name == "bash":
return run_bash(args["command"])
if name == "read_file":
return run_read_file(args["path"], args.get("limit"))
if name == "write_file":
return run_write_file(args["path"], args["content"])
if name == "edit_file":
return run_edit_file(args["path"], args["old_text"], args["new_text"])
return f"Unknown tool: {name}"
安全边界同样内建在能力层:safe_path(L141-L149)用 resolve() + is_relative_to(WORKDIR) 阻止 ../../etc/passwd 式的路径逃逸;run_bash(L152-L180)对 rm -rf /、sudo、shutdown、reboot、> /dev/ 等危险命令直接拦截并返回错误信息而不是抛异常——错误以文本形式回到上下文,让模型自己决定下一步。这套安全策略与课程章节 s03_permission 的"先划边界再给自由"思想一致。
3.2 Knowledge(它知道什么)
按需注入的领域专长:策略文档、工作流、最佳实践、数据模式。
设计原则:让知识"可获取"而非"必加载"——相关时才加载,而不是一开始全量塞进系统提示。
这条原则在仓库中的实证就是 s07 技能加载机制。从 agents/s05_skill_loading.py 的 SkillLoader 类(L59-L104)可以看到两层结构:
- Layer 1(廉价):只把技能名和短描述写进系统提示(约 100 token/技能),例如
- pdf: Process PDF files...; - Layer 2(按需):当模型调用
load_skill("pdf")时,完整技能正文才以tool_result形式返回,包裹在<skill name="pdf">...</skill>中。
"渐进式披露"(progressive disclosure)的价值在于:系统提示保持精简,上下文预算留给真正重要的对话历史——这正是 agent-builder 所说"Load it when relevant, not upfront"的机制化表达。
3.3 Context(发生过什么)
对话历史——把离散动作串成连贯行为的线索。
设计原则:上下文是稀缺资源。把嘈杂的子任务隔离出去,截断冗长输出,保护清晰度。
对应机制在仓库中有两处可查:
- 子智能体隔离:s06_subagent/code.py 中
run_subagent(L257-L293)为子任务开一个全新的messages列表,子智能体最多跑 30 轮,最终只把最后一段文本作为单个 tool_result 交还父对话——探索过程中产生的几十次工具调用不会污染主上下文。 - 输出截断:参考实现中所有工具输出统一截断到 50000 字符(如 minimal-agent.py 的
read_file返回[:50000]),这是对"Truncate verbose outputs"原则的最小实现。
四、构建前的设计思考:五个问题
SKILL.md 要求在动手前先回答五个问题:
- Purpose(目的):这个 Agent 要完成什么?
- Domain(领域):它在哪个世界里运行(客服、研究、运营、创意……)?
- Capabilities(能力):哪 3-5 个动作是必需的?
- Knowledge(知识):它需要访问哪些专长?
- Trust(信任):哪些决策可以下放给模型?
文档特别用 CRITICAL 标注了底线:信任模型,不要过度工程,不要预指定工作流——给它能力,让它自己推理。这与 agent-philosophy.md 中"Trust the Model"一节互为呼应:"不要预先设想要给每种边缘情况都写条件分支,你的条件逻辑会在边缘情况上失败,而模型会推理通过它们。"
五、渐进式复杂度:先跑通 Level 0,再按需升级
SKILL.md 给出的复杂度分级表:
| Level | 添加什么 | 什么时候加 |
|---|---|---|
| Basic | 3-5 个能力 | 永远从这里开始 |
| Planning | 进度跟踪 | 多步任务开始失去连贯性 |
| Subagents | 隔离的子智能体 | 探索过程污染上下文 |
| Skills | 按需知识 | 需要领域专长时 |
并给出一个关键经验判断:大多数 Agent 永远不需要超过 Level 2。
这套分级在脚手架脚本 init_agent.py 中被细化为 0-4 五档,--help 的输出(L259-L266)说明了每档的行数量级:
Levels:
0 Minimal (~50 lines) - Single bash tool, self-recursion for subagents
1 Basic (~200 lines) - 4 core tools: bash, read, write, edit
2 Todo (~300 lines) - + TodoWrite for structured planning
3 Subagent (~450) - + Task tool for context isolation
4 Skills (~550) - + Skill tool for domain expertise
其中 Level 0 的洞见与仓库口号"Bash is all you need"一脉相承:单个 bash 工具就能读(cat/grep/find/ls)、能写(echo > file)、甚至能派生子智能体(python {name}.py "subtask" 自我递归)。这套分级也与 agent-philosophy.md 的 Level 0-5 阶梯一致(从"模型 + 一个工具"到"模型 + 团队 + 自治 + 隔离"),并且与课程章节一一对应:s01 对应单工具循环、s02 对应工具分发表、s05 对应规划、s06 对应子智能体、s07 对应技能加载——技能文件中的渐进式复杂度不是抽象建议,而是课程的实践路线图。
六、领域示例与通用模式
SKILL.md 用四个领域示例说明"模式是通用的,只有能力不同":
- Business(业务):CRM 查询、邮件、日历、审批流
- Research(研究):数据库检索、文档分析、引用
- Operations(运营):监控、工单、通知、升级
- Creative(创意):资产生成、编辑、协作、评审
换领域时你要做的只有两件事:把 TOOLS 列表里的原子动作换成该领域的动作(把 read_file 换成 crm_query、send_email),把技能目录里的知识文档换成该领域的策略与规范。循环本身、消息结构、stop_reason 判定全部不变。
七、六条关键原则与五大反模式
七条设计原则
- 模型就是智能体——代码只是跑循环
- 能力使能——它"能"做什么
- 知识告知——它"知道"怎么做
- 约束聚焦——限制创造清晰度
- 信任解放——让模型推理
- 迭代显形——从最小开始,用真实使用驱动演化
反模式对照表
SKILL.md 最后给出一张可直接对照自检的反模式表:
| Pattern | Problem | Solution |
|---|---|---|
| Over-engineering | Complexity before need | Start simple |
| Too many capabilities | Model confusion | 3-5 to start |
| Rigid workflows | Can't adapt | Let model decide |
| Front-loaded knowledge | Context bloat | Load on-demand |
| Micromanagement | Undercuts intelligence | Trust the model |
值得强调的是"Front-loaded knowledge"这一条:把领域知识全量写进系统提示会挤占上下文预算,让模型在真正干活时"没地方记";解法就是第三节 3.2 小节的按需加载。
八、动手实践一:约 80 行的最小 Agent
references/minimal-agent.py 是技能提供的完整可运行起点,按文件头注释,使用方法只有三步:
# 1. 设置 API key 环境变量
export ANTHROPIC_API_KEY=sk-...
# 2. 运行
python minimal-agent.py
# 3. 输入命令,'q' 退出
配置项(L19-L22)全部走环境变量,可覆盖:
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
MODEL = os.getenv("MODEL_NAME", "claude-sonnet-4-20250514") # 默认模型,可用 MODEL_NAME 覆盖
WORKDIR = Path.cwd()
系统提示刻意保持极简(L25-L30):
SYSTEM = f"""You are a coding agent at {WORKDIR}.
Rules:
- Use tools to complete tasks
- Prefer action over explanation
- Summarize what you did when done"""
工具集只保留三个(bash / read_file / write_file),每个都带完整的 JSON Schema(L33-L64),例如 bash:
{
"name": "bash",
"description": "Run shell command",
"input_schema": {
"type": "object",
"properties": {"command": {"type": "string"}},
"required": ["command"]
}
}
Agent 主循环(L97-L133)展示了最小 Agent 的全部骨架——请求模型、追加 assistant 消息、按 stop_reason 决定继续还是返回、执行工具并回填 tool_result:
def agent(prompt: str, history: list = None) -> str:
"""Run the agent loop."""
if history is None:
history = []
history.append({"role": "user", "content": prompt})
while True:
response = client.messages.create(
model=MODEL,
system=SYSTEM,
messages=history,
tools=TOOLS,
max_tokens=8000,
)
# 追加 assistant 消息
history.append({"role": "assistant", "content": response.content})
# 没有工具调用 -> 返回文本,循环结束
if response.stop_reason != "tool_use":
return "".join(b.text for b in response.content if hasattr(b, "text"))
# 执行工具,结果以 tool_result 回填
results = []
for block in response.content:
if block.type == "tool_use":
output = execute_tool(block.name, block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output
})
history.append({"role": "user", "content": results})
工具执行层(L67-L94)内置了三条保护:bash 60 秒超时、read_file 截断到 50000 字符、所有异常以 Error: ... 文本返回而不是让进程崩溃——保证循环永远不会因为一次工具失败而中断。入口(L136-L148)维护一个跨轮的 history 列表,实现多轮对话。
对照 s01_agent_loop/code.py 可以看到,课程章节版在此基础上增加了 readline 中文输入适配、危险命令黑名单与更规范的退出逻辑,但核心循环完全同构——最小模板与课程实现之间没有架构差异,只有工程加固差异。
九、动手实践二:子智能体模式与上下文隔离
references/subagent-pattern.py 演示了复杂度分级表中 Subagents 一档的实现,核心洞见写在文件头:派生拥有隔离上下文的子智能体,防止探索细节填满主对话("context pollution")。
9.1 Agent 类型注册表
子智能体不是"再开一个一样的 Agent",而是按类型做权限裁剪(L18-L46):
AGENT_TYPES = {
# Explore: 只读,用于搜索和分析
"explore": {
"description": "Read-only agent for exploring code, finding files, searching",
"tools": ["bash", "read_file"], # No write access!
"prompt": "You are an exploration agent. Search and analyze, but NEVER modify files. ...",
},
# Code: 全功能,用于实现
"code": {
"description": "Full agent for implementing features and fixing bugs",
"tools": "*", # All tools
"prompt": "You are a coding agent. Implement the requested changes efficiently. ...",
},
# Plan: 只读,用于设计
"plan": {
"description": "Planning agent for designing implementation strategies",
"tools": ["bash", "read_file"], # Read-only
"prompt": "You are a planning agent. ... Do NOT make any changes.",
},
}
get_tools_for_agent(L57-L71)按 tools 字段做白名单过滤;注释中特别指出:子智能体拿不到 Task 工具本身,从而防止无限递归派生——这是用"能力缺失"实现的递归深度控制。
9.2 Task 工具定义与执行
Task 工具的 Schema(L78-L112)接收 description(3-5 词的进度显示名)、prompt(详细指令)、agent_type(注册表枚举)三个参数;描述文案里直接列出各类型说明和示例用法,帮助父模型判断该派生哪种子智能体。
run_task(L119-L216)的执行要点可以归纳为四条,与课程 s06 章节的实现(s06_subagent/code.py)逐条对应:
- 隔离历史:
sub_messages = [{"role": "user", "content": prompt}]——子智能体从空白开始,看不到父对话; - 过滤工具:只给该类型的白名单工具;
- 专用提示:按类型注入行为约束(如"NEVER modify files");
- 只返回摘要:循环结束后遍历最终响应,只把
text块作为 tool_result 交还父智能体——父对话里只多出一次干净的"任务 + 结论"。
run_task 还内建了进度显示(工具调用次数 + 耗时,\r 原地刷新)与异常兜底(未知类型直接返回错误文本)。把该模式接入主 Agent 只需两步(文件末尾的 USAGE EXAMPLE 给出接法):在 execute_tool 中加 if name == "Task": return run_task(...) 分支,并在 TOOLS 中追加 TASK_TOOL。
十、动手实践三:init_agent.py 项目脚手架
scripts/init_agent.py 把上述方法论打包成一条命令,为任意新 Agent 项目生成初始目录:
python init_agent.py my-agent # Level 1(4 工具,默认)
python init_agent.py my-agent --level 0 # 极简版(只有 bash,~50 行)
python init_agent.py my-agent --level 2 # 声明档位 2(含 TodoWrite 描述)
python init_agent.py my-agent --path ./bots # 指定输出目录
参数(L268-L272):
| 参数 | 说明 | 默认值 |
|---|---|---|
name(位置参数) |
新 Agent 的名称,同时作为文件名 | 必填 |
--level |
复杂度档位,choices 为 0-4 | 1 |
--path |
输出目录 | 当前目录 |
create_agent(L217-L252)会在 <path>/<name>/ 下生成三个文件:
<name>.py—— 按档位填充的 Agent 主程序;.env.example—— API 配置模板:
# API Configuration
ANTHROPIC_API_KEY=sk-xxx
ANTHROPIC_BASE_URL=https://api.anthropic.com
MODEL_NAME=claude-sonnet-4-20250514
.gitignore—— 屏蔽.env、__pycache__/、*.pyc。
脚本随后打印标准后续步骤:cp .env.example .env 填入真实 key → pip install anthropic python-dotenv → python <name>.py。
一个需要说明的实现细节:从源码结构看,TEMPLATES 字典目前只内置了 Level 0 和 Level 1 两套完整模板(L20-L208),--level 2/3/4 会经由 TEMPLATES.get(level, TEMPLATES[1]) 回退生成 Level 1 模板——Level 2(TodoWrite)、3(Task 子智能体)、4(Skill 按需知识)的完整实现需要参照仓库对应课程章节自行补全,脚手架的档位说明(epilog 中的行数标注)更多是演进路线而非开箱即用的模板。Level 1 模板本身已包含全部工程加固:safe_path 路径逃逸防护、危险命令黑名单、50KB 输出截断、60 秒超时,以及四条行为规则("Prefer tools over prose"、"Never invent file paths"、"Make minimal changes"、"After finishing, summarize what changed")。
十一、Agent 思维方式的转变
SKILL.md 以一组对照收尾,这也是整个技能包希望读者完成的心智迁移:
From: "How do I make the system do X?" → To: "How do I enable the model to do X?"("我如何让系统做 X" → "我如何让模型能做 X")
From: "What's the workflow for this task?" → To: "What capabilities would help accomplish this?"("这个任务的工作流是什么" → "哪些能力有助于完成它")
文档最后一句话值得记住:"The best agent code is almost boring. Simple loops. Clear capabilities. Clean context. The magic isn't in the code."(最好的 Agent 代码几乎是无聊的:简单的循环、清晰的能力、干净的上下文,魔法不在代码里。)——给模型能力和知识,信任它能搞定其余的。
十二、资源索引
| 文件 | 内容 |
|---|---|
| SKILL.md | 技能主体:哲学、三要素、设计清单、复杂度分级、反模式 |
| references/agent-philosophy.md | 理论深潜:Agent 是什么/不是什么、挽具五要素、约束使能、驾驶舱比喻 |
| references/minimal-agent.py | 完整可运行的最小 Agent(3 工具 + 循环,~80 行) |
| references/tool-templates.py | bash/read/write/edit/TodoWrite 工具定义、安全实现与 dispatcher 模式 |
| references/subagent-pattern.py | Task 工具、类型注册表与隔离上下文的子智能体执行 |
| scripts/init_agent.py | 新 Agent 项目脚手架(Level 0-4,生成 .env.example 与主程序) |
延伸阅读:s01_agent_loop/code.py(循环本体)、s06_subagent/code.py(子智能体机制)、s07_skill_loading(技能按需加载)、s03_permission(权限边界),以及 README 中关于"Agency Comes from the Model. An Agent Product = Model + Harness"的完整论述。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0625
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00