• 7.09.2026 13:38:45
  • Admin Admin

Yazılım eğitimi asistanlarının verdiği teknik yanıtları kaynaklara bağlamak yeterli değildir. Bu makale, iddia çıkarma, pasaj düzeyinde entailment kontrolü, atıf kapsama metriği ve üretim izleme akışını uygular.

Yazılım Eğitimi Asistanlarında Atıf Doğrulama ve Claim Grounding

Yazılım eğitimi yanıtlarında sorun: kaynak var ama iddia desteklenmiyor

Bir yazılım eğitimi asistanının yanıt sonuna 5 kaynak eklemesi, yanıtın doğrulandığını göstermez. Kritik ayrım, her atomik teknik iddianın bir kaynak pasajıyla desteklenmesidir. Örneğin 'PostgreSQL'de CREATE INDEX CONCURRENTLY transaction block içinde çalışmaz' iddiası, genel bir PostgreSQL dokümanı yerine bu kuralı açıkça içeren bir pasajla eşleşmelidir. Retrieval aşamasında her chunk için document_id, chunk_id, revision, byte_offset metadata'sını saklayın; yalnızca URL saklamak, doküman güncellendiğinde geçmiş cevabın hangi metne dayandığını kaybettirir.

Atıf modelini cevap metninden ayrı bir veri yapısı olarak üretin. Her iddia için kaynak pasaj kimliği ve karakter aralığı taşıyan bir kayıt, istemcinin tıklanabilir atıf göstermesini ve sonradan doğrulama çalıştırmasını sağlar. PostgreSQL tarafında JSONB yerine sorgulanabilir ilişki tablosu kullanmak, düşük destek skorlu cevapları sorgulamayı kolaylaştırır.

CREATE TABLE answer_claims (
  answer_id UUID NOT NULL,
  claim_id UUID NOT NULL,
  claim_text TEXT NOT NULL,
  citation_chunk_id UUID NOT NULL,
  support_score REAL NOT NULL,
  verifier_model TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (answer_id, claim_id)
);

CREATE INDEX answer_claims_low_support_idx
  ON answer_claims (created_at DESC)
  WHERE support_score < 0.80;

Yaygın hata, bir chunk'ın semantik olarak konuya yakın olmasını destek kanıtı saymaktır. 'Java HashMap thread-safe değildir' ile 'ConcurrentHashMap thread-safe kullanım için tasarlanmıştır' cümleleri ilişkili görünür; fakat ikincisi ilk iddianın mutlak ve sürümden bağımsız biçimini tek başına ispatlamaz. Verifier katmanı 'related' ile 'entailed' etiketlerini ayrı tutmalıdır.

Atomik iddia çıkarma ve doğrulanabilir cevap sözleşmesi

Doğrulama birimini paragraf değil atomik iddia yapın. Bir paragrafta API davranışı, performans sonucu ve güvenlik önerisi varsa, tek bir atıf bu üç önermeyi kapsamayabilir. Üretici modele, Markdown cevaptan önce JSON Schema ile claim listesi çıkarttırın ve her claim'i tek doğrulanabilir önerme ile sınırlayın. OpenAI Structured Outputs, PydanticAI veya Instructor gibi şema zorlayabilen istemciler bu aşamada serbest biçimli JSON ayrıştırma hatalarını azaltır.

from pydantic import BaseModel, Field
from typing import Literal

class Claim(BaseModel):
    text: str = Field(min_length=12, max_length=400)
    kind: Literal["fact", "procedure", "constraint", "recommendation"]
    requires_citation: bool = True

class DraftAnswer(BaseModel):
    answer_markdown: str
    claims: list[Claim] = Field(min_length=1, max_length=20)

# Prompt kuralı:
# Her claim tek bir teknik önerme içermeli.
# Bir claim içinde 've', 'ancak', 'bu nedenle' ile birleşen
# bağımsız doğrulanabilir sonuçlar ayrı claim olmalı.

İddia çıkarımından sonra deterministic kontroller ekleyin. Kod bloklarındaki paket sürümü, CLI bayrağı veya API adı gibi unsurlar claim listesinde yoksa, yanıtın doğrulanmamış yüzeyi büyür. Aşağıdaki kontrol, geri tırnak içindeki komutları yakalayıp en az bir claim ile sözcük kesişimi arar. Bu kontrol semantic verifier'ın yerine geçmez; gözden kaçmış operasyonel iddiaları kuyrukta işaretler.

import re

def uncovered_code_terms(markdown: str, claims: list[str]) -> set[str]:
    code_terms = set(re.findall(r"`([A-Za-z0-9_./:=@-]{3,})`", markdown))
    claim_blob = " ".join(claims).lower()
    return {term for term in code_terms if term.lower() not in claim_blob}

assert uncovered_code_terms(
    "Calistirin: `kubectl rollout status deployment/api`",
    ["kubectl rollout status komutu deployment durumunu bekler"]
) == set()

Pasaj düzeyinde entailment skoru ile atıf doğrulama

Her claim için top-k retrieval sonucu getirmek yerine, önce hybrid retrieval ile adayları daraltın, sonra claim-passage çiftlerini cross-encoder veya NLI modeliyle sıralayın. Qdrant üzerinde dense vektör araması ve BM25'yi Reciprocal Rank Fusion ile birleştirmek, API isimleri ve hata kodları gibi exact-match sinyallerini korur. Ardından Hugging Face `cross-encoder/nli-deberta-v3-base` benzeri bir NLI modeliyle labels entailment, neutral ve contradiction olasılıklarını ölçün. Karar skoru yalnızca entailment olasılığı değil, contradiction cezasını da içermelidir: `score = p_entailment - 0.75 * p_contradiction`.

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

name = "cross-encoder/nli-deberta-v3-base"
tok = AutoTokenizer.from_pretrained(name)
model = AutoModelForSequenceClassification.from_pretrained(name)

claim = "CREATE INDEX CONCURRENTLY bir transaction block icinde calismaz."
passage = "CREATE INDEX CONCURRENTLY cannot run inside a transaction block."
inputs = tok(claim, passage, return_tensors="pt", truncation=True, max_length=512)
probs = torch.softmax(model(**inputs).logits[0], dim=-1)
labels = {label.lower(): probs[i].item() for i, label in model.config.id2label.items()}
score = labels["entailment"] - 0.75 * labels["contradiction"]
print(labels, score)

NLI modelinin 512 token sınırı önemli bir edge case'tir. Pasajı doğrudan 2.000 token gönderirseniz tokenizer çoğunlukla son kısmı keser ve iddiayı destekleyen cümle yok olabilir. Chunk saklama katmanında 250-400 tokenlık bölümler ve 40-60 token overlap kullanın; verifier'a ise retrieval chunk'ının yanında komşu chunk'ları değil, önce hedef chunk'ın en ilgili 1-3 cümlesini gönderin. `spaCy` ile cümleleme ve embedding similarity ile sentence selection uygulanabilir.

Eşik değerini rastgele 0.8 seçmeyin. En az 300 gerçek claim-passage çiftini destekli, yetersiz ve çelişkili diye etiketleyin. Precision odaklı bir eğitim asistanında otomatik atıf için `support_score >= 0.88`, 0.70-0.88 arası için yeniden retrieval, altı için claim'i yanıttan çıkarma gibi üç kademeli politika uygulanabilir. Özellikle güvenlik ve veri kaybı iddialarında otomatik yayın eşiğini daha yüksek tutmak gerekir.

Önce-sonra ölçümü: atıf kapsama oranı ve yanlış destek oranı

Atıf kalitesini LLM'in kendi 'kaynaklar doğru mu?' yanıtıyla ölçmeyin. Deney setini soru, beklenen atomik iddialar ve kabul edilen kaynak pasajlarından oluşturun. Her sürüm için claim coverage, supported-claim precision ve contradiction escape rate raporlayın. Coverage, kaynak gerektiren claim'lerin kaçının geçerli bir atıf aldığıdır; precision ise atıf verilen claim'lerin insan incelemesinde gerçekten desteklenme oranıdır.

def citation_metrics(rows: list[dict]) -> dict:
    required = [r for r in rows if r["requires_citation"]]
    cited = [r for r in required if r["citation_chunk_id"] is not None]
    supported = [r for r in cited if r["human_label"] == "supported"]
    contradictions = [r for r in required if r["human_label"] == "contradicted"]
    return {
        "claim_coverage": len(cited) / max(len(required), 1),
        "supported_claim_precision": len(supported) / max(len(cited), 1),
        "contradiction_escape_rate": len(contradictions) / max(len(required), 1)
    }

Profiling için OpenTelemetry trace'lerinde `retrieval.ms`, `rerank.ms`, `nli_verify.ms`, `claims.count` ve `unsupported_claims.count` span attribute'larını kaydedin; Grafana'da p50, p95 ve p99 gecikmeyi ayrı izleyin. Önce mevcut akışta 1.000 sabit soruyu çalıştırıp metrikleri kaydedin. Sonra claim-level verifier'ı açıp aynı sorularla karşılaştırın. Örneğin NLI doğrulaması p95'e 180 ms eklerken supported-claim precision'ı 0.71'den 0.91'e taşıyorsa, bu maliyetin hangi soru sınıflarında kabul edileceğini somut veriye göre belirlersiniz. Sadece ortalama latency raporlamak, uzun dokümanlarda oluşan kuyruk etkisini gizler.

Canlı trafikte tüm yanıtları insanla etiketlemek pahalıdır. Her hafta support_score bandına göre stratified sampling yapın: 0.70-0.80, 0.80-0.90 ve 0.90+ aralıklarından eşit sayıda örnek inceleyin. Böylece modelin yüksek skorlu fakat yanlış atıf üretmeye başladığı calibration drift'i, yalnızca rastgele örneklemeye göre daha erken yakalanır.

Üretim politikası: desteklenmeyen iddiayı düzeltmek veya saklamak

Verifier başarısız olduğunda modeli aynı claim'i tekrar yazmaya körlemesine zorlamayın. Bu yaklaşım, doğru kaynak bulunmadığında daha ikna edici fakat hala dayanaksız bir ifade üretebilir. Önce aynı sorgunun query expansion varyantlarıyla ikinci retrieval turu yapın: API adı, hata mesajı ve ürün adı korunurken doğal dil kısmını sadeleştirin. İkinci tur da başarısızsa cevabı 'Bu ayrıntıyı mevcut kaynaklarla doğrulayamıyorum' şeklinde daraltın ve doğrulanmış prosedürü koruyun.

Doküman revizyonları için atıf geçerliliğini asenkron yeniden kontrol edin. Kaynak ingest edildiğinde içerik hash'i değişen chunk'lara bağlı `answer_claims` kayıtlarını bir işe alın. Temporal veya Celery kullanarak yalnızca etkilenen claim'leri yeniden verify etmek, tüm cevap arşivini tekrar çalıştırmaktan daha kontrollüdür. Bu işte citation URL'sinin hala 200 dönmesi yeterli değildir; yeni chunk metni eski hash'ten farklıysa entailment yeniden hesaplanmalıdır.

Kullanıcı arayüzünde support skorunu sayısal olarak göstermek yerine, her teknik iddianın yanında ilgili pasajın kısa alıntısını ve doküman revizyon tarihini gösterin. Alıntıyı 300 karakterle sınırlayın ve HTML render öncesi sanitize edin. Kaynak doküman içeriğini doğrudan `innerHTML` ile basmak, güvenilir görünen bir doküman deposundan bile XSS taşınmasına neden olabilir; DOMPurify gibi bir sanitizer kullanın.

Sık Sorulan Sorular

Yazılım eğitimi asistanında atıf doğrulama için embedding benzerliği yeterli mi?

Hayır. Embedding benzerliği retrieval adayı seçmek için uygundur, fakat 'ilgili' ile 'iddia tarafından destekleniyor' ayrımını yapmaz. Top-20 adayı dense retrieval ve BM25 ile toplayın, ardından claim-passage çiftlerinde NLI veya cross-encoder skoru hesaplayın. Çelişki olasılığını ayrıca ceza olarak kullanın.

Yazılım eğitimi cevaplarında her cümle için ayrı kaynak gerekli mi?

Her cümle için değil, doğrulanabilir her atomik teknik claim için kaynak gereklidir. Selamlama veya kullanıcının verdiği bilgiyi tekrar eden cümleler atıf istemez. API davranışı, komut sonucu, güvenlik sınırı, benchmark sonucu ve sürümle değişebilecek davranışlar `requires_citation=true` olarak işaretlenmelidir.

Atıf doğrulama gecikmesini nasıl ölçer ve sınırlarım?

OpenTelemetry ile retrieval, reranking ve NLI verification span'larını ayrı kaydedin; Grafana'da p95 ve p99'u izleyin. NLI çağrılarını claim bazında batch edin, aday pasajları 250-400 token chunk'lara bölün ve yalnızca top-3 pasajı doğrulayın. Değişiklikten önce ve sonra aynı sabit soru setinde supported-claim precision ile latency dağılımını birlikte karşılaştırın.

Kaynak dokümanı güncellenince eski yazılım eğitimi cevapları ne olmalı?

Chunk metninin SHA-256 hash'ini ve doküman revision bilgisini citation kaydında saklayın. Yeni ingest sırasında hash değişen chunk'lara bağlı claim'leri Celery veya Temporal işiyle yeniden doğrulayın. Destek skoru eşiğin altına düşerse atıfı güncelleyin, claim'i kaldırın veya cevabı yeniden üretim kuyruğuna alın.

AI / LLM Discovery

Bu makale Opendart Akademi Yapay Zeka eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.

Opendart Akademi llms.txt