الخطوة 5 في RAG: تحسين الدردشة باستخدام RAG
ادمج محرك RAG في نقطة نهاية الدردشة (endpoint) في Flask حتى يجيب الذكاء الاصطناعي على الأسئلة بالاستناد إلى قاعدة معرفتك.
الخطوة 1: إضافة مسار RAG
أضف نقطة نهاية جديدة إلى backend/app/routes.py:
from .rag_engine import search_similar_chunks, build_rag_context, generate_rag_response
from .models import Document
@api.route("/rag-chat", methods=["POST"])
def rag_chat():
data = request.get_json()
user_message = data.get("message", "")
if not user_message:
return jsonify({"error": "Message is required"}), 400
user_msg = Message(content=user_message, sender="user")
db.session.add(user_msg)
db.session.commit()
try:
results = search_similar_chunks(db, user_message, Document, top_k=5)
context = build_rag_context(results)
ai_reply = generate_rag_response(user_message, context)
ai_msg = Message(content=ai_reply, sender="ai")
db.session.add(ai_msg)
db.session.commit()
return jsonify({
"user_message": user_msg.to_dict(),
"ai_message": ai_msg.to_dict(),
"evidence": [
{"title": r["title"], "similarity": round(r["similarity"], 3)}
for r in results
],
})
except Exception as e:
return jsonify({"error": str(e)}), 500
تتضمن الاستجابة الآن حقل evidence الذي يوضّح المستندات التي استُخدمت.
الخطوة 2: إعادة تشغيل الواجهة الخلفية
أوقفه ثم أعد تشغيله بعد توصيل PostgreSQL:
docker compose -f advanced/docker-compose.rag.yml up --build
الخطوة 3: اختبار دردشة RAG
# اسأل عن الدعم التعليمي
curl -X POST http://localhost:5000/api/rag-chat \
-H "Content-Type: application/json" \
-d '{"message": "Where can I get tutoring at Clark?"}'
الاستجابة المتوقعة:
{
"user_message": {"content": "Where can I get tutoring at Clark?", ...},
"ai_message": {
"content": "Clark College offers free tutoring in business, English, math, science, and general education classes. You can also access online eTutoring through e-Chat or e-Questions."
},
"evidence": [
{"title": "Tutoring Services at Clark College", "similarity": 0.843},
{"title": "Tech Hub at Clark College", "similarity": 0.512},
{"title": "Libraries at Clark College", "similarity": 0.487}
]
}
جرّب مزيدًا من الأسئلة:
# اسأل عن المساعدة المالية
curl -X POST http://localhost:5000/api/rag-chat \
-H "Content-Type: application/json" \
-d '{"message": "How can I get help paying for college?"}'
# اسأل عن الأخبار
curl -X POST http://localhost:5000/api/rag-chat \
-H "Content-Type: application/json" \
-d '{"message": "What happened at the CTE Showcase?"}'
# اسأل عن الفعاليات
curl -X POST http://localhost:5000/api/rag-chat \
-H "Content-Type: application/json" \
-d '{"message": "Tell me about the Sakura Festival"}'
الخطوة 4: المقارنة بين وجود RAG وغيابه
بدون RAG (المسار الأصلي /api/chat):
curl -X POST http://localhost:5000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "What tutoring is available at Clark?"}'
# → إجابة عامة: "Most colleges offer tutoring services..."
مع RAG (/api/rag-chat):
curl -X POST http://localhost:5000/api/rag-chat \
-H "Content-Type: application/json" \
-d '{"message": "What tutoring is available at Clark?"}'
# → إجابة محددة: "Clark College offers free tutoring in business, English..."
تقدم نسخة RAG إجابة دقيقة ومحددة لأنها عثرت على مستند الدعم التعليمي.
الخطوة 5: كيف يعمل كل شيء من البداية إلى النهاية
المستخدم: "What tutoring is available at Clark?"
1. تضمين السؤال
"What tutoring is available at Clark?"
→ [0.04, -0.13, 0.29, ...] (متجه بأبعاد 384)
2. البحث في pgvector
SELECT * FROM document
ORDER BY embedding <=> :query_vec
LIMIT 5
3. عُثر على أفضل 3 مقاطع متشابهة:
[0.84] "Tutoring Services at Clark College"
[0.51] "Tech Hub at Clark College"
[0.49] "Libraries at Clark College"
4. حقن النتائج في الموجّه (prompt):
النظام: "Use this context to answer:\n\n
[Tutoring Services at Clark College]
Clark College offers free tutoring..."
5. يولّد النموذج اللغوي الكبير (LLM) إجابة باستخدام السياق
"Clark College offers free tutoring in business, English..."
6. إعادة الإجابة إلى المستخدم مع تضمين الأدلة (evidence)
اكتب اختبارات لخط أنابيب RAG
اختبر التدفق الكامل — التضمين والبحث وتوليد الاستجابة:
from app import create_app, db
from app.models import Document
from advanced.rag.rag_engine import search_similar_chunks, build_rag_context
app = create_app()
with app.app_context():
results = search_similar_chunks(db, "free tutoring", Document, top_k=3)
assert len(results) == 3
assert results[0]["similarity"] > 0.5
print(f"Top result: {results[0]['title']} (similarity: {results[0]['similarity']:.3f})")
ما الذي تغطيه هذه الاختبارات
| الاختبار | ما يتحقق منه |
|---|---|
test_embed_text_returns_384_dimensions |
ينتج نموذج التضمين حجم متجه صحيحًا |
test_embed_text_consistent_output |
المدخل نفسه → المتجه نفسه (حتمي) |
test_chunk_text_creates_chunks |
يُقسَّم النص الطويل بشكل صحيح |
test_chunk_text_short_text |
يبقى النص القصير مقطعًا واحدًا |
test_get_all_chunks_returns_list |
تُحوَّل المستندات إلى مقاطع بشكل صحيح |
test_build_rag_context_formats_correctly |
تُنسَّق سلسلة السياق من أجل النموذج اللغوي |
اختبر عملك (يدويًا)
اكتب اختبارًا للتحقق من عمل خط أنابيب RAG:
from app import create_app, db
from app.models import Document
from advanced.rag.rag_engine import search_similar_chunks, build_rag_context
app = create_app()
with app.app_context():
results = search_similar_chunks(db, "free tutoring", Document, top_k=3)
assert len(results) == 3
assert results[0]["similarity"] > 0.5
print(f"Top result: {results[0]['title']} (similarity: {results[0]['similarity']:.3f})")