-
Notifications
You must be signed in to change notification settings - Fork 1
features skills
Skills are named markdown instruction packets the model loads on demand. You write the "how" of a task once (a review rubric, a house style, a checklist), and the agent pulls it into context only when it decides the task calls for it — so the playbook is reusable and the context window stays cheap.
| What | A folder ~/.evi/skills/<name>/ containing a SKILL.md file with optional frontmatter + a markdown body of instructions. |
| How the model uses it | Every skill's one-line index (name + description) is injected into the system prompt. The model calls the invoke_skill(name) tool to pull the full body when it judges the skill relevant. |
| Where |
~/.evi/skills/ (yours) and ~/.evi/plugins/<plugin>/skills/ (plugin-supplied, exposed as <plugin>:<skill>). |
| Toggle |
[tools] skills = true (the default). |
Skills vs the neighbours:
- Skill — behavioural instructions the model loads itself when relevant. No arguments, not triggered by you typing anything.
-
Slash command (Slash commands) — a prompt template
you fire by typing
/name, with$ARGUMENTS. Deterministic, user-initiated. - Recipe (Recipes, Routines, Scheduled tasks, Channels) — a fixed sequence of prompts run start-to-finish through one conversation.
Reach for a skill when you want the model to consistently apply a method ("review code like this", "summarise papers like this") without restating it every time, and without forcing it on turns where it doesn't apply.
evi/skills.py defines a read-only SkillStore:
-
Discovery — on every call it rescans
~/.evi/skills/plus each installed plugin'sskills/directory, so a freshly added skill shows up without restarting the long-lived web/desktop process. Each skill is a directory containingSKILL.md(the directory layout leaves room for skill-local assets — helper scripts, sample data — without colliding with the instructions file). -
The index —
format_for_prompt()renders an## Available skillsblock (one- **name** — descriptionline each) and appendsCall invoke_skill(name) to load the full instructions.This block is added to the agent's system prompt when[tools] skillsis on and at least one skill exists. -
Loading — the model calls the
invoke_skill(name)tool (evi/tools/skills.py), which returns theSKILL.mdbody with frontmatter stripped. A companionlist_skillstool returns the index as JSON. Both are in theskillstool category. - No auto-firing. eVi deliberately does not keyword-match skills into the prompt. The model sees the menu and chooses — which keeps token use predictable and the model's behaviour debuggable. (If you want metadata-triggered or argument-driven behaviour, use a slash command or recipe instead.)
---
name: code-review
description: Review a diff for correctness, style, and security issues.
---
# Body — the actual instructions the model follows once loaded
Step 1 …
Step 2 …-
Frontmatter is an optional
----delimited block at the very top.-
name— overrides the folder name as the skill's id. If omitted, the folder name is used. Must match[A-Za-z0-9_-]+. -
description— the one-liner shown in the index (so the model can decide whether to load it). Falls back to(no description).
-
-
Body — everything after the frontmatter. This is what
invoke_skillreturns. Write it as direct instructions to the model: ordered steps, a priority list, and an explicit output format work best.
| Path | What |
|---|---|
~/.evi/skills/<name>/SKILL.md |
One skill. <name> is the folder; frontmatter name overrides the id. |
~/.evi/skills/<name>/… |
Optional skill-local assets (scripts, data) — eVi only reads SKILL.md. |
~/.evi/plugins/<plugin>/skills/<skill>/SKILL.md |
A plugin-supplied skill, surfaced as <plugin>:<skill>. |
# ~/.evi/config.toml
[tools]
skills = true # default; set false to drop the skill index + invoke_skill toolThe repo ships two ready-to-use skills under examples/skills/:
# one skill
mkdir -p ~/.evi/skills/code-review
cp examples/skills/code-review/SKILL.md ~/.evi/skills/code-review/
# or all of them
cp -r examples/skills/* ~/.evi/skills/Skills are model-driven — you don't type a skill (that's a slash command). There is a small CLI for managing them:
evi skill list # installed skills (yours + plugin skills)
evi skill show <name> # print a skill's description, body, bundled files
evi skill import <dir-or-SKILL.md> # copy a skill into ~/.evi/skills/
evi skill import <dir> --name foo --rewrite-paths --force
evi skill remove <name> # delete a user skill (~/.evi/skills/<name>/)remove only touches your own skills; a plugin skill (<plugin>:<skill>) is
owned by its plugin — remove it with evi plugin remove <plugin>.
Once installed:
- Start a chat (
evi chat, or the web/desktop app). - The agent's system prompt now lists your skills.
- When a turn matches a skill, the model calls
invoke_skill(<name>)and then follows the loaded instructions. You'll see theinvoke_skilltool call in the transcript / tool activity. If the skill bundles companion files, their absolute paths are appended to the loaded text so the model can read them with its file tools.
To nudge it explicitly, just ask: "review this diff" with a code-review skill
installed, or "use the summarize-paper skill on this PDF". To confirm what's
available, ask the model to call list_skills, or look in ~/.evi/skills/.
Skills work identically in the CLI, web, and desktop frontends — they're a property of the agent, not the UI.
~/.evi/skills/code-review/SKILL.md (the bundled example, abridged):
---
name: code-review
description: Review a diff for correctness, style, and security issues.
---
# Code review skill
When asked to review code, follow these steps in order:
## 1. Understand the change
- Read the diff in full before commenting.
## 2. Correctness pass (highest priority)
- Off-by-one errors, resource leaks, concurrency bugs, error handling,
security smells (string-built SQL/shell, secrets in code).
## 3. Style pass (lower priority)
- Follow the project's existing conventions, not your favourites.
## Output format
**Summary:** <one sentence>
### Correctness
- <issue> (`path/to/file.ext:42`)Then: evi chat → "review the staged diff" → the model loads the skill and
produces output in your fixed format, every time.
mkdir -p ~/.evi/skills/sql-explain
cat > ~/.evi/skills/sql-explain/SKILL.md <<'EOF'
---
name: sql-explain
description: Explain a SQL query in plain English and flag slow patterns.
---
# SQL explainer
1. Restate what the query returns in one sentence.
2. Walk the joins in execution order.
3. Flag full-table scans, N+1 patterns, and missing-index smells.
4. End with a one-line "Bottom line:" verdict.
EOF(That's just an illustration — examples/skills/sql-explain/ ships it too.)
A plugin that ships skills/threat-model/SKILL.md exposes it as
plugin-name:threat-model in the index once installed
(evi plugin add <dir-or-git-url>). See Plugins & Marketplace.
eVi's SKILL.md shape is the same one Claude Agent Skills use, so a Claude
skill folder is essentially drop-in:
evi skill import path/to/claude-skill # copies it into ~/.evi/skills/
evi skill import path/to/claude-skill --rewrite-paths # also fix relative refsWhat carries over and what doesn't:
- ✅
name+descriptionfrontmatter → eVi's skill index. Extra Claude keys (license,allowed-tools,metadata, …) are read but ignored — they don't break anything. - ✅ The instruction body is used verbatim as the
invoke_skillpayload. - ✅ Bundled files (a
reference.md, ascripts/dir, assets) are copied in, and when the model invokes the skill their absolute paths are appended to the loaded text — so the model canread_file/ run them on its own (it needs the relevant tools enabled). ⚠️ allowed-toolsis not enforced. eVi gates tools through its own permissions/modes, not the skill's frontmatter.⚠️ Frontmatter is single-linekey: value(not full YAML). A multi-line folded/literaldescription:would be truncated — keep it on one line.-
--rewrite-pathsrewrites standalone relative references inSKILL.md(e.g.reference.md,scripts/fill.py) to their absolute installed paths, so the model finds them regardless of its working directory.
Self-contained Claude skills (all instructions in SKILL.md) work with a plain
evi skill import; skills that lean on companion files work best with
--rewrite-paths (and the auto-appended file list as a backstop).
-
SKILL.mdis the entry point. Its body is whatinvoke_skillreturns; other files in the folder aren't loaded into the prompt, but their paths are surfaced to the model (see above) so it can read them on demand. -
Names must match
[A-Za-z0-9_-]+; skills that fail validation are skipped silently rather than erroring the whole list. -
Names must match
[A-Za-z0-9_-]+; skills that fail validation are skipped silently rather than erroring the whole list. - No arguments / no triggers. A skill is static instructions. For argument-substituted templates you fire by hand, use a slash command; for a fixed multi-step run, a recipe.
-
The model chooses. If a skill isn't being picked up, sharpen its
descriptionso the relevance is obvious from the one-line index, or ask for it by name. -
Context cost is just the one-line index per skill until
invoke_skillis called — so a big library of skills stays cheap.
Generated from docs/features/skills.md — edit there, not here.
Start here
Guides
- Architecture
- [[Agent SDK (
evi.sdk)|sdk]] - SDK coverage + borrowable features
- Multi-machine setup
- Self-update design (Phase 29 proposal)
- [[Self-build — developing and building eVi with eVi|self-build]]
- Development notes
- Releasing
- Desktop bundling
- Code signing policy
- Surface parity — CLI ↔ Web ↔ Desktop
- eVi vs Claude Code — feature comparison
- Future integrations — backlog
- Roadmap
Feature deep-dives
- eVi feature guides
- Agents & Orchestration
- Recipes, Routines, Scheduled tasks, Channels
- Evals & LLM-as-judge
- Content Guardrails
- Hooks (tool + lifecycle, command/url)
- MCP (client + serve)
- Memory & Context management
- Observability (OpenTelemetry, stats, crash reports)
- Permissions & Sandbox
- Plugins & Marketplace
- Sessions, Resume, Handoff, Checkpoints
- Skills
- Slash commands
- Structured Outputs & Batch
- Ultracode
- Voice (TTS engines, STT, AutoSpeaker)
- Web & Desktop (settings, multi-user, deep links, updater)