تصور کنید یک مهندس پشتیبانی از چتبات میپرسد تعداد پرداختهای ناموفق شرکتهای سازمانی چندتاست، اما هوش مصنوعی با اطمینان عددی غلط میدهد چون حدس زده مقدار ستون 'failed' است، در حالی که در دیتابیس از کلمه 'declined' استفاده شده است. این شکست رایج در سیستمهای تبدیل متن به SQL، ناشی از ضعف در تولید کد نیست، بلکه به دلیل نبود زمینه (Context) دقیق درباره محتوای واقعی پایگاه داده است. مدل ممکن است حدس بزند که دادههای «سازمانی» در یک جدول خاص قرار دارند، در حالی که در واقعیت، این دادهها سه Join دورتر و درون یک فیلد JSONB به نام metadata.plan.tier قرار گرفتهاند. چون پرسوجو بدون خطا اجرا میشود و ردیفهایی را برمیگرداند، کاربر تصمیمی را بر اساس عددی میگیرد که هرگز درست نبوده است.
همانطور که در تحلیل قبلی ما دربارهی فقدان شهود خلاق در مدلهای زبانی بزرگ اشاره کردیم، شکاف میان ساختار دیتابیس و معنای واقعی دادهها همچنان یک مانع جدی برای عاملهای هوشمند است. این چالش دقیقاً همان نقطهای است که مدلهای SQRL با بازبینی پیشفرض دادهها تلاش کردند تا دقت تبدیل متن به SQL را افزایش دهند. اکثر توسعهدهندگان صرفاً خروجی خام طرح (Schema) را به پرامپت میدهند؛ یعنی لیستی از نام ستونها که مقادیر واقعی، وضعیتهای دستهبندیشده و مسیرهای پنهان در فیلدهای JSONB را نادیده میگیرد. برای یک سیستم سازمانی با ۵۰۰ جدول و ۶۰۰۰ ستون، یک Dump کامل میتواند به دهها هزار توکن برسد. این حجم از داده پنجره متنی (Context Window) — مثل میز کاری که جا برای چند ورق دارد، نه برای کل کتابخانه — را پر میکند و با اجبار مدل به جستوجو در صدها جدول بیربط، فعالانه دقت را کاهش میدهد.
در ۱۶ اوت ۲۰۲۶، تیم توسعه dbctx یک ابزار متنباز با زبان Go منتشر کرد که دیتابیس را مانند کد منبعی میبیند که باید کامپایل شود. dbctx بهجای بازرسی مداوم دیتابیس در هر درخواست، به PostgreSQL متصل شده، دادههای واقعی را نمونهبرداری میکند و نتایج را در یک فایل SQLite قابل حمل به نام .dtx ذخیره میکند.

به نقل از گزارش dev.to، این ابزار سه لایه درک متنی ایجاد میکند تا مدل زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن جواب میدهد — نقشهای دقیق از دادهها داشته باشد:
- لایه ساختاری: ثبت موارد پایه شامل جداول، ستونها، انواع داده، کلیدهای اصلی، کلیدهای خارجی و ایندکسها. این خروجی استاندارد هر ابزار بازرسی (Introspection) است.
- لایه مشتقشده: نوآوری اصلی اینجاست. این لایه فیلدهای «وضعیتگونه» (ستونهایی با کمتر از ۱۰۰ مقدار متمایز) و مقادیر نماینده را از
pg_statsشناسایی میکند. همچنین ساختار داخلی ستونهای JSONB را از طریق نمونهبرداری از ردیفها برای استنتاج انواع دادهها (Type Inference) نقشهبرداری میکند. این لایه فاصله بین «دانستن وجود ستون» و «دانستن محتوای واقعی آن» را پر میکند. - لایه بازیابی: پیادهسازی ایندکس تماممتن (Full-text index)، یک ایندکس معنایی محلی اختیاری، یک لغتنامه اصطلاحات اختیاری و منطقی برای گسترش نتایج از طریق کلیدهای خارجی تا ایندکس در زمان تولید پرامپت در میلیثانیهها قابل پرسوجو باشد.

ستونهای JSONB اغلب منطقهای حیاتی کسبوکار، مانند سطوح پلن (Plan Tiers) یا سطوح شدت خطا (Severity Levels) را پنهان میکنند که در خروجیهای استاندارد Schema Dump دیده نمیشوند. یک Dump استاندارد تنها یک خط را نشان میدهد — metadata jsonb — اما این تک خط میتواند دهها مسیر متمایز را پنهان کند. در دیتابیس تولیدی LiveReview که برای تست استفاده شد، یک ستون متادیتا حاوی ۳۱ مسیر متمایز بود.
dbctx این مشکل را با یک فرآیند نمونهبرداری قطعی (Deterministic) حل میکند:
- جداول کوچک (کمتر از ۵۰۰۰ ردیف): استفاده از دستور ساده
LIMIT 50. - جداول بزرگ: استفاده از
TABLESAMPLE BERNOULLIبا درصدی که با رشد جدول کاهش مییابد (مثلاً در یک جدول میلیونی، حدود ۰.۰۵٪ نمونهبرداری شده و تقریباً ۵۰۰ ردیف بررسی میشود). - فیلترهای ایمنی: هر پرسوجوی نمونهبرداری، اسناد بزرگتر از ۱۰ کیلوبایت را فیلتر میکند تا از توقف فرآیند ساخت به دلیل وجود Blobهای غولپیکر و پرت (Outlier) جلوگیری شود.
- پردازش موازی: عملیات در چهار goroutine موازی اجرا میشود و در یک تراکنش واحد SQLite قرار میگیرد تا تضمین شود ایندکس هرگز به صورت نیمهکاره رها نمیشود.

این سازوکار باعث میشود ابزار متوجه شود یک ستون متادیتا دارای مسیری مثل $.review_result.comments[].Severity با مقادیر 'info' و 'warning' و 'critical' است. همچنین تداخلات نوع داده را با شمارش رایجترین نوع در نمونهها مدیریت میکند؛ مثلاً اگر $.discount در ۹۸٪ ردیفها عدد باشد، به عنوان عدد گزارش میشود. با ارائه این مقادیر واقعی، مدل دیگر نیازی به حدس زدن رشتههای وضعیت ندارد و نرخ توهم (Hallucination) — وقتی مدل با اطمینان چیزی میگوید که وجود ندارد، شبیه دوستی که خاطرهای را اشتباه تعریف میکند — بهشدت کاهش مییابد. این رویکرد در واقع نوعی اعتبارسنجی سختگیرانه برای حذف توهمات پارامتری است که در سیستمهای بازیابی دادههای حساس، حیاتیترین نقش را ایفا میکند.
برای حل مشکل تفاوت اصطلاحات (مثلاً وقتی کاربر میگوید «خریداران» اما در دیتابیس ستون customers وجود دارد)، dbctx از یک سیستم امتیازدهی ترکیبی استفاده میکند. جستوجوی لکسیکال (واژگانی) به تنهایی اگر تطابق رشتهای مستقیم نباشد، مجموعهای از صفرها را برمیگرداند. برای پر کردن این شکاف، dbctx از یک لایه معنایی محلی با مدل BGE-small-en-v1.5 بهره میبرد.
این مدل حدود ۱۰۰۰ برابر کوچکتر از یک LLM معمولی است (حدود ۳۳ میلیون پارامتر و ۳۸۴ بُعد) و کاملاً روی CPU بدون نیاز به API Key اجرا میشود. فایل مدل حدود ۱۳۳ مگابایت است و در اولین استفاده در مسیر ~/.dbctx دانلود میشود. در زمان ساخت، dbctx خلاصههای متنی کوتاه برای هر جدول، ستونهای معنادار (وضعیتگونه، دستهبندیشده یا کلیدهای خارجی) و مسیرهای قابل توجه JSONB را به بردارها (Vectors) تبدیل میکند.
در زمان پرسوجو، سیستم Embedding سؤال را با این بردارها با استفاده از اسکن شباهت کسینوسی (Cosine Similarity) مقایسه میکند. این ابزار از ایندکسهای تقریبی نزدیکترین همسایه (ANN) اجتناب میکند چون جستوجوی Brute Force برای تعداد اشیاء یک Schema به اندازه کافی سریع است. امتیاز نهایی با ترکیب امتیاز لکسیکال و امتیاز معنایی نرمالشده با فرمول زیر محاسبه میشود:final_score = lexical_score + 0.6 × normalized_semantic_score × strongest_lexical_score_in_results
این فرمول تضمین میکند که تطبیقهای دقیق شناسهها همچنان برنده باشند، در حالی که مترادفها نیز نمایش داده شوند. برای مثال، اگر یک پرسوجو امتیاز لکسیکال «orders» را ۴۰ و امتیاز معنایی آن را ۰.۹ ثبت کند، امتیاز نهایی ۶۱.۶ میشود. یک جدول مرتبط مثل «purchases» با امتیاز معنایی ۰.۴، منجر به امتیاز ۹.۶ میشود؛ یعنی نمایش داده میشود اما رتبه بالاتری از تطبیق دقیق نمیگیرد. اگر جستوجوی لکسیکال هیچ نتیجهای نیابد، ضریب مقیاس به ۱.۰ برمیگردد تا تطبیقهای معنایی واقعی بتوانند ظاهر شوند.
بر اساس بررسیهای فنی، در تست روی دیتابیس تولیدی با ۶۰ جدول، ۷۵۸ ستون و ۹۷ کلید خارجی، کل فرآیند ساخت تقریباً ۱۲ ثانیه زمان برد. تحلیل زمانها نشان میدهد ۵۳.۱٪ از این مدت (۶.۵ ثانیه) صرف تحلیل JSONB شده است، سپس تحلیل فیلدها (۳.۲ ثانیه) و استخراج طرح (۲.۵ ثانیه) قرار دارند. فایل نهایی .dtx تنها ۴۴۸ کیلوبایت بود که بهراحتی در Git ذخیره یا در اسلک ارسال میشود.

برای محیطهای عملیاتی، dbctx یک کتابخانه Go ارائه میدهد که اجازه میدهد ایندکس مستقیماً در سرویسها جاسازی شود. این سیستم از ساخت BuildAsync برای جلوگیری از مسدود شدن زمان استارتآپ پشتیبانی میکند که بلافاصله یک Index و یک کانال برای اعلام اتمام کار برمیگرداند. همچنین یک API به نام ResultSet ارائه میدهد تا توسعهدهنده بتواند با متدهایی مثل Include()، Exclude() و ScoredOnly() فیلتر کند که کدام جداول به LLM ارسال شوند.
این قابلیت اجازه میدهد سیستم یک طرح فشرده و مبتنی بر نمادگذاری (Notation) برگرداند که مدل زبانی از طریق یک راهنما (Legend) یاد میگیرد آن را بخواند. این نمادها عبارتند از:
PK: کلید اصلیcol → table: کلید خارجی^: نشانگر کلید اصلی?: مقدار پذیرای Null>target FK: کلید خارجی هدف[state]: فیلد دستهبندیشده وضعیتگونه (کمتر از ۱۰۰ مقدار متمایز)[cat]: فیلد دستهبندیشده{a, b, c}: مقادیر نماینده ازpg_stats$.path type {samples}: مسیر JSONB با نوع استنتاج شده(score: X.XX): امتیاز ارتباط از تطبیق پرسوجو
در یک تست برای «طرح اشتراک صورتحساب» (billing subscription plan)، ابزار dbctx جدول اشتراکها و کلیدهای خارجی آن به کاربران و سازمانها را شناسایی کرد و حدود ۳۰ ستون را برگرداند. این یعنی مدل زبانی سؤال را با استفاده از کمتر از ۴٪ کل دیتابیس پاسخ داد، در حالی که ۹۶٪ باقیمانده هرگز خوانده نشد.
علاوه بر این، یک قابلیت وارد کردن لغتنامه برای اصطلاحات داخلی شرکتها (مثلاً تبدیل LOC به lines_of_code) تعبیه شده است. این لغتنامه به عنوان سومین سیگنال مستقل در نظر گرفته میشود. کاربران میتوانند:
۱. با دستور dbctx terminology prompt پرامپتی حاوی طرح واقعی ایجاد کنند.
۲. از یک LLM مثل Claude یا GPT-4 برای ساخت یک نقشه JSON از اصطلاحات (مثلاً نگاشت "loc" به metrics.loc) استفاده کنند.
۳. فایل JSON بازبینی شده را از طریق dbctx terminology import به فایل .dtx وارد کنند.
dbctx هنگام وارد کردن، هر نگاشت را با طرح واقعی دیتابیس اعتبارسنجی میکند؛ بنابراین نام جدولهای توهمی رد میشوند. این لغتنامه به عنوان یک سیگنال بازیابی عمل میکند و به سیستم کمک میکند جداول درست را بدون اضافه کردن حتی یک توکن (Token) — تکههای کوچکی از متن، شبیه برشهای کیک که مدل تکهتکه میخورد — به پرامپت نهایی اضافه کند و پنجره متنی را خلوت و هزینهها را پایین نگه دارد.
با تبدیل فایل .dtx به یک آرتیفکت ساخت (Build Artifact)، تیمها میتوانند زمینه دیتابیس را در خط لولههای CI/CD ادغام کنند. چون این یک فایل SQLite ساده است، میتوان آن را با هر کلاینت SQLite بازرسی کرد یا با ابزارهایی مثل sqldiff مقایسه کرد. اگرچه در حال حاضر حالت ساخت افزایشی (Incremental Build) وجود ندارد و با تغییر طرح باید کل فرآیند تکرار شود، اما زمان ساخت ۱۲ ثانیهای برای اکثر طرحها ناچیز است.
این تغییر رویکرد، صنعت را از «مهندسی پرامپت» به سمت «مهندسی زمینه» (Context Engineering) میبرد؛ جایی که دانش هوش مصنوعی بهجای حدسهای احتمالی، بر اساس نمونههای واقعی دادهها مبنیسازی (Grounding) میشود و جداسازی بازیابی طرح از تولید SQL، یک خط لوله قطعی و تکرارپذیر ایجاد میکند.
تحلیل عملکرد در اعداد
برای تجسم کارایی، معیارهای زیر از دیتابیس تولیدی ۶۰ جدولی، سرعت سیستم را نشان میدهد:
- تأخیر پرسوجو (Query Latency): یک پرسوجوی متوسط حدود ۱۰۰ میلیثانیه زمان میبرد. پرسوجوهای صرفاً لکسیکال در حدود ۷ میلیثانیه و پرسوجوهای ترکیبی (لکسیکال + معنایی) در حدود ۷.۶ میلیثانیه اجرا میشوند (افزایش ۹٪). فراخوانی Embedding حدود ۱۶ میلیثانیه زمان میبرد.
- سربار مدل: بارگذاری مدل BGE در حافظه حدود ۲۴۰ میلیثانیه هزینه دارد که تنها یک بار در هر پروسه پرداخت میشود.
- کارایی ساخت: زمان کل ساخت حدود ۱۲ ثانیه است که بخش اصلی آن مربوط به تحلیل JSONB (۶.۵ ثانیه) و تحلیل فیلدها (۳.۲ ثانیه) است. استخراج طرح ۲.۵ ثانیه زمان میبرد. سایر مراحل شامل اتصال (۰.۱ میلیثانیه)، ذخیرهسازی (۱۱ میلیثانیه) و FTS (۴۹ میلیثانیه) است.
یکپارچهسازی و معماری
برای توسعهدهندگان Go، این کتابخانه طوری طراحی شده که مستقیماً در سرویسها جاسازی شود. تابع Open اجازه میدهد یک فایل .dtx پیشساخته از دیسک بارگذاری شود و اتصال به دیتابیس را کاملاً حذف کند؛ این حالت برای فایلهایی که در CI ساخته شده و همراه با باینری ارسال میشوند، ایدهآل است.
یک تصمیم طراحی حیاتی، جداسازی لایه معنایی است. هسته لکسیکال کاملاً بدون CGO باقی مانده است. چون لایه معنایی به ONNX Runtime نیاز دارد، پشت یک اینترفیس به نام SemanticScorer پنهان شده است. اگر این لایه بارگذاری نشود یا درخواست نشود، سیستم به بازیابی صرفاً لکسیکال بازمیگردد تا سرویس عملیاتی بماند.
توسعهدهندگان همچنین میتوانند از TextRaw() استفاده کنند تا راهنمای نمادگذاری را حذف کنند و هزینه توکنها را کاهش دهند. برای کسانی که ابزارهای سفارشی میسازند، کتابخانه توابعی مثل Tables()، TableDetail() و Stats() را برای ساخت اکسپلوررهای سفارشی و Report() برای خلاصههای متنی ساده فراهم میکند.
چرا بازیابی و تولید از هم جدا شدهاند؟
تمام موارد فوق به یک تصمیم واحد ختم میشود: یافتن بخش مرتبط از دیتابیس، مسئلهای متفاوت از نوشتن SQL است. این تفکیک مزایای طبیعی زیر را دارد:
- تکرارپذیری: ایندکس از بازرسی قطعی ساخته میشود. وضعیت و نسخه یکسان دیتابیس همیشه یک فایل .dtx یکسان تولید میکند.
- هزینه: هیچ فراخوانی API در مسیر ساخت یا پرسوجو وجود ندارد و از منابع پردازشی موجود استفاده میکند.
- شفافیت: امتیازدهی یک محاسبه ریاضی قابل مشاهده است، نه یک جعبه سیاه. شما دقیقاً میتوانید توضیح دهید چرا یک جدول گنجانده یا حذف شده است.
- قابلیت استفاده مجدد: یک فایل .dtx میتواند همزمان پشتیبان یک ابزار Text-to-SQL، یک چتبات داخلی و یک بررسی CI باشد.
با ارسال تنها حدود ۵۰ ستون مرتبط بهجای ۶۰۰۰ ستون، کار LLM هم ارزانتر و هم دقیقتر میشود. این رویکرد در هر جایی که یک سیستم هوش مصنوعی نیاز دارد بداند یک دیتابیس PostgreSQL شامل چه چیزهایی است — از رابطهای تحلیل زبان طبیعی تا عاملهای هوشمندی که دیگر نیاز ندارند در هر نوبت دیتابیس را بازرسی کنند — کاربرد دارد.
گام بعدی شما
- اگر از PostgreSQL استفاده میکنید، ابزار dbctx را برای تحلیل ساختار JSONBهای پیچیده خود امتحان کنید.
- فایلهای .dtx را در مخزن Git پروژه قرار دهید تا تغییرات طرح دیتابیس همگام با کد نسخهبندی شوند.
- برای کاهش هزینه توکنها، از نمادگذاری فشرده dbctx بهجای ارسال Schema Dumpهای حجیم استفاده کنید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو