4. 渐进式加载
4.1 三阶段加载
typescript
class ProgressiveSkillLoader {
// 阶段 1: 启动时加载元数据
async loadMetadata(): Promise<SkillMetadata[]> {
const skills = await this.scanSkills();
return skills.map(s => ({
name: s.name,
description: s.description,
triggers: s.triggers
// 不加载完整内容
}));
// Token 消耗: ~100 tokens per skill
}
// 阶段 2: 检测时加载 frontmatter + 简介
async loadSummary(skillName: string): Promise<SkillSummary> {
const content = await this.readSkill(skillName);
// 只提取前几段
const summary = this.extractSummary(content);
return {
name: skillName,
summary,
sections: this.extractSectionTitles(content)
};
// Token 消耗: ~300 tokens per skill
}
// 阶段 3: 使用时加载完整内容
async loadFull(skillName: string): Promise<Skill> {
const content = await this.readSkill(skillName);
// 加载完整内容
return {
name: skillName,
content,
references: await this.loadReferences(skillName)
};
// Token 消耗: ~2000 tokens per skill
}
// 提取摘要
private extractSummary(content: string): string {
// 提取 "When to Use" 和 "Prerequisites" 部分
const sections = ['When to Use', 'Prerequisites'];
const summary = [];
for (const section of sections) {
const regex = new RegExp(`## ${section}\\n([\\s\\S]*?)(?=## |$)`);
const match = content.match(regex);
if (match) {
summary.push(`## ${section}\n${match[1].trim()}`);
}
}
return summary.join('\n\n');
}
// 提取章节标题
private extractSectionTitles(content: string): string[] {
const matches = content.matchAll(/^## (.+)$/gm);
return [...matches].map(m => m[1]);
}
}4.2 按需加载引用文档
typescript
class ReferenceLoader {
// 解析引用链接
parseReferences(skillContent: string): Reference[] {
const references: Reference[] = [];
// 匹配 [text](./references/file.md) 格式
const regex = /\[([^\]]+)\]\(\.\/references\/([^)]+)\)/g;
const matches = skillContent.matchAll(regex);
for (const match of matches) {
references.push({
title: match[1],
path: match[2],
loaded: false
});
}
return references;
}
// 按需加载引用
async loadReference(skillName: string, refPath: string): Promise<string> {
const fullPath = path.join(
this.skillsDir,
skillName,
'references',
refPath
);
if (!await fs.exists(fullPath)) {
return `Reference not found: ${refPath}`;
}
return await fs.readFile(fullPath, 'utf-8');
}
// 智能加载:只加载被提及的引用
async loadRelevantReferences(
skillName: string,
conversation: string[]
): Promise<Map<string, string>> {
const skill = await this.loadSkill(skillName);
const references = this.parseReferences(skill.content);
const loaded = new Map<string, string>();
for (const ref of references) {
// 检查对话中是否提到这个引用
const mentioned = conversation.some(msg =>
msg.toLowerCase().includes(ref.title.toLowerCase())
);
if (mentioned) {
const content = await this.loadReference(skillName, ref.path);
loaded.set(ref.title, content);
}
}
return loaded;
}
}