ChanlChanl
Learning AI

Prompt Engineering desde Primeros Principios: 12 Técnicas que Todo Desarrollador de IA Necesita

Domina 12 técnicas esenciales de prompt engineering con ejemplos reales en TypeScript. Desde zero-shot hasta ReAct, construye mejores agentes de IA desde primeros principios.

DGDean GroverCo-founderFollow
March 6, 2026
25 min read
Ilustración de una persona escribiendo pensativamente en un escritorio con notas adhesivas y una lámpara cálida

La mayoría de las guías de prompt engineering te dan recetas sin explicar por qué funcionan. Cuando una receta falla, te quedas atascado. Esta guía construye desde primeros principios: doce técnicas con TypeScript ejecutable, para que entiendas no solo qué hacer sino cuándo cada técnica justifica su uso. Una vez que hayas construido tus prompts, querrás evaluarlos sistemáticamente en lugar de confiar en la intuición.

TécnicaQué haceCuándo usarla
Zero-shotInstrucción sin ejemplosTareas directas con formato de salida claro
Few-shot2-5 ejemplos de entrada/salidaFormato consistente, etiquetas específicas del dominio
Chain-of-thoughtRazonamiento paso a pasoMatemáticas, lógica, problemas de múltiples pasos
System/role promptingPersona + conocimiento del dominioCada agente en producción
Structured outputFormato JSON/XML obligatorioParsing downstream, respuestas de API
Template variablesValores dinámicos en tiempo de ejecuciónPrompts reutilizables en diferentes contextos
Instruction hierarchyReglas ordenadas por prioridadAgentes complejos con muchas restricciones
Negative promptingLímites explícitos de "no hacer"Corregir patrones de falla observados
Self-consistencyVoto mayoritario en múltiples ejecucionesDecisiones de clasificación de alto riesgo
Prompt chainingPipeline de pasos enfocadosFlujos de trabajo complejos de múltiples pasos
ReActBucle de razonamiento + llamada a herramientasAgentes que necesitan datos externos
Meta-promptingEl LLM mejora sus propios promptsOptimización de prompts desde casos de falla

1. Zero-shot prompting

La técnica más simple: dale al modelo una instrucción sin ejemplos. Clasificación, resumen, extracción. Cualquier cosa donde el comportamiento esperado sea obvio a partir de la instrucción sola.

El problema es que el modelo interpreta la ambigüedad de forma generosa. Pídele clasificar una reseña y obtendrás un párrafo en lugar de una etiqueta:

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 256,
  messages: [
    { role: "user", content: "Is this review positive or negative? 'The food was amazing but the service was painfully slow.'" }
  ],
});
 
// Output: A long paragraph discussing nuances of the review

Restringe el formato de salida y el problema desaparece:

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 64,
  messages: [
    {
      role: "user",
      content: `Classify this customer review as exactly one of: POSITIVE, NEGATIVE, or MIXED.
Respond with only the classification label, nothing else.
 
Review: "The food was amazing but the service was painfully slow."
 
Classification:`
    }
  ],
});
 
// Output: "MIXED"

Zero-shot funciona cuando haces la tarea inequívoca. Especifica el formato de salida, restringe el espacio de respuesta, no dejes lugar a interpretación.


2. Few-shot prompting

Cuando zero-shot produce formato inconsistente o malinterpreta tu intención, muéstrale al modelo lo que quieres en lugar de describirlo. De dos a cinco ejemplos de entrada/salida suelen ser suficientes.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 128,
  messages: [
    {
      role: "user",
      content: `Extract the action items from meeting notes. Format each as a JSON object.
 
Meeting notes: "John will send the Q3 report by Friday. Sarah needs to review the API docs."
Action items:
[{"owner": "John", "task": "Send Q3 report", "deadline": "Friday"},
 {"owner": "Sarah", "task": "Review API docs", "deadline": null}]
 
Meeting notes: "We agreed to postpone the launch. Mike will update the roadmap and notify stakeholders by EOD."
Action items:
[{"owner": "Mike", "task": "Update roadmap", "deadline": "EOD"},
 {"owner": "Mike", "task": "Notify stakeholders", "deadline": "EOD"}]
 
Meeting notes: "Lisa will schedule a follow-up for next week. The team should review the new pricing tiers before then."
Action items:`
    }
  ],
});
 
// Output: [{"owner": "Lisa", "task": "Schedule follow-up", "deadline": "next week"},
//          {"owner": "Team", "task": "Review new pricing tiers", "deadline": "next week"}]

Observa lo que los ejemplos enseñan implícitamente: el esquema JSON, los nombres de campo, el manejo de null para fechas límite faltantes, cómo normalizar referencias temporales vagas. No escribiste una especificación, demostraste una. Elige ejemplos que cubran casos extremos (como ese null en la fecha límite) y tu prompt few-shot se convierte en una especificación por demostración.


3. Chain-of-thought (CoT)

Pedirle al modelo que muestre su razonamiento antes de dar una respuesta final es la diferencia entre un estudiante que garabatea una respuesta y uno que muestra su trabajo. Es esencial para matemáticas, lógica y depuración de código: en cualquier lugar donde saltar directamente a una respuesta lleva a errores.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
// Without CoT — the model often gets this wrong
const naive = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 256,
  messages: [
    {
      role: "user",
      content: "A customer bought 3 items at $12.99 each, has a 15% discount coupon, and shipping is $5.99 for orders under $40 but free for orders $40+. What's the total?"
    }
  ],
});
 
// With CoT — dramatically more accurate
const withCoT = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 512,
  messages: [
    {
      role: "user",
      content: `A customer bought 3 items at $12.99 each, has a 15% discount coupon, and shipping is $5.99 for orders under $40 but free for orders $40+. What's the total?
 
Think through this step-by-step:
1. Calculate the subtotal
2. Apply the discount
3. Determine shipping cost
4. Calculate the final total
 
Show your reasoning, then give the final answer.`
    }
  ],
});
 
// Output:
// 1. Subtotal: 3 × $12.99 = $38.97
// 2. Discount: $38.97 × 0.15 = $5.85, so after discount: $38.97 - $5.85 = $33.12
// 3. Shipping: $33.12 < $40, so shipping is $5.99
// 4. Final total: $33.12 + $5.99 = $39.11

La verdadera ventaja no es solo la precisión, es la capacidad de depuración. Cuando el modelo se equivoca, puedes ver dónde el razonamiento falló. Eso es invaluable en sistemas de producción donde necesitas entender las fallas, no solo detectarlas.


4. System prompts y role prompting

Los system prompts definen quién es el modelo, qué sabe y cómo debe comportarse, antes de que ocurra cualquier interacción con el usuario. Esta es la columna vertebral de todo agente de IA en producción.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 1024,
  system: `You are a senior billing support specialist at a SaaS company.
 
Your knowledge:
- Subscription tiers: Free, Pro ($29/mo), Enterprise ($99/mo)
- Billing cycles are on the 1st of each month
- Prorated refunds are available within 14 days of a charge
- You can issue credits but cannot process direct refunds — those go to the billing team
 
Your behavior:
- Always verify the customer's email before discussing account details
- Be empathetic but concise — customers contacting billing are often frustrated
- If a request is outside your authority, explain what you CAN do and offer to escalate
- Never guess at account balances or charge amounts — say you'll look it up`,
  messages: [
    {
      role: "user",
      content: "I was charged twice this month and I want my money back."
    }
  ],
});
 
// The model responds in character: asks for email verification,
// acknowledges the frustration, explains the refund escalation process

Este prompt hace cuatro cosas bien: define el dominio (facturación), establece límites (lo que el agente puede y no puede hacer), establece el tono (empático pero conciso) y proporciona barandillas (nunca adivinar números). Esa combinación (conocimiento, límites de autoridad, tono y rieles de seguridad) es lo que separa un agente útil de un riesgo.

Si estás gestionando prompts en múltiples agentes, el control de versiones se vuelve crítico. Las plataformas con gestión dedicada de prompts te permiten iterar sin redesplegar código.


5. Structured output

Obtener una salida consistente y parseable es una de las habilidades más prácticamente importantes en IA de producción. Tienes dos buenas opciones: response_format de OpenAI para JSON garantizado, o etiquetas XML con Claude para estructuras anidadas.

typescript
import OpenAI from "openai";
 
const client = new OpenAI();
 
const response = await client.chat.completions.create({
  model: "gpt-4o",
  response_format: { type: "json_object" },
  messages: [
    {
      role: "system",
      content: "You extract structured data from customer support messages. Always respond in JSON."
    },
    {
      role: "user",
      content: `Extract the following from this message:
- intent (one of: billing_question, technical_issue, feature_request, cancellation, general_inquiry)
- urgency (low, medium, high)
- entities (any products, features, or account details mentioned)
 
Message: "My enterprise dashboard has been showing wrong analytics data since Tuesday.
This is blocking our quarterly review tomorrow — we need this fixed ASAP."
 
Respond as JSON with keys: intent, urgency, entities, summary`
    }
  ],
});
 
const parsed = JSON.parse(response.choices[0].message.content!);
// {
//   "intent": "technical_issue",
//   "urgency": "high",
//   "entities": ["enterprise dashboard", "analytics", "quarterly review"],
//   "summary": "Analytics data showing incorrect information since Tuesday, blocking quarterly review"
// }

Claude maneja las etiquetas XML particularmente bien para casos donde necesitas estructura anidada:

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 512,
  messages: [
    {
      role: "user",
      content: `Analyze this support ticket and provide your analysis in the following XML format:
 
<analysis>
  <intent>the primary intent</intent>
  <urgency>low|medium|high</urgency>
  <sentiment>positive|neutral|negative</sentiment>
  <recommended_action>what should happen next</recommended_action>
</analysis>
 
Ticket: "I've been a customer for 3 years and I love your product, but this new update
completely broke the reporting feature. I need it fixed or I'll have to look at alternatives."
 
Provide only the XML, no other text.`
    }
  ],
});
 
// Output:
// <analysis>
//   <intent>technical_issue</intent>
//   <urgency>high</urgency>
//   <sentiment>negative</sentiment>
//   <recommended_action>Escalate to engineering for reporting feature regression fix;
//   acknowledge loyalty and provide timeline</recommended_action>
// </analysis>

JSON es más fácil de parsear programáticamente. XML es más fácil para que el modelo lo produzca correctamente porque las etiquetas de cierre actúan como delimitadores naturales. Usa JSON con response_format cuando esté disponible, XML para Claude o cuando necesites estructuras anidadas sobre las que el modelo pueda razonar.


6. Template variables

Los prompts del mundo real no son cadenas estáticas. Las template variables separan la lógica del prompt de los datos del prompt, inyectando nombres de clientes, niveles de plan, contenido de la base de conocimiento en tiempo de ejecución para que un solo prompt funcione en diferentes contextos.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
// Define your template
const supportTemplate = (vars: {
  agentName: string;
  companyName: string;
  customerName: string;
  productTier: string;
  knowledgeBase: string;
}) => `You are ${vars.agentName}, a support agent for ${vars.companyName}.
 
The customer you're speaking with:
- Name: ${vars.customerName}
- Plan: ${vars.productTier}
- ${vars.productTier === "Enterprise" ? "This is a high-priority account. Prioritize their request." : "Standard priority."}
 
Reference knowledge:
${vars.knowledgeBase}
 
Respond helpfully and reference specific documentation when possible.`;
 
// Use with different contexts
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 1024,
  system: supportTemplate({
    agentName: "Alex",
    companyName: "Acme Cloud",
    customerName: "Sarah Chen",
    productTier: "Enterprise",
    knowledgeBase: "- SSO is configured via Settings > Security > SAML\n- Enterprise accounts have dedicated support SLAs",
  }),
  messages: [
    { role: "user", content: "How do I set up SSO for my team?" }
  ],
});

Esto se vuelve especialmente poderoso cuando almacenas las plantillas externamente: los gerentes de producto pueden ajustar la personalidad del agente, actualizar referencias de conocimiento o modificar el comportamiento por nivel sin tocar código. Ese es exactamente el tipo de flujo de trabajo para el que están construidas las herramientas de gestión de prompts.


7. Instruction hierarchy

Los modelos tienden a seguir las instrucciones que aparecen más tarde en un prompt con mayor confiabilidad, y pierden el rastro de las restricciones mencionadas al principio. Estructurar tu prompt con niveles de prioridad explícitos evita que el modelo "olvide" reglas críticas.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
// Bad: Important constraint buried in the middle
const weakPrompt = `Help the customer with their billing question.
Never reveal internal pricing formulas or discount approval thresholds.
Be friendly and conversational.
If they ask about competitor pricing, redirect to our value proposition.
Always confirm the customer's identity before sharing account details.
Use their first name when possible.`;
 
// Good: Structured with clear priority levels
const strongPrompt = `## CRITICAL RULES (never violate)
1. Verify customer identity (email + last 4 of card) before sharing ANY account details
2. Never reveal internal pricing formulas or discount approval thresholds
3. Never share other customers' information
 
## RESPONSE GUIDELINES
- Be friendly and conversational; use the customer's first name
- If asked about competitor pricing, redirect to our value proposition
- Keep responses under 3 sentences unless the customer asks for detail
 
## KNOWLEDGE
- Current plans: Starter ($19/mo), Growth ($49/mo), Scale ($149/mo)
- Billing cycle: 1st of each month
- Refund window: 30 days`;
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 1024,
  system: strongPrompt,
  messages: [
    { role: "user", content: "What discount can you give me?" }
  ],
});

Tres capas: reglas críticas (nunca deben romperse), directrices de respuesta (deben seguirse) y conocimiento de referencia (contexto). Esto refleja cómo Anthropic recomienda estructurar los prompts. Cuando tu agente tiene docenas de instrucciones, esta jerarquía es lo que evita que las importantes queden enterradas.


8. Negative prompting

A veces, decirle al modelo lo que no debe hacer es más efectivo que intentar describir todo lo que debería hacer. Esta es tu solución predeterminada cuando has observado patrones de falla específicos en las pruebas. En lugar de reescribir todo el conjunto de instrucciones positivas, agregas barandillas específicas.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 1024,
  system: `You are a medical information assistant providing general health education.
 
DO:
- Provide general health information from established medical sources
- Suggest the user consult a healthcare provider for personal medical questions
- Use clear, accessible language
 
DO NOT:
- Diagnose conditions or interpret symptoms for a specific person
- Recommend specific medications, dosages, or treatment plans
- Say "you probably have..." or "it sounds like you might have..."
- Provide information about self-harm methods
- Contradict established medical consensus (e.g., vaccine safety)
- Use phrases like "I'm not a doctor, but..." — instead, directly state the general information and recommend professional consultation`,
  messages: [
    {
      role: "user",
      content: "I've been having chest pain for two days. What do I have?"
    }
  ],
});
 
// Output explains that chest pain has many possible causes (general info),
// strongly recommends seeking immediate medical attention,
// does NOT attempt to diagnose

Esa lista de "NO HACER" surgió de observaciones de fallas reales: los modelos tienden a hacer cobertura con "No soy médico, pero..." y luego efectivamente diagnostican de todos modos. Cuando estás ejecutando pruebas basadas en escenarios contra tus agentes, descubrirás estos patrones rápidamente, y los prompts negativos son la forma más rápida de corregirlos.


9. Self-consistency

Ejecuta el mismo prompt múltiples veces, recopila las respuestas, elige la que aparece con más frecuencia. Es una técnica de confiabilidad de fuerza bruta. Si tres de cinco ejecuciones coinciden, puedes confiar más en el resultado que en cualquier ejecución individual. Vale el costo extra de API para clasificación, extracción de datos o moderación de contenido donde la precisión importa más que la latencia.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
async function classifyWithConsistency(
  text: string,
  labels: string[],
  runs: number = 5
): Promise<{ label: string; confidence: number }> {
  const prompt = `Classify the following text into exactly one category: ${labels.join(", ")}.
Respond with only the category label.
 
Text: "${text}"
 
Category:`;
 
  // Run multiple classifications in parallel
  const results = await Promise.all(
    Array.from({ length: runs }, () =>
      client.messages.create({
        model: "claude-sonnet-4-5-20250514",
        max_tokens: 32,
        temperature: 0.7, // Some variation to get diverse reasoning paths
        messages: [{ role: "user", content: prompt }],
      })
    )
  );
 
  // Count votes
  const votes: Record<string, number> = {};
  for (const result of results) {
    const label = (result.content[0] as { text: string }).text.trim();
    votes[label] = (votes[label] || 0) + 1;
  }
 
  // Find majority
  const sorted = Object.entries(votes).sort((a, b) => b[1] - a[1]);
  const [topLabel, topCount] = sorted[0];
 
  return {
    label: topLabel,
    confidence: topCount / runs,
  };
}
 
// Usage
const result = await classifyWithConsistency(
  "Your product is okay I guess, but I expected more for the price",
  ["positive", "negative", "neutral", "mixed"]
);
 
console.log(result);
// { label: "mixed", confidence: 0.8 }  — 4 out of 5 runs agreed

El temperature: 0.7 es deliberado. Con temperature 0, obtendrías la misma respuesta cada vez, lo que anula el propósito. Quieres suficiente variación para hacer emerger interpretaciones alternativas, y luego dejar que el voto mayoritario resuelva la ambigüedad. De tres a cinco ejecuciones alcanza el punto ideal entre confiabilidad y costo.


10. Prompt chaining

En lugar de pedirle al modelo que haga todo de una vez, construye un pipeline donde cada paso maneja una tarea y pasa su salida al siguiente. Un solo prompt monolítico que maneja investigación, análisis, formato y controles de calidad es frágil. Una cadena de prompts enfocados es testeable, depurable y mejorable individualmente.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
async function ask(system: string, user: string): Promise<string> {
  const res = await client.messages.create({
    model: "claude-sonnet-4-5-20250514",
    max_tokens: 1024,
    system,
    messages: [{ role: "user", content: user }],
  });
  return (res.content[0] as { text: string }).text;
}
 
async function analyzeCustomerFeedback(feedback: string) {
  // Step 1: Extract structured data
  const extracted = await ask(
    "You extract structured data from customer feedback. Respond in JSON only.",
    `Extract from this feedback:
- main_issue: the primary complaint or praise
- product_area: which part of the product (billing, UI, performance, support, other)
- emotion: the customer's emotional state (frustrated, satisfied, confused, angry, neutral)
- has_churn_risk: boolean
 
Feedback: "${feedback}"`
  );
 
  // Step 2: Generate response draft using extracted context
  const draft = await ask(
    `You are a customer success manager drafting responses to feedback.
Use the structured analysis provided to craft an appropriate response.`,
    `Based on this analysis:
${extracted}
 
Original feedback: "${feedback}"
 
Draft a response that:
1. Acknowledges their specific concern
2. Addresses the emotional tone appropriately
3. Provides a concrete next step`
  );
 
  // Step 3: Quality check the draft
  const qualityCheck = await ask(
    "You are a QA reviewer for customer communications. Be critical.",
    `Review this draft response for a customer:
 
Draft: "${draft}"
 
Check for:
1. Does it sound genuine (not robotic)?
2. Does it make promises we might not keep?
3. Is the tone appropriate for someone who is ${extracted}?
 
Respond with: APPROVED or NEEDS_REVISION with specific feedback.`
  );
 
  return { extracted: JSON.parse(extracted), draft, qualityCheck };
}
 
const result = await analyzeCustomerFeedback(
  "I've been waiting 3 weeks for a response to my support ticket. This is unacceptable for an enterprise customer paying $10k/month."
);

Cada paso tiene una responsabilidad única. Puedes probarlos de forma independiente, intercambiar modelos por paso (un modelo más barato para extracción, uno más capaz para redacción), y agregar pasos sin reescribir todo el pipeline. Si estás midiendo la calidad con scorecards, puedes calificar cada paso individualmente para identificar exactamente dónde tu cadena se rompe.


11. Patrón ReAct

ReAct (Reasoning + Acting) es lo que hace que un agente de IA sea un agente en lugar de un chatbot. El modelo razona sobre lo que necesita, llama a una herramienta, observa el resultado, y luego razona de nuevo. Aquí está el bucle completo:

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
// Define available tools
const tools: Anthropic.Messages.Tool[] = [
  {
    name: "lookup_order",
    description: "Look up a customer order by order ID. Returns order status, items, and shipping info.",
    input_schema: {
      type: "object" as const,
      properties: {
        order_id: { type: "string", description: "The order ID (e.g., ORD-12345)" },
      },
      required: ["order_id"],
    },
  },
  {
    name: "check_inventory",
    description: "Check current inventory level for a product SKU.",
    input_schema: {
      type: "object" as const,
      properties: {
        sku: { type: "string", description: "Product SKU" },
      },
      required: ["sku"],
    },
  },
];
 
// Simulate tool execution
function executeTool(name: string, input: Record<string, string>): string {
  if (name === "lookup_order") {
    return JSON.stringify({
      order_id: input.order_id,
      status: "shipped",
      tracking: "1Z999AA10123456784",
      items: [{ sku: "WIDGET-100", name: "Premium Widget", qty: 2 }],
      estimated_delivery: "2026-03-10",
    });
  }
  if (name === "check_inventory") {
    return JSON.stringify({ sku: input.sku, in_stock: 47, warehouse: "US-West" });
  }
  return "Unknown tool";
}
 
// ReAct loop
async function handleCustomerQuery(query: string) {
  const messages: Anthropic.Messages.MessageParam[] = [
    { role: "user", content: query },
  ];
 
  let response = await client.messages.create({
    model: "claude-sonnet-4-5-20250514",
    max_tokens: 1024,
    system: "You are a customer support agent. Use the available tools to look up real data before answering. Never guess at order details.",
    tools,
    messages,
  });
 
  // Loop while the model wants to use tools
  while (response.stop_reason === "tool_use") {
    const toolUseBlocks = response.content.filter(
      (block): block is Anthropic.Messages.ToolUseBlock => block.type === "tool_use"
    );
 
    // Execute each tool call
    const toolResults: Anthropic.Messages.ToolResultBlockParam[] = toolUseBlocks.map((block) => ({
      type: "tool_result" as const,
      tool_use_id: block.id,
      content: executeTool(block.name, block.input as Record<string, string>),
    }));
 
    // Feed results back
    messages.push({ role: "assistant", content: response.content });
    messages.push({ role: "user", content: toolResults });
 
    response = await client.messages.create({
      model: "claude-sonnet-4-5-20250514",
      max_tokens: 1024,
      system: "You are a customer support agent. Use the available tools to look up real data before answering. Never guess at order details.",
      tools,
      messages,
    });
  }
 
  return response.content;
}
 
await handleCustomerQuery("Where is my order ORD-12345? Can I add another widget to it?");
 
// The model:
// 1. Reasons: "I need to look up this order first"
// 2. Acts: calls lookup_order("ORD-12345")
// 3. Observes: order is shipped, contains 2 Premium Widgets
// 4. Reasons: "Order is already shipped, can't modify. Let me check widget inventory for a new order"
// 5. Acts: calls check_inventory("WIDGET-100")
// 6. Observes: 47 in stock
// 7. Responds: explains order status, offers to place new order for additional widget

Las herramientas a las que tu agente tiene acceso definen lo que realmente puede hacer, y la calidad de las descripciones de tus herramientas impacta directamente en qué tan confiablemente el modelo elige la correcta. Si estás conectando agentes a sistemas externos, MCP proporciona un protocolo estandarizado para el descubrimiento y ejecución de herramientas que se combina naturalmente con este patrón.


12. Meta-prompting

En lugar de iterar manualmente sobre el texto del prompt, pídele al modelo que critique y mejore tus prompts. Esta técnica está subestimada: el modelo a menudo sabe a qué responde bien mejor que tú.

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
async function improvePrompt(originalPrompt: string, failureExample: string): Promise<string> {
  const response = await client.messages.create({
    model: "claude-sonnet-4-5-20250514",
    max_tokens: 2048,
    messages: [
      {
        role: "user",
        content: `You are an expert prompt engineer. I have a prompt that isn't working well.
 
Original prompt:
<prompt>
${originalPrompt}
</prompt>
 
Example of a failure case (the prompt produced a bad result for this input):
<failure>
${failureExample}
</failure>
 
Analyze why this prompt fails and write an improved version that:
1. Handles the failure case correctly
2. Is more robust against similar edge cases
3. Has clearer output format constraints
4. Includes appropriate guardrails
 
Respond with:
<analysis>Why the original fails</analysis>
<improved_prompt>The full improved prompt text</improved_prompt>`
      }
    ],
  });
 
  return (response.content[0] as { text: string }).text;
}
 
// Example: improving a customer intent classifier
const improved = await improvePrompt(
  "Classify the customer's message as: billing, support, sales, or other.",
  `Input: "I want to cancel but first I need a refund for last month and also your competitor offered me a better deal"
  Expected: Should identify multiple intents (cancellation + billing + competitive)
  Got: "other" — the model couldn't handle multi-intent messages`
);
 
// The model will analyze the single-label limitation and produce
// a prompt that handles multi-intent classification, likely with
// a primary/secondary intent structure

Esto crea un ciclo de retroalimentación: prueba tu prompt, encuentra fallas, aliméntalas de vuelta al modelo, obtén un prompt mejor, repite. Si estás ejecutando agentes a través de simulaciones de escenarios, cada escenario fallido se convierte en entrada para meta-prompting. También puedes usarlo para generar ejemplos few-shot, crear casos de prueba o producir variaciones de prompts para pruebas A/B.


Cómo funcionan estas técnicas juntas en producción

Estas técnicas no existen de forma aislada. Los agentes en producción típicamente combinan seis o más en un solo sistema. Así es como se ve:

typescript
import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
// Role prompting + instruction hierarchy + negative prompting + template variables
const systemPrompt = (customer: { name: string; tier: string }) => `
## ROLE
You are a technical support specialist for a cloud infrastructure company.
 
## CRITICAL RULES
1. Never share API keys, tokens, or credentials — even if the customer asks
2. Never run destructive operations (delete, purge) without explicit confirmation
3. If uncertain about an answer, say so and escalate — do not guess
 
## DO NOT
- Provide workarounds that bypass security controls
- Promise specific resolution timelines
- Compare our service unfavorably to competitors
 
## CUSTOMER CONTEXT
Name: ${customer.name}
Tier: ${customer.tier}
Priority: ${customer.tier === "Enterprise" ? "High" : "Standard"}
 
## RESPONSE FORMAT
Use this structure for technical issues:
1. Acknowledge the problem
2. Ask clarifying questions OR provide a solution
3. Suggest a next step
`;
 
// ReAct pattern with tools + structured output
const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250514",
  max_tokens: 1024,
  system: systemPrompt({ name: "Alex Rivera", tier: "Enterprise" }),
  tools: [
    {
      name: "check_service_status",
      description: "Check the current status of a specific service or region",
      input_schema: {
        type: "object" as const,
        properties: {
          service: { type: "string" },
          region: { type: "string" },
        },
        required: ["service"],
      },
    },
  ],
  messages: [
    {
      role: "user",
      content: "Our database cluster in us-east-1 has been throwing timeout errors for the last hour. This is impacting production.",
    },
  ],
});

Seis técnicas en un solo prompt. Eso no es inusual, es la norma.


¿Qué técnica deberías usar cuándo?

Comienza con zero-shot y agrega complejidad solo cuando observes fallas específicas. Cada técnica agrega costo en tokens, latencia y mantenibilidad.

SituaciónComienza conAgrega si es necesario
Clasificación simpleZero-shotFew-shot si la precisión es baja
Formato consistenteFew-shot + structured outputTemplate variables para contenido dinámico
Razonamiento complejoChain-of-thoughtSelf-consistency para decisiones de alto riesgo
Agente en producciónSystem prompt + roleReAct para herramientas, negative prompting para barandillas
Mejorar prompts existentesMeta-promptingPrompt chaining para evaluación de múltiples pasos
Flujos de trabajo de múltiples pasosPrompt chainingReAct si los pasos requieren datos externos

Qué sigue: parte 2

Esta guía cubrió las doce fundamentales. En la Parte 2, iremos más profundo: retrieval-augmented generation (RAG), prompting de IA constitucional, selección dinámica de herramientas y optimización de prompts a escala. También construiremos pipelines de evaluación automatizados para que puedas medir si tus cambios de prompts realmente mejoran el rendimiento.

Elige una técnica que no hayas probado y aplícala a un problema real esta semana. La mejor forma de internalizar estos patrones es verlos fallar, entender por qué e iterar.

Si estás construyendo agentes y quieres ver dónde tus prompts tienen éxito y dónde fallan en producción, los dashboards de analíticas pueden revelar esos patrones a través de conversaciones reales.

Progress0/12
  • Prueba zero-shot con restricciones de formato explícitas antes de recurrir a few-shot
  • Agrega 2-3 ejemplos few-shot que cubran casos extremos, no solo caminos felices
  • Usa chain-of-thought para cualquier tarea de razonamiento de múltiples pasos
  • Estructura los system prompts con niveles de prioridad claros: reglas críticas, directrices, conocimiento
  • Usa JSON response_format (OpenAI) o etiquetas XML (Anthropic) para salida parseable
  • Separa las plantillas de prompts de los datos de prompts usando template variables
  • Ordena las instrucciones por prioridad: restricciones críticas primero, preferencias de estilo al final
  • Agrega prompts negativos para patrones de falla observados en las pruebas
  • Usa self-consistency (3-5 ejecuciones) para decisiones de clasificación de alto riesgo
  • Divide tareas complejas en cadenas de prompts: una responsabilidad por paso
  • Implementa el bucle ReAct para agentes que necesitan llamar herramientas
  • Usa meta-prompting para mejorar prompts a partir de casos de falla
DG

Co-founder

Building the platform for AI agents at Chanl — tools, testing, and observability for customer experience.

Aprende IA Agéntica

Una lección por semana: técnicas prácticas para construir, probar y lanzar agentes IA. Desde ingeniería de prompts hasta monitoreo en producción. Aprende haciendo.

500+ ingenieros suscritos

Frequently Asked Questions