İçeriğe geç
Çılgın Yazılım

Kurumsal Yazılım ve Entegrasyon kod örnekli

Laya ile Türkçe Metin Sınıflandırma: Talebi Yönlendirmek

Laya bir destek talebine üç soruyu tek istekte, olasılıklarıyla cevaplar. Varsayılan pencere 1.024 token: uzun bir e-postanın sonu okunmasa da istek hata vermez.

Çılgın Yazılım 9 dk okuma

Laya ile Türkçe Metin Sınıflandırma: Talebi Yönlendirmek
İçindekiler
  1. Adım 1: Soruları choice, score ve noul olarak yazın
  2. Adım 2: İsteği tek PHP fonksiyonuyla gönderin
  3. Adım 3: Alıntılanan eski yazışmayı metinden atın
  4. Adım 4: Kesilen ya da belirsiz talebi insana bırakın
  5. Hakaret tespitinde Laya, öteki üç Türkçe sette Clef önde
  6. Eşiği insanın etiketlediği eski taleplerle doğrulayın

EVREN yapay zekâ platformundaki laya modeli bir destek talebine sorduğunuz soruları tek istekte yanıtlar: hangi birime gitmeli, ne kadar acil, içinde hakaret var mı. Cevap serbest metin olarak gelmez. Her soru için bir değer ve olasılık döner. Böylece Türkçe metin sınıflandırmada iş, sohbet modelinin çıktısını şemaya zorlamaktan çıkar ve olasılığa eşik koymaya iner: eşiğin altında kalan talebi insan okur. Aşağıdaki adımlar bu akışı PHP 8.0 ve üstü, cURL ve mbstring ile kurar. Anahtarı almayı ve kullanım şartlarını onaylamayı EVREN API'sine PHP ile ilk istek yazısı anlatıyor.

Laya systemone isteğinin soru türlerini, okuma penceresini ve eşik kuralını özetleyen kart
Model emin olmadığında ya da metni sonuna kadar okumadığında karar insanındır.

Adım 1: Soruları choice, score ve noul olarak yazın

İstek gövdesi üç alandan oluşur: model (burada laya), state (sınıflandırılacak metin) ve questions. Her sorunun anahtarını siz seçersiniz, yanıt aynı anahtarlarla döner. Soru type, instructions ve gerekiyorsa criteria taşır. EVREN'in model kataloğu (giriş yapınca açılır) üç türü şöyle tanımlar:

TürNe sorarYanıtta ne döner
choiceSeçeneklerden biri (criteria: anahtar → açıklama)choice, probabilities, answer_confidence
scoreSıralı düzeyler (criteria: liste)score (düzeylerin beklenen değeri, üç düzeyde 0–2), probabilities
noulEvet mi, hayır mınoul: evet olasılığı (0–1)

Bu ve sonraki dört bloğu laya.php adlı tek dosyaya sırayla ekleyin. Talebin üç sorusu bir sabitte durur:

PHP
<?php
// Açıklamalar modelin okuduğu metindir: kısa ve birbirinden ayırt edici olsun.
const TALEP_SORULARI = [
    'birim' => [
        'type' => 'choice',
        'instructions' => 'Talebi hangi birim ele almalı?',
        'criteria' => [
            'fatura' => 'ödeme, iade, ücret, fatura',
            'teknik' => 'hata, kesinti, giriş sorunu',
            'kargo' => 'gönderim, teslimat, gecikme',
            'diger' => 'diğer',
        ],
    ],
    'aciliyet' => [
        'type' => 'score',
        'instructions' => 'Ne kadar acil?',
        'criteria' => ['acil değil', 'orta', 'kritik'],
    ],
    'hakaret' => [
        'type' => 'noul',
        'instructions' => 'Mesajda hakaret veya saldırgan ifade var mı?',
    ],
];

Seçenek sayısını küçük tutun. ConvAI'nin çok dilli Laya model kartı, 1.024 token'ın 256'sının soruya ve seçeneklerine ayrıldığını yazar ve choice sorularının yaklaşık 20 seçeneğin altında tutulmasını önerir. EVREN'in kataloğuna göre Türkçe metin EVREN'in Türkçe ince ayarlı checkpoint'ine, İngilizce metin ConvAI'nin convaiinnovations/laya checkpoint'ine gider. Hangisinin yanıtladığı routing.model alanındadır.

Adım 2: İsteği tek PHP fonksiyonuyla gönderin

laya_sor() soruları POST /v1/systemone adresine gönderir ve 200 ile gelen, answers alanı olan yanıtı dizi olarak döndürür. Geri kalan her durumda istisna fırlatır, böylece çağıran kod tek bir catch ile talebi insana bırakır.

PHP
// Anahtar kodda durmaz, sunucunun ortam değişkeninden okunur.
function laya_sor(string $metin, array $sorular, int $maxLen = 1024): array
{
    $ch = curl_init('https://evren-llmapi.ssyz.org.tr/v1/systemone');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT => 20,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('EVREN_API_KEY'), 'Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode(
            ['model' => 'laya', 'state' => $metin, 'questions' => $sorular, 'max_len' => $maxLen],
            JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR
        ),
    ]);
    $ham = curl_exec($ch);
    $kod = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    $yanit = is_string($ham) ? json_decode($ham, true) : null;
    if ($kod !== 200 || ! isset($yanit['answers'])) {
        // mb_strcut harfi ortadan bölmez: bölünen UTF-8, bu mesajı JSON'a ya da utf8mb4 sütuna yazdırmaz
        $neden = $ham === false ? curl_error($ch) : ($yanit['error']['message'] ?? mb_strcut($ham, 0, 200, 'UTF-8'));
        throw new RuntimeException("Laya HTTP $kod: $neden");
    }
    return $yanit;
}

Kimlik için hem Authorization: Bearer hem X-API-Key başlığı kabul edilir, hata gövdesi OpenAI biçimindedir. Belgeye göre 403 terms_not_accepted şartların onaylanmadığını, 429 hesap kotasını, 503 sunucunun o anki doluluğunu gösterir. Günlük token kotası Laya dahil bütün modellerin toplamıdır ve EVREN'in çıkarım sayfasına göre her gün 03:00'te (TSİ) yenilenir.

laya_sor() 503'te de yeniden denemez, istisna fırlatır; talebi Adım 4'teki talep_yonlendir() insana bırakır. Yeniden denemek isterseniz bekleme süresi ve devre kesici kararlarını üçüncü parti API'de dayanıklılık yazısı anlatıyor. Anahtar tanımlı değilse getenv() false döner ve istek boş bir Bearer başlığıyla gider. CodeIgniter 4'te .env dosyasına yazılan EVREN_API_KEY de getenv() ile okunur.

Adım 3: Alıntılanan eski yazışmayı metinden atın

Alıntılanan eski yazışma, Laya'nın 1.024 token'lık varsayılan okuma penceresini boşuna doldurur. Pencereyi aşan kısım kesilir, istek hata vermez ve tek işaret usage.truncated alanının true olmasıdır. Yanıtla açılan bir talep altındaki eski yazışmayı da taşır. Bu fonksiyon yeni mesajın alıntının üstünde olduğunu varsayar: > ile başlayan satırları ve alıntı başlığının altını atar.

PHP
// Karar en üstteki yeni mesajdan verilir, altındaki alıntı modele gitmez.
function talep_metni(string $govde): string
{
    $tut = [];
    foreach (preg_split('/\R/u', mb_scrub($govde, 'UTF-8')) as $satir) {
        $satir = trim($satir);
        if (preg_match('/^(-{2,}\s*Original Message\s*-*|.*\b(wrote|yazdı):)$/iu', $satir)) {
            break;   // alıntı başlığı: altındaki her şey eski yazışma
        }
        if ($satir !== '' && ! str_starts_with($satir, '>')) {
            $tut[] = $satir;
        }
    }
    return implode("\n", $tut);
}

Desenler örnektir. Kendi e-posta altyapınızın alıntı başlığını gerçek bir talep üzerinde görüp ekleyin. Yeni mesajın içinde yazdı: ile biten bir satır da alıntı başlığı sayılır; o satır ve altı atılır. Yanıt alıntı başlığının altına yazıldıysa o da atılır. Başlığın üstünde hiçbir satır kalmadıysa Adım 4 talebi konuya bakarak sınıflamaz, insana bırakır. Üstte bir selam satırı (Merhaba,) bile kalırsa talep konu ve o satırla sınıflanır.

mb_scrub() geçersiz UTF-8 baytlarını ? yapar. O çağrı olmasa preg_split() geçersiz metinde false döndürür, foreach uyarı verip döngüyü atlar ve talep boş sayılır.

Adım 4: Kesilen ya da belirsiz talebi insana bırakın

Kesilen ya da belirsiz talep üç fonksiyonla insan kuyruğuna gider. talep_sinifla() ilk yanıt kesildiyse aynı metni max_len 8.192 ile bir kez daha sorar, belgedeki en geniş pencere de budur. talep_yonlendir() gövdeden yeni mesaj kalmadıysa hiç istek atmaz, kaldıysa konuyu mesajın başına ekler.

PHP
// Kesilen yanıtı Laya'nın en geniş penceresiyle bir kez daha sorar.
function talep_sinifla(string $metin): array
{
    $y = laya_sor($metin, TALEP_SORULARI);
    return ($y['usage']['truncated'] ?? false) ? laya_sor($metin, TALEP_SORULARI, 8192) : $y;
}

// Ağ hatası, kota ya da bulunamayan mesaj: hepsinde talep kaybolmaz, insan kuyruğuna düşer.
function talep_yonlendir(string $konu, string $govde): array
{
    $mesaj = talep_metni($govde);
    if ($mesaj === '') {
        return ['kuyruk' => 'insan', 'neden' => 'yeni mesaj bulunamadı', 'oncelik' => null];
    }
    try {
        $y = talep_sinifla(trim(talep_metni($konu) . "\n" . $mesaj));
    } catch (RuntimeException $e) {
        return ['kuyruk' => 'insan', 'neden' => $e->getMessage(), 'oncelik' => null];
    }
    return talep_karar($y);
}

Geniş pencere yalnız kesilen talepte açılır, çünkü EVREN belgesi max_len'i uzun belgeler için anar. ConvAI'nin model kartı kısa girdinin 8.192 ile de aynı cevabı aldığını yazar, ama EVREN'in Türkçe checkpoint'i için böyle bir ölçüm yayımlanmadı. Aynı kart, yaklaşık 4.000 token'ın üstünde doğruluğun dağıldığını da not eder.

talep_karar() yanıtı dört yola ayırır. Metin yine kesildiyse ya da hakaret olasılığı 0,2 ile 0,8 arasındaysa talep insana gider. Hakaret olasılığı 0,8 ve üstündeyse birimden bağımsız olarak moderasyona gider. Kalan talep birim eşiğinin (answer_confidence < 0,8) altında kaldıysa ya da seçeneklerde olmayan bir birim geldiyse insana, değilse seçilen birime gider.

PHP
// Eşikler örnektir: birim eşiğini son adımdaki sayım verir.
function talep_karar(array $y): array
{
    $a = $y['answers'];
    $birim = $a['birim']['choice'] ?? '';
    $hakaret = $a['hakaret']['noul'] ?? 0.5;
    [$kuyruk, $neden] = match (true) {
        $y['usage']['truncated'] ?? false => ['insan', 'metin 8.192 tokenı aşıyor'],
        $hakaret > 0.2 && $hakaret < 0.8 => ['insan', 'hakaret belirsiz'],
        $hakaret >= 0.8 => ['moderasyon', null],   // birim belirsiz olsa da
        ($a['birim']['answer_confidence'] ?? 0) < 0.8,
        ! isset(TALEP_SORULARI['birim']['criteria'][$birim]) => ['insan', 'birim belirsiz'],
        default => [$birim, null],
    };
    return ['kuyruk' => $kuyruk, 'neden' => $neden, 'oncelik' => (int) round($a['aciliyet']['score'] ?? 2)];
}

Eşik için önerilen alan answer_confidence'tır, yani verilen yanıtın olasılığı; confidence dağılımın ne kadar sivri olduğunu ölçer. İsteğe min_confidence eklerseniz Laya eşiğin altındaki yanıtı low_confidence diye işaretler. Bu işaretin yanıttaki yeri katalog örneğinde görünmediği için kural burada kodda duruyor.

Aynı isteği "model": "clef" ile gönderirseniz bu kesilme kontrolü hiçbir şey yakalamaz. Belgeye göre Clef'in penceresi 16.384 token'dır, aşan kısım hata vermeden kesilir ve usage.truncated dönmez: input_tokens 16.384 ise metin kesilmiştir. Clef max_len, lang ve min_confidence alanlarını yok sayar, yanıtında answer_confidence da yoktur.

Hakaret tespitinde Laya, öteki üç Türkçe sette Clef önde

Platformun yayımladığı iç ölçüme göre Clef iki Türkçe karar setinde belirgin biçimde, niyet testinde az farkla önde. Hakaret tespitinde ise Laya önde. Katalogdaki karşılaştırma tablosu şöyle:

Veri setiÖlçütLayaClef
jevalt-bench TR (1.019 örnek)seçim / evet-hayır%59 / %76%91 / %98
jev-TR çeviri seti (1.539 örnek)seçim / evet-hayır%54 / %77%88 / %96
MASSIVE niyet testi (Türkçe)seçim%95%98
OffensEval-TR testievet-hayır%92%87

MASSIVE niyet testinde fark küçüktür: %95'e karşı %98. Rakamlar platformun kendi ölçümüdür ve sizin taleplerinizin dağılımını göstermez. Katalog hakaret ve saldırganlık akışlarında Laya'yı önerir. Birim sorusunu Clef'e taşımak isterseniz Adım 4'teki birim eşiğini probabilities üzerinden yeniden kurmanız ve kesilmeyi input_tokens ile yakalamanız gerekir.

Eşiği insanın etiketlediği eski taleplerle doğrulayın

Doğru eşik, birimini bir insanın verdiği eski talepleri Laya'ya sorup her eşikte kaç talebin otomatik gittiğini ve bunların kaçının yanlış birime düştüğünü sayarak bulunur. Bu betik laya.php ile aynı klasörde çalışır:

PHP
<?php
// gecmis.csv: başlıksız, UTF-8; her satır konu;govde;birim (birim TALEP_SORULARI anahtarıyla birebir: fatura, diger)
require __DIR__ . '/laya.php';
is_file(__DIR__ . '/gecmis.csv') || exit("gecmis.csv bulunamadı\n");
$f = fopen(__DIR__ . '/gecmis.csv', 'r');
$sonuc = [];
while (($s = fgetcsv($f, null, ';', '"', '')) !== false) {
    [$konu, $mesaj, $dogru] = [$s[0] ?? '', talep_metni($s[1] ?? ''), trim($s[2] ?? '')];
    if ($mesaj === '' || ! isset(TALEP_SORULARI['birim']['criteria'][$dogru])) {
        echo "atlandı: mesaj yok ya da birim tanımsız ($dogru)\n";
        continue;
    }
    try {
        $y = talep_sinifla(trim(talep_metni($konu) . "\n" . $mesaj));   // üretimdeki yol: gerekirse 8.192 ile
        $a = $y['answers']['birim'] ?? [];
        $kesik = $y['usage']['truncated'] ?? false;                      // üretimde insana gider, otomatik sayılmaz
        $sonuc[] = [$kesik ? 0 : ($a['answer_confidence'] ?? 0), ($a['choice'] ?? '') === $dogru];
    } catch (RuntimeException $e) {
        echo "atlandı: {$e->getMessage()}\n";
    }
}
foreach ([0.6, 0.7, 0.8, 0.9] as $esik) {
    $oto = array_filter($sonuc, fn ($r) => $r[0] >= $esik);
    $yanlis = count(array_filter($oto, fn ($r) => ! $r[1]));
    printf("eşik %.1f: %d/%d talep otomatik, %d yanlış birim\n", $esik, count($oto), count($sonuc), $yanlis);
}

PowerShell'de anahtarı $env:EVREN_API_KEY = 'evren_llm_...' ile verip C:\xampp\php\php.exe dogrula.php komutunu çalıştırabilirsiniz. Dosyayı UTF-8 kaydedin: başka kodlamadaki Türkçe harfleri mb_scrub() ? yapar ve sayım bozulur. Birim sütunu TALEP_SORULARI anahtarlarıyla birebir yazılır (fatura, diger); Fatura ya da Diğer yazan satır atlanır ve ekranda görünür. Betik üretimdeki kesilme yolunu izler: kesilen talebi 8.192 ile yeniden sorar, yine kesilirse otomatik saymaz. Hakaret bandına ya da moderasyona düşen talepleri ayırmaz, onları da birim olasılığına göre sayar.

Otomatik giden talepler içinde yanlış sayısının kabul edebileceğiniz düzeye indiği en düşük eşik, Adım 4'teki birim eşiğinin yerine geçer. Hakaret bandını aynı yolla seçmek için CSV'ye bir hakaret sütunu gerekir. Platform, dolaylı ifade edilen iptal ve ayrılma tehditlerinde modelin hata yapabileceğini yazar ve kritik akışlarda eşiğin kendi verinizle doğrulanmasını ister. Laya'nın model kartı da taban checkpoint'lerin olasılıklarını kalibre edilmeden fazla iyimser bulur.

Test ortamı: Kod PHP 8.2.12 (cURL, mbstring) ve CodeIgniter 4.7.4 (yalnız .env denemesi) ile, katalogdaki istek ve yanıt biçimini taklit eden yerel bir sunucuya karşı çalıştırıldı: normal ve eşik altı talep, boş, alıntılı ve alttan yanıtlanmış metin, 8.192 token'ı aşan metin, 401, 403, 429, 503, JSON olmayan 502, bozuk JSON ve zaman aşımı. Gerçek uç noktaya istek atılmadı. Taklit olasılıkları kurallarla ürettiği için Laya'nın doğruluğu ölçülmedi; uç noktanın davranışı belgeye göre yazıldı.


Eşiğin üstünde kalan yanlış karar doğrudan yanlış birime gider: Laya bir fatura itirazını 0,95 olasılıkla kargo sayarsa talep kimseye görünmeden kargo kuyruğuna düşer. Temsilci talebi başka kuyruğa taşıdığında bu hata görünür olur. Taşınan her talebi Laya'nın verdiği birim ve answer_confidence değeriyle birlikte kaydederseniz yanlış kararların hangi olasılık aralığında toplandığı görünür. Son adımdaki sayımı da bu taleplerle yenileyip birim eşiğini oradan güncellersiniz.

Beğeniniz benzer içerikleri öne çıkarmamıza yardımcı olur.

Sık sorulan sorular

Laya bir LLM mi, sohbet modelinin yerine geçer mi?

Hayır. Laya metin üretmeyen bir karar modelidir; verilen metin hakkında choice, score ve noul sorularını tek geçişte olasılıklarıyla yanıtlar. EVREN kataloğu serbest metin yanıtı gereken işlerde sohbet modellerini önerir: cevap taslağı, özet ya da çeviri için sohbet ucu kullanılır.

Jev için yazılmış bir istemci EVREN'de çalışır mı?

Evet, platform belgesine göre. EVREN'in /v1/systemone ucu Jev sözleşmesiyle uyumludur ve Jev istemcileri model alanına jev-1 yazıldığında değişiklik yapmadan çalışır; bu ad Laya'ya gider. Taban adres ve anahtar yine EVREN'inkiler olmalıdır.

Laya'yı Hugging Face'ten indirip kendi sunucumda çalıştırabilir miyim?

Evet, ama EVREN'in Türkçe ince ayarı olmadan. ConvAI'nin laya-multilingual checkpoint'i Apache 2.0 lisanslıdır ve laya-serve aynı /v1/systemone biçimini sunar; LAYA_API_KEY tanımlanmazsa bütün ağ arayüzlerinde kimliksiz dinler. EVREN'in Türkçe checkpoint'i evren/laya-tr-v5 ise 11 Ekim 2026'da herkese açık değildi.

Yazan

Çılgın Yazılım

Ben Evren Çılgın; yazılım geliştirme, web teknolojileri ve sistem tasarımı alanlarında uzmanlaşmış bir geliştiriciyim. Uzun yıllardır hem frontend hem de backend tarafında üretken, ölçeklenebilir ve kullanıcı dostu çözümler üretiyorum.

Hakkımızda Bize ulaşın

Bu konuda bir projeniz mi var?

İhtiyacınızı birkaç cümleyle anlatın; uygun yaklaşımı birlikte belirleyelim.

Projenizi Anlatın

İlgili yazılar

Yorumlar

Henüz yorum yok. Sorunuzu ya da deneyiminizi ilk siz yazın.

Yorum yazın

Yorumunuz onaylandıktan sonra yayınlanır. Ekibimiz gerekirse konuyla ilgili bir yanıt da paylaşır.

Yayınlanmaz; yalnızca gerektiğinde size ulaşmak için.

En az 10 karakter.

Tüm yazılar