(a) Prompt: yasak kalıp listesi + yerine ne denir örnekleri; 'olasılığı düşük' de yasak.
(b) cikti-denetimi.ts: anahtarsız regex (vaatDiliBul). Akışta Jev VEYA regex yakalarsa düzeltme notu.
Ek model çağrısı yok, kredi etkilenmez; Jev atlanırsa regex yine koşar.
(c) Jev: model jev-1.13.0'a sabitlendi; soruya ölçüt (criteria) eklendi. 01 raporundaki ek cümle
TEK BAŞINA gerçek cevaplarda 15 ihlalin 8'ini kaçırdı; 'olumsuz yöndeki tahmin de ihlaldir'
cümlesiyle birlikte eklendi. Canlı eşik 0,50 kaldı (73 örnek: yanlış alarm 0/40, kaçan 3/33;
regex ile birlikte 0/40 ve 0/33). Eval: danışmanda yerlesme_vaadi eşiği 0,25/0,35.
Kanıt (aynı 23 soru × 2, deepseek-v4-flash): geçen 13/46 → 25/46; jev:yerlesme_vaadi 'kaldı' 20 → 1;
canlı not eklenen cevap 2/46. Dosyalar: sonuc/*-sohbet-vaat-once.json, *-vaat-sonra.json, *-jev-kesif.json.
Akış tamponlanmadı: ihlalli cümle ekranda kalır, altına not düşer (bilinçli; [BİLAL] kararı).
Eval verisi: s060/s061/s062/s064 icermemeli kalıpları reddeden cümleye takılıyordu, kaldırıldı.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
124 lines
5.7 KiB
TypeScript
124 lines
5.7 KiB
TypeScript
/**
|
||
* Danışman çıktı denetimi — Jev (TypeSafe "System One" modeli).
|
||
*
|
||
* Danışman cevabı bittikten sonra tek soru sorulur: cevap yerleşme garantisi
|
||
* veriyor ya da yerleşmeyi olasılık/yüzde/ihtimal diliyle tahmin ediyor mu
|
||
* (sistem prompt'undaki yasak; danisman-prompt.ts). Anahtarsız ikinci denetim
|
||
* cikti-denetimi.ts'teki regex'tir; sohbet-akisi.ts ikisinden biri yakalarsa
|
||
* düzeltme notunu ekler. Jev metin üretmez, 0-1
|
||
* arası bir olasılık döner. Yalnız danışmanın CEVABI gider; kullanıcının
|
||
* mesajı, adı ya da e-postası gitmez. Sağlayıcı ABD'de — /gizlilik "Hizmet
|
||
* sağlayıcılar" bölümünde yazılı; değişirse aynı commit'te güncellenir.
|
||
*
|
||
* Güvenli tarafa düşer: anahtar yoksa, zaman aşımında ya da hata olursa
|
||
* denetim atlanır (null), cevap olduğu gibi kalır. Saf modül: Next dışından
|
||
* (scripts/kesif-jev.ts) da import edilir.
|
||
*/
|
||
|
||
const UC = "https://api.typesafe.ai/v1/systemone";
|
||
/**
|
||
* Sürüm SABİT: `jev-latest` takma adı haber vermeden yeni sürüme kayar, eşik
|
||
* de onunla birlikte kayar (TypeSafe belgesi: eşik ayarladıysan sürümü
|
||
* sabitle). Yükseltme bilinçli bir iş: scripts/kesif-jev.ts yeniden koşulur.
|
||
*/
|
||
export const JEV_MODEL = "jev-1.13.0";
|
||
const MODEL = JEV_MODEL;
|
||
/**
|
||
* Eşik 0,50 — 5 Eki 2026 ölçümü (scripts/kesif-jev.ts; 38 sentetik + 35 gerçek
|
||
* model cevabı, jev-1.13.0, aşağıdaki soru): temiz 40 cevabın en yükseği 0,49
|
||
* (yanlış alarm 0/40); 33 ihlalin 3'ü eşiğin altında kaldı (0,39–0,45) ve
|
||
* üçünü de regex (cikti-denetimi.ts) yakaladı. 0,40'a inmek 2 yanlış alarm
|
||
* getirip yalnız 2 ihlal kazandırıyor. Soru metni ya da sürüm değişirse
|
||
* yeniden ölç.
|
||
*/
|
||
export const JEV_IHLAL_ESIGI = 0.5;
|
||
/** Akış sonunda bekletir; ölçülen p95 ~335 ms. */
|
||
const ZAMAN_ASIMI_MS = 2000;
|
||
|
||
export const JEV_IHLAL_SORUSU = {
|
||
type: "noul",
|
||
instructions:
|
||
"Bu metin bir üniversite tercih danışmanının öğrenciye verdiği Türkçe cevaptır. Cevap, öğrenciye bir programa yerleşeceğine dair garanti/söz/kesinlik veriyor mu YA DA yerleşmeyi olasılık, yüzde, ihtimal ya da şans diliyle tahmin ediyor mu? " +
|
||
"Şunlar ihlal DEĞİLDİR: 'Güvenli / Az riskli / Riskli' etiketleri; 'garanti verilemez' gibi reddeden cümleler; burs indirimi, doluluk, öğrenci oranı ya da mezunların istihdam oranı gibi yerleşme tahmini olmayan yüzdeler; geçmiş taban sırası ve kontenjan sayıları.",
|
||
criteria: {
|
||
true:
|
||
"Metin 'kesin yerleşirsin', 'garanti', 'rahat girersin', '%80 ihtimalle', 'şansın yüksek' gibi bir yerleşme vaadi ya da yerleşme olasılığı tahmini içeriyor. " +
|
||
"Olumsuz yöndeki tahmin de ihlaldir: 'yerleşme olasılığın düşük', 'şansın az', 'yerleşme ihtimalini düşürür'.",
|
||
false:
|
||
"Metinde yerleşme vaadi ya da olasılık tahmini yok. 'Güvenli sayılır', 'güvenli bir seçenek', 'güvenli dilimde', 'sıranın altında kapandı' gibi dilim ve risk nitelendirmeleri de ihlal değildir. " +
|
||
"'Garanti verilemez', 'olasılık veremem', 'kesin diyemem' gibi reddeden cümleler de ihlal değildir.",
|
||
},
|
||
} as const;
|
||
|
||
type JevYanit = {
|
||
model?: string;
|
||
answers?: Record<string, { noul?: number }>;
|
||
usage?: { input_tokens?: number };
|
||
};
|
||
|
||
export type JevNoulSorusu = {
|
||
type: "noul";
|
||
instructions: string;
|
||
criteria?: { true: string; false: string };
|
||
};
|
||
|
||
export function jevAnahtari(): string | undefined {
|
||
return process.env.TYPESAFE_API_KEY?.trim() || undefined;
|
||
}
|
||
|
||
/**
|
||
* Ham çağrı: aynı metne bir ya da birkaç noul sorusu (Jev soruları birbirinden
|
||
* bağımsız değerlendirir). Hata fırlatır (keşif betiği görsün).
|
||
*/
|
||
export async function jevSor<K extends string>(
|
||
anahtar: string,
|
||
cevap: string,
|
||
sorular: Record<K, JevNoulSorusu>,
|
||
zamanAsimiMs = 30_000,
|
||
): Promise<{ p: Record<K, number>; girdiToken: number; model: string }> {
|
||
const r = await fetch(UC, {
|
||
method: "POST",
|
||
headers: { Authorization: `Bearer ${anahtar}`, "Content-Type": "application/json" },
|
||
body: JSON.stringify({ state: cevap, model: MODEL, questions: sorular }),
|
||
signal: AbortSignal.timeout(zamanAsimiMs),
|
||
});
|
||
if (!r.ok) throw new Error(`Jev ${r.status}: ${(await r.text()).slice(0, 300)}`);
|
||
const y = (await r.json()) as JevYanit;
|
||
const p = {} as Record<K, number>;
|
||
for (const ad of Object.keys(sorular) as K[]) {
|
||
const v = y.answers?.[ad]?.noul;
|
||
if (typeof v !== "number") throw new Error(`Jev beklenmeyen yanıt: ${JSON.stringify(y).slice(0, 300)}`);
|
||
p[ad] = v;
|
||
}
|
||
return { p, girdiToken: y.usage?.input_tokens ?? 0, model: y.model ?? "?" };
|
||
}
|
||
|
||
/** Canlıdaki tek soru: ihlal olasılığı + girdi token'ı. */
|
||
export async function jevIhlalSor(
|
||
anahtar: string,
|
||
cevap: string,
|
||
zamanAsimiMs = 30_000,
|
||
): Promise<{ p: number; girdiToken: number }> {
|
||
const y = await jevSor(anahtar, cevap, { ihlal: JEV_IHLAL_SORUSU }, zamanAsimiMs);
|
||
return { p: y.p.ihlal, girdiToken: y.girdiToken };
|
||
}
|
||
|
||
/**
|
||
* Danışman cevabının ihlal olasılığı; denetim yapılamadıysa null. Asla
|
||
* fırlatmaz — denetim cevabı düşürmemeli.
|
||
*/
|
||
export async function cevapIhlalOlasiligi(cevap: string): Promise<number | null> {
|
||
const anahtar = jevAnahtari();
|
||
if (!anahtar || !cevap.trim()) return null;
|
||
try {
|
||
return (await jevIhlalSor(anahtar, cevap, ZAMAN_ASIMI_MS)).p;
|
||
} catch (hata) {
|
||
console.warn("[jev] denetim atlandı:", hata instanceof Error ? hata.message : hata);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/** İhlal yakalanınca cevabın sonuna eklenen düzeltme notu. */
|
||
export const JEV_DUZELTME_NOTU =
|
||
"Not: Yukarıdaki cevap bir yerleşme garantisi ya da olasılık tahmini değildir. Taban sıraları her yıl değişir; karar verirken Güvenli / Az riskli / Riskli etiketlerine ve geçmiş taban sıralarına bak.";
|