Soru-Cevap (RAG)
POST /v1/ask, retrieval (bilgi getirme) ve LLM sentezini tek cagrida
birlestiren bir kolaylik katmanidir: sorgunuzu alir, /v1/search ile ayni
hibrit (RRF) motorla ilgili chunk'lari bulur ve yalnizca bu
chunk'lardan sentezlenmis, sayfa atifli bir cevap doner.
Search'ten farki
/v1/search bir retrieval primitifidir — sonuc olarak bir chunk
listesi doner, sentez yapmaz; kendi RAG akisinizi (kendi
promptunuz/LLM'iniz ile) kurmak istediginizde temel yapi tasidir.
/v1/ask ayni retrieval katmanini kullanir ama sentez adimini da
sizin yerinize yapar: hazir, kaynak atifli bir cevap metni alirsiniz.
/v1/search | /v1/ask | |
|---|---|---|
| Doner | Chunk sonuc listesi | Sentezlenmis cevap metni + kaynak listesi |
| Mod secimi | mode: hybrid | semantic | Her zaman hybrid |
| Maliyet | Dusuk (yalniz retrieval) | Daha yuksek (retrieval + LLM) |
| Ne zaman | Kendi RAG akisinizi kuracaksaniz | Hazir, sentezlenmis cevap yeterliyse |
Nasil calisir (retrieve -> generate)
- Retrieve —
query,/v1/searchile ayni hibrit (vektor + kelime, RRF) motora gonderilir;top_k(varsayilan 5, maksimum 20) chunk getirilir.document_idverilirse arama tek bir dokumana, bunun yerinebatch_idverilirse o batch'teki tum dokumanlara scope edilir (ikisi birlikte verilemez — asagidaki Istek bolumune bkz.). - Baglam yoksa — hic chunk bulunamazsa LLM'e hic gidilmez; sabit
ve durust bir cevap donulur:
"Bu soruya belgelerde yanit bulunamadi."Bu cagri yine de basarili sayilir ve normal sekilde ucretlendirilir. - Generate — chunk bulunduysa her biri
[Kaynak: belge=..., sayfa=..., bolum=...]basligiyla bir baglam bloguna donusturulur (bloklar---ile ayrilir) ve motor-bagimsiz, OpenAI-uyumlu bir/chat/completionsuc noktasina (dusuk sicaklik,temperature=0.1) gonderilir. Gecici hatalarda (5xx/timeout) exponential backoff ile tekrar denenir; kalici hatalarda (4xx) veya sunucu tarafinda RAG yapilandirilmamissaRagErrorfirlatilir (→503). - Cevap — LLM'in urettigi metin
answeralaninda doner. Pasajlar numaralidir ([S1],[S2], ...) ve model her iddiayi kaynak numarasiyla isaretler;citations[]yalniz cevapta gercekten atif yapilan kaynaklari icerir (her birisource_notasir).
Auth
Tum M2M uc noktalari gibi Authorization: Bearer <api_key> basligi
gerektirir (dip_live_... ya da dip_test_..., bkz. Baslangic ve Auth).
Istek
Content-Type: application/json govdesi:
{
"query": "fatura odeme kosullari nedir?",
"top_k": 5,
"document_id": null,
"batch_id": null,
"lang": null
}
| Alan | Zorunlu | Aciklama |
|---|---|---|
query | evet | Sorulan soru (bos olamaz) |
top_k | hayir | Baglam icin cekilecek chunk sayisi — varsayilan 5, maksimum 20 |
document_id | hayir | Belirtilirse cevap tek bir dokumana scope edilir |
batch_id | hayir | Belirtilirse cevap bir batch'teki (b_...) tum dokumanlara scope edilir. document_id ile birlikte verilemez — 400 invalid_request |
lang | hayir | Cevabin uretilecegi dil (ISO 639-1 kodu, or. en, de, fr) — verilmezse tenant'in Console → Modeller ayarindaki varsayilan, o da yoksa tr kullanilir. Gecersiz/desteklenmeyen bir kod hata dondurmez, sessizce dusulur (bkz. asagida Cikti dili) |
Cevap
{
"query": "fatura odeme kosullari nedir?",
"answer": "...[belge/sayfa 3]...",
"evidence_trail": {
"identity": true,
"passages": 2,
"entities": 1,
"tables": 0,
"claims": 1
},
"truncated": false,
"proof": {
"verdict": "verified",
"weakest_link": "exact",
"holes": [],
"stats": { "total": 3, "observed": 2, "computed": 1, "rule": 0,
"computed_refuted": 0, "holes": 0 },
"steps": [ ... ]
},
"citations": [
{
"document_id": "...",
"external_item_ref": "...",
"page_no": 3,
"section": "Odeme Kosullari",
"chunk_id": "...",
"snippet": "...",
"kind": "passage"
}
]
}
citations[] yalniz cevabin gercekten atif yaptigi kaynaklari
icerir (answer metnindeki [S#] isaretleriyle source_no uzerinden
birebir eslesir) — retrieval'in getirdigi ama kullanilmayan chunk'lar
artik kaynak olarak sunulmaz. Durust cevap "belgede bulunamadi" ise
citations bostur. Retrieval ayrica bir reranker alaka tabani uygular
(RERANK_MIN_SCORE): cross-encoder'in tabanin altinda puanladigi
adaylar senteze hic ulasmaz — cevabi olmayan soru "kotulerin en iyisi"
kaynak kartlari uretmez. snippet, atif yapilan chunk metninin ilk 200
karakteridir.
Her citation ayrica bir kind tasir: normal bir chunk icin
"passage", kaynak belgenin yapisal temsil katmanindan geldiyse
(asagiya bkz.) "entity" / "table" / "claim". kind alanini
gormezden gelen mevcut entegrasyonlar hicbir sey degistirmeden calismaya
devam eder — chunk kaynakli citation'lar eskisiyle birebir aynidir.
Cikti dili
lang istek alani, answer icindeki anlati metnini — yani modelin
urettigi cevap cumlelerini — hangi dilde yazacagini belirler. Oncelik
sirasi: istek lang > tenant'in Console → Modeller sayfasindaki
varsayilan cikti dili > sabit varsayilan (tr). Gecersiz ya da
desteklenmeyen bir kod hata DONDURMEZ — sessizce tenant ayarina, o da
yoksa varsayilana duser.
lang yalniz modelin urettigi anlatiyi kapsar, asla su ucunu
cevirmez: belgeden alinan alintilar (snippet, ve kanit ogesi
citation'larindaki metinler birebir kalir), varlik degerleri
(kind: "entity" citation'larindaki TIP: ad = deger satirlari kaynak
belgedeki haliyle doner) ve atif etiketleri ([S1], [S2], ... her
zaman ayni bicimde kalir). Bu davranis bilinclidir: bir tutar, tarih ya
da firma adi cevrilerek belge ile uyusmazliga dusmemelidir.
Sadik kalma (hallucination yok)
Sentez sistem promptu modele su kurallari dayatir: sadece verilen
baglamdaki bilgiyi kullan, her onemli iddiadan sonra [S#] bicimli
atif ver, cevap baglamda yoksa bunu acikca soyle ("bu bilgi belgede
bulunamadi"), asla uydurma. Baglam (chunk) hic bulunamazsa bu kurala
gerek kalmadan sabit, durust bir cevap donulur — LLM'e hic gidilmez.
Kredi ve ucretlendirme
/v1/ask, varsayilan olarak 0.20 kredi/sorgudur — /v1/search'ten
daha pahalidir cunku hem embed hem de LLM adimini icerir. Istek oncesi
bakiye kontrol edilir (yetersizse 402 insufficient_credit); sentez
basarisiz olursa (503) ucret dusulmez, yalniz basarili cevapta
dusulur. dip_test_... test key'leri query ucretinden muaftir (kullanim
yine de olculur, bakiyeden dusulmez).
Hatalar
| HTTP | code | Aciklama |
|---|---|---|
| 400 | invalid_request | query eksik/gecersiz, document_id/batch_id gecersiz opak id, ya da document_id ve batch_id birlikte verildi |
| 401 | unauthorized | Eksik, gecersiz veya revoke edilmis key |
| 402 | insufficient_credit | Bakiye, sorgu basi ucret icin yetersiz — /ask, /search'ten daha yuksek maliyetlidir (embed + LLM) |
| 404 | not_found | batch_id tenant'iniza ait degil |
| 429 | rate_limited | tenant_ask throttle scope'u (60/dk) asildi |
| 503 | rag_unavailable | RAG yapilandirilmamis (sunucu tarafi eksik config) ya da LLM kalici hata verdi — bu durumda ucret dusulmez |
Notlar
/v1/ask, retrieve+generate adimlarini tek cagriya sikistiran bir
kolaylik uc noktasidir; kendi promptunuzu/LLM'inizi kullanmak isterseniz
/v1/search ile kendi RAG akisinizi kendiniz kurabilirsiniz.
Kanit izi: chunk'in otesinde
Retrieval artik yalniz metin chunk'i dondurmuyor. Hedef belge(ler)in
zaten yapisal bir temsili varsa (varliklar, tablolar, dogrulanmis
mantik iddialari — bkz. Extraction), /v1/ask bu katmanlardan da
kucuk, deterministik (LLM'siz) bir kanit ogesi seti cekip chunk'larla
ayni numarali [S#] kaynak listesine katar — bir kanit ogesi tipki bir
pasaj gibi atif alabilir, ayni sadakat kurallariyla:
- Varlik — sorguyla kanonik ad/eslenik uzerinden eslesen
TIP: ad = degerbicimli bir satir. - Tablo — tablo-bicimli bir soruyla (or. "hangi miktarlar...") eslesen en fazla 2 markdown tablosu.
- Iddia — sorguyla eslesen, dogrulanmis bir mantik iddiasi
(
statement+ onu destekleyen birebirquote). - Kalem — fatura/beyanname/irsaliye satirlari, belgenin kendi
tablosundan hucre hucre okunmus halde (
KALEM: kalem no=..., tanim=..., miktar=..., tutar=...). Kalem/miktar/adet/dokum sorularinda devreye girer; bir de KALEM OZETI gelir: belgedeki GERCEK kalem sayisi, belge toplami ve kalemlerin toplamiyla belge toplaminin uyusup uyusmadigi. Ozet, gosterilen kalem kotasindan BAGIMSIZDIR — 72 kalemin 40'i gosterilse bile "kac kalem var" sorusu 72 diye cevaplanir. - Kural — belgenin KOYDUGU bir sart ve o sartin deterministik
degerlendirmesi (
IHLAL/saglandi/DEGERLENDIRILEMEDI), sartin belgedeki birebir alintisiyla birlikte. Bulunmus bir ihlal, kullanici sormasa bile cevapta acikca bildirilir; degerlendirmeyi model yapmaz, motorun sonucunu aktarir.
Bu katmanlar tavanlidir (varlik ≤ 6, tablo ≤ 2, iddia ≤ 4, kural ≤ 4,
toplam kanit ≤ 14; kalem katmani devredeyse kalemler bu kotanin
USTUNE eklenir, digerlerinin yerini almaz) ve olagan chunk retrieval'ina
eklemeli (additive) calisir —
hicbir sey eslesmezse kanit hicbir katki yapmaz, /v1/ask tam olarak
eskisi gibi davranir.
Yanittaki evidence_trail objesi, cevapta gercekten atif yapilan
kaynaklar icin raporlar: identity (belge(ler)in bir temsili olup
olmadigi), ve atif yapilan passages, entities, tables, claims
sayilari. Tamamen bilgilendirici amaclidir — evidence_trail additive'dir
ve gormezden gelinmesi guvenlidir.
Sayfa kisiti
Soru acikca bir sayfa soyluyorsa ("2. sayfanin kalemleri", "sayfa 5")
ve tek bir belge kapsami verilmisse, o sayfalarin metni dogrudan
baglama alinir ve diger sayfalardan pasaj gosterilmez. Sayfa bir siralama
sinyali degil, document_id gibi bir kapsam kisitidir.
Goreli ifadeler ("son sayfa", "ilk sayfa") ve "tum sayfalar" bilerek daraltma YAPMAZ.
Kesilen cevap: truncated
Cok kalemli dokum isteyen sorular (or. "tum kalemleri listele") modelin
cikti sinirina dayanabilir. Bu durumda Docsfra once cevabi kaldigi
yerden surdurur (bir devam cagrisi); buna ragmen tamamlanamazsa
truncated: true doner ve cevabin sonuna acik bir uyari yazilir.
Kesilmis bir cevap asla tam cevap gibi sunulmaz — alani yok sayan bir istemci bile metindeki uyariyi gorur.
Cikti butcesi soruya gore secilir: dar bir soru ("gonderici kim") ile
105 kalemlik bir dokum ayni tavani paylasmaz. Cok uzun dokumler icin
/v1/ask yerine Cikarim (extract) yolunu kullanin — kalem listesi
orada deterministik olarak, LLM'in tek tek kopyalamasina bagli
kalmadan uretilir.
Ispat zinciri: cevap degil, adimlar
Atif ([S1]) bir iddianin kaynagini gosterir. Yanittaki proof
objesi bir adim otesine gecer ve cevabin adimlarini verir — her adim
ya belgeden okunmus bir deger, ya deterministik bir kural sonucu, ya da
yeniden hesaplanmis bir aritmetik:
"proof": {
"verdict": "verified",
"weakest_link": "exact",
"holes": [],
"stats": { "total": 3, "observed": 2, "computed": 1, "rule": 0,
"computed_refuted": 0, "holes": 0 },
"steps": [
{ "no": 1, "kind": "observed", "ground": "exact", "source_no": 1,
"page_no": 2, "layer": "entity", "statement": "..." },
{ "no": 2, "kind": "computed", "ground": "exact",
"expression": "40.470,00 + 2.100,00 = 42.570,00",
"inputs": ["40.470,00", "2.100,00"], "result": "42.570,00",
"terms": 2, "recomputed": "42570.00", "arithmetic_ok": true,
"inputs_grounded": true, "source_nos": [1, 2],
"engine": "deterministic" }
]
}
Adim turleri:
observed— belgeden okunmus deger.ground, degerin yuzeyinin belgede nasil dogrulandigidir:exact(birebir),tolerant,relocated(baska yerde bulundu) ya daunverified.computed— cevabin acikca gosterdigi hesap. Modelin aritmetigine guvenilmez: islem Python'da yeniden yapilir. Zincir cok terimli olabilir (a + b + c = toplam) ve soldan saga uygulanir. Tutmazsa adimground: "refuted"damgalanir verecomputedalani dogru degeri tasir. Model islemi gostermeden yalnizca sonucu yazarsacomputedadim olusmaz — seffaflik sarttir.rule— kural motorunun deterministik degerlendirmesi (engine: "deterministic").
verdict zincirin en zayif halkasindan turer, ortalamadan degil:
verified (her adim kaynagina oturuyor), partial (zincirde delik var)
ya da broken (bir hesap denetimde curudu). holes, cevapta gecen ama
belgede bulunamayan sayisal yuzeylerdir — gizlenmez.
proof additive ve nullable'dir: zincir kurulamazsa (atif da hesap da
yoksa) null doner ve gormezden gelinmesi guvenlidir.
Cross-check: belgeler arasi celiski denetimi
POST /v1/cross-check, islenmis 2+ belgenin (ust sinir YOK — belge
sayisi artinca her belge ortak butce icinde en onemli iddialariyla temsil
edilir) dogrulanmis mantik iddialarini birbiriyle karsilastirir ve belgeler-arasi bulgular doner —
celiskiler ("belge A X diyor, belge B degilini kanitliyor") ve destek
ciftleri (bir belgedeki yukumluluk, digerindeki yerine-getirme kaniti).
Belge (ve iddia) sayisina bagli olarak bir cross-check bir dakikadan az
surebilecegi gibi birkac dakika de surebilir; bu yuzden islem arka
plan isi olarak calisir: POST sadece isi kuyruga alir ve hemen doner,
gercek sonucu ardindan bir GET ile alirsiniz.
1. Isi baslat — POST /v1/cross-check
{ "document_ids": ["d_...", "d_..."], "lang": null }
Opsiyonel lang alani (ISO 639-1 kodu), tam olarak /v1/ask ile ayni
oncelik zincirini izler (istek lang > tenant'in Console → Modeller
ayari > tr, bkz. yukarida Cikti dili) ve yalniz her bulgunun
explanation alanini (modelin urettigi anlati) kapsar — bulgudaki
statement/quote/page_no alanlari her zaman cikarim aninda
belgeden alinan orijinal degerlerdir, cross-check bunlari yeniden
uretmez, dolayisiyla lang'dan etkilenmez.
Dogrulama hatalari bu cagrida hemen doner (asagida Hatalar). Aksi
halde yanit 202 Accepted'tir:
{
"id": "xc_...",
"status": "queued",
"documents": [{ "document_id": "d_...", "label": "..." }]
}
2. Sonucu yokla — GET /v1/cross-check/{id}
status, queued → running → completed (ya da failed) sirasiyla
ilerler. Bu uc noktayi (or. birkac saniyede bir) queued/running
durumundan cikana dek yoklayin — GET cagrilari asla
ucretlendirilmez. Islem surerken yanit yalniz id, status ve
documents tasir:
{
"id": "xc_...",
"status": "running",
"documents": [{ "document_id": "d_...", "label": "..." }]
}
status completed oldugunda yanit findings, stats, version ve
cost alanlarini da kazanir:
{
"id": "xc_...",
"status": "completed",
"documents": [{ "document_id": "d_...", "label": "..." }],
"version": "xchk-v4",
"findings": [
{
"kind": "contradiction",
"explanation": "…",
"a": { "document_id": "d_...", "node_id": "g2-c2", "statement": "…", "quote": "…", "page_no": 4, "span": {"start": 120, "end": 180} },
"b": { "document_id": "d_...", "node_id": "g7-r1", "statement": "…", "quote": "…", "page_no": 27, "span": {"start": 40, "end": 130} }
}
]
}
status failed ise yanit bunun yerine ne oldugunu aciklayan bir
error objesi ({"code", "message"}) kazanir.
Mekanizma, mantik katmaninin halusinasyon kalkanini miras alir:
karsilastirilan iddialar zaten cikarim aninda belge metnine karsi
dogrulanmistir (her biri sayfa numarasi + birebir alinti tasir) ve
modelin onerdigi her bulgu deterministik olarak denetlenir — yalnizca
bilinen iddia id'lerine isaret edebilir, iki taraf FARKLI belgelerden
olmak zorundadir ve yanittaki statement/alinti/sayfa modelin ekosundan
degil sunucu kayitlarindan doldurulur. Bos findings gecerli bir
cevaptir; model emin olmadigi cifti yazmamakla yukumludur.
Kapsama sistematiktir, modelin dikkatiyle sinirli degildir: aday ciftler
once deterministik uretilir — her iddia (Docsfra'nin kendi altyapisinda)
embed edilip DIGER belgelerin en benzer iddialariyla eslestirilir, ayrica
belirgin ortak token (referans no, tutar, tarih) tasiyan her cift aday
olur — ve her aday model tarafindan TEK TEK yargilanir (celiski / destek /
yok). Ayri bir serbest-tarama gecisi, benzerligin yakalayamayacagi
kural-vs-ihlal ciftlerini bulur (or. "tum belgeler Ingilizce olmali"
kurali vs Almanca bir cumle). Belgelerin temsilinde bir varlik grafigi
varsa, ucuncu bir aday kanali belgeler arasi ayni-turden varliklari
(kanonik ad/eslenik ortusmesiyle) eslestirir ve bu varliklari anan
iddialari ciftler — eslesen varliklar farkli deger tasiyorsa oncelik
verilir, bu en guclu dogal-celiski sinyalidir. Tum kanallar cift-anahtariyla
birlesir; sonuclar cagridan cagriya kararlidir ve deterministik sirayla
doner (once celiskiler). Tamamlanmis yanittaki stats objesi kac iddia ve
kac aday ciftin incelendigini raporlar, entity_candidates (varlik
kanaliyla bulunan ciftler) dahil.
Hatalar
| HTTP | code | Aciklama |
|---|---|---|
| 400 | invalid_request | 2'den az document_ids, ya da gecersiz opak id — POST uzerinde hemen doner |
| 402 | insufficient_credit | Bakiye, sorgu ucreti icin yetersiz — POST uzerinde hemen doner |
| 404 | document_not_found | Id'lerden biri tenant'iniza ait degil — POST uzerinde hemen doner |
| 422 | reasoning_not_available | Belgelerden biri mantik katmanini henuz tamamlamamis — POST uzerinde hemen doner |
Is basladiktan sonra olusan bir hata POST uzerinde HTTP hatasi
uretmez — sonraki bir GET'te status: "failed" ve bir error
objesi olarak yuzeye cikar.
Ucretlendirme
Cagri 1 ask sorgusu olarak ucretlendirilir (ayni oran, ayni
throttle), POST isi olusturdugunda BIR KEZ alinir — GET ile yoklama
her zaman ucretsizdir ve status: "failed" ile biten bir is
ucretlendirilmez. Ayni yetenek Console'da Capraz Denetim sayfasinda
ve MCP'de cross_check tool'unda da vardir (tool kendi icinde yoklar ve
bitmis bulgulari dogrudan doner).