---
name: agentes-como-servicio
description: >
  Patrón para usar agentes SWL como componentes invocables en aplicaciones de producción
  usando el Anthropic Agent SDK. Cubre la separación dev/prod, deployment, presupuesto
  por invocación, y guardrails. Cargar cuando el usuario quiera integrar un agente SWL
  en una app web, API o servicio.
version: "1.0.0"
herramientasPermitidas: [Read]
user-invocable: false
exclusiones:
  - "No cargar para ejecutar agentes SWL en el entorno de desarrollo local — este skill documenta el patrón de deployment a producción; para invocar agentes en desarrollo usar la invocación normal de Claude Code."
  - "No cargar para diseñar la lógica de negocio de un agente — el diseño de instrucciones, tools y flujo de un agente es responsabilidad de `diseno-herramientas-agente` y `estructura-proyecto-claude`; este skill es exclusivo para el patrón de deployment como servicio."
  - "No cargar cuando el proyecto ya usa Managed Agents de Anthropic o LangGraph — la tabla de comparación del skill cubre cuándo Agent SDK es la opción correcta; si ya hay otra solución deployada, este skill no agrega valor."
  - "No cargar para configurar guardrails de seguridad del sistema SWL en desarrollo — los hooks de guardrails de swl-ses se configuran con `reglas/seguridad-agentes.md`; este skill muestra guardrails en contexto de producción con Agent SDK."
evolvable: true  # default para skill estandar
---
# Agentes como Servicio — De Desarrollo a Producción

Patrón para usar agentes SWL como componentes invocables en aplicaciones de producción.
Basado en "Your .claude Folder Is a Production Agent" y el Anthropic Agent SDK.

## Cuándo cargar

- El usuario quiere integrar un agente de IA en su app web
- Se necesita un componente de razonamiento invocable (no un chatbot, un servicio)
- Migración de prototipo en Claude Code a producción

## Principio fundamental

> Las 5 primitivas de `.claude/` (CLAUDE.md, Skills, MCPs, Hooks, Sub-agents)
> que usas en desarrollo **ya son el runtime de producción**. No hay capa de
> traducción. Si funciona en tu terminal, funciona en tu app.

## Las 5 primitivas como runtime

| Primitiva | En desarrollo (Claude Code) | En producción (Agent SDK) |
|-----------|---------------------------|--------------------------|
| **CLAUDE.md** | Guía a Claude Code en tu terminal | Se carga como system prompt del agente |
| **Skills** | Comportamientos reutilizables | Mismo loader, mismo formato |
| **MCPs** | Chrome, filesystem, APIs de dev | Tu API de búsqueda, tu BD, servicios internos |
| **Hooks** | PreToolUse/PostToolUse para calidad | Guardrails de seguridad, logging, observabilidad |
| **Sub-agents** | Carpetas en .claude/agents/ | Cada carpeta = agente auto-contenido deployable |

## Arquitectura: Agent as Callable Component

```
Tu App (Next.js, FastAPI, Express, etc.)
  │
  ├── Routing, Auth, CRUD, Validación ← Tu código
  │
  └── Cuando necesita razonamiento ─────────────┐
                                                 │
                                    ┌────────────▼────────────┐
                                    │     Agent SDK           │
                                    │  cwd: .claude/agents/X  │
                                    │  settingSources: project│
                                    │  maxBudgetUsd: 0.15     │
                                    │  maxTurns: 5            │
                                    │  allowedTools: [...]    │
                                    └─────────────────────────┘
```

**Tu app** maneja el ciclo de vida del request: autenticación, almacenamiento, UI.
**El agente** maneja razonamiento, selección de herramientas, iteración.
**Una función** conecta ambos mundos.

## Invocación con Agent SDK

```javascript
const { query } = require('@anthropic-ai/claude-agent-sdk');

// Invocar agente como componente
for await (const msg of query({
  prompt: preguntaDelUsuario,
  options: {
    cwd: './.claude/agents/revisor-codigo',
    settingSources: ['project'],     // Auto-carga CLAUDE.md, skills, MCP
    allowedTools: ['Read', 'Glob', 'Grep'],
    maxTurns: 5,                     // Prevenir loops infinitos
    maxBudgetUsd: 0.15,              // Hard cap en USD
    model: 'claude-sonnet-4-6',
    hooks: { /* guardrails */ },
  },
})) {
  // Streaming de texto + metadata
  yield msg;
}
```

### Parámetros clave

| Parámetro | Propósito | Valor típico |
|-----------|-----------|-------------|
| `cwd` | Directorio del agente (contiene su CLAUDE.md) | `.claude/agents/{nombre}/` |
| `settingSources` | Auto-carga config del proyecto | `['project']` |
| `allowedTools` | Whitelist de herramientas | `['Read', 'Glob', 'Grep']` para read-only |
| `maxTurns` | Máximo de iteraciones | 3-10 según complejidad |
| `maxBudgetUsd` | Costo máximo por invocación | $0.05-$0.50 según agente |
| `model` | Modelo de IA | `claude-sonnet-4-6` para balance costo/calidad |

## Separación Dev vs Prod

### CLAUDE.md raíz = solo desarrollo

```
proyecto/
├── CLAUDE.md              ← DEV ONLY: reglas para Claude Code en tu IDE
├── .claude/
│   ├── agents/
│   │   └── knowledge-bot/
│   │       ├── CLAUDE.md  ← PROD: instrucciones del agente deployable
│   │       ├── skills/
│   │       └── mcp.json
│   └── settings.json
└── src/
```

**Regla**: El CLAUDE.md raíz contiene reglas de desarrollo del proyecto (linting,
convenciones, stack). El CLAUDE.md dentro de `.claude/agents/{nombre}/` contiene
las instrucciones del agente de producción.

**En postbuild**: eliminar el CLAUDE.md raíz para que no interfiera con el runtime.

## Guardrails vía Hooks

### PreToolUse — Bloquear operaciones peligrosas

```javascript
// Ejemplo: bloquear lectura de .env en producción
const BLOCKED_PATHS = ['.env', 'credentials', 'secrets'];

function preToolUse({ tool_name, tool_input }) {
  if (tool_name === 'Read') {
    const path = tool_input.file_path || '';
    if (BLOCKED_PATHS.some(p => path.includes(p))) {
      return { decision: 'block', reason: 'Acceso a archivo sensible bloqueado' };
    }
  }
  return { decision: 'approve' };
}
```

### PostToolUse — Logging y observabilidad

```javascript
// Ejemplo: registrar cada archivo leído para mostrar en UI
function postToolUse({ tool_name, tool_input, tool_output }) {
  if (tool_name === 'Read') {
    emitMetadata({
      type: 'file_read',
      path: tool_input.file_path,
      timestamp: Date.now(),
    });
  }
}
```

## Presupuesto por agente (patrón maxBudgetUsd)

En frontmatter de agentes SWL:

```yaml
---
name: revisor-codigo-swl
presupuestoMaxUsd: 0.50    # Hard cap por invocación
maxTurnos: 10               # Máximo iteraciones
model: sonnet
---
```

El hook `tracking-costos.js` aplica estos límites:
- Al 80% → advertencia
- Al 100% → sugiere detener

## Agregar un segundo agente

```bash
# Crear directorio
mkdir .claude/agents/soporte-tecnico

# Crear CLAUDE.md del agente
cat > .claude/agents/soporte-tecnico/CLAUDE.md << 'EOF'
Eres un agente de soporte técnico. Respondes preguntas sobre
la documentación del producto usando solo los archivos en docs/.
EOF

# Invocar desde la app
query({ prompt: "...", options: { cwd: '.claude/agents/soporte-tecnico' } })
```

Cada agente es una carpeta. Misma estructura siempre.

## Cuándo usar Agent SDK vs Managed Agents vs LangGraph

| Criterio | Agent SDK | Managed Agents | LangGraph/n8n |
|----------|-----------|----------------|---------------|
| Ya tienes hosting | Mejor opción | Overhead innecesario | Overhead innecesario |
| Necesitas serverless | No (requiere runtime) | Mejor opción | Alternativa |
| Multi-paso complejo | Hooks + lógica de negocio | Limitado | Mejor opción |
| Observabilidad | OTEL nativo + hooks | Dashboard Anthropic | LangSmith |
| Costo de infra | Tu hosting | Pricing de Anthropic | Tu hosting |
| Vendor lock-in | Bajo (archivos .md) | Alto | Medio |
| Tiempo a producción | Horas (ya tienes los .md) | Minutos | Días |

## Cuándo NO cargar

- Se invoca un agente SWL en el entorno de desarrollo local — este skill cubre el patrón de deployment a producción con Agent SDK; en desarrollo los agentes se invocan directamente desde Claude Code.
- Se diseña la lógica, instrucciones o tools de un agente nuevo — eso es `diseno-herramientas-agente` y `estructura-proyecto-claude`; este skill es para el patrón de deployment, no para el diseño del agente.
- El proyecto ya usa LangGraph, n8n o Managed Agents de Anthropic de forma satisfactoria — la tabla de comparación del skill es la herramienta para elegir; si ya hay una solución deployada que funciona, este skill no justifica una migración.
- Se configuran guardrails de seguridad del sistema SWL en desarrollo (risk-scoring, bloqueo de rutas) — esos guardrails siguen `reglas/seguridad-agentes.md`; los ejemplos de hooks en este skill son para contexto de producción con Agent SDK.

## Gotchas / Errores comunes no obvios

- **CLAUDE.md raíz no eliminado en postbuild afecta al agente de producción**: el agente de producción lee el CLAUDE.md raíz (reglas de desarrollo: linting, convenciones de código) y las aplica incorrectamente en el runtime de producción. Causa: el postbuild no elimina el CLAUDE.md raíz antes de deployar. Solución: el skill documenta explícitamente "En postbuild: eliminar el CLAUDE.md raíz para que no interfiera con el runtime" — agregar este paso como parte obligatoria del script de build/deploy.
- **`presupuestoMaxUsd` declarado en frontmatter pero no aplicado porque el hook no está activo en producción**: el agente excede el presupuesto declarado porque `tracking-costos.js` solo corre en el entorno de desarrollo con Claude Code. Causa: los hooks de `hooks/` solo se ejecutan cuando Claude Code los registra en `settings.json`; en el Agent SDK de producción el runtime de hooks es diferente. Solución: implementar la lógica de presupuesto directamente en el código de invocación de la app (`maxTokens` en el payload del SDK) además del frontmatter — el frontmatter es documentación del intent, no un mecanismo de enforcement en producción.
- **Segundo agente creado con `cwd: '.claude/agents/soporte-tecnico'` relativo en lugar de ruta absoluta**: la invocación falla o usa el directorio de trabajo incorrecto dependiendo del entorno de ejecución. Causa: `cwd` relativo se resuelve desde el directorio de trabajo del proceso, que varía entre desarrollo y producción. Solución: construir siempre la ruta como `path.join(process.cwd(), '.claude/agents/soporte-tecnico')` o usar `__dirname` — las rutas relativas son ambiguas en producción.
- **Guardrail PreToolUse que bloquea sin mensaje de error informativo devuelve error 500 al usuario**: el hook devuelve `{ decision: 'block' }` sin el campo `reason` y el SDK propaga el bloqueo como un error interno sin contexto. Causa: omitir el campo `reason` en la respuesta del guardrail. Solución: todo guardrail de bloqueo debe incluir `reason` descriptivo ("Acceso a archivo sensible bloqueado — usar endpoint /api/docs para documentación") — el `reason` aparece en los logs del SDK y puede propagarse al usuario como mensaje de error útil.
