Cliente ficticio
VitalSaaS — Lead Scoring Automático
Plataforma B2B SaaS de gestión de equipos de ventas. Su RevOps necesita clasificar
leads entrantes desde HubSpot en tiempo real: Fit, intención de compra,
acción recomendada y resumen ejecutivo — todo estructurado para el CRM.
| Patrones aplicados | 6 patterns |
| Modelo | claude-sonnet-4-6 |
| Output | Pydantic validated JSON |
| Latencia p95 | ~1.4s |
Lead entrante (HubSpot JSON)
{
"nombre": "Laura Fernández",
"empresa": "Distribuciones Ruiz S.L.",
"cargo": "Directora Comercial",
"empleados": 85,
"sector": "Distribución mayorista",
"mensaje": "Llevamos 6 meses buscando...",
"paginas_visitadas": 7,
"tiempo_en_web_min": 14
}
Patrón 1 · Structured Output
Schema Pydantic — LeadScore
Fuerza al modelo a devolver JSON parseable. Cero ambigüedad, integración directa con HubSpot API.
from pydantic import BaseModel, Field
from typing import Literal
class LeadScore(BaseModel):
fit: Literal["high","medium","low"]
intencion: float = Field(ge=0, le=1)
accion: Literal[
"llamada_inmediata",
"nurturing",
"descartar"
]
resumen: str
razonamiento: str
señales_positivas: list[str]
riesgos: list[str]
Patrón 2 · Chain-of-Thought
Razonamiento paso a paso
El modelo explica su scoring antes de decidir. Mejora precisión y hace el output auditables.
COT_INSTRUCTIONS = """
Analiza el lead siguiendo estos pasos:
1. FIRMOGRAFÍA: ¿Encaja empresa/sector/tamaño
con nuestro ICP (50-500 empleados, B2B)?
2. COMPORTAMIENTO: Visitas, tiempo en web,
fuente de entrada — ¿indican interés real?
3. MENSAJE: ¿Hay urgencia, presupuesto,
autoridad o fecha concreta mencionados?
4. SCORING: Asigna fit e intencion (0-1).
5. ACCIÓN: Decide llamada/nurturing/descartar.
Muestra tu razonamiento antes del JSON.
"""
Patrón 3 · Few-Shot Dinámico
Ejemplos por similitud semántica
Selecciona los 2 ejemplos de scoring más parecidos al lead actual. Guía al modelo con casos reales.
EXAMPLES = [
{
"input": "85 empleados, demo urgente,
14 min en web",
"output": "fit:high, intencion:0.88,
accion:llamada_inmediata"
},
{
"input": "12 empleados, solo curiosidad,
2 min en web",
"output": "fit:low, intencion:0.21,
accion:descartar"
},
# ... más ejemplos en vector store
]
Patrón 4 · Template System
Prompt parametrizable
Separación limpia entre instrucciones, contexto y datos. Fácil A/B testing y versionado.
prompt = ChatPromptTemplate.from_messages([
("system", SYSTEM_PROMPT), # cacheado
("human", """
Ejemplos de referencia:
{examples}
---
Lead a analizar:
Empresa: {empresa} ({empleados} empleados)
Cargo: {cargo} | Sector: {sector}
Mensaje: {mensaje}
Web: {paginas} páginas, {minutos} min
Fuente: {fuente}
""")
])
Patrón 5 · Error Recovery
Fallback y reintentos
Si el modelo devuelve JSON malformado, reintenta con prompt simplificado. Cero crashes en producción.
async def score_lead_safe(lead):
try:
return await score_lead(lead)
except (ValidationError,
JSONDecodeError) as e:
# Fallback: prompt simplificado
simple = await score_lead_simple(lead)
return LeadScore(
fit=simple.fit,
intencion=0.5, # default
accion="nurturing",
resumen=simple.text,
razonamiento="fallback mode",
señales_positivas=[], riesgos=[]
)
Patrón 6 · System Prompt de Rol
RevOps Expert persona
Define comportamiento, expertise y restricciones. El modelo mantiene consistencia a lo largo de miles de leads.
SYSTEM_PROMPT = """
Eres un experto en Revenue Operations B2B
con 10 años de experiencia en SaaS de ventas.
Tu ICP objetivo:
- Empresas: 50-500 empleados
- Sector: B2B, distribución, servicios
- Cargo: Director Comercial o superior
Scoring:
- fit: high/medium/low (ICP match)
- intencion: 0-1 (urgencia + engagement)
- accion: llamada si intencion > 0.7
nurturing si intencion 0.3-0.7
descartar si intencion < 0.3
Responde SOLO con JSON válido.
"""
Over-engineering del prompt inicial
Arrancar con prompts de 500+ tokens cuando uno de 50 da el mismo resultado.
Empieza simple. Usa el patron de Progressive Disclosure: nivel 1 → 2 → 3 segun necesidad.
Ejemplos few-shot desalineados
Usar ejemplos de otro dominio o con distribuciones distintas al caso real.
Usa SemanticSimilarityExampleSelector para seleccion dinamica por embedding.
Sin manejo de errores de parseo
Asumir que el modelo siempre devolvera JSON valido. El 1-3% fallara en produccion.
Implementa siempre el Patron 5 (fallback + reintento con prompt simplificado).
Valores hardcodeados en el prompt
Poner umbrales, nombres o reglas negocio directamente en el string del prompt.
Usa ChatPromptTemplate con variables. Cambia config sin tocar el codigo base.