Docsfra
API Dokumantasyonu
v1

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
DonerChunk sonuc listesiSentezlenmis cevap metni + kaynak listesi
Mod secimimode: hybrid | semanticHer zaman hybrid
MaliyetDusuk (yalniz retrieval)Daha yuksek (retrieval + LLM)
Ne zamanKendi RAG akisinizi kuracaksanizHazir, sentezlenmis cevap yeterliyse

Nasil calisir (retrieve -> generate)

  1. Retrievequery, /v1/search ile ayni hibrit (vektor + kelime, RRF) motora gonderilir; top_k (varsayilan 5, maksimum 20) chunk getirilir. document_id verilirse arama tek bir dokumana, bunun yerine batch_id verilirse o batch'teki tum dokumanlara scope edilir (ikisi birlikte verilemez — asagidaki Istek bolumune bkz.).
  2. 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.
  3. Generate — chunk bulunduysa her biri [Kaynak: belge=..., sayfa=..., bolum=...] basligiyla bir baglam bloguna donusturulur (bloklar --- ile ayrilir) ve motor-bagimsiz, OpenAI-uyumlu bir /chat/completions uc noktasina (dusuk sicaklik, temperature=0.1) gonderilir. Gecici hatalarda (5xx/timeout) exponential backoff ile tekrar denenir; kalici hatalarda (4xx) veya sunucu tarafinda RAG yapilandirilmamissa RagError firlatilir (→ 503).
  4. Cevap — LLM'in urettigi metin answer alaninda doner. Pasajlar numaralidir ([S1], [S2], ...) ve model her iddiayi kaynak numarasiyla isaretler; citations[] yalniz cevapta gercekten atif yapilan kaynaklari icerir (her biri source_no tasir).

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
}
AlanZorunluAciklama
queryevetSorulan soru (bos olamaz)
top_khayirBaglam icin cekilecek chunk sayisi — varsayilan 5, maksimum 20
document_idhayirBelirtilirse cevap tek bir dokumana scope edilir
batch_idhayirBelirtilirse cevap bir batch'teki (b_...) tum dokumanlara scope edilir. document_id ile birlikte verilemez — 400 invalid_request
langhayirCevabin 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

HTTPcodeAciklama
400invalid_requestquery eksik/gecersiz, document_id/batch_id gecersiz opak id, ya da document_id ve batch_id birlikte verildi
401unauthorizedEksik, gecersiz veya revoke edilmis key
402insufficient_creditBakiye, sorgu basi ucret icin yetersiz — /ask, /search'ten daha yuksek maliyetlidir (embed + LLM)
404not_foundbatch_id tenant'iniza ait degil
429rate_limitedtenant_ask throttle scope'u (60/dk) asildi
503rag_unavailableRAG 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 = deger bicimli 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 birebir quote).
  • 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 da unverified.
  • 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 adim ground: "refuted" damgalanir ve recomputed alani dogru degeri tasir. Model islemi gostermeden yalnizca sonucu yazarsa computed adim 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, queuedrunningcompleted (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

HTTPcodeAciklama
400invalid_request2'den az document_ids, ya da gecersiz opak id — POST uzerinde hemen doner
402insufficient_creditBakiye, sorgu ucreti icin yetersiz — POST uzerinde hemen doner
404document_not_foundId'lerden biri tenant'iniza ait degil — POST uzerinde hemen doner
422reasoning_not_availableBelgelerden 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).