agentic-awesome-skills 稳定技能清单(Stable Skills Manifest v1):自定义宿主集成与懒加载接入指南
【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,115+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址: https://gitcode.com/gh_mirrors/an/agentic-awesome-skills
导读
本指南围绕 agentic-awesome-skills 仓库中的skills_index.json(即 Stable Skills Manifest v1)展开,它是自定义宿主(Custom Host)集成与懒加载器(Lazy Loader)使用的「遗留兼容」公开契约:一个 JSON 数组,每个技能对应一个条目,用于在不加载任何SKILL.md正文的前提下完成技能发现、@skill-id解析与按需读取。读完本文,你将掌握该清单的完整字段契约、Schema 约束、data/镜像同步规则,以及一条「读清单 → 解析 ID → 懒加载单文件 → 限制每轮上限 → 路径安全校验」的官方推荐集成路径,并理解它与 AAS Core(面向 Codex / Claude Code 的本地只读 MCP 目录)之间的边界。
适用前提:本契约面向没有 AAS Core 宿主适配器的自定义集成(例如 Jetski/Cortex 风格的宿主)。Codex 与 Claude Code 用户应优先使用 AAS Core,而不是直接把宿主直连仓库清单。
1. Manifest v1 契约总览
清单的稳定契约可以概括为以下四点(完整定义见 discovery-manifest.md):
| 契约项 | 内容 |
|---|---|
| 规范文件 | 仓库根目录的skills_index.json |
| 镜像文件 | data/skills_index.json,必须是根清单的精确兼容镜像(exact compatibility mirror) |
| 格式 | JSON 数组,每个技能一个对象 |
| Schema | schemas/skills-index.v1.schema.json |
从仓库实际状态看,当前根清单与镜像均为 52,540 行、2,124 个技能条目,且两份文件内容完全一致(可用diff -q skills_index.json data/skills_index.json验证)。这一点也印证了文档中「两者载荷相同」的稳定约定。
1.1 为什么需要一份「稳定清单」
仓库实际包含 2,000+ 个技能目录(仅skills/目录下就有数百个以SKILL.md为核心的技能子目录),如果宿主在启动时把每一个SKILL.md都读进上下文,模型上下文窗口会被瞬间占满,并触发类似 Jetski/Cortex 宿主常见的错误:
TrajectoryChatConverter: could not convert a single message before hitting truncation
稳定清单的价值在于:用一份轻量 JSON 数组替代全量正文扫描,让宿主只根据对话中出现的@skill-id按需读取对应技能正文。这不是 AAS Core 的目录或栈生命周期契约(后者由 aas-core.md 定义),而是面向自定义多技能宿主的上下文截断与轨迹转换错误的主要预防手段。
2. 必填字段与 Schema 约束
2.1 必填字段
每个清单条目包含以下字段(discovery-manifest.md 中明确定义):
| 字段 | 含义 |
|---|---|
id | 技能标识符,与@skill-id一致 |
path | 相对技能目录,例如skills/brainstorming |
category | 用于 UI / 搜索表面的分组 |
name | 显示名称 |
description | 简短用途 / 触发摘要 |
risk | 仓库风险标签之一 |
source | 权威 / 信任元数据的来源 |
date_added | ISO 日期字符串或null |
此外,允许附加字段(如tags),plugin元数据为可选项。从根清单统计看,当前 2,124 个条目中,risk分布为:critical1,101、safe859、none103、offensive61;source以community(1,399)为主,另有official、personal、self以及大量标注了上游仓库来源的条目;有 444 个条目带tags字段,且所有条目当前都带有plugin元数据(date_added均非null)。这些统计可直接用于宿主侧的 UI 过滤或展示。
2.2 Schema 的强制约束
schemas/skills-index.v1.schema.json 将契约落到可验证的 JSON Schema(draft 2020-12)上:
- 顶层必须是array;
- 每个条目必须包含上述 8 个必填字段(缺任一字段即校验失败);
id、category、name、risk、source均要求minLength: 1(非空字符串);path必须以^skills/开头,保证条目路径不会指向仓库技能目录之外;description为任意字符串;date_added允许string或null;plugin为可选对象,内部含targets(codex/claude等目标到状态字符串的映射)、setup(任意附加配置对象)与reasons(字符串数组);additionalProperties: true意味着额外字段(如tags)合法。
以文档给出的完整示例条目为准(discovery-manifest.md):
{ "id": "brainstorming", "path": "skills/brainstorming", "category": "planning", "name": "brainstorming", "description": "Use before any creative or constructive work.", "risk": "safe", "source": "official", "date_added": "2026-02-27" }注意:仓库中实际存在的 skills/brainstorming/SKILL.md 的 frontmatter 为risk: critical、source: community,说明文档示例是「结构示意」,真实条目以清单文件当前内容为准——这也提醒集成方:清单是运行时的事实来源,不要硬编码任何单条技能的风险或来源值。
3. 推荐的宿主行为:清单驱动的懒加载
稳定集成绝不能在启动时加载全部技能指令文件。官方推荐的宿主行为(discovery-manifest.md)是:
- 读取清单
skills_index.json(一次); - 只解析对话中出现的
@skill-id; - 对每个解析出的技能,懒加载对应的那一个
SKILL.md; - 施加每轮(per-turn)技能数量上限,避免用户提示超出上下文限制;
- 校验每个解析出的路径都落在你配置的
SKILLS_ROOT之内。
其中第 4、5 步正是「上下文截断与轨迹转换错误」在自定义多技能宿主中的主要预防手段。
3.1 完整参考实现:Jetski Gemini 懒加载器
仓库在 docs/integrations/jetski-gemini-loader/README.md 提供了一个最小参考实现,其核心模块 loader.mjs 将上述 5 步拆成了可复用的四个导出函数:
| 函数 | 职责 |
|---|---|
loadSkillIndex(indexPath) | 启动时读取清单,构建id -> SkillMeta的Map |
resolveSkillsFromMessages(messages, index, maxSkills) | 扫描消息中的@skill-id并解析为元数据,受maxSkills限制 |
loadSkillBodies(skillsRoot, metas) | 按路径读取SKILL.md正文(含路径逃逸校验) |
buildModelMessages({...}) | 组装[基础 system 消息 + 每个选中技能的 system 消息 + 轨迹] |
3.1.1 启动引导与 ID 解析
const SKILL_ID_REGEX = /@([a-zA-Z0-9-_./]+)/g; export function loadSkillIndex(indexPath) { const raw = fs.readFileSync(indexPath, "utf8"); const arr = JSON.parse(raw); const map = new Map(); for (const meta of arr) { map.set(meta.id, meta); } return map; } export function resolveSkillsFromMessages(messages, index, maxSkills) { const referencedSkillIds = new Set(); for (const msg of messages) { for (const match of msg.content.matchAll(SKILL_ID_REGEX)) { const id = match[1]; if (index.has(id)) referencedSkillIds.add(id); } } const metas = []; for (const id of referencedSkillIds) { const meta = index.get(id); if (meta) metas.push(meta); if (metas.length >= maxSkills) break; } return metas; }要点:
- 正则
@([a-zA-Z0-9-_./]+)支持带连字符、点、斜杠的技能 ID 形态; - 只在清单中存在的 ID 才会被收集(
index.has(id)); maxSkills必须为正整数(assertValidMaxSkills会拒绝非整数或< 1的值)。
3.1.2 懒加载与路径安全(源码级细节)
loadSkillBodies是路径安全的重点(loader.mjs),其防御手段可归纳为三层:
- 相对路径逃逸校验:对
path.resolve(skillsRoot, meta.path)计算相对路径,若以..开头或为绝对路径则抛错Skill path escapes skills root; - 符号链接拒绝:技能目录与
SKILL.md都必须是通过lstat确认的普通目录 / 普通文件,任何符号链接都会被拒绝; - realpath 二次校验:读取前先
realpath解析最终目标,再次确认其仍位于SKILLS_ROOT之内,防止目录内软链绕出。
这直接对应文档中「Validate each resolved path stays under your configuredSKILLS_ROOT」的要求,也解释了为什么推荐集成必须把路径安全当作硬约束而非可选项。
3.1.3 组装模型消息与溢出策略
export async function buildModelMessages(options) { const { baseSystemMessages, trajectory, skillIndex, skillsRoot, maxSkillsPerTurn = 8, overflowBehavior = "truncate", } = options; const referencedSkillIds = collectReferencedSkillIds(trajectory, skillIndex); if (overflowBehavior === "error" && referencedSkillIds.length > maxSkillsPerTurn) { throw new Error( `Too many skills requested in a single turn. Reduce @skill-id usage to ${maxSkillsPerTurn} or fewer.`, ); } const selectedMetas = resolveSkillsFromMessages(trajectory, skillIndex, maxSkillsPerTurn); if (selectedMetas.length === 0) { return [...baseSystemMessages, ...trajectory]; } const skillBodies = await loadSkillBodies(skillsRoot, selectedMetas); const skillMessages = skillBodies.map((body) => ({ role: "system", content: body })); return [...baseSystemMessages, ...skillMessages, ...trajectory]; }默认参数与语义:
maxSkillsPerTurn默认8(文档与 Jetski 指南建议的实用范围是 5–10);overflowBehavior默认"truncate"(静默截断到上限);设为"error"时,若单轮引用数超过上限会直接抛错,适合希望「明确失败而非静默丢失技能」的宿主;- 无任何
@skill-id引用时,buildModelMessages原样返回[基础消息 + 轨迹],不产生额外开销。
典型调用示例(TypeScript 伪代码,见 jetski-gemini-loader README):
const REPO_ROOT = "/path/to/agentic-awesome-skills"; const SKILLS_ROOT = REPO_ROOT; const INDEX_PATH = path.join(REPO_ROOT, "skills_index.json"); const skillIndex = loadSkillIndex(INDEX_PATH); // 1. 启动时引导一次 const modelMessages = await buildModelMessages({ baseSystemMessages, trajectory, skillIndex, skillsRoot: SKILLS_ROOT, maxSkillsPerTurn: 8, overflowBehavior: "error", }); // 2. 将 modelMessages 交给 Jetski/Cortex + Gemini 客户端该示例是最小参考而非生产级库:实际宿主应在接入
TrajectoryChatConverter的位置挂载buildModelMessages,并按需补充 token 计数 / 截断逻辑、更严格的安全预算。
4. 为什么要保留data/镜像
data/skills_index.json的存在是为了下游兼容:部分客户端仍从data/子树读取。稳定的契约是两份文件载荷完全相同(discovery-manifest.md)。
对集成方而言,这意味着:
- 新集成优先读根目录
skills_index.json; - 仅当宿主明确从
data/读取时,才把data/skills_index.json作为兼容读取路径; - 不要把两份文件当作可能分叉的独立数据源——它们必须保持一致。
5. 与 AAS Core 的边界
清单契约明确强调:它不是AAS Core 目录或栈生命周期契约(discovery-manifest.md)。两者的分工如下:
| 维度 | Stable Skills Manifest v1(本文主题) | AAS Core |
|---|---|---|
| 面向宿主 | 无 AAS Core 适配器的自定义集成 / 懒加载器 | Codex、Claude Code |
| 暴露方式 | 原始 JSON 清单 + 手动懒加载 | 本地只读 MCP 工具(search_skills、get_skill、compose_stack等) |
| 核心能力 | 技能发现 + 按需读取 | 完整本地目录检索、agent 自主选型、栈校验与规划 |
| 上下文保护 | 宿主自行实现 per-turn 上限与SKILLS_ROOT校验 | 只读、按需返回,技能正文标记为不可信内容 |
需要说明的是,AAS Core 的完整能力(含compose_stack、inspect_stack、diff_stack、证据导出等)属于 aas-core.md 的范围,本文不展开;自定义集成方应判断自己是否有 AAS Core 宿主适配器,若有则优先走 AAS Core,而不是直连仓库清单。
6. 集成中的上下文溢出与边界场景
6.1 溢出处理策略
参考 jetski-cortex.md 的建议,宿主应同时设置两类阈值:
- 安全阈值:例如上下文窗口的 70%–80%;
- 每轮技能数量上限:例如 5–10 个。
当阈值被触发时,两种策略二选一:
- 减少纳入的技能(例如按最近引用或优先级取舍);
- 向用户返回明确错误,例如:
"Too many skills were requested in a single turn. Reduce the number of
@skill-idreferences in your message or split them into multiple turns."
6.2 推荐的验证场景
- 场景 1(普通消息):消息不含
@skill-id→ 不加载任何SKILL.md→ prompt 保持精简 → 无错误; - 场景 2(少量技能):消息含 1–2 个
@skill-id→ 仅加载对应SKILL.md→ 无溢出; - 场景 3(大量技能):消息含大量
@skill-id→maxSkillsPerTurn或 token 护栏触发 → 不出现静默溢出。
6.3 Windows 崩溃循环恢复
若宿主(如 Antigravity 或 Jetski/Cortex 集成)在 Windows 上因截断错误陷入重启循环(TrajectoryChatConverter: could not convert a single message before hitting truncation),完整恢复步骤见 windows-truncation-recovery.md,核心思路是:备份(%USERPROFILE%\.gemini\antigravity-browser-profile\Default、%AppData%\antigravity等)→ 移除问题技能 / 包 → 清理 Local/Session Storage 与%TEMP%→ 以「懒加载 + 显式上限」重启。预防复发的关键是:优先overflowBehavior: "error",并持续校验解析路径位于skillsRoot内。
6.4 技能子集与 Bundles 的进一步控制
如果希望进一步收敛加载范围,可参考 jetski-cortex.md 与 bundles.md:
- 将不必要的技能移入
skills/.disabled/,在特定环境中排除它们; - 使用仓库的 bundles(见 data/bundles.json、data/editorial-bundles.json)只加载聚焦的技能分组。
7. 快速接入清单(Checklist)
| 步骤 | 动作 | 依据 |
|---|---|---|
| 1 | 启动时读取根skills_index.json,构建id -> meta映射 | discovery-manifest.md |
| 2 | 若宿主从data/读取,确认data/skills_index.json与根清单一致 | discovery-manifest.md |
| 3 | 用@([a-zA-Z0-9-_./]+)扫描消息中的@skill-id | loader.mjs |
| 4 | 只对命中 ID 懒加载path/SKILL.md | loader.mjs |
| 5 | 设置maxSkillsPerTurn(建议 5–10)并选择truncate/error | jetski-cortex.md |
| 6 | 校验路径不逃逸SKILLS_ROOT(相对路径 + 符号链接 + realpath 三层) | loader.mjs |
| 7 | 用 skills-index.v1.schema.json 校验清单 | discovery-manifest.md |
| 8 | 有 AAS Core 适配器时优先走 AAS Core,而非直连清单 | aas-core.md |
8. 总结
skills_index.json是 agentic-awesome-skills 面向自定义宿主暴露的稳定发现契约:8 个必填字段 + 可选的plugin/ 附加字段,配套 JSON Schema 可验证,根清单与data/镜像保持完全一致。它的正确使用方式不是「全量注入」,而是清单驱动 + 按@skill-id懒加载 + 每轮上限 +SKILLS_ROOT路径安全——这正是自定义多技能宿主避免上下文截断与轨迹转换错误的关键。仓库中的 loader.mjs 提供了可直接借鉴的四函数参考实现;若你的目标是 Codex 或 Claude Code,则请转向 AAS Core,让 Core 完成目录检索、选型校验与可复现的规划闭环。
相关文档
- AAS Core:Agent-Owned Skill Stacks
- Jetski/Cortex + Gemini 集成指南
- Jetski Gemini 懒加载器参考实现
- Windows 截断崩溃循环恢复
- Skills Index v1 Schema
- 根清单 skills_index.json 与 镜像 data/skills_index.json
【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,115+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址: https://gitcode.com/gh_mirrors/an/agentic-awesome-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考