يقوم هذا البرنامج التعليمي بإنشاء وكيل مع استدعاء الوظائف حيث لا تقوم الأداة المعرضة للنموذج أبدًا بتنفيذ SQL عشوائي. فهو يجمع بين آليتين تم التحقق منهما بالفعل في كود Aurabase: مدقق NL2SQL ومعاملة Postgres للقراءة فقط، وهما قالبان من الذكاء الاصطناعي الأصليمدمجان في الواجهة الخلفية. المتطلبات الأساسية: مشروع Aurabase، ومفتاح service_roleالخاص به، وحساب مع أحد موفري LLM الأصليين الثلاثة (OpenAI، وAnthropic، وGemini).
الأساسيات
- الخطر الحقيقي ليس استدعاء الوظيفة نفسها، ولكن الأداة المكشوفة للنموذج:
execute_sql(query)الخام يمنحها وصولاً كاملاً إلى SQL. - تعرض البنية الآمنة أداة
query_database(question)التي تفوض إلى مدقق شجرة بناء الجملة (SELECT فقط، LIMIT محدود، مخطط معزول) بدلاً من التنفيذ المباشر. - يعرض Aurabase أداة التحقق هذه محليًا (
/nl2sql): يؤدي إعادة استخدامها كتطبيق للأداة إلى تجنب الاضطرار إلى إعادة ترميز التحقق من صحة SQL بنفسك. - يتم بعد ذلك تنفيذ SQL الملتزم من خلال
aura.db.sql()في وضعreadOnly: true، وهي معاملة Postgres فعلية للقراءة فقط، وليست مرشحًا نصيًا بسيطًا. - لا تقبل نقطة نهاية
/chatالأصلية لـ Aurabase بعد دورًاtoolولا معلمةtools(تم التحقق منها في الكود): يتم تشغيل حلقة الوكيل حاليًا عبر SDK الخاص بموفر LLM، وليس عبر وكيل Aurabase. - يتجاوز المفتاح
service_roleRLS حسب التصميم: يجب ألا يغادر الواجهة الخلفية لديك أبدًا، ويرث الوكيل وصولاً أوسع من المستخدم المعتمد النموذجي.
ماذا ستبني
ستقوم بإنشاء وكيل يجيب على أسئلة اللغة الطبيعية المتعلقة بالبيانات في مشروع Postgres، دون السماح للنموذج بكتابة SQL الذي يتم تنفيذه كما هو. يستدعي النموذج أداة اسمها query_database، تقوم هذه الأداة بترجمة السؤال إلى SQL تم التحقق من صحته عبر NL2SQL، ثم تنفذ SQL للقراءة فقط وتعيد الأسطر إلى النموذج بحيث يقوم بصياغة إجابته.
يستخدم هذا البرنامج التعليمي @aurabase/aurabase-js JavaScript SDK على جانب الخادم (ليس من جانب المتصفح أبدًا، يجب ألا يتم عرض المفتاح service_role للعميل) ووظيفة OpenAI التي تستدعي واجهة برمجة التطبيقات لحلقة الوكيل. ينطبق نفس المبدأ على Anthropic أو Gemini SDK.
لماذا تعتبر أداة "تشغيل SQL هذه" خطيرة
تحدد معظم البرامج التعليمية لوكلاء Postgres، بما في ذلك بعض الأدلة الرسمية، أداة واحدة: دالة execute_sql التي تأخذ سلسلة SQL كوسيطة وتنفذها كما هي. يكتب النموذج هذه السلسلة بنفسه، بناءً على سؤال المستخدم والمخطط المعطى له في السياق.
ينقل هذا الاختيار مسؤولية إلى النموذج لا يمكنه الوفاء بها بشكل موثوق. يمكن أن يؤدي الحقن الفوري في السؤال إلى إنتاج SQL مدمر تنفذه الأداة بشكل عشوائي، نظرًا لعدم وجود مفهوم حول الشكل الذي يجب أن يبدو عليه الاستعلام "المشروع". توضح مقالتنا المخصصة تفاصيل ناقل الهجوم هذا: تأمين NL2SQL ضد حقن SQL.
يكشف البديل المضمن في هذا البرنامج التعليمي عن أداة أضيق، query_database(question). لم يعد النموذج قادرًا على كتابة SQL مباشرة: يمكنه فقط طرح سؤال في استدعاء الأداة الخاص به. إنه محرك Aurabase NL2SQL الذي يترجم هذا السؤال إلى SQL، قبل تمريره عبر أداة التحقق من صحة الشجرة النحوية (حدد وحده، لا توجد استعلامات فرعية، عشر وظائف معتمدة، LIMIT محدود).
تمنح أداة execute_sql(query: string) النموذج وصولاً كاملاً إلى SQL، بغض النظر عن مدى جودة مطالبة النظام لديك. تظل التعليمات ("تنفيذ التحديدات فقط") بمثابة تعليمات يمكن للنموذج اتباعها أو إساءة تفسيرها أو رؤيتها يتم التحايل عليها عن طريق حقنة تم إدخالها في سؤال المستخدم.
تحديد مخطط الأداة المكشوفة للنموذج
يقبل مقدمو خدمات LLM الثلاثة الأصليون في Aurabase (OpenAI وAnthropic وGemini) جدول تعريفات الأدوات بتنسيق مخطط JSON. أداة واحدة تكفي لهذا الوكيل: query_database، والتي تجيب على السؤال باللغة الطبيعية ولا شيء غير ذلك. لا يرى النموذج مخطط SQL ولا حقل query الذي يمكنه ملؤه بنفسه.
قم بتنفيذ الأداة: NL2SQL ثم للقراءة فقط
يعمل معالج الأداة على الواجهة الخلفية لديك، وليس في المتصفح أبدًا. إنه يحمل مفتاح المشروع service_role، الذي يتجاوز RLS حسب التصميم وبالتالي لا ينبغي أبدًا كشفه للعميل. يقوم بإجراء مكالمتين إلى Aurabase SDK.
الاستدعاء الأول يترجم السؤال إلى SQL تم التحقق من صحته عبر aura.ai.nl2sql(): SELECT فقط، LIMIT محدود، لا يمكن الوصول إلى كتالوج النظام. الثاني ينفذ SQL هذا الذي تم التحقق من صحته بالفعل عبر aura.db.sql()، مع خيار readOnly: true: ثم يرفض Postgres نفسه أي كتابة في هذه المعاملة، بشكل مستقل عن التحقق النصي المطبق بالفعل بواسطة NL2SQL المنبع.
readOnly: true يطلق معاملة Postgres حقيقية للقراءة فقط: يرفض المحرك الكتابة، ولا يتم تطبيق مرشح على نص الطلب. بالاشتراك مع التحقق من صحة التحديد فقط في NL2SQL، يحتوي الوكيل على طبقتين مستقلتين: إذا كان في إحداهما عيب، فإن الأخرى لا تزال قائمة.
حلقة الوكيل: استدعاء الوظيفة على جانب SDK الخاص بالمورد
تعرض Aurabase ثلاثة موفري LLM أصليين، لكن نقطة النهاية /chat الخاصة بها لا تقوم بعد بترحيل معلمة tools أو دور tool. ChatOptions يحمل فقط temperatureو max_tokens و model، وتقتصر الأدوار المقبولة على systemو user و assistant (تم التحقق منها في llm/mod.rs و handlers/chat.rs). وبالتالي، يتم تشغيل حلقة استدعاء الوظائف اليوم مباشرةً عبر SDK الخاص بالموفر، وليس عبر وكيل Aurabase.
طالما أن Aurabase لا يقوم بتنسيق استدعاءات الأدوات بشكل أصلي، فيجب أن تدير الواجهة الخلفية لديك الحلقة نفسها باستخدام OpenAI أو Anthropic أو Gemini SDK. يظل تنفيذ NL2SQL وSQL هو استدعاءات Aurabase الكلاسيكية داخل هذه الحلقة.
يظل المبدأ كما هو إذا قمت بتنسيق الوكيل مع LangChain أو خدمة مثل Azure AI Agent: يجب أن تظل الأداة المعلنة في إطار العمل كما هي query_database، وليس منفذ SQL أوليًا أبدًا. تفاصيل المقارنة الخاصة بنا حيث يوفر LangChain وLlamaIndex قيمة حقيقية على Postgres، وحيث يضيفان تعقيدًا بشكل خاص: وكلاء Postgres مع LangChain أو LlamaIndex.
اختبار مع سؤال حقيقي
تم إرسال السؤال إلى الوكيل: "كم عدد العملاء المميزين الذين قدموا طلبًا هذا الشهر؟" ". يستدعي القالب query_database مع هذا السؤال كما هو، دون رؤية أو كتابة أي SQL. إليك نتيجة الاستدعاءين الداخليين اللذين أطلقتهما الأداة.
تعتمد الإجابة النهائية للنموذج على هذه الخطوط الفعلية، وليس على التخمين. إذا قامت الأداة بإرجاع صفر صفوف، يصبح احتمال الهلوسة الرقمية أقل بكثير من النموذج الذي قد يستجيب بدون بيانات تم التحقق منها.
تأمين الوكيل قبل الدخول في الإنتاج
- لا يترك المفتاح
service_roleالواجهة الخلفية لديك أبدًا: لا في الموجه المرسل إلى النموذج، ولا في السجل، ولا في متغير البيئة من جانب العميل. - يظل
readOnly: trueنشطًا علىaura.db.sql()لهذه الأداة المحددة، حتى إذا كان مشروعك يحتاج إلى الكتابة في مكان آخر في التطبيق. service_roleيتجاوز RLS حسب التصميم. إذا كان يجب على الوكيل الاستجابة بشكل مختلف اعتمادًا على المستخدم الذي يطرح السؤال، فقم بالتصفية بشكل صريح في SQL أو ارجع إلى نقاط نهاية PostgREST الكلاسيكية، التي تحترم RLS. راجع عزل RLS متعدد المستأجرين.- تسجيل كل استدعاء للأداة (السؤال المطروح، التحقق من صحة SQL، عدد الأسطر): هذا هو التتبع الوحيد القابل للاستخدام إذا أدى السؤال إلى نتيجة غير متوقعة.
- يتم تطبيق حد معدل Aurabase والحصة الشهرية بالفعل لكل مشروع على
/nl2sql: لا يمكن للوكيل الثرثار أن يتجاوز ميزانية الذكاء الاصطناعي الخاصة بك بصمت.
الحدود الحالية التي يجب أن تكون على علم بها
ترث أداة query_database جميع قيود مدقق NL2SQL: لا توجد استعلامات فرعية، ولا CTE/WITH، ولا UNION، وقائمة مغلقة من عشر وظائف SQL. السؤال الذي يستدعي بشكل طبيعي استعلامًا فرعيًا ("العملاء الذين لم يطلبوا مطلقًا") يجب إعادة صياغته أو معالجته بواسطة أداة مخصصة ثانية بدلاً من فرضه على NL2SQL.
لا يوجد تنسيق لاستدعاءات الأدوات اليوم داخل وكيل Aurabase /chat: حلقة الوكيل الموضحة هنا موجودة في كود التطبيق الخاص بك، وليس في خدمة مُدارة. إذا كان يتعين على الوكيل ربط عدة أدوات (قاعدة بيانات ووثائق RAG، على سبيل المثال)، فإن الواجهة الخلفية لديك هي التي تنظم المكالمتين.
RAG واستدعاء الوظيفة مدمجان
يغطي هذا البرنامج التعليمي أسئلة منظمة حول البيانات العلائقية. بالنسبة للأسئلة حول المحتوى غير المنظم (المستندات، التذاكر، الملاحظات)، يمكن لنفس الوكيل الكشف عن أداة ثانية متصلة بـ RAG الأصلي لـ Aurabase (pgvector، بحث HNSW). تم تفصيل الإمكانيتين والتعبير عنهما على صفحة Native AI على Postgres.