mini-coding-agent源码解析(六):有界子Agent委派,只读受限的delegate工具设计思路

发布时间:2026/10/14 19:52:06

mini-coding-agent源码解析(六):有界子Agent委派,只读受限的delegate工具设计思路 【免费下载链接】mini-coding-agentMinimal and readable coding agent harness implementation in Python to explain the core components of coding agents.项目地址https://gitcode.com/gh_mirrors/mi/mini-coding-agent点击查看免费下载在mini-coding-agent的六大核心组件中第六个组件是委派与有界子AgentDelegation And Bounded Subagents。它通过一个名为delegate的工具让主 Agent 把耗时的调查类子任务交给一个只读、有步数上限的子 Agent 去执行既扩展了主 Agent 的探索能力又严格限制了子 Agent 的权限边界。本文带你读懂 mini_coding_agent.py 中tool_delegate的完整设计思路。为什么 Coding Agent 需要委派能力想象你让 Agent 排查一个跨文件的问题为什么这个函数在某个输入下返回异常这类任务可能需要读 5~10 个文件多轮搜索关键字逐步缩小排查范围如果全部由主 Agent 完成这些工具调用和输出会全部挤进主会话的历史很快把上下文撑爆。委派delegation的思路是把这些跑腿式的调查工作外包给一个临时子 Agent子 Agent 独立跑完只返回一份浓缩的结论主 Agent 的上下文只多出一条delegate_result。这就是有界bounded的含义子 Agent 不是全能的它被锁在深度、权限、步数三道栅栏之内。delegate 工具如何被条件注册delegate工具并非无条件存在。在 build_tools 的末尾有这样一段判断if self.depth self.max_depth: tools[delegate] { schema: {task: str, max_steps: int3}, risky: False, description: Ask a bounded read-only child agent to investigate., run: self.tool_delegate, }mini_coding_agent.py 的这段逻辑很巧妙只有当当前 Agent 的depth小于max_depth时才把 delegate 注入工具表。也就是说顶层 Agent 构造时默认 depth0, max_depth1因此它拥有 delegate 工具子 Agent 构造时depthself.depth 1恰好等于max_depth它根本看不到 delegate 这个工具从源头上杜绝了子 Agent 再套娃的无限递归委派。工具本身只有两个参数task子任务描述必填和max_steps子 Agent 最多可用的步数默认 3。risky标记为False因为委派本身不直接修改任何东西——真正的安全约束写在下一节的栅栏里。tool_delegate 的三道安全栅栏核心实现位于 tool_delegatedef tool_delegate(self, args): if self.depth self.max_depth: raise ValueError(delegate depth exceeded) task str(args.get(task, )).strip() if not task: raise ValueError(task must not be empty) child MiniAgent( model_clientself.model_client, workspaceself.workspace, session_storeself.session_store, approval_policynever, max_stepsint(args.get(max_steps, 3)), max_new_tokensself.max_new_tokens, depthself.depth 1, max_depthself.max_depth, read_onlyTrue, ) child.session[memory][task] task child.session[memory][notes] [clip(self.history_text(), 300)] return delegate_result:\n child.ask(task)虽然代码不长但信息密度极高。逐条拆解栅栏一深度检查depth / max_depth入口处的if self.depth self.max_depth是最后一道保险。虽然条件注册已经保证只有depth max_depth的 Agent 才拥有该工具但 validate_tool 中对delegate的校验也重复了同一检查并在越界时抛出delegate depth exceeded。注册层 校验层双重检查任何路径都无法突破深度上限。栅栏二read_onlyTrue只读锁子 Agent 被显式标记为read_onlyTrue。它的效果体现在 approve 方法的第一行def approve(self, name, args): if self.read_only: return Falseread_only会让所有 risky 工具的审批直接返回 False。由于 run_tool 在高风险工具执行前强制走approve关卡子 Agent 即便想调用write_file、patch_file或run_shell也会在审批环节被拒绝。于是子 Agent 在物理上只能使用list_files、read_file、search这类安全的只读工具——这正是标题中只读受限四个字的由来。栅栏三approval_policynever审批策略兜底read_only已经拒绝了 risky 工具approval_policynever是双保险即使未来某次修改遗漏了read_only分支never策略也会让 approve 对所有审批返回False。更值得注意的是子 Agent 的approval_policy被硬编码为never不会继承父 Agent 的策略——即使你在命令行用--approval auto启动了主 Agent自动批准所有危险操作委派出去的子 Agent 依然是只读的。父级信任模型不代表信任模型派生出的子代理这一细节体现了权限设计上最小授权的原则。步数预算max_steps 控制子 Agent 的体力子 Agent 的max_steps直接取自调用参数默认 3并沿depthself.depth 1向下传递。回顾 ask 的主循环while tool_steps self.max_steps意味着子 Agent 最多只能发起 3 次工具调用就必须给出最终答案超时会返回Stopped after reaching the step limit without a final answer.。这一步数预算的作用限制 token 消耗子 Agent 每次模型调用都独立计费3 步是够用但不浪费的默认值防止跑偏调查任务如果 3 步还没结果说明子任务定义可能有问题早停比死磕更划算父级可调主 Agent 委派时可以根据任务复杂度主动传max_steps: 2或更大的值把预算分配权交给最需要判断的主体。上下文交接子 Agent 带着什么信息出发子 Agent 是全新构造的MiniAgent实例历史是空的。如果什么都不给它就像蒙着眼睛进仓库。tool_delegate用两行代码完成交接child.session[memory][task] task child.session[memory][notes] [clip(self.history_text(), 300)]memory[task] task把委派任务写入子 Agent 的工作记忆后续 memory_text 会将其渲染进提示词让子 Agent 始终知道我为什么在这里memory[notes] [clip(self.history_text(), 300)]把父 Agent **当前历史的压缩摘要裁剪到 300 字符**塞进子 Agent 的 notes。这样子的子 Agent 虽然看不到父级的完整对话但能大致了解排查背景避免从零开始乱撞。注意这里刻意只传 300 字符委派的本意就是隔离上下文如果父级的完整历史灌进去委派就失去了节省上下文的意义。这是足够信息与上下文隔离之间的精妙折中。另外子 Agent 复用了父级的model_client、workspace和session_store意味着它操作的是同一个工作区快照、调用同一个 Ollama 模型并且它的会话 JSON 也会照常落盘到 .mini-coding-agent/sessions/事后可以完整追溯子 Agent 干过什么。结果回传一条 delegate_result 就够了子 Agent 跑完后tool_delegate只返回一行结构化结果delegate_result: 子 Agent 的最终答案这个返回值作为普通工具输出记录进父 Agent 的历史父 Agent 在下一轮模型调用中读取它并整合进最终答案。由于子 Agent 的输出本身被 ask 约束为简洁结论、工具输出又被clip截断默认 MAX_TOOL_OUTPUT 4000父级的上下文增量被控制得很小。官方测试 test_delegate_uses_child_agent 完整验证了这条链路父 Agent 先发出 delegate 工具调用子 Agent由FakeModelClient喂给的答案返回结果父 Agent 将结果写进delegate_result工具记录最终输出整合后的答案。一张表看懂 delegate 的约束全景约束维度机制代码位置递归深度depth max_depth才注册工具构造时depth1L321-L327、L860越界校验双重检查越界抛delegate depth exceededL594-L600、L848-L849只读权限read_onlyTrue使approve恒返回 FalseL862、L602-L604审批兜底approval_policynever硬编码不继承父级L857、L607-L608步数预算max_steps默认 3超步即停L858、L455上下文隔离仅传 300 字符历史摘要 任务文本L864-L865小结有界委派的三个设计要点读完tool_delegate可以提炼出 mini-coding-agent 委派设计的三条通用原则对你自己设计多 Agent 系统同样有参考价值能力从结构上剥夺而不是从提示词上请求。子 Agent 不是被要求不要写文件而是通过read_onlynever策略在机制上无法写文件。依赖模型自觉的安全设计都是脆弱的。递归必须有界。depth/max_depth的组合让能否再委派成为构造期就确定的事实子 Agent 的工具表里压根没有 delegate比运行时拒绝更干净。上下文按需交接。只传任务文本 300 字符摘要既给了子 Agent 足够的背景又保住了委派最核心的价值——把冗长的调查过程关在子上下文里只让结论上浮。至此mini-coding-agent 六大核心组件已全部解析完毕实时仓库上下文、提示词结构与缓存复用、结构化工具与权限、上下文缩减与输出管理、转录记忆与断点续传、有界子 Agent 委派。整个项目仅一个 mini_coding_agent.py约千行想动手复现一个最小 coding agent 的同学可以从 EXAMPLE.md 的完整交互示例开始上手。赞分享【免费下载链接】mini-coding-agentMinimal and readable coding agent harness implementation in Python to explain the core components of coding agents.项目地址https://gitcode.com/gh_mirrors/mi/mini-coding-agent点击查看免费下载相关推荐Caveman 探索与委派机制详解Explorer、Cavecrew 子代理与 Delegate 工具的上下文隔离设计Caveman 探索与委派机制详解Explorer、Cavecrew 子代理与 Delegate 工具的上下文隔离设计 在 Caveman一个通过压缩 to人工智能AI 应用AI 技能AI 插件LLMOps开发工具AI-Coding-Guide-Zh Subagent教程子代理协作、任务委派与Agent团队AI Coding Guide Zh Subagent教程子代理协作、任务委派与Agent团队 在 AI Coding Guide Zh 这套中文教程中 S文档教程Claude Security 插件源码解读explore 只读代码探查 Agent 的设计与实战Claude Security 插件源码解读explore 只读代码探查 Agent 的设计与实战 claude plugins official 仓库中的AI 插件开发工具插件系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/14 19:52:06

Java多线程文件压缩实战:线程池与CountDownLatch性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 19:52:06

基于STM32的空气质量监测系统:传感器选型、采集与校准实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 19:52:06

DGX Spark本地部署Hermes:Token物理账本与KV Cache优化实战

把一台DGX Spark抱回家后,我第一件事就是往上面部署Hermes系列的开源私有大模型。原因很简单:数据不出门、离线能跑、不用按token计费,听起来像是一劳永逸。可真的折腾下来才意识到,本地部署并没有把“token成本”消灭&#xff0c…

2026/10/14 23:41:09

从工具调用到Code Mode:AI Agent范式转移与工程实践

1. 从「工具调用」到「Code Mode」:一场正在发生的 Agent 范式转移过去一年多,我一直在做 AI Agent 相关的落地项目,从最早的 Function Calling 到后来的多工具编排,踩过的坑可以说能写满一个笔记本。但最近半年,一个明…

2026/10/14 23:41:09

PS5串流全攻略:从局域网配置到延迟调优,让主机走出客厅

1. 项目设想:一台 PS5,凭什么只能待在客厅1.1 当游戏机被电视“独占”时的痛点很多有 PS5 的家庭都会遇到类似的尴尬:主机明明摆在客厅,电视却不一定永远属于你。家里人要看综艺、小孩要上网课、长辈要投屏刷剧,这时候…

2026/10/14 23:41:09

零基础80天PMP备考复盘:逆向思维与笨方法如何拿下3A

拿到成绩那天,屏幕上跳出三个 Above Target,我心里其实没有太多意外。并不是我多有把握,而是这80天里每一天做了什么、做得对不对,我自己清楚得很。这篇不是来炫耀分数的,是想把一套“零基础 80天 笨方法”的组合拳完…

2026/10/14 23:41:09

Libtorch部署实战:从模型导出到C++高性能推理的完整指南

在深度学习落地这条路上,我折腾过不少推理框架,但最后上生产环境时,Libtorch是我最常用的选择之一。很多人觉得Libtorch部署是个“高大上”的事,其实说白了就是把PyTorch训练好的模型,从Python环境搬到C环境里跑起来。…

2026/10/14 23:41:09

个人AI Agent架构实战:记忆层、权限机制与跨应用编排设计

你可能见过不少号称“AI 助理”的产品,打开一看就是个问答盒子,能陪你聊天、能写点文案,但真要让它“替我办成一件事”,它既记不住你上周交代过的偏好,也不敢碰你的日历、邮件和通讯录。这种产品本质上还是聊天界面&am…

2026/10/14 23:36:07

Redis从安装到实战:配置、数据结构与缓存问题排查全攻略

先问自己一个问题:有没有遇到过这样的场景——线上接口突然变慢,数据库CPU飙高,用户反馈页面打不开,重启服务后过几分钟又被打爆;或者明明是同一个数据,每次请求都要去数据库查一遍,白白浪费了连…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/14 2:32:55

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑