Course Content
Skill Engineering
Inputs, outputs, and constraints as a contract; failure handling, retries, fallback, and recovery; state, context, and memory across turns
Engineering Means Deciding on Purpose
“No Failure Path” was the seventh smell in the previous lesson, and it’s the one nearly every first-draft skill carries, because the happy path is the part you naturally write first — and often the only part you test, since your own manual tries tend to be well-formed requests. Skill engineering is the discipline of deciding, on purpose, what happens in every other case: bad input, a tool that fails, a multi-turn conversation where the skill needs to remember something from three messages ago.
The Contract: Inputs, Outputs, Constraints
Before writing a skill’s instructions, it’s worth stating its contract explicitly — the same way you’d document a function’s signature before implementing it, even though a skill’s “signature” is prose, not types.
Inputs — what the skill needs to do its job, and where that comes from: a file path the user provides, data already visible in the conversation, a value a bundled script produces. Be specific about what’s required versus optional, and what a missing required input should mean for execution.
Outputs — what the skill produces, and in what shape. A validator’s output is a list of pass/fail results with reasons; a transformation skill’s output is the converted artifact; a planner’s output is an ordered task list, not a finished report (from the previous lesson’s pattern catalog).
Constraints — the limits the skill operates under: a data volume it can’t reasonably handle inline, an action it must never take without explicit confirmation, a value range outside of which it should refuse rather than guess.
## Contract
**Input:** a CSV file path, and a column name to summarize.
**Output:** a markdown table with count, mean, min, max for that column.
**Constraints:** if the file exceeds 50,000 rows, do not load it entirely —
report that a sample-based approach is needed instead of attempting it.Stating this explicitly, even briefly, forces the failure-mode questions that come next: what happens when the input doesn’t match what’s expected, and what happens when a constraint is violated.
Failure Handling, by Name
Retries. Some failures are transient — a network blip, a rate limit, a tool that occasionally times out. A skill should say explicitly when a retry is appropriate and how many times, rather than leaving the agent to improvise:
If the API call times out, retry once after a brief pause. If it fails a
second time, report the failure to the user rather than retrying further —
do not retry more than twice.Without a stated limit, an agent has no principled way to know whether a third or fourth retry is reasonable persistence or a wasted, expensive loop.
Fallback. When the primary approach isn’t available, a stated fallback avoids the agent guessing at one on the spot:
Use the internal pricing API for current rates. If the API is unreachable,
fall back to the cached rates in references/last-known-rates.md, and clearly
label the result as using cached data with the file's last-updated date.A fallback that isn’t clearly labeled as a fallback is worse than an outright failure — the user has no way to know the result came from stale data.
Recovery. Some failures need cleanup, not just a retry — a partially-completed multi-step action left in an inconsistent state. A workflow skill from the design-patterns lesson that’s three steps into a five-step process when step four fails needs to say what happens to steps one through three:
If step 4 (send approval email) fails after steps 1-3 have completed, do
not roll back the earlier steps — the approval record should stand. Instead,
report that the email failed and that manual notification is needed.Validation. Checking input before acting on it, not discovering a problem mid-execution:
Before processing, confirm the CSV has the expected columns
(date, amount, category). If any are missing, report exactly which ones
before attempting any calculation — do not proceed with partial data.Why This Belongs in the Skill, Not the Agent’s Judgment
It would be reasonable to ask why any of this needs to be written down at all — can’t a capable agent just handle a timeout sensibly on its own? Sometimes. But “sensibly” varies by model, by mood of the specific run, and by how the failure is framed in the tool’s error output — which means the same skill can behave differently on two separate runs against the identical failure, for reasons that have nothing to do with the task. Writing the retry count, the fallback, and the recovery behavior into the skill converts an improvised, inconsistent decision into a deliberate, repeatable one — the same reason a workflow skill states its steps explicitly rather than trusting the agent to infer a sensible order every time.
State, Context, and Memory Across Turns
Skills that complete in one exchange don’t need to think about this. Skills that span multiple turns — a workflow skill walking through several steps, one turn each — do, and getting it wrong is a quiet, common source of bugs.
State is what’s true right now that the skill needs to track — which step of a workflow is currently active, what’s already been validated, what’s still pending. A skill spanning multiple turns should be explicit about what it’s tracking and where:
## Multi-turn state
Track which of the 5 approval steps has been completed. If the user's
message doesn't make this clear, ask which step they're on rather than
assuming step 1.Context is what’s relevant from the conversation so far that the skill needs to carry forward — a file path mentioned three messages ago, a constraint the user stated once and shouldn’t need to repeat.
Memory, in the sense that matters for a skill, is not the same as the progressive-loading mechanics from the free course — that’s about when a skill’s own instructions load. This is about what the skill instructs the agent to carry forward from the conversation itself, turn to turn, which is a design decision the skill’s author makes explicitly rather than something the format handles automatically.
A workflow skill that silently assumes it’s always starting at step 1 will misbehave the moment a user returns to a multi-turn task after a distraction — which is exactly the kind of failure that’s invisible in a quick manual test and only shows up once real usage patterns hit it.
Summary
- Stating a skill’s contract — inputs, outputs, constraints — before writing instructions surfaces failure-mode questions early instead of leaving them implicit
- Retries need a stated limit, fallbacks need to be clearly labeled as fallbacks, recovery needs to say what happens to already-completed steps, and validation needs to happen before acting, not after
- Writing failure behavior into the skill converts an improvised, run-to-run-inconsistent decision into a deliberate, repeatable one
- Multi-turn skills need explicit state and context tracking — silently assuming a workflow always starts at step 1 is a common, easy-to-miss bug
You now know how to engineer a skill’s behavior deliberately, not just its happy path. Next, you’ll place skills precisely into a full agent architecture — exactly where a skill’s authority starts and stops relative to everything else in the pipeline.
