简介:本文围绕“子代理”与“技能包(Skills)”两类智能体扩展机制展开对比,先厘清常驻说明文件、手动触发命令、独立上下文子代理与按需能力包四者的边界,再从上下文隔离、触发方式、工具权限、复用性与维护成本等维度系统分析差异,并给出代码审查、测试排查等典型场景的选型建议与落地注意事项。
在长期使用代码智能助手类工具的过程中,开发者往往会遇到两类典型问题。
第一类是上下文膨胀。对话越聊越长,翻阅过的大文件、执行过的长输出、反复试错的中间结果全部堆积在同一段对话里。随着上下文窗口被逐渐填满,模型的响应会变得迟钝,早期关键信息也容易被淹没。第二类是角色混杂。同一个对话里,模型刚写完代码,转头又被要求充当审查者,自己审自己,难免出现“放水”;或者刚完成实现,又被要求排查测试失败原因,视角切换不彻底,定位效率下降。
这两类问题的共同根源,是所有工作都挤在同一个容器里完成。解决思路是让不同的活拥有不同的“容器”:把长耗时、高噪声、需要独立视角的任务隔离出去,只在主对话中保留结论。
在落地层面,常见的扩展机制可以归纳为四类,它们最容易被混淆:
| 机制 | 定位 | 触发方式 | 上下文 |
|---|---|---|---|
| 常驻说明文件 | 项目级说明书,描述规范、约定与背景 | 每次会话自动读取 | 与主对话共享 |
| 手动触发命令 | 预置的提示词模板 | 由使用者显式调用 | 与主对话共享 |
| 子代理 | 独立上下文的专职助手 | 可主动委派,也可显式指定 | 独立窗口,仅回传结论 |
| 技能包 | 按需加载的能力封装 | 由模型按任务需要自动调用 | 按需注入,粒度可控 |
本文的对比对象,就是其中最容易讲不清的两类:子代理与技能包。前者强调“独立工位、独立视角、只交结论”,后者强调“一个目录、一份说明、按需取用”。二者并非替代关系,而是在上下文管理策略上走向了两个不同方向。
子代理可以理解为“主对话请来的专门助手”。它拥有自己的上下文窗口,可以限定可用的工具集合,任务完成后只把结论带回主对话,过程中的大量中间细节不会挤占主对话的上下文空间。
一个典型的子代理定义文件包含三部分:元信息(名称、描述、可用工具)、角色设定、工作流程。示意性结构如下:
---name: 角色名称description: 什么时候使用这个子代理(关键:写清触发时机)tools: 只读工具集合---你是……(角色设定)工作方式:1. ……2. ……输出格式:- 分级结论- 每条注明文件与行号
其中三个细节值得特别注意:
技能包是另一种思路:把某类任务所需的知识、步骤、模板、脚本封装在一个目录中,附一份说明文件描述“这个能力是什么、什么时候用、怎么用”。主对话在处理任务时,按需加载对应技能包的内容,用完即走,不长期占用上下文。
它的核心特征是粒度可控与复用性强:一个技能包可以描述一套固定流程(例如某类文档的生成规范、某类配置的校验步骤),在多个不同任务中被反复调用,而不需要每次都重新描述一遍要求。技能包本身不必然拥有独立上下文窗口,它的价值在于“把可复用的能力沉淀下来,按需注入”。
子代理解决的是“这件事不该在主对话里干”——它要的是隔离;技能包解决的是“这套做法不该每次重讲”——它要的是复用。前者是上下文的分区,后者是能力的沉淀。
尽管定位不同,二者在以下方面高度一致:
这是最本质的差异。子代理拥有独立上下文窗口,过程性内容(大量文件读取、长输出、多轮试错)被隔离在子上下文内,主对话只接收最终结论。这带来两个好处:主对话的上下文增长被显著抑制;子代理可以在自己的窗口内“放开手脚”读取大量材料而不污染主线。
技能包则通常是按需注入主上下文,加载的内容会进入当前对话。它的优势是信息连贯、无需跨窗口传递,但如果技能包内容本身较长,仍会占用主对话空间。因此技能包更适合“内容精炼、流程固定”的能力封装,而不适合承载大量探索性读取。
子代理支持两种触发:由模型根据描述主动委派,或由使用者显式指定。前者适合“改完一段代码自动触发审查”这类自然衔接;后者适合需要明确控制的场合。
技能包以按需自动调用为主,模型根据任务特征判断是否加载。它的调度更轻量,但也更依赖描述质量——描述不清时,容易出现该用不用、或用错场景的问题。
子代理可以限定工具集合,这是它的一大优势。审查类子代理只给只读工具,从机制上保证“想改也改不了”;排查类子代理可以给读取、检索与受控执行能力,但禁止修改测试文件。权限边界是声明式的,可审计。
技能包本身不直接改变工具权限,它更多是“知识与流程”的封装。若需要权限约束,仍需依赖外层机制。因此在需要强边界的场景(如审查、合规检查),子代理的机制更直接。
技能包的复用性更强:同一套流程可被多个任务、多个角色反复调用,且易于版本化管理与团队共享。它天然适合沉淀“团队共识的做法”。
子代理的复用体现在“角色可反复召唤”,但每个子代理通常对应一个较完整的角色设定,粒度较粗,组合灵活性不如技能包。多个子代理之间的编排需要主对话协调,成本略高。
子代理的调试相对直观:输入明确、输出结构化、过程可回看,出问题容易定位是描述不清还是工具不足。但子代理数量增多后,委派决策会变复杂,需要维护描述之间的边界,避免职责重叠。
技能包的维护集中在内容准确性上:流程写错、示例过时都会直接导致错误输出,且因为注入主上下文,出错时影响面更直接。版本管理要求更高。
子代理的输出强调收敛与分级:按严重级别给结论、每条注明文件与行号、没有问题就直说没有。这种形态适合“审查、排查、评估”类任务。
技能包的输出强调可执行产物:生成的文档、校验结果、配置片段。它更适合“生产型”任务,而非“判断型”任务。
| 对比维度 | 子代理 | 技能包 |
|---|---|---|
| 上下文 | 独立窗口,仅回传结论 | 按需注入主上下文 |
| 触发方式 | 主动委派 + 显式指定 | 按需自动调用 |
| 工具权限 | 可声明式限定 | 不直接控制 |
| 复用粒度 | 角色级,粒度较粗 | 能力级,粒度较细 |
| 组合灵活性 | 需主对话编排 | 易于多任务复用 |
| 输出形态 | 分级结论、定位信息 | 可执行产物 |
| 调试重点 | 委派边界与描述清晰度 | 内容准确性与版本管理 |
| 典型用途 | 审查、排查、评估 | 生成、校验、流程固化 |
审查任务有三个特征:需要读取大量改动与相关文件、需要独立视角避免“自己审自己”、绝对不能顺手改代码。这三点正好对应子代理的三项能力:独立上下文、角色隔离、工具白名单。
落地时,子代理的定义应包含:只读工具集合;描述中写明“在完成功能或修复后使用,主动使用”;正文写明“先查看本次改动,再按需读取相关文件;只审查不修改;按严重级别输出必须修复、建议、可选三类,每条注明文件与行号;没有问题就直说没有”。
这里的关键设计是分级输出:把“安全漏洞、逻辑错误、数据丢失风险”列为必须修复,把“边界条件、错误处理、明显性能问题”列为建议,把“命名、重复代码”列为可选。分级让结论可直接转化为行动优先级,而不是一堆平铺的意见。
测试挂掉时最烦的是报错一大屏、改哪儿都不确定。排查任务的难点在于区分原因类型:是代码有 bug、测试已过时,还是环境有问题。这三类原因的处置方式完全不同。
子代理在此处的价值是先把原因定下来,再给最小修复建议。定义中应写明流程:先复现失败,再用检索定位相关代码,区分三种情况,给出最小改动建议;禁止修改测试来迁就代码,若认为测试本身有误,需说明理由,由主对话决定。
最后一条约束尤为重要。排查类任务最容易出现的偏差,是让测试迁就实现,把问题“改没了”而不是“改对了”。把这条禁令写进角色规则,比事后纠偏更有效。
如果需求是“把某类文档的生成规范、某类配置的校验步骤统一起来,供多人多次使用”,那么技能包更合适。这类任务的特征是:流程固定、内容可复用、不需要独立视角、也不需要隔离大量探索性读取。
技能包的价值在于把“每次都讲一遍的要求”变成“一次写好、按需加载”的沉淀物。它适合内容精炼、边界清晰的流程,而不适合承载需要大量试错与文件遍历的探索型任务——后者交给子代理更稳妥。
不做绝对化推荐,给出可操作的判断路径:
从“全部在主对话完成”迁移到“分容器执行”,需要注意以下几点:
子代理与技能包的分野,本质上是对“上下文”这一稀缺资源的两种管理策略:子代理做分区,技能包做沉淀。前者用独立窗口换取视角独立与噪声隔离,代价是跨窗口的协调与额外调用;后者用按需加载换取复用性与一致性,代价是对主上下文的占用与更高的内容准确性要求。
选型时回到三个问题即可:这件事是否需要独立视角?是否会产生大量过程性内容?这套做法是否需要被反复使用?前两个问题指向子代理,第三个问题指向技能包。二者不是二选一,而是可以按任务阶段组合使用——把探索与判断交给独立助手,把稳定流程沉淀为可复用能力包,让主对话专注于推进,而不是承载一切。