0Pricing
AI Agents · Ders

Şema Anlama ve Enjeksiyonu

LLM bağlamı için DB şemasını çıkarma ve biçimlendirme: tablolar, sütunlar ve ilişkiler.

Şema Anlama ve Enjeksiyonu, CoddyKit'te ücretsiz bir AI Agents dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, AI Agents öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. AI Agents kursu toplamda 4 dersten oluşur.

Şema Bağlamı Neden Önemlidir

LLM SQL söz dizimini bilir ancak sizin veritabanınız hakkında hiçbir şey bilmez. Şema bağlamı olmadan tablo ve sütun adlarını uydurur.

Şema ekleme, veritabanı yapınızı program aracılığıyla çıkarıp her isteme dâhil etmek anlamına gelir — böylece LLM tam tablolarınızdan, sütunlarınızdan ve türlerinizden haberdar olur.

INFORMATION_SCHEMA Üzerinden Sorgulama

Tüm büyük ilişkisel veritabanları meta verileri INFORMATION_SCHEMA aracılığıyla sunar. Uygulama koduna dokunmadan her tabloyu, sütun adını ve veri türünü almak için burayı sorgulayabilirsiniz.

Bu yöntem PostgreSQL, MySQL, SQL Server ve SQLite'ta küçük farklılıklarla çalışır.

import psycopg2

def get_schema(conn):
    query = '''
        SELECT table_name, column_name, data_type
        FROM information_schema.columns
        WHERE table_schema = 'public'
        ORDER BY table_name, ordinal_position
    '''
    with conn.cursor() as cur:
        cur.execute(query)
        return cur.fetchall()

Sütunları Tabloya Göre Gruplama

Ham INFORMATION_SCHEMA sonucu, düz bir satır listesidir. İsteme daha kolay biçimlendirilebilecek yapılandırılmış bir gösterim oluşturmak için bunları tablo adına göre gruplayın.

from collections import defaultdict

def build_schema_dict(conn):
    rows = get_schema(conn)
    schema = defaultdict(list)
    for table_name, column_name, data_type in rows:
        schema[table_name].append({
            'name': column_name,
            'type': data_type
        })
    return dict(schema)

# Result:
# {
#   'users': [{'name': 'id', 'type': 'integer'}, {'name': 'email', 'type': 'character varying'}],
#   'orders': [{'name': 'id', 'type': 'integer'}, {'name': 'user_id', 'type': 'integer'}]
# }

LLM İstemleri İçin Şemayı Biçimlendirme

LLM şemayı düz metin olarak okur. Kısa ve okunabilir bir biçim kullanın: her satırda bir tablo, parantez içinde sütun adları ve türleri.

Birincil anahtarları (PK) ve yabancı anahtarları (FK) eklemek, LLM'nin doğru JOIN ifadeleri yazmasına yardımcı olur.

def format_schema_for_prompt(schema_dict, pk_info=None, fk_info=None):
    lines = []
    for table, columns in schema_dict.items():
        col_parts = []
        for col in columns:
            label = col['name']
            if pk_info and (table, col['name']) in pk_info:
                label += ' PK'
            if fk_info and (table, col['name']) in fk_info:
                label += f' FK->{fk_info[(table, col["name"])]}'
            col_parts.append(f"{label} ({col['type']})")
        lines.append(f"Table {table}: {', '.join(col_parts)}")
    return '\n'.join(lines)

# Output:
# Table users: id PK (integer), email (varchar), created_at (timestamp)
# Table orders: id PK (integer), user_id FK->users.id (integer), total (float)

if __name__ == '__main__':
    demo_schema = {'users': [{'name': 'id', 'type': 'integer'}, {'name': 'email', 'type': 'varchar'}]}
    demo_pk = {('users', 'id')}
    print(format_schema_for_prompt(demo_schema, pk_info=demo_pk))

Birincil ve Yabancı Anahtarları Ekleme

Yabancı anahtar ilişkileri, şema bağlamının en önemli bölümüdür — LLM'ye JOIN'leri nasıl yazacağını gösterir. Bunları çıkarmak için information_schema.table_constraints ve key_column_usage sorgularını kullanın.

def get_foreign_keys(conn):
    query = '''
        SELECT
            kcu.table_name,
            kcu.column_name,
            ccu.table_name AS foreign_table,
            ccu.column_name AS foreign_column
        FROM information_schema.table_constraints AS tc
        JOIN information_schema.key_column_usage AS kcu
            ON tc.constraint_name = kcu.constraint_name
        JOIN information_schema.constraint_column_usage AS ccu
            ON ccu.constraint_name = tc.constraint_name
        WHERE tc.constraint_type = 'FOREIGN KEY'
    '''
    with conn.cursor() as cur:
        cur.execute(query)
        return {
            (row[0], row[1]): f'{row[2]}.{row[3]}'
            for row in cur.fetchall()
        }

if __name__ == '__main__':
    class FakeCursor:
        def __enter__(self): return self
        def __exit__(self, *a): return False
        def execute(self, query): pass
        def fetchall(self):
            return [('orders', 'user_id', 'users', 'id')]
    class FakeConn:
        def cursor(self): return FakeCursor()

    fks = get_foreign_keys(FakeConn())
    print('Foreign keys found:')
    for (table, col), ref in fks.items():
        print(f'  {table}.{col} -> {ref}')

Şema Sıkıştırma: Sorun

Gerçek bir kurumsal veritabanında 200'den fazla tablo bulunabilir. Şemanın tamamını eklerseniz GPT-4'ün bağlam penceresini aşar ve belirteçler için gereksiz para harcarsınız.

Her birinde 20 sütun bulunan 200 tabloluk bir şema yaklaşık 40.000'den fazla belirteç içerir — her sorguda gönderilemeyecek kadar pahalıdır.

def estimate_schema_tokens(schema_dict):
    text = format_schema_for_prompt(schema_dict)
    # Rough estimate: 1 token per 4 characters
    estimated_tokens = len(text) // 4
    print(f'Tables: {len(schema_dict)}')
    print(f'Estimated schema tokens: {estimated_tokens}')
    return estimated_tokens

# 200 tables * 15 columns * 25 chars/col = 75,000 chars = ~18,750 tokens
# Plus user question + system prompt = easily over context limit

Şema Sıkıştırma: Seçmeli Ekleme

En etkili sıkıştırma stratejisi şudur: soruyla ilgili tabloları yalnızca ekleyin. İki aşamalı bir yaklaşım kullanın — önce LLM'ye hangi tablolara ihtiyaç duyduğunu sorun, ardından yalnızca bu tabloların şemalarını ekleyin.

def select_relevant_tables(question, all_table_names, n=5):
    table_list = ', '.join(all_table_names)
    prompt = f'''Database tables: {table_list}

Question: {question}

List the {n} most relevant table names as a JSON array.
Example: ["users", "orders", "products"]'''

    response = llm_call(prompt)
    import json
    return json.loads(response)

def compressed_schema(question, conn):
    all_tables = list(build_schema_dict(conn).keys())
    relevant = select_relevant_tables(question, all_tables)
    full_schema = build_schema_dict(conn)
    return {t: full_schema[t] for t in relevant if t in full_schema}

Şema Sıkıştırma: Gürültü Sütunlarını Çıkarma

Birçok tabloda iş sorgularıyla nadiren ilgili olan created_at, updated_at, deleted_at, version, created_by gibi denetim sütunları bulunur. Belirteç sayısını azaltmak için bunları çıkarın.

AUDIT_COLUMNS = {
    'created_at', 'updated_at', 'deleted_at', 'created_by',
    'updated_by', 'version', 'is_deleted', 'modified_at'
}

def compress_schema(schema_dict, exclude_audit=True):
    compressed = {}
    for table, columns in schema_dict.items():
        # Skip internal/system tables
        if table.startswith('_') or table.startswith('pg_'):
            continue
        if exclude_audit:
            columns = [c for c in columns if c['name'] not in AUDIT_COLUMNS]
        if columns:  # only include if columns remain
            compressed[table] = columns
    return compressed

if __name__ == '__main__':
    demo_schema = {
        'users': [{'name': 'id', 'type': 'INT'}, {'name': 'email', 'type': 'VARCHAR'}, {'name': 'created_at', 'type': 'TIMESTAMP'}],
        'pg_stat': [{'name': 'x', 'type': 'INT'}],
    }
    compressed = compress_schema(demo_schema)
    print('Tables kept:', list(compressed.keys()))
    print('users columns after compression:', [c['name'] for c in compressed['users']])

Tablo Açıklamaları Ekleme

Sütun adları tek başına her zaman kendiliğinden anlaşılır değildir. Her tablonun neyi temsil ettiğine ilişkin doğal dil açıklamaları eklemek, SQL üretim kalitesini önemli ölçüde artırır.

Açıklamaları bir yapılandırma dosyasında veya PostgreSQL tablo yorumları olarak saklayın.

TABLE_DESCRIPTIONS = {
    'users': 'Registered app users with authentication info',
    'orders': 'Customer purchase orders',
    'order_items': 'Individual line items within an order',
    'products': 'Product catalog with pricing',
    'payments': 'Payment transactions linked to orders'
}

def format_schema_with_descriptions(schema_dict):
    lines = []
    for table, columns in schema_dict.items():
        desc = TABLE_DESCRIPTIONS.get(table, '')
        col_str = ', '.join(f"{c['name']} ({c['type']})" for c in columns)
        if desc:
            lines.append(f"Table {table} ({desc}): {col_str}")
        else:
            lines.append(f"Table {table}: {col_str}")
    return '\n'.join(lines)

if __name__ == '__main__':
    demo_schema = {'users': [{'name': 'id', 'type': 'INT'}], 'orders': [{'name': 'id', 'type': 'INT'}]}
    print(format_schema_with_descriptions(demo_schema))

Şemayı Önbelleğe Alma

Veritabanı şemaları nadiren değişir. Her sorguda INFORMATION_SCHEMA bilgisini almak gecikmeyi ve yükü artırır. Biçimlendirilmiş şema dizesini önbelleğe alın ve şema değişikliği olaylarında veya zamana dayalı bir TTL ile geçersiz kılın.

import time

class SchemaCache:
    def __init__(self, ttl_seconds=300):
        self._cache = None
        self._timestamp = 0
        self.ttl = ttl_seconds

    def get(self, conn):
        now = time.time()
        if self._cache is None or (now - self._timestamp) > self.ttl:
            print('Refreshing schema cache...')
            schema_dict = build_schema_dict(conn)
            fk_info = get_foreign_keys(conn)
            self._cache = format_schema_for_prompt(schema_dict, fk_info=fk_info)
            self._timestamp = now
        return self._cache

schema_cache = SchemaCache(ttl_seconds=300)

Tam Şema Ekleme Akışı

Tüm teknikleri birleştirin: sıkıştırılmış şemayı önbelleğe alın, sistem istemine ekleyin ve büyük veritabanları için seçici tablo filtreleme kullanın.

def build_sql_agent_prompt(question, conn, large_db=False):
    if large_db:
        schema = compressed_schema(question, conn)
        schema_text = format_schema_with_descriptions(schema)
    else:
        schema_text = schema_cache.get(conn)

    system = f'''You are a PostgreSQL expert.
Return ONLY a valid SELECT query based on this schema:

{schema_text}

Rules:
- Use only SELECT statements
- Use table aliases for clarity
- Limit results to 100 rows unless asked for all
'''
    return system

Bilgi Kontrolü

Tam şemayı eklemek yerine seçici tablo eklemeyi ne zaman kullanmalısınız?

Özet: Şemayı Anlama ve İsteme Ekleme

Etkili şema ekleme, güvenilir NL-to-SQL aracılarının temelidir. Yapıyı INFORMATION_SCHEMA üzerinden çıkarın, birincil ve yabancı anahtar ilişkilerini ekleyin ve bunu LLM için kısa bir metin olarak biçimlendirin.

Büyük veritabanları için şemayı önbelleğe alın, denetim sütunlarını çıkarın ve her soruyla ilgili tabloları göndermek için seçici ekleme kullanın. Tabloların doğal dildeki açıklamaları da sorgu kalitesini artırır.

Sıkça Sorulan Sorular

“Şema Anlama ve Enjeksiyonu” dersi ücretsiz mi?

Evet — “Şema Anlama ve Enjeksiyonu” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve AI Agents kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. AI Agents kursu toplamda 4 dersten oluşur.

“Şema Anlama ve Enjeksiyonu” dersinde ne öğreneceğim?

LLM bağlamı için DB şemasını çıkarma ve biçimlendirme: tablolar, sütunlar ve ilişkiler. AI Agents ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

AI Agents öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te AI Agents, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“Şema Anlama ve Enjeksiyonu” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu AI Agents dersinde kod yazıp çalıştırabilir miyim?

Evet. Her AI Agents dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. NL'den SQL'e Aracılar Nasıl Çalışır
  2. Şema Anlama ve Enjeksiyonu
  3. SQL Sorguları Oluşturma ve Doğrulama
  4. Belirsiz Veritabanı Sorularını Ele Alma
← AI Agents Sayfasına Dön