NL'den SQL'e Aracılar Nasıl Çalışır
Şema enjeksiyonu, sorgu oluşturma, yürütme ve sonuç biçimlendirme.
NL'den SQL'e Aracılar Nasıl Çalışır, CoddyKit'te ücretsiz bir AI Agents dersidir. Bu, 4 dersinin 1. 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.
NL'den SQL'e Ajan Nedir
Doğal dilden SQL'e ajan, düz İngilizce soruları SQL sorgularına çevirir, bunları bir veritabanında çalıştırır ve insanların okuyabileceği yanıtlar döndürür.
SELECT COUNT(*) FROM orders WHERE status='pending' yazmak yerine kullanıcılar yalnızca şunu sorar: "Kaç bekleyen siparişimiz var?"
Temel Mimari
Her NL'den SQL'e ajan aynı işlem hattını izler:
- Şema ekleme — veritabanı yapısını isteme ekleyin
- LLM SQL üretir — model bir sorgu oluşturur
- Çalıştırma — sorguyu veritabanında çalıştırın
- Sonuçları biçimlendirme — satırları okunabilir metne dönüştürün
- Yanıtı döndürme — kullanıcıya yanıt verin
# High-level pipeline
def nl_to_sql_agent(user_question, db_connection):
schema = get_schema(db_connection)
sql = llm_generate_sql(user_question, schema)
rows = execute_query(db_connection, sql)
answer = format_results(rows, user_question)
return answerŞema Ekleme Açıklaması
LLM, veritabanınızın yapısı hakkında hiçbir bilgiye sahip değildir. Modelin hangi tabloların ve sütunların bulunduğunu bilmesi için şemayı her isteme eklemelisiniz.
Kısa bir şema açıklaması modele şunu söyler: "orders tablosunda şu sütunlar bulunur: id, user_id, status, total, created_at."
def build_schema_prompt(schema_info):
lines = []
for table in schema_info:
cols = ', '.join(
f"{c['name']} ({c['type']})"
for c in table['columns']
)
lines.append(f"Table {table['name']}: {cols}")
return '\n'.join(lines)
# Output:
# Table users: id (INT), email (VARCHAR), created_at (TIMESTAMP)
# Table orders: id (INT), user_id (INT), status (VARCHAR), total (FLOAT)
if __name__ == '__main__':
demo_schema = [
{'name': 'users', 'columns': [{'name': 'id', 'type': 'INT'}, {'name': 'email', 'type': 'VARCHAR'}]},
{'name': 'orders', 'columns': [{'name': 'id', 'type': 'INT'}, {'name': 'user_id', 'type': 'INT'}]},
]
print(build_schema_prompt(demo_schema))
LLM SQL Üretim İstemi
İstem, LLM'ye üç şey vermelidir: şema, soru ve yalnızca geçerli SQL döndürmesi için açık talimatlar.
Yalnızca SELECT kullanılması ve hedef SQL lehçesinin (PostgreSQL, MySQL, SQLite) açıkça belirtilmesi güvenlik ve doğruluk açısından kritik önem taşır.
SYSTEM_PROMPT = '''You are a SQL expert. Given a database schema and a question,
generate a valid {dialect} SELECT query. Return ONLY the SQL query, no explanation.
Do not use INSERT, UPDATE, DELETE, or DROP.
Schema:
{schema}
'''
def llm_generate_sql(question, schema, dialect='PostgreSQL'):
prompt = SYSTEM_PROMPT.format(schema=schema, dialect=dialect)
response = client.chat.completions.create(
model='gpt-4o',
messages=[
{'role': 'system', 'content': prompt},
{'role': 'user', 'content': question}
]
)
return response.choices[0].message.content.strip()Üretilen SQL'i Çalıştırma
LLM SQL döndürdükten sonra bu SQL'i gerçek veritabanında çalıştırırsınız. Mümkün olduğunda parametreli sorgular kullanın ve istisnaları her zaman yakalayın — LLM geçersiz SQL üretebilir.
Çalıştırma işlemini bir hata yakalama bloğuna sarmalamak, LLM'ye gönderilen bir hata ipucuyla yeniden denemenizi sağlar.
import psycopg2
def execute_query(conn, sql):
try:
with conn.cursor() as cur:
cur.execute(sql)
columns = [desc[0] for desc in cur.description]
rows = cur.fetchmany(100) # limit rows
return {'columns': columns, 'rows': rows}
except psycopg2.Error as e:
return {'error': str(e), 'sql': sql}Kullanıcı İçin Sonuçları Biçimlendirme
Ham veritabanı satırları kullanıcı dostu değildir. Ajan bunları doğal dilde bir yanıta dönüştürmelidir.
Sonuç kümesi küçükse satırları yorumlaması için LLM'ye geri gönderin. Büyük kümelerde önce özet istatistikleri hesaplayın.
def format_results(result, original_question):
if 'error' in result:
return f'Query failed: {result["error"]}'
rows = result['rows']
columns = result['columns']
if not rows:
return 'No results found.'
# For simple counts/aggregates — just return the value
if len(columns) == 1 and len(rows) == 1:
return f'Result: {rows[0][0]}'
# For multi-row results — summarize
summary = f'Found {len(rows)} rows.\n'
for row in rows[:5]: # show first 5
summary += ', '.join(f'{columns[i]}: {row[i]}' for i in range(len(columns))) + '\n'
return summary
if __name__ == '__main__':
demo_result = {'rows': [[42]], 'columns': ['count']}
print(format_results(demo_result, 'How many users signed up?'))
demo_result2 = {'rows': [], 'columns': ['id']}
print(format_results(demo_result2, 'Any orders today?'))
NL'den SQL'e Neden Zordur: Belirsizlik
Belirsizlik en büyük zorluktur. Şunu düşünün: "En iyi müşterileri göster."
- Gelire göre mi? Sipariş sayısına göre mi? Yeniliğe göre mi?
- Geçen aya göre mi? Tüm zamanlara göre mi?
- En iyi 10 mu? En iyi 100 mü?
İnsanlar bağlamı anlar; LLM'ler varsayımlarda bulunur. Ajanların belirsiz soruları ele almak veya netleştirmek için stratejilere ihtiyacı vardır.
AMBIGUITY_PROMPT = '''If the question is ambiguous, respond with JSON:
{"needs_clarification": true, "question": "your clarifying question"}
If clear, respond with the SQL query directly.
User question: {question}
'''
def generate_or_clarify(question, schema):
response = llm_call(AMBIGUITY_PROMPT.format(
question=question, schema=schema
))
if '"needs_clarification"' in response:
import json
return json.loads(response)
return {'sql': response}NL'den SQL'e Neden Zordur: Şema Boyutu
Kurumsal veritabanlarında yüzlerce tablo ve binlerce sütun bulunabilir. Şemanın tamamını eklemek LLM'nin bağlam penceresini aşar.
Çözümler arasında şema araması (tablo açıklamalarını temsil olarak ekleyip ilgili olanları getirme), tablo filtreleme (önce LLM'ye hangi tabloların gerektiğini sorma) ve şema sıkıştırma (indeks ve denetim sütunlarını çıkarma) bulunur.
# Two-phase approach for large schemas
def get_relevant_tables(question, all_tables):
prompt = f'''Given these tables: {all_tables}
Which 3-5 tables are most relevant to answer: "{question}"?
Return a JSON list of table names only.'''
response = llm_call(prompt)
import json
return json.loads(response)
def nl_to_sql_large_db(question, conn):
all_tables = list_all_tables(conn) # just names
relevant = get_relevant_tables(question, all_tables)
schema = get_schema_for_tables(conn, relevant)
return llm_generate_sql(question, schema)NL'den SQL'e Neden Zordur: SQL Lehçesi Farklılıkları
SQL evrensel değildir. PostgreSQL/MySQL'deki LIMIT, SQL Server'da TOP hâline gelir. Tarih işlevleri veritabanları arasında farklılık gösterir. LLM hangi lehçeyi kullanacağını bilmelidir.
Sistem isteminize her zaman hedef lehçeyi ekleyin ve az örnekli istem kullanımına lehçeye özel örnekler eklemeyi düşünün.
DIALECT_EXAMPLES = {
'postgresql': 'Use LIMIT for row limits. Use NOW() for current time.',
'mysql': 'Use LIMIT for row limits. Use NOW() for current time.',
'sqlite': 'Use LIMIT. Use datetime("now") for current time.',
'mssql': 'Use TOP N for row limits. Use GETDATE() for current time.',
'bigquery': 'Use LIMIT. Use CURRENT_TIMESTAMP() for current time. Use backtick for table names.'
}
def get_dialect_hint(dialect):
return DIALECT_EXAMPLES.get(dialect.lower(), '')
if __name__ == '__main__':
for dialect in ['postgresql', 'sqlite', 'mssql']:
print(f'{dialect}: {get_dialect_hint(dialect)}')
Hata Kurtarma Döngüsü
Üretilen SQL çoğu zaman ilk denemede başarısız olur. Sağlam bir ajan bir hata kurtarma döngüsü uygular: başarısız SQL'i ve hata mesajını LLM'ye geri gönderir ve sorguyu düzeltmesini ister.
Düzeltilemeyen sorgularda sonsuz döngüye girmemek için yeniden denemeleri 2-3 ile sınırlayın.
def nl_to_sql_with_retry(question, schema, conn, max_retries=3):
sql = llm_generate_sql(question, schema)
for attempt in range(max_retries):
result = execute_query(conn, sql)
if 'error' not in result:
return format_results(result, question)
# Ask LLM to fix the error
fix_prompt = f'The SQL query failed with error: {result["error"]}\n'\
f'Original SQL: {sql}\n'\
f'Please fix the SQL query.'
sql = llm_call(fix_prompt)
print(f'Retry {attempt + 1} with fixed SQL')
return 'Could not generate a valid query after retries.'Tümünü Birleştirme
Üretime hazır bir NL'den SQL'e ajan tüm parçaları birleştirir: şema getirme, istem oluşturma, SQL üretimi, doğrulama, çalıştırma, hata kurtarma ve sonuçları biçimlendirme.
Sorgu önbelleğe alma eklemek (aynı soru → aynı SQL), tekrarlanan sorgularda gecikmeyi ve LLM maliyetlerini önemli ölçüde azaltır.
import hashlib
query_cache = {}
def cached_nl_to_sql(question, schema_hash, conn):
cache_key = hashlib.md5((question + schema_hash).encode()).hexdigest()
if cache_key in query_cache:
print('Cache hit!')
sql = query_cache[cache_key]
else:
schema = get_schema(conn)
sql = llm_generate_sql(question, schema)
query_cache[cache_key] = sql
result = execute_query(conn, sql)
return format_results(result, question)Bilgi Kontrolü
NL'den SQL'e ajan işlem hattındaki adımların doğru sırası nedir?
Özet: NL'den SQL'e Mimari
NL'den SQL'e ajanlar, doğal dildeki soruları yapılandırılmış bir işlem hattı aracılığıyla çalıştırılabilir SQL sorgularına dönüştürür: şemayı ekle → SQL üret → çalıştır → biçimlendir → döndür.
Başlıca zorluklar, kullanıcı sorularındaki belirsizlik, bağlam pencerelerini aşan büyük şema boyutları ve veritabanları arasındaki SQL lehçesi farklılıklarıdır. Hata kurtarma döngüleri, ilk çalıştırmada başarısız olan LLM üretimi SQL'i ele alır.
Sıkça Sorulan Sorular
“NL'den SQL'e Aracılar Nasıl Çalışır” dersi ücretsiz mi?
Evet — “NL'den SQL'e Aracılar Nasıl Çalışır” 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.
“NL'den SQL'e Aracılar Nasıl Çalışır” dersinde ne öğreneceğim?
Şema enjeksiyonu, sorgu oluşturma, yürütme ve sonuç biçimlendirme. 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 1. dersidir.
“NL'den SQL'e Aracılar Nasıl Çalışır” 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
- NL'den SQL'e Aracılar Nasıl Çalışır
- Şema Anlama ve Enjeksiyonu
- SQL Sorguları Oluşturma ve Doğrulama
- Belirsiz Veritabanı Sorularını Ele Alma