Beş yıl önce faturalardan yapılandırılmış veri çıkarmak, bir derin öğrenme işlem hattı anlamına geliyordu: bir OCR aşaması, binlerce elle etiketlenmiş belge üzerinde ince ayar yapılmış yerleşim farkındalıklı bir model (LayoutLM, Donut) ve bir tedarikçi şablonunu her değiştirdiğinde ortaya çıkan bakım yükü. 2026'da tüm işlem hattı tek bir görsel-LLM API çağrısına dönüşüyor: görüntü girer, şema doğrulamalı JSON çıkar — sıfır eğitim verisi, sıfır barındırılan model ve yeni yerleşimler sıfır örnekle işlenir. Kunavo'nun bu rehberi — bu yaklaşımın çalıştığı görsel modellere OpenAI uyumlu, bağımsız bir ağ geçidi — kendi yayımlanmış ücretlerimiz üzerinden ölçülen fatura başına maliyeti, eksiksiz çalışan yaklaşımı ve doğruluğu üretim düzeyinde tutma yöntemini gösterir.
Fatura çıkarma yaklaşımları karşılaştırması: kurallar, makine öğrenimi, derin öğrenme, LLM
Faturadan yapılandırılmış veri elde etmek için dört teknik nesli kullanıldı. Bunları yan yana koymaya değer; çünkü yirmi yıl boyunca aralarındaki seçimi belirleyen ödünleşim — etiketli verilerle satın alınan doğruluk — artık geçerli değil.
| Yaklaşım | Nasıl çalışır | Kurulum maliyeti | Yeni bir tedarikçi yerleşimini işler mi |
|---|---|---|---|
| Şablonlar / kurallar (1990'lar–) | OCR, ardından tedarikçi başına koordinat bölgeleri ve regex'ler (“toplam, ‘TOTAL’ ifadesinin hemen sağındaki sayıdır”) | Tedarikçi başına saatler, sonsuza kadar | Hayır — yeni bir şablon gerekir |
| Klasik makine öğrenimi (2010'lar) | OCR, ardından her token'ı etiketleyen bir CRF veya SVM'ye aktarılan elle tasarlanmış özellikler (konum, yazı tipi boyutu, komşu kelimeler) | Özellik mühendisliği + birkaç bin etiket | Kısmen — görülmemiş yerleşimlerde performans düşer |
| Derin öğrenme (2020–) | Metni, konumu ve pikselleri birlikte okumak üzere ince ayarlanmış yerleşim farkındalıklı transformer'lar (LayoutLM, Donut, DocTR) | 3.000–50.000 etiketli fatura + GPU üzerinde model sunumu | Çoğu zaman hayır — genellikle yeniden etiketleme ve yeniden eğitim gerekir |
| Görsel LLM (2024–) | Tek API çağrısı: fatura görüntüsü ve bir JSON şeması; yapılandırılmış çıktı bu şemayla sınırlandırılır | Yok — bir şema ve istem; fatura başına 0,00248–0,00497 ABD doları | Evet, sıfır örnekle |
İlk üç yöntemin ortak bir özelliği vardır: doğruluk etiketli verilerle satın alınır. Her tedarikçi şablonu, her CRF özelliği, her LayoutLM ince ayarı bir açıklama projesidir. Görsel LLM bu maliyeti ön eğitim sırasında zaten üstlendiği için yeni bir yerleşimin marjinal maliyeti sıfırdır. Tüm değişim bundan ibarettir — eski yöntemlerin çalışmayı bırakması değil, bütçelerini harcadıkları şeyin ücretsiz hâle gelmesi.
İnce ayarlı derin öğrenme ve görsel LLM, ayrıntılı karşılaştırma
| İnce ayarlı yerleşim modeli (2021) | Görsel LLM (2026) | |
|---|---|---|
| Eğitim verileri | 3.000–50.000 etiketli fatura | Yok (sıfır örnekle) — birkaç örnek uç durumlara yardımcı olur |
| Yeni tedarikçi yerleşimi | Genellikle yeniden etiketleme + yeniden eğitim gerekir | Sıfır örnekle işlenir |
| Altyapı | GPU sunumu + OCR aşaması | Tek HTTPS çağrısı |
| Çıktı biçimi | Token etiketleri → özel kod çözme | Şemayla kısıtlanmış JSON |
| Fatura başına maliyet | Mühendislik zamanı baskındır | $0,00248–$0,00497 |
İnce ayarlı bir çıkarıcı tek ve sabit, yüksek hacimli bir yerleşimde hâlâ kazanabilir; ancak gerçek dünyadaki faturaların uzun kuyruğu — farklı tedarikçiler, diller, tarama kalitesi — için sıfır örnekli görsel LLM pratikte daha doğrudur ve sahip olma maliyeti çok daha düşüktür. Bu iş yükü sınıfına yönelik daha fazla yaklaşım veri çıkarma kullanım alanında yer alır.
Eksiksiz yaklaşım: görüntü → şema doğrulamalı JSON
Aşağıdaki her şey Kunavo'nun OpenAI uyumlu uç noktasına karşı çalışır — base_url değerini https://api.kunavo.com/v1 olarak ayarlayın; aynı kod, tek bir dizeyi değiştirerek Claude veya GPT'ye istek gönderebilir:
from openai import OpenAI
import base64, json
client = OpenAI(
base_url="https://api.kunavo.com/v1",
api_key="sk-kn-...",
)
SCHEMA = {
"name": "invoice",
"schema": {
"type": "object",
"properties": {
"vendor_name": {"type": "string"},
"vendor_tax_id": {"type": ["string", "null"]},
"invoice_number": {"type": "string"},
"invoice_date": {"type": "string", "description": "ISO 8601"},
"due_date": {"type": ["string", "null"]},
"currency": {"type": "string", "description": "ISO 4217"},
"line_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {"type": "string"},
"quantity": {"type": "number"},
"unit_price": {"type": "number"},
"amount": {"type": "number"},
},
"required": ["description", "amount"],
},
},
"subtotal": {"type": ["number", "null"]},
"tax": {"type": ["number", "null"]},
"total": {"type": "number"},
},
"required": ["vendor_name", "invoice_number", "invoice_date",
"currency", "line_items", "total"],
},
}
def extract(path: str) -> dict:
image_b64 = base64.b64encode(open(path, "rb").read()).decode()
resp = client.chat.completions.create(
model="claude-haiku-4-5", # the cheapest capable model for clean invoices
response_format={"type": "json_schema", "json_schema": SCHEMA},
messages=[
{"role": "system", "content":
"Extract the invoice into the schema. Copy values exactly as "
"printed; use null when a field is absent. Never invent data."},
{"role": "user", "content": [
{"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{image_b64}"}},
]},
],
)
return json.loads(resp.choices[0].message.content)
inv = extract("invoice_0231.png")
# Cheap arithmetic guardrail: reject when the line items don't add up.
delta = abs(sum(li["amount"] for li in inv["line_items"])
+ (inv.get("tax") or 0) - inv["total"])
if delta > 0.02:
raise ValueError(f"line items disagree with total by {delta:.2f}")
print(inv["vendor_name"], inv["total"], inv["currency"])İşin çoğunu üç ayrıntı yapar: response_format alanında bulunan JSON şeması (Claude'da model başka hiçbir şey üretemez — aşağıda bağlantısı verilen referanstaki GPT notuna bakın), sistem istemi kuralı “değerleri tam olarak kopyala; yoksa null; asla uydurma” (uydurulmuş vergi kimliklerini ortadan kaldırır) ve aritmetik güvenlik katmanı — satır kalemleri + vergi toplamla eşleşmelidir; aksi hâlde belge daha güçlü bir modele veya bir insana gönderilir. Her model ailesinde response_format alanıyla neyin zorunlu kılındığını görmek için chat completions referansına bakın.
Aynı şema, tür belirtilmiş bir Pydantic modeli olarak
Ham bir JSON şeması sözlüğü tek bir uç nokta için uygundur, ancak on uç nokta için zahmetlidir. Üretimde çoğu ekip şemayı bir kez Pydantic modeli olarak tanımlar ve hem kısıtlamayı hem de ayrıştırılmış nesneyi bundan türetir; böylece çıkarıcı ile kod tabanının geri kalanı biçim konusunda hiçbir zaman anlaşmazlığa düşmez:
from pydantic import BaseModel, Field
from typing import Literal
from openai import OpenAI
client = OpenAI(base_url="https://api.kunavo.com/v1", api_key=KEY)
class LineItem(BaseModel):
description: str
quantity: float | None = None
unit_price: float | None = None
amount: float
class Invoice(BaseModel):
vendor_name: str
vendor_tax_id: str | None = None
invoice_number: str
invoice_date: str = Field(description="ISO 8601")
currency: str = Field(description="ISO 4217")
line_items: list[LineItem]
tax: float | None = None
total: float
# A confidence field the model fills in itself is a cheap, surprisingly
# reliable router: low self-reported confidence correlates well with the
# documents a human should see.
confidence: Literal["high", "medium", "low"]
resp = client.chat.completions.create(
model="claude-haiku-4-5",
response_format={
"type": "json_schema",
"json_schema": {"name": "invoice", "schema": Invoice.model_json_schema()},
},
messages=[...],
)
invoice = Invoice.model_validate_json(resp.choices[0].message.content)Burada iki şeyi kopyalamaya değer. float | None yerine float olarak tür belirtilen alanlar, modele “yok” deme olanağı sağlar — bu olmadan eksik bir vergi satırı, sıfır uydurmaya güçlü bir eğilim oluşturur. Ayrıca modelin kendi bildirdiği confidence alanı üç çıktı token'ına mal olur ve şaşırtıcı derecede iyi yönlendirme yapar; kalibre edilmiş değildir, ancak “düşük” değeri bir insanın bakması gerektiğine dair güvenilir bir sinyaldir.
İki katmanlı yönlendirme: üretimde gerçekten ne çalışır
Her belgede tek bir model kullanmak yanlış biçimdir. Temiz, basılı faturalar — ezici çoğunluk — mevcut en ucuz görsel model tarafından işlenir; zor kuyruk (el yazısı, kötü taramalar, alışılmadık yerleşimler), daha güçlü bir modelin ücretini hak ettiği yerdir. Tahminle değil, doğrulama başarısızlığı üzerine yükseltin:
CHEAP, STRONG = "claude-haiku-4-5", "claude-sonnet-5"
def valid(inv: dict) -> bool:
"""Arithmetic is the guardrail no confidence score replaces."""
items = sum(li["amount"] for li in inv["line_items"])
return abs(items + (inv.get("tax") or 0) - inv["total"]) <= 0.02
def extract_routed(path: str) -> tuple[dict, str]:
inv = extract(path, model=CHEAP)
if valid(inv) and inv.get("confidence") != "low":
return inv, CHEAP
# Escalate: same prompt, same schema, stronger model. Only the failures
# pay the higher rate, which is what keeps the blended cost near the
# cheap tier's.
inv = extract(path, model=STRONG)
if not valid(inv):
raise NeedsHumanReview(path, inv)
return inv, STRONG
# Blended cost at a 90/10 split, per 10,000 invoices:
# 9,000 x $0.00248 + 1,000 x $0.00497
# = $27.29Gerçek işi aritmetik kontrol yapar: modelin kendisi hakkındaki görüşünden bağımsız tek sinyal budur. Satır kalemleri belirtilen toplama eşit olan bir belge, önemli bir açıdan neredeyse hiçbir zaman yanlış değildir; başarısız olan belge, güven alanı ne iddia ederse etsin, daha güçlü modeli veya bir insanı hak eder.
Modele göre fatura başına maliyet
Tek sayfalık bir fatura ≈ 1.800 girdi token'ı (görüntü olarak gönderilir) + ~350 JSON çıktı token'ı:
| Model | Fatura başına | 10.000 fatura başına | Şunun için kullanın |
|---|---|---|---|
claude-haiku-4-5 | $0,00248 | $24,80 | Varsayılan: temiz, basılı faturalar ve en ucuz toplu çalıştırmalar |
claude-sonnet-5 | $0,00497 | $49,70 | Yükseltme katmanı: taramalar, el yazısı, başarısızlıklar |
Ücretler fiyatlandırma sayfasından günceldir (sağlayıcıların liste fiyatlarından yaklaşık 30% daha düşük) ve başarısız istekler faturalandırılmaz. İki katmanlı yönlendirmeyle — her şey Haiku üzerinden, aritmetik kontrol başarısızlıkları Sonnet'e yükseltilir — ayda 10.000 fatura genellikle 27,29 ABD dolarının altında kalır.
Doğruluk: üretime ulaşmanızı sağlayan kontrol listesi
- Önce şema. Gerçekten zorunlu alanları
requiredolarak işaretleyin, diğer her yerdenulldeğerine izin verin — bir değeri zorlamak halüsinasyonu zorlar. - OCR metnini değil, görüntüyü gönderin. Yerleşim anlam taşır (sütunlar, toplam kutuları); görsel modeller bunu doğrudan okur. Yalnızca temiz bir metin katmanı çıkarabildiğiniz, dijital olarak oluşturulmuş PDF'lerde metne geri dönün.
- Aritmetiği kodla doğrulayın. Satır kalemleri + vergi = toplam kontrolü, çoğu çıkarma hatasını ücretsiz yakalar.
- Körü körüne yeniden denemek yerine yükseltin. Başarısızlıkları, doğrulama hatasını isteme ekleyerek Sonnet'e gönderin; devam eden başarısızlıkları insan kuyruğuna aktarın.
- Gerçek uç durumlar için few-shot kullanın. En kötü yerleşimlerinizden (alacak dekontları, çoklu para birimi) sistem istemine eklenen iki veya üç örnek, her türlü talimat ayarından daha iyi sonuç verir.
Faturaların ötesinde
Aynı şemayla kısıtlanmış yaklaşım makbuzları, satın alma siparişlerini, teslimat notlarını, gümrük formlarını ve banka ekstrelerini kapsar — şemayı değiştirin, güvenlik katmanlarını koruyun. RAG'e yakın yaklaşımlar için daha geniş yapılandırılmış veri çıkarma kullanım alanına, hacim büyüdüğünde yönlendirme stratejileri için maliyet optimizasyonu rehberine göz atın. Tek bir Kunavo anahtarı burada kullanılan her model katmanını kapsar — ücretsiz kaydolun ve parçacığı olduğu gibi çalıştırmak için bir anahtar oluşturun.
Sık sorulan sorular
Faturalardan veri çıkarmak için derin öğrenme modeline ihtiyacım var mı?
Artık yok. Klasik işlem hattının — OCR, ardından binlerce etiketli fatura üzerinde ince ayar yapılmış LayoutLM gibi bir yerleşim modeli — yerini çoğu ekip için tek bir görsel LLM çağrısı aldı: fatura görüntüsünü ve bir JSON şemasını gönderin, doğrulanmış yapılandırılmış veriyi geri alın. Etiketlenecek eğitim kümesi, barındırılacak model yoktur; ince ayarlı modelleri bozan yerleşim değişiklikleri de sıfır örnekle ele alınır.
Makine öğrenimiyle fatura çıkarma, LLM kullanımıyla karşılaştırıldığında nasıldır?
Klasik makine öğrenimi çıkarıcıları (OCR çıktısı üzerinde CRF veya SVM ve elle tasarlanmış konum ve yazı tipi özellikleri) ile bunların derin öğrenme halefleri (LayoutLM, Donut), her dağıtım için binlerce açıklamalı faturanın etiketlenmesini ve yerleşimler değiştiğinde yeniden etiketlenmesini gerektirerek doğruluk satın alır. Görsel LLM bu maliyeti ön eğitim sırasında üstlendiği için, daha önce görmediği bir tedarikçi yerleşimini sıfır örnekle okur ve tek bir API çağrısından şemayla kısıtlanmış JSON döndürür. Çıkarım maliyetinin baskın olduğu, tek ve sabit, çok yüksek hacimli bir yerleşimde makine öğrenimi hâlâ kazanır; gerçek faturaların uzun kuyruğu için LLM pratikte hem daha doğrudur hem de sahip olma maliyeti çok daha düşüktür.
Fatura çıkarma için hâlâ LayoutLM veya Donut kullanabilir miyim?
Evet; tek bir sabit yerleşimde milyonlarca belge işlediğiniz ve etiketleme ile GPU sunum maliyetlerini yayabildiğiniz durumlarda hâlâ makuldürler. Değişen şey varsayılandır: yeni bir proje için görsel LLM, eğitim kümesi olmadan bir öğleden sonra içinde üretim doğruluğuna ulaşır ve belge başına maliyet, ince ayar ekonomisinin nadiren kendini amorti edeceği kadar küçüktür. Yaygın bir ara yol, önce LLM'yi çalıştırmak ve yalnızca daha sonra, LLM'nin kabul edilmiş kendi çıktılarını etiketli külliyat olarak kullanarak ince ayar yapmaktır.
Fatura çıkarmanın belge başına maliyeti ne kadar?
Tek sayfalık bir fatura, görüntü olarak kabaca 1.800 girdi token'ı ve yaklaşık 350 JSON çıktı token'ı içerir. Kunavo'da bu, claude-haiku-4-5 ile fatura başına yaklaşık 0,00248 ABD doları ve claude-sonnet-5 ile 0,00497 ABD dolarıdır — yani Sonnet kalitesinde bile bin fatura birkaç dolara mal olur. Başarısız istekler faturalandırılmaz.
Fatura verisi çıkarmak için hangi modeli kullanmalıyım?
claude-haiku-4-5 ile başlayın: temiz, basılı faturaları en düşük fiyata neredeyse kusursuz işler. Yalnızca başarısız olanları — el yazısı, düşük çözünürlüklü taramalar, alışılmadık yerleşimler veya aritmetik kontrolünüzden geçmeyen belgeler — claude-sonnet-5'e yönlendirin. Bu iki katmanlı yönlendirme genellikle hacmin %90'ından fazlasını ucuz katmanda tutar.
Çıktının geçerli JSON olduğunu nasıl garanti edebilirim?
Yapılandırılmış çıktıları kullanın: JSON şeması içeren response_format parametresini gönderin; Claude modeli tam olarak bu biçimi üretmekle kısıtlanır — regex ile sonradan işleme gerek kalmaz. Üzerine ucuz bir uygulama düzeyi güvenlik katmanı ekleyin: satır kalemleri artı verginin toplama eşit olduğunu kontrol edin ve uyuşmazlıkları daha güçlü modele veya insan kuyruğuna gönderin.
Yalnızca görüntülerden değil, PDF faturalardan da veri çıkarabilir miyim?
Evet — her PDF sayfasını PNG'ye dönüştürün (örneğin pdf2image ile) ve yukarıdaki gibi gönderin. Dijital olarak oluşturulmuş PDF'lerde metin katmanını da çıkarıp düz metin olarak gönderebilirsiniz; bu daha ucuzdur. Taramalar için görüntü yolunu koruyun.
LLM ile fatura çıkarma ne kadar doğru?
Temiz, basılı faturalarda, aritmetik güvenlik katmanına sahip şemayla kısıtlanmış görsel çıkarma, alan düzeyinde rutin olarak %98'in üzerinde doğruluğa ulaşır — ayrıca ince ayarlı bir modelin aksine doğruluk, hiç görmediği yerleşimlerde de korunur. Kendi belgeleriniz üzerinde ölçün: etiketli 100 fatura sağlam bir değerlendirme kümesi oluşturur.
Fatura verilerim eğitim için kullanılıyor mu?
Hayır — Kunavo üzerinden gönderilen istekler model sağlayıcılarına API kullanım koşulları kapsamında (tüketici uygulaması koşulları kapsamında değil) iletilir ve modelleri eğitmek için kullanılmaz. Saklama ayrıntıları için faturalandırma ve veri belgelerine bakın.