Ostatnio aktywny 3 days ago

Script del Episodio 827 - atareao con Linux

demo-sqlite-vec.py Surowy
1#!/usr/bin/env python3
2"""
3demo-sqlite-vec.py — Demo de sqlite-vec + Ollama embeddings
4
5Uso:
6 pip install sqlite-vec ollama
7 python demo-sqlite-vec.py
8
9Descripción:
10 Demuestra cómo usar sqlite-vec para almacenar y buscar vectores de
11 embeddings generados por Ollama. Este es el fundamento del RAG local
12 que exploraremos en episodios posteriores.
13
14 Flujo:
15 1. Carga la extensión sqlite-vec
16 2. Crea una tabla virtual para vectores de 768 dimensiones
17 3. Genera embeddings con Ollama (nomic-embed-text)
18 4. Inserta documentos con sus vectores
19 5. Busca por similitud semántica
20
21Requiere:
22 - Ollama instalado y corriendo
23 - Modelo nomic-embed-text descargado (ollama pull nomic-embed-text)
24 - Python 3.10+
25 - pip install sqlite-vec ollama
26
27Referencia:
28 https://github.com/asg017/sqlite-vec
29"""
30
31import sqlite3
32import sys
33
34
35def main():
36 # --- Comprobar que tenemos los modelos necesarios --------------------
37 print("=" * 50)
38 print("Demo: sqlite-vec + Ollama embeddings")
39 print("=" * 50)
40 print()
41
42 # --- 1. Conectar a SQLite en memoria --------------------------------
43 print("[1/5] Conectando a SQLite en memoria...")
44 conn = sqlite3.connect(":memory:")
45 conn.enable_load_extension(True)
46
47 try:
48 conn.load_extension("vec0")
49 print(" ✓ Extensión sqlite-vec cargada")
50 except sqlite3.OperationalError as e:
51 print(f" ✗ No se pudo cargar vec0: {e}")
52 print(" Asegúrate de tener sqlite-vec instalado:")
53 print(" pip install sqlite-vec")
54 sys.exit(1)
55
56 # --- 2. Crear tabla vectorial ---------------------------------------
57 print()
58 print("[2/5] Creando tabla vectorial vec_docs (768 dimensiones)...")
59 conn.execute("""
60 CREATE VIRTUAL TABLE vec_docs USING vec0(
61 embedding float[768]
62 )
63 """)
64 print(" ✓ Tabla vec_docs creada")
65
66 # --- 3. Preparar documentos -----------------------------------------
67 print()
68 print("[3/5] Preparando documentos de ejemplo...")
69
70 documentos = [
71 {
72 "id": 1,
73 "titulo": "Linux",
74 "texto": "Linux es un sistema operativo libre y de código abierto "
75 "basado en el kernel de Linux. Fue creado por Linus Torvalds "
76 "en 1991 y se distribuye bajo la GPL.",
77 },
78 {
79 "id": 2,
80 "titulo": "Python",
81 "texto": "Python es un lenguaje de programación interpretado, "
82 "multiparadigma y de alto nivel. Creado por Guido van Rossum "
83 "en 1991, es conocido por su sintaxis clara y legible.",
84 },
85 {
86 "id": 3,
87 "titulo": "IA Local",
88 "texto": "La inteligencia artificial local permite ejecutar modelos "
89 "de lenguaje en tu propio hardware sin conexión a internet. "
90 "Herramientas como Ollama facilitan este proceso.",
91 },
92 {
93 "id": 4,
94 "titulo": "Docker",
95 "texto": "Docker es una plataforma de contenedores que permite "
96 "empaquetar aplicaciones y sus dependencias en unidades "
97 "portables llamadas contenedores.",
98 },
99 ]
100
101 for doc in documentos:
102 print(f" - [{doc['id']}] {doc['titulo']}")
103
104 # --- 4. Generar embeddings e insertar --------------------------------
105 print()
106 print("[4/5] Generando embeddings con Ollama (nomic-embed-text)...")
107 print(" (Esto puede tardar unos segundos por documento)")
108 print()
109
110 try:
111 import ollama
112 except ImportError:
113 print(" ✗ No se pudo importar ollama. Instálalo con:")
114 print(" pip install ollama")
115 sys.exit(1)
116
117 for doc in documentos:
118 # Generar embedding
119 response = ollama.embeddings(model="nomic-embed-text", prompt=doc["texto"])
120 vector = response["embedding"]
121
122 # Insertar en sqlite-vec
123 conn.execute(
124 "INSERT INTO vec_docs(rowid, embedding) VALUES (?, ?)",
125 [doc["id"], str(vector)],
126 )
127 print(f" ✓ Embedding generado para: {doc['titulo']}")
128
129 # --- 5. Búsqueda semántica -------------------------------------------
130 print()
131 print("[5/5] Búsqueda semántica...")
132 print()
133
134 # Consulta de ejemplo
135 consulta = "¿Qué sistema operativo libre puedo usar?"
136 print(f' Consulta: "{consulta}"')
137 print()
138
139 # Generar embedding de la consulta
140 response = ollama.embeddings(model="nomic-embed-text", prompt=consulta)
141 query_vector = response["embedding"]
142
143 # Buscar en sqlite-vec
144 cursor = conn.execute(
145 """
146 SELECT rowid, distance
147 FROM vec_docs
148 WHERE embedding match ?
149 ORDER BY distance
150 LIMIT 3
151 """,
152 [str(query_vector)],
153 )
154
155 resultados = cursor.fetchall()
156
157 print(" Resultados (más cercano primero):")
158 print()
159 for rowid, distancia in resultados:
160 doc = documentos[rowid - 1] # rowid empieza en 1
161 print(f" [{rowid}] {doc['titulo']} (distancia: {distancia:.4f})")
162 print(f" {doc['texto'][:80]}...")
163 print()
164
165 # --- Cerrar conexión ------------------------------------------------
166 conn.close()
167 print("=" * 50)
168 print("Demo completada")
169 print()
170 print(" Este es el fundamento del RAG local.")
171 print(" En episodios posteriores veremos cómo:")
172 print(" - Indexar documentos completos")
173 print(" - Combinar búsqueda semántica + keywords")
174 print(" - Integrar con Ollama para respuestas contextuales")
175 print("=" * 50)
176
177
178if __name__ == "__main__":
179 main()
180