learn-claude-code第六、七章,子Agent和Skill开源笔记分享
s06 Subagent — 给子任务一份自己干净的上下文一次task调用 一个全新messages[]的嵌套循环结束后只把最终文本作为一条工具结果返回。Harness 层Delegation在独立会话上下文里跑聚焦任务前序s05循环不变一、要解决的问题Agent 修 bug 时要读很多文件追踪调用链每一次工具调用与结果都留在父级messages[]里。链路一旦理解清楚这些中间细节大多不再需要却仍霸占上下文。二、核心机制调用task会同步跑一个嵌套 agent 循环使用全新的messages[]。子循环结束时它的最终文本成为父对话里的一条工具结果。边界定义决策选择原因对话全新messages[]父历史不拷进子代理执行同进程、同WORKDIR文件改动对两边都可见返回值仅最终文本子级工具调用与结果不回灌父消息委派深度SUB_TOOLS不含task本课只允许一层委派工具策略共享 Hooks父/子用同一套权限检查三、关键代码SUB_TOOLSlist(BASE_TOOLS)# 注意不含 taskdefrun_subagent(prompt:str)-str:messages[{role:user,content:prompt}]# 全新上下文for_inrange(30):# 有圈数上限responseclient.messages.create(modelMODEL,systemSUB_SYSTEM,messagesmessages,toolsSUB_TOOLS,max_tokens8000)messages.append({role:assistant,content:response.content})tool_calls[bforbinresponse.contentifb.typetool_use]ifnottool_calls:returnextract_text(response.content)or(no summary)results[{type:tool_result,tool_use_id:b.id,content:execute_tool(b,SUB_HANDLERS)}forbintool_calls]messages.append({role:user,content:results})returnSubagent stopped after 30 turns without a final answer.TOOLS[*BASE_TOOLS,TASK_TOOL]# 父级多一个 task 工具TOOL_HANDLERS{**BASE_HANDLERS,task:run_subagent}四、与 s05 的变化父级工具数 1task子级用SUB_SYSTEM/SUB_TOOLS/ 自己的messages父循环本身不变。五、关键洞察隔离的是消息不是进程/文件系统。父与子同进程、同工作目录写文件和命令仍然作用于同一工作区。子代理是个一次性执行单元跑完即结束只回一句结论。这正是它和 s13 常驻 teammate 的根本区别。子代理结果的中间过程被丢弃只保留最终文本——这就是上下文隔离的价值把噪声挡在父上下文之外。六、一句话总结把会污染上下文的探索过程装进一个独立会话只把结论带回主线。s07 Skill Loading — 知识要按需加载系统提示里只放技能目录真正的SKILL.md由load_skill按需取回。Harness 层Knowledge loading先告诉模型有哪些技能再按名字加载前序s06循环不变一、要解决的问题项目里有 React 组件规范、SQL 风格指南、API 设计文档。最直接的做法是全塞进系统提示SYSTEM(You are a coding agent. open(docs/react-style.md).read()open(docs/sql-style.md).read()open(docs/api-design.md).read())问题是三分文档被永久固化在系统提示里。即使当前只改 React 组件SQL 和 API 文档仍要随着每一次LLM 调用发送白白吃掉 input token 与上下文空间。二、核心机制启动时SkillLoader扫描skills/*/SKILL.md从 YAML frontmatter 读name/description把目录加进系统提示。模型需要完整说明时调load_skill(name)返回的SKILL.md作为一条tool_result追加进消息列表。内容去向何时技能名 描述系统提示启动时完整SKILL.mdtool_result调用load_skill时三、关键代码classSkillLoader:defscan(self):self.skills.clear()formanifestinsorted(self.skills_dir.glob(*/SKILL.md)):contentmanifest.read_text(encodingutf-8)metadata,bodyself.parse_frontmatter(content)name(metadata.get(name)ormanifest.parent.name).strip()descself.normalize(metadata.get(description)orbody.split(\n,1)[0])self.skills[name]{name:name,description:desc,content:content}defcatalog(self):# 只返回 名字: 描述return\n.join(f-{k}:{v[description]}fork,vinself.skills.items())defload(self,name):# 按名字查注册表不当路径处理returnself.skills.get(name,{}).get(content)orfError: Unknown skill {name}defbuild_system_prompt():return(fYou are a coding agent at{WORKDIR}...\n\nfSkills available:\n{SKILL_LOADER.catalog()}\n\nUse load_skill to read the full instructions when a skill applies.)四、与 s06 的变化系统提示从固定文本变成运行期拼装固定说明 启动时扫描到的技能目录。工具池 1load_skill。五、关键洞察渐进式披露progressive disclosure先给索引需要时再取全文——这正是 s09 记忆系统复用的读取范式。技能是人类手写、只读的记忆s09则是 Agent 从对话中提取、可写的。二者共享目录 按需加载的模式但来源不同。name只用于查启动时的注册表不会被解释成文件路径——天然避免路径穿越。六、一句话总结把知识从系统提示里搬出来改成目录常驻、正文按需加载用一次工具调用换取上下文空间的节省。