Przejdź do treści

~/projekty / ai-semantic-db

Semantic DB

CLI do lokalnego wyszukiwania semantycznego w twoich danych strukturalnych: definiujesz schemat, dodajesz rekordy i szukasz zwykłym językiem. Bez chmury i kluczy API.

rola
projekt i implementacja: model schematu, CLI, embeddingi, testy
czas
sie – wrz 2026
typ
własny
stack
Python 3.12 · Typer · SQLAlchemy · Alembic · PostgreSQL + pgvector · Ollama (bge-m3)
demo.mp4
[wideo demo: nagranie ekranu 1–3 min]

01 / problem

Wyszukiwanie semantyczne bez usługi w chmurze

Istniejące narzędzia do wyszukiwania semantycznego działają w chmurze albo są związane z jednym źródłem danych. Celem było zdefiniowanie własnej struktury, trzymanie danych na własnej maszynie i szukanie po znaczeniu, a nie po słowach kluczowych.

02 / rozwiązanie

Kolekcje sterowane schematem z lokalnymi embeddingami

Kolekcję definiuje się zwięzłą gramatyką pól, np. price:float:embed:unit=PLN, obsługującą typy text, enum, int, float, bool, date i tablice stringów. Każdy rekord jest renderowany do jednej sformatowanej karty tekstowej i przy zapisie osadzany modelem bge-m3 przez Ollama, więc dodany znaczy przeszukiwalny. Wyszukiwanie to cosinusowe top-k z tabelą Rich i trybem --explain; odmawia działania, gdy kolekcję osadzono innym modelem, bo odległości między modelami nic nie znaczą.

  • [screenshot 1]

    [podpis]

  • [screenshot 2]

    [podpis]

03 / architektura

Jak to działa

ingest
  1. schemat
  2. rekordy
  3. embeddingi
  4. pgvector
query
  1. pytanie
  2. embeddingi
  3. retrieval top-k
  4. CLI

CLI w Pythonie 3.12 na Typer, w warstwach: domain, application (porty i przypadki użycia), infrastructure (SQLAlchemy, Alembic, klient Ollama) i cli, a kontrakty import-linter pilnują, by zależności szły do środka. Rekordy to payloady JSONB w PostgreSQL 17 z pgvector (halfvec 1024), więc schemat zmienia się bez DDL dla każdej kolekcji. Zapisy to przypadki użycia; odczyty przechodzą przez jedną fasadę zapytań.

04 / wyniki

Efekt

05 / wnioski

Czego się nauczyłem

  • Payloady JSONB zamiast tabel dla każdej kolekcji kosztują trochę szybkości, ale dają dużo prostsze migracje i dowolne schematy.
  • Zapisywanie dokładnie wyrenderowanego tekstu obok każdego wektora chroni przed cichym rozjazdem, gdy szablon zmieni się po utworzeniu embeddingów.

galeria

  • [zdjęcie]

    [podpis]

  • [zdjęcie]

    [podpis]

  • [zdjęcie]

    [podpis]