Builds reliable product features on top of LLMs — prompts, tools, evals, and guardrails. Use when adding AI/LLM functionality, designing prompts or agent tools, fixing flaky model behavior, or shipping and maintaining a model-powered feature in production.
Installation
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Builds reliable product features on top of LLMs — prompts, tools, evals, and guardrails. Use when adding AI/LLM functionality, designing prompts or agent tools, fixing flaky model behavior, or shipping and maintaining a model-powered feature in production.
LLM Feature Engineering
An LLM is a non-deterministic dependency — it can be wrong, slow, expensive, or manipulated.
Treating it like fetchUser(id) produces flaky, unsafe features. Engineer around its nature: define a
contract, constrain output, ground facts, measure quality with evals, handle failure
modes, and never trust raw model text as correct ([[hardening]]).
LLM features are products — users need predictable behavior, fallbacks when AI fails, and clarity
when output is machine-generated. "Demo magic" is not shipping.
Pairs with [[context-curation]] for prompt payload size, [[source-first]] for grounding, [[interface-design]]
for tool schemas, [[resilience]] for timeouts/retries, [[observability]] for cost/quality/latency,
[[test-first]] mindset for eval sets, [[incremental-delivery]] to ship slices, and [[launch-readiness]]
for gradual rollout of AI behavior.
Designing prompts, system instructions, RAG pipelines, or tool/function definitions
A model-powered feature is inconsistent, hallucinating, slow, or too expensive
Putting an LLM feature into production or preventing quality regression after prompt/model changes
Reviewing AI-related PRs for safety and contract discipline
Also ask: should this be an LLM at all? Rules, regex, search, or classical ML often beat a general
model for narrow tasks — cheaper, deterministic, auditable. Use LLM when language understanding,
open-ended generation, or flexible reasoning is genuinely required.
Skip heavy LLM engineering for one-off internal scripts with no user impact — still validate outputs
if they touch production data.
Process
Work in order. Prompt tuning before task definition is wasted iteration.
1. Define the task contract — before prompts
Write what the feature must do in testable terms ([[spec-first]]):
Field
Example
Input
User question + retrieved docs; ticket text; form fields
≥90% category match on eval set; summary contains all key facts; p95 < 3s
Failure cost
Wrong medical dose = critical; wrong emoji suggestion = low
Out of scope
Model must not execute purchases, access arbitrary data
Vague goals ("be helpful") are unmeasurable. One sentence output contract minimum.
Choose pattern:
Pattern
Use when
Avoid when
Classification / extraction
Fixed labels, fields from text
Need creative prose
Generation
Drafts, explanations, transforms
Facts without sources
RAG
Answers must cite company data
Tiny static FAQ (use search)
Tool/agent
Multi-step actions in product
Simple single API call
Hybrid
Retrieve → extract → generate with schema
Over-agent for one lookup
2. Pick model and budget — fit task to model
Don't default to the largest model:
Factor
Tradeoff
Quality
Hard reasoning, long context → larger model
Latency
Chat UX → smaller/faster or streaming
Cost
High volume → smaller model + better prompt/RAG
Determinism
Lower temperature for extraction; higher for creative drafts
Set token budgets — max input/output tokens, max retrieval chunks ([[context-curation]]).
Instrument cost per request from day one ([[observability]]).
Re-evaluate when volume grows — a cheap model at scale beats a premium model on every request.
3. Structure the prompt — role, task, format, constraints
System prompt — stable rules: role, safety boundaries, output format, what never to do.
User/content — task instance; separate from untrusted data when possible ([[hardening]]).
Effective structure:
Role: You extract order issues from support tickets.
Task: Return category and one-line summary.
Output: JSON only, schema: { "category": enum, "summary": string, "confidence": 0-1 }
Rules:
- If unsure, category "unknown" and confidence < 0.5
- Do not invent order IDs not in the ticket
- Max summary 200 chars
Examples:
Input: "..." → Output: { ... }
Few-shot examples — 2–5 representative cases, including edge cases (empty input, ambiguous).
Update examples when evals fail — don't grow prompts without measurement.
Keep prompts minimal ([[context-curation]]) — every token is cost, latency, and distraction.
4. Constrain and validate output — never trust raw text
Model text is untrusted input to your app ([[hardening]]):