Technik, Herausforderungen & Learnings
Crawler • Vector DB • LLMsitemap.xml und des lastmod Datums.# 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, ...)
# 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 ...
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]
BeautifulSoup, um "Main Text" zu finden.# 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}
"""
Vielen Dank für die Aufmerksamkeit.