news 2026/9/19 23:38:12

agentic-awesome-skills 与 Jetski/Cortex + Gemini 的延迟加载集成:在上下文窗口内安全使用 1,936+ 技能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
agentic-awesome-skills 与 Jetski/Cortex + Gemini 的延迟加载集成:在上下文窗口内安全使用 1,936+ 技能

agentic-awesome-skills 与 Jetski/Cortex + Gemini 的延迟加载集成:在上下文窗口内安全使用 1,936+ 技能

【免费下载链接】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

本指南面向基于 Jetski/Cortex(或同类自定义 Host)接入 Gemini 的开发者,核心解决"如何在不超过模型上下文窗口的前提下,安全、可扩展地使用 agentic-awesome-skills 仓库中 1,936+ 个技能"。读完本文,你将掌握"轻量级清单 + 按需延迟加载 + 显式上限"的集成范式,能复现可运行的 TypeScript/Node.js 加载器,并具备排查TrajectoryChatConverter截断崩溃循环的实战能力。

在 Jetski/Cortex 这类 Host 中集成技能库时,一个典型报错是:

TrajectoryChatConverter: could not convert a single message before hitting truncation

问题通常不在于技能本身,而在于加载方式——一次性把整库技能指令灌入上下文,任何模型都扛不住。下文先剖析反模式,再给出仓库官方推荐的替代方案。


1. 应避免的反模式:全量加载

在启动或每次请求时做以下任何一件事,都会迅速耗尽上下文窗口:

  • 在启动时读取所有skills/*/SKILL.md目录;
  • 将所有SKILL.md的内容拼接进单个系统提示词;
  • 每次请求重新注入整个技能库。

对于超过 1,936 个技能,这种方法在添加任何用户消息之前就已经填满上下文,进而触发截断错误。从仓库结构看,skills/目录下每个技能子目录都含一份SKILL.md(例如 skills/brainstorming/SKILL.md),全量拼接的 token 成本随技能数线性膨胀,是不可持续的。

2. 推荐模式:清单驱动 + 延迟加载

正确的集成遵循四条关键原则:

  • 轻量级清单:使用仓库根目录的 skills_index.json 作为规范清单,只了解存在哪些技能,不加载完整文本;data/skills_index.json仅为兼容性镜像;
  • 延迟加载:仅针对对话中实际调用的技能(例如消息中出现@skill-id时)读取对应SKILL.md
  • 显式限制:对每轮加载的最大技能数 / token 数施加限制,并提供清晰的回退机制;
  • 路径安全:读取SKILL.md之前,验证清单中的路径始终保持在SKILLS_ROOT内。

推荐的完整流程如下:

  1. 引导(Bootstrap):代理启动时读取skills_index.json,构建id -> meta映射;
  2. 消息解析:调用模型之前,从用户 / 系统消息中提取所有@skill-id引用;
  3. 解析:用引导映射把找到的 id 映射为SkillMeta对象;
  4. 延迟加载:仅针对这些 id 读取SKILL.md(最多不超过可配置上限);
  5. 提示词构建:系统消息中只包含被选中技能的定义。

仓库在 docs/integrations/jetski-gemini-loader/ 提供了可直接参考的示例实现(loader.mjs+README.md),并在 docs/users/discovery-manifest.md 中固化了这一契约,本文第 4 节将结合真实源码展开。

3.skills_index.json清单结构与字段契约

文件skills_index.json是一个对象数组(JSON Array),每个技能一个条目。例如:

{ "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" }

关键字段:

  • id:在@id提及中使用的标识符(例如@brainstorming);
  • path:包含SKILL.md的目录(例如skills/brainstorming/);
  • category:用于 UI / 搜索分组的归类;
  • name:显示名称;
  • description:简短的用途 / 触发条件摘要;
  • risk:仓库定义的技能风险标签;
  • source:来源与信任元数据;
  • date_added:ISO 日期字符串或null

要获得技能定义文件的完整路径:

fullPath = path.join(SKILLS_ROOT, meta.path, "SKILL.md")

注意:SKILLS_ROOT是安装仓库的根目录(例如~/.agents/skills)。

从 schemas/skills-index.v1.schema.json 可以看到更完整的契约细节:id最小长度为 1,path必须匹配^skills/前缀,categorynamedescriptionrisksourcedate_added均为必需字段;同时允许附加字段,plugin元数据(含targetssetupreasons)为可选。仓库的根清单实际还扩展了tags等字段,说明清单契约对附加字段保持开放。

关于data/skills_index.json兼容性镜像

仓库同时维护了data/skills_index.json。根据 docs/users/discovery-manifest.md 的说明,两者必须保持相同内容data/镜像的存在只是为了兼容仍从data/子树读取清单的下游客户端。新集成应优先读取根目录skills_index.json,仅在宿主必须读取data/子树时才回退到镜像。

4. 集成实现:从伪代码到可运行源码

完整可运行示例位于 docs/integrations/jetski-gemini-loader/(纯 Node.js ESM 模块,无需 TypeScript 运行时即可直接 import)。

4.1 基本类型

type SkillMeta = { id: string; path: string; name: string; description?: string; category?: string; risk?: string; };

在真实实现 loader.mjs 中,该类型以 JSDoc@typedef形式声明,Message类型则限定role"system" | "user" | "assistant"

4.2 引导:加载清单

function loadSkillIndex(indexPath: string): Map<string, SkillMeta> { const raw = fs.readFileSync(indexPath, "utf8"); const arr = JSON.parse(raw) as SkillMeta[]; const map = new Map<string, SkillMeta>(); for (const meta of arr) { map.set(meta.id, meta); } return map; }

对应源码见 loader.mjs 的loadSkillIndex:读取 JSON 后逐条map.set(meta.id, meta),整个过程不触碰任何SKILL.md,因此引导成本极低。

4.3 解析消息以查找@skill-id

const SKILL_ID_REGEX = /@([a-zA-Z0-9-_./]+)/g; function resolveSkillsFromMessages( messages: { role: string; content: string }[], index: Map<string, SkillMeta>, maxSkills: number ): SkillMeta[] { const found = new Set<string>(); for (const msg of messages) { let match: RegExpExecArray | null; while ((match = SKILL_ID_REGEX.exec(msg.content)) !== null) { const id = match[1]; if (index.has(id)) { found.add(id); } } } const metas: SkillMeta[] = []; for (const id of found) { const meta = index.get(id); if (meta) metas.push(meta); if (metas.length >= maxSkills) break; } return metas; }

真实源码中的实现更严谨:先由collectReferencedSkillIdsString.prototype.matchAll收集引用集合(天然去重,见 loader.mjs L24-L37),再由assertValidMaxSkills校验maxSkills必须是大于 0 的整数(loader.mjs L39-L45),最后按序截断到上限(loader.mjs L59-L75)。

4.4SKILL.md文件的延迟加载(含路径安全)

async function loadSkillBodies( skillsRoot: string, metas: SkillMeta[] ): Promise<string[]> { const bodies: string[] = []; for (const meta of metas) { const fullPath = path.join(skillsRoot, meta.path, "SKILL.md"); const text = await fs.promises.readFile(fullPath, "utf8"); bodies.push(text); } return bodies; }

仓库的真实实现(loader.mjs L77-L116)在此之上做了三层路径安全防护,值得完整采纳:

  1. 相对路径检查path.relative(rootPath, skillDirPath)若以..开头或为绝对路径,则抛出Skill path escapes skills root
  2. 目录类型检查:通过lstat确认技能目录是普通目录而非符号链接,避免链接逃逸;
  3. 解析后二次校验:对最终SKILL.mdrealpath后再次path.relative校验,任何解析到SKILLS_ROOT之外的情况都直接抛错。

这种"读取前校验 + 读取后复核"的做法,正是原文档第 2 节"路径安全"原则的落地实现。

4.5 构建 Jetski/Cortex 提示词

TrajectoryChatConverter之前的预处理阶段,按如下方式组装消息:

async function buildModelMessages( baseSystemMessages: { role: "system"; content: string }[], trajectory: { role: "user" | "assistant" | "system"; content: string }[], skillIndex: Map<string, SkillMeta>, skillsRoot: string, maxSkillsPerTurn: number, overflowBehavior: "truncate" | "error" = "truncate" ): Promise<{ role: string; content: string }[]> { const referencedSkills = resolveSkillsFromMessages( trajectory, skillIndex, Number.MAX_SAFE_INTEGER ); if ( overflowBehavior === "error" && referencedSkills.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 ); const skillBodies = await loadSkillBodies(skillsRoot, selectedMetas); const skillMessages = skillBodies.map((body) => ({ role: "system" as const, content: body, })); return [...baseSystemMessages, ...skillMessages, ...trajectory]; }

仓库的 loader.mjsbuildModelMessages与其一一对应,并有两个额外细节:

  • 默认值:maxSkillsPerTurn = 8overflowBehavior = "truncate"
  • 零技能短路:selectedMetas.length === 0时直接返回[...baseSystemMessages, ...trajectory],连一次文件系统访问都不会发生。

建议:加入 token 估算,在上下文窗口接近限制时对SKILL.md做截断或摘要。参考加载器已支持显式回退overflowBehavior: "error",让宿主在超限时明确失败而非静默丢弃技能。

使用方式(摘自 jetski-gemini-loader/README.md)大致如下:

const REPO_ROOT = "/path/to/agentic-awesome-skills"; const SKILLS_ROOT = REPO_ROOT; const INDEX_PATH = path.join(REPO_ROOT, "skills_index.json"); // 1. 启动时加载一次清单 const skillIndex = loadSkillIndex(INDEX_PATH); // 2. 调用模型前构建消息 const modelMessages = await buildModelMessages({ baseSystemMessages, trajectory, skillIndex, skillsRoot: SKILLS_ROOT, maxSkillsPerTurn: 8, overflowBehavior: "error", }); // 3. 把 modelMessages 交给 Jetski/Cortex + Gemini 客户端 // 例如 trajectoryChatConverter.convert(modelMessages)

5. 处理上下文溢出

为避免出现用户难以理解的报错,建议设置:

  • 安全阈值:例如上下文窗口的 70-80%;
  • 每轮最大技能数限制:例如 5-10 个。

超过阈值时的两种策略:

  • 缩减:减少本轮包含的技能数量(例如按最近使用或优先级排序后裁剪);
  • 显式报错:向用户返回明确错误,例如:

"在此轮中请求了太多技能。减少消息中的@skill-id数量或将其分为多个步骤。"

在参考实现中,overflowBehavior: "error"会抛出带技能上限数字的明确异常;"truncate"则按清单顺序截断。需要指出的是,"截断"是静默行为,实际加载的技能可能与用户期望不完全一致,因此在偏好显式失败的环境中应保持overflowBehavior: "error"(docs/integrations/jetski-gemini-loader/README.md 也给出了同样的建议)。

6. 推荐的测试场景

上线前至少覆盖以下三个场景:

  • 场景 1 — 简单消息("hi")
    • 没有@skill-id→ 不加载SKILL.md→ 提示词保持较小 → 无错误。
  • 场景 2 — 少量技能
    • 消息包含 1-2 个@skill-id→ 仅加载相关SKILL.md→ 无溢出。
  • 场景 3 — 大量技能
    • 消息包含许多@skill-id→ 触发maxSkillsPerTurn限制或 token 检查 → 无静默溢出(可断言error模式下抛出异常、truncate模式下消息数受限)。

这三个场景分别验证了"零技能短路"、"按需加载"与"显式上限"三条核心路径,可以快速回归加载器的行为是否符合预期。

7. 技能子集与捆绑包:进一步控制加载面

除延迟加载外,还可以通过缩小技能安装面来控制上下文:

  • 将不需要的技能移至skills/.disabled/,在某些环境中将其排除;
  • 使用 docs/users/bundles.md 描述的捆绑包(Bundles),只加载主题分组。

捆绑包是"按角色与专业水平整理的精选技能集合",例如 "Essentials" 起步包、Web Wizard、Security Engineer 等。它们在仓库中以plugins/agentic-bundle-*/目录形式存在(如plugins/agentic-bundle-aas-web-app-builder/),属于可安装的插件子集与激活预设,而非可被@调用的巨型技能。若希望捆绑包表现为"聚焦的活动子集"而非全量安装,可借助仓库的激活脚本:

# macOS/Linux ./scripts/activate-skills.sh --clear Essentials ./scripts/activate-skills.sh --clear "Web Wizard" # Windows .\scripts\activate-skills.bat --clear Essentials

从 docs/users/bundles.md 的说明可以看出,捆绑包内的每个技能都指向具体技能目录,这一映射关系与清单中path字段一致,因此延迟加载器可以直接复用。

8. 如果已在崩溃循环中:Windows 恢复指南

若主机在截断错误后反复重新打开同一份损坏轨迹(表现为应用启动即崩溃、或删除问题技能后仍回到同一错误),可参考 docs/users/windows-truncation-recovery.md 的完整恢复流程:

  1. 备份先行:备份%USERPROFILE%\.gemini\antigravity-browser-profile\Default%AppData%\antigravity%USERPROFILE%\.gemini\antigravity(若技能安装在其他目录也一并备份);
  2. 删除问题技能或包:默认安装路径为%USERPROFILE%\.gemini\antigravity\plugins\skills
  3. 删除本地存储:清掉 Antigravity 浏览器配置中的Local StorageSession StorageIndexedDB,以及%AppData%\antigravity下的Local StorageSession Storage
  4. 清空临时目录%TEMP%
  5. 重启并用延迟加载 + 显式限制重新安装:只装真正需要的技能,或切换为带显式上限的延迟加载集成。

该文档还附带一个社区贡献的批处理恢复脚本(Anti-Gravity_Recovery_Tool_Universal),会自动执行备份、清理Local Storage等步骤,使用前请先审阅脚本内容。

为防止问题再次出现:

  • 更偏好显式失败时,保持overflowBehavior: "error"
  • 持续验证解析出的路径是否保持在skillsRoot内。

9. 总结

  • 切勿将所有SKILL.md拼接到单个提示词中;
  • 使用根目录 skills_index.json 作为轻量级规范清单;仅在宿主必须读取data/子树时使用data/skills_index.json兼容性镜像;
  • 基于@skill-id按需加载技能;
  • 设置明确限制(每轮最大技能数、token 阈值);
  • 参考实现见 docs/integrations/jetski-gemini-loader/loader.mjs,清单契约见 schemas/skills-index.v1.schema.json 与 docs/users/discovery-manifest.md,崩溃恢复见 docs/users/windows-truncation-recovery.md。

遵循以上模式,Jetski/Cortex + Gemini 就可以以安全、可扩展且与现代模型上下文窗口兼容的方式,使用整个 agentic-awesome-skills 技能库。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 23:37:56

告别粗糙架构图:纯HTML+SVG实现出版级图解方案

如果你画过架构图&#xff0c;大概率经历过这种尴尬&#xff1a;方案讲得头头是道&#xff0c;图一放出来&#xff0c;评审现场直接就尬住了。框线对不齐、字体发虚、配色像调色盘打翻&#xff0c;逻辑再严谨&#xff0c;也很难让人相信你“考虑周全”。我从前端转到基建、又在…

作者头像 李华
网站建设 2026/9/19 23:37:51

汽车QMS系统架构:从供应商追溯链到SPC/CPK集成落地

简介&#xff1a;汽车行业QMS整体解决方案以PDF文档形式呈现&#xff0c;面向汽车整车厂、零部件供应商及质量管理信息化人员&#xff0c;系统梳理从供应商到售后服务的全链路质量管控思路。方案围绕ISO/TS16949体系要求&#xff0c;涵盖APQP、PPAP等核心方法&#xff0c;给出体…

作者头像 李华
网站建设 2026/9/19 23:35:48

误删除文件100%恢复完整解决方案

需要工具&#xff1a;u盘&#xff08;大于>4GB) 1.误删除文件后&#xff0c;不要再误删除的磁盘上做写入操作&#xff0c;否则无法恢复 使用另一台电脑&#xff0c;制作数据恢复功能启动盘 2.用带数据恢复功能的winPE盘启动&#xff0c;进行误删除的文件恢复 制作启动盘…

作者头像 李华