Skill Wiki v0.1.0

文档 / implementation / chunker

本页目录

Chunker

Chunker 把解析过的 AtomDeclaration 切成三份 Markdown 投影。 切法按 kind 走 —— 每种 kind 都有自己的规矩,决定 summary、core、full 各装什么。

函数签名

// packages/compiler/src/chunker.ts
export interface ChunkLevels {
  /** ~30 tok: description + tags + 1-line claim */
  summary: string;
  /** ~150 tok: + core body fields */
  core: string;
  /** ~380 tok: + sources + examples + relations + notes */
  full: string;
}

export function chunk(atom: AtomDeclaration): ChunkLevels {
  const splitter = SPLITTERS[atom.kind] ?? defaultSplitter;
  return splitter(atom);
}

每种 kind 的 splitter

每种 kind 配一个 splitter 函数。chunker 按 atom.kind 派发。 新 kind(见 自定义 kind)通过 SPLITTERS 这张表注册自己的 splitter。

const SPLITTERS: Record<AtomKind, Splitter> = {
  rule:         ruleSplitter,
  pattern:      patternSplitter,
  fact:         factSplitter,
  method:       methodSplitter,
  // ...
};

function ruleSplitter(atom: AtomDeclaration): ChunkLevels {
  return {
    summary: `# ${atom.name}

${atom.fields.find('claim')?.value}`,

    core: `# ${atom.name}

${atom.fields.find('claim')?.value}

**Applies to:** ${atom.fields.find('applies-to')?.value.join(', ')}
**Severity:** ${atom.fields.find('severity')?.value}`,

    full: `# ${atom.name}

${atom.fields.find('claim')?.value}

**Applies to:** ${atom.fields.find('applies-to')?.value.join(', ')}
**Severity:** ${atom.fields.find('severity')?.value}

## Remediation
${atom.fields.find('remediation')?.value ?? '(none specified)'}

## Validates with
${edgesByVerb(atom, 'validates-with').map(formatRef).join('\n- ')}
`,
  };
}

Token 计数

Token 目标是粗估值。编译期 chunker 用一个快速的字符级启发式(约 3.5 字符一个 token), 不调 LLM 的 tokenizer。_index.xml<atom> 上的 tokens 属性才是发射后 full 投影的实际长度。

从一层到下一层丢什么

从 → 到丢掉
full → coresources、counter-example、例外情形、软性 verb 关联
core → summary次要字段(applies-to、severity、parameters)

原则只有一条:原子在每一层都得有用。一份只剩名字的 summary 是错的 —— agent 要的是 claim。 一份只有名字加 claim 的 full 同样是错的 —— agent 要的是 body。

输出文件

compiled/
└── @scope/
    └── rule-keyboard-accessible/
        ├── atom.yaml
        ├── graph.yaml
        └── chunks/
            ├── summary.md     ←  ~30 tok
            ├── core.md        ←  ~150 tok
            └── full.md        ←  ~380 tok