Budowa chatbota CLI
5. Budowa lokalnego indeksu
Lokalne chatboty, agenci i systemy RAG z własną bazą wiedzy
Instrukcja krok po kroku · materiał uzupełniający
Budujemy chatbota w konsoli
dane/index.json
Zamień każdy fragment na wektor i zapisz wektory razem z informacją, jak powstały. Indeks zbudujesz raz dla danej wersji bazy i modelu.
Zależności, które muszą pozostać zgodne
Pytanie i dokumenty muszą być osadzane tym samym modelem embeddingowym. Sama zgodność liczby wymiarów nie wystarcza. Dlatego zapiszemy tag i digest modelu, skrót pliku fragmentów oraz kolejność identyfikatorów.
Utwórz indeks.py: pierwsza część
Skopiuj poniższy blok do nowego pliku indeks.py. Następny podrozdział zawiera dalszą część tego samego pliku. Uruchomisz go dopiero po złożeniu obu części.
"""Mały indeks JSON; pełny przegląd wektorów, bez zewnętrznych bibliotek."""
import argparse
import hashlib
import json
import math
from datetime import datetime, timezone
from lokalny import ROOT, CONFIG, api, embed, require_models, unit
from baza import CHUNKS, read_chunks
INDEX = ROOT / "dane" / "index.json"
def file_hash(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def build():
if INDEX.exists():
raise FileExistsError("index.json już istnieje. Zachowaj go pod inną nazwą przed nową budową.")
records = read_chunks()
model = CONFIG["embedding_model"]
before = require_models([model])[model]
vectors = []
for i, record in enumerate(records, 1):
vectors.append(embed(record["text"]))
print(f"Embedding {i}/{len(records)}", flush=True)
if len({len(v) for v in vectors}) != 1:
raise ValueError("Niezgodne wymiary embeddingów.")
if require_models([model])[model] != before:
raise ValueError("Model zmienił się podczas budowania indeksu. Powtórz budowę.")
result = {"format": "poradnik-json-v1", "created_at": datetime.now(timezone.utc).isoformat(),
"embedding_model": model, "embedding_digest": before,
"ollama_version": api("/api/version")["version"],
"chunks_sha256": file_hash(CHUNKS), "dimension": len(vectors[0]),
"chunk_ids": [r["chunk_id"] for r in records], "vectors": vectors}
with INDEX.open("x", encoding="utf-8") as output:
json.dump(result, output, ensure_ascii=False)
print("Indeks gotowy:", INDEX)Co zapisujemy
| Pole | Po co |
|---|---|
| vectors | Wektory w kolejności odpowiadającej fragmentom. |
| chunk_ids | Kontrola przypisania wiersza wektora do treści. |
| embedding_digest | Wykrycie zmiany modelu pod tym samym tagiem. |
| chunks_sha256 | Wykrycie zmiany treści, kolejności lub metadanych bazy. |
| dimension | Kontrola zgodności rozmiaru wszystkich wektorów. |
Funkcja unit() normalizuje wektor. Dla dwóch wektorów o długości jeden iloczyn skalarny jest podobieństwem kosinusowym. Wynik służy do porządkowania fragmentów, nie do określania prawdopodobieństwa prawdziwości odpowiedzi.
Punkt kontrolny
- Rozumiesz, dlaczego zmiana dokumentu wymaga nowego indeksu.
- Masz zapisaną pierwszą część indeks.py.
Instrukcja uczestnika · Python i Ollama · wydanie 29.09.2026