← capítulo

Vector stores y recuperación

Capítulo 10 · el loop de búsqueda, con casa propia

La hora

¿Por qué no un simple loop?

Dos cosas se rompen a escala:

Un vector store arregla las dos.

add() + search()

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)

Dos decisiones de diseño

"Como este query, pero solo billing, solo este cliente, solo desde marzo."

Dónde termina el juguete

Todavía un escaneo lineal. Una base de datos real (pgvector, Qdrant, Pinecone) agrega:

La misma interfaz add / search.

Ponlo a trabajar — tres vistas

Un store.py compartido; solo cambian el corpus + el query.

La regla que saca los dientes

El modelo de embeddings es parte de tu schema.

Cámbialo → cada vector guardado queda sin sentido → re-embebe todo el corpus. Versiónalo.

Lo que te llevas

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.