Choosing the Right Primitive: Instructions, Tools, Skills, Hooks, and Commands
Choosing the Right Primitive: Instructions, Tools, Skills, Hooks, and Commands#
TL;DR#
Seven primitives - an instruction, a tool, a skill, a hook, a command, an external capability server, and a delegated sub-agent - each solve a different shape of problem, and picking the wrong one doesn't usually fail loudly; it quietly costs context budget, reliability, or maintainability in a way nobody traces back to the original choice. This lesson gives a complete decision framework across all seven, now that every primitive this domain teaches has been covered: the first five in this subject, an external capability server in model-context-protocol, and a delegated sub-agent in multi-agent-orchestration.
The idea#
By this point in the domain you've built up seven separable mechanisms for getting an agent to do the right thing at the right moment: an instruction (always-loaded or on-demand text the model reasons over, lessons 01-03, 06), a tool (a function the model can call, covered in depth in tool-use-agentic-loop), a skill (a self-contained, triggerable package of instructions plus optional files and scripts, lessons 07-09), a hook (deterministic code that fires on a lifecycle event, lesson 10), a command (an explicit, human-invoked shortcut, also lesson 10), an external capability server (a standardized connection to a system outside the agent's own process, model-context-protocol), and a delegated sub-agent (a separate instance of judgment with its own context window, multi-agent-orchestration). Each subject up to now taught one primitive in isolation - how to write it well, how it fails, how to evaluate it. This lesson is about the choice that comes before any of that craft: given a requirement, which of these seven do you even reach for?
Getting this choice wrong doesn't usually produce an obvious error. A capability that should have been a tool but got implemented as an instruction ("when the user asks for the weather, describe how to check it") works today, badly, describing instead of doing, wasting a turn's roundtrip on a task a single function call would have resolved deterministically. A recurring workflow that should have been a skill but stayed as a giant always-loaded instruction block works today too, at the cost of every single session paying full context tax for material that's relevant to a fraction of sessions. A hard rule that should have been a hook but got phrased as an instruction works today, until the one session where the model has too much else competing for attention and the rule silently doesn't fire. None of these are crashes. They're all quiet taxes - on context budget, on reliability, on the next engineer's ability to find where a given behavior actually lives - and at staff level, the job is recognizing that this tax accumulates across a whole system, not any single decision.
This is exactly the kind of choice this lesson's seniority band anchors: not "is this decision right or wrong in isolation" (a mid-level question with a mostly clean answer) but "what does the wrong choice cost across the system as it grows, and how do you keep the choice legible to whoever inherits this system next." Five interacting primitives, chosen inconsistently across a growing codebase of instructions, skills, and hooks, is exactly the kind of cross-cutting, second-order-consequence problem that doesn't show up in any single code review but shows up unmistakably a year later when nobody can explain why a given behavior lives where it does.
How it works#
The seven primitives, sorted by what question each one answers#
Rather than memorizing seven definitions, sort by the question each primitive is actually built to answer:
- Instruction answers "what should the model always (or usually) know, without being asked?" - persona, constraints, house style, a fact too small and too universally relevant to justify its own loadable unit (lesson 02's cheap-signal framing, lesson 03's always-loaded-vs-on-demand line).
- Tool answers "what can the model actually do to the outside world, beyond producing text?" - a deterministic function with a schema, executed and returning a real result, not described in prose. If the requirement is "the model needs to change or query something outside its own context window," the answer starts here, not with an instruction describing how to do it manually.
- Skill answers "what recurring, self-contained expertise should the model load only when a request's content actually calls for it?" - a packaged unit with its own trigger, sized to stay off the always-loaded surface until needed (lesson 07's core question: is this worth the packaging overhead versus just writing it inline).
- Hook answers "what must happen on every occurrence of a detectable event, with zero tolerance for a missed occurrence, regardless of what the model would have chosen?" - lesson 10's deterministic-guarantee case.
- Command answers "what should only ever happen because a human explicitly, unambiguously said so, right now?" - lesson 10's human-gated case.
- External capability server answers "what can the model reach that lives outside this agent's own process entirely, in a form other hosts and other agents can also reach without a bespoke integration?" -
model-context-protocol/01's M x N framing. A locally-defined tool is the answer when the capability is specific to this one agent; an external server is the answer when the same capability needs to be reachable by more than one host, maintained independently of any one agent's codebase, or trusted/audited as its own unit (model-context-protocol/04,06). - Delegated sub-agent answers "does this piece of work need its own context window, its own narrower toolset, or its own focused judgment, separate from what's already accumulating in the current session?" -
multi-agent-orchestration/01's independence test and02's context-isolation framing. This is not a mechanism for equipping one agent with one more capability; it's a mechanism for handing a bounded piece of the problem to a separate instance of judgment entirely.
Read this way, the seven aren't competing options for the same job - they answer seven different questions, and the actual skill is correctly diagnosing which question a given requirement is really asking. A useful compression that's converged in 2026 practitioner framing collapses this to three coarser buckets before the fine-grained diagnosis: skills change behavior, sub-agents protect context, and capability servers add reach - "is the gap knowledge, judgment isolation, or an external connection?" is a fast first pass before working through the seven individually.
A worked decision walk: "summarize the weekly team standup notes into a report"#
Trace one requirement through all five to see how the diagnosis actually happens: - Is this something the model needs to always know, unprompted? No - it's relevant only when someone actually asks for this report. Rules out a permanent instruction. - Does it need to reach outside the model's context to act on the world - fetch live data, write a file, call an API? Possibly (pulling this week's notes from wherever they live), which argues for at least one tool as a component, separate from the summarization logic itself. - Is it a recurring, self-contained piece of expertise - a specific format, a specific set of sections, specific phrasing conventions the team wants - that should load only when this exact kind of request shows up, and that benefits from bundling a template file? That's a skill: package the report format, the section headings, and the tone guidance together, with a trigger description scoped to "weekly status/standup report" requests (lesson 07's worked criteria). - Does any part of this need to happen on every occurrence of a mechanical event, with zero tolerance for a miss? Not obviously - nothing here is "must fire on every file save" or similar. Rules out a hook for the core task (though a hook might reasonably exist elsewhere in the system, e.g., archiving old reports on a schedule - a different requirement). - Does it need to be gated behind an explicit human decision rather than triggered by request content? Only if the team specifically wants control over exactly when the report goes out (e.g., it triggers an external send action with real consequences) - in which case the summarization stays a skill, but the final "send it" step becomes a command, keeping the human in the loop for the one part of this where a wrong guess about timing has a real cost.
Notice the answer isn't "pick one primitive for this requirement" - it's "decompose the requirement and assign the right primitive to each piece." That decomposition instinct, more than knowing any single primitive's mechanics, is what staff-level judgment on this topic actually looks like.
Extend the same requirement one step further to bring the two remaining primitives into the walk. Suppose "pull this week's notes from wherever they live" turns out to mean a company-wide notes system that three other internal agents also need to read, not just this one: that's the signal to reach for an external capability server instead of a locally-defined tool - the capability now needs to be reachable by more than one host, maintained as its own unit, and trusted independently of any single agent's codebase (model-context-protocol/01, 04). And suppose the "summarize" step itself turns out to be genuinely heavy - synthesizing forty people's raw notes requires enough exploratory reading and drafting that doing it inline would flood the parent session's context with scratch work nobody needs to see afterward: that's the signal to reach for a delegated sub-agent instead of doing the work in the current context - hand off the bounded sub-task, get back a distilled result, and keep the parent's context clean (multi-agent-orchestration/02). Neither addition changes the original five; they're two more questions to ask when a piece of the decomposition doesn't cleanly fit any of the first five.
Worked example: the same wrong choice recurring in different disguises#
A pattern worth naming explicitly because it recurs across unrelated requirements: treating something that needs a guarantee as if it only needed a description. It shows up as a hard business rule phrased as a system-prompt instruction instead of enforced by a hook (lesson 10). It shows up as a capability that genuinely needs to touch the outside world implemented as an instruction telling the model to describe the steps instead of a tool that actually performs them - the model narrates competently, nothing happens, and the failure is easy to miss because the narration reads as if the work got done. It shows up as an important, load-bearing piece of expertise buried in an always-loaded instruction block so large it crowds out everything else competing for the same context budget, instead of packaged as a skill that only loads when actually needed. All three are the same underlying mistake wearing a different costume: reaching for the flexible, model-judged primitive (an instruction) when the requirement's actual shape called for a primitive with a different property (a hook's guarantee, a tool's real-world effect, a skill's on-demand sizing). The fix in every case is the same move: ask which of the five questions above the requirement is actually asking, not which primitive is easiest to bolt onto the existing system prompt.
Why this decision compounds at staff scope#
A single wrong primitive choice in a small system is a minor inefficiency. The reason this earns a staff-level lesson is what happens as a system grows: every inconsistent choice becomes a small piece of tribal knowledge someone has to carry ("oh, that rule is actually enforced by a hook, but this similar-looking rule is just an instruction and sometimes gets missed"), every capability implemented as prose instead of a tool is context budget spent every session instead of once at build time, and every skill that should have been a hook (or vice versa) is a latent reliability gap that won't surface until the exact session where it matters. None of this shows up in a diff review of any single change. It shows up a year later as "why does this system behave inconsistently in ways nobody can quite explain," which is a cross-system, evolution-over-time cost - exactly the shape of concern this subject's seniority baseline (senior-to-staff) and this lesson's band specifically are calibrated to.
Example (Aug 2026): one framing used in 2026 practitioner writing about a specific agent product's extension surface reduces the decision to three resource questions: is the gap knowledge (reach for a skill), context (reach for a delegated sub-task with its own context window), or capability - i.e. does the agent need to touch a system it currently has no access to at all (reach for an external capability connector). That framing is a genuinely useful compression, but it's scoped to that product's specific menu of primitives at that point in time; treat the underlying instinct - name what kind of gap you actually have before reaching for a mechanism - as the durable takeaway, and verify the current menu of available primitives against whichever system you're actually building on.
Pros#
- Turns a vague "how should I build this" into a concrete, answerable diagnostic - five questions to check against a requirement, rather than defaulting to whichever primitive is fastest to reach for (usually: another line in the system prompt).
- Prevents the compounding cost of inconsistent choices by giving a team a shared vocabulary for why a given capability lives where it does, which matters enormously once more than one person is adding to the same agent system.
- Surfaces decomposition as the real skill, not primitive selection in isolation - most non-trivial requirements are several sub-requirements wearing one description, and treating them as one indivisible choice is itself a common source of the wrong-primitive mistake.
Cons#
- The framework can be applied too rigidly, turning every small requirement into a five-question ceremony when the honest answer for a tiny, one-off need is "just write the instruction and move on" - over-applying a staff-level framework to junior-level-sized decisions is its own form of waste.
- Seven primitives are not necessarily the final menu either - this domain's own
landscape-snapshot/02and03track how the concrete tools implementing orchestration and interoperability keep evolving, and a durable framework like this one has to be re-checked against whatever primitives a given system actually offers, not assumed to be permanently complete. - Boundaries between primitives are genuinely fuzzy in places - a tool with a very elaborate description starts to look like it's carrying instruction-shaped guidance, a skill that mostly just points at other tools starts to look like a thin wrapper - and treating this framework as a hard classification exercise rather than a diagnostic lens leads to unproductive debate about which bucket something belongs in, echoing the harness/scaffolding fuzziness from
tool-use-agentic-loop/05.
Alternatives#
- Default everything to an instruction and let the model figure out the rest - the simplest possible mental model, and defensible for a very small, single-purpose system with one maintainer and no ambitions to scale. Fails exactly the way this lesson describes once the system grows: context bloat, missed guarantees, capabilities that never actually execute.
- Default to building a tool for anything that isn't trivially a permanent fact - over-corrects in the other direction; not every recurring need is a function call, and packaging genuinely recurring expertise (format conventions, multi-step workflows, reference material) as a skill is usually a better fit than forcing it through a tool's narrow input/output contract.
- A rigid, mandatory checklist enforced for every single capability added to a system, however small - more process than most requirements justify; useful as a discipline for a team's larger or shared capabilities, wasted ceremony applied uniformly to every trivial addition.
When to use it#
Apply this decision framework whenever you're adding a new capability to an agent system and it's not immediately obvious which of the five primitives fits, whenever you're reviewing an existing system and something's behavior seems inconsistent with similar-looking behavior elsewhere, and especially whenever a team beyond just you is adding capabilities to a shared agent system - that's exactly when inconsistent, undiagnosed primitive choices start compounding into the kind of tribal-knowledge cost described above.
When NOT to use it#
Don't run the full five-question decomposition for a genuinely trivial, one-off addition to a small personal system - "add one line to the system prompt telling the model my timezone" doesn't need a staff-level framework; that's obviously an instruction and reaching for ceremony here is itself the mistake this lesson warns against in its Cons section. Also don't treat the framework as capable of resolving every case cleanly - some requirements are genuinely borderline between two primitives, and the right move there is to make a reasoned, documented choice and revisit it if it turns out wrong, not to keep searching for a version of the framework precise enough to remove the judgment call entirely.
Key takeaways / mental model#
Five primitives, five different questions: what should the model always know (instruction), what can it actually do to the world (tool), what recurring expertise should load only on demand (skill), what must happen on every occurrence of an event with zero tolerance for a miss (hook), what should only happen because a human explicitly said so (command). Diagnose the requirement's actual shape before reaching for whichever primitive is easiest to bolt onto what already exists, and decompose compound requirements into their separate pieces rather than forcing one primitive to answer several different questions at once. The cost of getting this wrong rarely shows up as an error - it shows up as quiet, compounding tax on context, reliability, or a future maintainer's ability to understand why a given behavior lives where it does.
Where the two later primitives change earlier answers#
Adding the external capability server and the delegated sub-agent doesn't just extend the list to seven - it changes how you answer the first five questions in some cases. A capability that looked like it needed a locally-defined tool under the five-primitive framework might actually need an external capability server once you learn a second host or agent needs the same access (model-context-protocol/01's M x N argument applies retroactively the moment "just this one agent" stops being true). A skill that's grown large enough to carry real exploratory work - not just reference material a session reads once, but multi-step work the model has to actually do before it can use the material - might actually need to become a sub-agent's job instead, so that exploratory work happens in an isolated context rather than bloating the parent session (multi-agent-orchestration/02). Treat every earlier answer in this lesson as provisional to that check: "does this actually need to live outside my process, or get delegated to its own context," not just "which of the first five fits."
Example (Aug 2026): 2026 practitioner guidance on structuring a coding-agent's extension surface prioritizes these questions in a specific order for exactly this reason - whether the capability needs to reach outside the current system is checked first, because it eliminates entire categories of primitive (a local tool and a skill are both off the table if the honest answer is "this must be a shared, externally-reachable connection"), before ever reaching a build-effort question. Treat the ordering as one reasonable heuristic, not the only correct one - verify the current primitive menu and their trade-offs against whichever system you're actually building on.
Self-check questions#
- Walk through the "weekly standup report" decomposition from this lesson using a different requirement of your own choosing (from any domain you work in). Which pieces map to which primitives, and where, if anywhere, is the choice genuinely ambiguous?
- A team's agent system has slowly accumulated a dozen important rules, some enforced as hooks, some as always-loaded instructions, with no documented reason for which rule ended up where. Using this lesson's staff-level framing, explain what this inconsistency actually costs the team over time, distinct from any single rule being individually wrong.
- Explain the "narrating instead of doing" failure mode in your own words: why does implementing a real-world-effecting capability as an instruction instead of a tool often look like it worked, and what would you check to catch it?
- Pick a capability you'd currently model as a tool under this lesson's framework. Using what you now know from
model-context-protocolandmulti-agent-orchestration, describe a concrete change in the requirement that would tip it over into needing an external capability server instead, and a separate change that would tip it into needing a delegated sub-agent instead. What clue in each case gives it away? - A junior engineer asks why the team doesn't "just put everything important in the system prompt so nothing ever gets missed." Using this lesson's cost framing (not lesson 03's context-budget framing alone), explain the fuller cost of that approach as a system and a team scale.
References#
- Anthropic Platform Docs: Agent Skills overview
- Claude Code Docs: Automate actions with hooks
- Anthropic engineering blog: Equipping agents for the real world with Agent Skills
- systemprompt.io: Compare Skills vs Subagents vs MCP Servers in Claude
- AIStackInsights: MCP, Agents, Skills, Subagents - The Definitive Guide to AI's New Building Blocks
agentic-engineering/instruction-and-context-design/lessons/07-what-a-skill-is.md,10-hooks-commands-and-deterministic-levers.md(prerequisites)agentic-engineering/tool-use-agentic-loop/(whole subject, prerequisite for the tool primitive)agentic-engineering/tool-use-agentic-loop/lessons/05-harness-vs-scaffolding.md(referenced for the "diagnostic lens, not a hard boundary" framing)agentic-engineering/model-context-protocol/lessons/01-why-mcp-exists.md,04-building-an-mcp-server.md(the external-capability-server primitive)agentic-engineering/multi-agent-orchestration/lessons/01-single-agent-vs-multi-agent.md,02-subagents-delegation-with-context-isolation.md(the delegated-sub-agent primitive)- dibi8.com: Subagent vs MCP Server vs Skill - When to Build Each Claude Code Extension (2026)
- manveerc.substack.com: MCP vs. CLI for AI agents - A Practical Decision Framework for 2026