fix(danisman): olasılık/vaat dili — prompt kalıpları, anahtarsız regex denetimi, Jev sorusu ve sürümü (iş 1) [KARAR]
(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>
This commit is contained in:
@@ -24,12 +24,22 @@ import {
|
||||
} from "ai";
|
||||
import { aracSeti, type AracBaglami } from "./araclar";
|
||||
import { sohbetDilModeli } from "./client";
|
||||
import { vaatDiliBul } from "./cikti-denetimi";
|
||||
import { cevapIhlalOlasiligi, JEV_DUZELTME_NOTU, JEV_IHLAL_ESIGI } from "./jev";
|
||||
|
||||
/** Bir cevapta en fazla model adımı (araç turları + son cevap). */
|
||||
const ARAC_TUR_SINIRI = 4;
|
||||
const HATA_METNI = "Danışman şu anda yanıt veremiyor.";
|
||||
|
||||
export type CiktiDenetimi = {
|
||||
/** Jev'in ihlal olasılığı; denetim yapılamadıysa null. */
|
||||
jevP: number | null;
|
||||
/** Regex'in yakaladığı garanti/olasılık ifadeleri (boş = temiz). */
|
||||
vaatRegex: string[];
|
||||
/** Cevabın sonuna düzeltme notu eklendi mi. */
|
||||
vaatNotu: boolean;
|
||||
};
|
||||
|
||||
export function danismanAkisi(opts: {
|
||||
system: string;
|
||||
mesajlar: ModelMessage[];
|
||||
@@ -40,6 +50,8 @@ export function danismanAkisi(opts: {
|
||||
onYarim: (metin: string) => Promise<void>;
|
||||
/** Sağlayıcı bu sürede bitirmezse cevap yarım sayılır (varsayılan 120 sn). */
|
||||
zamanAsimiMs?: number;
|
||||
/** Çıktı denetiminin sonucu (gözlem/eval için; cevabı etkilemez). */
|
||||
onDenetim?: (d: CiktiDenetimi) => void;
|
||||
}): ReadableStream<UIMessageChunk> {
|
||||
return createUIMessageStream<UIMessage>({
|
||||
execute: async ({ writer }) => {
|
||||
@@ -97,21 +109,24 @@ export function danismanAkisi(opts: {
|
||||
if (zamanAsimi.aborted) throw new Error("Zaman aşımı: sağlayıcı cevabı bitirmedi");
|
||||
if (!metin.trim()) throw new Error("Boş cevap");
|
||||
|
||||
// Çıktı denetimi (jev.ts): cevap garanti/olasılık dili içeriyorsa
|
||||
// sonuna düzeltme notu eklenir. Akış zaten gittiği için cevap geri
|
||||
// alınamaz; not hem ekrana hem kayda yazılır. Denetim yapılamazsa
|
||||
// (anahtar yok, zaman aşımı) cevap olduğu gibi kalır.
|
||||
const ihlalP = await cevapIhlalOlasiligi(metin);
|
||||
if (ihlalP != null) {
|
||||
console.info("[soru] jev ihlal olasılığı:", ihlalP.toFixed(2));
|
||||
if (ihlalP >= JEV_IHLAL_ESIGI) {
|
||||
const id = crypto.randomUUID();
|
||||
metin += `\n\n${JEV_DUZELTME_NOTU}`;
|
||||
writer.write({ type: "text-start", id });
|
||||
writer.write({ type: "text-delta", id, delta: JEV_DUZELTME_NOTU });
|
||||
writer.write({ type: "text-end", id });
|
||||
}
|
||||
// Çıktı denetimi: cevap garanti/olasılık dili içeriyorsa sonuna
|
||||
// düzeltme notu eklenir. İki bağımsız denetimden biri yeter: Jev
|
||||
// (jev.ts; anahtar yoksa ya da zaman aşımında atlanır) ve anahtarsız
|
||||
// regex (cikti-denetimi.ts; her cevapta koşar). Akış zaten gittiği
|
||||
// için cümle ekrandan geri alınamaz; not hem ekrana hem kayda yazılır.
|
||||
// Ek model çağrısı yok; kredi etkilenmez.
|
||||
const vaatRegex = vaatDiliBul(metin);
|
||||
const jevP = await cevapIhlalOlasiligi(metin);
|
||||
const vaatNotu = vaatRegex.length > 0 || (jevP != null && jevP >= JEV_IHLAL_ESIGI);
|
||||
console.info("[soru] çıktı denetimi: jev", jevP == null ? "atlandı" : jevP.toFixed(2), "regex", vaatRegex.length, vaatNotu ? "→ not eklendi" : "");
|
||||
if (vaatNotu) {
|
||||
const id = crypto.randomUUID();
|
||||
metin += `\n\n${JEV_DUZELTME_NOTU}`;
|
||||
writer.write({ type: "text-start", id });
|
||||
writer.write({ type: "text-delta", id, delta: JEV_DUZELTME_NOTU });
|
||||
writer.write({ type: "text-end", id });
|
||||
}
|
||||
opts.onDenetim?.({ jevP, vaatRegex, vaatNotu });
|
||||
await opts.onTamam(metin);
|
||||
tamamlandi = true;
|
||||
writer.write({ type: "finish" });
|
||||
|
||||
Reference in New Issue
Block a user