Memahami dan Menyuntik Skema
Mengekstrak dan memformat skema DB untuk konteks LLM: jadual, lajur dan hubungan.
Memahami dan Menyuntik Skema ialah pelajaran Ejen AI percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Ejen AI, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Ejen AI merangkumi sejumlah 4 pelajaran.
Mengapa Konteks Skema Penting
LLM mengetahui sintaks SQL tetapi tidak mengetahui apa-apa tentang pangkalan data anda. Tanpa konteks skema, LLM akan mereka-reka nama jadual dan lajur.
Penyisipan skema bermaksud mengekstrak struktur pangkalan data anda secara programatik dan menyertakannya dalam setiap arahan — supaya LLM mengetahui jadual, lajur dan jenis data anda yang tepat.
Membuat Pertanyaan pada INFORMATION_SCHEMA
Semua pangkalan data hubungan utama mendedahkan metadata melalui INFORMATION_SCHEMA. Anda boleh membuat pertanyaan padanya untuk mendapatkan setiap jadual, nama lajur dan jenis data tanpa menyentuh kod aplikasi.
Kaedah ini berfungsi dalam PostgreSQL, MySQL, SQL Server dan SQLite (dengan perbezaan kecil).
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()Mengumpulkan Lajur Mengikut Jadual
Hasil mentah INFORMATION_SCHEMA ialah senarai baris rata. Kumpulkan baris tersebut mengikut nama jadual untuk membina perwakilan berstruktur yang lebih mudah diformatkan ke dalam arahan.
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'}]
# }Memformatkan Skema untuk Arahan LLM
LLM membaca skema sebagai teks biasa. Gunakan format yang ringkas dan mudah dibaca: satu jadual bagi setiap baris dengan nama lajur dan jenis dalam kurungan.
Menyertakan kunci utama (PK) dan kunci asing (FK) membantu LLM menulis pernyataan JOIN yang betul.
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))
Menyertakan Kunci Utama dan Kunci Asing
Hubungan kunci asing ialah bahagian paling penting dalam konteks skema — hubungan ini memberitahu LLM cara menulis JOIN. Buat pertanyaan pada information_schema.table_constraints dan key_column_usage untuk mengekstraknya.
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}')
Pemampatan Skema: Masalahnya
Pangkalan data perusahaan sebenar mungkin mempunyai lebih daripada 200 jadual. Jika anda menyisipkan keseluruhan skema, anda akan melebihi tetingkap konteks GPT-4 dan membazirkan wang untuk token.
Skema dengan 200 jadual dan 20 lajur setiap satu mempunyai kira-kira 40,000+ token — terlalu mahal untuk dihantar bagi setiap pertanyaan.
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 limitPemampatan Skema: Penyisipan Terpilih
Strategi pemampatan yang paling berkesan: hanya sisipkan jadual yang berkaitan dengan soalan. Gunakan pendekatan dua fasa — mula-mula tanya LLM jadual yang diperlukan, kemudian sisipkan skema jadual tersebut sahaja.
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}Pemampatan Skema: Mengecualikan Lajur Tidak Diperlukan
Banyak jadual mempunyai lajur audit seperti created_at, updated_at, deleted_at, version, created_by yang jarang berkaitan dengan pertanyaan perniagaan. Buang lajur tersebut untuk mengurangkan bilangan token.
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']])
Menambah Penerangan Jadual
Nama lajur sahaja tidak semestinya cukup jelas. Menambah penerangan dalam bahasa semula jadi tentang perkara yang diwakili oleh setiap jadual meningkatkan kualiti penjanaan SQL dengan ketara.
Simpan penerangan dalam fail konfigurasi atau sebagai ulasan jadual PostgreSQL.
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))
Penyimpanan Skema dalam Cache
Skema pangkalan data jarang berubah. Mendapatkan INFORMATION_SCHEMA bagi setiap pertanyaan menambah kependaman dan beban. Simpan rentetan skema berformat dalam cache dan batalkan cache apabila berlaku peristiwa perubahan skema atau selepas TTL berasaskan masa.
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)Aliran Penyisipan Skema Lengkap
Menggabungkan semua teknik: cache skema termampat, sisipkannya ke dalam gesaan sistem, dan gunakan penapisan jadual terpilih untuk pangkalan data yang besar.
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 systemSemakan Pengetahuan
Bilakah anda patut menggunakan penyisipan jadual terpilih berbanding menyisipkan skema lengkap?
Imbas Kembali: Pemahaman dan Penyisipan Skema
Penyisipan skema yang berkesan ialah asas kepada ejen NL-ke-SQL yang boleh dipercayai. Ekstrak struktur daripada INFORMATION_SCHEMA, sertakan hubungan kunci utama dan kunci asing, dan formatkan sebagai teks padat untuk LLM.
Untuk pangkalan data yang besar: cache skema, buang lajur audit, dan gunakan penyisipan terpilih supaya hanya jadual yang berkaitan dengan setiap soalan dihantar. Penerangan jadual dalam bahasa semula jadi turut meningkatkan kualiti pertanyaan.
Pelajari Ejen AI dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 60
- Pelajaran
- 239
Soalan Lazim
Adakah pelajaran “Memahami dan Menyuntik Skema” percuma?
Ya — teks penuh “Memahami dan Menyuntik Skema” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Ejen AI, tingkat taraf kepada CoddyKit PRO. Kursus Ejen AI merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Memahami dan Menyuntik Skema”?
Mengekstrak dan memformat skema DB untuk konteks LLM: jadual, lajur dan hubungan. Anda berlatih Ejen AI menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Ejen AI?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Ejen AI di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Memahami dan Menyuntik Skema” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Ejen AI ini?
Ya. Setiap pelajaran Ejen AI menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Cara Ejen NL-ke-SQL Berfungsi
- Memahami dan Menyuntik Skema
- Menjana dan Mengesahkan Pertanyaan SQL
- Mengendalikan Soalan Pangkalan Data yang Kabur