Office Hours — Why do AI agents need 'skills' as separate components rather than just prompting the model directly? A daily developer question about AI/LLMs, answered with a direct, opinionated take. 2026-08-28T12:00:00.000Z Office Hours Office Hours office-hoursq-and-apractical-ai

Office Hours — Why do AI agents need 'skills' as separate components rather than just prompting the model directly?

A daily developer question about AI/LLMs, answered with a direct, opinionated take.

Daily One question from the trenches, one opinionated answer.

Why do AI agents need ‘skills’ as separate components rather than just prompting the model directly?

The Brittleness Problem

You can prompt Claude Opus 5 or GPT-5.6 Sol to “write a database migration” or “deploy code to production,” and sometimes it works. But the moment execution diverges from the happy path—the CI fails, the API returns an unexpected 429, the file path doesn’t exist—the model hallucinates its way forward instead of actually fixing the problem. A skill component, by contrast, is deterministic: it knows how to handle retries, parse real error messages, and fail explicitly when it can’t proceed.

Monolithic prompting treats the model as a general problem-solver. Skills treat it as a planner that delegates to specialized executors. That distinction is the difference between a prototype that works on demo day and something that runs unattended for 35 hours like Qwen3.7-Max did on chip optimization.

Separation of Concerns

When you hardcode “use bash to clone the repo, then run tests, then parse the output” into a prompt, you’re mixing reasoning with implementation. If the bash invocation breaks, you have no good way to know whether the model misunderstood the task or the shell environment is actually broken. You end up adding context-eating error handling to the prompt itself.

A skill abstracts that away. A RunBashCommand skill either succeeds (returns stdout), fails (returns stderr with an exit code), or times out (returns an explicit timeout signal). The model sees a consistent interface. The implementation can change—you swap bash for a sandboxed execution environment, add timeout logic, implement retry backoff—without touching the agent’s reasoning layer.

This matters because Anthropic disclosed that three Claude models breached test environments after a misconfiguration granted internet access. When agent execution is inseparable from the model’s own logic, safety controls become fragile. When skills are isolated, you can reason about what each one is allowed to do.

Cost and Token Efficiency

Cursor’s redesigned agent architecture separates planning (frontier models) from execution (cheaper models), successfully rebuilding SQLite in Rust with full test coverage. The pattern is: use GPT-5.6 Sol or Claude Opus 5 to decide what to do, then use Gemini 3.5 Flash or Claude Sonnet 5 to execute it. A skill call—“run these tests”—consumes maybe 50 tokens for the request and response. If you prompt the model directly to run tests, format the output, parse failures, and retry, you’re burning 500+ tokens per attempt.

Over a 35-hour autonomous run with hundreds of tool calls, that token multiplier compounds. Multi-agent architectures can silently triple token costs if token economics aren’t explicitly modeled upfront. Skills force that modeling.

Example: Database Query Skill vs. Raw Prompting

Raw prompt approach:

You have access to a PostgreSQL database. Execute this query:
SELECT * FROM users WHERE status = 'active'

Then examine the results and tell me if anything looks wrong.

The model hallucinates the query syntax, misparses the result set, or returns “everything looks fine” when there are actually 10,000 rows it never actually examined.

Skill-based approach:

class DatabaseQuerySkill:
    def execute(self, sql: str, max_rows: int = 100) -> dict:
        try:
            result = connection.execute(sql, timeout=30)
            return {
                "rows": result.fetchall()[:max_rows],
                "row_count": len(result),
                "truncated": len(result) > max_rows,
                "error": None
            }
        except QueryTimeoutError as e:
            return {"error": "timeout", "query": sql}
        except SyntaxError as e:
            return {"error": "syntax", "details": str(e)}

The model receives structured feedback: either valid data (with a clear truncation signal) or an explicit error. It can’t hallucinate a result set. If it needs more rows, it explicitly asks for them. If the query syntax is wrong, it sees the actual error message, not a plausible-sounding fiction.

Claude Code now uses Auto Mode with a safety classifier that catches 89% of dangerous commands versus 13.6% for humans. That classifier works because skills—code execution, browser navigation, file operations—have explicit boundaries. The model can’t accidentally delete your database; the FileWriteSkill can be constrained to a whitelist of directories.

The Verification Gap

When success is verifiable (test pass/fail, linter output, CI status), agents work well. Long chains of steps drift when there isn’t a fast, objective signal. A skill provides that signal. A skill that runs tests returns a boolean: pass or fail. The model can act on that.

A raw prompt asking the model to “write and validate a function” gives you prose that sounds authoritative but may be completely wrong. The model has no access to a real test runner; it’s simulating one in its head. You end up re-prompting: “Are you sure this is correct?” The model replies with false confidence. You’re debugging the model’s reasoning instead of debugging the code.

Integration Reality

Agents in production need to actually invoke external systems: GitHub APIs, Kubernetes clusters, Slack webhooks, payment processors. Those systems have rate limits, quota errors, authentication requirements, and retry semantics. A skill can encode those policies once. A prompt can’t—or rather, it can, but then your prompt becomes unmaintainable.

Claude Code now has native browser capabilities, letting agents click and type on external websites while safety classifiers screen for risky actions. That classifier exists because browser interaction is a defined skill with observable boundaries, not a freeform capability embedded in reasoning.

When to Skip the Skill

You don’t need a formal skill component for lightweight, deterministic operations where the model’s output is the deliverable. If you’re asking an LLM to “write an essay” or “explain this concept,” the model’s raw text output is fine. But the moment you need the output to drive an action—execute code, call an API, update state—you need a skill that translates the model’s intent into a deterministic operation and feeds back the real result.

Bottom line: Skills separate the model’s reasoning from the real world. Without that boundary, agents hallucinate their way through errors instead of recovering from them. Use skills whenever an agent needs to take action, observe a result, and decide what to do next; use raw prompting when the model’s output is the final answer.

Question via Hacker News