Blog · 4 de julio de 2026
Aprende cómo Retrieval‑Augmented Generation (RAG) añade memoria real a tus chatbots para respuestas más precisas, trazables y útiles — con ejemplos prácticos, código funcional y recomendaciones actuales (actualizado a julio 4, 2026).
¿Tu bot suena convincente pero a veces inventa hechos? Eso le pasa al 99% de los modelos que solo confían en su "memoria" paramétrica. RAG (Retrieval‑Augmented Generation) soluciona eso al combinar recuperación de documentos con generación de lenguaje: recupera evidencia relevante y la usa como contexto para producir respuestas más precisas y verificables. (en.wikipedia.org)
La investigación y las competencias recientes confirman que RAG sigue siendo un enfoque relevante para problemas reales; hay publicaciones y tracks de evaluación que documentan avances y retos en 2024–2026. (arxiv.org)
¿Te suena a lego para IA? Exacto: cada bloque puede cambiar según requisitos de latencia, costo y cumplimiento.
¿Listo para ver todo esto en código? Vamos con ejemplos prácticos.
# ejemplo1_faiss_rag.py
# Requisitos: pip install openai faiss-cpu tiktoken
import os
import openai
import faiss
import numpy as np
openai.api_key = os.getenv('OPENAI_API_KEY') # define tu variable de entorno
# 1) Embeddings: convierte textos a vectores
def get_embedding(text):
resp = openai.Embedding.create(model='text-embedding-3-small', input=text)
return np.array(resp['data'][0]['embedding'], dtype='float32')
# 2) Indexación FAISS
texts = [
'La hipertensión es presión arterial alta definida como... (documento A)',
'La dosis recomendada de medicación X es... (documento B)'
]
embs = np.vstack([get_embedding(t) for t in texts])
index = faiss.IndexFlatL2(embs.shape[1])
index.add(embs)
# 3) Recuperación simple
def retrieve(query, k=2):
q_emb = get_embedding(query).reshape(1, -1)
D, I = index.search(q_emb, k)
return [texts[i] for i in I[0]]
# 4) Generación con contexto
def answer(query):
chunks = retrieve(query)
prompt = (
'Eres un asistente. Usa SOLO la información entre === para responder y cita la fuente.\n'
'===\n' + '\n---\n'.join(chunks) + '\n===\n'
'Pregunta: ' + query + '\nRespuesta: '
)
resp = openai.ChatCompletion.create(
model='gpt-4o-mini',
messages=[{'role':'user','content':prompt}],
max_tokens=300
)
return resp['choices'][0]['message']['content']
if __name__ == '__main__':
print(answer('¿Cuál es la dosis recomendada de X?'))
# Nota: verifica nombres de modelo y parámetros en la doc oficial de OpenAI.
# ejemplo2_pinecone_rag.py
import os
import openai
import pinecone
openai.api_key = os.getenv('OPENAI_API_KEY')
pinecone.init(api_key=os.getenv('PINECONE_API_KEY'), environment='us-west1-gcp')
index_name = 'docs-index'
# create or connect index (vector_dim must coincidir con embeddings usados)
if index_name not in pinecone.list_indexes():
pinecone.create_index(index_name, dimension=1536) # ajustar según embedding
index = pinecone.Index(index_name)
# Indexar un documento
def index_doc(id, text, meta=None):
emb = openai.Embedding.create(model='text-embedding-3-large', input=text)
vec = emb['data'][0]['embedding']
index.upsert([(id, vec, meta or {})])
# Recuperar
def retrieve(query, top_k=3):
q_emb = openai.Embedding.create(model='text-embedding-3-large', input=query)['data'][0]['embedding']
res = index.query(q_emb, top_k=top_k, include_metadata=True, include_values=False)
return [match['metadata'].get('text', '') for match in res['matches']]
# Generar respuesta (similar al ejemplo FAISS)
# ... (llama a OpenAI ChatCompletion con prompt construido)
# Nota: este fragmento asume la API pública de Pinecone; consulta la documentación oficial
LangChain ofrece integraciones rápidas entre retrievers, embeddings y LLMs. Útil para prototipado y pipelines complejos. Consulta su documentación para versiones y cambios. (en.wikipedia.org)
# ejemplo3_langchain_simple.py
# Requisitos: pip install langchain openai faiss-cpu
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
emb = OpenAIEmbeddings() # usa variables de entorno para la API
# asume que tienes una lista de docs: docs = ["texto1", "texto2"]
store = FAISS.from_texts(docs, emb)
retriever = store.as_retriever(search_kwargs={'k':3})
llm = ChatOpenAI(model_name='gpt-4o-mini', temperature=0)
qa = RetrievalQA.from_chain_type(llm=llm, chain_type='stuff', retriever=retriever)
print(qa.run('¿Cuál es la contraindicación principal de X?'))
# Verifica la versión de langchain y las firmas de funciones en su repo oficial.
| 🔧 Componente | 👍 Ventaja | ⚠️ Cuándo NO usar | Fuente y notas |
|---|---|---|---|
| FAISS (local) | Gratis, rápido para prototipos | No es gestionado; ops complejas a escala | local / open source. (en.wikipedia.org) |
| Pinecone | Managed, serverless, escala fácil | Coste en producción; revisar pricing | Pinecone pricing page (2026). (pinecone.io) |
| Weaviate | Vector DB con generación de embeddings opcional | Self‑host si control total requerido | weaviate.io docs. (weaviate.io) |
| Milvus | Distribuido, buena performance | Requiere infraestructura propia | Milvus docs/releases. (milvus.io) |
| LangChain / Haystack | Integraciones y pipelines listos | Cambios frecuentes en APIs—ver docs | LangChain, Haystack docs. (en.wikipedia.org) |
¿Quieres que te entregue un repo de ejemplo con flujo FAISS → Pinecone → LangChain y tests de evaluación listos para clonar? Puedo prepararlo con scripts de ingestión, CI básico y ejemplos de prompts (nota: necesitaré permisos para publicar claves si las incluyes, y te recordaré nunca subir keys a repos públicos).
Artículo actualizado a julio 4, 2026. Fuentes: Wikipedia y encuestas académicas sobre RAG; documentación pública de LangChain, Haystack, Pinecone, Weaviate y Milvus; artículos técnicos y comparativas de precios consultadas en junio–julio 2026. (en.wikipedia.org)