Capítulo 10 · el loop de búsqueda, con casa propia
Dos cosas se rompen a escala:
Un vector store arregla las dos.
class VectorStore:
def add(self, docs):
vecs = self._embed([d["text"] for d in docs])
for d, v in zip(docs, vecs):
self._items.append({**d, "vec": v})
def search(self, query, k=3, where=None):
qv = self._embed([query])[0]
pool = [it for it in self._items
if not where or matches(it, where)]
return top_k_by_cosine(qv, pool, k)embed → la misma clase para OpenAI + Gemini"Como este query, pero solo billing, solo este cliente, solo desde marzo."
Todavía un escaneo lineal. Una base de datos real (pgvector, Qdrant, Pinecone) agrega:
La misma interfaz add / search.
billing: acota, luego rankeaUn store.py compartido; solo cambian el corpus + el query.
El modelo de embeddings es parte de tu schema.
Cámbialo → cada vector guardado queda sin sentido → re-embebe todo el corpus. Versiónalo.
Un vector store es add() + search() con los vectores guardados junto al texto. Ya tienes la mitad de retrieval de RAG. Sigue: entrégale los pasajes a un modelo y responde a partir de ellos, con citas.