توليد ومعالجة ردود RAG
يريد العميل معرفة أي الدواسات تناسب دراجته Mountain-500. تستخدم البحث المتجه للعثور على المنتجات ذات الصلة، وتهيئة بصيغتها JSON، وتبني تنبيه مع تعليمات التأريض. تم الانتهاء من خطوات الاسترجاع والتعزيز. الآن يأتي حرف "G" في RAG: الجيد. هذه الخطوة هي التي ترسل فيها كل شيء إلى نموذج لغوي وتحصل على إجابة.
فكر في الأمر هكذا: جمعت كل المكونات (تم استرجاع البيانات)، وحضرت الوصفة (التوجيه المعزز)، والآن تضعها في الفرن (تتصل بالنموذج) لخبز الطبق النهائي (الرد). يستخدم النموذج السياق الذي قدمته لتوليد إجابة واقعية.
استدعاء النموذج من SQL
قد تعتقد أن هذه الخطوة تتطلب ترك T-SQL وكتابة كود التطبيق. لكن SQL Server وAzure SQL Database يمكنهم استدعاء نقاط نهاية REST مباشرة باستخدام sp_invoke_external_rest_endpoint. ترسل هذه العملية المخزنة طلبات HTTPS إلى خدمات خارجية وتعيد الرد. يتم تفعيل الإجراء المخزن افتراضيا في قاعدة بيانات Azure SQL ويمكن تفعيله في SQL Server 2025 باستخدام sp_configure.
إليك النمط الأساسي:
DECLARE @response NVARCHAR(MAX);
DECLARE @returnValue INT;
EXECUTE @returnValue = sp_invoke_external_rest_endpoint
@url = N'https://<endpoint>.openai.azure.com/openai/deployments/<model>/chat/completions?api-version=<api-version>',
@method = 'POST',
@payload = @payload,
@credential = [https://<endpoint>.openai.azure.com],
@response = @response OUTPUT;
يشير المعامل @url إلى نقطة نهاية نشر Azure OpenAI الخاص بك.
@method عادة ما يكون 'POST' لطلبات التوليد. يحتوي على @payload موجه JSON الذي قمت ببناؤه سابقا. تشير إلى @credential بيانات اعتماد ضمن نطاق قاعدة البيانات تحتوي على تفاصيل المصادقة الخاصة بك.
@response تلتقط معامل الإخراج استجابة النموذج.
عندما تتصل بنقطة نهاية نشر النموذج باستخدام الموجه المعزز، يقوم النموذج بمعالجتها ويعيد النتيجة. يعيد الإجراء المخزن 0 عندما ينجح استدعاء HTTP برمز حالة 2xx، أو رمز حالة HTTP الفعلي عند الفشل.
تحقق من النقطة النهائية
يشير المعامل @credential إلى بيانات اعتماد ضمن نطاق قاعدة البيانات يحتوي على تفاصيل المصادقة الخاصة بك. تقوم بإعداد هذه البيانات عند إنشاء نموذج خارجي، باستخدام هوية مدارة أو مفتاح API. نفس الاعتماد يعمل لكل من استدعاءات النماذج الخارجية واستدعاءات نقطة النهاية المباشرة في REST مع sp_invoke_external_rest_endpoint.
استخرج الإجابة من الرد
عندما ينتهي النموذج من معالجة الطلب، sp_invoke_external_rest_endpoint يعيد النتيجة المغلفة في ظرف قياسي. تضيف الإجراء المخزن بيانات وصفية عن معاملة HTTP، ثم تضع استجابة API الفعلية داخل result خاصية:
{
"response": {
"status": {
"http": {
"code": 200,
"description": "OK"
}
}
},
"result": {
"choices": [
{
"message": {
"role": "assistant",
"content": "The Mountain-500 is compatible with several pedal options..."
}
}
]
}
}
الإجابة التي تريدها موجودة عند $.result.choices[0].message.content. للوصول إلى ذلك، استخدم JSON_VALUE، الذي يستخرج القيم القياسية من JSON:
IF @returnValue = 0
BEGIN
DECLARE @answer NVARCHAR(MAX);
SET @answer = JSON_VALUE(@response, '$.result.choices[0].message.content');
SELECT @answer AS AssistantResponse;
END
ELSE
BEGIN
SELECT
@returnValue AS HttpStatus,
JSON_VALUE(@response, '$.response.status.http.description') AS ErrorDescription;
END
إذا احتجت يوما لاستخراج كائن أو مصفوفة JSON بدلا من قيمة واحدة، استخدمها JSON_QUERY بدلا من ذلك. في معظم سيناريوهات RAG، JSON_VALUE محتوى الرسالة هو كل ما تحتاجه.
إدارة الأخطاء وإعادة المحاولات
استدعاء خدمة خارجية من قاعدة بيانات يمكن أن يدخل أوضاع فشل لا تواجهها مع الاستعلامات المحلية. قد تكون نقطة النهاية غير متاحة مؤقتا، أو قد يصبح طلبك محدودا بالمعدل، أو قد تفشل المصادقة. يجب أن تتعامل استفسارات SQL مع هذه الشروط برفق.
قيمة الإرجاع من sp_invoke_external_rest_endpoint تخبرك بما حدث. 0 تعني أن استدعاء HTTP نجح مع حالة 2xx. بالنسبة للإخفاقات، القيمة المرجعية هي رمز حالة HTTP نفسه. على سبيل المثال، حالة 429 تعني أن الخدمة تقيد طلباتك. تشير 401 أو 403 إلى مشاكل في الاعتماد:
IF @returnValue = 0
SET @answer = JSON_VALUE(@response, '$.result.choices[0].message.content');
ELSE IF @returnValue = 429
RAISERROR('Service is busy. Try again later.', 16, 1);
ELSE IF @returnValue = 401 OR @returnValue = 403
RAISERROR('Authentication failed. Check your credential configuration.', 16, 1);
ELSE
BEGIN
DECLARE @errorMsg NVARCHAR(500) = 'API call failed with status ' + CAST(@returnValue AS NVARCHAR(10));
RAISERROR(@errorMsg, 16, 1);
END
في حالات الفشل المؤقتة مثل انتهاء المهلة أو عدم توفر الخدمة المؤقتة، يمكن للإجراء المخزن إعادة المحاولة تلقائيا. أضف المعامل @retry_count وفي هذا المثال، يحاول الاستدعاء حتى ثلاث مرات قبل أن يستسلم:
EXECUTE @returnValue = sp_invoke_external_rest_endpoint
@url = @url,
@payload = @payload,
@credential = @credentialName,
@retry_count = 3,
@response = @response OUTPUT;
يتعامل هذا المعامل مع الحالة الشائعة التي يفشل فيها الطلب مرة واحدة لكنه ينجح في المحاولة التالية.
بناء إجراء مخزن كامل بنظام RAG
أنت الآن تعرف كل جزء من لغز RAG. دعونا نجمعها معا في إجراء مخزن واحد يمكن لتطبيق دعم العملاء الاتصال به. تقبل العملية سؤالا باللغة الطبيعية وتعيد إجابة مبنية على بيانات منتجك.
إليك ما تفعله هذه الإجراءات:
- يحول السؤال إلى تضمين حتى تتمكن من مقارنته بوصف منتجك.
- يجد أكثر المنتجات صلة باستخدام مسافة المتجهات لمقارنة تضمين السؤال مع تضمين وصف كل منتج محسوب مسبقا.
- يبني الملف برسالة نظام تخبر النموذج بالالتزام بالبيانات المقدمة، ورسالة مستخدم تجمع بين المنتجات المسترجعة والسؤال الأصلي.
- يرسل كل شيء إلى Azure OpenAI.
- يستخرج الإجابة من الرد ويعيده إلى المتصل.
CREATE PROCEDURE dbo.AskProductQuestion
@Question NVARCHAR(1000),
@Answer NVARCHAR(MAX) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @questionVector VECTOR(1536);
DECLARE @context NVARCHAR(MAX);
DECLARE @payload NVARCHAR(MAX);
DECLARE @response NVARCHAR(MAX);
DECLARE @returnValue INT;
-- Step 1:Convert question to embedding
SELECT @questionVector = AI_GENERATE_EMBEDDINGS(@Question USE MODEL my_embedding_model);
-- Step 2: Retrieve relevant products using vector search
SET @context = (
SELECT TOP 3
p.Name AS ProductName,
p.Color,
p.Size,
pm.Name AS Model
FROM Production.Product p
INNER JOIN Production.ProductModel pm ON p.ProductModelID = pm.ProductModelID
ORDER BY VECTOR_DISTANCE('cosine', p.DescriptionVector, @questionVector)
FOR JSON PATH
);
-- Step 3: Build augmented prompt
SET @payload = JSON_OBJECT(
'messages': JSON_ARRAY(
JSON_OBJECT('role': 'system', 'content': 'You are an Adventure Works product assistant. Answer questions using only the provided product data.'),
JSON_OBJECT('role': 'user', 'content': 'Products: ' + @context + ' Question: ' + @Question)
),
'max_tokens': 500,
'temperature': 0.5
);
-- Step 4: Call the model
EXECUTE @returnValue = sp_invoke_external_rest_endpoint
@url = N'https://adventureworks-openai.openai.azure.com/openai/deployments/gpt-5.2/chat/completions?api-version=2024-10-21',
@method = 'POST',
@payload = @payload,
@credential = [https://adventureworks-openai.openai.azure.com],
@response = @response OUTPUT;
-- Extract and return the answer
IF @returnValue = 0
SET @Answer = JSON_VALUE(@response, '$.result.choices[0].message.content');
ELSE
SET @Answer = 'Unable to process your question. Please try again.';
END;
أكملت خط أنابيب RAG في T-SQL. يسأل أحد الزبائن: "أي الدواسات تعمل مع ماونتن-500؟" إجراءك يحول هذا السؤال إلى متجه، ويجد المنتجات الأكثر ملاءمة، ويرسلها إلى النموذج مع تعليمات التأريض، ويعيد إجابة بناء على مخزونك الفعلي. لا يوجد برنامج وسيط، ولا كود تطبيقات خارجي، فقط SQL ينادي الذكاء الاصطناعي ويعيد النتائج.
النقاط الموجزة الأساسية
خطوة التوليد هي حيث يقدم خط أنابيب RAG الخاص بك قيمة. ترسل الموجه المعزز إلى Azure OpenAI باستخدام sp_invoke_external_rest_endpoint، الذي يتعامل مع اتصال HTTP دون مغادرة T-SQL. المصادقة تستخدم نفس بيانات اعتماد نطاق قاعدة البيانات التي أعددتها عند إنشاء نماذج خارجية. عندما يأتي الرد، JSON_VALUE يخرج إجابة المساعد. قم ببناء معالجة أخطاء لأن مكالمات الشبكة تفشل بطرق لا تفشل بها الاستعلامات المحلية. مع تشغيل جميع خطوات RAG الثلاث في T-SQL، تصبح قاعدة بياناتك أكثر من مجرد تخزين. تصبح خدمة ذكية تجيب على الأسئلة باستخدام بياناتك.