English · 中文
skill+ — a skill that knows what stage it's in, and feeds the right tips into each turn.
skill+ is a small, backward-compatible extension to the Agent Skills format.
You keep writing a normal SKILL.md; skill+ lets you add two optional things:
- a
flow— a short outline of the stages the task moves through, and rules/— soft advice and hard guardrails, each scoped with awhen:.
A runtime that understands skill+ then does one thing a plain skill can't: it tracks which stage you're in and injects only the knowledge and rules relevant to that stage into each turn's context — just-in-time, instead of dumping the whole manual up front.
It's still a skill. Delete the flow and rules/ and you're back to an ordinary skill. skill+ is a strict superset — the extras are opt-in.
Status: spec-first. This repo opens the idea, the format spec, and the design (
docs/spec.md,docs/design.md). A reference implementation lives behind theskillplus/package skeleton and is not written yet. Expect the spec to move; everything marked 🚧 is undecided.
A plain skill hands the model one flat block of prose and every tool at once, with no sense of where in the task it is. And as you keep piling more .md and more scripts into one skill to cover more cases, the model's ability to actually follow it degrades: the longer and busier the prompt, the more instructions get diluted, skipped, or half-applied. That's most costly where determinism matters — finance, law, compliance — where "mostly followed the procedure" isn't good enough.
skill+ treats process as a kind of knowledge and attacks the problem from two sides:
- Stage-scoped context — naming the stages a task moves through gives you hooks to hang knowledge on. A tip or rule attached to
stage=deep-diveis injected into the turn-level context only when you reach that stage, once, then left in history. The model sees less, and more of what it sees is relevant — so it follows it more reliably. - In-turn hooks — a
.py/.shrule runs inside the turn as a gate: it can read a live fact and stop or require approval before an irreversible or non-compliant action. That's a hard guarantee that doesn't rely on the model remembering an instruction.
Won't stronger models just fix this? Maybe — as models improve, even a fat, sprawling skill may be followed more faithfully. But the same jump makes skill+ better too, and by more: it's guided, not enforced (the flow is a map the model reads, not a graph an engine walks — the model still drives), so a stronger model runs the same skill+ better, with no rewrite. You're not betting against stronger models; you're handing a stronger model cleaner context and explicit guardrails so it can be even more reliable.
| a plain skill | a skill+ | |
|---|---|---|
| Carrier | SKILL.md (prose) |
SKILL.md + a flow + scoped rules/ |
| What the model sees | one flat block, every turn | a map + where you are + the slice that matters now |
| As knowledge grows | the manual gets longer & noisier | knowledge/rules accumulate, the prompt stays lean |
| As models improve | helps only so much | the same skill+ gets better, no rewrite |
| Best for | one-shot, exploratory, fuzzy-boundary tasks | repeated, staged tasks where knowledge accumulates |
skill+ sits on top of skills, it doesn't replace them: a worker inside a skill+ can still load plain skills; fuzzy sub-tasks should still be plain skills.
recommend-stocks/
├── SKILL.md # required — a normal skill (frontmatter + body)
├── flow.py # optional — the flow (stages + state) as a small Python eDSL
├── rules/ # optional — soft advice & hard guardrails, each with a when:
│ ├── suitability.py # hard: block if the risk assessment hasn't passed
│ ├── disclaimer.md # hard: output must carry a risk disclaimer
│ └── diversify.md # soft: prefer spreading across sectors
├── scripts/ # optional — callable tools (always available)
└── references/ # optional — knowledge files (a when: makes them stage-scoped tips)
SKILL.md — this is just a skill, unchanged:
---
name: recommend-stocks
description: Recommend stocks — check risk suitability, ask preferences, screen, research, then give a Top 3. Use when the user asks which stock to pick or buy.
---
Move through: suitability → preferences → screen → research → recommend.
Decide mechanically where you can; every conclusion carries a risk disclaimer.flow.py — the flow declares the stages and a typed state. build(flow) declares an IR; it does not execute business logic:
from skillplus import Flow, State
class StockState(State): # domain fields only; the base carries position + persistence
risk_level: str | None = None
profile_fresh: bool = False
candidates: list = []
def build(flow: Flow): # declarative — builds the IR, does not run
flow.stage("load-profile", tool=scripts.get_profile)
with flow.branch(lambda s: not s.profile_fresh):
flow.stage("kyc", rule=rules.suitability) # hard rule: block if assessment fails
flow.ask("ask-preference", "ask sector / horizon / ESG")
with flow.loop("screen", until=lambda s: len(s.candidates) <= 3, max=4):
flow.stage("filter", tool=scripts.apply_filters)
with flow.fanout("deep-dive", over=lambda s: s.candidates):
flow.agent("analyze", prompt="research {item.ticker}: fundamentals + news + risk")
flow.stage("recommend", rule=rules.disclaimer) # hard rule: must carry a disclaimerThe full version is in
examples/recommend-stocks/.
flow.pyis provisional. A Python eDSL is how this repo expresses the idea for now — not a claim that it's the best authoring surface. The flow is fundamentally an IR; the eDSL is just one front-end, and the right surface (quite possibly something more natural-language) is an open question — seedocs/design.md.
rules/ — two orthogonal axes: on_fail sets soft vs hard, the extension sets delivery (.md = injected text the model reads, .py/.sh = a machine-enforced check):
<!-- rules/disclaimer.md — hard + md: injected as a strong instruction, trust the model -->
---
on_fail: ask
when: stage=recommend
---
Every recommendation must explicitly include a risk disclaimer and a "not investment advice" note. If it's missing, stop and add it before sending.references/high-vol-market.md — a knowledge file with a when: is a stage/condition-scoped tip:
---
when: market=volatile
---
In turbulent markets, prefer low-beta names and call out drawdown risk explicitly.The runtime routes to the skill, renders "the map + where you are + the tips/soft-rules that match right now" into context, runs tools, tracks state, enforces hard rules, and pauses at ask/confirm. You only write the skill+.
The point isn't "give the model a map." It's this chain:
a flow gives the task well-defined positions (stages)
→ position + domain facts become a small structured state
→ each turn, state decides what to inject (the right tips, the matching rules)
A flow's real job is to cut the task into named hooks (stages) so knowledge and rules light up only on the hook, only when you arrive. A tip scoped when: stage=deep-dive is injected the first time you hit that stage and never re-injected — it stays in history. That's anti-dilution: never inject the irrelevant, never re-inject the already-said. A plain skill can't do this — it has no well-defined position to condition on.
| You want | Read |
|---|---|
| What it is / how to use it | this README |
The exact format (directory, frontmatter, flow primitives, when, rules, validation) |
docs/spec.md |
| Why it's designed this way / the conceptual execution model / where it sits in the field | docs/design.md |
skill+ is guided by design — strict, deterministic execution is explicitly a non-goal (see docs/design.md). The format spec is a v0 draft. The skillplus/ package is a skeleton with no implementation yet; a first reference runtime would cover: routing (an Agent Skills registry that recognizes a flow/rules/), building the flow IR, the two-layer context (resident map + scenario-gated injection), a small persisted state, and hard-rule guardrails.
This is an early, evolving spec — issues and proposals on the format are very welcome, especially on the open questions marked 🚧 in the spec and design docs.
License: TBD (see repo settings).