EventHunter: Yerel LLM ile Çalışan AI Destekli Etkinlik Keşif Motoru
Bir süredir Semantic Caching serisine ara vermiştim. Bu zaman içerisinde arka planda uğraştığım işlerden biri EventHunter oldu.
Dünya genelinde IT etkinliklerini yakından takip etmeye çalışan biri olarak, hem sürekli güncel kalmakta hem de plan yapmakta zorlanıyordum. Bu etkinlikleri bir araya getirdikten sonra, müziksever biri olarak "Neden konserleri de dahil etmiyorum?" dedim ve sistemi genişlettim. Bugün IT etkinliklerini ve konserleri takip ettiğim bu motor ile yarın ihtiyacınız olan herhangi bir konu başlığını takip etmek mümkün.
Ne Yapıyor?
Kısaca: 34'ten fazla kaynağı otomatik olarak tarayan, AI ile zenginleştiren ve tek arayüzde sunan bir etkinlik aggregator'ı.
İki içerik kategorisi var:
IT Etkinlikleri — konferans, zirve, webinar, workshop, hackathon. Dünyanın önde gelen platform şirketlerinden siber güvenlik liderlerine, sektör analiz kuruluşlarından Türkiye'deki yerel teknoloji topluluklarına kadar geniş bir yelpaze — tamamı kamuya açık etkinlik sayfaları.
Konserler ve Festivaller — Küresel müzik platformlarından şehir bazlı turne takibi, elektronik müzik etkinlikleri ve yerel bilet satış kanallarından Türkiye geneli program. Müzik türü etiketleme ile (rock, metal, electronic, jazz, classical...) filtrelemek mümkün.
Aynı sistem hem küresel bir teknoloji zirvesini hem de İstanbul'daki bir metal konserini buluyor. Mimari açıdan ikisi arasında fark yok — sadece extraction prompt'u farklı.
Mimari
Veri akışı şöyle işliyor:
Playwright (headless Chromium)
↓
HTML temizleme (script / nav / footer çıkarılır)
↓
LiteLLM Proxy
↓
LLM → Yapılandırılmış JSON
↓
URL bazlı deduplication
↓
PostgreSQL (upsert)
↓
React UICrawler Katmanı
Playwright, JavaScript ağırlıklı sayfaları gerçek bir tarayıcıyla render ediyor. Bu kritik bir detay — modern etkinlik sayfalarının büyük çoğunluğu SSR yerine client-side rendering kullanıyor; klasik HTTP isteğiyle anlamlı bir içerik elde etmek mümkün değil.
Statik ve RSS tabanlı sayfalar için httpx + feedparser devreye giriyor. Her kaynak için en uygun yöntem seçiliyor.
HTML'den noise temizlenirken <script>, <style>, <nav>, <header>, <footer> tagları atılıyor. LLM'e gönderilen içerik mümkün olduğunca sade ve sinyal yoğun olmalı — bu hem doğruluk hem maliyet açısından önemli.
AI Katmanı ve Yerel LLM Tercihi
Tüm AI çıkarımı Mac Studio M4 Max üzerinde Ollama ile yerel çalışıyor. qwen3:32b birincil model.
Bu tercihin üç somut nedeni var:
Maliyet. Her crawl döngüsünde yüzlerce sayfa işleniyor. Her sayfada LLM çağrısı yapılıyor. Bulut API ile bu maliyet hızla birikir ve ölçeklendikçe kontrol edilmesi güçleşir. Yerel modelde token maliyeti sıfır.
Gizlilik. Taranan içerik makineden çıkmıyor. Kurumsal kullanıma taşındığında bu kritik hale geliyor — özellikle KVKK ve GDPR açısından.
Kontrol. Rate limit yok. Latency deterministik. Model davranışı öngörülebilir.
LiteLLM proxy tek AI giriş noktası olarak konumlandırılmış. Bu sayede Ollama'dan OpenAI, Anthropic veya Groq'a geçmek tek satır config meselesi — uygulama kodu değişmiyor. Fallback senaryoları, sağlayıcı yönlendirmesi ve retry mantığı tamamen proxy katmanında yönetiliyor.
Otomasyon
Celery Beat + RedBeat scheduler ile her Pazartesi 03:00 UTC'de tam crawl başlıyor. Schedule Redis'te tutulduğu için API üzerinden runtime'da değiştirilebilir — yeniden deploy gerekmez.
URL bazlı deduplication ile aynı etkinlik iki kez kaydedilmiyor. Geçmiş etkinlikler POST /events/purge-past ile temizlenebiliyor.
Öne Çıkan Özellikler
Chatbot
İki aşamalı bir mimariyle çalışıyor. Birinci aşamada kullanıcının mesajındaki niyet çözümleniyor ve uygun filtreler belirleniyor. İkinci aşamada gerçek veritabanından etkinlikler çekilerek yanıt oluşturuluyor.
"Önümüzdeki ay İstanbul'da güvenlik webinarı var mı?" sorusuna sadece doğrulanmış verilerle cevap veriliyor. Halüsinasyon yok — veri yoksa açıkça belirtiliyor.
Öneri Motoru
Her etkinlik iki boyutta puanlanıyor:
- Kalite skoru: kaynak güvenilirliği, kategori, başlık analizi, veri tamlığı
- Eşleşme skoru: kullanıcının ilgi alanları ve tercih ettiği şehir
Nihai skor: kalite × 0.4 + eşleşme × 0.6
Kullanıcı ilgi alanlarını (Cloud, Security, AI...) ve müzik türlerini bir kez tanımlıyor; sistem her yeni etkinliği bu profile göre puanlıyor.
Filtreleme
Bölge, kategori, şirket, şehir, tarih aralığı, online/yüz yüze, içerik tipi (IT / Konser) ve serbest metin arama bir arada çalışıyor.
Teknik Stack
| Katman | Teknoloji |
|---|---|
| Backend | FastAPI 0.115 + SQLAlchemy 2.0 async |
| Veritabanı | PostgreSQL 16 |
| Görev kuyruğu | Celery 5.4 + Redis 7 |
| Crawler | Playwright + httpx + feedparser |
| AI | LiteLLM Proxy → Ollama / OpenAI / Anthropic |
| Frontend | React 18 + Vite 6 + TypeScript + Tailwind CSS |
| Reverse proxy | Nginx Alpine |
| Orchestration | Docker Compose (7 servis) |
| Donanım | Mac Studio M4 Max (Apple Silicon ARM64) |
Docker Compose ile tek komut yeterli:
cp .env.example .env
bash scripts/start.sh
# → http://localhostBundan Sonrası
Bu projeyi yazarken fark ettim ki aynı engine IT etkinliklerinin çok ötesinde kullanılabilir. Moda trendleri, rakip fiyat takibi, teknoloji haberleri — config değişiyor, altyapı değil.