Przejdź do treści

~/projekty / ai-book-chat

AI Book Chat

Wgrywasz PDF i zadajesz pytania o jego treść. Odpowiedzi spływają strumieniowo ze wskazaniem stron źródłowych, na lokalnym pipeline RAG.

rola
backend, pipeline RAG, interfejs w React
czas
sie – wrz 2026
typ
własny
stack
Python · FastAPI · PostgreSQL + pgvector · Celery + Redis · Ollama · Groq · React 19 · TypeScript
demo.mp4
[wideo demo: nagranie ekranu 1–3 min]

01 / problem

Czy można ufać odpowiedzi o długiej książce?

Zwykły model czatu odpowiada z ogólnej wiedzy i nie pokaże, skąd wziął twierdzenie. Przy długim PDF-ie potrzeba odpowiedzi opartych na tekście, stron do sprawdzenia i uczciwej informacji, że książka nie porusza danego tematu.

02 / rozwiązanie

Wyszukiwanie z re-rankingiem i cytatami

Worker parsuje PDF, wykrywa sekcje (najpierw spis treści, potem heurystyki nagłówków, na końcu zwykłe strony) i tnie tekst na chunki po ok. 600 tokenów z 15% zakładką, które nigdy nie przekraczają granicy sekcji. Każde pytanie jest przepisywane na samodzielne zapytanie na podstawie ostatnich wypowiedzi, dopasowywane wyszukiwaniem kosinusowym w pgvector i re-rankowane przez LLM przed generowaniem. Źródła płyną jako pierwsze, więc interfejs pokazuje cytaty, zanim odpowiedź się skończy; gdy nic trafnego nie znaleziono, odpowiedź mówi o tym na początku.

  • [screenshot 1]

    [podpis]

  • [screenshot 2]

    [podpis]

03 / architektura

Jak to działa

ingest
  1. dokumenty
  2. parsowanie
  3. chunking
  4. embeddingi
  5. pgvector
query
  1. pytanie
  2. przepisanie pytania
  3. retrieval top-k
  4. LLM re-rank
  5. LLM
  6. UI

Frontend w React komunikuje się przez HTTP i SSE z API w FastAPI, opartym na PostgreSQL z pgvector (HNSW, cosinus). Wgrane pliki trafiają do kolejki w Redis i przetwarza je worker Celery: parsowanie PyMuPDF, chunking i wsadowe embeddingi w lokalnym Ollama (nomic-embed-text). Czat, przepisywanie zapytań i re-ranking używają dowolnego endpointu zgodnego z OpenAI, domyślnie Groq. Obie aplikacje obsługują pnpm workspaces i Turborepo.

04 / wyniki

Efekt

05 / wnioski

Czego się nauczyłem

  • Embeddingów celowo nie da się podmienić: kolumna wektorowa ma stałą szerokość, więc inny model to migracja i ponowny import. Aplikacja nie startuje, gdy skonfigurowane wymiary nie zgadzają się z kolumną, zamiast zwracać wyniki, które wyglądają wiarygodnie, ale nic nie znaczą.
  • Pytania uzupełniające, jak „a co z jego bratem?”, działają tylko dzięki krokowi przepisywania; samo wyszukiwanie nie widzi kontekstu. Poza zakresem na razie: zapytania między dokumentami, OCR skanów i konta użytkowników.

galeria

  • [zdjęcie]

    [podpis]

  • [zdjęcie]

    [podpis]

  • [zdjęcie]

    [podpis]