---
title: "Değerlendirme (Eval) Süitinizin API Anahtarı ve Ağ Olmadan Çalışması İçin Deterministik Bir Mock LLM Sağlayıcısı Oluşturun"
url: https://blog.edumints.com/degerlendirme-eval-suitinizin-api-anahtari-ve-ag-olmadan-calismasi
category: "LLM"
date: 2026-10-24T07:07:29.942Z
publisher: Edumints Blog
lang: tr-TR
source_name: "dev.to"
source_url: https://dev.to/royalpinto007/build-a-deterministic-mock-llm-provider-so-your-eval-suite-runs-with-no-api-keys-and-no-network-1415
---

# Değerlendirme (Eval) Süitinizin API Anahtarı ve Ağ Olmadan Çalışması İçin Deterministik Bir Mock LLM Sağlayıcısı Oluşturun

Her LLM projesi er ya da geç aynı engelle karşılaşır: Değerlendirme (eval) süitiniz ve birim testleriniz gerçek bir modeli çağırmak ister. Ancak bunu yaptıkları anda CI/CD süreçleri yavaşlar, maliyet artar, gizli API anahtarlarına ihtiyaç duyulur ve sağlayıcı modelde bir güncelleme yaptığında testler kararsızlaşır. LLM çıktıları doğası gereği deterministik değildir; bu yüzden sadece "veri hattı (pipeline) çalıştı mı?" sorusunu ölçen bir test bile kodunuzla ilgisi olmayan nedenlerle başarısız olabilir.

Bu sorunu çözmenin en etkili yolu **deterministik bir mock (sahte) sağlayıcı** kullanmaktır. Gerçek sağlayıcılarınızla birebir aynı arayüzü uygular, aynı yanıt yapısını döner ve tamamen çevrimdışı çalışır. Puanlama, veri toplama ve raporlama mantığınızı denetleyen testler hiçbir zaman ağa çıkmaz. `evalgate` projesini temel alan bu yaklaşım, kullandığınız her teknoloji yığınına kolayca uyarlanabilir ve **AI Test Stratejileri** açısından kritik bir pratik sunar.

## 1. Her İki Tarafın Paylaştığı Ortak Bir Arayüzle Başlayın

Tüm sistemin temeli tek bir kurala dayanır: Gerçek sağlayıcınız ve mock sağlayıcınız birbiriyle tamamen değiştirilebilir olmalıdır. Bu nedenle önce dar ve net bir arayüz (`Provider`, `ProviderRequest`, `ProviderResponse`) tanımlamalı ve her adaptörün buna uymasını sağlamalısınız.

```typescript
export interface ProviderRequest {
  model: string;
  messages?: { role: string; content: string }[];
  prompt?: string;
  temperature?: number;
  maxTokens?: number;
}

export interface ProviderResponse {
  output: string;
  latencyMs: number;
  usage?: { promptTokens: number; completionTokens: number; totalTokens: number };
  costUsd?: number;
  model: string;
  raw?: unknown;
}

export interface Provider {
  readonly name: string;
  complete(request: ProviderRequest): Promise<ProviderResponse>;
  embed?(text: string): Promise<number[]>;
}
```

- **Pratik Çıkarım:** Yanıt nesnesi yalnızca metin (`output`) değil; gecikme süresi (`latencyMs`), token kullanımı (`usage`) ve maliyet (`costUsd`) bilgilerini de taşır. Eğer mock sağlayıcınız yalnızca düz bir metin dönerse, token kullanımını veya maliyeti hesaplayan kod yollarınız test edilmemiş olur. Her zaman yanıtın **tam şeklini** modelleyin.

## 2. İsteği Tek Bir Prompt Metnine İndirgeyin

İstekler sisteme tek bir `prompt` dizgesi olarak veya bir sohbet mesajları listesi (`messages`) halinde gelebilir. Mock sağlayıcının üzerinde mantık yürütebilmesi için tek bir standart (canonical) metne ihtiyacı vardır; bu yüzden ilk adım olarak girdiyi normalize edin.

```typescript
export function resolvePrompt(request: ProviderRequest): string {
  if (request.prompt !== undefined) return request.prompt;
  if (request.messages && request.messages.length > 0) {
    return request.messages.map((m) => `${m.role}: ${m.content}`).join("\n");
  }
  return "";
}
```

- **Pratik Çıkarım:** Farklı girdi formatlarını (`prompt` ve `messages`) tek bir standart metinde birleştirmek, test altyapınızın karmaşıklığını azaltır ve sonraki adımlarda deterministik hesaplama yapmayı kolaylaştırır.

## 3. Tohumlanmış (Seeded) Hash ile Deterministik Hale Getirin

Mock sağlayıcının temel vaadi, **aynı girdinin her zaman aynı çıktıyı üretmesidir**. Bunun için prompt metninin bir hash değerini hesaplayıp bu değeri küçük bir sözde-rastgele sayı üretecine (PRNG) tohum (`seed`) olarak besleyebilirsiniz. **FNV-1a** ve **mulberry32** algoritmaları sadece birkaç satır koddan oluşur ve sıfır dış bağımlılık gerektirir.

```typescript
const seed = fnv1a(prompt);
const rand = mulberry32(seed);
const latencyMs = Math.round(5 + rand() * 50); // 5-55ms arasında sabit "gecikme"
```

- **Pratik Çıkarım:** Tohum değeri doğrudan prompt'tan türetildiği için, üretilen sahte gecikme süresi (`latencyMs`) bile tamamen tekrarlanabilirdir. Test süitini bin kez çalıştırsanız dahi birebir aynı sayıları alırsınız; bu da **snapshot (anlık görüntü) tarzı doğrulamaları (assertions)** mümkün kılar.

## 4. Çıktıyı Kontrol Etmenin İki Yolu: Fixture'lar ve Direktifler

Kullanışlı bir mock sağlayıcı rastgele değil, **yönlendirilebilir (steerable)** olmalıdır. Çıktıyı kontrol etmek için iki temel mekanizma kullanılır:

- **Fixture'lar (Hazır Yanıtlar):** Prompt içerisindeki metinle büyük/küçük harf duyarsız alt dizge (substring) olarak eşleşen önceden hazırlanmış yanıtlardır ve ilk eşleşen kural kazanır. Bu yaklaşım, belirli bir birim testin mock sağlayıcının iç çalışma mantığıyla ilgilenmeden tam ve sabit bir çıktıyı sabitlemesine (pinlemesine) olanak tanır.

---

**Kaynak:** dev.to (https://dev.to/royalpinto007/build-a-deterministic-mock-llm-provider-so-your-eval-suite-runs-with-no-api-keys-and-no-network-1415)
**Yayıncı:** [Edumints Blog](https://blog.edumints.com) · Alıntılarken bu URL'ye bağlantı verin: https://blog.edumints.com/degerlendirme-eval-suitinizin-api-anahtari-ve-ag-olmadan-calismasi
