Yapay Zeka Sistemi
Sistemde üç farklı AI katmanı var: Google Gemini, OpenAI, ve n8n. Hangi özelliğin neyi kullandığı birbirinden tamamen farklı, karıştırılmaması gerekiyor.
| Özellik | Altyapı |
|---|---|
| Header'daki "Deep" genel asistan | n8n webhook |
| PDF/LaTeX içerik çıkarma | n8n webhook |
| Ders içi AI Öğretmen (sağ panel) | Gemini + OpenAI doğrudan |
| Eksiklik Öğretmeni | Gemini doğrudan |
n8n Entegrasyonu
Dosyalar: src/modules/ai/services/index.js, src/modules/files/services/ai.processor.js
n8n, workflow otomasyonu için kullanılıyor. Backend doğrudan n8n webhook'larına HTTP POST atar; n8n tarafında hangi AI'ın çalıştığı, nasıl çalıştığı tamamen n8n workflow'larında tanımlı. Backend sadece sonucu alır.
1. Header "Deep" Genel Asistan
Uygulamanın üst köşesindeki AI logosu açıldığında çıkan chat paneli ("Deep" başlıklı) n8n üzerinden çalışır.
Akış: AIAssistantPanel.tsx → POST /ai/chat → backend → n8n webhook → { output: "..." } dönüyor
Backend n8n'e şunu gönderir:
{
"action": "sendMessage",
"sessionId": "<kullanıcı id>",
"message": "<kullanıcının yazdığı metin>"
}
n8n'den gelen yanıtta output alanı olması beklenir. Yoksa hata mesajı gösterilir.
Varsayılan webhook URL: http://n8n.app.cozizle.com/webhook/c42a080e-ad67-44fc-a7aa-3fe6e0a759ae
Bu URL, Sistem Ayarları ekranından değiştirilebilir (n8nChatWebhookUrl ayarı). setting tablosunda saklanır. Boş bırakılırsa varsayılan URL kullanılır.
Panelde ses kaydı da destekleniyor — kullanıcı mikrofona konuşunca ses OpenAI ile yazıya çevrilir, sonra bu metin n8n'e gönderilir.
Sohbet geçmişi: Konuşmalar message tablosunda session_id ile saklanıyor. Panel her açılışta bu geçmişi yükler.
2. LaTeX / PDF İçerik Çıkarma
Soru bankasına veya içerik olarak yüklenen PDF dosyaları, n8n üzerinden işlenir. n8n workflow'u içindeki LaTeX/matematik içeriği tanır ve markdown formatına dönüştürür.
Varsayılan webhook URL: http://n8n.app.cozizle.com/webhook/latex-extractor
Bu URL da Sistem Ayarları ekranından değiştirilebilir (n8nLatexExtractorWebhookUrl ayarı).
n8n'den beklenen yanıt formatı (birden fazla format destekleniyor):
{ "markdown_formatted": "...", "pages": [...] }
// veya
{ "output": "..." }
// veya
{ "text": "..." }
Google Gemini
Dosya: src/integrations/gemini.client.js
Hangi Modeller Kullanılıyor?
| Görev | Model |
|---|---|
| Genel metin üretimi (chat, analiz, JSON) | gemini-3-flash-preview |
| Görsel (resim) üretimi | gemini-3.1-flash-image-preview |
| Text-to-Speech (TTS) | gemini-3.1-flash-tts-preview |
| Canlı WebSocket stream | Aynı client üzerinden BidiGenerateContent API'si |
Fallback zinciri: Ana model (gemini-3-flash-preview) yanıt vermezse sırasıyla şunlar denenir:
gemini-3-flash-preview → gemini-2.5-flash → gemini-2.0-flash → gemini-flash-latest
Önemli Teknik Detaylar
- HTTP timeout: 90 saniye (TTS için 300 saniye)
- Retry: 4 deneme, exponential backoff — başlangıç: 1.5 saniye, maksimum: 12 saniye
- Safety threshold: Tüm kategoriler
BLOCK_NONE— içerik filtrelemesi kapalı - TTS çıktı formatı: PCM, 24kHz, mono, 16-bit
- Streaming:
generateTextStreammetodu SSE (Server-Sent Events) üzerinden frontende aktarır
Güvenlik Seviyesi Neden BLOCK_NONE?
Eğitim içeriklerinde (tarih soruları, biyoloji, fizik, kimya vb.) sık sık Gemini'nin güvenlik filtresine takılan içerikler geliyordu. Bunun önüne geçmek için tüm kategoriler devre dışı bırakıldı.
OpenAI
Dosya: src/integrations/openai.client.js
Hangi Modeller Kullanılıyor?
| Görev | Model |
|---|---|
| Genel metin / görsel analiz | gpt-4o-mini |
| Ses transkripsiyonu (temel) | gpt-4o-mini-transcribe |
| Ses transkripsiyonu (zaman damgalı) | whisper-1 |
| Türkçe metin düzeltme | gpt-4o-mini |
Desteklediği Metodlar
extractLearningOutcomes— Video veya PDF içeriğinden kazanım çıkarıranalyzeQuestion— Soru görselini analiz ederextractLearningOutcomesWithVideoTimes— Video bölümlerine göre kazanımları eşleştirirtranscribeAudio— Ses dosyasından metin dönertranscribeAudioWithTimestamps— Whisper ile hem metni hem de kelime/cümle başlangıç-bitiş zamanlarını dönercorrectTurkishText— Yazım hatalarını düzeltir
Görsel İşleme
Görseller OpenAI'ye gönderilmeden önce sharp kütüphanesi ile PNG formatına dönüştürülür. detail: "high" modu kullanılır — bu detaylı görsel analiz sağlar ama daha fazla token harcar.
AI Öğretmen (Sağ Panel Chat)
Dosya: src/modules/ai/services/ai.teacher.service.js
Sağ taraftaki chat paneli, öğrenciye özel ders veren bir AI öğretmen simüle eder. Gemini ve OpenAI birlikte kullanılır:
- Metin chat: Gemini (
gemini-3-flash-preview) — streaming ile - Görsel (resim) analizi: OpenAI (
gpt-4o-mini) — öğrenci görsel yüklerse - Ses transkripsiyonu: OpenAI (
gpt-4o-mini-transcribeveyawhisper-1) - TTS (sesli yanıt): Gemini (
gemini-3.1-flash-tts-preview)
Sistem Prompt Yapısı
AI öğretmenin davranış kuralları büyük bir Türkçe sistem promptuyla belirlenir. Prompt içinde bazı sabit kurallar var:
- Markdown kullanma (yıldız, tire, başlık yok)
- Madde listesi kullanma
- Her yanıt 3-5 cümle
- Her yanıt bir soruyla bitecek
- Dosya adı veya URL söyleyemez
- Öğrencinin adını biliyor ve kullanıyor
Tool Calling
Öğretmen 4 araca sahip. Bunlar Gemini'nin function calling API'si üzerinden çağrılır:
| Tool Adı | Açıklama |
|---|---|
open_lesson_video |
İlgili ders videosunu panelde açar |
show_pdf_on_canvas |
PDF içeriğini canvas'a aktarır |
open_simulation |
İnteraktif simülasyon başlatır |
open_practice_test |
Alıştırma testini açar |
AI öğretmen bu tool'lardan birini çağırdığında frontend event alır ve ilgili içeriği görünür yapar.
Konuşma Geçmişi
Her oturumda son 10 mesaj tutulur. Mesaj başına maksimum 2000 karakter alınır. Daha eski mesajlar bağlam penceresine dahil edilmez.
PDF İşleme
Öğrenci bir PDF yüklediyse:
- Maksimum 20 sayfa işlenir
- Çıkarılan metin
object_notetablosunasource: 'ai_teacher_pdf_text'ile kaydedilir (önbellek) - Bir sonraki istekte aynı PDF'den tekrar çıkarma yapılmaz
PDF'den metin çıkarma veya görsel üretme ortam değişkenleriyle kontrol edilir:
AI_TEACHER_EXTRACT_PDF_TEXT_ON_CHAT=true
AI_TEACHER_GENERATE_PDF_IMAGES_ON_CHAT=true
TTS Önbelleği
Sesli yanıt üretimi pahalı bir operasyon olduğu için sonuçlar bellekte önbelleğe alınır:
- Önbellek: in-memory
Map - TTL:
AI_TEACHER_TTS_CACHE_TTL_MS(varsayılan: 600000ms = 10 dakika) - Maksimum kayıt:
AI_TEACHER_TTS_CACHE_MAX_ITEMS(varsayılan: 80) - Eş zamanlı aynı metni işlememek için
aiTeacherSpeechInFlightdeduplication yapısı var
TTS için maksimum karakter sınırı AI_TEACHER_TTS_MAX_CHARS ile belirlenir (varsayılan: 900). Bu sınırı aşan metinler kesilir.
Performans Loglama
Yanıt sürelerini izlemek için loglara [ai-teacher:timing] prefix'i eklenir. Hangi adımın ne kadar sürdüğünü buradan takip edebilirsin.
Eksiklik Öğretmeni (Deficiency Tutor)
Dosya: src/modules/ai/services/deficiency.tutor.service.js
Öğrencinin başaramadığı konular tespit edilince (bkz. Eksiklik Tespiti) bu servis devreye girer. Sadece Gemini kullanır:
- Model:
gemini-3.1-flash(veyaAI_TUTOR_GEMINI_MODELenv var ile özelleştirilebilir) - Çıktı modu: JSON — Gemini'den doğrudan yapılandırılmış JSON istenir
- Kaynak:
lessonSectionContentTimestablosundan ilgili video bölüm aralıkları çekilir. Zaman aralığına 20 saniye padding eklenir (başa ve sona).
Eksiklik Tespiti Algoritması
Dosya: src/modules/wdeficiencies/services/index.js
Öğrencinin hangi konularda eksik olduğunu otomatik olarak hesaplar.
Nasıl Çalışır?
Her kazanım için şu metrikler hesaplanır:
totalQuestions → o kazanıma ait toplam soru sayısı
correctAnswers → doğru cevap sayısı
incorrectAnswers → yanlış cevap sayısı
errorRate → incorrectAnswers / totalQuestions
isDeficient → errorRate >= 0.20 VE totalQuestions >= 3
Eşik değerleri:
- Hata oranı: %20 (0.20) — eşik değeri env var ile değiştirilebilir
- Minimum soru sayısı: 3 — 3'ten az sorusu olan kazanımlar değerlendirilmez
Önemli Detay
Bir öğrencinin 2 sorudan ikisini de yanlış yapması (%100 hata) eksiklik sayılmaz çünkü veri yetersizdir. Sistemin yanlış alarm üretmemesi için minimum 3 soru şartı konulmuştur.
Whiteboard WebSocket
Dosya: src/modules/whiteboard/socket.js
Beyaz tahta için özel bir WebSocket sunucusu çalışır. Bu Socket.IO değil, ham WebSocket (ws kütüphanesi).
src/index.js içinde Express HTTP sunucusu başlatıldıktan sonra şu şekilde aktif edilir:
initWhiteboardSocket(expressServer);
Express HTTP sunucusu ile aynı port üzerinde çalışır — ayrı bir port açılmaz. HTTP upgrade mekanizması üzerinden WebSocket bağlantısı kurulur.
Önemli Not: GraphQL/Apollo
src/server.js dosyasında Apollo Server import'u ve GraphQL konfigürasyonu var, ama tamamen yorum satırına alınmış durumdaki. Sistem şu an GraphQL kullanmıyor. Tüm API'lar REST endpoint üzerinden çalışıyor.