Zurück zu schuemann.it

RAG Chatbot
für die Uni Erfurt

Technik, Herausforderungen & Learnings

Crawler • Vector DB • LLM

Agenda

  • Was ist RAG? (Architektur)
  • Der Crawler (Datengewinnung)
  • Vektordatenbank & Caching
  • Learnings & Herausforderungen
  • Live-Code Beispiele

Die Architektur

graph LR A[Website Uni Erfurt] -->|Crawler| B(Raw JSON) B -->|Text Splitter| C(Chunks) C -->|Mistral Embeddings| D[(FAISS Vector DB)] User -->|Frage| App[Streamlit App] App -->|Suche| D D -->|Kontext| App App -->|Kontext + Frage| LLM[Mistral LLM] LLM -->|Antwort| User

Technik: Der Inkrementelle Crawler

  • Problem: Wir wollen nicht jedes Mal 15.000 Seiten neu laden.
  • Lösung: Nutzung der sitemap.xml und des lastmod Datums.
  • Feature: Cleanup-Logik für gelöschte Seiten.
# crawler.py - Logic Snippet
def run_crawler():
    # 1. Alle URLs aus der Sitemap holen
    all_urls = _get_all_page_urls_from_sitemap(SITEMAP_INDEX_URL)
    
    # 2. Aufräumen: Gelöschte Seiten entfernen
    _cleanup_deleted_pages(list(all_urls.keys()), CRAWLER_OUTPUT_DIR)

    # 3. Nur Neues crawlen
    for url, lastmod_str in all_urls.items():
        if lastmod_dt > last_run_time:
            # Download & Save
            _crawl_and_save_page_as_json(url, lastmod, ...)

Technik: Custom Embeddings Cache

  • Problem: Embeddings kosten Geld (API) und Zeit.
  • Lösung: Ein lokaler Cache-Wrapper um die LangChain Embeddings.
  • Berechnet Hash des Text-Chunks -> Speichert Vektor lokal.
# build_db.py - Custom Class
class CachedMistralEmbeddings(Embeddings):
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        # 1. Cache prüfen (Hash des Textes)
        text_hash = hashlib.md5(text.encode('utf-8')).hexdigest()
        cache_path = os.path.join(self.cache_folder, f"{text_hash}.pkl")

        # 2. Wenn da: Laden
        if os.path.exists(cache_path):
            results[i] = pickle.load(f)
        
        # 3. Wenn weg: API rufen & speichern
        else:
            new_embeddings = self.wrapped.embed_documents(texts_to_fetch)
            # ... save pickle ...

Learning 1: "Wann beginnt das Semester?"

❌ Bot Fehler: "Das Wintersemester beginnt am 01.10.2019."
✅ Lösung: Re-Ranking nach Publikationsdatum.

Aktuelle Inhalte müssen technisch priorisiert werden, da die Vektor-Ähnlichkeit allein das Datum oft ignoriert.

# app.py - Re-Ranking Logic
def re_rank_docs(docs):
    # Sortiere Suchergebnisse nach Datum (Neueste zuerst)
    # und nimm nur die Top 5
    return sorted(
        docs, 
        key=lambda d: d.metadata.get('publication_date', '1970-01-01'), 
        reverse=True
    )[:5]

Learning 2: Strukturierte Seiten

  • Der Crawler nutzt BeautifulSoup, um "Main Text" zu finden.
  • Problem: Wenn Navigation, Footer oder Cookie-Banner im Main-Content landen, halluziniert der Bot.
  • Vorteil Schema.org: Strukturierte Daten liefern sauberes JSON statt geratenes HTML.
  • "Garbage in, Garbage out" gilt auch für KI.

👉 Zum vorherigen Vortrag: Strukturierte Daten & Schema.org

Learning 3: Deutsch vs. Englisch

  • Die Uni-Website ist zweisprachig.
  • User-Frage: Deutsch.
  • Kontext: Oft gemischt (englische Studiengangsbezeichnungen, deutsche Verwaltungstexte).
  • Mistral LLM: Kann gut übersetzen, aber der Prompt muss die Ausgabesprache erzwingen.
# app.py - Prompt Engineering
prompt_template = """
Du bist ein freundlicher und präziser Chatbot für die Universität Erfurt.
Beantworte die Frage des Nutzers ausschließlich basierend auf dem folgenden Kontext.
Achte dabei besonders auf das Publikationsdatum der Quellen und bevorzuge die neuesten Informationen. Das heutige Datum ist {datetime.now().strftime('%Y-%m-%d')}.
Wenn die Antwort nicht im Kontext enthalten ist, sage höflich, dass du die Information nicht finden konntest.
Antworte auf Deutsch.
Kontext: {context}
Frage: {question}
"""

Zusammenfassung

Technik

  • Python & LangChain
  • Mistral AI (LLM & Embeddings)
  • FAISS (Vector Store)
  • Streamlit (UI)

Content

  • Aktualität ist King (Metadaten!)
  • Sauberes HTML hilft dem Crawler
  • Strukturierte Daten (Schema.org) wären der Goldstandard

Fragen?

Vielen Dank für die Aufmerksamkeit.