MoonshotAI / MoonshotAI/kimi-code
feat(skill): skill search via BM25 index for large skill catalogues
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Problem
When a user has a large number of skills installed (e.g. 1,000+), the current implementation injects the entire skill listing into the system prompt — including name, description (250 chars), whenToUse, and file path for every skill.
With 1,530 real skills this amounts to ~118,000 tokens in the system prompt alone, which:
- Consumes ~46% of a 256K context window
- Loads all SKILL.md file bodies into memory at startup (~88 MB JS heap)
- Forces the LLM to scan a massive listing to find the right skill — poor accuracy due to lost-in-the-middle effects
Proposed Solution
A 3-tier auto-detection system based on invocable skill count:
| Skill count | Listing format | Strategy |
|---|---|---|
| ≤ 80 | Legacy full listing (name + desc + path) | Prompt-cache optimal for small catalogues |
| 81–300 | Compact (name + 80-char desc) | Search available but not required |
| > 300 | Names only | Search required via action: "search" |
Key changes:
- BM25 search index built at startup from skill metadata (name, description, whenToUse). Zero external dependencies, ~24ms for 1,500 skills, <1ms per query.
Skilltool extended withaction: "search"(new) alongside existingaction: "load"(default). Backward-compatible —skillfield remains required.- Lazy content loading: only frontmatter parsed at startup; full SKILL.md body loaded from disk on-demand when a skill is activated (~0.4ms per activation).
- Auto-detection: no feature flag needed — tier selected by skill count at session start.
Token savings (measured with real 1,530 skills)
| Metric | Before | After |
|---|---|---|
| System prompt | 118,120 tokens | 8,436 tokens (93% reduction) |
| Startup memory | ~88 MB | ~4 MB (95% reduction) |
| Search latency | N/A | 0.0–0.2ms |
Files changed
skill/search.ts(new) — BM25 index with synonym expansionskill/registry.ts— auto-detect tier, lazy load, searchSkills()skill/parser.ts— parseSkillMetaFromFile() for frontmatter-only parsingskill-tool.ts/.md— search action on existing Skill toolsystem.md— search-first workflow instructions- Tests merged into existing
registry.test.ts+ integration proof inintegration-proof.test.ts
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading skill/registry.ts and skill/parser.ts, then inspect the existing registry.test.ts and integration-proof.test.ts coverage. Review skill/search.ts, skill-tool.ts, skill-tool.md, and system.md to understand the search action, tier selection, and lazy loading boundaries. Done means the documented catalogue tiers, search behavior, frontmatter parsing, and integration proof are covered by the existing tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, search, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100