Ingeniería de Contexto: La Estructura de Archivos como tu Arma Secreta en claude-agent-sdk

Programación· 4 min de lectura

El Problema Real que Nadie Menciona

Cuando empecé a construir agentes con claude-agent-sdk, cometí el error que cometen todos: tiré todo el contexto posible al agente y esperé que Claude "lo entendiera".

Resultado: agentes lentos, costosos (en tokens), y que tomaban decisiones erráticas.

El problema no era Claude. Era que estaba alimentando al agente como si fuera un basural de información. Sin estructura. Sin propósito.

Luego lo entendí: la arquitectura de tus archivos y cómo los cargas es lo que determina si tu agente es inteligente o simplemente ruidoso.

Context Engineering: Más Que Prompt Engineering

Prompt engineering es lo que todos hacen. Context engineering es lo que funciona.

La diferencia:

  • **Prompt engineering**: "Dale al agente las instrucciones correctas"
  • **Context engineering**: "Dale al agente SOLO la información que necesita, en el momento exacto que la necesita"

Esto cambia todo.

En mi proyecto actual con claude-agent-sdk, estructuré los archivos así:

``` project/ ├── agents/ │ ├── analyzer.ts │ ├── decision-maker.ts │ └── executor.ts ├── context/ │ ├── rules/ │ │ ├── validation.txt │ │ ├── constraints.txt │ │ └── patterns.txt │ ├── data/ │ │ ├── user-profiles.json │ │ ├── historical-decisions.log │ │ └── edge-cases.md │ └── schemas/ │ ├── input.schema.json │ └── output.schema.json └── loaders/ ├── context-loader.ts └── selective-loader.ts ```

Pero la estructura no es suficiente. Cómo cargas esa información es lo que importa.

Bash Commands: Tu Filtro de Contexto

Aquí es donde la mayoría falla. Cargan archivos completos cuando deberían cargar fragmentos específicos.

Usando `grep` y `tail`, puedes ser quirúrgico:

Ejemplo 1: Cargar Solo Reglas Relevantes

```bash

En lugar de cargar todo validation.txt

grep -A 3 "payment_validation" context/rules/validation.txt ```

Esto te da solo las reglas de validación de pagos, no las 200 líneas del archivo completo.

Ejemplo 2: Últimas Decisiones Relevantes

```bash

Cargar solo las últimas 5 decisiones similares

tail -20 context/data/historical-decisions.log | grep "similar_case_type" ```

En tu agente con claude-agent-sdk, esto se vería así:

```typescript import { Anthropic } from "@anthropic-ai/sdk"; import { execSync } from "child_process";

const client = new Anthropic();

async function loadRelevantContext(caseType: string) { // Cargar solo reglas relevantes const rules = execSync( `grep -A 5 "${caseType}" context/rules/validation.txt` ).toString();

// Cargar decisiones históricas similares const history = execSync( `grep "${caseType}" context/data/historical-decisions.log | tail -3` ).toString();

return { rules, history }; }

async function runAgent(userInput: string, caseType: string) { const context = await loadRelevantContext(caseType);

const response = await client.messages.create({ model: "claude-3-5-sonnet-20241022", max_tokens: 1024, system: `You are a decision-making agent. Use ONLY this context:

Relevant Rules: ${context.rules}

Historical Decisions: ${context.history}

Make decisions based on these patterns. Be concise.`, messages: [ { role: "user", content: userInput, }, ], });

return response; } ```

Ejemplo 3: Cargar Esquemas Dinámicamente

```bash

Obtener solo los campos requeridos de un esquema

jq '.properties | keys' context/schemas/input.schema.json ```

Combinado con claude-agent-sdk:

```typescript async function validateInput(input: any, schemaType: string) { const requiredFields = execSync( `jq '.properties | keys' context/schemas/${schemaType}.schema.json` ).toString();

const response = await client.messages.create({ model: "claude-3-5-sonnet-20241022", max_tokens: 512, system: `Validate this input against required fields: ${requiredFields}`, messages: [ { role: "user", content: `Input to validate: ${JSON.stringify(input)}`, }, ], });

return response; } ```

Por Qué Esto Funciona

1. Menos tokens = Más rápido: No cargas contexto innecesario 2. Decisiones mejores: El agente se enfoca en lo relevante, no en ruido 3. Escalable: Añades más archivos sin que el agente se ralentice 4. Mantenible: Cambias reglas sin tocar el código del agente

El Pattern que Uso

En cada proyecto que construyo con claude-agent-sdk sigo este patrón:

```typescript class SelectiveContextLoader { private basePath: string;

constructor(basePath: string = "context") { this.basePath = basePath; }

loadByPattern(filePath: string, pattern: string): string { return execSync( `grep -i "${pattern}" ${this.basePath}/${filePath} | head -10` ).toString(); }

loadRecent(filePath: string, lines: number = 5): string { return execSync( `tail -${lines} ${this.basePath}/${filePath}` ).toString(); }

loadSchema(schemaName: string): object { const content = execSync( `cat ${this.basePath}/schemas/${schemaName}.schema.json` ).toString(); return JSON.parse(content); } }

// Uso const loader = new SelectiveContextLoader(); const paymentRules = loader.loadByPattern( "rules/validation.txt", "payment" ); const recentDecisions = loader.loadRecent( "data/historical-decisions.log", 3 ); ```

Lo Que Aprendí (y Tú También Deberías)

Trabajando con claude-agent-sdk durante varios meses, descubrí que:

  • **La estructura importa más que el contenido**: Un archivo bien organizado es 10x mejor que contenido perfecto pero desordenado
  • **Los agentes son perezosos**: Si pueden ignorar contexto, lo harán. Fuerza la relevancia
  • **Bash es tu amigo**: Grep y tail te permiten hacer cosas que muchos developers no consideran
  • **El contexto es dinámico**: Lo que necesita el agente hoy es diferente a mañana

Takeaway

No se trata de tener mejor contexto. Se trata de tener el contexto correcto.

La próxima vez que construyas un agente con claude-agent-sdk, antes de escribir el prompt, pregúntate:

  • ¿Cuál es la información mínima que necesita?
  • ¿Cómo puedo cargarla dinámicamente?
  • ¿Qué puedo filtrar con bash?

Haz eso y verás la diferencia inmediatamente.

---

¿Cómo estructuras tu contexto en tus agentes? Comparte en los comentarios.