fix(danisman): revizyon aracı atlanmasın — geçmiş araç kaydına indirgenir, beyan regex'i genişledi, soru formu Türkçe karakter (QA B1, B4)

Kök neden (B1): chat_messages yalnız metin tutar; başarılı revizyonun kaydı
("revize ediyorum… Liste yenilendi… 1-5") araçsız cevapla aynı görünüyordu ve
model sonraki turda bu kalıbı taklit edip liste_revize çağırmadan "yenilendi"
yazıyor, program adlarını eski cevaptan kopyalıyordu (eval: 8 revizyon
isteğinde 1 çağrı, 5 sahte beyan). Metnin altına "[araç çağrıldı]" işareti
eklemek işe yaramadı — model işareti de kopyaladı.

- sohbet-gecmisi.kayitliMesajModelMetni: modele giden pencerede başarılı
  revizyon turu kısa araç kaydına iner (meta.revizyon'dan), araçsız
  "yenilendi" diyen tur (düzeltme notu olmayan eski kayıtlar dâhil) uydurma
  listesiyle birlikte düşer; kayıt ve ekran değişmez. route.ts bunu kullanır.
- revizyonNiyetiVar + sohbet-akisi.ilkAdimAracZorunlu: niyet algılanınca ilk
  adımda tool_choice "required". VARSAYILAN KAPALI
  (SOHBET_REVIZYON_ARAC_ZORUNLU=1): ölçümde 7/8 çağrı, 0 sahte beyan verdi ama
  OpenRouter isteği Baidu yerine OpenInference'a yönlendirdi, gecikme 1-7 sn →
  80-112 sn, onlarca paralel araç çağrısı. Açmak Bilal'in kararı.
- danisman-prompt revizyon bölümü: 5 (geçmiş örnek değildir; önce aracı çağır)
  ve 6 (soru formunda Türkçe karakter).
- cikti-denetimi REVIZE_BEYANI: "değişiklikler yapıldı", "artık … tercihin …
  oluşuyor", "listeyi yeniden kurdum", "liste_revize çağrıldı" kalıpları.
- araclar.ts (B4): soru_sor açıklamasına Türkçe karakter kuralı; formdaki
  ASCII'ye düşmüş il adları koddan düzelir (ilAdlariniDuzelt: Istanbul →
  İstanbul, Eskisehir → Eskişehir; yalnız büyük harfle başlayan tam eşleşme).
- scripts/eval/revizyon-arac.ts (pnpm eval:revizyon): gerçek modelle 10
  senaryo, liste_revize çağrı oranı + sahte beyan; liste_revize çalıştırılmaz
  (mesajId yok). Sonuç dosyaları scripts/eval/sonuc/*-revizyon.json.

Kredi: değişmez. akis-denetim 9/9, revizyon-denetim 5/5, tsc ve lint temiz.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-10-09 00:16:35 +03:00
parent f955a76c1e
commit 128c175327
13 changed files with 1067 additions and 16 deletions

View File

@@ -98,6 +98,18 @@ export function danismanAkisi(opts: {
* eski davranışı korur).
*/
rehberler?: readonly RehberKaydi[];
/**
* İlk adımda model araç çağırmak ZORUNDA (toolChoice "required"; hangi araç
* olduğunu model seçer). Route bunu adayın mesajı liste değişikliği
* istediğinde (sohbet-gecmisi.revizyonNiyetiVar) ve aday paketliyken verir:
* model araçsız "listeni yeniden kurdum" yazamaz, ya liste_revize ya
* soru_sor çağırır (QA B1, 8 Eki 2026). Kredi: değişmez; ek adım yok,
* yalnız ilk adımın metin yerine araç olması zorunlu. Ölçüm (8 Eki 2026):
* liste_revize çağrı oranı 1/8 → 7/8, sahte beyan 5 → 0; ama OpenRouter
* "required" parametresini destekleyen sağlayıcıya (OpenInference) geçti,
* gecikme 1-7 sn → 80-112 sn. Bu yüzden route'ta env bayrağıyla, varsayılan kapalı.
*/
ilkAdimAracZorunlu?: boolean;
}): ReadableStream<UIMessageChunk> {
return createUIMessageStream<UIMessage>({
execute: async ({ writer }) => {
@@ -168,7 +180,10 @@ export function danismanAkisi(opts: {
prepareStep: ({ stepNumber }) => {
adimdakiArac = 0;
// Form açıldıysa model cevabı bitirmek zorunda (araç kapalı)
return stepNumber >= ARAC_TUR_SINIRI - 1 || formAcildi ? { toolChoice: "none" } : undefined;
if (stepNumber >= ARAC_TUR_SINIRI - 1 || formAcildi) return { toolChoice: "none" };
// Revizyon niyeti: ilk adım araçsız bitemez
if (stepNumber === 0 && opts.ilkAdimAracZorunlu) return { toolChoice: "required" };
return undefined;
},
maxOutputTokens: 1024,
abortSignal: zamanAsimi,