Ir al contenido

F03 — Context & Knowledge Design

AI-First Engineering Framework — Baseline v6.5

Sección titulada «AI-First Engineering Framework — Baseline v6.5»

Versión: 3.0.0 | Estado: Activo | Fecha: Marzo 2026 | Tipo: Framework Baseline
Origen: v2.0 — Adición de Sección 8 (Semantic Cache), mejoras en GraphRAG y Self-RAG


Context Engineering es el arte y ciencia de construir el contexto óptimo para un LLM en cada momento. No es solo “poner datos en el prompt” — es un sistema completo de:

  • Recuperación: qué datos traer y cuándo
  • Compresión: cómo reducir tokens sin perder información
  • Priorización: qué información importa más
  • Actualización: cuándo refrescar el contexto
┌──────────────────────────────────────────────────────────┐
│ SYSTEM PROMPT (~10%) │ Instrucciones, rol, reglas │
├──────────────────────────────────────────────────────────┤
│ CONTEXTO RAG (~40%) │ Chunks relevantes recuperados │
├──────────────────────────────────────────────────────────┤
│ HISTORIAL (~20%) │ Últimas N conversaciones │
├──────────────────────────────────────────────────────────┤
│ TOOLS/MCP (~15%) │ Definición de herramientas │
├──────────────────────────────────────────────────────────┤
│ USER MESSAGE (~15%) │ Query actual del usuario │
└──────────────────────────────────────────────────────────┘
Total recomendado: < 60% de la ventana máxima del modelo

Documentos fuente
[1] Extracción → PDF, DOCX, HTML, CSV, código
[2] Limpieza → normalización, eliminación de ruido
[3] Chunking → estrategia según tipo de documento
[4] Enriquecimiento → metadata (fuente, fecha, sección, idioma)
[5] Embedding → text-embedding-3-large (OpenAI) o nomic-embed-text
[6] Indexación → pgvector / Vectorize / Qdrant

2.2 Fase de Recuperación (Online, por query)

Sección titulada «2.2 Fase de Recuperación (Online, por query)»
Query del usuario
[1] Transformación → HyDE / multi-query / step-back
[2] Embedding de query
[3] Búsqueda híbrida → semántica (cosine) + léxica (BM25)
[4] Re-ranking → CrossEncoder / cohere-rerank
[5] Top-K filtrado → metadata filters + diversity
[6] Compresión → eliminar redundancia, extraer pasajes clave
Contexto enriquecido → inyectar en prompt

TipoEstrategiaTamañoOverlap
Documentos técnicosSemántico512-1024 tokens10%
Código fuentePor función/claseVariable0%
FAQ / PolíticasPropositional (por idea)128-256 tokens5%
Contratos legalesParent-childParent 2048 / Child 25615%
TranscripcionesTemporal (por segmento)30s de audio = ~300 tokens20%
# Chunk padre → contexto amplio para embedding de búsqueda
parent_chunk = "Sección completa de 2048 tokens sobre política de privacidad"
# Chunk hijo → contexto preciso para la respuesta
child_chunks = [
"El usuario tiene derecho a solicitar eliminación...", # 256 tokens
"Los datos se retienen máximo 90 días...", # 256 tokens
]
# Estrategia: buscar por padre, responder con hijo

3.3 Propositional Chunking (para documentos densos)

Sección titulada «3.3 Propositional Chunking (para documentos densos)»
# Transforma párrafos en proposiciones atómicas verificables
input = "Los contratos se firman digitalmente. La validez es de 2 años.
Se renueva automáticamente salvo aviso 30 días antes."
output = [
"Los contratos se firman digitalmente.",
"La validez de los contratos es de 2 años.",
"Los contratos se renuevan automáticamente.",
"Para no renovar, se requiere aviso con 30 días de antelación."
]

# En lugar de embeder la query directamente, se genera un documento hipotético
query = "¿Cómo se procesa una devolución?"
hypothetical_doc = llm.generate(
f"Escribe un párrafo que respondería perfectamente a: {query}"
)
# → "Las devoluciones se procesan en 5-7 días hábiles. El cliente debe..."
# Se embede el documento hipotético → mayor recall
embedding = embed(hypothetical_doc)
# Genera múltiples reformulaciones de la query
queries = llm.generate(f"""
Genera 3 reformulaciones diferentes de: "{original_query}"
Formato: JSON array de strings
""")
# → ["¿proceso de reembolso?", "pasos para devolver producto", "política devoluciones"]
# Recuperar para cada query y hacer union/dedup
results = union([retrieve(q) for q in queries])
# Primero pregunta más general, luego específica
specific = "¿Cuál fue el revenue Q3 2025 de la organización?"
general = "¿Cuál es el modelo de revenue de la organización?"
# Recuperar contexto general primero, luego específico
context = retrieve(general) + retrieve(specific)

Retrieval
Evaluador de relevancia (LLM-as-judge)
├── Alta relevancia → usar chunks
├── Baja relevancia → búsqueda web externa
└── Parcial → refinar query y re-buscar
Query → ¿Necesito retrieval? (token [Retrieve])
├── NO → Respuesta directa
└── SÍ → Retrieve → ¿Es relevante? (token [IsRel])
└── SÍ → Generar con contexto → ¿Está soportado? (token [IsSup])
└── SÍ → Respuesta final

⚠️ Limitación: Self-RAG requiere modelos fine-tuned con tokens especiales. En producción usar CRAG con LLM-as-judge.

query_classifier = llm.classify(query, categories=[
"factual_simple", → RAG directo
"multi_hop", → GraphRAG o agente
"procedural", → RAG + secuencia de steps
"creative", → LLM directo sin RAG
"real_time" → MCP Server (no RAG)
])
Query compleja → Agente planificador
[Iteración 1] → Retrieve → Evaluar → ¿Suficiente?
├── SÍ → Sintetizar respuesta
└── NO → Refinar query / Buscar en otra fuente
[Iteración 2] → Retrieve adicional → ...

  • Preguntas multi-hop: “¿Qué clientes comparten el mismo proveedor que tiene incidencias abiertas?”
  • Relaciones complejas entre entidades
  • Cuando el RAG vectorial pierde contexto de relaciones
# Extracción de entidades y relaciones
entities = extract_entities(doc) # → [Cliente, Proveedor, Producto]
relations = extract_relations(doc) # → [Cliente -usa-> Producto, Producto -de-> Proveedor]
# Construir grafo (Neo4j o NetworkX)
graph.add_entities(entities)
graph.add_relations(relations)
# Query en lenguaje natural → Cypher
cypher = nl_to_cypher("¿Qué clientes usan productos del proveedor X?")
results = graph.query(cypher)
# Combinar con RAG vectorial para contexto
context = results + vector_search(query)

ADR Pendiente: GraphRAG requiere Architecture Decision Record para elegir proveedor de grafo (Neo4j Aura, Memgraph, etc.) segun el stack y deployment track del proyecto.


def hybrid_search(query: str, k: int = 10) -> list[Document]:
# Búsqueda semántica (cosine similarity)
semantic_results = vector_db.search(
embedding=embed(query),
k=k * 2,
filter={"tenant_id": current_tenant}
)
# Búsqueda léxica (BM25)
lexical_results = bm25_index.search(query, k=k * 2)
# Fusión RRF (Reciprocal Rank Fusion)
fused = rrf_merge(semantic_results, lexical_results, k=60)
# Re-ranking final
reranked = cross_encoder.rerank(query, fused[:k*2])
return reranked[:k]

Documento completo: Ver Semantic Cache & Performance AI para implementacion detallada, metricas, estrategias de invalidacion, TTL por tipo de dato y monitoreo.

El Semantic Cache evita llamadas repetidas al LLM para queries semánticamente similares. Si la pregunta “¿Cuál es el horario de atención?” ya fue respondida, una pregunta como “¿A qué hora abren?” puede reutilizar esa respuesta.

Query del usuario
[1] Embed query → vector
[2] Buscar en cache (cosine similarity)
├── similarity ≥ 0.95 → HIT: devolver respuesta cacheada
└── similarity < 0.95 → MISS: ejecutar pipeline completo
Guardar en cache con TTL
ParámetroValor RecomendadoReferencia
Similarity Threshold0.92-0.95Doc 18 §2
Cache Hit Rate Target≥ 30%Doc 18 §5
Token Savings Target≥ 40%Doc 18 §5
Latencia con HIT< 50msDoc 18 §5
Precisión (no falsos HIT)≥ 98%Doc 18 §5

MétricaDefiniciónUmbral MínimoAcción si falla
Recall@5% de respuestas correctas en top-5≥ 85%Revisar chunking
Precision@5% de chunks relevantes en top-5≥ 70%Revisar re-ranking
FaithfulnessRespuesta fundamentada en contexto≥ 0.8Revisar prompt
Hallucination RateAfirmaciones sin soporte en contexto< 10%Revisar temperatura, prompt
Answer RelevanceRespuesta relevante para la query≥ 0.85Revisar retrieval
evaluacion/rag_evaluator.py
def evaluate_with_llm_judge(query, context, response):
judgment = llm.evaluate(f"""
Query: {query}
Contexto recuperado: {context}
Respuesta generada: {response}
Evalúa:
1. ¿La respuesta está completamente soportada por el contexto? (0-1)
2. ¿Hay afirmaciones que no aparecen en el contexto? (lista)
3. ¿La respuesta es relevante para la query? (0-1)
Responde en JSON.
""")
return judgment

TipoImplementaciónDuraciónUso
Working MemoryVentana de contexto LLMSesión actualConversación activa
Episodic MemoryPostgreSQL + timestampsPersistenteHistorial de interacciones
Semantic MemoryVector DB (RAG)PersistenteConocimiento documental
Procedural MemoryPrompts / Fine-tuned modelPersistenteHabilidades aprendidas

  • Estrategia de chunking documentada y justificada
  • Evaluación baseline con RAGAS antes de ir a producción
  • Recall@5 ≥ 85% y Hallucination Rate < 10%
  • Semantic Cache configurado con umbral documentado
  • Metadata filters para tenant isolation activos
  • Re-ranking implementado (CrossEncoder o cohere-rerank)
  • Estrategia de actualización de índice documentada
  • Monitoreo de drift en embeddings (revisar cada 90 días)

AI-First Engineering Framework — Baseline v6.5