核心内容摘要
StructBERT模型轻量化:知识蒸馏与量化联合优化
❝该系列文章基于github.com/shareAI-lab/learn-claude-code写就该仓库以大道至简的风格剖析了Claude Code的核心原理值得大家学习。
由于该仓库是基于Python语言为方便.NET开发者学习我已经将代码基于.NET 10的dotnet file重写源码已上传至github源码地址见文末。
v3: 子代理机制 - 上下文隔离的艺术❝本文是 Learn Claude Code (C# 版) 系列的
对应代码文件v3_subagent.cs。
问题上下文污染v2 添加了规划能力。
但对于大型任务You: 探索代码库的架构然后重构 auth 模块单 Agent 的执行过程[探索中...] cat src/Services/AuthService.cs - 500 行 [探索中...] cat src/Models/User.cs - 300 行 [探索中...] cat src/Controllers/AuthController.cs - 400 行 ... 15 个文件后 ... [现在重构...] 等等AuthService 里那个方法签名是什么来着模型的上下文被探索细节填满了。
当真正开始重构时关键代码片段已经滚出上下文窗口模型需要重新读取文件效率低下成本增加这就是上下文污染——前置任务的输出污染了后续任务的工作空间。
解决方案子代理主 Agent 历史: [Task: 探索代码库] - 子代理探索 20 个文件在自己的上下文中 - 只返回: Auth 在 src/Services/AuthService.cs依赖 User, Token 模型... [现在用干净上下文重构]进程隔离 上下文隔离每个子代理有自己的干净消息历史过滤后的工具集专门的系统提示只向父代理返回最终摘要Agent 类型注册表record AgentConfig(string Description, string[] Tools, string Prompt); var agentTypes new Dictionarystring, AgentConfig { [explore] new( 只读代理用于探索代码、查找文件、搜索, [bash, read_file], // 没有写权限 你是一个探索代理。
搜索和分析但不要修改文件。
返回简洁的摘要。
), [code] new( 完整代理用于实现功能和修复 bug, [*], // 所有工具 你是一个编程代理。
高效地实现请求的更改。
), [plan] new( 规划代理用于设计实现策略, [bash, read_file], // 只读 你是一个规划代理。
分析代码库并输出编号的实现计划。
不要做更改。
) };类型工具用途explorebash, read_file安全探索不会意外修改code全部实际实现planbash, read_file设计方案不执行Task 工具定义var taskTool new Tool { Name Task, Description $ 为专注的子任务生成子代理。
子代理在隔离上下文中运行 - 它们看不到父代理的历史。
用这个来保持主对话干净。
Agent 类型: - explore: 只读探索 - code: 完整实现 - plan: 设计策略 示例: - Task(explore): 查找所有使用 auth 模块的文件 - Task(plan): 设计数据库迁移策略 - Task(code): 实现用户注册表单 , InputSchema new InputSchema { Type object, Properties new Dictionarystring, JsonElement { [description] ..., // 简短描述
词 [prompt] ..., // 详细指令 [agent_type] ... // explore | code | plan }, Required [description, prompt, agent_type] } };子代理执行核心async Taskstring RunTaskAsync(string description, string prompt, string agentType) { var config agentTypes[agentType]; //
专门的系统提示 var subSystem $ 你是一个位于 {workDir} 的 {agentType} 子代理。
{config.Prompt} 完成任务并返回清晰简洁的摘要。
; //
过滤后的工具集 var subTools GetToolsForAgent(agentType); //
关键隔离的消息历史 var subMessages new ListMessage { prompt.AsUserMessage() }; //
运行相同的 Agent 循环 while (true) { var response await client.CreateMessageAsync( modelId, subMessages, new MessageParameters { System subSystem, Tools subTools }); if (response.StopReason ! StopReason.ToolUse) { //
只返回最终文本 return ExtractText(response); } // 执行工具添加结果... } }关键点隔离的subMessages- 不包含父代理的历史过滤的工具- explore 不能写文件专门的系统提示- 引导子代理行为只返回摘要- 父代理不看中间细节进度显示Console.WriteLine($ [{agentType}] {description}); var start DateTime.Now; var toolCount 0; // 执行中... Console.Write($\r [{agentType}] {description} ... {toolCount} tools, {elapsed:F1}s); // 完成 Console.WriteLine($\r [{agentType}] {description} - done ({toolCount} tools, {elapsed:F1}s));输出效果 Task: 探索 auth 架构 [explore] 探索 auth 架构 ... 5 tools,
3s [explore] 探索 auth 架构 - done (8 tools,
1s)用户看到子代理在工作但不会被中间输出淹没。
典型工作流程You: 重构 auth 模块使用 JWT 让我先了解现有架构 Task: 探索 auth 架构 [explore] 探索 auth 架构 - done (12 tools,
2s) 摘要Auth 模块位于 src/Services/AuthService.cs使用 Session 认证。
依赖User 模型、TokenRepository。
主要方法Login(), Logout(), ValidateToken()。
接下来设计迁移方案 Task: 设计 JWT 迁移 [plan] 设计 JWT 迁移 - done (5 tools,
1s) 迁移计划
添加 JWT 依赖包
创建 JwtService 类
修改 AuthService 使用 JwtService
更新 TokenRepository
添加配置项 现在执行实现 Task: 实现 JWT 认证 [code] 实现 JWT 认证 - done (15 tools,
1
3s) 完成创建了 JwtService.cs修改了 AuthService.cs 更新了 appsettings.json添加了 3 个单元测试。
任务完成主要改动 - 新增 JwtService 处理 token 生成和验证 - AuthService 现在使用 JwtService 而非 Session - 配置文件新增 Jwt 配置节深层洞察分治策略子代理本质上是分治法的应用分把大任务分解为独立子任务治每个子代理独立解决其任务合父代理整合子代理的摘要上下文是稀缺资源Claude 的上下文窗口有限128K-200K tokens。
如何使用这个有限资源策略效果全部放主 Agent快速溢出早期信息丢失子代理隔离主 Agent 保持干净按需获取摘要子代理是上下文管理的工具。
工具权限控制为什么 explore 不能写文件安全- 探索时意外修改很危险专注- 强制子代理只做一件事可预测- 你知道 explore 任务不会产生副作用这是最小权限原则的应用。
v0 的递归 vs v3 的子代理v0 用 bash 调用自身实现子代理dotnet run v0_bash_agent.cs 探索 src/v3 用显式的 Task 工具Task(explore, 探索 src/)区别v0 更纯粹——一切通过 bashv3 更可控——明确的类型和权限防止无限递归注意 v3 的设计ListTool GetToolsForAgent(string agentType) { var allowed agentTypes[agentType].Tools; if (allowed.Contains(*)) return baseTools; // 不包括 Task 工具 return baseTools.Where(t allowed.Contains(t.Name)).ToList(); }子代理没有Task工具——不能再生成子代理。
这防止了无限递归。
生产系统可能允许有限深度的嵌套但需要仔细控制。
运行示例Mini Claude Code v3 (with Subagents) - /path/to/project Agent 类型: explore, code, plan 输入 exit 退出。
You: 分析这个项目的架构并给出改进建议 让我先探索项目结构 Task: 分析项目结构 [explore] 分析项目结构 - done (8 tools,
5s) 项目是一个 ASP.NET Core Web API - Controllers/: 3 个控制器 - Services/: 5 个服务类 - Models/: 8 个模型 - Data/: EF Core DbContext 潜在问题Services 直接使用 DbContext没有 Repository 层。
接下来让我设计改进方案 Task: 设计 Repository 模式 [plan] 设计 Repository 模式 - done (4 tools,
1s) 改进计划
创建 IRepositoryT 接口
实现 GenericRepositoryT
为每个实体创建具体 Repository
修改 Services 使用 Repository 而非 DbContext
更新 DI 配置 基于分析我的改进建议是
引入 Repository 层分离数据访问
Services 应该依赖接口而非实现
考虑添加 Unit of Work 模式管理事务 需要我实现这些改进吗从 v3 到 v4v3 解决了上下文隔离问题。
但还有一个挑战You: 处理这个 PDF 文件 You: 构建一个 MCP 服务器模型怎么知道处理 PDF 应该用pdftotext还是PyMuPDFMCP 服务器需要什么协议规范这些是领域知识不是工具能力。
v4 将引入Skills 机制——按需加载专业知识。
总结v3 的哲学❝分而治之上下文隔离。
干净上下文 更好结果。
子代理不是新概念但用得好能显著提升 Agent 的能力边界。
关键是理解上下文是稀缺资源需要精心管理。
点击阅读原文获取仓库地址