Kimi Code CLI 统一 Skills 发现机制(KLIP-8)深度解析:分层合并、目录查找与跨工具兼容
2026/9/15 20:57:29 网站建设 项目流程

Kimi Code CLI 统一 Skills 发现机制(KLIP-8)深度解析:分层合并、目录查找与跨工具兼容

【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cli

导读

本篇以 Kimi Code CLI 的设计提案 KLIP-8: Unified Skills Discovery 为核心,结合当前仓库中 Agent Skills 文档 与 Skill 发现源码 的实现,完整讲解 Kimi Code CLI 如何发现、合并和加载 Skills。读完本文,你将掌握:Skills 发现的"分层合并 + 目录查找"两级逻辑、用户级与项目级候选目录的精确优先级、--skills-dirextra_skill_dirs的差异,以及merge_all_available_skills配置对品牌目录合并行为的控制,并能在自己的项目中正确规划 Skills 目录布局,实现与 Claude、Codex 等工具的 Skills 共享。

一、背景:为什么需要"统一 Skills 发现"

编码 Agent 生态长期处于碎片化状态:不同工具(Kimi、Claude、Codex 等)各自定义了专有的 Skills 目录布局。其结果正如 KLIP-8 Motivation 中所指出的——用户必须为同一份 Skills 维护多份副本,或者使用 symlink 技巧才能在多个客户端之间复用。这既增加了维护成本,也容易在同步时产生版本漂移。

KLIP-8 的目标是统一 Skill 发现机制,使其与现有工具兼容,让一份 Skill 定义可以无需修改即可被多个编码 Agent 客户端使用。该提案当前状态为Implemented(已实现),其在仓库中的落地点是 src/kimi_cli/skill/init.py 中整套发现/加载工具,以及 docs/zh/customization/skills.md 中的用户文档。

设计边界

KLIP-8 明确划定了自己的 Scope 与 Non-goals,理解这一点有助于区分"统一 Skills 发现"与 Kimi 自身的配置体系:

  • Scope:仅包含 Skills 发现;mcp.json的标准化留作未来工作,不在本 KLIP 范围内。
  • Non-goals(明确不做)~/.kimi/config.toml等 Kimi 专属配置,以及~/.local/share/kimi/数据目录。这些仍然是 Kimi 特有的运行时数据,不参与跨工具统一。

也就是说,统一的是"Skills 在哪里被找到"这一层,而不是把 Kimi 的全部配置体系推倒重来。

二、两级发现逻辑:分层合并 × 目录查找

KLIP-8 提出的 Skills 发现机制由两个正交的维度组成,它们共同决定了最终加载到哪些 Skills:

第一级:分层合并(Layered Merge)

不同来源的 Skills 目录按作用域分层加载:builtin → user → project 全部加载,同名 Skill 由更靠后的层覆盖。这一"后层覆盖前层"的语义,在用户文档中被进一步细化为更具体的作用域优先级:

Project > User > Extra > Built-in

即项目级最优先、内置级优先级最低。分层合并不是"只取一层",而是每一层都可能贡献 Skills,只是当不同层出现同名 Skill 时,更具体的层胜出。

第二级:目录查找(Directory Lookup)

在每一层内部,按优先级依次检查候选目录,停在第一个存在的目录(first existing directory wins)。这一查找语义对应源码中的 find_first_existing_dir 实现:

async def find_first_existing_dir(candidates: Iterable[KaosPath]) -> KaosPath | None: for candidate in candidates: if await candidate.is_dir(): return candidate return None

两个维度的组合效果

用一句话概括两级逻辑的配合:每个作用域层内用"目录查找"确定具体目录,多个作用域层之间用"分层合并"叠加并仲裁同名冲突

值得注意的是,KLIP-8 的原始设计中,用户层的优先级顺序是~/.config/agents/skills/(规范、推荐)→~/.kimi/skills/(遗留回退)→~/.claude/skills/(遗留回退),项目层是.agents/skills/。当前仓库的实现在此基础上做了演进——详见下一节。

三、当前实现中的目录候选与优先级(源码级演进)

对比 KLIP-8 的原始提案,当前实现(src/kimi_cli/skill/init.py)将每个作用域层内部的候选目录拆分成了**品牌组(brand group)通用组(generic group)**两个互斥小组,分别查找后合并结果,品牌组特异性更高、优先级更高。

用户级 Skills

用户级目录存放在用户主目录,对所有项目生效。源码 find_user_skills_dirs 展示了完整的查找逻辑:

  • 品牌组(互斥选一,按优先级):
    1. ~/.kimi/skills/
    2. ~/.claude/skills/
    3. ~/.codex/skills/
  • 通用组(互斥选一,按优先级):
    1. ~/.config/agents/skills/(推荐 —— 这正是 KLIP-8 指定的"canonical"目录,也是跨工具共享的关键)
    2. ~/.agents/skills/

两组分别选出第一个存在的目录后独立合并加载。当同名 Skill 同时存在于品牌组与通用组时,品牌组的版本优先(因为它特异性更高,更接近用户对特定工具的意图)。

项目级 Skills

项目级目录存放在项目内,仅在该项目生效。候选路径以项目根为起点——即工作目录向上最近的包含.git的祖先目录;找不到.git时回退到工作目录本身。这样即使从 monorepo 的某个子 package 内启动 kimi-cli,仓库根目录下的 Skills 也能被正确识别。项目级同样分为两组:

  • 品牌组(互斥选一):.kimi/skills/.claude/skills/.codex/skills/
  • 通用组.agents/skills/

项目根的解析在 find_project_skills_dirs 中完成,它内部调用 utils/path.py 的find_project_root来定位.git祖先目录。

内置 Skills

随软件包安装的 Skills 优先级最低。内置目录的解析见 get_builtin_skills_dir:PyInstaller 冻结环境下使用_MEIPASS定位打包资源,常规环境下指向包内的skills目录。当前仓库内置了两个 Skills(见 src/kimi_cli/skills/):

  • kimi-cli-help(SKILL.md):解答安装、配置、斜杠命令、键盘快捷键、MCP 集成、供应商、环境变量等问题;
  • skill-creator(SKILL.md):创建或更新 Skill 的指导与最佳实践。

KLIP-8 特别强调:内置 Skills 仅在 KAOS 后端为LocalKaosACPKaos时加载。这一条件对应源码中的 _supports_builtin_skills,它检查当前 KAOS 后端名称是否为local_kaos.name"acp",因为只有这些后端才能可靠读取随包分发的资源目录。

四、--skills-dirextra_skill_dirs:覆盖 vs 追加

KLIP-8 规定:--skills-dir覆盖用户/项目自动发现,仅使用指定目录(内置 Skills 在受支持时仍然加载)。当前实现忠实地贯彻了这一语义,同时额外引入了追加式的extra_skill_dirs配置。

--skills-dir:覆盖式指定

CLI 参数定义见 cli/init.py,可重复指定:

kimi --skills-dir /path/to/my-skills --skills-dir /path/to/more-skills

在 resolve_skills_roots 中,一旦传入skills_dirs,就不再执行用户级与项目级的自动发现,仅使用指定的目录;但这些目录处于优先级的最顶端(其 Skills 优先于其他来源),且内置 Skills 在受支持的后端上仍会照常加载——与 KLIP-8 的设计完全一致。

extra_skill_dirs:追加式声明

如果你希望在内置 / 用户级 / 项目级自动发现的基础上追加自定义目录(而不是替代它们),可在配置文件中设置extra_skill_dirs(配置项定义见 config.py):

extra_skill_dirs = [ "~/my-skills-collection", # `~` 会展开为 $HOME ".claude/plugins/my-skills", # 相对路径以“项目根”为基准解析 "/opt/team-shared/skills", # 绝对路径原样使用 ]

每一项可以是绝对路径、~前缀路径,或相对于项目根(即 work_dir 向上第一个包含.git的目录)的相对路径。不存在的条目会被静默跳过(源码中_resolve_extra_skill_dir对不可解析、不可 stat 的条目逐一容错)。从这些目录发现的 Skills 在系统提示中归入Extra作用域。

两者在优先级中的位置

resolve_skills_roots中 Roots 按优先级从高到低排列,同名 Skill 由discover_skills_from_roots按"首次出现者胜出"(first wins)解析。最终排序为:

Project > User > Extra(config) > Extra(plugins) > Built-in

其中--skills-dir指定的目录以extra作用域置于最顶端(显式意图优先);extra_skill_dirs追加在自动发现的 project/user 之后;插件目录(plugin/manager.py 的get_plugins_dir)也作为extra来源参与,但排在配置声明的 extras 之下。

五、源码实现剖析:从根目录到系统提示

作用域标记(ScopedSkillsRoot)

ScopedSkillsRoot 将"Skills 目录"与其所属作用域(builtin/user/project/extra)绑定在一起。作用域标记贯穿整个发现流程,最终用于系统提示的分组渲染,让模型能区分"项目里的 skill"与"用户级的 skill"。

去重与规范化

resolve_skills_roots内部的_append对每个根目录做去重:先对本地后端做Path.resolve()(解析 symlink),再做KaosPath.canonical()(规范化..与尾部斜杠),从而避免 symlink、..段或尾部斜杠造成系统提示中出现"幽灵重复条目"。

单目录内的两种 Skill 形态

discover_skills 在一个 Skills 目录内并行支持两种布局:

  1. 子目录形式(canonical)<skills_dir>/<name>/SKILL.md
  2. 扁平.md形式<skills_dir>/<name>.mdname默认取文件名去掉.md(适合从其他用扁平 Markdown 存 Skills 的工具迁移的用户)。

两遍扫描分别处理两种形态:第一遍收集子目录形式,第二遍收集扁平形式并跳过已被子目录占用名字的条目;若同名冲突,子目录胜出并记录警告日志。位于目录顶层的裸SKILL.md会被视为游离标记文件而非 Skill。

description 的三级解析链

无论子目录还是扁平形式,parse_skill_text 对每个 Skill 的description走同一条链:

  1. Frontmatter 的description:字段(推荐,遵循 SKILL.md 规范);
  2. 正文第一个非空行(回退;超过 240 字符截断并追加省略号,见_DESCRIPTION_FALLBACK_MAX_LEN);
  3. "No description provided."(兜底)。

系统提示中的分组渲染

format_skills_for_prompt 将发现的 Skills 按作用域分组注入系统提示,输出布局如下:

### Project - <name> - Path: <skill_md_file> - Description: <description> ### User - ...

空分组不渲染。分组顺序固定为 Project → User → Extra → Built-in,与作用域优先级一致,让模型在回答"项目里的 skill"这类问题时能准确区分来源。

六、merge_all_available_skills:品牌目录合并策略

KLIP-8 的原始设计是"每层内停在第一个存在的目录",而当前实现在此基础上提供了更灵活的品牌目录合并策略,由配置项merge_all_available_skills控制(定义见 config.py):

  • 默认true:合并所有存在的品牌目录(kimi / claude / codex),同名 Skill 按 kimi > claude > codex 的优先级解析;通用组不受影响。这样"在多个品牌目录中都维护了 Skills"的用户开箱即用就能看到全部内容;
  • 设为false:恢复旧的"仅取优先级最高的那个品牌目录"行为——只使用 kimi,缺失时回退到 claude,再缺失时回退到 codex。
# 默认值;合并所有已存在的品牌目录 merge_all_available_skills = true # 恢复 first-match-only 行为 merge_all_available_skills = false

该配置对用户级与项目级 Skills 同样生效,对应 find_user_skills_dirs 与 find_project_skills_dirs 中的merge_brands参数:为True时逐个检查并收集所有存在的品牌目录,为False时仅取第一个存在的目录。

七、测试验证:行为即契约

仓库的 tests/core/test_skill.py 完整覆盖了上述发现语义,是理解"first wins"与分组优先级的最佳佐证:

  • test_discover_skills_from_roots_prefers_earlier_dirs/test_discover_skills_from_roots_first_wins:验证同名 Skill 出现在多个根目录时,更早(更高优先级)的根目录胜出
  • test_find_user_skills_dirs_empty_generic_does_not_shadow_brand:验证通用组为空时不会遮蔽品牌组结果;
  • test_find_user_skills_dirs_only_brand/test_find_user_skills_dirs_only_generic:验证品牌组与通用组独立查找、互不干扰;
  • test_discover_skills_parses_frontmatter_and_defaults/test_discover_skills_parses_flow_type:验证 Frontmatter 解析、name/description 默认值与flow类型解析,以及 flow 解析失败时回退为standard的容错行为。

这些测试同时印证了 tests/core/test_config.py 中merge_all_available_skillsextra_skill_dirs的配置默认值(true与空列表)。

八、实战:在项目中规划 Skills 目录

综合 KLIP-8 设计与当前实现,推荐的 Skills 布局策略如下:

  1. 跨工具共享的团队规范放在通用组~/.config/agents/skills/.agents/skills/——这是 KLIP-8 推崇的 canonical 位置,Kimi、Claude、Codex 均可直接发现,无需复制或 symlink;
  2. 特定工具的个性化 Skills放在品牌目录(如~/.kimi/skills/.kimi/skills/),利用品牌组特异性在冲突时优先;
  3. 团队私有仓库通过extra_skill_dirs追加,例如/opt/team-shared/skills,让所有成员共享一份只读规范;
  4. 临时或隔离的测试使用--skills-dir覆盖自动发现,确保只加载你指定的目录;
  5. 单个 Skill 采用<name>/SKILL.md子目录结构,Frontmatter 至少声明namedescription,正文控制在 500 行以内,细节内容放入scripts/references/assets/子目录。

需要特别注意:Skills 路径独立于KIMI_SHARE_DIRKIMI_SHARE_DIR只影响配置、会话、日志等运行时数据的存储位置,不影响 Skills 搜索路径——因为 Skills 是跨工具共享的能力扩展,与应用运行时数据是不同类型的数据。如需自定义 Skills 路径,请使用--skills-dir参数或extra_skill_dirs配置。

结语

KLIP-8 用两个简洁的原则——分层合并目录查找——解决了编码 Agent 生态中 Skills 布局碎片化的问题,使同一份 Skill 可以被多个工具直接使用。当前仓库不仅完整实现了提案中的两级发现逻辑,还演进出了品牌组/通用组分组、merge_all_available_skills合并策略与extra_skill_dirs追加机制,并通过 tests/core/test_skill.py 将"first wins"与作用域优先级固化为契约。深入理解这套机制,你就能在 Kimi Code CLI(以及兼容的 Claude、Codex 等工具)之间优雅地共享、分层管理 Skills,彻底告别复制与 symlink 维护。

【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cli

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询