Build, review, and architect applications that use AI models - from single-API calls to
multi-agent systems with RAG pipelines. The goal is production-grade AI apps that are reliable,
cost-effective, and don't hallucinate their way into an incident.
Target versions: September 2026 snapshot. Read references/target-versions.md before
pinning model IDs (Claude/OpenAI families), SDKs, runtimes, vector stores, or evaluation tools.
When to use
Integrating LLM APIs (Anthropic, OpenAI, etc.) into applications
Building RAG pipelines (chunking, embedding, retrieval, generation)
Designing agent systems (tool use, loops, state, multi-agent)
Choosing between fine-tuning, RAG, and prompt engineering
Setting up vector stores for semantic search
Implementing structured output and tool use / function calling
Building evaluation and testing harnesses for AI features
Optimizing token costs, latency, and model routing
Building MCP servers or tools (use mcp - it handles the protocol layer)
Writing or refining individual prompts (use prompt-generator)
General database configuration, schema design, or migrations (use databases)
Security auditing AI application code (use security-audit)
Reviewing code quality unrelated to AI/ML patterns (use code-review)
Building AI-powered HTTP APIs (use backend-api for the API layer; return here for the LLM integration within it)
Reviewing AI-generated application code for slop, hallucinated APIs, or over-abstraction (use anti-slop)
AI Self-Check
AI tools consistently produce the same mistakes when generating AI application code.
Before returning any generated AI/ML code, verify against this list:
API keys loaded from environment variables, never hardcoded
Streaming responses handled with proper error boundaries and cleanup
Token limits respected - input truncation or chunking for long contexts
Structured output uses the provider's native schema enforcement (Anthropic tool_use,
OpenAI response_format), not post-hoc parsing with regex
Tool use / function calling validates tool results before passing back to the model
Retry logic uses exponential backoff with jitter, not fixed delays
Rate limit errors (429) handled distinctly from server errors (5xx)
Vector store queries include a relevance threshold - don't blindly pass low-similarity
results to the model
Embedding model matches between indexing and querying (mixing models = garbage results)
Prompt templates use parameterized injection, not string concatenation
Model responses validated before use (check for refusals, empty content, malformed JSON)
No synchronous LLM calls in request handlers - always async with timeouts
PII stripped or masked before sending to external model APIs
Temperature set intentionally (0 for deterministic tasks, higher for creative)
Provider drift checked: Responses/Agents/SDK examples use current provider surfaces, not deprecated patterns - specifically verify no use of openai.beta.assistants.create (Assistants API, superseded by Responses/Agents API) or other Assistants-era surfaces
RAG evidence bounded: retrieval thresholds, citations, and empty-result behavior are defined before generation
Cross-cutting agent hygiene applied - see references/agent-hygiene.md
Performance
Batch embeddings and eval runs; avoid one request per row when the provider offers batch or bulk APIs.
Cache deterministic retrieval, tool metadata, and prompt templates, but never cache tenant-specific model outputs without a data-retention decision.
Track token, latency, and retry budgets separately for interactive, background, and eval traffic.
Best Practices
Prefer raw provider SDKs until orchestration complexity justifies LangGraph, LlamaIndex, or LangChain.
Keep model, tool, retrieval, and safety decisions configurable per environment; avoid hardcoding preview model names in application logic.
Treat model output as untrusted input: validate structure, refusal states, tool arguments, and downstream side effects.
Workflow
Step 1: Determine the architecture pattern
Need
Pattern
Start with
Single model call
Direct API integration
Provider SDK
Knowledge-grounded answers
RAG pipeline
Vector store + retrieval
Multi-step reasoning
Agent with tools
LangGraph, OpenAI Agents SDK, or custom loop
Multiple specialized models
Model routing / chain
Custom router or Vercel AI SDK
Offline / air-gapped
Local inference
Ollama or vLLM
Existing data enrichment
Batch processing
Provider batch APIs
Step 2: Choose the right abstraction level
Pick the lightest tool that solves the problem:
Raw SDK - direct Anthropic/OpenAI SDK calls. Best for simple integrations, maximum
control, minimum dependencies. Start here unless you have a specific reason not to.
Vercel AI SDK - unified provider interface with streaming primitives. Good for
TypeScript apps that need provider-agnostic code or React/Next.js streaming UI.
LangChain / LlamaIndex - orchestration frameworks. Use when you need complex chains,
built-in document loaders, or 300+ pre-built integrations. Don't use for simple API calls -
the abstraction overhead isn't worth it.
LangGraph / OpenAI Agents SDK - stateful agent frameworks. Use when you need cycles,
persistence, human-in-the-loop, or multi-agent coordination.
The anti-pattern: importing LangChain to make a single API call. That's like importing
Django to serve a static HTML file.
Step 3: Implement
Follow the domain-specific sections below. Read the appropriate reference file for detailed
patterns and code examples.
Step 4: Evaluate and validate
Every AI feature needs evaluation. Not "run it once and eyeball the output" - structured evals
with datasets, metrics, and regression detection.
Minimum viable eval: create a promptfooconfig.yaml with 20+ test cases, use contains,
llm-rubric, and cost assertions, run npx promptfoo eval in CI on every PR that touches
prompts. Track pass rate over time - any regression blocks the merge.
Read references/evaluation.md for promptfoo setup, assertion types, CI integration (GitHub
Actions example), RAG-specific evals, agent evals, and red teaming patterns.
LLM Integration Patterns
Streaming
Always stream for user-facing responses. Buffer for background processing.
# Anthropic streaming (Python)
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
) as stream:
for text in stream.text_stream:
yield text
Structured output
Use native provider mechanisms, not regex parsing of free-text responses.
Anthropic: tool_use with JSON schema, or response_format with json_schema
Read references/llm-patterns.md for multi-turn tool use, parallel tool calls, error
recovery, and provider-specific gotchas.
RAG Architecture
The quality of a RAG system depends more on retrieval quality than model quality.
A mediocre model with great retrieval beats a frontier model with bad retrieval.
Chunking strategy
Strategy
When to use
Chunk size
Fixed-size with overlap
Default starting point
512-1024 tokens, 10-20% overlap
Semantic (sentence/paragraph)
Well-structured documents
Varies by content
Recursive character
Mixed content types
1000 chars, 200 overlap
Document-aware (markdown headers, code blocks)
Structured docs, code
Section-based
Parent-child
Need both precision and context
Small retrieval, large context
Embedding model selection
Use the same model for indexing and querying. Mixing models produces meaningless similarity
scores.
Model
Dimensions
Best for
text-embedding-3-large (OpenAI)
3072 (or lower via dimensions)
General-purpose, scalable
voyage-3-large (Voyage AI)
1024
Code and technical content
embed-v4.0 (Cohere)
1024
Multilingual, compression
Open-source (e5-mistral, gte-Qwen2)
Varies
Air-gapped / self-hosted
Retrieval patterns
Vector search alone - fast, good for semantic similarity, bad for exact keyword matches
Hybrid search (vector + BM25/keyword) - best default. Qdrant, Weaviate, and Pinecone
support this natively. pgvector + tsvector for PostgreSQL.
Reranking - retrieve more candidates (top-50), rerank with a cross-encoder or Cohere
Rerank, return top-5. Adds latency but significantly improves relevance.
Query expansion - rephrase the user query using an LLM before retrieval. Helps when
user queries are vague or use different terminology than the source docs.
Vector store selection
Store
Type
Best for
pgvector
PostgreSQL extension
Already using Postgres, <10M vectors
Qdrant
Self-hosted or cloud
Production self-hosted, hybrid search
Pinecone
Managed only
Zero-ops, serverless scaling
ChromaDB
Embedded / local
Prototyping, small datasets
Minimal RAG example (Python + pgvector)
from anthropic import Anthropic
import psycopg
client = Anthropic()
def search(query: str, limit: int = 5) -> list[dict]:
embedding = get_embedding(query) # same model used at index time
with psycopg.connect(DB_URL) as conn:
rows = conn.execute(
"SELECT content, 1 - (embedding <=> %s::vector) AS score "
"FROM documents WHERE 1 - (embedding <=> %s::vector) > 0.7 "
"ORDER BY embedding <=> %s::vector LIMIT %s",
[embedding, embedding, embedding, limit],
).fetchall()
return [{"content": r[0], "score": r[1]} for r in rows]
def ask(question: str) -> str:
context = search(question)
if not context:
return "No relevant documents found."
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": (
f"Answer based on these documents:\n\n"
+ "\n---\n".join(d["content"] for d in context)
+ f"\n\nQuestion: {question}"
)}],
)
return response.content[0].text
Key patterns: relevance threshold (0.7), same embedding model for index/query, context passed as user message prefix.
Read references/rag-patterns.md for indexing pipelines, metadata filtering, multi-index
strategies, and production RAG architecture.
Agent Systems
The agent loop
Every agent system is fundamentally: observe -> think -> act -> repeat. The differences are in
how you manage state, handle failures, and know when to stop.
while not done:
observation = get_context(state)
action = model.decide(observation, tools)
if action.type == "final_answer":
done = True
else:
result = execute_tool(action)
state.add(result)
Framework selection
Framework
Best for
Key feature
Custom loop
Simple agents, maximum control
No dependencies
LangGraph
Complex state machines, cycles, persistence
Graph-based, checkpointing
OpenAI Agents SDK
OpenAI-native, multi-agent handoffs
Sessions, tracing
Claude Agent SDK
Claude-native agentic loops in code
Programmatic SDK for building custom agents with Claude; use when you need fine-grained control over Claude agent behavior in your own application
Vercel AI SDK
TypeScript agents with UI streaming
ToolLoopAgent, React hooks
Common pitfalls
Infinite loops - always set a max iteration count. Agents will happily loop forever.
Tool explosion - more than 10-15 tools degrades model performance. Group related
operations into fewer, more capable tools.
Missing error handling - tool failures are normal. The agent needs to recover, not crash.
No cost ceiling - a runaway agent can burn through API budget. Set per-request token
and cost limits.
Stale context - long-running agents accumulate context. Summarize or prune periodically.
Minimal safe agent loop
Every agent loop needs an iteration cap, a cost gate, and a tool-error policy. Retry transient
errors with backoff, abort on permanent errors, and pass failed tool results back with an error
marker so the model can choose the next step instead of silently losing state.
Read references/agent-patterns.md for multi-agent architectures, human-in-the-loop patterns,
memory management, and production agent deployment.
Fine-Tuning vs RAG vs Prompt Engineering
Pick the cheapest approach that meets your quality bar:
Fine-tune when: prompt engineering can't capture the behavior, you need consistent
style/format across thousands of outputs, or you need lower latency than RAG provides.
Don't fine-tune when: your data changes frequently (use RAG), you have fewer than 100
high-quality examples, or prompt engineering already works (you're just cargo-culting).
Read references/fine-tuning.md for data preparation, PEFT/LoRA patterns, evaluation during
training, and when to use full fine-tuning vs parameter-efficient methods.
Local Inference
Local serving choices
Tool
Best for
GPU required
Ollama
Dev, prototyping, Mac (MLX)
No (CPU/MLX), optional GPU
vLLM
Production serving, high throughput
Yes
llama.cpp / llama-cpp-python
Minimal deps, quantized models, CPU-only
No (CPU), optional GPU
TGI (HF Text Generation Inference)
HF model hub integration
Yes
CPU-only inference with llama.cpp
CPU inference is viable - sometimes preferable - for: dense models that fit in RAM (7-13B
at Q4 hits 5-10 t/s on modern x86), MoE models with low active params (Qwen3-30B-A3B
at Q4 reaches 13+ t/s even on a 2013-era Xeon - active params dominate decode), and
air-gapped or compliance-bound environments. Key gotchas:
ISA cliff: pre-Haswell CPUs lack AVX2/FMA/BMI2. PyTorch >= 2.1, TF >= 2.8, JAX, and
Ollama prebuilts SIGILL. llama.cpp from source with -DGGML_AVX2=OFF -DGGML_FMA=OFF -DGGML_BMI2=OFF works.
GGUF quants: Q4_K_M is the default sweet spot. Q5_K_M for +25% memory and quality.
IQ4_XS for tighter budgets. Avoid Q2/Q3 - quality cliff is real.
Reproducible models: pin both filename and HF commit SHA. Bare repo+filename pulls
"whatever the author serves now" - silent runtime changes on rebase.
--mlock page-faults the GGUF into RAM at start. Sum GGUF sizes for capacity planning.
API keys: --api-key-file <path>, never --api-key <value> on the command line - leaks
into /proc/<pid>/cmdline via systemd env expansion.
Benchmarking
Fixed prompt suite (chat-short, chat-long, code-simple, code-complex, reasoning), warmup pass,
record latency + decode t/s at fixed max_tokens and temperature. Re-run after model swaps,
llama.cpp version bumps, or build-flag changes. Compare decode t/s, not raw latency.
Read references/local-inference.md for the full llama.cpp build walkthrough (per-CPU-generation
flags), HF SHA-pinned model download, systemd-per-model deployment, NUMA tuning, mlock memory
budgeting, benchmark methodology, and production serving configuration.
Batch APIs - Anthropic and OpenAI offer 50% discounts for async batch processing.
Output length limits - set max_tokens to what you actually need, not 4096 "just in case."
Context pruning - for multi-turn conversations, summarize history instead of sending
the full transcript.
Safety and Guardrails
Input validation (prompt injection), output validation (schema + content policy), PII handling
(strip before external API calls), rate limiting (per-user + per-IP), content filtering, and
audit logging (redact PII). These are non-negotiable for production AI apps.
Read references/safety.md for prompt injection defense patterns, output validation schemas,
PII detection setup, and content policy implementation.
Production Checklist
API keys in environment variables or secret manager (never in code)
Retry logic with exponential backoff and jitter on all LLM calls
Timeouts set on all LLM calls (model inference can hang)
Rate limiting on AI-powered endpoints
Cost monitoring and alerting (daily spend, per-request cost tracking)
Structured logging of prompts, responses, latency, token usage
Evaluation suite running in CI (regression detection)
Model fallback chain configured (primary -> secondary -> error response)
Input validation and prompt injection defense
Output validation before returning to users
PII scrubbed from external API calls
Max token limits set per request type
Health checks on model endpoints (especially self-hosted)
A/B testing infrastructure for prompt and model changes
references/target-versions.md - September 2026 snapshot: Claude/OpenAI model families, AI SDKs, runtimes, vector stores, and eval tools
Output Contract
See references/output-contract.md for the full contract.
Skill name: AI-ML
Deliverable bucket:audits
Mode: conditional. When invoked to analyze, review, audit, or improve existing repo content, emit the full contract - monospace inline header, severity-grouped inline summary, linked Markdown deliverable, and concise monospace conclusion - and write the deliverable to docs/local/audits/ai-ml/<YYYY-MM-DD>-<slug>.md. When invoked to answer a question, teach a concept, build a new artifact, or generate content, respond freely without the contract.
Severity scale:P0 | P1 | P2 | P3 | info (see shared contract; only used in audit/review mode).
Related Skills
mcp - handles MCP server development (the protocol/tooling layer). This skill handles
the application layer - how to build apps that call models, retrieve context, and orchestrate
agents. If building an MCP server, use mcp. If building an app that uses AI, use this skill.
prompt-generator - for crafting and refining individual prompts. This skill covers prompt
template management and patterns within applications; prompt-generator handles one-off prompt
creation and iteration.
databases - for general database operations. This skill covers vector store integration
for RAG; databases handles engine configuration, schema design, and traditional DB operations.
security-audit - for security review of AI application code. This skill provides
guardrail patterns; security-audit provides the audit methodology.
code-review - for reviewing AI application code quality beyond AI-specific patterns.
backend-api - for the HTTP API layer wrapping AI features. Use backend-api for contract design, auth, and route structure; use this skill for the LLM integration within those handlers.
anti-slop - for auditing AI-generated application code for hallucinated APIs, over-abstraction, and slop patterns introduced by AI generation tools.
Rules
Start with the simplest approach. Direct SDK calls before frameworks. Prompt engineering
before fine-tuning. Single agent before multi-agent. Complexity is a cost.
Never hardcode API keys. Environment variables or secret managers. No exceptions.
Set token limits explicitly.max_tokens on every call. Unbounded generation wastes
money and risks timeouts.
Match embedding models. Same model for indexing and querying. Mixing models produces
meaningless similarity scores that silently degrade retrieval quality.
Validate model output. Check for refusals, empty content, malformed structured output.
Models fail in creative ways - handle all of them.
Budget before you batch. Calculate cost before running batch operations. A 100k-row
embedding job at the wrong model can cost thousands.
Evaluate with data, not vibes. Structured evals with datasets and metrics. "It looks
good" is not a quality gate.
Cap agent iterations. Set a max loop count. Runaway agents burn budget and produce
garbage. 10-20 iterations is a reasonable default.
Run the AI self-check. Every generated AI/ML code gets verified against the checklist
above before returning.
1---2name: ai-ml3description: >4 · Build/review AI apps: LLMs, RAG, embeddings, agents, evals, local inference. Triggers: 'llm', 'rag', 'embedding', 'openai sdk', 'agent loop', 'fine-tune', 'ollama', 'vllm'. Not for MCP (use mcp).5license: MIT6compatibility: "Varies by task. Common: Python 3.10+, Node.js 18+. Optional: GPU for local inference"7metadata:8 source: iuliandita/skills9 date_added: "2026-04-02"10 effort: high11 argument_hint: "[task description or architecture question]"12---1314# AI/ML: Building Production AI Applications1516Build, review, and architect applications that use AI models - from single-API calls to17multi-agent systems with RAG pipelines. The goal is production-grade AI apps that are reliable,18cost-effective, and don't hallucinate their way into an incident.1920**Target versions**: September 2026 snapshot. Read `references/target-versions.md` before21pinning model IDs (Claude/OpenAI families), SDKs, runtimes, vector stores, or evaluation tools.2223## When to use2425- Integrating LLM APIs (Anthropic, OpenAI, etc.) into applications26- Building RAG pipelines (chunking, embedding, retrieval, generation)27- Designing agent systems (tool use, loops, state, multi-agent)28- Choosing between fine-tuning, RAG, and prompt engineering29- Setting up vector stores for semantic search30- Implementing structured output and tool use / function calling31- Building evaluation and testing harnesses for AI features32- Optimizing token costs, latency, and model routing33- Setting up local inference with Ollama or vLLM34- Adding safety guardrails (content filtering, PII handling, output validation)3536## When NOT to use3738- Building MCP servers or tools (use **mcp** - it handles the protocol layer)39- Writing or refining individual prompts (use **prompt-generator**)40- General database configuration, schema design, or migrations (use **databases**)41- Security auditing AI application code (use **security-audit**)42- Reviewing code quality unrelated to AI/ML patterns (use **code-review**)43- Building AI-powered HTTP APIs (use **backend-api** for the API layer; return here for the LLM integration within it)44- Reviewing AI-generated application code for slop, hallucinated APIs, or over-abstraction (use **anti-slop**)4546## AI Self-Check4748AI tools consistently produce the same mistakes when generating AI application code.49**Before returning any generated AI/ML code, verify against this list:**5051- [ ] API keys loaded from environment variables, never hardcoded52- [ ] Streaming responses handled with proper error boundaries and cleanup53- [ ] Token limits respected - input truncation or chunking for long contexts54- [ ] Structured output uses the provider's native schema enforcement (Anthropic tool_use,55 OpenAI response_format), not post-hoc parsing with regex56- [ ] Tool use / function calling validates tool results before passing back to the model57- [ ] Retry logic uses exponential backoff with jitter, not fixed delays58- [ ] Rate limit errors (429) handled distinctly from server errors (5xx)59- [ ] Vector store queries include a relevance threshold - don't blindly pass low-similarity60 results to the model61- [ ] Embedding model matches between indexing and querying (mixing models = garbage results)62- [ ] Prompt templates use parameterized injection, not string concatenation63- [ ] Model responses validated before use (check for refusals, empty content, malformed JSON)64- [ ] Cost estimation done before batch operations (token count * price * volume)65- [ ] No synchronous LLM calls in request handlers - always async with timeouts66- [ ] PII stripped or masked before sending to external model APIs67- [ ] Temperature set intentionally (0 for deterministic tasks, higher for creative)68- [ ] **Provider drift checked**: Responses/Agents/SDK examples use current provider surfaces, not deprecated patterns - specifically verify no use of `openai.beta.assistants.create` (Assistants API, superseded by Responses/Agents API) or other Assistants-era surfaces69- [ ] **RAG evidence bounded**: retrieval thresholds, citations, and empty-result behavior are defined before generation70- [ ] Cross-cutting agent hygiene applied - see `references/agent-hygiene.md`7172## Performance7374- Batch embeddings and eval runs; avoid one request per row when the provider offers batch or bulk APIs.75- Cache deterministic retrieval, tool metadata, and prompt templates, but never cache tenant-specific model outputs without a data-retention decision.76- Track token, latency, and retry budgets separately for interactive, background, and eval traffic.7778## Best Practices7980- Prefer raw provider SDKs until orchestration complexity justifies LangGraph, LlamaIndex, or LangChain.81- Keep model, tool, retrieval, and safety decisions configurable per environment; avoid hardcoding preview model names in application logic.82- Treat model output as untrusted input: validate structure, refusal states, tool arguments, and downstream side effects.8384## Workflow8586### Step 1: Determine the architecture pattern8788| Need | Pattern | Start with |89|------|---------|------------|90| Single model call | Direct API integration | Provider SDK |91| Knowledge-grounded answers | RAG pipeline | Vector store + retrieval |92| Multi-step reasoning | Agent with tools | LangGraph, OpenAI Agents SDK, or custom loop |93| Multiple specialized models | Model routing / chain | Custom router or Vercel AI SDK |94| Offline / air-gapped | Local inference | Ollama or vLLM |95| Existing data enrichment | Batch processing | Provider batch APIs |9697### Step 2: Choose the right abstraction level9899Pick the lightest tool that solves the problem:1001011. **Raw SDK** - direct Anthropic/OpenAI SDK calls. Best for simple integrations, maximum102 control, minimum dependencies. Start here unless you have a specific reason not to.1032. **Vercel AI SDK** - unified provider interface with streaming primitives. Good for104 TypeScript apps that need provider-agnostic code or React/Next.js streaming UI.1053. **LangChain / LlamaIndex** - orchestration frameworks. Use when you need complex chains,106 built-in document loaders, or 300+ pre-built integrations. Don't use for simple API calls -107 the abstraction overhead isn't worth it.1084. **LangGraph / OpenAI Agents SDK** - stateful agent frameworks. Use when you need cycles,109 persistence, human-in-the-loop, or multi-agent coordination.110111**The anti-pattern**: importing LangChain to make a single API call. That's like importing112Django to serve a static HTML file.113114### Step 3: Implement115116Follow the domain-specific sections below. Read the appropriate reference file for detailed117patterns and code examples.118119### Step 4: Evaluate and validate120121Every AI feature needs evaluation. Not "run it once and eyeball the output" - structured evals122with datasets, metrics, and regression detection.123124Minimum viable eval: create a `promptfooconfig.yaml` with 20+ test cases, use `contains`,125`llm-rubric`, and `cost` assertions, run `npx promptfoo eval` in CI on every PR that touches126prompts. Track pass rate over time - any regression blocks the merge.127128Read `references/evaluation.md` for promptfoo setup, assertion types, CI integration (GitHub129Actions example), RAG-specific evals, agent evals, and red teaming patterns.130131## LLM Integration Patterns132133### Streaming134135Always stream for user-facing responses. Buffer for background processing.136137```python138# Anthropic streaming (Python)139import anthropic140141client = anthropic.Anthropic()142143with client.messages.stream(144 model="claude-sonnet-4-6",145 max_tokens=1024,146 messages=[{"role": "user", "content": prompt}],147) as stream:148 for text in stream.text_stream:149 yield text150```151152### Structured output153154Use native provider mechanisms, not regex parsing of free-text responses.155156- **Anthropic**: `tool_use` with JSON schema, or `response_format` with `json_schema`157- **OpenAI**: `response_format: { type: "json_schema", json_schema: {...} }`158- **Vercel AI SDK**: `generateObject()` with Zod schema159160### Tool use / function calling161162Define tools with tight schemas. Validate tool results before feeding them back.163164```python165tools = [{166 "name": "search_docs",167 "description": "Search internal documentation",168 "input_schema": {169 "type": "object",170 "properties": {171 "query": {"type": "string", "maxLength": 200},172 "limit": {"type": "integer", "minimum": 1, "maximum": 50}173 },174 "required": ["query"]175 }176}]177```178179Read `references/llm-patterns.md` for multi-turn tool use, parallel tool calls, error180recovery, and provider-specific gotchas.181182## RAG Architecture183184The quality of a RAG system depends more on retrieval quality than model quality.185A mediocre model with great retrieval beats a frontier model with bad retrieval.186187### Chunking strategy188189| Strategy | When to use | Chunk size |190|----------|------------|------------|191| Fixed-size with overlap | Default starting point | 512-1024 tokens, 10-20% overlap |192| Semantic (sentence/paragraph) | Well-structured documents | Varies by content |193| Recursive character | Mixed content types | 1000 chars, 200 overlap |194| Document-aware (markdown headers, code blocks) | Structured docs, code | Section-based |195| Parent-child | Need both precision and context | Small retrieval, large context |196197### Embedding model selection198199Use the same model for indexing and querying. Mixing models produces meaningless similarity200scores.201202| Model | Dimensions | Best for |203|-------|-----------|----------|204| `text-embedding-3-large` (OpenAI) | 3072 (or lower via `dimensions`) | General-purpose, scalable |205| `voyage-3-large` (Voyage AI) | 1024 | Code and technical content |206| `embed-v4.0` (Cohere) | 1024 | Multilingual, compression |207| Open-source (e5-mistral, gte-Qwen2) | Varies | Air-gapped / self-hosted |208209### Retrieval patterns2102111. **Vector search alone** - fast, good for semantic similarity, bad for exact keyword matches2122. **Hybrid search** (vector + BM25/keyword) - best default. Qdrant, Weaviate, and Pinecone213 support this natively. pgvector + `tsvector` for PostgreSQL.2143. **Reranking** - retrieve more candidates (top-50), rerank with a cross-encoder or Cohere215 Rerank, return top-5. Adds latency but significantly improves relevance.2164. **Query expansion** - rephrase the user query using an LLM before retrieval. Helps when217 user queries are vague or use different terminology than the source docs.218219### Vector store selection220221| Store | Type | Best for |222|-------|------|----------|223| pgvector | PostgreSQL extension | Already using Postgres, <10M vectors |224| Qdrant | Self-hosted or cloud | Production self-hosted, hybrid search |225| Pinecone | Managed only | Zero-ops, serverless scaling |226| ChromaDB | Embedded / local | Prototyping, small datasets |227228### Minimal RAG example (Python + pgvector)229230```python231from anthropic import Anthropic232import psycopg233234client = Anthropic()235236def search(query: str, limit: int = 5) -> list[dict]:237 embedding = get_embedding(query) # same model used at index time238 with psycopg.connect(DB_URL) as conn:239 rows = conn.execute(240 "SELECT content, 1 - (embedding <=> %s::vector) AS score "241 "FROM documents WHERE 1 - (embedding <=> %s::vector) > 0.7 "242 "ORDER BY embedding <=> %s::vector LIMIT %s",243 [embedding, embedding, embedding, limit],244 ).fetchall()245 return [{"content": r[0], "score": r[1]} for r in rows]246247def ask(question: str) -> str:248 context = search(question)249 if not context:250 return "No relevant documents found."251 response = client.messages.create(252 model="claude-sonnet-4-6",253 max_tokens=1024,254 messages=[{"role": "user", "content": (255 f"Answer based on these documents:\n\n"256 + "\n---\n".join(d["content"] for d in context)257 + f"\n\nQuestion: {question}"258 )}],259 )260 return response.content[0].text261```262263Key patterns: relevance threshold (0.7), same embedding model for index/query, context passed as user message prefix.264265Read `references/rag-patterns.md` for indexing pipelines, metadata filtering, multi-index266strategies, and production RAG architecture.267268## Agent Systems269270### The agent loop271272Every agent system is fundamentally: observe -> think -> act -> repeat. The differences are in273how you manage state, handle failures, and know when to stop.274275```276while not done:277 observation = get_context(state)278 action = model.decide(observation, tools)279 if action.type == "final_answer":280 done = True281 else:282 result = execute_tool(action)283 state.add(result)284```285286### Framework selection287288| Framework | Best for | Key feature |289|-----------|----------|-------------|290| Custom loop | Simple agents, maximum control | No dependencies |291| LangGraph | Complex state machines, cycles, persistence | Graph-based, checkpointing |292| OpenAI Agents SDK | OpenAI-native, multi-agent handoffs | Sessions, tracing |293| Claude Agent SDK | Claude-native agentic loops in code | Programmatic SDK for building custom agents with Claude; use when you need fine-grained control over Claude agent behavior in your own application |294| Vercel AI SDK | TypeScript agents with UI streaming | ToolLoopAgent, React hooks |295296### Common pitfalls2972981. **Infinite loops** - always set a max iteration count. Agents will happily loop forever.2992. **Tool explosion** - more than 10-15 tools degrades model performance. Group related300 operations into fewer, more capable tools.3013. **Missing error handling** - tool failures are normal. The agent needs to recover, not crash.3024. **No cost ceiling** - a runaway agent can burn through API budget. Set per-request token303 and cost limits.3045. **Stale context** - long-running agents accumulate context. Summarize or prune periodically.305306### Minimal safe agent loop307308Every agent loop needs an iteration cap, a cost gate, and a tool-error policy. Retry transient309errors with backoff, abort on permanent errors, and pass failed tool results back with an error310marker so the model can choose the next step instead of silently losing state.311312Read `references/agent-patterns.md` for multi-agent architectures, human-in-the-loop patterns,313memory management, and production agent deployment.314315## Fine-Tuning vs RAG vs Prompt Engineering316317Pick the cheapest approach that meets your quality bar:318319| Approach | Cost | Lead time | Best for |320|----------|------|-----------|----------|321| **Prompt engineering** | Lowest | Hours | Formatting, tone, simple tasks |322| **Few-shot examples** | Low | Hours | Pattern matching, classification |323| **RAG** | Medium | Days | Knowledge-grounded, dynamic data |324| **Fine-tuning** | High | Days-weeks | Style/behavior, latency-critical, domain specialization |325326**Fine-tune when**: prompt engineering can't capture the behavior, you need consistent327style/format across thousands of outputs, or you need lower latency than RAG provides.328329**Don't fine-tune when**: your data changes frequently (use RAG), you have fewer than 100330high-quality examples, or prompt engineering already works (you're just cargo-culting).331332Read `references/fine-tuning.md` for data preparation, PEFT/LoRA patterns, evaluation during333training, and when to use full fine-tuning vs parameter-efficient methods.334335## Local Inference336337### Local serving choices338339| Tool | Best for | GPU required |340|------|----------|-------------|341| Ollama | Dev, prototyping, Mac (MLX) | No (CPU/MLX), optional GPU |342| vLLM | Production serving, high throughput | Yes |343| llama.cpp / llama-cpp-python | Minimal deps, quantized models, CPU-only | No (CPU), optional GPU |344| TGI (HF Text Generation Inference) | HF model hub integration | Yes |345346### CPU-only inference with llama.cpp347348CPU inference is viable - sometimes preferable - for: dense models that fit in RAM (7-13B349at Q4 hits 5-10 t/s on modern x86), **MoE models with low active params** (Qwen3-30B-A3B350at Q4 reaches 13+ t/s even on a 2013-era Xeon - active params dominate decode), and351air-gapped or compliance-bound environments. Key gotchas:352353- **ISA cliff**: pre-Haswell CPUs lack AVX2/FMA/BMI2. PyTorch >= 2.1, TF >= 2.8, JAX, and354 Ollama prebuilts SIGILL. llama.cpp from source with `-DGGML_AVX2=OFF -DGGML_FMA=OFF355 -DGGML_BMI2=OFF` works.356- **GGUF quants**: `Q4_K_M` is the default sweet spot. `Q5_K_M` for +25% memory and quality.357 `IQ4_XS` for tighter budgets. Avoid Q2/Q3 - quality cliff is real.358- **Reproducible models**: pin both filename and HF commit SHA. Bare repo+filename pulls359 "whatever the author serves now" - silent runtime changes on rebase.360- **`--mlock`** page-faults the GGUF into RAM at start. Sum GGUF sizes for capacity planning.361- **Threading**: `-t = physical_cores - 4` (decode, memory-bandwidth-bound), `-tb = logical`362 (prefill, compute-bound).363- **API keys**: `--api-key-file <path>`, never `--api-key <value>` on the command line - leaks364 into `/proc/<pid>/cmdline` via systemd env expansion.365366### Benchmarking367368Fixed prompt suite (chat-short, chat-long, code-simple, code-complex, reasoning), warmup pass,369record latency + decode t/s at fixed `max_tokens` and temperature. Re-run after model swaps,370llama.cpp version bumps, or build-flag changes. Compare **decode t/s**, not raw latency.371372Read `references/local-inference.md` for the full llama.cpp build walkthrough (per-CPU-generation373flags), HF SHA-pinned model download, systemd-per-model deployment, NUMA tuning, mlock memory374budgeting, benchmark methodology, and production serving configuration.375376## Cost Optimization377378### Token budgeting379380Know your costs before you scale:381382```383cost_per_request = (input_tokens * input_price + output_tokens * output_price) / 1_000_000384monthly_cost = cost_per_request * requests_per_day * 30385```386387### Strategies (ordered by impact)3883891. **Model routing** - use cheaper models for easy tasks, frontier models for hard ones.390 Route by task complexity, not by default.3912. **Caching** - cache identical or semantically similar requests. Anthropic prompt caching392 reduces repeated prefix costs by 90%.3933. **Prompt optimization** - shorter prompts cost less. Cut examples, compress instructions.3944. **Batch APIs** - Anthropic and OpenAI offer 50% discounts for async batch processing.3955. **Output length limits** - set `max_tokens` to what you actually need, not 4096 "just in case."3966. **Context pruning** - for multi-turn conversations, summarize history instead of sending397 the full transcript.398399## Safety and Guardrails400401Input validation (prompt injection), output validation (schema + content policy), PII handling402(strip before external API calls), rate limiting (per-user + per-IP), content filtering, and403audit logging (redact PII). These are non-negotiable for production AI apps.404405Read `references/safety.md` for prompt injection defense patterns, output validation schemas,406PII detection setup, and content policy implementation.407408## Production Checklist409410- [ ] API keys in environment variables or secret manager (never in code)411- [ ] Retry logic with exponential backoff and jitter on all LLM calls412- [ ] Timeouts set on all LLM calls (model inference can hang)413- [ ] Rate limiting on AI-powered endpoints414- [ ] Cost monitoring and alerting (daily spend, per-request cost tracking)415- [ ] Structured logging of prompts, responses, latency, token usage416- [ ] Evaluation suite running in CI (regression detection)417- [ ] Model fallback chain configured (primary -> secondary -> error response)418- [ ] Input validation and prompt injection defense419- [ ] Output validation before returning to users420- [ ] PII scrubbed from external API calls421- [ ] Max token limits set per request type422- [ ] Health checks on model endpoints (especially self-hosted)423- [ ] A/B testing infrastructure for prompt and model changes424425## Reference Files426427- `references/llm-patterns.md` - multi-turn tool use, parallel tool calls, error recovery, provider gotchas428- `references/rag-patterns.md` - indexing pipelines, metadata filtering, multi-index, production architecture429- `references/agent-patterns.md` - multi-agent, human-in-the-loop, memory management, production deployment430- `references/evaluation.md` - promptfoo setup, assertion types, CI integration, RAG/agent evals, red teaming431- `references/fine-tuning.md` - data prep, PEFT/LoRA, training evaluation, full vs parameter-efficient methods432- `references/local-inference.md` - quantization, model selection, GPU memory, production serving config433- `references/safety.md` - prompt injection defense, output validation, PII handling, content filtering, audit logging434- `references/target-versions.md` - September 2026 snapshot: Claude/OpenAI model families, AI SDKs, runtimes, vector stores, and eval tools435436## Output Contract437438See `references/output-contract.md` for the full contract.439440- **Skill name:** AI-ML441- **Deliverable bucket:** `audits`442- **Mode:** conditional. When invoked to **analyze, review, audit, or improve** existing repo content, emit the full contract - monospace inline header, severity-grouped inline summary, linked Markdown deliverable, and concise monospace conclusion - and write the deliverable to `docs/local/audits/ai-ml/<YYYY-MM-DD>-<slug>.md`. When invoked to **answer a question, teach a concept, build a new artifact, or generate content**, respond freely without the contract.443- **Severity scale:** `P0 | P1 | P2 | P3 | info` (see shared contract; only used in audit/review mode).444445## Related Skills446447- **mcp** - handles MCP server development (the protocol/tooling layer). This skill handles448 the application layer - how to build apps that call models, retrieve context, and orchestrate449 agents. If building an MCP server, use mcp. If building an app that uses AI, use this skill.450- **prompt-generator** - for crafting and refining individual prompts. This skill covers prompt451 template management and patterns within applications; prompt-generator handles one-off prompt452 creation and iteration.453- **databases** - for general database operations. This skill covers vector store integration454 for RAG; databases handles engine configuration, schema design, and traditional DB operations.455- **security-audit** - for security review of AI application code. This skill provides456 guardrail patterns; security-audit provides the audit methodology.457- **code-review** - for reviewing AI application code quality beyond AI-specific patterns.458- **backend-api** - for the HTTP API layer wrapping AI features. Use backend-api for contract design, auth, and route structure; use this skill for the LLM integration within those handlers.459- **anti-slop** - for auditing AI-generated application code for hallucinated APIs, over-abstraction, and slop patterns introduced by AI generation tools.460461## Rules4624631. **Start with the simplest approach.** Direct SDK calls before frameworks. Prompt engineering464 before fine-tuning. Single agent before multi-agent. Complexity is a cost.4652. **Never hardcode API keys.** Environment variables or secret managers. No exceptions.4663. **Always stream user-facing responses.** Buffered LLM responses feel broken. Stream.4674. **Set token limits explicitly.** `max_tokens` on every call. Unbounded generation wastes468 money and risks timeouts.4695. **Match embedding models.** Same model for indexing and querying. Mixing models produces470 meaningless similarity scores that silently degrade retrieval quality.4716. **Validate model output.** Check for refusals, empty content, malformed structured output.472 Models fail in creative ways - handle all of them.4737. **Budget before you batch.** Calculate cost before running batch operations. A 100k-row474 embedding job at the wrong model can cost thousands.4758. **Evaluate with data, not vibes.** Structured evals with datasets and metrics. "It looks476 good" is not a quality gate.4779. **Cap agent iterations.** Set a max loop count. Runaway agents burn budget and produce478 garbage. 10-20 iterations is a reasonable default.47910. **Run the AI self-check.** Every generated AI/ML code gets verified against the checklist480 above before returning.
Run npx skillmds@latest add iuliandita/ai-ml in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
· Build/review AI apps: LLMs, RAG, embeddings, agents, evals, local inference. Triggers: 'llm', 'rag', 'embedding', 'openai sdk', 'agent loop', 'fine-tune', 'ollama', 'vllm'. Not for MCP (use mcp). It is listed under AI & ML on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. Capability flags: reads secrets. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
iuliandita (@iuliandita) published this skill. Their other Agent Skills are listed on their SkillMD profile.