Ana içeriğe geç

Docling: Belge Zekâsı Uygulaması Oluşturmak için Adım Adım Rehber

Docling ile dağınık PDF’leri yapılandırılmış, aranabilir verilere dönüştürün. Getirme ile güçlendirilmiş akıl yürütme için LangGraph’ı ve etkileşimli bir ön yüz için Streamlit’i entegre edin. Belgeleriniz için kişisel ChatGPT’niz gibi hissettiren yerel bir Belge Zekâsı Uygulamasını oluşturun, test edin ve dağıtın.
· 15 dk. oku

Yapay Zeka ile Keşfedin

pypdf veya PDFMiner gibi geleneksel PDF çıkarma araçları size ham metin verir ancak belge yapısını kaybeder. Tablolar karmakarışık metne dönüşür, başlıklar gövde metniyle karışır ve görseller kaybolur. RAG sistemleri için bu dağınık veri, zayıf getirme ve güvenilmez yanıtlar demektir. Docling, IBM Research tarafından geliştirilen açık kaynaklı bir araç setidir; belge yerleşimlerini anlamak için bilgisayarlı görü modelleri kullanır ve tabloları, görselleri, başlıkları ve yapıyı korur. Geleneksel OCR tabanlı yöntemlerden 30 kata kadar daha hızlı belge işler ve yerel makinenizde çalışır.

Bu eğitimde Docling kullanarak bir Belge Zekâsı Asistanı—dosya yüklemenizi, yapısını görselleştirmenizi ve RAG destekli bir sohbet botu ile sorular sormanızı sağlayan bir Streamlit web uygulaması—oluşturacağız. Docling ile çok formatlı belgeleri işlemeyi, tabloları ve görselleri çıkarmayı ve görüntülemeyi, ChromaDB ile bir vektör deposu kurmayı ve LangGraph ile bir sohbet ajanı oluşturmayı öğreneceksiniz. Sonunda, karmaşık belgeleri yapılandırılmış verilere dönüştüren ve akıllı soru-cevap imkânı sağlayan çalışan bir uygulamaya sahip olacaksınız.

Uygulama ön izlemesi:

Docling Streamlit uygulamasında bir kullanıcının belgeyle ilgili sorular sorduğu ve yapılandırılmış yanıtlar aldığı sohbet arayüzü

Belge yapısı görselleştirme:

Docling'in belge yapısını görselleştirdiği, örnek bir PDF'de algılanan tabloları, görselleri ve başlıkları gösteren ekran görüntüsü

Ön Koşullar

Bu eğitime başlamadan önce şunlara sahip olmalısınız:

Teknik beceriler: Python sınıfları, dekoratörler, tür ipuçları ve bağlam yöneticileriyle çalışmaya rahat olmak. Tüm süreçte async işlemler ve fabrika desenleri kullanacağız. Büyük dil modellerinin istemler, belirteçler ve gömlemelerle nasıl çalıştığını anlamak gereklidir. Getirme ile güçlendirilmiş üretim sistemleri ve vektör veritabanlarına aşinalık faydalıdır ancak zorunlu değildir—temel kavramları inşa ederken açıklayacağız.

Geliştirme kurulumu: Paket yönetimi için pip ile Python 3.10 veya üzeri. VS Code gibi bir kod düzenleyici önerilir. Şuradan bir OpenAI API anahtarına ihtiyacınız olacak: platform.openai.com—işleme maliyeti belge başına yaklaşık $0,10–0,20’dir.

Zaman planı: Açıklamaları okumak, kod yazmak ve uygulamayı test etmek dahil, eğitimi tamamlamak için 60–90 dakika ayırın. Bu öğretici, orta düzey Python becerileri varsayar.

Docling’i Anlamak: Özellikler ve Yetenekler

Çoğu belge işleme aracı PDF’leri görsel dosyaları ya da metin akışları gibi ele alır. Ya her sayfada OCR çalıştırırlar ya da ne okuduklarını anlamadan düz metin çıkarırlar. Docling farklı bir yaklaşım benimser. Bu, IBM Research’ten açık kaynaklı bir araç takımıdır ve belgelerin yapısını bir insan gibi anlamak için bilgisayarlı görü modelleri kullanır.

Bir belgeyi Docling’e verdiğinizde, iki yapay zekâ modeli onu analiz eder:

  • Yerleşim analizi: DocLayNet üzerinde eğitilmiş modeller, sayfa yerleşimlerini analiz ederek başlık, gövde metni, tablo ve görsel gibi farklı öğeleri tanımlar
  • Tablo yapısı: TableFormer tabloları ele alır ve bunları yapılandırılmış veriye dönüştürür

Bu modeller bir belgenin yalnızca bir metin yığını olmadığını anlar. Hiyerarşi, ilişkiler ve anlam vardır.

Bu yapısal anlayış RAG sistemleri için önemlidir. Getirme ile güçlendirilmiş üretim uygulamaları geliştirirken, belge işlemenin kalitesi doğrudan getirme doğruluğunu etkiler. PDF çıkarımınız bir finansal tabloyu karmakarışık metne çevirirse, vektör aramanız işe yaramaz sonuçlar döndürür. Docling yapıyı korur; böylece belgeleri parçalayıp gömdüğünüzde temiz ve düzenli verilerle çalışırsınız.

Docling, kutudan çıktığı haliyle birden fazla belge formatını destekler:

  • PDF belgeler
  • Word belgeleri (DOCX)
  • PowerPoint sunumları (PPTX)
  • Excel çalışma kitapları (XLSX)
  • HTML dosyaları
  • Görseller

Ayrıca EasyOCR, Tesseract veya RapidOCR gibi motorlarla taranmış belgeler için OCR’ı etkinleştirebilirsiniz. Araç takımı; Markdown (LLM’ler için harika), JSON (yapılandırılmış veri hatları için) ve DocTags (matematik denklemleri ve kod blokları gibi karmaşık öğeleri yakalayan bir format) dahil çeşitli biçimlere dışa aktarım yapar.

Biçim esnekliğinin ötesinde, Docling performans avantajları sunar. Geleneksel OCR tabanlı belge işleme yavaştır; çünkü her sayfayı karakter tanıma gerektiren bir görsel gibi ele alır. Docling, dijital belgelerde bu adımı atlayarak çok daha hızlı işlem sunar. Sıradan donanımda yerel olarak çalışır; böylece API maliyeti ödemez veya hassas belgeleri üçüncü taraf hizmetlere göndermezsiniz. İşleme hızı, belge karmaşıklığına, sayfa sayısına ve donanım özelliklerine bağlı olarak değişir; modern donanımda tipik performans sayfa başına bir saniyeden birkaç saniyeye kadar değişir.

IBM, Docling’in yeteneklerini geliştirmeye devam ediyor. Şunu yayınladılar: Granite-Docling, karmaşık yerleşimlerde başarılı ve deneysel çok dilli destek sunan (birincil dil İngilizce, Arapça, Çince ve Japonca için erken aşama destek) 258 milyon parametreli bir görsel-dil modelidir. Araç takımı artık yapılandırılabilir çözünürlükle görsel çıkarımını da destekliyor; bunu uygulamamızda PDF’lerden gerçek görselleri metin içerikleriyle birlikte göstermek için kullanacağız.

Bizim kullanım senaryomuz için Docling mantıklı; çünkü sadece ham metne değil, yapılandırılmış veriye ihtiyacımız var. Yalnızca temel metin çıkarımı gerekiyorsa pypdf gibi daha basit araçlar yeterli olabilir. Ancak analiz ve sohbet için belgeleri işleyen bir yapay zekâ uygulaması inşa ettiğimizden, Docling’in yapı farkında işleme yaklaşımı daha iyi bir seçimdir. Özellikle tabloların ve yerleşimin önemli olduğu teknik belgeler, araştırma makaleleri veya iş raporlarıyla çalışırken değerlidir.

Geliştirme Ortamınızı Kurma

Belge işlemciyi oluşturmaya başlamadan önce proje yapınızı kurmanız ve gerekli paketleri yüklemeniz gerekir. Bu bölümde ilk kurulum ele alınır: dizinlerin oluşturulması, bağımlılıkların yüklenmesi ve API anahtarlarınızın yapılandırılması.

Proje yapısını oluşturma

Projeye yeni bir dizin oluşturarak başlayın:

mkdir docling-demo
cd docling-demo

Bu dizin içinde, Python modülleriniz için bir src/ klasörü oluşturun:

mkdir src
touch src/__init__.py

__init__.py dosyası Python’a src/ klasörünün bir paket olduğunu söyler ve from src.document_processor import DocumentProcessor gibi içe aktarımlara imkân verir.

Proje yapınız:

docling-demo/
├── src/
│   └── __init__.py

Bağımlılıkları yükleme

requirements.txt dosyasını proje kökünüzde oluşturun:

docling>=2.55.0
langchain-docling>=0.1.0
langchain>=0.3.0
langchain-openai>=0.2.0
langgraph>=0.2.0
langchain-chroma>=0.1.0
streamlit>=1.28.0
streamlit-extras>=0.7.0
python-dotenv>=1.0.0
chromadb>=0.4.22
tiktoken>=0.5.0
pandas>=2.0.0
numpy<2

numpy<2 kısıtı, Docling’in bağımlılıkları (TensorFlow ve Transformers) NumPy 1.x gerektirdiği için vardır.

Paketleri yükleyin:

pip install -r requirements.txt

İlk kurulum birkaç dakika sürer; çünkü Docling önceden eğitilmiş AI modellerini (yaklaşık 500MB) indirir. Bu modeller yerleşim analizi ve tablo yapısı tanımadan sorumludur. Modeller yerelde önbelleğe alınır; böylece sonraki çalıştırmalar daha hızlıdır.

Ortam değişkenlerini yapılandırma

OpenAI API anahtarınızı saklamak için bir .env dosyası oluşturun:

OPENAI_API_KEY=your-openai-api-key-here

platform.openai.com adresinden API anahtarınızı alın. Gömlemeler ve sohbet ajanı için gereklidir.

.env.example şablonu oluşturun:

OPENAI_API_KEY=your-openai-api-key-here

Hassas verileri commit etmemek için bir .gitignore ekleyin:

# Environment variables
.env

# Python
__pycache__/
*.py[cod]
*.so
venv/
*.egg-info/

# Chroma
chroma_db/

Ana uygulama dosyasını oluşturma

Proje kökünüzde app.py oluşturun. Bu dosyayı eğitim boyunca kademeli olarak inşa edeceğiz. Şimdilik temel içe aktarımlar ve yapılandırmayı ekleyin:

import streamlit as st
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

# Page configuration
st.set_page_config(
    page_title="Document Intelligence Assistant",
    page_icon="📄",
    layout="wide"
)

st.title("Document Intelligence Assistant")
st.write("Application setup complete. We'll build the functionality next.")

Kurulumunuzu test edin:

streamlit run app.py

Streamlit, http://localhost:8501 adresinde bir tarayıcı penceresi açarak temel sayfanızı gösterir.

Nihai proje yapınız (sonraki bölümlerde yeni betikler eklemeden önce):

docling-demo/
├── .env
├── .env.example
├── .gitignore
├── requirements.txt
├── app.py
└── src/
   └── __init__.py

Ortam hazır olduğuna göre, Docling kullanarak yüklenen dosyalardan yapıyı çıkaracak belge işlemciyi inşa edebiliriz.

> Not: Aşağıdaki bölümler uygulama betiklerini parçalara ayırarak ele alacak. Bu nedenle, büyük resmi görmek ve kolayca takip etmek için bu projenin GitHub deposunu ayrı bir sekmede açmanızı öneririz. 

Çekirdek Belge İşlemciyi Oluşturma

📄 Tam betik: src/document_processor.py

Belge işlemci, Docling’in işini yaptığı yerdir. Bu bileşen, yüklenen dosyaları alır ve hem RAG hem de görselleştirme için kullanabileceğimiz yapılandırılmış verilere dönüştürür. Bu süreçten iki çıktı gerekir: vektör deposu için temiz markdown metni ve tablolar, görseller gibi tüm yapısal bilgileri koruyan orijinal Docling belge nesnesi.

Bunu, src/ dizininizde document_processor.py adlı yeni bir dosya oluşturarak inşa edelim. Docling’in işleme hattını yapılandıran ve dosya yüklemelerini yöneten bir DocumentProcessor sınıfı oluşturacağız.

Boru hattı seçeneklerini yapılandırma

Docling, boru hattı seçenekleri aracılığıyla belgeleri nasıl işleyeceğinizi kontrol etmenizi sağlar. PDF’ler için taranmış belgelerde OCR’ı açabilir, tablo yapısı tanımayı etkinleştirebilir ve görselleri çıkarabilirsiniz:

from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions
from langchain_core.documents import Document

class DocumentProcessor:
    def __init__(self):
        # Configure pipeline options for PDF processing
        pipeline_options = PdfPipelineOptions()
        pipeline_options.do_ocr = True
        pipeline_options.do_table_structure = True
        pipeline_options.generate_picture_images = True
        pipeline_options.images_scale = 2.0

PdfPipelineOptions nesnesi oluşturarak Docling’in PDF dosyalarını nasıl işleyeceğini yapılandırıyoruz. Her seçenek belirli bir işleme yeteneğini kontrol eder: do_ocr taranmış belgeler için optik karakter tanımayı etkinleştirir, do_table_structure tablo tespit ve ayrıştırmasını açar, generate_picture_images Docling’e gömülü görselleri PIL nesneleri olarak çıkarmasını söyler ve images_scale çıkarılan görsellerin çözünürlük çarpanını ayarlar.

# Initialize converter with PDF options
self.converter = DocumentConverter(
    format_options={InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)}
)

DocumentConverter Docling’in ana işleme motorudur. PDF boru hattı seçeneklerimizi bir PdfFormatOption nesnesine sararak başlatıyoruz; bu da bu ayarları özel olarak PDF giriş dosyalarıyla ilişkilendirir.

Her boru hattı seçeneğinin ne yaptığına bakalım. do_ocr bayrağı optik karakter tanımayı etkinleştirir. Gömülü metin katmanlarına sahip dijital PDF’leri işlerken Docling, zamanı azaltmak için OCR’ı otomatik olarak atlar. Taranmış belgeler veya metin içeren görseller için bu ayar, Docling’e metni çıkarmak üzere görsel modelleri çalıştırmasını söyler.

do_table_structure seçeneği tablo yapısı tanımayı etkinleştirir. Bu olmadan, tablolar biçimlendirme kaybolmuş düz metin olarak çıkarılır. Etkinleştirildiğinde Docling, satırları, sütunları, başlıkları ve hücre ilişkilerini belirlemek için TableFormer AI modelini kullanır. Bu yapılandırılmış temsil, tablo biçimini koruyarak tabloları daha sonra pandas DataFrame’leri olarak dışa aktarmanıza olanak tanır.

generate_picture_images değerini True yapmak görsel çıkarımını etkinleştirir. Varsayılan olarak Docling, gerçek görselleri çıkarmadan yalnızca görsel konumlarını kaydeder. Bunu etkinleştirmek, UI’nizde gösterebileceğiniz veya görsel modellerle işleyebileceğiniz PIL görsel nesneleri verir. images_scale parametresi çıkarım çözünürlüğünü kontrol eder—2.0 değeri, görselleri görüntülerken veya ek analiz çalıştırırken daha iyi kalite için çözünürlüğü iki katına çıkarır.

Yüklenen dosyaları işleme

Boru hattı yapılandırıldıktan sonra, Streamlit üzerinden yüklenen dosyaları işleyen yöntemi ekleyebiliriz. Bu yöntem, Streamlit’in dosya nesnelerini ele alır, bunları geçici olarak kaydeder, Docling dönüştürmesini çalıştırır ve hem RAG için markdown hem de görselleştirme için Docling belgeleri döndürür:

import os
import tempfile
from typing import List, Any

def process_uploaded_files(self, uploaded_files) -> tuple[List[Document], List[Any]]:
    documents = []
    docling_docs = []
    temp_dir = tempfile.mkdtemp()

    try:
        for uploaded_file in uploaded_files:
            # Save uploaded file to temporary location
            temp_file_path = os.path.join(temp_dir, uploaded_file.name)
            with open(temp_file_path, "wb") as f:
                f.write(uploaded_file.getbuffer())

Streamlit, yüklenen dosyaları bellek içi dosya nesneleri olarak sağlar; ancak Docling’in işlemesi için diskte gerçek dosyalar gerekir. Geçici bir dizin oluşturup her yüklenen dosyayı özgün dosya adını koruyarak buraya yazarız.

# Process the document with Docling
result = self.converter.convert(temp_file_path)
          
# Export to markdown
markdown_content = result.document.export_to_markdown()

converter.convert() çağrısı, Docling’in tam belge analiz boru hattını çalıştırır. Belge yerleşimini tanımlar, gerekirse OCR uygular, tabloları ve görselleri algılar ve yapılandırılmış bir temsil oluşturur. Görsel çıkarımı olmadan 20–30 saniye, görseller etkinleştirildiğinde 40–60 saniye işlem süresi bekleyin.

Dönüşüm tamamlandıktan sonra, doğru biçimlendirme korunmuş, LLM dostu temiz metin üreten markdown biçimine dışa aktarırız—başlıklar başlık olarak kalır, listeler yapılarını korur ve tablolar markdown tablolarına dönüştürülür.

# Create LangChain document
doc = Document(
    page_content=markdown_content,
    metadata={
        "filename": uploaded_file.name,
        "file_type": uploaded_file.type,
        "source": uploaded_file.name,
    }
)

documents.append(doc)

# Store the Docling document for structure visualization
docling_docs.append({
    "filename": uploaded_file.name,
    "doc": result.document
})

Her işlenen belgenin iki temsilini oluştururuz. LangChain Document nesnesi, page_content olarak markdown metnini ve ilişkili üst veriyi içerir—bu, RAG için vektör deposuna gider. Orijinal Docling belge nesnesi ise dosya adıyla ayrı depolanır; tüm yapısal bilgiler (tablolar, görseller, hiyerarşi) görselleştirme için korunur.

finally:
    import shutil
    shutil.rmtree(temp_dir)

return documents, docling_docs

finally bloğu, işleme başarılı olsa da olmasa da geçici dosyaların temizlenmesini sağlar. Bir demet döndürürüz: RAG sistemi için LangChain belgeleri ve yapı görselleştirme için Docling belgeleri.

Belge işlemci artık hazır. Sırada, kullanıcıların dosya yüklemesine ve işlem durumunu görmesine olanak tanıyan Streamlit arayüzünü oluşturmak var.

Belge Yapısı Görselleştirmesini Uygulama

📄 Tam betik: src/structure_visualizer.py

Artık Docling ile belgeleri işleyebildiğimize göre, çıkarılanları görselleştirmenin bir yoluna ihtiyacımız var. Ham Docling belge nesnesi zengin yapısal bilgiler (başlıklar, tablolar, görseller ve üst veriler) içerir, ancak doğal hâliyle kullanıcı dostu değildir. Bu veriyi dört görünümle etkileşimli bir arayüze dönüştüren bir görselleştirme katmanı inşa edeceğiz: özet panosu, hiyerarşik taslak, etkileşimli tablolar ve çıkarılan görseller.

src/ dizininizde structure_visualizer.py adlı yeni bir dosya oluşturun. Bu bileşen, Docling’in belge yapısını ayrıştırıp görüntülemeye uygun hâle getirecek.

Görselleştirici sınıfını oluşturma

Bir Docling belgesini saran ve farklı yapısal öğeleri çıkarmak için yöntemler sağlayan bir sınıf oluşturarak başlayın:

from typing import List, Dict, Any
import pandas as pd
from docling_core.types.doc import DoclingDocument

class DocumentStructureVisualizer:
    def __init__(self, docling_document: DoclingDocument):
        self.doc = docling_document

Başlatıcı, (DocumentConverter.convert() tarafından döndürülenle aynı) bir DoclingDocument nesnesi alır. Bu nesne, Docling’in belgeden çıkardığı her şeyi içerir. texts özelliği, etiketleri ve konumlarıyla tüm metin öğelerini; tables tablo verilerini yapı bilgisiyle; pictures görsel üst verilerini ve gerçek görsel verisini; pages ise sayfa düzeyi bilgileri sağlar.

Belge hiyerarşisini çıkarma

Belgeler, yalnızca paragrafların ötesinde bir yapıya sahiptir. Başlıklar, okuyucuların içeriği gezmesine yardımcı olan bir hiyerarşi oluşturur. Bu hiyerarşi şöyle çıkarılır:

def get_document_hierarchy(self) -> List[Dict[str, Any]]:
    hierarchy = []

    if not hasattr(self.doc, "texts") or not self.doc.texts:
        return hierarchy

    for item in self.doc.texts:
        label = getattr(item, "label", None)

        if label and "header" in label.lower():
            text = getattr(item, "text", "")
            prov = getattr(item, "prov", [])
            page_no = prov[0].page_no if prov else None

            hierarchy.append({
                "type": label,
                "text": text,
                "page": page_no,
                "level": self._infer_heading_level(label)
            })

    return hierarchy

Belgedeki tüm metin öğeleri üzerinde yineleme yapar, header içeren etiketlere sahip olanları filtreleriz. Her metin öğesinde, Docling’in yerleşim analizi sırasında atadığı bir label bulunur. Yaygın etiketler arasında section_header, page_header, title ve normal text yer alır. prov (provenans) niteliği, öğenin hangi sayfada göründüğü dâhil konum bilgilerini içerir. Başlık metnini, sayfa numarasını çıkarır ve etiket türünden hiyerarşik seviyeyi çıkarımlarız.

Taslağı görüntülerken başlık seviyesi girintilemeyi belirler. Yardımcı bir yöntem, etiket türlerini sayısal seviyelere eşler:

def _infer_heading_level(self, label: str) -> int:
    if "title" in label.lower():
        return 1
    elif "section" in label.lower():
        return 2
    elif "subsection" in label.lower():
        return 3
    else:
        return 4

Bu, belge başlıklarının seviye 1, bölüm başlıklarının seviye 2, alt bölümlerin seviye 3 ve diğer tüm başlıkların varsayılan olarak seviye 4 olduğu bir hiyerarşi oluşturur.

Tabloları DataFrame’lere dönüştürme

Belge hiyerarşisini çıkardıktan sonra, tablolara geçelim. Basit metin çıkarımı tabloları karmakarışık dizgelere dönüştürürken, Docling bunların yapısını korur—en değerli özelliklerinden biridir:

def get_tables_info(self) -> List[Dict[str, Any]]:
    tables_info = []

    if not hasattr(self.doc, "tables") or not self.doc.tables:
        return tables_info

    for i, table in enumerate(self.doc.tables, 1):
        try:
            df = table.export_to_dataframe(doc=self.doc)

            prov = getattr(table, "prov", [])
            page_no = prov[0].page_no if prov else None

            caption_text = getattr(table, "caption_text", None)
            caption = caption_text if caption_text and not callable(caption_text) else None

            tables_info.append({
                "table_number": i,
                "page": page_no,
                "caption": caption,
                "dataframe": df,
                "shape": df.shape,
                "is_empty": df.empty
            })
        except Exception as e:
            print(f"Warning: Could not process table {i}: {e}")
            continue

    return tables_info

table.export_to_dataframe(doc=self.doc) yöntemi, Docling’in tablo temsilini bir pandas DataFrame’ine dönüştürür. Mevcut olduğunda altyazıları ve sayfa numaralarını da çıkarırız.

PIL ile görselleri çıkarma

Tabloların ötesinde, Docling belgelerden gerçek görsel verisini çıkarabilir. Bu, yalnızca görsel konumlarını izlemeyi aşan yeni bir özelliktir—görselleri gerçekten bayt düzeyinde alır ve gösterebilirsiniz. (Bunu belge işlemcinin boru hattı seçeneklerinde etkinleştirdik.)

def get_pictures_info(self) -> List[Dict[str, Any]]:
    pictures_info = []

    if not hasattr(self.doc, "pictures") or not self.doc.pictures:
        return pictures_info

    for i, pic in enumerate(self.doc.pictures, 1):
        prov = getattr(pic, "prov", [])

        if prov:
            page_no = prov[0].page_no
            bbox = prov[0].bbox

            caption_text = getattr(pic, "caption_text", None)
            caption = caption_text if caption_text and not callable(caption_text) else None

            pil_image = None
            try:
                if hasattr(pic, "image") and pic.image is not None:
                    if hasattr(pic.image, "pil_image"):
                        pil_image = pic.image.pil_image
            except Exception as e:
                print(f"Warning: Could not extract image {i}: {e}")

            pictures_info.append({
                "picture_number": i,
                "page": page_no,
                "caption": caption,
                "pil_image": pil_image,
                "bounding_box": {
                    "left": bbox.l,
                    "top": bbox.t,
                    "right": bbox.r,
                    "bottom": bbox.b
                } if bbox else None
            })

    return pictures_info

Her görsel, sayfa numarası ve sınırlayıcı kutu koordinatları dâhil provenans bilgisine sahiptir. Sınırlayıcı kutu, sol, üst, sağ ve alt koordinatlarını kullanarak görselin sayfadaki konumunu tanımlar.

Görsel çıkarımı etkinleştirildiğinde, görsel nesnesinde gerçek görsel verisini içeren bir image özelliği olur. PIL görseline picture.image.pil_image üzerinden erişiriz; bu, Streamlit’in st.image() ile doğrudan görüntüleyebileceği bir PIL Image nesnesi döndürür. try-except bloğu, görsel çıkarımının başarısız olduğu veya etkinleştirilmediği durumları ele alır ve zarifçe yalnızca üst verileri göstermeye geri döner.

Belge özeti oluşturma

Görselleştiricinin bir yönteme daha ihtiyacı var: kullanıcılara belgenin yapısına genel bir bakış sunan, üst düzey bir özet:

def get_document_summary(self) -> Dict[str, Any]:
    pages = getattr(self.doc, "pages", {})
    texts = getattr(self.doc, "texts", [])
    tables = getattr(self.doc, "tables", [])
    pictures = getattr(self.doc, "pictures", [])

    text_types = {}
    for item in texts:
        label = getattr(item, "label", "unknown")
        text_types[label] = text_types.get(label, 0) + 1

    return {
        "name": self.doc.name,
        "num_pages": len(pages) if pages else 0,
        "num_texts": len(texts),
        "num_tables": len(tables),
        "num_pictures": len(pictures),
        "text_types": text_types
    }

Belgedeki sayfa, metin öğesi, tablo ve görsel sayısını sayarız. text_types sözlüğü, metin öğelerini etiketlerine göre dökümleyerek Docling’in kaç başlık, paragraf ve diğer öğeleri tanıdığını gösterir. Bu, kullanıcılara belgenin yapısı ve karmaşıklığı hakkında hızlı bir fikir verir.

Görselleştiriciyi Streamlit’e ekleme

Görselleştirici tamamlandığına göre, onu Streamlit’e dört sekmeyle entegre edelim: Summary, Hierarchy, Tables ve Images.

def render_structure_viz():
    st.title("📊 Document Structure")

    if not st.session_state.docling_docs:
        st.info("👈 Please upload and process your documents first!")
        return

    doc_names = [doc["filename"] for doc in st.session_state.docling_docs]
    selected_doc_name = st.selectbox("Select document to analyze:", doc_names)

    selected_doc_data = next(
        (doc for doc in st.session_state.docling_docs if doc["filename"] == selected_doc_name),
        None
    )

    if not selected_doc_data:
        return

    visualizer = DocumentStructureVisualizer(selected_doc_data["doc"])

    tab1, tab2, tab3, tab4 = st.tabs(["📑 Summary", "🏗️ Hierarchy", "📊 Tables", "🖼️ Images"])

Kullanıcıların hangi belgeyi analiz edeceğini seçmesine olanak tanıyan bir açılır liste oluşturuyoruz (birden çok dosya yüklendiğinde kullanışlıdır). Oturum durumundan seçilen Docling belgesini aldıktan sonra görselleştiriciyi başlatır ve farklı görünümler için dört sekme oluştururuz.

with tab1:
    st.subheader("Document Summary")
    summary = visualizer.get_document_summary()

    col1, col2, col3, col4 = st.columns(4)
    with col1:
        st.metric("Pages", summary["num_pages"])
    with col2:
        st.metric("Tables", summary["num_tables"])
    with col3:
        st.metric("Images", summary["num_pictures"])
    with col4:
        st.metric("Text Items", summary["num_texts"])

    st.subheader("Content Types")
    text_types_df = pd.DataFrame([
        {"Type": k, "Count": v}
        for k, v in sorted(summary["text_types"].items(), key=lambda x: -x[1])
    ])
    st.dataframe(text_types_df, use_container_width=True)

with tab2:
    st.subheader("Document Hierarchy")
    hierarchy = visualizer.get_document_hierarchy()

    if hierarchy:
        for item in hierarchy:
            indent = "  " * (item["level"] - 1)
            st.markdown(f"{indent}**{item['text']}** _(Page {item['page']})_")
    else:
        st.info("No hierarchical structure detected")

with tab3:
    st.subheader("Tables")
    tables_info = visualizer.get_tables_info()

    if tables_info:
        for table_data in tables_info:
            st.markdown(f"### Table {table_data['table_number']} (Page {table_data['page']})")

            if table_data["caption"]:
                st.caption(table_data["caption"])

            if not table_data["is_empty"]:
                st.dataframe(table_data["dataframe"], use_container_width=True)
            else:
                st.info("Table is empty")

            st.divider()
    else:
        st.info("No tables found in this document")

with tab4:
    st.subheader("Images")
    pictures_info = visualizer.get_pictures_info()

    if pictures_info:
        for pic_data in pictures_info:
            st.markdown(f"**Image {pic_data['picture_number']}** (Page {pic_data['page']})")

            if pic_data["caption"]:
                st.caption(pic_data["caption"])

            if pic_data["pil_image"] is not None:
                st.image(pic_data["pil_image"], use_container_width=True)
            else:
                st.info("Image data not available")

            if pic_data["bounding_box"]:
                bbox = pic_data["bounding_box"]
                with st.expander("📐 Position Details"):
                    st.text(
                        f"Position: ({bbox['left']:.1f}, {bbox['top']:.1f}) - "
                        f"({bbox['right']:.1f}, {bbox['bottom']:.1f})"
                    )

            st.divider()
    else:
        st.info("No images found in this document")

Belge Yapısı sekmesinin ekran görüntüsü: Dört alt sekmenin tümü gösteriliyor: Belge metrikleriyle Summary, girintili başlıklarla Hierarchy, etkileşimli DataFrame'lerle Tables ve altyazılı çıkarılmış görselleri gösteren Images

Yapı görselleştirici tamamlandı. Kullanıcılar bir belge yükleyip hemen anatomisini görebilir—kaç sayfa, tablo ve görsel içerdiğini; başlıklar ve bölümlerle hiyerarşik yapısını; keşfedebilecekleri etkileşimli tabloları ve belgeden çıkarılmış gerçek görselleri. Bu şeffaflık, kullanıcıların Docling’in ne çıkardığını anlamasına yardımcı olur ve sisteme güven verir.

Belge işleme ve görselleştirme çalıştığına göre, bu işlenen belgeler üzerinde soru-cevap sağlayan RAG sistemini kurabiliriz.

RAG Vektör Deposunu ve Arama Aracını Oluşturma

📄 Tam betikler: src/vectorstore.py | src/tools.py

Belge işleme ve görselleştirme tamamlandığına göre, S&C yeteneklerini inşa edebiliriz. RAG (Retrieval Augmented Generation), kullanıcıların belgeleri hakkında sorular sormasını sağlar. Sistem, belgeleri gömlemelere dönüştürür, bir vektör veritabanında saklar ve soruları yanıtlamak için ilgili parçaları getirir.

Bu bölüm iki bileşeni kapsar: belgeleri parçalayıp gömen bir vektör depo yöneticisi ve ilgili bilgiyi getiren bir arama aracı.

Vektör deposunu kurma

Vektör deposu, belge gömlemelerinin yaşadığı yerdir. Kullanıcılar bir soru sorduğunda, bu depoda ilgili parçaları arayıp bunları bağlam olarak LLM’e iletiriz.

src/ dizininizde vectorstore.py oluşturun:

from typing import List
from langchain_core.documents import Document
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma

Bu içe aktarımlar, belge işleme, metin bölme, gömleme üretimi ve ChromaDB vektör depolama için LangChain bileşenlerini getirir. Birlikte şöyle çalışırlar:

class VectorStoreManager:
    def __init__(self):
        self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
        self.text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=1000,
            chunk_overlap=100,
            length_function=len,
        )

İki temel bileşeni başlatıyoruz. OpenAI’nin text-embedding-3-small modeli metni vektörlere dönüştürür. text-embedding-3-large modelinden daha küçük ve hızlıdır; yüzlerce parçayı gömerken önemlidir. RecursiveCharacterTextSplitter ise belgeleri, önemli bilgilerin parça sınırlarında cümle ortasında kesilmemesini sağlayacak şekilde 1000 karakterlik parçalar ve 100 karakter örtüşmeyle böler.

Neden 1000 karakter?

1000 karakter, kesinlik ve bağlam arasında denge kurar—küçük parçalar hassas getirme sağlar ancak bağlam kaybeder; büyük parçalar bağlamı korur ancak ilgililiği seyreltebilir.

Parçalama yöntemini ekleyin:

def chunk_documents(self, documents: List[Document]) -> List[Document]:
    """Split documents into smaller chunks for better retrieval."""
    chunks = self.text_splitter.split_documents(documents)
    return chunks

Böleyici, üst verileri otomatik olarak ele alır ve özgün belgelerden bilgileri korur. Her parça, hangi dosyadan geldiğini bilir; bu da ajanın yanıtlarda kaynak belirtirken önem kazanır.

Şimdi vektör deposunu oluşturan yöntemi ekleyin:

def create_vectorstore(self, chunks: List[Document]) -> Chroma:
    """Create a Chroma vector store from document chunks."""
    vectorstore = Chroma.from_documents(
        documents=chunks,
        embedding=self.embeddings,
        collection_name="documents"
    )
    return vectorstore

Ağır işi ChromaDB yapar. Her parçayı gömleme modelimizle gömler ve vektörleri bellekte saklar. Bir benzerlik araması yaptığınızda ChromaDB, sorgu vektörüyle tüm belge vektörleri arasındaki kosinüs benzerliğini hesaplar ve en yakın eşleşmeleri döndürür.

Arama aracını oluşturma

Vektör deposu gömlemeleri ele almaya hazır olduğuna göre, ajana bunu sorgulama yolu vermeliyiz. Araçlar, LLM’in ihtiyacı olduğunda çağırabileceği işlevlerdir.

src/ dizininizde tools.py oluşturun:

from typing import Annotated
from langchain_core.tools import tool

def create_search_tool(vectorstore):
    """Create a search tool that has access to the vector store."""

Bu fabrika işlevi bir kapanım deseni kullanır: bir vektör deposu alır ve onu arayabilen bir araç döndürür. Araç, genel değişkenlere ihtiyaç olmadan vektör deposuna erişimi sürdürür.

@tool
def search_documents(query: Annotated[str, "The search query or question about the documents"]) -> str:
    """Search the uploaded documents for relevant information."""

@tool dekoratörü bu işlevi, ajanın çağırabileceği bir LangChain aracına dönüştürür. Annotated tür ipucu, parametreyi tanımlar ve LLM’in aracı çağırırken ne geçmesi gerektiğini anlamasına yardımcı olur.

try:
   results = vectorstore.similarity_search(query, k=8)

   if not results:
      return "No relevant information found in the documents for this query."

Vektör deposundan 8 benzer parça (k=8) getiririz. Bu, LLM’e yeterli bağlam verir ancak onu yinelemeli bilgilerle boğmaz. Doğru sayı belge türünüze bağlıdır—yoğun bilgi içeren teknik belgeler, daha az parça (k=4–6) ile daha iyi çalışabilirken anlatı türündeki belgeler daha fazla parçadan (k=10–12) fayda görebilir.

context_parts = []
for i, doc in enumerate(results, 1):
    source = doc.metadata.get("filename", doc.metadata.get("source", "Unknown source"))
    content = doc.page_content.strip()

    context_parts.append(
        f"[Source {i}: {source}]\n"
        f"Content: {content}\n"
    )

return "\n---\n".join(context_parts)

Her parçayı kaynak dosya adıyla biçimlendirir, sonra ayırıcılarla birleştiririz. LLM bu yapılandırılmış bağlamı alır ve yanıt üretirken kaynakları belirtir.

except Exception as e:
    return f"Error searching documents: {str(e)}"

return search_documents

Hata yönetimi, arama başarısız olursa ajanın çökmesi yerine net bir mesaj almasını sağlar. İşlev, ajanın kullanmaya hazır yapılandırılmış aracı döndürür.

Vektör deposu ve arama aracı şimdi hazır. Sırada, getirme ve üretimi koordine ederek kullanıcı sorularını yanıtlayan LangGraph ajanını oluşturmak var.

Akış ile LangGraph Ajanı Oluşturma

📄 Tam betik: src/agent.py

Arama aracı vektör deposunu sorgulayabilir; ancak akıllı bir koordinatöre ihtiyaç duyar. LangGraph ajanı ne zaman arama yapacağına karar verir, sonuçları yorumlar ve doğal dilde yanıtlar üretir. İlerlemeyi gerçek zamanlı göstermek için akış da uygulayacağız.

LangGraph ajanını inşa etme

Ajan, soruları alır, ne zaman belge araması yapılacağına karar verir ve getirilen bağlamlara dayalı yanıtlar üretir.

src/ dizininizde agent.py oluşturun:

from typing import List
from langchain_core.tools import BaseTool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver

Araç işlemesi, OpenAI’nin sohbet modelleri, LangGraph’ın ReAct ajan uygulaması ve konuşma belleği için bileşenleri içe aktarırız.

SYSTEM_PROMPT = """You are a helpful document intelligence assistant. You have access to documents that have been uploaded and processed.

GUIDELINES:
- Use the search_documents tool to find relevant information
- Keep it simple: one well-crafted search is usually sufficient
- Only search again if the first results are clearly incomplete
- Provide clear, accurate answers based on the document contents
- Always cite your sources with filenames
- If information isn't found, say so clearly
- Be concise but thorough

When answering:
1. Search the documents with a focused query
2. Synthesize a clear answer from the results
3. Include source citations (filenames)
4. Only search again if absolutely necessary
"""

def create_documentation_agent(tools: List[BaseTool], model_name: str = "gpt-4o-mini"):
    """Create a document intelligence assistant agent using LangGraph."""
    llm = ChatOpenAI(model=model_name, temperature=0)
    memory = MemorySaver()

gpt-4o-mini kullanıyoruz; çünkü daha hızlı ve daha ucuzdur ve yine de belge S&C’yi iyi şekilde karşılar. Sıcaklık 0’a ayarlanır; böylece tutarlı ve olgusal yanıtlar alınır. MemorySaver ajana konuşma belleği sağlar; böylece bir oturum içinde önceki alışverişleri hatırlar.

agent = create_react_agent(
    llm,
    tools=tools,
    prompt=SYSTEM_PROMPT,
    checkpointer=memory
)

return agent

LangGraph’ın create_react_agent işlevi ReAct desenini (Akıl Yürütme + Eylem) uygular. Ajan ne yapması gerektiğini düşünür, araçları kullanarak eyleme geçer, sonuçları gözlemler ve bir yanıt elde edene kadar tekrarlar. Bu desen, RAG için uygundur; çünkü ajan ne zaman arama yapacağına ve getirilen bağlamı nasıl kullanacağına karar verebilir.

Akışlı yanıtları uygulama

Ajan artık arama yapıp yanıt üretebilir; ancak kullanıcılar o çalışırken 10 saniye boş bir ekrana bakmamalıdır. Akış, ilerlemeyi gerçek zamanlı gösterir—önce bir “düşünüyor” göstergesi, sonra “arama yapılıyor”, ardından yanıtın belirteç belirteç görünmesi.

app.py içindeki render_chat() işlevinizi, daha önce TODO ile işaretlediğimiz yanıt işleme kısmını tamamlamak için güncelleyin:

if prompt:
    st.session_state.messages.append({"role": "user", "content": prompt})
    with st.chat_message("user"):
        st.markdown(prompt)

Kullanıcının mesajını konuşma geçmişine ekler ve sohbet arayüzünde gösteririz.

with st.chat_message("assistant"):
    status_placeholder = st.empty()
    message_placeholder = st.empty()

    try:
        config = {"configurable": {"thread_id": "document_chat"}}

Durum göstergesi ve yanıt mesajı için yer tutucular oluştururuz. Yapılandırma, LangGraph’ın konuşma belleğini turlar arasında sürdürmek için kullandığı bir iş parçacığı kimliği içerir.

def generate_response():
    """Generator that yields tokens from LangGraph stream."""
    status_placeholder.markdown("🤔 **Thinking...**")
    first_content_token = True
    tool_call_detected = False
    final_answer_started = False

Bu üretici işlev, LangGraph’ın akış çıktısını işler. Ajan iş akışında ilerlerken uygun durum mesajlarını göstermek için bayraklarla durumu izleriz.

for msg, metadata in st.session_state.agent.stream(
    {"messages": [HumanMessage(content=prompt)]},
    config=config,
    stream_mode="messages",
):
    langgraph_node = metadata.get("langgraph_node", "")

stream_mode="messages" parametresi, yalnızca nihai çıktılar değil, oluşturuldukça gerçek LLM belirteçleri verir. LangGraph, ajanın yürütümü boyunca—düşünmeye başladığında, araçları çağırdığında ve metin ürettiğinde—olaylar yayar.

if "tools" in langgraph_node.lower() or "tool" in langgraph_node.lower():
    if not tool_call_detected:
        status_placeholder.markdown("🔍 **Searching documents...**")
        tool_call_detected = True
    continue

if "agent" in langgraph_node.lower() and hasattr(msg, "content"):
    content = msg.content

if content:
    if first_content_token:
        status_placeholder.markdown("💬 **Generating answer...**")
        first_content_token = False
        final_answer_started = True

if final_answer_started:
    yield content

Ajan düğümü nihai yanıtı üretmeye başladığında, durumu günceller ve içerik belirteçlerini sunmaya başlarız. Her belirteç anında görüntülenir ve akıcı bir yazma etkisi oluşturur.

status_placeholder.empty()

with message_placeholder.container():
    full_response = st.write_stream(generate_response())

Akış tamamlandıktan sonra durum göstergesini temizleriz. Streamlit’in st.write_stream() işlevi, belirteçleri biriktirmeyi ve UI’yi akıcı şekilde güncellemeyi otomatik olarak yönetir. Sonuç, sistemin çalıştığına dair güven veren, duyarlı bir sohbet deneyimidir.

st.session_state.messages.append({"role": "assistant", "content": full_response})

except Exception as e:
    st.error(f"Error generating response: {str(e)}")

Tam yanıtı mesaj geçmişine kaydeder ve akış sırasında oluşabilecek hataları ele alırız.

RAG sistemi tamamlandı. Kullanıcılar artık belgeleri yükleyebilir, Docling ile işleyebilir, yapısını keşfedebilir ve içerik hakkında doğal sohbetler yapabilir. Ajan akıllıca arama yapar, kaynak belirtir ve akışla yanıtlar üretir.

Test ve Doğrulama

Belge Zekâsı Asistanınız hazır. Dağıtmadan veya paylaşmadan önce, her şeyin doğru çalıştığını doğrulamak için uygulamayı test etmelisiniz.

Uygulamayı çalıştırma

Uygulamayı proje kökünüzden başlatın:

streamlit run app.py

Streamlit http://localhost:8501 adresinde bir tarayıcı penceresi açar. Kenar çubuğunda yükleme kontrollerini ve ana alanda iki sekmeyi görmelisiniz.

Belge işleme boru hattını test etme

Tam işleme yeteneklerini test etmek için tablolar ve görseller içeren örnek bir PDF belge yükleyin:

  1. Kenar çubuğunda “Upload Documents”a tıklayın
  2. Bir PDF dosyası seçin (tercihen tablolar, görseller ve net başlıklar içeren)
  3. “Process & Index”e tıklayın

İşleme göstergelerini izleyin:

  • “Processing documents with Docling…” (belge boyutuna bağlı olarak 20–60 saniye)
  • “Chunking documents…”
  • “Creating vector store…”
  • “Creating agent…”

Tamamlandığında, durum bölümünde “✅ Ready to chat!” göreceksiniz.

Belge yapısı görselleştirmeyi test etme

Docling’in her şeyi doğru çıkardığını doğrulamak için “Document Structure” sekmesine geçin:

  1. Summary sekmesi: Sayfa, tablo, görsel ve metin öğesi sayılarını belgenizle eşleştiğinden emin olun
  2. Hierarchy sekmesi: Başlıkların doğru sırada ve uygun girintilemeyle göründüğünü doğrulayın
  3. Tables sekmesi: Tabloların karmakarışık metin yerine etkileşimli DataFrame’ler olarak görüntülendiğini doğrulayın
  4. Images sekmesi: Görsellerin düzgün renderlandığını doğrulayın (görsel çıkarımı etkinse)

Tablolar boş görünüyorsa veya görseller çıkmıyorsa, boru hattı seçeneklerinde do_table_structure=True ve generate_picture_images=True değerlerini etkinleştirdiğinizi kontrol edin.

S&C sistemini test etme

“Chat” sekmesine dönün ve ajanı şu örnek sorularla test edin:

İyi başlangıç soruları:

  • “Bu belge ne hakkında?”
  • “Ele alınan ana konuları özetleyin”
  • “Bu belgede hangi tablolar var?”
  • “Herhangi bir şekil veya görseli altyazılarıyla listeleyin”

Belgeye özgü sorular (belgenize göre uyarlayın):

  • “Tablo 1’de hangi veriler gösteriliyor?”
  • “Bölüm 3’te açıklanan metodolojiyi açıklayın”
  • “Temel bulgular neler?”
  • “Yazarlar kim?”

Takip soruları (konuşma belleğini test etmek için):

  • Bir tablo hakkında sorduktan sonra: “Bu veriler bize ne söylüyor?”
  • Bir yanıt aldıktan sonra: “Bunu daha basit terimlerle açıklayabilir misiniz?”

Nelere dikkat etmeli

Belgenizden doğrudan yanıtlar ve kaynak atıfları, akıcı akış belirteçleri ve durum göstergeleri (“Thinking…”, “Searching documents…”, “Generating answer…”) arayın. Belgenizden gelmeyen genel yanıtlar, eksik kaynak atıfları, durum göstergeleri olmadan yavaş yanıtlar veya eksik API anahtarlarıyla ilgili hatalara dikkat edin.

Yaygın sorunlar ve çözümleri

“No module named ‘docling’” hatası

pip install docling langchain langchain-openai langchain-chroma langgraph streamlit streamlit-extras pandas python-dotenv

“OpenAI API key not found” hatası

  • .env dosyasının OPENAI_API_KEY=your-key-here içeriğiyle mevcut olduğunu doğrulayın

  • Streamlit’i yeniden başlatın

İşleme 60 saniyeden uzun sürüyor

  • İlk çalıştırma için normaldir (Docling ~500MB model indirir) veya büyük belgelerde

Ajan genel yanıtlar veriyor

  • Belgelerin işlendiğini ve vektör deposunun oluşturulduğunu doğrulayın
  • Daha spesifik sorular deneyin

Tablolar boş DataFrame olarak görünüyor

  • PdfPipelineOptions içinde do_table_structure=True değerini doğrulayın

  • Yerel tablolar içeren farklı bir PDF deneyin

Uygulama artık doğrulandı ve kullanıma hazır. Kendi belgelerinizle test edebilir veya başkalarının kullanması için dağıtabilirsiniz.

Sonuç

Artık, yapısını koruyarak PDF, Word belgeleri, PowerPoint sunumları ve HTML dosyalarını işleyen çalışan bir Belge Zekâsı Asistanına sahipsiniz. Docling, kullanıcıların etkileşimli sekmeler aracılığıyla keşfedebileceği metni, tabloları, görselleri ve belge hiyerarşisini çıkarır. ChromaDB ve LangGraph ile birleşen RAG sistemi, kaynak atıflarını gerçek zamanlı akışla sunarak sohbet tarzı S&C sağlar. Bu, yapı farkında belge işlemenin, temel metin çıkarıma kıyasla getirme kalitesini nasıl iyileştirdiğini gösterir. Tam kaynak kodu şurada mevcuttur: GitHub deposu.

Bu temel, genişletme için çeşitli yönler açar:

  • Toplu işleme ve kalıcı vektör depolama ekleyin
  • Farklı motorlarla tarama belgeleri için OCR etkinleştirin
  • Streamlit Cloud’a dağıtın veya Docker ile konteynerleştirin
  • Çıkarılan grafikleri analiz etmek için görsel-dil modellerini entegre edin
  • Alana özgü çıkarım kuralları oluşturun veya dışa aktarma işlevi ekleyin

RAG sistemleri ve LLM uygulamalarını daha derinlemesine keşfetmek için AI Engineering eğitim yolumuz burada kullandığınız kavram ve desenleri kapsar.

Bexruz (Bex) Tuychiev

Yazar

Bexruz (Bex) Tuychiev

2 yılı aşkın deneyime sahip bir veri bilimi içerik üreticisiyim ve Medium’da en büyük takipçi kitlelerinden birine sahibim. Yapay zekâ ve makine öğrenimi üzerine, biraz da alaycı bir üslupla yazılmış, ayrıntılı makaleler kaleme almayı seviyorum; çünkü onları biraz daha az sıkıcı hale getirmek için bir şeyler yapmak gerekiyor. 130’un üzerinde makale ve bir de DataCamp kursu ürettim; bir diğeri de hazırlık aşamasında. İçeriklerim 5 milyondan fazla kişi tarafından görüldü; bunların 20 bini Medium ve LinkedIn’de takipçim oldu. 

Konular

İlgili