← Back to Plugins
Tools

Skill Search

thomaszhang2661 By thomaszhang2661 👁 115 views ▲ 0 votes

OpenClaw skill discovery plugin with BM25 + semantic vector search

GitHub

Install

npm install

#

Configuration Example

# skills/github/manifest.yaml
intentExamples:
  - check if my PR is passing CI
  - create a GitHub issue for this bug
  - list open pull requests assigned to me
  - review someone's code changes
  - view failed GitHub Actions logs

README

# openclaw-skill-search

OpenClaw plugin for on-demand skill discovery. Instead of loading all Skills into the system prompt on every turn, Claude searches for relevant Skills on demand using BM25 keyword search (with optional vector/semantic search).

## Why

OpenClaw normally injects every enabled Skill's full content into the system prompt. With 50+ Skills this:
- Consumes thousands of tokens per API call (even with prompt caching)
- Degrades Claude's ability to pick the right Skill as the list grows
- Breaks prompt cache whenever any Skill is updated

This plugin replaces that with an on-demand pattern: Skills are indexed locally, and Claude calls `skill_search` when it needs a specific capability.

## How It Works

```
User sends message
    ↓
Claude receives task involving an external service or workflow
    ↓
Calls skill_search("send a GitHub PR review comment")
    ↓
BM25Index searches skill index in memory
    ↓
Returns matching SKILL.md content to Claude
    ↓
Claude reads the instructions and acts
```

Skills are excluded from the system prompt via `disable-model-invocation: true` in their SKILL.md frontmatter. The plugin injects a system prompt rule telling Claude to call `skill_search` **first** whenever a task involves an external service, app, or multi-step workflow.

## Search Quality

The index is built from each skill's `manifest.yaml` when present. If no `manifest.yaml` exists, the plugin falls back to reading `name` and `description` from the `SKILL.md` frontmatter automatically — so any skill with a `SKILL.md` is searchable out of the box.

When a `manifest.yaml` is present, the BM25 index uses:

| Field | Weight | Notes |
|-------|--------|-------|
| `name` | 2× | Repeated to increase weight |
| `intentExamples` | high | Most important for retrieval — write as real user phrases |
| `semanticDescription` | normal | Short description from user's POV |
| `tags` | normal | Keywords |
| `category` | low | code / communication / content / data |

**To improve search accuracy**, edit `manifest.yaml` and add realistic `intentExamples`:

```yaml
# skills/github/manifest.yaml
intentExamples:
  - check if my PR is passing CI
  - create a GitHub issue for this bug
  - list open pull requests assigned to me
  - review someone's code changes
  - view failed GitHub Actions logs
```

Optionally add vector/semantic search by configuring an OpenAI-compatible embedding API (see Configuration below).

## Installation

```bash
# 1. Install dependencies
cd /path/to/openclaw-skill-search
npm install

# 2. Link to your OpenClaw installation
openclaw plugins install --link /path/to/openclaw-skill-search
openclaw plugins enable skill-search

# 3. Configure skillsDirs (path to your workspace skills)
openclaw config set plugins.entries.skill-search.config.skillsDirs[0] \
  "$HOME/.openclaw/workspace/skills"

# 4. Restart gateway (Mac: menubar → Restart Gateway)
```

## Preparing Skills

Any skill directory containing a `SKILL.md` is indexed automatically — no `manifest.yaml` required. The plugin reads `name` and `description` from the frontmatter as a fallback.

To get better search accuracy, run the migration script which copies bundled OpenClaw skills to your workspace and generates a `manifest.yaml` (with `intentExamples`) for each:
- Copy bundled OpenClaw skills to workspace (upgrade-safe)
- Add `disable-model-invocation: true` to each SKILL.md (excludes from system prompt)
- Generate `manifest.yaml` for higher-quality BM25 indexing

```bash
# From the openclaw source repo directory:
node --import tsx/esm scripts/migrate-skills-to-workspace.ts

# Dry-run first to preview:
node --import tsx/esm scripts/migrate-skills-to-workspace.ts --dry-run
```

## Configuration

All config goes under `plugins.entries.skill-search.config` in `~/.openclaw/openclaw.json`.

```yaml
# ~/.openclaw/openclaw.json (excerpt)
plugins:
  entries:
    skill-search:
      enabled: true
      config:
        # Directories to scan for skills (required)
        skillsDirs:
          - /Users/you/.openclaw/workspace/skills

        # Max results per search (default: 5)
        topK: 5

        # Min relevance score 0–1, 0 = no filter (default: 0)
        minScore: 0

        # Optional: enable vector/semantic search
        # Any OpenAI-compatible embedding API works
        embedding:
          baseUrl: https://ark.cn-beijing.volces.com/api/v3   # ByteDance Ark
          # baseUrl: https://api.openai.com/v1                # OpenAI
          # baseUrl: http://localhost:11434/v1                 # Ollama
          model: doubao-embedding
          apiKey: your-api-key
          timeoutMs: 10000
```

## Upgrade Safety

- **Plugin code** lives in its own directory, independent of OpenClaw
- **Workspace skills** live in `~/.openclaw/workspace/skills/`, never touched by `npm update openclaw`
- **Manifest files** (`manifest.yaml`) are generated once and stay alongside SKILL.md

When OpenClaw upgrades its bundled skills, your workspace copies take precedence (workspace > bundled in OpenClaw's loading order). Re-run the migration script with `--force` to pull in updated SKILL.md content from new OpenClaw versions.

## File Structure

```
openclaw-skill-search/
├── index.ts                 # Plugin entry point
├── openclaw.plugin.json     # Plugin manifest (id, configSchema)
├── package.json
└── src/
    ├── skill-index.ts       # BM25 + cosine vector index + RRF fusion
    ├── skill-registry.ts    # Manifest loader, search, singleton
    ├── skill-search-tool.ts # Claude tool definition
    └── types.ts             # SkillManifest, SkillSearchConfig types
```
tools

Comments

Sign in to leave a comment

Loading comments...