Chapter 13: Putting Experience into an Instruction Manual — Skill

Xiao A noticed that every time his team did a code review, they repeated the same instructions to the Agent: check the blast radius first, run the tests, verify the permissions, and don't rush to say "ready to merge." As he recited them yet again, he thought: this is far too wasteful.
"Can we save this whole routine somewhere and have the Agent follow it every time?" he asked Lao Z.
"We can. External capabilities already have their integration boundary — what you've run into is a different problem: tasks of the same kind repeatedly need checklists, conventions, and reference material. This kind of reusable work instruction is what people call a Skill," Lao Z said. "One warning first: 'Skill' has no cross-platform definition. This chapter treats it as an engineering pattern — organizing experience into discoverable, on-demand instructions — without assuming any particular file format or automatic trigger mechanism."
Align the names first
| Term | English / abbreviation | Working definition in this book | What it is not |
|---|---|---|---|
| skill | Skill | a discoverable, on-demand-loaded instruction capturing task experience; not an industry-standard protocol | an executable Tool |
| instruction bundle | instruction bundle | the combination of applicability conditions, steps, reference material, tools, and acceptance criteria | an enforcement engine |
| discovery / trigger / progressive loading | discovery / trigger / progressive loading | the three steps of reading the index first, judging applicability, then loading the body | a guarantee that the model chooses correctly |
| soft constraint | soft constraint | a rule that influences the model's decisions through text | code-level permission or validation |
What a Skill contains, and where it stops
"What goes inside a Skill?"
"Applicability conditions, the goal, the steps, the tools available, input and output constraints, exceptions, and the acceptance method — usually these," Lao Z said. "The carrier isn't fixed: a Markdown file, a database record, code configuration, any of them work. What matters is that the content is reviewable, versionable, and verifiable. The format itself is not that important."
"Can you go through those seven parts one by one?"
"Sure. Take a 'code review' Skill as the sample and open it up item by item:"
| Component | Example in a code-review Skill | Consequence of writing it loosely |
|---|---|---|
| applicability conditions | "code changes ready to merge into the main branch" | written as "code-related tasks" → triggers on any task |
| goal | "confirm the change is safe to merge and leave a traceable review record" | missing goal → the model doesn't know what to produce when done |
| steps | blast radius → run tests → check permissions → output the conclusion | unordered steps → the model skips or misses steps |
| tools available | read, run_test, git_diff | undeclared → the model uses the wrong tool or no tool |
| input constraints | "the list of files touched by the change, the target branch" | unconstrained → the model reviews unrelated files |
| output constraints | "conclusion + test results + risk list" | unconstrained → a prose blob that no one can accept |
| exceptions | "if tests can't run, flag it and hand off to a human" | no exception → it stalls at an obstacle or invents a result |
| acceptance | "each step has a result; the conclusion can be re-checked by another person" | not verifiable → no one knows whether it's done |
"You don't have to write all eight parts into every Skill," Lao Z added. "But whichever part you leave out, you leave its risk to runtime. Applicability conditions and acceptance are the two bottom lines: the first decides whether the Skill should be loaded at all, the second decides whether loading it counted as finishing. The more complete the rest is, the more reliably the model follows it."
"Which of these are easiest to write loosely?"
"The applicability conditions and the acceptance method," Lao Z said. "If the applicability conditions are vague, the model loads the Skill in the wrong scenario — applying a 'pre-release check' to an ordinary draft, for example. If acceptance isn't observable — 'check carefully' — then even after loading it you can't tell whether the job is done. A usable Skill must answer at least two questions: when should it be used, and what counts as finished using it."
"I keep confusing the relationship between Skill, Tool, and MCP," Xiao A said.
Lao Z laid the three out in one table:
| Concept | The main question it answers | Constraint strength |
|---|---|---|
| Tool | what actions can be executed | determined by the implementation and the permissions |
| MCP | how external capabilities are discovered and exchanged | determined by the protocol and the host |
| Skill | how to organize actions when facing a task | usually a soft constraint |
"The three live at different layers," Lao Z said, pointing at the table. "A Skill needs to call Tools to actually do anything, and it may discover resources through MCP, but it is itself only an instruction manual. It replaces none of those layers."
"If a Skill says 'run tests before releasing,' is it guaranteed to run them?"
"No. The model can overlook it, misread it, or simply ignore the text," Lao Z said. "Preconditions that must be enforced belong in CI, tool validation, approvals, or permission controls. The value of a Skill is that it makes the correct path clearer; it cannot replace those mechanisms. A simple test: any step whose failure would cause irreversible consequences cannot rely on a Skill alone — it needs a hard constraint underneath it."
"Then what's the difference from a System Prompt? Aren't both just text written for the model?"
"Different lifecycles," Lao Z said. "A System Prompt is a resident rule present in every request; it declares the boundaries that always apply. A Skill loads on demand and enters the context only in specific task scenarios. The System Prompt is a load-bearing wall of the house — it can't be too thick. A Skill is an instruction manual you pick up when needed — it can be written in great detail, since it isn't loaded every time."
Metaphor: the job handbook
No matter how well a handbook is written, it cannot guarantee everyone follows it; the steps that must be guaranteed rely on a gate. The Skill is the handbook (a soft constraint); the gate is code (a hard constraint).
Discovery and on-demand loading
"Then why not just cram every Skill into the prompt and be done in one step?"
"Don't. Putting full texts into the context both crowds out the task space and lets unrelated rules interfere with each other," Lao Z said. "The sound split is two tiers: load the index first — name, description, applicability scope. Only when the task genuinely matches, or the user explicitly names the Skill, do you load the body. Matching can be done by rules, by the user, or by the model. The three have different false-trigger rates and different explainability — you can't just say 'automatic must be right.'"
"What's the difference between those three triggers?"
"Different costs," Lao Z said. "Rule triggering is explainable and testable, but its conditions are hard-coded and can't cover scenarios you didn't anticipate. User selection is accurate, but the interaction burden falls on the human. Model judgment has wide coverage but can misfire and drag in irrelevant Skills — at best a waste of context, at worst a source of conflicting rules. Most systems mix them: critical Skills fall back to rules or the user, only auxiliary ones go to model judgment, and all of them keep logs."
Lao Z laid out the differences in a table:
| Trigger method | Accuracy | Coverage | Cost |
|---|---|---|---|
| rule matching | high (explicit conditions) | low (only predefined conditions) | maintaining the conditions |
| user selection | highest (a human decides) | depends on what users know | interaction burden |
| model judgment | medium (can misfire) | high (semantic matching) | false triggers occupying context |
"Can the index itself go wrong?"
"It can. The index is a snapshot of the Skill: name, description, applicability scope," Lao Z said. "If you edit the body and the index doesn't follow, the model reads a stale description. An index may say 'applies to all TypeScript projects' while a particular Skill actually targets only the test framework. Once the index drifts, every trigger decision rests on outdated or over-broad information. So the index and the body must be versioned together, and the loading log must record both versions."
"What about the body once it's loaded?"
"Label its source and version too. Then when an answer or a behavior goes wrong, you can trace whether it was a reasoning problem in the model, an outdated instruction, or simply a Skill that was loaded wrongly in the first place."
"So how long does that body stay in the context?"
"That's a trade-off," Lao Z said. "Keep it, and it takes space every turn, but the model can refer back to it repeatedly. Drop it when done, and you save space, but the model may forget it in later turns. The common practice keys off reference frequency: step-type Skills — one-shot checklists — get removed once used; rule-type Skills — conventions that span the whole task — stay until the task ends. Either way, when you remove it, write a record into the message history saying 'the Skill at version X has been removed from the context,' so audits have evidence."
Why a soft constraint is soft
"I still don't fully see what makes a 'soft constraint' soft," Xiao A said. "The Skill is written in such detail — how could the model not follow it?"
"Because instructions and data travel through the same channel," Lao Z said. "When the model receives the context, mechanistically it cannot tell 'this is a rule I must obey' apart from 'this is reference text.' All it sees are tokens. It continues in the most probable way — and 'most probable' does not mean 'follows the Skill.'"
"Is there any way to make the constraint hard?"
"There is: change the channel," Lao Z said. "A hard constraint doesn't go through text; it goes through code: the tool executor refuses, the permission layer blocks, CI enforces the check. These don't depend on the model's self-discipline — they execute outside the model and can't be routed around. A soft constraint influences the probability of the model's decisions; a hard constraint bounds the model's range of action. Use them together: the former makes the correct path easier to pick, the latter guarantees that when it isn't picked, nothing spirals out of control."
Key point
A soft constraint is soft because it shares one channel with ordinary text, and the model decides whether to follow it by probability. For the steps that must be guaranteed, use code-level hard constraints — not words.
"What does failure look like for a soft constraint?"
"At least three kinds," Lao Z listed them:
| Failure scenario | Symptom | Root cause |
|---|---|---|
| omission | the Skill requires running tests; the model jumps straight to the conclusion | with many steps, the model may skip some |
| misreading | the Skill requires "list the blast radius"; the model lists a pile of unrelated files | ambiguous description or a gap in the model's understanding |
| conflict | the Skill forbids declaring the change merge-ready; the model still writes "ready to merge" at the end | the task's momentum overrides the rule |
"None of these three is a bug," Lao Z added. "They are inherent properties of a soft constraint. The response isn't to 'write a harsher Skill' but to pair the critical steps with hard constraints: if tests get skipped, block the merge at the gate; if the model wants to declare it merge-ready, stop the tool layer from ever emitting that word."
Writing instructions as an executable checklist
"Can I see an example?"
"Sure. This one is illustrative and doesn't bind to any system:"
---
name: review-change
when: "When a code change is ready to merge"
---
1. Describe the blast radius of this change.
2. Run the tests for the affected modules, and record the commands and results.
3. If permissions or network access are involved, list the new boundaries and request confirmation.
4. Until every item is complete, do not declare the change merge-ready."Does 'describe the blast radius' count as a good step?"
"It does — it's observable," Lao Z said. "A good instruction states a completion condition someone can verify. 'Check the code carefully' is impossible to accept. There's a simple test for whether a step is written well: hand it alone to a colleague who knows no context, and see whether they can carry it out and say, clearly, 'done' or 'not done.'"
Lao Z sorted the common ways of writing steps into a table:
| Step wording | Observable? | Problem |
|---|---|---|
| "Run the tests of the affected modules; record the commands and results" | yes | none |
| "Carefully check the code quality" | no | completion state can't be judged |
| "List the blast radius of this change" | yes | another person can re-check the scope |
| "Make sure there are no security issues" | no | "make sure" has no acceptance criterion |
"So for a step like 'carefully check the code quality,' hand it to that colleague and he'd most likely ask back: check what? Against what standard?"
Lao Z laid out the rewrites of a few vague steps:
| Vague step | The colleague's question | Rewritten |
|---|---|---|
| "check code quality" | check what? against what standard? | "run npm test and record the pass/fail counts" |
| "ensure security" | ensure how? what counts as secure? | "list the permission changes this change involves; write 'none' if there are none" |
| "optimize performance" | optimize what? to what target? | "measure the duration of npm run bench before and after the change, and record the difference" |
| "review the code" | look at what? output what? | "read the diff and list, per file, the potential risks with reasons" |
"What about dangerous operations, then?"
"The Skill should delegate dangerous operations to hard constraints, not write secrets, bypass methods, or unlimited privileges into the context," Lao Z said. "Illustratively: the Skill says 'deployment requires approval,' while the approval itself is enforced by a tool or a workflow engine; the Skill only reminds everyone that this step exists — it takes no enforcement responsibility. Writing a key or bypass logic into a Skill means putting sensitive information into the model's context, which only widens the exposure surface."
"What if the steps depend on each other?"
"Write the order into the instructions; don't let the model guess," Lao Z said. "For example, 'run the tests first; once they pass, request approval; commit only after the approval comes through' — the completion of each step is the precondition of the next. A Skill can express order but cannot enforce it. If you truly need a guarantee, rely on the tool's state checks or a workflow engine — not on the numbering inside the instructions."
"Measure acceptance with the same yardstick," Lao Z added. "'Looks good' measures no result; only 'all tests pass' can be verified."
Wrong choices and conflicting rules
"What if the model picks the wrong Skill?"
"Choosing the Skill is itself a fallible decision: the index may miss the instruction that should have loaded, and semantic matching can pair a 'pre-release check' with an ordinary draft task," Lao Z said. "Illustratively: two Skills, one requiring 'generate a preview only,' the other requiring 'execute the commit.' On conflict, the system adjudicates by task phase, explicit user selection, or a predefined priority, and records the adjudication. If it can't decide, it requests clarification — it must not let the model blend the steps of both Skills and pretend both were completed."
"How do you tell whether the wrong Skill was chosen or the model simply didn't follow it?"
"Keep the loading log and the execution log separate," Lao Z said. "The loading log records which Skill was loaded under which conditions and at which version; the execution log records what the model actually did and the status of each step. Only when you lay the two side by side can the problem be located: loaded correctly but not followed is a model-adherence problem; loaded wrongly is a trigger or description problem. Without these two logs, failure diagnosis is guesswork."
"When several Skills apply at once, what's the adjudication order?"
"Follow this priority chain:"
1. Explicit user selection ── highest priority, adopt directly
│(when there is no explicit selection)
↓
2. Mutual-exclusion check ── are the two Skills marked mutually exclusive? → stop and request clarification
│(when they are not mutually exclusive)
↓
3. Predefined priority ── does the configuration declare who wins? → adopt the higher-priority one
│(when no priority is declared)
↓
4. Task-phase judgment ── which phase are we in right now? → adopt the one matching the phase
│(when it still can't be decided)
↓
5. Request clarification ── never let the model blend the two on its own"The last step is the key: if you can't adjudicate, request clarification — never let the model blend two sets of steps and pretend both were done," Lao Z stressed. "Blending is the most dangerous outcome: it produces a result that looks plausible while satisfying neither Skill's requirements."
"What does a blend actually look like?"
"Two Skills: A requires 'generate a preview only, modify no files'; B requires 'modify directly and commit'," Lao Z said. "Blend them, and you can get 'the files were modified but not committed, and it claims it only generated a preview': the files were touched, so A's read-only requirement is broken, and B's commit requirement is unmet. That blended artifact is harder to diagnose than simply choosing one of the two wrongly."
Treating instructions as version-controlled inputs
"Then how do you manage the Skills themselves? You can't just write them and walk away."
"Manage them as version-controlled inputs," Lao Z said. "A Skill for release changes carries its check scope, test commands, human confirmation points, and output template. The discovery phase reads only the name, description, version, and applicability scope; the trigger phase decides by user selection, rules, or model matching; only the loading phase brings the body and its referenced material into the context. Keep a log at each of the three phases, and when something goes wrong you can tell whether the description was inaccurate, the trigger fired wrongly, or the model didn't follow."
"When two Skills apply at once, can't we just order them in the prompt and call it a day?"
"No — that's gambling," Lao Z said. "Adjudication goes through priorities, mutual-exclusion labels, or merge rules. When the requirements conflict — one read-only, one write, for example — stop and hand the choice to a human. Don't stitch two instructions together."
"After a Skill is edited, how do you verify you didn't break it?"
"For each version change, run it against a fixed test set: did the instruction that should load actually load, did the tools that should be called get called, did any non-skippable hard constraint break," Lao Z said. "Skills go stale. Business processes change, tool signatures change, security policies change — and the old Skill is out of touch with reality. So treat it as a version-controlled input, not as a truth you write once and never revisit."
"What does staleness look like?"
"Three typical kinds," Lao Z said, and wrote three lines on paper:
| Drift type | Symptom | Cause |
|---|---|---|
| tool-signature drift | the Skill says 'call run_test,' but the tool has been renamed to run_tests | the Skill wasn't updated after the tool was refactored |
| process drift | the Skill requires 'commit to the main branch,' but the team has moved to a PR workflow | the team convention changed and the Skill didn't follow |
| security-policy drift | the Skill says 'notify Slack before deploying,' but the notification channel has changed | an infrastructure change never propagated to the Skill |
"What the three kinds of drift have in common is that the world the Skill describes no longer matches the real world," Lao Z said. "That's why a stale Skill is more dangerous than no Skill at all: with none, the model explores cautiously; with a stale one, the model confidently takes the wrong path."
"How do you detect drift?"
"With two kinds of signals," Lao Z said. "One is active inspection: periodically compare the tool names, branch names, and command names the Skill references against the current system, and flag anything that doesn't match. The other is passive capture: when the model acts per the Skill yet fails frequently — tool not found, branch not found, command errors — those failure signals are evidence of drift. Both must land in logs, or the drift keeps lurking until some incident exposes it."
"What about Hooks? Earlier you said Skill, Tool, and MCP each own a layer."
"A Hook is runtime intervention," Lao Z said. "The Skill replaces none of these layers. It is one layer of organized experience instructions, so that when the model faces a recurring task, there is one clear, correct path to follow."
The Skill catalog and namespaces
"When there are lots of Skills, how do you manage them?"
"Just like code, they proliferate — so you need a catalog and namespaces," Lao Z said. "Dozens of Skills spread flat in one directory and the index gets harder and harder to maintain: descriptions overlap each other, applicability conditions collide, names are arbitrary. Layering is the first step of engineering it, for exactly the same reason code gets split into packages."
"How do you split? By project?"
"By responsibility," Lao Z said. "The common split is three layers: global-generic, team-convention, project-specific. Project-specific Skills bind to a particular project or repository; team-convention Skills collect process agreements. The three layers differ in applicability scope, update cadence, and permissions:"
| Layer | Applicability scope | Update cadence | Permissions |
|---|---|---|---|
| global-generic | all sessions | slow, requires review | platform admins |
| team-convention | a specific team | medium, team review | team members |
| project-specific | a specific project | fast, follows the project | project maintainers |
"And namespaces?"
"They solve same-name conflicts," Lao Z said. "Different teams may each have a review Skill with completely different content. Prefix the names with namespaces — eng-review, sec-review — and the origin is obvious at a glance, and the loading log shows at a glance which one was used. Leave the conflict unhandled, and the model swings between two same-named Skills, and the logs can't tell them apart either."
"Who maintains these catalogs and namespaces?"
"There must be a clear owner," Lao Z said. "Skills are assets that need maintenance: new ones need review, changes need testing, stale ones need cleanup. A Skill catalog without an owner rots like a codebase without an owner: more and more, older and older, and no one dares touch it. Marking every Skill with an owner is the minimum requirement for maintainability."
"How many Skills can one task load? Is there a budget?"
"There should be — this is another budget people commonly forget," Lao Z said. "Every body takes context space; three carefully written Skills can easily eat several thousand tokens. Set the loading budget together with the task budget: the question isn't whether a Skill can be loaded, but whether this Skill is worth the slice of context it occupies."
"What happens if too many get loaded?"
"The symptom is a swollen context and a task that got no clearer," Lao Z said. "Facing a pile of Skills, the model either nibbles at each one and its behavior gets diluted, or it grabs the most conspicuous one and ignores the rest. Overloading is as bad as having no Skills at all — the only difference is that one looks well-prepared and the other plainly isn't. The test is: after adding this Skill, did task success rate or quality actually improve? Not 'does it have everything it should.'"
"Is there a simple budget rule?"
"There's a practical starting point, but nothing absolute," Lao Z said. "Load the index by default; keep no more than 2–3 bodies loaded at once, with a cap on total words. For a task over budget, use the single most relevant Skill first and demote the rest to 'description available.' This rule isn't universal, but it's far safer than unbounded loading: keeping a budget means leaving context space for the task itself."
A running scenario: the full Skill lifecycle of one release review
"Can you thread one scenario through from beginning to end?"
"Sure. Suppose there's a release-review Skill; follow it from discovery to the end of the task."
Lao Z drew a timeline:
task starts: the user says "review this release for me"
↓
[discovery] the system reads the index of every Skill (name, description, applicability scope, version)
↓ `release-review`'s description contains "release review" → it enters the candidate set
[trigger] model judgment: the current task matches "release review" → mark it applicable
↓ loading log: skill=release-review, version=3, trigger=model
[loading] read the `release-review` body (8 steps + tool list + acceptance criteria)
↓ the body enters the context, labeled with source and version
[execution] the model works through the steps:
step 1: read the changelog → tool read returns content → done
step 2: run the tests → tool run_test returns pass → done
step 3: check permission changes → tool git_diff returns no change → done
step 4: output the conclusion → generate the review report
↓ execution log: completion status of each step + a summary of the tool results
[removal] the task ends; the Skill body is removed from the context
↓ the message history keeps the record "release-review v3 was loaded and executed"
task ends"Every station on this timeline can fail," Lao Z said. "Discovery: the index is stale, its description still names an old tool. Trigger: the model misjudges and matches 'draft review' onto 'release review.' Loading: the body and the index versions disagree. Execution: the model skips or misreads a step. Removal: someone forgets to remove it, and later turns keep carrying it in the context. Each station's failure can only be located by its corresponding log."
"What if the user changes their mind halfway through?"
"Say that partway in, the user says 'never mind — skip the full process this time, just take a quick look,'" Lao Z said. "The already-loaded release-review now conflicts with the new intent. The correct move is to mark the current Skill as aborted, record the reason for the abort, and then decide, based on the new intent, whether to load a lighter one. The old Skill and the new intent must not coexist — that's two rule sets fighting."
Summary
A Skill is a layer that packages process experience into discoverable, on-demand instructions. When a task recurs and its steps and acceptance criteria are fixed, it's worth writing that experience into an instruction manual, so the model can find it when needed, read it, and follow it. Its value is reuse: write it once, use it across many sessions, instead of explaining everything from scratch in a prompt every time. A complete Skill contains applicability conditions, a goal, steps, available tools, input and output constraints, exceptions, and an acceptance method; applicability conditions and acceptance are the two bottom lines — the first decides whether the Skill should be loaded, the second decides what counts as done. Loading is progressive: read the index and judge applicability first, load the body only when it applies, rather than stuffing every Skill into the context at once. The three trigger methods (rules, user selection, model judgment) each carry their own costs; most systems mix them, falling back to the more reliable method for critical Skills.
A Skill is essentially a soft constraint. It is "soft" because instructions and data travel through the same channel: the model cannot mechanistically distinguish "a rule I must obey" from "reference text," and can only continue in the most probable way. So the model may omit steps, misread descriptions, or push back against constraints — and none of those three is a bug; they are inherent properties of a soft constraint. The countermeasure isn't harsher wording but hard constraints paired to the critical steps: the tool executor refuses, the permission layer blocks, the CI gate holds. The soft constraint makes the correct path easier to pick; the hard constraint guarantees that when it isn't picked, nothing spirals out of control.
A Skill's reliability rests on three kinds of logs: the loading log records which Skill was loaded under which conditions and at which version, the execution log records what the model actually did and the completion status of each step, and the removal record notes when it left the context. The three logs correspond to the three sources of failure: wrong triggering, non-adherence by the model, and context residue. Skills also drift over time: renamed tools, changed processes, migrated infrastructure — each can make an old Skill describe a world that no longer exists. A stale Skill is more dangerous than no Skill at all: with none, the model explores cautiously; with a stale one, the model confidently takes the wrong path. Treating the Skill as a version-controlled input and watching for drift with the two signal kinds — active inspection and passive capture — is the long-term work of maintaining reliability.
The engineering of Skills goes beyond writing bodies: there must be a catalog and namespaces — the three layers of global-generic, team-convention, and project-specific, each with its own update cadence and permissions; names get prefixes to settle same-name conflicts; every Skill needs an owner to maintain it. There must be a loading budget — read the index by default, limit the bodies to 2–3 with a cap on total words, and judge by whether adding one actually improves task quality. In the release-review scenario we followed, the complete lifecycle is discovery (read the index) → trigger (judge applicability) → loading (read the body) → execution (follow the steps) → removal (task ends): every station can fail, and every station's failure can only be located by its corresponding log. Once a task is complex enough that several independent goals must advance at the same time, Skills and a single Agent are no longer enough — the next thing to discuss is whether to introduce multiple executors.
Hands-on Verification
- Write a Skill of no more than ten steps for a code review, and give every step an observable completion condition.
- Take the parts of that Skill marked "must be done" and land them in tests, tool validation, or approvals, to verify that text alone cannot substitute for them.
- Write the index description for that Skill, and list one task that should trigger it and one that should not.
