从零实现 GeekAgent —— Day11 技能系统(Skills)
内容提要
本文介绍GeekAgent项目第11天实现技能系统(Skills)。技能将任务指令和工具组合成目录,通过/use加载、/unuse卸载,同一时间只激活一个技能。与AGENTS.md长期项目指令不同,技能按任务切换,可增加或筛选工具,如code-review技能自带git_diff,explore技能仅保留只读工具。实现包括skills.ts加载、tools.ts可见性控制、权限补充及命令接入。
延伸解读
技能与项目指令的分工
技能系统与AGENTS.md的核心区别在于作用范围和生效方式。AGENTS.md是项目级长期规则,每轮请求都会加载,但不改变工具列表;技能则按任务切换,通过/use和/unuse控制,可以增加或筛选工具。例如,explore技能只暴露只读工具,从机制上防止模型修改文件,而AGENTS.md中的文字约束无法做到这一点。这种设计让项目指令保持精简,避免无关内容占用上下文。
工具可见性的实现机制
技能通过setVisibleTools和toOpenAITools控制模型可见的工具列表。visibleTools为null时,所有内置工具可见;技能激活时,只发送白名单内的工具。这种过滤发生在工具发送给模型之前,确保模型无法调用未列出的工具。技能自带工具通过registerTool注册,卸载时用unregisterTool移除,保证状态干净。权限层默认对技能工具使用ask策略,用户可在配置中改为allow。
当前实现的局限与扩展方向
文章明确列出未实现的功能:一次只能加载一个技能、技能不随会话保存、没有独立权限配置。这些限制简化了实现,但实际应用中可能需要多技能组合或持久化。此外,技能加载采用一次性读取SKILL.md和tools.ts,而成熟的技能系统会渐进式加载,先显示简介再按需加载完整内容,以节省上下文。后续可考虑自动选择技能或支持更多资源类型。
Q&A
GeekAgent的技能系统是什么?
GeekAgent的技能系统是一种将任务指令和工具组合成目录的机制,通过/use加载、/unuse卸载,同一时间只激活一个技能。它允许根据任务切换指令和工具,例如code-review技能自带git_diff工具,explore技能只保留只读工具。
技能系统与AGENTS.md有什么区别?
AGENTS.md是项目长期指令,每轮请求都加载,不改变工具列表;技能系统是当前任务的指令和工具,通过/use加载、/unuse卸载,可以增加或筛选工具。例如,AGENTS.md中写“只读代码”只是行为要求,模型仍能看到修改工具;而加载explore技能后,模型只能看到ls、glob和read三个只读工具。
为什么需要技能系统?
因为不同任务需要不同的工具。例如代码审查需要先看diff,只读浏览只需要查看目录和文件。如果把这些要求都写进AGENTS.md,项目指令会越来越长,模型每轮都要读取与当前任务无关的内容。技能系统按任务拆开,加载代码审查技能时增加git_diff,加载只读技能时只提供三个只读工具。
技能系统是如何实现的?
实现包括:skills.ts负责加载和卸载技能,解析SKILL.md;tools.ts控制工具可见性,通过setVisibleTools和toOpenAITools过滤工具;permissions.ts为技能自带工具补充默认权限(ask);chat.ts将技能指令拼入system prompt;index.ts接入命令和面板。
技能系统如何控制工具可见性?
通过setVisibleTools设置可见工具名单,toOpenAITools在发送给模型前过滤工具。没有加载技能时,visibleTools为null,所有内置工具可见;加载技能后,只返回名单中的工具。例如explore技能只保留ls、glob、read,模型就看不到其他工具。
技能系统有哪些限制?
限制包括:一次只能加载一个技能;当前技能不会随会话保存;技能没有独立的权限配置。
如何验证技能系统是否正常工作?
验证步骤:运行npm run typecheck和npm run dev -- day11/index.ts;输入/skills确认能看到code-review和explore;输入/use code-review让模型审查未提交改动,确认能调用git_diff;输入/use explore让模型执行shell,确认只能使用三个只读工具;输入/unuse确认面板恢复为“技能 无”。