Skip to main content
A Skill is a named, versioned bundle of (system prompt fragment, tool list, optional output template). Agents — both built-in and custom — pull in skills as building blocks when handling specialized tasks. Think of skills as the unix-pipe primitive of the agent surface: small, composable, single-purpose.

When to use a skill vs. a custom agent

ScenarioSkillCustom agent
Reusable behavior shared across multiple agents
Standalone, end-to-end workflow
Quickly testable in isolation
Versioned + auditable
Has its own avatar / persona
Build a skill when the same logic — say, “summarize a campaign in three bullets” — needs to be invoked from Houston, Space Bob, AND a custom Performance Reporter agent. Build a custom agent when the workflow is end-to-end and persona-defined.

Skill shape

A Skill row has:
FieldTypePurpose
skill_idUUIDStable id.
client_idstringTenant scope.
namestringDisplay name.
descriptionstringWhat the skill does.
prompttextSystem prompt fragment, prepended to the agent’s prompt when the skill is active.
toolsJSON listTool keys this skill expects/uses.
output_templatetext | nullOptional Jinja-style template for shaping the skill’s response.
versionintAuto-incremented on save.
is_activebool
created_by, created_at, updated_atmeta
Skills are created via the Skills page in the agent surface. Saving creates a new version (the prior version is preserved for replay).

Markdown skills

skills/markdown.py provides a renderer that converts Skill prompts written in lightweight markdown into the format LangGraph expects. Operators write skills like:
# Skill: campaign-summary

Summarize a campaign's performance in exactly three bullets:

1. Spend, revenue, and ROAS for the period
2. The top-performing creative (by ROAS)
3. The single most actionable issue or opportunity

## Tools
- `get_campaign_performance`
- `get_creative_performance`
- `get_creative_insights`

## Output
- Use markdown bullets (no numbered list).
- No preamble. Start with the first bullet.
- If data is missing, say so explicitly.
The ## Tools and ## Output sections are parsed and applied to the underlying Skill model. The ## Output block becomes the output_template.

Skill chaining + run replay

Two endpoints make skills production-grade:
  • POST /api/skills/<id>/clone/ — fork a skill so you can iterate without breaking the in-use version.
  • POST /api/skills/<id>/run-replay/ — re-run a previous invocation through the current skill version (not the version that ran originally). Surfaces gains from a prompt tweak retroactively.
Both are useful when tuning skill prompts: clone → tweak → replay → compare → either promote or discard.

Invocation paths

Skills are passed into the LangGraph swarm at run time. The agent’s tool list is augmented with the skill’s tools (deduplicated), and the skill’s prompt is prepended to the agent’s system prompt. Three places this happens:
  1. In-chat — a user runs /skill <name> (the chat parser detects the slash command and loads the skill into the next turn’s context).
  2. Custom agent — a custom agent’s tool list can include run_skill:<skill_id>, which is a meta-tool that the agent calls when it wants to invoke a skill mid-conversation.
  3. Automation — the run_agent action accepts a skill_id field; if set, the skill is loaded into the one-shot run.

Endpoints

List skills the caller can see. Tenant-scoped.
POST /api/skills/
Create a new skill. Body: { name, description, prompt, tools, output_template? }.
Fetch a single skill (latest version).
List historical versions of a skill.
POST /api/skills/<id>/clone/
Fork a skill into a new id. Useful for A/B-testing prompt variants.
POST /api/skills/<id>/run-replay/
Replay a prior run through the skill’s current version. Returns the new run’s output for diffing.
All gated by shared.permissions.AgentSurfaceAllowed.

Worked example

A “Hook Diagnoser” skill that any creative-savvy agent can call:
# Skill: hook-diagnoser

Given a creative_id, produce a 5-bullet diagnosis:

1. **Archetype + confidence** — what hook archetype this is and how confident.
2. **Strengths** — 1-2 things this hook does well.
3. **Weaknesses** — 1-2 things hurting this hook.
4. **Recommended fixes** — 1-2 concrete production-level changes to test.
5. **Closest match** — the most-similar already-tested creative in the library
   (concept-similarity, not visual-twin).

## Tools
- `recommend_next_creative_brief`
- `find_similar_creatives`
- `analyze_hook_exhaustion`

## Output
Use ` - ` bullets. No preamble. Reference the creative_id in the title.
Wired into Space Bob via tools: ['run_skill:hook-diagnoser', ...]. When a user says “diagnose creative-abc-123”, Space Bob calls the skill, which calls find_similar_creatives + recommend_next_creative_brief and shapes the response per the skill’s output template.

Where the code lives

ConcernPath
Modelskills/models.py
Markdown parserskills/markdown.py
API viewsskills/views.py
URL routesskills/urls.py
Frontend skill editorl5ui/src/app/components/skills/
Swarm wiringai_chat/graph.py