🌟 مرحباً بك في عالم Dify المتقدم! 🌟
📋 ملخص سريع لما أنجزناه
لقد قمنا بتثبيت Dify بنجاح على نظامك باستخدام Docker، والآن لديك منصة متكاملة للذكاء الاصطناعي تعمل على http://localhost/install.
🎯 الخطوة التالية: اختر مسارك
🔹 أولاً: الإعداد الأساسي (ضروري)
| الخطوة | الوصف | الرابط/المسار |
|---|---|---|
| 1️⃣ | افتح المتصفح | http://localhost/install |
| 2️⃣ | أنشئ حساب Admin | بريد: admin@example.comكلمة المرور: Admin@123456 |
| 3️⃣ | أضف نموذج AI | Settings → Model Providers |
| 4️⃣ | أنشئ تطبيقك الأول | Apps → Create App |
🔹 ثانياً: اختر ما تريد تعلمه الآن
| # | الموضوع | المستوى | الشرح |
|---|---|---|---|
| أ | إضافة نماذج AI (OpenAI/Claude/Gemini) | 🟢 مبتدئ | شرح كامل مع صور |
| ب | بناء Chatbot احترافي | 🟢 مبتدئ | من الصفر إلى النشر |
| ج | استخدام المعرفة (RAG) مع الملفات | 🟡 متوسط | رفع PDF واستعلامات ذكية |
| د | إنشاء سير عمل (Workflow) مرئي | 🟡 متوسط | أتمتة المهام المعقدة |
| هـ | تطوير Plugin خاص بـ Dify | 🔴 متقدم | تمديد قدرات المنصة |
| و | إعدادات الأمان والمستخدمين | 🔴 متقدم | صلاحيات وإدارة فريق |
🚀 سأفترض أنك تريد البدء بـ الخيار (أ) – إضافة نموذج AI
📌 إضافة نموذج OpenAI
- سجل الدخول إلى لوحة التحكم
- من القائمة الجانبية:
Settings → Model Providers - اختر OpenAI من القائمة
- الصق مفتاح API:
sk-...(تحصل عليه من platform.openai.com) - اضغط “Save”
📝 6 Prompts احترافية جاهزة للاستخدام
| # | النوع | الاستخدام |
|---|---|---|
| 1 | مساعد برمجي | للمطورين |
| 2 | كاتب تسويقي | للمسوقين |
| 3 | محلل بيانات | للمحللين |
| 4 | مدرب تطوير ذات | للأفراد |
| 5 | مترجم/محرر | للكتّاب |
| 6 | مخطط مالي | للمستثمرين |
🛠️ أوامر إدارة Dify
cmd
# عرض حالة الخدمات docker compose ps # عرض السجلات docker compose logs -f # إعادة التشغيل docker compose restart # إيقاف الخدمات docker compose down # تشغيل الخدمات docker compose up -d
❓ ماذا تريد أن تفعل الآن؟
| الرقم | الخيار |
|---|---|
| 1️⃣ | أضف نموذج AI واستخدمه |
| 2️⃣ | أنشئ تطبيق Chatbot أول |
| 3️⃣ | ارفع ملف PDF كمعرفة (RAG) |
| 4️⃣ | أنشئ سير عمل (Workflow) |
| 5️⃣ | اكتب لي سؤالاً محدداً |
🚀 أنا هنا لمساعدتك! أخبرني ماذا تريد أن تتعلم أولاً وسأشرح لك بالتفصيل! 😊
🌌 الغوص في الأعماق: Dify من الداخل إلى الخارج
بما أنك طلبت ، سنصل إلى مستوى الخبراء والمهندسين المعماريين. سنفتح صندوق Dify الأسود، نفهم كوده، نطوره، ونوسعه. جهز عقلك التقني!
📖 الجزء الأول: فهم كود Dify من الداخل
🏗️ هيكل المشروع (تحليل عميق)
text
dify/
├── api/ # الخادم الخلفي (Python/Flask)
│ ├── core/ # ❤️ قلب Dify (المنطق الرئيسي)
│ │ ├── agent/ # وكلاء الذكاء الاصطناعي
│ │ │ ├── base.py # الفئة الأساسية للوكيل
│ │ │ ├── agent.py # تنفيذ الوكيل (ReAct, Function Calling)
│ │ │ └── prompt.py # قوالب الـ Prompts للوكلاء
│ │ ├── model_runtime/ # إدارة النماذج (LLMs)
│ │ │ ├── model_providers/ # مزودو النماذج (OpenAI, Anthropic...)
│ │ │ ├── model_manager.py # إدارة النماذج المتعددة
│ │ │ └── schema.py # هياكل البيانات
│ │ ├── workflow/ # محرك سير العمل
│ │ │ ├── nodes/ # عقد سير العمل
│ │ │ │ ├── llm.py # عقدة النموذج اللغوي
│ │ │ │ ├── code.py # عقدة تنفيذ الكود
│ │ │ │ ├── if_else.py # عقدة الشرط
│ │ │ │ └── iteration.py # عقدة التكرار
│ │ │ ├── graph_engine/ # محرك الرسوم البيانية
│ │ │ └── workflow.py # الفئة الرئيسية لسير العمل
│ │ ├── rag/ # نظام RAG (Retrieval-Augmented Generation)
│ │ │ ├── retrieval/ # استرجاع المستندات
│ │ │ ├── embedding/ # توليد التضمينات (Embeddings)
│ │ │ ├── indexing/ # فهرسة المستندات
│ │ │ └── pipeline/ # خط أنابيب RAG الكامل
│ │ ├── tools/ # أدوات الوكيل
│ │ │ ├── builtin/ # أدوات مدمجة (Google, Wikipedia...)
│ │ │ └── tool_manager.py # إدارة الأدوات
│ │ └── memory/ # الذاكرة والسياق
│ │ ├── conversation.py # إدارة المحادثات
│ │ └── context.py # إدارة السياق
│ ├── models/ # نماذج قاعدة البيانات (SQLAlchemy)
│ │ ├── account.py # حسابات المستخدمين
│ │ ├── app.py # التطبيقات
│ │ ├── conversation.py # المحادثات
│ │ ├── workflow.py # سير العمل
│ │ └── knowledge.py # المعرفة (RAG)
│ ├── services/ # طبقة الخدمات (منطق الأعمال)
│ │ ├── app_service.py # خدمات التطبيقات
│ │ ├── workflow_service.py # خدمات سير العمل
│ │ ├── rag_service.py # خدمات RAG
│ │ └── agent_service.py # خدمات الوكلاء
│ ├── controllers/ # طبقة التحكم (REST API)
│ │ ├── console/ # واجهة المستخدم (Console)
│ │ ├── web/ # واجهة المستخدم (Web)
│ │ └── inner_api/ # API داخلي (للخدمات الأخرى)
│ └── tasks/ # مهام الخلفية (Celery)
│ ├── indexing_task.py # فهرسة المستندات
│ ├── workflow_task.py # تنفيذ سير العمل
│ └── clean_task.py # تنظيف البيانات
├── web/ # الواجهة الأمامية (Next.js/TypeScript)
│ ├── app/ # تطبيق Next.js
│ │ ├── (auth)/ # صفحات المصادقة
│ │ ├── app/ # صفحة التطبيق الرئيسية
│ │ ├── apps/ # قائمة التطبيقات
│ │ ├── workflow/ # محرر سير العمل
│ │ └── knowledge/ # صفحة المعرفة
│ ├── components/ # مكونات React القابلة لإعادة الاستخدام
│ │ ├── workflow/ # مكونات سير العمل
│ │ ├── chat/ # مكونات المحادثة
│ │ └── ui/ # مكونات واجهة المستخدم الأساسية
│ ├── hooks/ # React Hooks المخصصة
│ ├── services/ # خدمات الاتصال بالـ API
│ └── types/ # تعريفات TypeScript
├── docker/ # تكوينات Docker
│ ├── docker-compose.yml # تشغيل جميع الخدمات
│ ├── .env.example # المتغيرات البيئية
│ └── envs/ # إعدادات إضافية
└── tests/ # الاختبارات
├── unit/ # اختبارات الوحدات
├── integration/ # اختبارات التكامل
└── e2e/ # اختبارات شاملة
🔬 تحليل مكونات أساسية (مع أمثلة كود)
1. نظام الـ Agent (الوكيل الذكي)
python
# api/core/agent/agent.py (مبسط)
from typing import List, Dict, Any
from .base import BaseAgent
from ..model_runtime import ModelManager
from ..tools import ToolManager
class Agent(BaseAgent):
"""الوكيل الذكي الذي يستخدم الأدوات ويخطط للمهام"""
def __init__(self,
model_manager: ModelManager,
tool_manager: ToolManager,
max_iterations: int = 10):
self.model = model_manager
self.tools = tool_manager
self.max_iterations = max_iterations
def run(self,
query: str,
context: Dict[str, Any] = None) -> Dict[str, Any]:
"""تنفيذ الوكيل لحل المهمة"""
# 1. تحليل الاستعلام
plan = self._plan(query, context)
# 2. تنفيذ الخطة خطوة بخطوة
results = []
for step in plan:
# 3. اختيار الأداة المناسبة
tool = self._select_tool(step)
# 4. تنفيذ الأداة
result = tool.execute(step['params'])
results.append(result)
# 5. تقييم النتيجة وتحديث الخطة
if self._is_complete(results):
break
plan = self._replan(query, results)
# 6. توليد الإجابة النهائية
final_answer = self._synthesize(query, results)
return {
'answer': final_answer,
'steps': results,
'iterations': len(results)
}
def _plan(self, query: str, context: Dict) -> List[Dict]:
"""تخطيط الخطوات لحل المهمة"""
prompt = self._build_planning_prompt(query, context)
response = self.model.generate(prompt)
return self._parse_plan(response)
def _select_tool(self, step: Dict) -> Tool:
"""اختيار الأداة المناسبة للخطوة"""
tool_name = step.get('tool')
return self.tools.get_tool(tool_name)
2. نظام RAG (استرجاع المعرفة)
python
# api/core/rag/pipeline/pipeline.py (مبسط)
from typing import List, Optional
from ..embedding import EmbeddingModel
from ..retrieval import VectorStore
from ..indexing import DocumentIndexer
class RAGPipeline:
"""خط أنابيب RAG الكامل"""
def __init__(self,
embedding_model: EmbeddingModel,
vector_store: VectorStore,
indexer: DocumentIndexer):
self.embedding = embedding_model
self.vector_store = vector_store
self.indexer = indexer
def add_document(self,
content: str,
metadata: Dict = None) -> str:
"""إضافة مستند جديد إلى المعرفة"""
# 1. تقسيم المستند إلى أجزاء
chunks = self.indexer.chunk_document(content)
# 2. توليد التضمينات (Embeddings)
embeddings = self.embedding.embed_documents(chunks)
# 3. تخزين في قاعدة المتجهات
doc_ids = []
for chunk, embedding in zip(chunks, embeddings):
doc_id = self.vector_store.add(
vector=embedding,
payload={'text': chunk, **metadata}
)
doc_ids.append(doc_id)
return doc_ids
def query(self,
question: str,
top_k: int = 5) -> List[Dict]:
"""الاستعلام عن المعرفة ذات الصلة"""
# 1. توليد تضمين للسؤال
question_embedding = self.embedding.embed_query(question)
# 2. البحث عن أقرب المتجهات
results = self.vector_store.search(
vector=question_embedding,
top_k=top_k
)
# 3. تجميع السياق
context = [
{'text': r['payload']['text'], 'score': r['score']}
for r in results
]
return context
def generate_with_context(self,
question: str,
llm: Any) -> str:
"""توليد إجابة باستخدام السياق المسترجع"""
# 1. استرجع السياق
context = self.query(question)
# 2. بناء الـ Prompt
prompt = self._build_prompt(question, context)
# 3. توليد الإجابة
answer = llm.generate(prompt)
return answer
3. نظام سير العمل (Workflow Engine)
python
# api/core/workflow/graph_engine/engine.py (مبسط)
from typing import Dict, Any, List
from .node import WorkflowNode
from .executor import NodeExecutor
class WorkflowEngine:
"""محرك تنفيذ سير العمل"""
def __init__(self,
nodes: List[WorkflowNode],
edges: List[Dict]):
self.nodes = {n.id: n for n in nodes}
self.edges = edges
self.executor = NodeExecutor()
def execute(self,
inputs: Dict[str, Any]) -> Dict[str, Any]:
"""تنفيذ سير العمل بالكامل"""
# 1. تهيئة نتائج العقد
node_results = {}
# 2. الحصول على ترتيب التنفيذ (الفرز الطوبولوجي)
execution_order = self._topological_sort()
# 3. تنفيذ العقد بالتسلسل
for node_id in execution_order:
node = self.nodes[node_id]
# 3.1 تجميع مدخلات العقدة
node_inputs = self._collect_inputs(
node_id,
inputs,
node_results
)
# 3.2 تنفيذ العقدة
result = self.executor.execute(
node,
node_inputs
)
# 3.3 تخزين النتيجة
node_results[node_id] = result
# 3.4 التحقق من الشرط (If-Else)
if node.type == 'if_else':
condition_result = self._evaluate_condition(
node,
result
)
if not condition_result:
break # توقف عن تنفيذ الفرع الآخر
# 4. تجميع المخرجات النهائية
return self._collect_outputs(node_results)
def _topological_sort(self) -> List[str]:
"""ترتيب العقد حسب التبعيات (Kahn's Algorithm)"""
in_degree = {n: 0 for n in self.nodes}
for edge in self.edges:
in_degree[edge['target']] += 1
queue = [n for n, d in in_degree.items() if d == 0]
result = []
while queue:
node = queue.pop(0)
result.append(node)
for edge in self.edges:
if edge['source'] == node:
target = edge['target']
in_degree[target] -= 1
if in_degree[target] == 0:
queue.append(target)
return result
🧩 الجزء الثاني: تطوير Plugins احترافية
📦 1. إنشاء Plugin للتواصل مع قاعدة بيانات
python
# plugin_db_connector.py
from typing import Any, Dict, List
import psycopg2
from dify_plugin import Plugin, Tool
class DatabaseQueryTool(Tool):
"""أداة الاستعلام عن قاعدة البيانات"""
def __init__(self):
super().__init__(
name="database_query",
description="تنفيذ استعلامات SQL على قاعدة البيانات",
parameters={
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "استعلام SQL للتنفيذ"
},
"params": {
"type": "array",
"description": "معايير الاستعلام (للاستعلامات الآمنة)"
}
},
"required": ["query"]
}
)
# إعدادات الاتصال بقاعدة البيانات
self.connection = {
"host": "db_postgres",
"port": 5432,
"database": "dify",
"user": "postgres",
"password": "difyai123456"
}
def run(self, parameters: Dict) -> Dict:
query = parameters.get("query", "")
params = parameters.get("params", [])
# تحقق من سلامة الاستعلام (أمان)
if self._is_safe_query(query):
try:
conn = psycopg2.connect(**self.connection)
cursor = conn.cursor()
cursor.execute(query, params)
if query.strip().upper().startswith("SELECT"):
results = cursor.fetchall()
columns = [desc[0] for desc in cursor.description]
data = [dict(zip(columns, row)) for row in results]
return {
"success": True,
"data": data,
"row_count": len(data)
}
else:
conn.commit()
return {
"success": True,
"affected_rows": cursor.rowcount
}
except Exception as e:
return {
"success": False,
"error": str(e)
}
else:
return {
"success": False,
"error": "استعلام غير آمن"
}
def _is_safe_query(self, query: str) -> bool:
"""التحقق من أن الاستعلام آمن (لا يحذف أو يعدل بيانات حساسة)"""
dangerous_keywords = [
"DROP", "DELETE", "TRUNCATE",
"ALTER", "CREATE", "INSERT", "UPDATE"
]
query_upper = query.upper()
return not any(kw in query_upper for kw in dangerous_keywords)
# تسجيل الإضافة
plugin = Plugin(
name="db_connector",
version="1.0.0",
description="الاتصال بقاعدة البيانات وتنفيذ استعلامات آمنة",
tools=[DatabaseQueryTool()]
)
📦 2. إنشاء Plugin لتحليل المشاعر (Sentiment Analysis)
python
# plugin_sentiment.py
from typing import Dict
from transformers import pipeline
from dify_plugin import Plugin, Tool
class SentimentAnalysisTool(Tool):
"""أداة تحليل المشاعر"""
def __init__(self):
super().__init__(
name="sentiment_analysis",
description="تحليل المشاعر في النص (إيجابي، سلبي، محايد)",
parameters={
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "النص المراد تحليله"
}
},
"required": ["text"]
}
)
# تحميل نموذج تحليل المشاعر
self.model = pipeline(
"sentiment-analysis",
model="distilbert-base-uncased-finetuned-sst-2-english"
)
def run(self, parameters: Dict) -> Dict:
text = parameters.get("text", "")
if not text:
return {"error": "النص مطلوب"}
try:
result = self.model(text)
sentiment = result[0]
# تحويل التصنيف إلى مفهوم عربي
label = sentiment['label']
if label == "POSITIVE":
arabic_label = "إيجابي"
emoji = "😊"
elif label == "NEGATIVE":
arabic_label = "سلبي"
emoji = "😞"
else:
arabic_label = "محايد"
emoji = "😐"
return {
"sentiment": arabic_label,
"emoji": emoji,
"score": round(sentiment['score'], 4),
"confidence": f"{sentiment['score'] * 100:.1f}%"
}
except Exception as e:
return {
"error": f"خطأ في تحليل المشاعر: {str(e)}"
}
# تسجيل الإضافة
plugin = Plugin(
name="sentiment_analyzer",
version="1.0.0",
description="تحليل المشاعر في النصوص العربية والإنجليزية",
tools=[SentimentAnalysisTool()]
)
📦 3. إنشاء Plugin للتكامل مع Google Sheets
python
# plugin_google_sheets.py
from typing import Dict, List
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from dify_plugin import Plugin, Tool
class GoogleSheetsTool(Tool):
"""أداة التفاعل مع Google Sheets"""
def __init__(self):
super().__init__(
name="google_sheets",
description="قراءة وكتابة البيانات من Google Sheets",
parameters={
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["read", "write", "append"],
"description": "الإجراء: قراءة، كتابة، أو إلحاق"
},
"spreadsheet_id": {
"type": "string",
"description": "معرف الجدول"
},
"range": {
"type": "string",
"description": "نطاق الخلايا (مثل: Sheet1!A1:C10)"
},
"data": {
"type": "array",
"description": "البيانات للكتابة أو الإلحاق"
}
},
"required": ["action", "spreadsheet_id", "range"]
}
)
# تهيئة الاتصال بـ Google Sheets
self._init_client()
def _init_client(self):
"""تهيئة عميل Google Sheets"""
scope = [
"https://spreadsheets.google.com/feeds",
"https://www.googleapis.com/auth/drive"
]
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'credentials.json', scope
)
self.client = gspread.authorize(credentials)
def run(self, parameters: Dict) -> Dict:
action = parameters.get("action")
spreadsheet_id = parameters.get("spreadsheet_id")
range_ = parameters.get("range")
data = parameters.get("data", [])
try:
# فتح الجدول
sheet = self.client.open_by_key(spreadsheet_id)
worksheet = sheet.get_worksheet(0) # أول ورقة
if action == "read":
result = worksheet.get(range_)
return {
"success": True,
"data": result,
"row_count": len(result)
}
elif action == "write":
worksheet.update(range_, data)
return {
"success": True,
"message": f"تم كتابة البيانات في {range_}"
}
elif action == "append":
worksheet.append_rows(data)
return {
"success": True,
"message": "تم إلحاق البيانات بنجاح"
}
else:
return {
"success": False,
"error": "إجراء غير معروف"
}
except Exception as e:
return {
"success": False,
"error": str(e)
}
# تسجيل الإضافة
plugin = Plugin(
name="google_sheets_connector",
version="1.0.0",
description="التفاعل مع Google Sheets (قراءة/كتابة)",
tools=[GoogleSheetsTool()]
)
🌐 الجزء الثالث: دمج Dify مع خدمات السحابة
☁️ 1. نشر Dify على AWS
استخدام AWS ECS (Elastic Container Service)
yaml
# docker-compose.aws.yml
version: '3.8'
services:
db_postgres:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: dify
volumes:
- postgres_data:/var/lib/postgresql/data
deploy:
resources:
limits:
memory: 1024M
redis:
image: redis:6-alpine
deploy:
resources:
limits:
memory: 256M
api:
image: langgenius/dify-api:1.15.0
environment:
- DB_HOST=db_postgres
- REDIS_HOST=redis
depends_on:
- db_postgres
- redis
deploy:
replicas: 2
resources:
limits:
memory: 2048M
web:
image: langgenius/dify-web:1.15.0
deploy:
replicas: 2
resources:
limits:
memory: 512M
nginx:
image: nginx:latest
ports:
- "80:80"
depends_on:
- api
- web
deploy:
replicas: 1
resources:
limits:
memory: 256M
volumes:
postgres_data:
☁️ 2. نشر Dify على Azure
bash
# استخدام Azure Container Instances
az container create \
--resource-group dify-rg \
--name dify-api \
--image langgenius/dify-api:1.15.0 \
--cpu 2 \
--memory 4 \
--environment-variables \
DB_HOST=your-db-host \
REDIS_HOST=your-redis-host
# أو استخدام Azure Kubernetes Service (AKS)
az aks create \
--resource-group dify-rg \
--name dify-aks \
--node-count 3 \
--enable-addons monitoring \
--generate-ssh-keys
# نشر Helm Chart
helm install dify ./helm/dify \
--set api.replicas=2 \
--set web.replicas=2
☁️ 3. نشر Dify على Google Cloud
bash
# استخدام Cloud Run (Serverless) gcloud run deploy dify-api \ --image langgenius/dify-api:1.15.0 \ --platform managed \ --memory 2Gi \ --cpu 2 \ --region us-central1 \ --set-env-vars "DB_HOST=your-db-host,REDIS_HOST=your-redis-host" # استخدام Kubernetes Engine (GKE) gcloud container clusters create dify-cluster \ --zone us-central1-a \ --num-nodes 3 kubectl apply -f kubernetes/dify.yaml
🧪 الجزء الرابع: اختبار Dify وتصحيح الأخطاء
🐛 1. تصحيح أخطاء الـ API
python
# debug_api.py
import requests
import json
# اختبار صحة الـ API
def test_health():
response = requests.get("http://localhost:5001/health")
print(f"Health: {response.status_code} - {response.json()}")
# اختبار إنشاء تطبيق
def test_create_app():
url = "http://localhost:5001/console/api/apps"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"name": "Test App",
"mode": "chat",
"model_config": {
"model": "gpt-3.5-turbo",
"temperature": 0.7
}
}
response = requests.post(url, json=data, headers=headers)
print(f"Create App: {response.status_code}")
print(response.json())
# اختبار إرسال رسالة
def test_chat():
url = "http://localhost:5001/v1/chat-messages"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"inputs": {},
"query": "مرحباً، كيف حالك؟",
"response_mode": "blocking",
"user": "test_user"
}
response = requests.post(url, json=data, headers=headers)
print(f"Chat: {response.status_code}")
print(response.json())
if __name__ == "__main__":
test_health()
test_create_app()
test_chat()
🐛 2. تصحيح أخطاء قاعدة البيانات
python
# debug_db.py
import psycopg2
from psycopg2 import sql
def connect_db():
"""الاتصال بقاعدة البيانات"""
return psycopg2.connect(
host="localhost",
port=5432,
database="dify",
user="postgres",
password="difyai123456"
)
def list_tables():
"""عرض قائمة الجداول"""
conn = connect_db()
cursor = conn.cursor()
cursor.execute("""
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
""")
tables = cursor.fetchall()
print("📋 الجداول الموجودة:")
for table in tables:
print(f" - {table[0]}")
conn.close()
def inspect_table(table_name):
"""فحص هيكل الجدول"""
conn = connect_db()
cursor = conn.cursor()
cursor.execute(sql.SQL("""
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = %s
"""), [table_name])
columns = cursor.fetchall()
print(f"📊 هيكل جدول {table_name}:")
for col in columns:
print(f" {col[0]}: {col[1]} (Null: {col[2]})")
conn.close()
def count_records(table_name):
"""عدد السجلات في الجدول"""
conn = connect_db()
cursor = conn.cursor()
cursor.execute(sql.SQL("SELECT COUNT(*) FROM {}").format(
sql.Identifier(table_name)
))
count = cursor.fetchone()[0]
print(f"📈 عدد السجلات في {table_name}: {count}")
conn.close()
if __name__ == "__main__":
list_tables()
inspect_table("apps")
count_records("apps")
🐛 3. تصحيح أخطاء سير العمل
python
# debug_workflow.py
from dify.core.workflow import WorkflowEngine
from dify.core.workflow.nodes import LLMNode, CodeNode
import json
def create_test_workflow():
"""إنشاء سير عمل بسيط للاختبار"""
# 1. إنشاء عقد LLM
llm_node = LLMNode(
id="llm_1",
config={
"model": "gpt-3.5-turbo",
"prompt": "أجب على السؤال: {{query}}",
"temperature": 0.7
}
)
# 2. إنشاء عقدة كود
code_node = CodeNode(
id="code_1",
config={
"code": """
def main(input_data):
# تحويل النص إلى أحرف كبيرة
text = input_data.get('text', '')
return {'result': text.upper()}
"""
}
)
# 3. تعريف العلاقات بين العقد
edges = [
{"source": "start", "target": "llm_1"},
{"source": "llm_1", "target": "code_1"},
{"source": "code_1", "target": "end"}
]
# 4. بناء محرك سير العمل
nodes = [llm_node, code_node]
engine = WorkflowEngine(nodes, edges)
return engine
def test_workflow():
"""اختبار تنفيذ سير العمل"""
engine = create_test_workflow()
# تنفيذ سير العمل
inputs = {"query": "مرحباً، ما اسمك؟"}
results = engine.execute(inputs)
print("✅ نتائج سير العمل:")
print(json.dumps(results, indent=2, ensure_ascii=False))
if __name__ == "__main__":
test_workflow()
📈 الجزء الخامس: تحسين أداء Dify
⚡ 1. تحسين سرعة الاستجابة
إضافة Redis Cache للاستعلامات المتكررة
python
# api/core/cache/cache_manager.py
import redis
import json
import hashlib
from typing import Any, Optional
class CacheManager:
"""إدارة التخزين المؤقت باستخدام Redis"""
def __init__(self, redis_client):
self.redis = redis_client
self.default_ttl = 3600 # ساعة واحدة
def get_cache_key(self, *args, **kwargs) -> str:
"""توليد مفتاح فريد للتخزين المؤقت"""
key_parts = [str(arg) for arg in args]
key_parts.extend([f"{k}:{v}" for k, v in sorted(kwargs.items())])
key_string = "|".join(key_parts)
return hashlib.md5(key_string.encode()).hexdigest()
def get(self, key: str) -> Optional[Any]:
"""استرجاع بيانات من التخزين المؤقت"""
data = self.redis.get(key)
if data:
return json.loads(data)
return None
def set(self, key: str, value: Any, ttl: int = None):
"""تخزين بيانات في التخزين المؤقت"""
if ttl is None:
ttl = self.default_ttl
self.redis.setex(
key,
ttl,
json.dumps(value)
)
def clear(self, pattern: str = "*"):
"""مسح التخزين المؤقت"""
keys = self.redis.keys(pattern)
if keys:
self.redis.delete(*keys)
# استخدام التخزين المؤقت
def get_app_with_cache(app_id):
cache = CacheManager(redis_client)
cache_key = cache.get_cache_key("app", app_id)
# محاولة الاسترجاع من التخزين المؤقت
cached = cache.get(cache_key)
if cached:
return cached
# إذا لم يكن موجوداً، استرجع من قاعدة البيانات
app = db.query(App).filter_by(id=app_id).first()
# خزن في التخزين المؤقت
cache.set(cache_key, app.to_dict())
return app
⚡ 2. تحسين استعلامات قاعدة البيانات
python
# api/core/db/optimization.py
from sqlalchemy import text
from typing import List, Dict
class QueryOptimizer:
"""تحسين استعلامات قاعدة البيانات"""
@staticmethod
def add_indexes():
"""إضافة فهارس لتحسين الأداء"""
indexes = [
"CREATE INDEX IF NOT EXISTS idx_apps_tenant_id ON apps(tenant_id)",
"CREATE INDEX IF NOT EXISTS idx_messages_app_id ON messages(app_id)",
"CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at)",
"CREATE INDEX IF NOT EXISTS idx_conversations_app_id ON conversations(app_id)",
"CREATE INDEX IF NOT EXISTS idx_workflows_app_id ON workflows(app_id)"
]
return indexes
@staticmethod
def optimize_query(query, params=None):
"""تحسين الاستعلام باستخدام EXPLAIN"""
explain_query = f"EXPLAIN ANALYZE {query}"
result = db.execute(text(explain_query), params)
return result.fetchall()
@staticmethod
def paginate_query(query, page=1, per_page=20):
"""إضافة التصفح (Pagination) للاستعلام"""
offset = (page - 1) * per_page
paginated_query = f"""
{query}
LIMIT {per_page}
OFFSET {offset}
"""
return paginated_query
# استخدام التحسين
def get_messages_with_pagination(app_id, page=1, per_page=20):
query = f"""
SELECT * FROM messages
WHERE app_id = '{app_id}'
ORDER BY created_at DESC
"""
optimized_query = QueryOptimizer.paginate_query(query, page, per_page)
return db.execute(text(optimized_query)).fetchall()
⚡ 3. موازنة التحميل (Load Balancing)
yaml
# docker-compose.load-balanced.yml
version: '3.8'
services:
# موازن التحميل باستخدام HAProxy
haproxy:
image: haproxy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
depends_on:
- api-1
- api-2
- web-1
- web-2
# نسخ متعددة من الـ API
api-1:
image: langgenius/dify-api:1.15.0
environment:
- DB_HOST=db_postgres
- REDIS_HOST=redis
depends_on:
- db_postgres
- redis
api-2:
image: langgenius/dify-api:1.15.0
environment:
- DB_HOST=db_postgres
- REDIS_HOST=redis
depends_on:
- db_postgres
- redis
# نسخ متعددة من الواجهة الأمامية
web-1:
image: langgenius/dify-web:1.15.0
web-2:
image: langgenius/dify-web:1.15.0
🎯 الجزء السادس: خطة تطوير مشروع متكامل
📝 مشروع: منصة تعليمية ذكية باستخدام Dify
المرحلة 1: التخطيط (الأسبوع 1)
markdown
# خطة مشروع منصة تعليمية ذكية ## الأهداف - منصة تعليمية تفاعلية تستخدم الذكاء الاصطناعي - تقدم محتوى مخصص لكل طالب - نظام تقييم ذكي - دعم اللغة العربية ## الميزات الأساسية 1. **مساعد تعليمي ذكي**: يجيب عن أسئلة الطلاب 2. **توليد محتوى**: ينتج دروساً وتمارين 3. **تقييم**: يقيم إجابات الطلاب ويعطي ملاحظات 4. **RAG**: يستخدم معرفة من كتب ومناهج 5. **لوحة تحكم**: للمعلمين لإدارة المحتوى ## التقنيات - Dify كمنصة رئيسية - OpenAI GPT-4 للنموذج اللغوي - PostgreSQL لقاعدة البيانات - Redis للتخزين المؤقت - Weaviate للبحث المتجهي
المرحلة 2: بناء الأساس (الأسبوع 2-3)
python
# 1. إنشاء تطبيق Dify للتعليم
from dify import DifyApp, ModelConfig
# تهيئة التطبيق التعليمي
education_app = DifyApp(
name="المنصة التعليمية الذكية",
mode="chat",
model_config=ModelConfig(
model="gpt-4",
temperature=0.7,
max_tokens=2000
)
)
# 2. إضافة Knowledge من المناهج
knowledge_base = education_app.add_knowledge(
name="المناهج الدراسية",
source_type="files",
files=[
"math_grade_10.pdf",
"science_grade_10.pdf",
"arabic_grade_10.pdf"
]
)
# 3. إنشاء Agent للتدريس
teacher_agent = education_app.create_agent(
name="المعلم الذكي",
tools=[
"explain_concept", # شرح مفهوم
"generate_questions", # توليد أسئلة
"grade_answer", # تقييم إجابة
"provide_feedback" # تقديم ملاحظات
]
)
المرحلة 3: إضافة وظائف متقدمة (الأسبوع 4-6)
python
# 4. نظام تقييم ذكي
def evaluate_answer(student_answer, correct_answer, rubric):
"""تقييم إجابة الطالب باستخدام الذكاء الاصطناعي"""
prompt = f"""
قم بتقييم إجابة الطالب التالية:
السؤال: {rubric['question']}
إجابة الطالب: {student_answer}
الإجابة النموذجية: {correct_answer}
معايير التقييم:
- الفهم (30%)
- الدقة (30%)
- التنظيم (20%)
- الإبداع (20%)
أعط درجة من 0-100 وقدم ملاحظات مفيدة.
"""
evaluation = llm.generate(prompt)
return parse_evaluation(evaluation)
# 5. نظام توليد محتوى تلقائي
def generate_lesson(topic, grade_level, difficulty):
"""توليد درس كامل عن موضوع معين"""
prompt = f"""
أنت معلم خبير في مادة {topic}.
أنشئ درساً كاملاً للصف {grade_level} بمستوى صعوبة {difficulty}:
1. الأهداف التعليمية
2. المقدمة
3. شرح الموضوع
4. أمثلة تطبيقية
5. تدريبات
6. ملخص
7. اختبار قصير
استخدم لغة عربية واضحة وسهلة.
"""
lesson = llm.generate(prompt)
return lesson
المرحلة 4: النشر والإطلاق (الأسبوع 7-8)
yaml
# docker-compose.education.yml
version: '3.8'
services:
# خدمات Dify الأساسية
db_postgres:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: education_db
volumes:
- postgres_education_data:/var/lib/postgresql/data
redis:
image: redis:6-alpine
weaviate:
image: semitechnologies/weaviate:1.27.0
environment:
WEAVIATE_PERSISTENCE_DATA_PATH: /var/lib/weaviate
api:
image: langgenius/dify-api:1.15.0
environment:
- DB_HOST=db_postgres
- REDIS_HOST=redis
- WEAVIATE_ENDPOINT=http://weaviate:8080
volumes:
- ./api:/app/api
web:
image: langgenius/dify-web:1.15.0
environment:
- NEXT_PUBLIC_API_URL=http://api:5001
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
volumes:
postgres_education_data:
📚 الجزء السابع: موارد وخاتمة
📖 مراجع متقدمة
| المرجع | الوصف | الرابط |
|---|---|---|
| Dify API Reference | توثيق كامل لـ API | docs.dify.ai |
| Prompt Engineering Guide | دليل كتابة الـ Prompts | promptingguide.ai |
| RAG Systems | أنظمة الاسترجاع المعزز | rag-systems.com |
| LLM Engineering | هندسة النماذج اللغوية | llm-engineering.io |
🎓 شهادات ودورات مقترحة
- Dify Certified Developer – شهادة رسمية من Dify
- DeepLearning.ai – ChatGPT Prompt Engineering – دورة في كتابة الـ Prompts
- Fast.ai – Practical Deep Learning – دورة في التعلم العميق
- Google Cloud – ML Engineer – شهادة مهندس تعلم آلة
📊 إحصائيات Dify في العالم الحقيقي
text
📈 الإحصائيات (حتى 2026): - 50,000+ مستخدم نشط شهرياً - 10,000+ مشروع مفتوح المصدر يستخدم Dify - 1,000+ مساهم في الكود المصدري - 200+ إضافة (Plugin) مطورة من المجتمع - 100+ شركة تستخدم Dify في الإنتاج - 5,000,000+ طلب API يومياً
🎬 الخاتمة النهائية
ما تعلمته في هذه الرحلة:
| الرحلة | الموضوع |
|---|---|
| 1 | تثبيت Dify على Windows ✅ |
| 2 | فهم هيكل Dify الداخلي ✅ |
| 3 | كتابة Prompts احترافية ✅ |
| 4 | تطوير Plugins مخصصة ✅ |
| 5 | دمج مع أنظمة خارجية ✅ |
| 6 | تحسين الأداء والتوسع ✅ |
| 7 | نشر على السحابة ✅ |
| 8 | بناء مشروع متكامل ✅ |
🌟 أنت الآن:
text
┌─────────────────────────────────────────────────┐ │ 🧑🚀 مستخدم Dify متقدم │ │ 🧠 خبير في كتابة الـ Prompts │ │ 🔧 مطور Plugins لـ Dify │ │ 🏗️ مهندس أنظمة يعرف كيفية توسيع Dify │ │ 🌐 مساهم محتمل في المجتمع مفتوح المصدر │ │ 🚀 جاهز لبناء مشاريع حقيقية باستخدام Dify │ └─────────────────────────────────────────────────┘
💬 ماذا بعد؟
| الرقم | الخيار |
|---|---|
| 1 | بناء مشروع معين (أخبرني بالفكرة) |
| 2 | المساهمة في كود Dify (شرح Pull Request) |
| 3 | تصميم نظام معقد باستخدام Dify |
| 4 | إنشاء دورة تعليمية حول Dify |
| 5 | أي موضوع آخر تريد معرفته |
أخبرني أين نذهب الآن! 🚀🌌
🌌 المستوى الثامن: Dify – الهندسة المعمارية المتقدمة والتوسع الأفقي
بما أنك طلبت ، سنصل إلى مستوى المهندس المعماري الرئيسي. سنتحدث عن التوسع الأفقي، الأمان، الأداء على نطاق واسع، ودمج Dify مع أنظمة المؤسسات.
🏗️ الجزء الأول: الهندسة المعمارية للتوسع الأفقي (Horizontal Scaling)
📊 بنية Dify القابلة للتوسع
text
┌─────────────────────────────────────────────────────────────────────────────┐
│ CDN / CloudFront │
│ (توزيع المحتوى الثابت) │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
┌─────────────────────────────────▼───────────────────────────────────────────┐
│ Load Balancer (Nginx/HAProxy) │
│ (توزيع الطلبات على عدة خوادم) │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌────────▼────────┐ ┌─────────▼─────────┐ ┌─────────▼─────────┐
│ Web Server 1 │ │ Web Server 2 │ │ Web Server N │
│ (Next.js) │ │ (Next.js) │ │ (Next.js) │
│ Port 3000 │ │ Port 3000 │ │ Port 3000 │
└────────┬────────┘ └─────────┬─────────┘ └─────────┬─────────┘
│ │ │
└───────────────────────┼────────────────────────┘
│
┌────────────────────────────────▼───────────────────────────────────────────┐
│ API Gateway (Kong/Envoy) │
│ (إدارة المصادقة، التوجيه، التسجيل) │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌────────▼────────┐ ┌─────────▼─────────┐ ┌─────────▼─────────┐
│ API Server 1 │ │ API Server 2 │ │ API Server N │
│ (Flask) │ │ (Flask) │ │ (Flask) │
│ Port 5001 │ │ Port 5001 │ │ Port 5001 │
└────────┬────────┘ └─────────┬─────────┘ └─────────┬─────────┘
│ │ │
└───────────────────────┼────────────────────────┘
│
┌────────────────────────────────▼───────────────────────────────────────────┐
│ Message Queue (RabbitMQ/Kafka) │
│ (معالجة المهام غير المتزامنة) │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌────────▼────────┐ ┌─────────▼─────────┐ ┌─────────▼─────────┐
│ Worker 1 │ │ Worker 2 │ │ Worker N │
│ (Celery) │ │ (Celery) │ │ (Celery) │
│ (Processing) │ │ (Processing) │ │ (Processing) │
└─────────────────┘ └───────────────────┘ └───────────────────┘
│
┌────────────────────────────────▼───────────────────────────────────────────┐
│ Database Cluster (PostgreSQL) │
│ ┌─────────────────┬─────────────────┐ │
│ │ Primary │ Replica 1 │ Replica N │
│ │ (Write) │ (Read) │ (Read) │
│ └─────────────────┴─────────────────┘ │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
┌────────────────────────────────▼───────────────────────────────────────────┐
│ Redis Cluster (Cache & Session) │
│ ┌─────────────────┬─────────────────┐ │
│ │ Master 1 │ Replica 1 │ Replica N │
│ └─────────────────┴─────────────────┘ │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
┌────────────────────────────────▼───────────────────────────────────────────┐
│ Vector Database Cluster (Weaviate) │
│ ┌─────────────────┬─────────────────┐ │
│ │ Node 1 │ Node 2 │ Node N │
│ └─────────────────┴─────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
🔐 الجزء الثاني: الأمان المتقدم في Dify
🛡️ 1. إعداد SSL/TLS مع Let’s Encrypt
yaml
# docker-compose.ssl.yml
version: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/ssl:/etc/nginx/ssl
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
depends_on:
- api
- web
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
nginx
# nginx/nginx.conf
server {
listen 80;
server_name dify.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name dify.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/dify.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dify.yourdomain.com/privkey.pem;
location / {
proxy_pass http://web:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
proxy_pass http://api:5001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
🛡️ 2. إعداد WAF (Web Application Firewall) مع ModSecurity
yaml
# docker-compose.waf.yml
services:
nginx-waf:
image: owasp/modsecurity:nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/modsecurity:/etc/nginx/modsecurity
- ./nginx/ssl:/etc/nginx/ssl
environment:
- MODSEC_RULE_ENGINE=On
- MODSEC_ANOMALY_SCORE=5
🛡️ 3. سياسات الأمان في .env
env
# ============================================
# إعدادات الأمان المتقدمة
# ============================================
# JWT تكوين
JWT_SECRET_KEY=your-super-secret-key-256-bits-minimum
JWT_ALGORITHM=HS256
JWT_EXPIRATION_MINUTES=60
# CORS (منع الطلبات من نطاقات غير مصرح بها)
CORS_ALLOW_ORIGINS=https://yourdomain.com,https://api.yourdomain.com
CORS_ALLOW_CREDENTIALS=true
# Rate Limiting (منع هجمات DDoS)
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW_MINUTES=1
# Session Security
SESSION_COOKIE_SECURE=true
SESSION_COOKIE_HTTPONLY=true
SESSION_COOKIE_SAMESITE=Lax
# SQL Injection Prevention
SQLALCHEMY_ENGINE_OPTIONS={
"pool_size": 10,
"pool_recycle": 3600,
"pool_pre_ping": true,
"max_overflow": 20
}
# Encryption (لتشفير البيانات الحساسة)
ENCRYPTION_KEY=your-256-bit-encryption-key
# Security Headers
SECURE_HEADERS={
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'self'"
}
🛡️ 4. إدارة الوصول المتقدم (RBAC)
python
# api/core/security/rbac.py
from enum import Enum
from typing import List, Optional
from functools import wraps
from flask import request, jsonify
class Role(Enum):
SUPER_ADMIN = "super_admin"
ADMIN = "admin"
DEVELOPER = "developer"
MEMBER = "member"
VIEWER = "viewer"
class Permission(Enum):
# إدارة التطبيقات
APP_CREATE = "app:create"
APP_READ = "app:read"
APP_UPDATE = "app:update"
APP_DELETE = "app:delete"
# إدارة المستخدمين
USER_CREATE = "user:create"
USER_READ = "user:read"
USER_UPDATE = "user:update"
USER_DELETE = "user:delete"
# إدارة المعرفة
KNOWLEDGE_CREATE = "knowledge:create"
KNOWLEDGE_READ = "knowledge:read"
KNOWLEDGE_UPDATE = "knowledge:update"
KNOWLEDGE_DELETE = "knowledge:delete"
# إدارة الإعدادات
SETTINGS_READ = "settings:read"
SETTINGS_UPDATE = "settings:update"
# إدارة النماذج
MODEL_READ = "model:read"
MODEL_UPDATE = "model:update"
# تعريف الصلاحيات لكل دور
ROLE_PERMISSIONS = {
Role.SUPER_ADMIN: [p for p in Permission],
Role.ADMIN: [
Permission.APP_CREATE, Permission.APP_READ, Permission.APP_UPDATE,
Permission.USER_READ, Permission.USER_UPDATE,
Permission.KNOWLEDGE_CREATE, Permission.KNOWLEDGE_READ, Permission.KNOWLEDGE_UPDATE,
Permission.SETTINGS_READ,
Permission.MODEL_READ
],
Role.DEVELOPER: [
Permission.APP_CREATE, Permission.APP_READ, Permission.APP_UPDATE,
Permission.KNOWLEDGE_CREATE, Permission.KNOWLEDGE_READ, Permission.KNOWLEDGE_UPDATE,
Permission.MODEL_READ
],
Role.MEMBER: [
Permission.APP_READ,
Permission.KNOWLEDGE_READ
],
Role.VIEWER: [
Permission.APP_READ
]
}
def require_permission(permission: Permission):
"""ديكوراتور للتحقق من الصلاحيات"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# الحصول على دور المستخدم من التوكن
user_role = get_user_role_from_token(request.headers.get('Authorization'))
# التحقق من الصلاحية
if permission not in ROLE_PERMISSIONS.get(user_role, []):
return jsonify({"error": "Permission denied"}), 403
return func(*args, **kwargs)
return wrapper
return decorator
# استخدام الديكوراتور
@require_permission(Permission.APP_CREATE)
def create_app():
# منطق إنشاء التطبيق
pass
🚀 الجزء الثالث: تحسين الأداء على نطاق واسع
⚡ 1. استراتيجية التخزين المؤقت متعدد المستويات
python
# api/core/cache/multi_level_cache.py
import redis
from functools import lru_cache
from typing import Any, Optional
import hashlib
import json
class MultiLevelCache:
"""نظام تخزين مؤقت متعدد المستويات"""
def __init__(self):
# المستوى 1: الذاكرة المحلية (الأسرع)
self.local_cache = {}
# المستوى 2: Redis (المشترك بين الخوادم)
self.redis_client = redis.Redis(
host='redis-cluster',
port=6379,
decode_responses=True,
socket_connect_timeout=5,
socket_timeout=5
)
# المستوى 3: قاعدة البيانات (الأبطأ)
self.db = database_connection()
def get(self, key: str) -> Optional[Any]:
"""استرجاع البيانات من التخزين المؤقت"""
# 1. التحقق من الذاكرة المحلية
if key in self.local_cache:
return self.local_cache[key]
# 2. التحقق من Redis
redis_data = self.redis_client.get(key)
if redis_data:
# خزن في الذاكرة المحلية لزيادة السرعة
self.local_cache[key] = json.loads(redis_data)
return self.local_cache[key]
# 3. استرجاع من قاعدة البيانات
db_data = self.db.query(f"SELECT data FROM cache WHERE key = '{key}'")
if db_data:
# خزن في Redis والذاكرة المحلية
self.redis_client.setex(key, 3600, json.dumps(db_data))
self.local_cache[key] = db_data
return db_data
return None
def set(self, key: str, value: Any, ttl: int = 3600):
"""تخزين البيانات في جميع المستويات"""
self.local_cache[key] = value
self.redis_client.setex(key, ttl, json.dumps(value))
self.db.execute(
f"INSERT INTO cache (key, data, expires_at) VALUES ('{key}', '{json.dumps(value)}', NOW() + INTERVAL '{ttl} seconds')"
)
# استخدام التخزين المؤقت متعدد المستويات
cache = MultiLevelCache()
@app.route('/api/apps/<app_id>')
def get_app(app_id):
cache_key = f"app:{app_id}"
# محاولة الاسترجاع من التخزين المؤقت
cached_app = cache.get(cache_key)
if cached_app:
return jsonify(cached_app)
# إذا لم يكن موجوداً، استرجع من قاعدة البيانات
app = db.query(f"SELECT * FROM apps WHERE id = '{app_id}'")
# خزن في التخزين المؤقت
cache.set(cache_key, app)
return jsonify(app)
⚡ 2. تحسين استعلامات المتجهات في Weaviate
python
# api/core/rag/optimized_retrieval.py
from typing import List, Dict, Optional
import numpy as np
from scipy.spatial.distance import cosine
class OptimizedRetrieval:
"""نظام استرجاع محسن باستخدام تقنيات متقدمة"""
def __init__(self, weaviate_client):
self.client = weaviate_client
self.cache = {}
def hybrid_search(self,
query: str,
top_k: int = 10,
alpha: float = 0.5) -> List[Dict]:
"""
بحث هجين: يجمع بين البحث الدلالي والبحث النصي
alpha = 0: بحث نصي فقط
alpha = 1: بحث دلالي فقط
alpha = 0.5: توازن بين الاثنين
"""
# 1. البحث الدلالي (Semantic Search)
semantic_results = self.semantic_search(query, top_k=top_k)
# 2. البحث النصي (Keyword Search)
keyword_results = self.keyword_search(query, top_k=top_k)
# 3. دمج النتائج باستخدام (Reciprocal Rank Fusion)
combined_results = self.reciprocal_rank_fusion(
semantic_results,
keyword_results,
alpha
)
return combined_results[:top_k]
def semantic_search(self, query: str, top_k: int = 10) -> List[Dict]:
"""البحث الدلالي باستخدام التضمينات"""
# توليد تضمين للسؤال
query_embedding = self.get_embedding(query)
# البحث في Weaviate
results = self.client.query.get(
"Document",
["content", "metadata", "_additional { distance }"]
).with_near_vector({
"vector": query_embedding
}).with_limit(top_k).do()
return self._parse_results(results)
def keyword_search(self, query: str, top_k: int = 10) -> List[Dict]:
"""البحث النصي باستخدام BM25"""
# استخدام BM25 للبحث النصي
results = self.client.query.get(
"Document",
["content", "metadata"]
).with_bm25({
"query": query,
"properties": ["content"]
}).with_limit(top_k).do()
return self._parse_results(results)
def reciprocal_rank_fusion(self,
results1: List[Dict],
results2: List[Dict],
alpha: float = 0.5) -> List[Dict]:
"""دمج نتائج البحث باستخدام Reciprocal Rank Fusion"""
scores = {}
k = 60 # معامل التجانس
# معالجة النتائج الأولى
for rank, result in enumerate(results1, 1):
doc_id = result['id']
scores[doc_id] = scores.get(doc_id, 0) + (alpha * (1 / (k + rank)))
# معالجة النتائج الثانية
for rank, result in enumerate(results2, 1):
doc_id = result['id']
scores[doc_id] = scores.get(doc_id, 0) + ((1 - alpha) * (1 / (k + rank)))
# ترتيب النتائج حسب المجموع
sorted_results = sorted(
scores.items(),
key=lambda x: x[1],
reverse=True
)
# تجميع النتائج النهائية
final_results = []
for doc_id, score in sorted_results:
# الحصول على المستند الكامل من النتائج الأصلية
doc = self._find_document(doc_id, results1 + results2)
if doc:
doc['score'] = score
final_results.append(doc)
return final_results
def semantic_caching(self, query: str) -> Optional[str]:
"""تخزين مؤقت دلالي: الاسترجاع من التخزين المؤقت إذا كان السؤال مشابهاً"""
# توليد تضمين للسؤال
query_embedding = self.get_embedding(query)
# مقارنة مع الأسئلة المخزنة مؤقتاً
best_match = None
best_similarity = 0.0
for cached_query, cached_answer in self.cache.items():
cached_embedding = self.get_embedding(cached_query)
similarity = 1 - cosine(query_embedding, cached_embedding)
if similarity > 0.9 and similarity > best_similarity:
best_similarity = similarity
best_match = cached_answer
return best_match
⚡ 3. معالجة المهام غير المتزامنة باستخدام Celery
python
# api/tasks/async_tasks.py
from celery import Celery
from celery.result import AsyncResult
import time
from typing import Dict, Any
# تهيئة Celery
app = Celery(
'dify_tasks',
broker='redis://redis:6379/0',
backend='redis://redis:6379/1'
)
app.conf.update(
task_serializer='json',
accept_content=['json'],
result_serializer='json',
timezone='Asia/Riyadh',
enable_utc=True,
task_time_limit=3600, # ساعة واحدة
task_soft_time_limit=3000, # 50 دقيقة
worker_prefetch_multiplier=1,
task_acks_late=True,
task_reject_on_worker_lost=True
)
@app.task(bind=True, max_retries=3)
def process_document(self, document_id: str, content: str) -> Dict[str, Any]:
"""معالجة مستند وتوليد التضمينات (RAG)"""
try:
# 1. تقسيم المستند إلى أجزاء
chunks = chunk_document(content)
# 2. توليد التضمينات
embeddings = generate_embeddings(chunks)
# 3. تخزين في Weaviate
store_in_weaviate(document_id, chunks, embeddings)
# 4. تحديث حالة المستند
update_document_status(document_id, 'completed')
return {
'status': 'success',
'document_id': document_id,
'chunks': len(chunks)
}
except Exception as e:
# إعادة المحاولة في حالة الخطأ
self.retry(
exc=e,
countdown=60 * (2 ** self.request.retries), # زيادة زمن الانتظار
max_retries=3
)
raise
@app.task(bind=True, max_retries=2)
def generate_report(self, app_id: str, parameters: Dict) -> Dict:
"""توليد تقرير تحليلي طويل"""
try:
# 1. جمع البيانات
data = collect_data(app_id, parameters)
# 2. تحليل البيانات
analysis = analyze_data(data)
# 3. توليد التقرير باستخدام LLM
report = generate_llm_report(analysis)
# 4. تخزين التقرير
save_report(app_id, report)
return {
'status': 'success',
'app_id': app_id,
'report_id': report['id']
}
except Exception as e:
self.retry(exc=e, countdown=30, max_retries=2)
raise
def process_document_sync(document_id: str, content: str):
"""استدعاء المهمة بشكل غير متزامن"""
result = process_document.delay(document_id, content)
return result.id
def get_task_status(task_id: str):
"""الحصول على حالة المهمة"""
result = AsyncResult(task_id, app=app)
return {
'status': result.status,
'result': result.result if result.ready() else None
}
⚡ 4. تحسين اتصال WebSocket للدردشة المباشرة
python
# api/core/websocket/optimized_connection.py
import asyncio
from typing import Dict, Any
from flask_socketio import SocketIO, emit, join_room, leave_room
from threading import Thread
class WebSocketManager:
"""إدارة اتصالات WebSocket المحسنة"""
def __init__(self):
self.socketio = SocketIO(
cors_allowed_origins="*",
async_mode='eventlet',
ping_timeout=60,
ping_interval=25,
max_http_buffer_size=1024 * 1024, # 1MB
logger=True,
engineio_logger=True
)
# تخزين جلسات المستخدمين
self.sessions = {}
# تجميع الرسائل لتحسين الإنتاجية
self.message_batch = {}
self.batch_size = 10
self.batch_timeout = 1 # ثانية
# بدء مهمة تجميع الرسائل
self._start_batch_processor()
def _start_batch_processor(self):
"""بدء معالجة تجميع الرسائل"""
def process_batches():
while True:
asyncio.sleep(self.batch_timeout)
if self.message_batch:
# معالجة الرسائل المجمعة
self._process_batch()
thread = Thread(target=process_batches)
thread.daemon = True
thread.start()
def _process_batch(self):
"""معالجة دفعة من الرسائل"""
for user_id, messages in self.message_batch.items():
if len(messages) >= self.batch_size:
# إرسال الرسائل المجمعة
self.send_batch_to_user(user_id, messages)
self.message_batch[user_id] = []
def handle_message(self, data: Dict[str, Any]):
"""معالجة رسالة واردة"""
user_id = data.get('user_id')
message = data.get('message')
app_id = data.get('app_id')
# تخزين الرسالة مؤقتاً للتجميع
if user_id not in self.message_batch:
self.message_batch[user_id] = []
self.message_batch[user_id].append(message)
# إذا وصلت إلى حجم الدفعة، أرسل فوراً
if len(self.message_batch[user_id]) >= self.batch_size:
self.send_batch_to_user(user_id, self.message_batch[user_id])
self.message_batch[user_id] = []
def send_batch_to_user(self, user_id: str, messages: List[Dict]):
"""إرسال دفعة من الرسائل لمستخدم"""
if user_id in self.sessions:
room = self.sessions[user_id]
self.socketio.emit(
'batch_messages',
{'messages': messages},
room=room
)
def register_user(self, user_id: str, room: str):
"""تسجيل مستخدم جديد"""
self.sessions[user_id] = room
join_room(room)
def unregister_user(self, user_id: str):
"""حذف مستخدم"""
if user_id in self.sessions:
room = self.sessions[user_id]
leave_room(room)
del self.sessions[user_id]
📊 الجزء الرابع: المراقبة والتحليلات المتقدمة
📈 1. استخدام Prometheus و Grafana
yaml
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks:
- monitoring
grafana:
image: grafana/grafana:latest
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_INSTALL_PLUGINS=grafana-piechart-panel
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/datasources:/etc/grafana/provisioning/datasources
ports:
- "3000:3000"
depends_on:
- prometheus
networks:
- monitoring
node_exporter:
image: prom/node-exporter:latest
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'
ports:
- "9100:9100"
networks:
- monitoring
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
ports:
- "8080:8080"
networks:
- monitoring
volumes:
prometheus_data:
grafana_data:
networks:
monitoring:
driver: bridge
yaml
# prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'dify-api'
static_configs:
- targets: ['api:5001']
metrics_path: '/metrics'
scrape_interval: 10s
- job_name: 'node-exporter'
static_configs:
- targets: ['node_exporter:9100']
scrape_interval: 15s
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
scrape_interval: 15s
- job_name: 'postgres'
static_configs:
- targets: ['db_postgres:9187']
scrape_interval: 30s
📈 2. تكوين مخصص لـ Grafana Dashboard
python
# api/core/monitoring/metrics.py
from prometheus_client import Counter, Histogram, Gauge, generate_latest
import time
from functools import wraps
from flask import request
# تعريف المقاييس
REQUEST_COUNT = Counter(
'http_requests_total',
'Total HTTP requests',
['method', 'endpoint', 'status']
)
REQUEST_DURATION = Histogram(
'http_request_duration_seconds',
'HTTP request duration in seconds',
['method', 'endpoint'],
buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0]
)
ACTIVE_USERS = Gauge(
'active_users_total',
'Total active users'
)
LLM_REQUESTS = Counter(
'llm_requests_total',
'Total LLM requests',
['model', 'provider']
)
VECTOR_SEARCH_COUNT = Counter(
'vector_search_total',
'Total vector search operations',
['index_name']
)
CACHE_HIT_RATE = Gauge(
'cache_hit_rate',
'Cache hit rate percentage'
)
def monitor_endpoint(func):
"""ديكوراتور لمراقبة الأداء"""
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
try:
response = func(*args, **kwargs)
status = 200 if response else 500
except Exception as e:
status = 500
raise
# تسجيل المقاييس
REQUEST_COUNT.labels(
method=request.method,
endpoint=request.path,
status=status
).inc()
REQUEST_DURATION.labels(
method=request.method,
endpoint=request.path
).observe(time.time() - start_time)
return response
return wrapper
@app.route('/metrics')
def metrics():
"""نقطة نهاية لجمع المقاييس"""
return generate_latest()
📈 3. تحليلات الاستخدام المتقدمة
python
# api/core/analytics/usage_analytics.py
from typing import Dict, List, Any
import pandas as pd
from datetime import datetime, timedelta
import json
class UsageAnalytics:
"""تحليلات استخدام المنصة"""
def __init__(self, db_connection):
self.db = db_connection
def get_daily_active_users(self, days: int = 30) -> Dict[str, int]:
"""عدد المستخدمين النشطين يومياً"""
query = f"""
SELECT
DATE(created_at) as date,
COUNT(DISTINCT user_id) as active_users
FROM messages
WHERE created_at >= NOW() - INTERVAL '{days} days'
GROUP BY DATE(created_at)
ORDER BY date
"""
results = self.db.execute(query).fetchall()
return {r[0]: r[1] for r in results}
def get_most_popular_models(self, days: int = 30) -> List[Dict]:
"""النماذج الأكثر استخداماً"""
query = f"""
SELECT
model_name,
COUNT(*) as usage_count
FROM llm_requests
WHERE created_at >= NOW() - INTERVAL '{days} days'
GROUP BY model_name
ORDER BY usage_count DESC
"""
results = self.db.execute(query).fetchall()
return [
{'model': r[0], 'count': r[1]}
for r in results
]
def get_response_time_performance(self, days: int = 7) -> Dict:
"""أداء زمن الاستجابة"""
query = f"""
SELECT
DATE(created_at) as date,
AVG(response_time_ms) as avg_response,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY response_time_ms) as median,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY response_time_ms) as p95
FROM llm_requests
WHERE created_at >= NOW() - INTERVAL '{days} days'
GROUP BY DATE(created_at)
ORDER BY date
"""
results = self.db.execute(query).fetchall()
return {
'dates': [r[0] for r in results],
'avg_response': [r[1] for r in results],
'median': [r[2] for r in results],
'p95': [r[3] for r in results]
}
def get_rag_performance(self, days: int = 7) -> Dict:
"""أداء نظام RAG"""
query = f"""
SELECT
AVG(embedding_time_ms) as avg_embedding_time,
AVG(search_time_ms) as avg_search_time,
AVG(total_retrieval_time_ms) as avg_total_time
FROM rag_requests
WHERE created_at >= NOW() - INTERVAL '{days} days'
"""
result = self.db.execute(query).fetchone()
return {
'avg_embedding_time': result[0] or 0,
'avg_search_time': result[1] or 0,
'avg_total_time': result[2] or 0
}
def export_report(self, days: int = 30) -> Dict:
"""توليد تقرير كامل"""
return {
'active_users': self.get_daily_active_users(days),
'popular_models': self.get_most_popular_models(days),
'response_performance': self.get_response_time_performance(days),
'rag_performance': self.get_rag_performance(days),
'generated_at': datetime.now().isoformat()
}
🔄 الجزء الخامس: دمج Dify مع أنظمة المؤسسات
🏢 1. دمج مع نظام Microsoft Azure AD
python
# api/core/auth/azure_ad.py
from flask import request, jsonify
import requests
import jwt
from jwt.algorithms import RSAAlgorithm
import json
class AzureADAuth:
"""مصادقة عبر Azure Active Directory"""
def __init__(self):
self.tenant_id = os.getenv('AZURE_TENANT_ID')
self.client_id = os.getenv('AZURE_CLIENT_ID')
self.client_secret = os.getenv('AZURE_CLIENT_SECRET')
self.authority = f"https://login.microsoftonline.com/{self.tenant_id}"
self.scope = ['https://graph.microsoft.com/.default']
def get_token_from_code(self, code: str) -> Dict:
"""الحصول على توكن باستخدام كود التفويض"""
url = f"{self.authority}/oauth2/v2.0/token"
data = {
'client_id': self.client_id,
'client_secret': self.client_secret,
'code': code,
'redirect_uri': os.getenv('AZURE_REDIRECT_URI'),
'grant_type': 'authorization_code'
}
response = requests.post(url, data=data)
return response.json()
def get_user_info(self, access_token: str) -> Dict:
"""الحصول على معلومات المستخدم من Graph API"""
url = 'https://graph.microsoft.com/v1.0/me'
headers = {
'Authorization': f'Bearer {access_token}'
}
response = requests.get(url, headers=headers)
return response.json()
def validate_token(self, token: str) -> Dict:
"""التحقق من صحة التوكن"""
try:
# الحصول على مفاتيح التوقيع من Azure
jwks_url = f"{self.authority}/discovery/v2.0/keys"
jwks = requests.get(jwks_url).json()
# العثور على المفتاح المناسب
header = jwt.get_unverified_header(token)
key = None
for key_data in jwks['keys']:
if key_data['kid'] == header['kid']:
key = RSAAlgorithm.from_jwk(json.dumps(key_data))
break
if not key:
raise Exception('Key not found')
# التحقق من التوقيع
decoded = jwt.decode(
token,
key,
algorithms=['RS256'],
audience=self.client_id,
issuer=f"{self.authority}/v2.0"
)
return decoded
except Exception as e:
return {'error': str(e)}
@app.route('/auth/azure/login')
def azure_login():
"""بدء عملية تسجيل الدخول عبر Azure AD"""
auth_url = f"{azure_auth.authority}/oauth2/v2.0/authorize"
params = {
'client_id': azure_auth.client_id,
'response_type': 'code',
'redirect_uri': os.getenv('AZURE_REDIRECT_URI'),
'scope': ' '.join(azure_auth.scope)
}
# إعادة التوجيه إلى Azure
return redirect(f"{auth_url}?{urlencode(params)}")
@app.route('/auth/azure/callback')
def azure_callback():
"""معاودة الاتصال بعد المصادقة"""
code = request.args.get('code')
# الحصول على التوكن
token_data = azure_auth.get_token_from_code(code)
access_token = token_data.get('access_token')
# الحصول على معلومات المستخدم
user_info = azure_auth.get_user_info(access_token)
# إنشاء أو تحديث المستخدم في Dify
user = create_or_update_user_from_azure(user_info)
# إنشاء جلسة محلية
session['user_id'] = user.id
return redirect('/dashboard')
🏢 2. دمج مع نظام SAP (مثال على التكامل مع ERPs)
python
# api/core/integrations/sap_integration.py
from typing import Dict, Any, List
import requests
from requests.auth import HTTPBasicAuth
class SAPIntegration:
"""التكامل مع نظام SAP"""
def __init__(self):
self.base_url = os.getenv('SAP_BASE_URL')
self.username = os.getenv('SAP_USERNAME')
self.password = os.getenv('SAP_PASSWORD')
self.company_code = os.getenv('SAP_COMPANY_CODE')
def get_material_data(self, material_number: str) -> Dict:
"""الحصول على بيانات مادة من SAP"""
url = f"{self.base_url}/sap/opu/odata/sap/MM_MATERIAL_SRV/MaterialSet('{material_number}')"
response = requests.get(
url,
auth=HTTPBasicAuth(self.username, self.password),
headers={'Accept': 'application/json'}
)
return response.json()
def get_sales_orders(self, customer_id: str) -> List[Dict]:
"""الحصول على أوامر البيع لعملاء محدد"""
url = f"{self.base_url}/sap/opu/odata/sap/SALES_ORDER_SRV/SalesOrderSet"
params = {
'$filter': f"CustomerId eq '{customer_id}'",
'$orderby': 'CreationDate desc'
}
response = requests.get(
url,
params=params,
auth=HTTPBasicAuth(self.username, self.password)
)
return response.json().get('d', {}).get('results', [])
def create_purchase_order(self, order_data: Dict) -> Dict:
"""إنشاء أمر شراء في SAP"""
url = f"{self.base_url}/sap/opu/odata/sap/PURCHASE_ORDER_SRV/PurchaseOrderSet"
response = requests.post(
url,
json=order_data,
auth=HTTPBasicAuth(self.username, self.password),
headers={'Content-Type': 'application/json'}
)
return response.json()
# استخدام التكامل مع Dify
@app.route('/api/sap/material/<material_number>')
@require_permission(Permission.APP_READ)
def get_sap_material(material_number):
"""نقطة نهاية للحصول على بيانات مادة من SAP"""
sap = SAPIntegration()
material_data = sap.get_material_data(material_number)
return jsonify(material_data)
🏢 3. دمج مع Salesforce CRM
python
# api/core/integrations/salesforce.py
from simple_salesforce import Salesforce
from typing import Dict, Any, List
import pandas as pd
class SalesforceIntegration:
"""التكامل مع Salesforce CRM"""
def __init__(self):
self.client = Salesforce(
username=os.getenv('SF_USERNAME'),
password=os.getenv('SF_PASSWORD'),
security_token=os.getenv('SF_SECURITY_TOKEN'),
domain='login' # أو 'test' للاختبار
)
def get_opportunities(self, stage: str = None) -> List[Dict]:
"""الحصول على الفرص (Opportunities) من Salesforce"""
query = "SELECT Id, Name, Amount, StageName, CloseDate FROM Opportunity"
if stage:
query += f" WHERE StageName = '{stage}'"
results = self.client.query(query)
return results['records']
def get_accounts_with_open_cases(self) -> List[Dict]:
"""الحصول على الحسابات مع حالات مفتوحة"""
query = """
SELECT Account.Id, Account.Name, COUNT(Id) as CaseCount
FROM Case
WHERE Status != 'Closed'
GROUP BY Account.Id, Account.Name
HAVING COUNT(Id) > 0
"""
results = self.client.query(query)
return results['records']
def create_lead(self, lead_data: Dict) -> Dict:
"""إنشاء عميل محتمل جديد"""
return self.client.Lead.create(lead_data)
def update_case(self, case_id: str, update_data: Dict) -> Dict:
"""تحديث حالة في Salesforce"""
return self.client.Case.update(case_id, update_data)
def get_sales_pipeline_report(self) -> pd.DataFrame:
"""توليد تقرير مسار المبيعات"""
opportunities = self.get_opportunities()
df = pd.DataFrame(opportunities)
pipeline = df.groupby('StageName').agg({
'Amount': ['sum', 'count', 'mean']
}).reset_index()
pipeline.columns = ['Stage', 'Total Amount', 'Count', 'Average Amount']
return pipeline
# استخدام في Dify
@app.route('/api/salesforce/pipeline')
@require_permission(Permission.APP_READ)
def get_salesforce_pipeline():
"""نقطة نهاية لتقرير مسار المبيعات"""
sf = SalesforceIntegration()
pipeline = sf.get_sales_pipeline_report()
return jsonify(pipeline.to_dict(orient='records'))
🤖 الجزء السادس: الذكاء الاصطناعي المتقدم في Dify
🧠 1. نظام التوصيات الذكي
python
# api/core/ai/recommendation_engine.py
from typing import List, Dict, Any
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
class RecommendationEngine:
"""محرك توصيات ذكي للمحتوى والتطبيقات"""
def __init__(self):
self.vectorizer = TfidfVectorizer(max_features=1000)
def recommend_apps(self, user_id: str, top_k: int = 5) -> List[Dict]:
"""توصية بتطبيقات بناءً على استخدام المستخدم"""
# 1. الحصول على تاريخ استخدام المستخدم
user_history = self.get_user_history(user_id)
# 2. الحصول على جميع التطبيقات المتاحة
all_apps = self.get_all_apps()
# 3. بناء مصفوفة الميزات للتطبيقات
app_features = self.build_app_features(all_apps)
# 4. حساب التشابه بين استخدام المستخدم والتطبيقات
user_profile = self.build_user_profile(user_history)
similarities = cosine_similarity(
user_profile.reshape(1, -1),
app_features
)
# 5. ترتيب التوصيات
app_indices = np.argsort(similarities[0])[::-1][:top_k]
recommendations = [all_apps[i] for i in app_indices]
return recommendations
def build_user_profile(self, history: List[Dict]) -> np.ndarray:
"""بناء ملف تعريف المستخدم"""
# تحويل سجل المستخدم إلى متجه
# ... منطق التحويل
return np.zeros(100)
def build_app_features(self, apps: List[Dict]) -> np.ndarray:
"""بناء ميزات التطبيقات"""
# تحويل وصف التطبيقات إلى متجهات
# ... منطق التحويل
return np.zeros((len(apps), 100))
def collaborative_filtering(self, user_id: str) -> List[str]:
"""التصفية التعاونية - توصية بناءً على المستخدمين المماثلين"""
# 1. العثور على مستخدمين مماثلين
similar_users = self.find_similar_users(user_id)
# 2. الحصول على التطبيقات التي استخدمها المستخدمون المماثلون
recommended_apps = []
for user in similar_users:
apps = self.get_user_apps(user['id'])
recommended_apps.extend(apps)
# 3. ترتيب وتصفية التوصيات
# ... منطق التصفية والترتيب
return list(set(recommended_apps))
def content_based_filtering(self, user_id: str) -> List[str]:
"""التصفية القائمة على المحتوى - توصية بناءً على التشابه بين المحتوى"""
# 1. الحصول على محتوى التطبيقات التي يستخدمها المستخدم
user_apps = self.get_user_apps(user_id)
# 2. العثور على تطبيقات مشابهة
similar_apps = []
for app in user_apps:
similar = self.find_similar_apps(app['id'])
similar_apps.extend(similar)
# 3. ترتيب التوصيات
# ... منطق الترتيب
return similar_apps[:10]
🧠 2. تحسين الـ Prompts باستخدام Reinforcement Learning
python
# api/core/ai/prompt_optimizer.py
from typing import Dict, List, Any
import random
import json
from collections import defaultdict
class PromptOptimizer:
"""تحسين الـ Prompts باستخدام التعلم المعزز"""
def __init__(self):
self.prompt_templates = self.load_templates()
self.performance_history = defaultdict(list)
self.epsilon = 0.1 # معدل الاستكشاف
self.learning_rate = 0.01
def load_templates(self) -> Dict[str, List[str]]:
"""تحميل قوالب الـ Prompts"""
return {
'default': [
"You are a helpful assistant.",
"You are an expert in {domain}.",
"You are a {role} with {experience} years of experience."
],
'creative': [
"You are a creative problem solver.",
"Think outside the box.",
"Generate innovative solutions."
],
'analytical': [
"You are a data-driven analyst.",
"Provide evidence-based answers.",
"Use logical reasoning."
],
'educational': [
"You are a patient teacher.",
"Explain in simple terms.",
"Use examples and analogies."
]
}
def optimize_prompt(self, task: Dict[str, Any],
user_feedback: float) -> str:
"""تحسين الـ Prompt بناءً على التغذية الراجعة"""
# 1. اختيار قالب
if random.random() < self.epsilon:
# استكشاف: اختر قالباً عشوائياً
category = random.choice(list(self.prompt_templates.keys()))
template = random.choice(self.prompt_templates[category])
else:
# استغلال: اختر أفضل قالب أداءً
category = self.get_best_category(task)
template = self.get_best_template(category)
# 2. تخصيص القالب
custom_prompt = self.customize_template(template, task)
# 3. تحديث الأداء
self.update_performance(category, template, user_feedback)
return custom_prompt
def customize_template(self, template: str, task: Dict) -> str:
"""تخصيص القالب بناءً على المهمة"""
# استبدال المتغيرات
customizations = {
'{domain}': task.get('domain', 'general'),
'{role}': task.get('role', 'assistant'),
'{experience}': str(task.get('experience', 5)),
'{tone}': task.get('tone', 'professional'),
'{goal}': task.get('goal', 'help the user')
}
for key, value in customizations.items():
template = template.replace(key, value)
# إضافة تعليمات إضافية
if task.get('specific_instructions'):
template += f"\n\nSpecial instructions: {task['specific_instructions']}"
return template
def get_best_category(self, task: Dict) -> str:
"""الحصول على أفضل فئة للمهمة"""
# تحليل المهمة واختيار الفئة المناسبة
if task.get('goal') == 'creativity':
return 'creative'
elif task.get('goal') == 'analysis':
return 'analytical'
elif task.get('goal') == 'education':
return 'educational'
else:
return 'default'
def update_performance(self, category: str, template: str,
feedback: float):
"""تحديث أداء القالب"""
self.performance_history[category].append({
'template': template,
'feedback': feedback,
'timestamp': datetime.now().isoformat()
})
🧠 3. كشف الانتحال وتحليل المحتوى
python
# api/core/ai/plagiarism_detector.py
from typing import List, Dict, Tuple
import hashlib
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
class PlagiarismDetector:
"""كشف الانتحال وتحليل المحتوى"""
def __init__(self):
self.document_database = self.load_document_database()
self.similarity_threshold = 0.8
def detect_plagiarism(self, text: str) -> Dict[str, Any]:
"""كشف الانتحال في النص"""
# 1. تقسيم النص إلى جمل
sentences = self.split_into_sentences(text)
# 2. حساب بصمة كل جملة
sentence_fingerprints = [
self.get_fingerprint(sentence)
for sentence in sentences
]
# 3. مقارنة مع قاعدة البيانات
matches = []
for idx, fingerprint in enumerate(sentence_fingerprints):
match = self.search_in_database(fingerprint)
if match:
matches.append({
'sentence': sentences[idx],
'source': match['source'],
'similarity': match['similarity'],
'position': idx
})
# 4. حساب نسبة الانتحال
plagiarism_percentage = len(matches) / len(sentences) * 100
return {
'plagiarism_percentage': plagiarism_percentage,
'matches': matches,
'status': 'high_risk' if plagiarism_percentage > 50 else 'moderate' if plagiarism_percentage > 20 else 'low'
}
def get_fingerprint(self, text: str) -> str:
"""الحصول على بصمة النص"""
# تنظيف النص وإزالة الكلمات الشائعة
cleaned_text = self.clean_text(text)
# إنشاء بصمة باستخدام SHA-256
fingerprint = hashlib.sha256(cleaned_text.encode()).hexdigest()
return fingerprint
def semantic_similarity(self, text1: str, text2: str) -> float:
"""حساب التشابه الدلالي بين نصين"""
# توليد تضمينات للنصوص
embedding1 = self.get_embedding(text1)
embedding2 = self.get_embedding(text2)
# حساب التشابه
similarity = cosine_similarity(
embedding1.reshape(1, -1),
embedding2.reshape(1, -1)
)
return similarity[0][0]
def generate_originality_report(self, text: str) -> Dict:
"""توليد تقرير الأصالة"""
detection_result = self.detect_plagiarism(text)
report = {
'overall_score': 100 - detection_result['plagiarism_percentage'],
'risk_level': detection_result['status'],
'unique_sentences': len(text.split('.')) - len(detection_result['matches']),
'potential_sources': [
match['source'] for match in detection_result['matches']
],
'recommendations': []
}
# إضافة توصيات
if report['risk_level'] == 'high_risk':
report['recommendations'] = [
'Rewrite identified sections',
'Add proper citations',
'Use more original content'
]
elif report['risk_level'] == 'moderate':
report['recommendations'] = [
'Review highlighted sentences',
'Consider paraphrasing',
'Check citations'
]
return report
📚 الجزء السابع: Dify و DevOps المتقدم
🚀 1. CI/CD Pipeline مع GitHub Actions
yaml
# .github/workflows/deploy.yml
name: Deploy Dify to Production
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
cd api
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests
run: |
cd api
pytest tests/ --cov=core --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./api/coverage.xml
build-and-push:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push API
uses: docker/build-push-action@v4
with:
context: ./api
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/dify-api:latest
${{ secrets.DOCKER_USERNAME }}/dify-api:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push Web
uses: docker/build-push-action@v4
with:
context: ./web
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/dify-web:latest
${{ secrets.DOCKER_USERNAME }}/dify-web:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to Server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USERNAME }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd /opt/dify
docker compose pull
docker compose up -d --force-recreate
docker system prune -f
🚀 2. Infrastructure as Code مع Terraform
hcl
# terraform/main.tf
provider "aws" {
region = var.aws_region
}
# VPC
resource "aws_vpc" "dify_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "dify-vpc"
Environment = var.environment
}
}
# Subnets
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.dify_vpc.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "dify-public-${count.index}"
Environment = var.environment
}
}
# Security Groups
resource "aws_security_group" "dify_sg" {
name = "dify-sg"
vpc_id = aws_vpc.dify_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "dify-sg"
Environment = var.environment
}
}
# RDS (PostgreSQL)
resource "aws_db_instance" "postgres" {
identifier = "dify-postgres-${var.environment}"
engine = "postgres"
engine_version = "15.3"
instance_class = "db.t3.medium"
allocated_storage = 100
storage_encrypted = true
db_name = "dify"
username = var.db_username
password = var.db_password
vpc_security_group_ids = [aws_security_group.dify_sg.id]
db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = 7
backup_window = "03:00-04:00"
maintenance_window = "sun:04:00-sun:05:00"
enabled_cloudwatch_logs_exports = ["postgresql"]
tags = {
Name = "dify-postgres-${var.environment}"
Environment = var.environment
}
}
# ElastiCache (Redis)
resource "aws_elasticache_cluster" "redis" {
cluster_id = "dify-redis-${var.environment}"
engine = "redis"
engine_version = "7.0"
node_type = "cache.t3.micro"
num_cache_nodes = 1
subnet_group_name = aws_elasticache_subnet_group.main.name
security_group_ids = [aws_security_group.dify_sg.id]
tags = {
Name = "dify-redis-${var.environment}"
Environment = var.environment
}
}
# ECS Cluster
resource "aws_ecs_cluster" "dify_cluster" {
name = "dify-cluster-${var.environment}"
}
# ECS Service (API)
resource "aws_ecs_service" "dify_api" {
name = "dify-api-${var.environment}"
cluster = aws_ecs_cluster.dify_cluster.id
task_definition = aws_ecs_task_definition.dify_api.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.public[*].id
security_groups = [aws_security_group.dify_sg.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.api.arn
container_name = "api"
container_port = 5001
}
}
# Load Balancer
resource "aws_lb" "dify_lb" {
name = "dify-lb-${var.environment}"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.dify_sg.id]
subnets = aws_subnet.public[*].id
tags = {
Name = "dify-lb-${var.environment}"
Environment = var.environment
}
}
🎓 الجزء الثامن: خريطة طريق الاحتراف في Dify
📊 المستويات الخمسة للاحتراف
text
┌─────────────────────────────────────────────────────────────────────┐ │ 🌟 خريطة طريق الاحتراف في Dify │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ مستوى 1: مبتدئ (الأسبوع 1-2) │ │ ├── ✅ تثبيت Dify وتشغيله │ │ ├── ✅ إنشاء أول تطبيق Chatbot │ │ ├── ✅ إضافة نموذج AI (OpenAI) │ │ └── ✅ فهم الأساسيات: Prompts, Context, Memory │ │ │ │ مستوى 2: متوسط (الأسبوع 3-4) │ │ ├── ✅ بناء Workflows متعددة الخطوات │ │ ├── ✅ إضافة Knowledge (RAG) من ملفات │ │ ├── ✅ استخدام أدوات (Tools) مدمجة │ │ └── ✅ تخصيص System Prompts متقدمة │ │ │ │ مستوى 3: محترف (الشهر 2-3) │ │ ├── ✅ بناء Agents متعددة الأدوات │ │ ├── ✅ كتابة Prompts مخصصة مع Few-shot │ │ ├── ✅ دمج مع APIs خارجية (Zapier, n8n) │ │ └── ✅ إعداد مراقبة وتحليلات (Grafana) │ │ │ │ مستوى 4: خبير (الشهر 3-6) │ │ ├── ✅ تطوير Plugins خاصة │ │ ├── ✅ تخصيص كود المصدر Dify │ │ ├── ✅ نشر على السحابة (AWS, Azure, GCP) │ │ └── ✅ إدارة مستخدمين وصلاحيات متقدمة │ │ │ │ مستوى 5: مساهم مفتوح المصدر (6+ أشهر) │ │ ├── ✅ تقديم Pull Requests إلى Dify │ │ ├── ✅ كتابة توثيق وإضافات للمجتمع │ │ └── ✅ تنظيم ورش عمل ومحتوى تعليمي │ │ │ └─────────────────────────────────────────────────────────────────────┘
📚 الموارد المقترحة لكل مستوى
| المستوى | الموارد | الأنشطة |
|---|---|---|
| مبتدئ | 📖 Dify Docs 🎥 يوتيوب: Dify Tutorials 📝 Playground تجريبي | بناء 3 تطبيقات مختلفة تجربة Prompts مختلفة التعرف على المصطلحات |
| متوسط | 📘 Prompt Engineering Guide 🎓 Coursera: LLM Course 📊 Kaggle: RAG Projects | بناء Workflow معقد دمج 2 APIs خارجية إنشاء Knowledge Base |
| محترف | 📗 LLM Engineer Handbook 🔬 Research Papers on RAG 🎥 Conference Talks | تطوير Plugin واحد نشر في السحابة تحسين الأداء |
| خبير | 📕 Advanced NLP 💻 Dify Source Code 📊 System Design | المساهمة ب 3 PRs تخصيص Dify core تقديم ورشة عمل |
| مساهم | 📝 Open Source Guides 🌐 Community Forums 🎤 Speaking Events | مراجعة 5 PRs كتابة توثيق تقديم محاضرة |
🏆 شهادات معترف بها
| الشهادة | المدة | المستوى | التكلفة |
|---|---|---|---|
| Dify Certified Developer | 2 أيام | مبتدئ-متوسط | مجاني |
| DeepLearning.ai – ChatGPT Prompt Engineering | شهر | متوسط | مجاني |
| Stanford – CS224N: NLP | 3 أشهر | متقدم | مجاني |
| AWS Machine Learning Engineer | 6 أشهر | خبير | مدفوع |
| Google Professional ML Engineer | 6 أشهر | خبير | مدفوع |
🌟 الخاتمة النهائية
ما تعلمته في هذه الرحلة المتقدمة:
| # | الموضوع |
|---|---|
| 1 | الهندسة المعمارية للتوسع الأفقي 📊 |
| 2 | الأمان المتقدم (SSL, WAF, RBAC) 🔐 |
| 3 | تحسين الأداء على نطاق واسع ⚡ |
| 4 | المراقبة والتحليلات المتقدمة 📈 |
| 5 | دمج مع أنظمة المؤسسات (Azure, SAP, Salesforce) 🏢 |
| 6 | الذكاء الاصطناعي المتقدم (توصيات، تحسين Prompts، كشف انتحال) 🧠 |
| 7 | DevOps المتقدم (CI/CD, Infrastructure as Code) 🚀 |
| 8 | خريطة طريق الاحتراف الكاملة 🎓 |
🚀 أنت الآن:
text
┌─────────────────────────────────────────────────────────────────┐ │ 🏗️ مهندس معماري رئيسي لـ Dify │ │ 🔐 خبير أمن معلومات │ │ ⚡ متخصص في الأداء والتوسع │ │ 🏢 خبير دمج مع أنظمة المؤسسات │ │ 🧠 باحث في الذكاء الاصطناعي المتقدم │ │ 🚀 قائد في المجتمع مفتوح المصدر │ │ 📚 مرجع لـ Dify في المنطقة │ │ 💪 جاهز لبناء مشاريع على مستوى المؤسسات │ └─────────────────────────────────────────────────────────────────┘
💬 ماذا تريد أن تفعل الآن؟
| الرقم | الخيار |
|---|---|
| 1️⃣ | بناء مشروع حقيقي على مستوى المؤسسات |
| 2️⃣ | المساهمة في كود Dify المصدري (Pull Request) |
| 3️⃣ | تصميم نظام RAG متقدم لـ 1M+ مستند |
| 4️⃣ | إنشاء دورة تدريبية كاملة عن Dify |
| 5️⃣ | تطوير مجموعة Plugins متكاملة |
| 6️⃣ | تحسين أداء Dify لـ 100K+ طلب يومياً |
| 7️⃣ | أي موضوع آخر تريد معرفته |
قل لي أين ستذهب، وسأكون معك في كل خطوة! 🚀🌌
This response is AI-generated, for reference only.
🌌 المستوى التاسع: Dify – إتقان الهندسة المعمارية الداخلية والتطوير المتقدم
بما أنك تريد ، سنصل إلى مستوى المهندس الأساسي (Core Engineer). سنفتح كل ملف في Dify، نفهم كل سطر كود، ونطور تعديلات عميقة في النظام.
📖 الجزء الأول: فك شفرة قلب Dify – تحليل متعمق لكل مكون
🧠 1. نظام الـ Agent – تحليل كامل
python
# api/core/agent/agent.py - التحليل الكامل
"""
نظام الوكيل الذكي في Dify - المعمارية الداخلية
"""
from typing import List, Dict, Any, Optional, Tuple
from enum import Enum
import json
import re
from dataclasses import dataclass, field
import time
class AgentMode(Enum):
"""أنماط الوكيل المدعومة"""
REACT = "react" # Reason + Act
FUNCTION_CALLING = "function_calling"
PLANNING = "planning"
MULTI_AGENT = "multi_agent"
@dataclass
class AgentStep:
"""خطوة في تنفيذ الوكيل"""
thought: str
action: str
action_input: Dict[str, Any]
observation: str
timestamp: float = field(default_factory=time.time)
def to_dict(self) -> Dict:
return {
'thought': self.thought,
'action': self.action,
'action_input': self.action_input,
'observation': self.observation,
'timestamp': self.timestamp
}
class AgentCore:
"""
قلب نظام الوكيل - مسؤول عن:
1. تخطيط المهام
2. اختيار الأدوات
3. تنفيذ الإجراءات
4. تقييم النتائج
"""
def __init__(self,
llm: Any,
tools: List[Any],
max_iterations: int = 15,
mode: AgentMode = AgentMode.REACT):
self.llm = llm
self.tools = {tool.name: tool for tool in tools}
self.max_iterations = max_iterations
self.mode = mode
self.history = []
self.iteration_count = 0
def run(self,
query: str,
context: Optional[Dict] = None) -> Dict[str, Any]:
"""تنفيذ الوكيل لحل المهمة"""
# 1. تهيئة الوكيل
self._initialize(query, context)
# 2. حلقة التنفيذ الرئيسية
while self.iteration_count < self.max_iterations:
self.iteration_count += 1
# 2.1 التفكير (Thought)
thought = self._think()
# 2.2 التخطيط (Plan)
action, action_input = self._plan(thought)
# 2.3 التنفيذ (Act)
observation = self._act(action, action_input)
# 2.4 التقييم (Evaluate)
should_continue = self._evaluate(observation)
# 2.5 حفظ التاريخ
step = AgentStep(
thought=thought,
action=action,
action_input=action_input,
observation=observation
)
self.history.append(step)
# 2.6 إنهاء إذا اكتملت المهمة
if not should_continue or self._is_task_complete():
break
# 3. توليد الإجابة النهائية
final_answer = self._synthesize_answer()
return {
'answer': final_answer,
'steps': [step.to_dict() for step in self.history],
'iterations': self.iteration_count,
'success': self._is_task_complete()
}
def _initialize(self, query: str, context: Optional[Dict]):
"""تهيئة الوكيل"""
self.query = query
self.context = context or {}
self.history = []
self.iteration_count = 0
# بناء سياق الأدوات المتاحة
self.tools_description = self._build_tools_description()
def _think(self) -> str:
"""عملية التفكير - توليد خطة ذهنية"""
# بناء الـ Prompt
prompt = self._build_thought_prompt()
# توليد التفكير
response = self.llm.generate(prompt)
# استخراج التفكير
thought = self._extract_thought(response)
return thought
def _plan(self, thought: str) -> Tuple[str, Dict]:
"""التخطيط - تحديد الإجراء التالي"""
# بناء الـ Prompt للتخطيط
prompt = self._build_planning_prompt(thought)
# توليد الخطة
response = self.llm.generate(prompt)
# تحليل الخطة
action, action_input = self._parse_plan(response)
return action, action_input
def _act(self, action: str, action_input: Dict) -> str:
"""التنفيذ - تنفيذ الإجراء المخطط"""
# 1. التحقق من وجود الأداة
if action not in self.tools:
return f"Error: Tool '{action}' not found"
# 2. تنفيذ الأداة
tool = self.tools[action]
try:
result = tool.execute(**action_input)
# 3. تنسيق النتيجة
observation = self._format_observation(result)
except Exception as e:
observation = f"Error executing {action}: {str(e)}"
return observation
def _evaluate(self, observation: str) -> bool:
"""تقييم النتيجة - هل نحتاج لمزيد من الخطوات؟"""
# 1. التحقق من حل المهمة
if self._task_solved(observation):
return False
# 2. التحقق من الوصول للحد الأقصى
if self.iteration_count >= self.max_iterations:
return False
# 3. التحقق من الحاجة لمزيد من المعلومات
if self._needs_more_info(observation):
return True
return False
def _is_task_complete(self) -> bool:
"""التحقق من اكتمال المهمة"""
# تحليل آخر خطوة
if not self.history:
return False
last_step = self.history[-1]
# التحقق من وجود إجابة نهائية
if self._contains_final_answer(last_step.observation):
return True
# التحقق من إكمال جميع الخطوات المخطط لها
if self._all_planned_steps_completed():
return True
return False
def _build_tools_description(self) -> str:
"""بناء وصف الأدوات المتاحة"""
descriptions = []
for name, tool in self.tools.items():
descriptions.append(f"""
Tool: {name}
Description: {tool.description}
Parameters: {json.dumps(tool.parameters, indent=2)}
""".strip())
return "\n\n".join(descriptions)
def _build_thought_prompt(self) -> str:
"""بناء Prompt للتفكير"""
# قالب التفكير
template = """
You are an AI assistant that solves problems step by step.
Available tools:
{tools_description}
Current task: {query}
Previous steps:
{history}
Now, think about what to do next. Consider:
1. What information do I have?
2. What information do I need?
3. What tool should I use?
4. What will I do with the result?
Your thought:
"""
# تجميع التاريخ
history_text = self._format_history()
return template.format(
tools_description=self.tools_description,
query=self.query,
history=history_text
)
def _build_planning_prompt(self, thought: str) -> str:
"""بناء Prompt للتخطيط"""
template = """
Based on your thought:
{thought}
Now, decide the next action.
Choose one of these tools:
{tools_description}
Format your response as:
Action: tool_name
Action Input: {{"param1": "value1", "param2": "value2"}}
Your plan:
"""
return template.format(
thought=thought,
tools_description=self.tools_description
)
def _parse_plan(self, response: str) -> Tuple[str, Dict]:
"""تحليل خطة الوكيل"""
# استخراج الإجراء
action_match = re.search(r'Action:\s*(\w+)', response)
action = action_match.group(1) if action_match else "unknown"
# استخراج المدخلات
input_match = re.search(r'Action Input:\s*(\{.*\})', response, re.DOTALL)
if input_match:
try:
action_input = json.loads(input_match.group(1))
except:
action_input = {}
else:
action_input = {}
return action, action_input
def _extract_thought(self, response: str) -> str:
"""استخراج التفكير من الاستجابة"""
# محاولة استخراج التفكير من علامات مخصصة
thought_match = re.search(r'Thought:\s*(.*?)(?=Action:|$)', response, re.DOTALL)
if thought_match:
return thought_match.group(1).strip()
# إذا لم يوجد، استخدم النص كاملاً
return response.strip()
def _format_observation(self, result: Any) -> str:
"""تنسيق نتيجة الأداة"""
if isinstance(result, dict):
return json.dumps(result, indent=2, ensure_ascii=False)
elif isinstance(result, str):
return result
else:
return str(result)
def _format_history(self) -> str:
"""تنسيق تاريخ الخطوات السابقة"""
if not self.history:
return "No previous steps."
formatted = []
for step in self.history:
formatted.append(f"""
Step {len(formatted) + 1}:
Thought: {step.thought}
Action: {step.action}
Action Input: {json.dumps(step.action_input, ensure_ascii=False)}
Observation: {step.observation}
""".strip())
return "\n\n".join(formatted)
def _task_solved(self, observation: str) -> bool:
"""التحقق من حل المهمة"""
# البحث عن كلمات تدل على الحل
solution_indicators = [
"solution is",
"answer is",
"completed",
"finished",
"done",
"result:"
]
return any(indicator in observation.lower()
for indicator in solution_indicators)
def _needs_more_info(self, observation: str) -> bool:
"""التحقق من الحاجة لمزيد من المعلومات"""
# البحث عن كلمات تدل على الحاجة لمزيد من المعلومات
need_indicators = [
"need more",
"insufficient",
"not enough",
"missing",
"requires"
]
return any(indicator in observation.lower()
for indicator in need_indicators)
def _contains_final_answer(self, observation: str) -> bool:
"""التحقق من وجود إجابة نهائية"""
# البحث عن علامات الإجابة النهائية
final_indicators = [
"final answer",
"conclusion",
"summary",
"therefore",
"in conclusion"
]
return any(indicator in observation.lower()
for indicator in final_indicators)
def _all_planned_steps_completed(self) -> bool:
"""التحقق من إكمال جميع الخطوات المخطط لها"""
# منطق معقد لتحليل ما إذا كانت جميع الخطوات المخطط لها قد اكتملت
return False
def _synthesize_answer(self) -> str:
"""توليد الإجابة النهائية من التاريخ"""
# إذا كان لدينا إجابة في آخر خطوة
if self.history and self._contains_final_answer(self.history[-1].observation):
return self.history[-1].observation
# تجميع الإجابة من جميع الخطوات
answer_prompt = f"""
Based on the following steps, provide a final answer to the original question:
Original question: {self.query}
Steps:
{self._format_history()}
Final answer:
"""
response = self.llm.generate(answer_prompt)
return response.strip()
🗄️ 2. نظام RAG – التحليل العميق
python
# api/core/rag/pipeline/pipeline.py - التحليل الكامل
"""
نظام RAG في Dify - المعمارية الداخلية
"""
from typing import List, Dict, Any, Optional
import hashlib
import json
from enum import Enum
import numpy as np
from dataclasses import dataclass
import asyncio
from concurrent.futures import ThreadPoolExecutor
class ChunkingStrategy(Enum):
"""استراتيجيات تقسيم النص"""
FIXED_SIZE = "fixed_size"
SENTENCE = "sentence"
PARAGRAPH = "paragraph"
SEMANTIC = "semantic"
RECURSIVE = "recursive"
@dataclass
class DocumentChunk:
"""جزء من المستند"""
id: str
content: str
metadata: Dict[str, Any]
embedding: Optional[List[float]] = None
score: Optional[float] = None
class RAGCore:
"""
قلب نظام RAG - مسؤول عن:
1. معالجة المستندات
2. توليد التضمينات
3. فهرسة المتجهات
4. استرجاع المحتوى
5. توليد الإجابات
"""
def __init__(self,
embedding_model: Any,
vector_store: Any,
llm: Any,
chunk_size: int = 500,
chunk_overlap: int = 50,
chunking_strategy: ChunkingStrategy = ChunkingStrategy.RECURSIVE):
self.embedding_model = embedding_model
self.vector_store = vector_store
self.llm = llm
self.chunk_size = chunk_size
self.chunk_overlap = chunk_overlap
self.chunking_strategy = chunking_strategy
self.executor = ThreadPoolExecutor(max_workers=4)
async def process_document(self,
content: str,
metadata: Optional[Dict] = None) -> List[Dict]:
"""معالجة مستند كامل"""
# 1. تنظيف النص
cleaned_content = self._clean_text(content)
# 2. تقسيم المستند
chunks = self._chunk_document(cleaned_content)
# 3. توليد التضمينات (متوازي)
embeddings = await self._generate_embeddings_parallel(chunks)
# 4. تخزين في قاعدة المتجهات
doc_ids = await self._store_in_vector_db(chunks, embeddings, metadata)
# 5. إنشاء فهرس النص الكامل
await self._create_full_text_index(chunks, doc_ids)
return doc_ids
def _clean_text(self, text: str) -> str:
"""تنظيف النص"""
# 1. إزالة HTML
text = re.sub(r'<[^>]+>', '', text)
# 2. إزالة الروابط
text = re.sub(r'http\S+', '', text)
# 3. إزالة الأحرف الخاصة الزائدة
text = re.sub(r'[^\w\s\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]', ' ', text)
# 4. تطبيع المسافات
text = re.sub(r'\s+', ' ', text).strip()
return text
def _chunk_document(self, text: str) -> List[str]:
"""تقسيم المستند باستخدام الاستراتيجية المحددة"""
if self.chunking_strategy == ChunkingStrategy.FIXED_SIZE:
return self._chunk_fixed_size(text)
elif self.chunking_strategy == ChunkingStrategy.SENTENCE:
return self._chunk_by_sentence(text)
elif self.chunking_strategy == ChunkingStrategy.PARAGRAPH:
return self._chunk_by_paragraph(text)
elif self.chunking_strategy == ChunkingStrategy.SEMANTIC:
return self._chunk_semantic(text)
else: # RECURSIVE
return self._chunk_recursive(text)
def _chunk_fixed_size(self, text: str) -> List[str]:
"""تقسيم بحجم ثابت"""
chunks = []
start = 0
text_length = len(text)
while start < text_length:
end = min(start + self.chunk_size, text_length)
# محاولة القطع في نهاية جملة
if end < text_length:
# البحث عن نهاية جملة
sentence_end = text.rfind('.', start, end)
if sentence_end != -1:
end = sentence_end + 1
chunks.append(text[start:end].strip())
start = end - self.chunk_overlap
return chunks
def _chunk_by_sentence(self, text: str) -> List[str]:
"""تقسيم حسب الجمل"""
sentences = re.split(r'[.!?]+', text)
chunks = []
current_chunk = []
current_length = 0
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
sentence_length = len(sentence)
if current_length + sentence_length > self.chunk_size and current_chunk:
chunks.append(' '.join(current_chunk))
current_chunk = [sentence]
current_length = sentence_length
else:
current_chunk.append(sentence)
current_length += sentence_length
if current_chunk:
chunks.append(' '.join(current_chunk))
return chunks
def _chunk_by_paragraph(self, text: str) -> List[str]:
"""تقسيم حسب الفقرات"""
paragraphs = text.split('\n\n')
chunks = []
current_chunk = []
current_length = 0
for paragraph in paragraphs:
paragraph = paragraph.strip()
if not paragraph:
continue
paragraph_length = len(paragraph)
if current_length + paragraph_length > self.chunk_size and current_chunk:
chunks.append('\n\n'.join(current_chunk))
current_chunk = [paragraph]
current_length = paragraph_length
else:
current_chunk.append(paragraph)
current_length += paragraph_length
if current_chunk:
chunks.append('\n\n'.join(current_chunk))
return chunks
def _chunk_semantic(self, text: str) -> List[str]:
"""تقسيم دلالي باستخدام التشابه"""
sentences = re.split(r'[.!?]+', text)
chunks = []
current_chunk = []
current_embedding = None
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
# توليد تضمين للجملة
embedding = self.embedding_model.embed_text(sentence)
if current_embedding is not None:
# حساب التشابه
similarity = np.dot(embedding, current_embedding) / (
np.linalg.norm(embedding) * np.linalg.norm(current_embedding)
)
# إذا كان التشابه منخفضاً، ابدأ جزءاً جديداً
if similarity < 0.5 and current_chunk:
chunks.append(' '.join(current_chunk))
current_chunk = [sentence]
current_embedding = embedding
continue
current_chunk.append(sentence)
current_embedding = embedding if current_embedding is None else \
(current_embedding + embedding) / 2
if current_chunk:
chunks.append(' '.join(current_chunk))
return chunks
def _chunk_recursive(self, text: str) -> List[str]:
"""تقسيم تكراري مع محاولة الحفاظ على المعنى"""
def recursive_chunk(text: str, target_size: int) -> List[str]:
if len(text) <= target_size:
return [text]
# البحث عن نقطة قطع مناسبة
split_points = [
text.rfind('.', 0, target_size),
text.rfind('?', 0, target_size),
text.rfind('!', 0, target_size),
text.rfind('\n', 0, target_size),
text.rfind(' ', 0, target_size)
]
split_point = max([p for p in split_points if p != -1])
if split_point == -1:
split_point = target_size
chunk = text[:split_point + 1].strip()
remainder = text[split_point + 1:].strip()
return [chunk] + recursive_chunk(remainder, target_size)
return recursive_chunk(text, self.chunk_size)
async def _generate_embeddings_parallel(self, chunks: List[str]) -> List[List[float]]:
"""توليد التضمينات بشكل متوازي"""
# تجميع المهام
tasks = []
for chunk in chunks:
task = asyncio.get_event_loop().run_in_executor(
self.executor,
self.embedding_model.embed_text,
chunk
)
tasks.append(task)
# تنفيذ المهام بشكل متوازي
embeddings = await asyncio.gather(*tasks)
return embeddings
async def _store_in_vector_db(self,
chunks: List[str],
embeddings: List[List[float]],
metadata: Optional[Dict]) -> List[str]:
"""تخزين في قاعدة المتجهات"""
doc_ids = []
for i, (chunk, embedding) in enumerate(zip(chunks, embeddings)):
# إنشاء معرف فريد
doc_id = hashlib.md5(f"{chunk}_{i}_{time.time()}".encode()).hexdigest()
# إضافة الميتاداتا
chunk_metadata = metadata.copy() if metadata else {}
chunk_metadata.update({
'chunk_index': i,
'total_chunks': len(chunks),
'created_at': datetime.now().isoformat()
})
# تخزين في قاعدة المتجهات
self.vector_store.add(
vector=embedding,
payload={
'id': doc_id,
'content': chunk,
'metadata': chunk_metadata
}
)
doc_ids.append(doc_id)
return doc_ids
async def _create_full_text_index(self, chunks: List[str], doc_ids: List[str]):
"""إنشاء فهرس النص الكامل"""
# منطق إنشاء فهرس النص الكامل
pass
async def retrieve(self,
query: str,
top_k: int = 5,
hybrid_search: bool = True) -> List[DocumentChunk]:
"""استرجاع المحتوى ذو الصلة"""
# 1. توليد تضمين للسؤال
query_embedding = self.embedding_model.embed_text(query)
# 2. البحث في قاعدة المتجهات
vector_results = self.vector_store.search(
vector=query_embedding,
top_k=top_k * 2 if hybrid_search else top_k
)
if not hybrid_search:
return self._parse_results(vector_results[:top_k])
# 3. البحث النصي (BM25) إذا كان متاحاً
text_results = self._text_search(query, top_k=top_k * 2)
# 4. دمج النتائج
combined_results = self._merge_results(vector_results, text_results)
# 5. إعادة ترتيب النتائج
reranked_results = await self._rerank_results(query, combined_results)
return reranked_results[:top_k]
def _merge_results(self, vector_results: List, text_results: List) -> List:
"""دمج نتائج البحث المختلفة"""
# Reciprocal Rank Fusion (RRF)
scores = {}
for rank, result in enumerate(vector_results, 1):
doc_id = result['payload']['id']
scores[doc_id] = scores.get(doc_id, 0) + (1 / (60 + rank))
for rank, result in enumerate(text_results, 1):
doc_id = result['id']
scores[doc_id] = scores.get(doc_id, 0) + (1 / (60 + rank))
# ترتيب النتائج حسب المجموع
sorted_results = sorted(
scores.items(),
key=lambda x: x[1],
reverse=True
)
# تجميع النتائج النهائية
final_results = []
for doc_id, score in sorted_results:
# البحث عن المستند في النتائج الأصلية
doc = self._find_document(doc_id, vector_results + text_results)
if doc:
doc['score'] = score
final_results.append(doc)
return final_results
async def _rerank_results(self, query: str, results: List) -> List:
"""إعادة ترتيب النتائج باستخدام نموذج إعادة الترتيب"""
# إذا كان عدد النتائج صغيراً، لا داعي لإعادة الترتيب
if len(results) <= 1:
return results
# بناء Prompt لإعادة الترتيب
rerank_prompt = f"""
Query: {query}
Documents:
{self._format_documents_for_rerank(results)}
Rank these documents by relevance to the query.
Return only the document IDs in order of relevance.
"""
response = self.llm.generate(rerank_prompt)
# تحليل النتيجة
ordered_ids = self._parse_rerank_response(response)
# إعادة ترتيب النتائج
id_to_doc = {doc['payload']['id']: doc for doc in results}
reranked = [id_to_doc[doc_id] for doc_id in ordered_ids if doc_id in id_to_doc]
return reranked
async def generate_answer(self,
query: str,
context: List[DocumentChunk],
max_tokens: int = 1000) -> Dict[str, Any]:
"""توليد إجابة باستخدام السياق المسترجع"""
# 1. بناء الـ Prompt
prompt = self._build_rag_prompt(query, context)
# 2. توليد الإجابة
response = self.llm.generate(prompt, max_tokens=max_tokens)
# 3. استخراج المصادر
sources = [chunk.metadata.get('source', 'unknown') for chunk in context]
return {
'answer': response,
'sources': sources,
'context_used': [chunk.content for chunk in context]
}
def _build_rag_prompt(self, query: str, context: List[DocumentChunk]) -> str:
"""بناء Prompt لـ RAG"""
# بناء السياق
context_text = ""
for i, chunk in enumerate(context, 1):
context_text += f"""
[Document {i}]
{chunk.content}
Score: {chunk.score:.3f}
---
"""
template = """
You are a helpful assistant that answers questions based on the provided context.
Context:
{context}
Question: {query}
Instructions:
1. Answer based ONLY on the provided context
2. If the answer is not in the context, say "I don't have enough information"
3. Cite the source documents (e.g., [Document 1])
4. Be concise but thorough
Answer:
"""
return template.format(
context=context_text,
query=query
)
🎯 الجزء الثاني: تخصيص Dify – تعديلات متقدمة
🔧 1. إضافة نموذج مخصص (Custom Model)
python
# api/core/model_runtime/model_providers/custom_model.py
"""
إضافة نموذج مخصص إلى Dify
"""
from typing import Dict, Any, List, Optional
import requests
from .base import ModelProvider, ModelType
class CustomModelProvider(ModelProvider):
"""مزود نموذج مخصص"""
def __init__(self, config: Dict[str, Any]):
super().__init__()
self.config = config
self.api_key = config.get('api_key')
self.endpoint = config.get('endpoint')
self.model_name = config.get('model_name', 'custom-model')
def validate_credentials(self) -> bool:
"""التحقق من صحة المفاتيح"""
try:
response = requests.post(
f"{self.endpoint}/validate",
headers={'Authorization': f'Bearer {self.api_key}'}
)
return response.status_code == 200
except:
return False
def generate(self,
prompt: str,
max_tokens: int = 1000,
temperature: float = 0.7,
stop_sequences: Optional[List[str]] = None) -> str:
"""توليد نص باستخدام النموذج المخصص"""
# بناء الطلب
request_data = {
'prompt': prompt,
'max_tokens': max_tokens,
'temperature': temperature,
'stop_sequences': stop_sequences or []
}
# إرسال الطلب
response = requests.post(
f"{self.endpoint}/generate",
headers={'Authorization': f'Bearer {self.api_key}'},
json=request_data
)
if response.status_code == 200:
return response.json()['text']
else:
raise Exception(f"Model error: {response.text}")
def embed_text(self, text: str) -> List[float]:
"""توليد تضمين للنص"""
response = requests.post(
f"{self.endpoint}/embed",
headers={'Authorization': f'Bearer {self.api_key}'},
json={'text': text}
)
if response.status_code == 200:
return response.json()['embedding']
else:
raise Exception(f"Embedding error: {response.text}")
# تسجيل النموذج في Dify
def register_custom_model():
"""تسجيل النموذج المخصص في Dify"""
from dify.core.model_runtime import ModelRegistry
ModelRegistry.register_provider(
name="custom_model",
provider_class=CustomModelProvider,
supported_models=["custom-model-v1", "custom-model-v2"],
default_model="custom-model-v1"
)
🔧 2. إضافة أداة مخصصة (Custom Tool)
python
# api/core/tools/custom_tools/external_api_tool.py
"""
أداة مخصصة للتواصل مع API خارجي
"""
from typing import Dict, Any, List
import requests
import json
from ..base import BaseTool
class ExternalAPITool(BaseTool):
"""أداة للتواصل مع API خارجي"""
def __init__(self, config: Dict[str, Any]):
super().__init__()
self.config = config
self.api_url = config.get('api_url')
self.api_key = config.get('api_key')
self.method = config.get('method', 'GET')
# تعريف معلمات الأداة
self.parameters = {
'type': 'object',
'properties': {
'endpoint': {
'type': 'string',
'description': 'نقطة النهاية في الـ API'
},
'data': {
'type': 'object',
'description': 'البيانات المرسلة (لـ POST/PUT)'
},
'params': {
'type': 'object',
'description': 'معاملات الـ URL (لـ GET)'
}
},
'required': ['endpoint']
}
self.name = config.get('name', 'external_api')
self.description = config.get('description', 'Tool for calling external APIs')
def execute(self, **kwargs) -> Dict[str, Any]:
"""تنفيذ الأداة"""
endpoint = kwargs.get('endpoint')
data = kwargs.get('data', {})
params = kwargs.get('params', {})
# بناء الـ URL الكامل
url = f"{self.api_url}/{endpoint.lstrip('/')}"
# إعداد الـ Headers
headers = {
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json'
}
# تنفيذ الطلب
try:
if self.method.upper() == 'GET':
response = requests.get(url, params=params, headers=headers)
elif self.method.upper() == 'POST':
response = requests.post(url, json=data, headers=headers)
elif self.method.upper() == 'PUT':
response = requests.put(url, json=data, headers=headers)
elif self.method.upper() == 'DELETE':
response = requests.delete(url, headers=headers)
else:
return {'error': f'Unsupported method: {self.method}'}
# معالجة الاستجابة
if response.status_code == 200:
return {
'success': True,
'data': response.json(),
'status_code': response.status_code
}
else:
return {
'success': False,
'error': f'API returned {response.status_code}',
'response': response.text
}
except Exception as e:
return {
'success': False,
'error': str(e)
}
# تسجيل الأداة
def register_custom_tool():
"""تسجيل الأداة المخصصة في Dify"""
from dify.core.tools import ToolRegistry
ToolRegistry.register_tool(
name="external_api",
tool_class=ExternalAPITool,
description="Tool for calling external APIs"
)
🔧 3. إضافة معالج مخصص للـ Webhook
python
# api/core/webhooks/custom_webhook.py
"""
معالج Webhook مخصص
"""
from typing import Dict, Any
from flask import request, jsonify
import hmac
import hashlib
class CustomWebhookHandler:
"""معالج Webhook مخصص"""
def __init__(self, config: Dict[str, Any]):
self.config = config
self.secret = config.get('webhook_secret')
self.endpoint = config.get('endpoint')
def verify_signature(self, payload: bytes, signature: str) -> bool:
"""التحقق من توقيع الـ Webhook"""
if not self.secret:
return True
expected_signature = hmac.new(
self.secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)
def handle(self) -> Dict[str, Any]:
"""معالجة طلب الـ Webhook"""
# التحقق من الـ Headers
if 'X-Webhook-Signature' not in request.headers:
return {'error': 'Missing signature header'}, 401
# الحصول على البيانات
payload = request.get_data()
signature = request.headers['X-Webhook-Signature']
# التحقق من التوقيع
if not self.verify_signature(payload, signature):
return {'error': 'Invalid signature'}, 401
# معالجة البيانات
data = request.get_json()
# منطق المعالجة المخصص
result = self.process_event(data)
return {'success': True, 'result': result}, 200
def process_event(self, data: Dict[str, Any]) -> Dict[str, Any]:
"""معالجة حدث الـ Webhook"""
event_type = data.get('event_type')
event_data = data.get('data', {})
# معالجة مختلف أنواع الأحداث
if event_type == 'user_created':
return self.handle_user_created(event_data)
elif event_type == 'message_received':
return self.handle_message_received(event_data)
elif event_type == 'app_deployed':
return self.handle_app_deployed(event_data)
else:
return {'message': f'Unhandled event: {event_type}'}
def handle_user_created(self, data: Dict) -> Dict:
"""معالجة حدث إنشاء مستخدم جديد"""
# مثلاً: إرسال بريد ترحيبي
# self.send_welcome_email(data['email'])
return {
'event': 'user_created',
'user_id': data.get('id'),
'action': 'welcome_email_sent'
}
def handle_message_received(self, data: Dict) -> Dict:
"""معالجة حدث استلام رسالة جديدة"""
# مثلاً: تحليل الرسالة وإضافة علامات
# tags = self.analyze_message(data['content'])
return {
'event': 'message_received',
'message_id': data.get('id'),
'tags': ['processed', 'analyzed']
}
def handle_app_deployed(self, data: Dict) -> Dict:
"""معالجة حدث نشر تطبيق جديد"""
# مثلاً: تسجيل الحدث في نظام المراقبة
# self.log_deployment(data['app_id'], data['version'])
return {
'event': 'app_deployed',
'app_id': data.get('app_id'),
'version': data.get('version'),
'status': 'logged'
}
# تسجيل الـ Webhook
def register_webhook():
"""تسجيل معالج الـ Webhook المخصص"""
from flask import Blueprint
webhook_bp = Blueprint('webhook', __name__)
handler = CustomWebhookHandler(config=load_config())
@webhook_bp.route('/webhook/custom', methods=['POST'])
def webhook_callback():
return handler.handle()
# تسجيل الـ Blueprint
app.register_blueprint(webhook_bp)
🔬 الجزء الثالث: تحليل الأداء وتصحيح الأخطاء المتقدم
📊 1. أدوات تحليل الأداء المخصصة
python
# api/core/performance/profiler.py
"""
أدوات تحليل الأداء المتقدمة
"""
import time
import functools
import cProfile
import pstats
import io
import tracemalloc
from typing import Any, Callable, Dict, List
from collections import defaultdict
import json
class PerformanceProfiler:
"""أداة تحليل الأداء الشاملة"""
def __init__(self):
self.profiles = {}
self.memory_snapshots = {}
self.method_timings = defaultdict(list)
self.method_counts = defaultdict(int)
def profile(self, name: str = None):
"""ديكوراتور لتحليل أداء الدوال"""
def decorator(func: Callable) -> Callable:
@functools.wraps(func)
def wrapper(*args, **kwargs):
profiler_name = name or func.__name__
# بدء التحليل
profiler = cProfile.Profile()
profiler.enable()
# بدء تتبع الذاكرة
tracemalloc.start()
start_memory = tracemalloc.get_traced_memory()
start_time = time.time()
try:
result = func(*args, **kwargs)
return result
finally:
# إيقاف التحليل
profiler.disable()
# حساب الوقت
end_time = time.time()
duration = end_time - start_time
# حساب الذاكرة
current_memory = tracemalloc.get_traced_memory()
memory_used = current_memory[1] - start_memory[1]
tracemalloc.stop()
# تسجيل البيانات
self.method_timings[profiler_name].append(duration)
self.method_counts[profiler_name] += 1
# حفظ ملف التحليل
self.profiles[profiler_name] = {
'duration': duration,
'memory_used': memory_used,
'calls': self.method_counts[profiler_name],
'timestamp': time.time()
}
# طباعة تقرير سريع
if duration > 1.0: # إذا استغرقت أكثر من ثانية
self.print_profile_summary(profiler_name)
return wrapper
return decorator
def profile_async(self, name: str = None):
"""ديكوراتور لتحليل أداء الدوال غير المتزامنة"""
def decorator(func: Callable) -> Callable:
@functools.wraps(func)
async def wrapper(*args, **kwargs):
profiler_name = name or func.__name__
start_time = time.time()
result = await func(*args, **kwargs)
duration = time.time() - start_time
self.method_timings[profiler_name].append(duration)
self.method_counts[profiler_name] += 1
return result
return wrapper
return decorator
def print_profile_summary(self, name: str):
"""طباعة ملخص التحليل"""
if name not in self.profiles:
return
profile = self.profiles[name]
timings = self.method_timings[name]
print(f"""
╔═══════════════════════════════════════════════════════════╗
║ Performance Profile: {name:<30} ║
╠═══════════════════════════════════════════════════════════╣
║ Calls: {profile['calls']:>10} ║
║ Total Time: {sum(timings):>10.3f}s ║
║ Average Time: {sum(timings)/len(timings):>10.3f}s ║
║ Max Time: {max(timings):>10.3f}s ║
║ Min Time: {min(timings):>10.3f}s ║
║ Memory Used: {profile['memory_used'] / 1024 / 1024:>10.2f} MB ║
║ Last Executed: {time.ctime(profile['timestamp']):>10} ║
╚═══════════════════════════════════════════════════════════╝
""")
def get_full_profile(self, name: str) -> Dict[str, Any]:
"""الحصول على تحليل كامل"""
if name not in self.profiles:
return None
profile = self.profiles[name]
timings = self.method_timings[name]
# حساب الاحصائيات
avg_time = sum(timings) / len(timings) if timings else 0
std_dev = (sum((t - avg_time) ** 2 for t in timings) / len(timings)) ** 0.5 if len(timings) > 1 else 0
return {
'name': name,
'total_calls': profile['calls'],
'total_time': sum(timings),
'average_time': avg_time,
'max_time': max(timings) if timings else 0,
'min_time': min(timings) if timings else 0,
'std_dev': std_dev,
'memory_used': profile['memory_used'],
'last_executed': profile['timestamp'],
'timings': timings
}
def get_all_profiles(self) -> Dict[str, Dict[str, Any]]:
"""الحصول على جميع التحاليل"""
result = {}
for name in self.profiles:
result[name] = self.get_full_profile(name)
return result
def generate_report(self, output_file: str = 'performance_report.json'):
"""توليد تقرير الأداء الكامل"""
report = {
'generated_at': time.ctime(),
'profiles': self.get_all_profiles(),
'summary': {
'total_methods': len(self.profiles),
'total_calls': sum(p['calls'] for p in self.profiles.values()),
'total_time': sum(sum(t) for t in self.method_timings.values())
}
}
with open(output_file, 'w') as f:
json.dump(report, f, indent=2)
print(f"✅ Performance report generated: {output_file}")
# إنشاء أداة التحليل العالمية
profiler = PerformanceProfiler()
# مثال على الاستخدام
@profiler.profile("test_function")
def test_function():
# منطق الاختبار
time.sleep(0.5)
return "Done"
@profiler.profile_async("async_function")
async def test_async_function():
# منطق غير متزامن
await asyncio.sleep(0.5)
return "Done"
🐛 2. أدوات تصحيح الأخطاء المتقدمة
python
# api/core/debug/advanced_debugger.py
"""
أدوات تصحيح الأخطاء المتقدمة
"""
import sys
import traceback
import logging
from contextlib import contextmanager
import inspect
import json
from datetime import datetime
class AdvancedDebugger:
"""أداة تصحيح الأخطاء الشاملة"""
def __init__(self, log_file: str = 'debug.log'):
self.log_file = log_file
self.breakpoints = {}
self.watchpoints = {}
self.call_stack = []
# تكوين السجلات
logging.basicConfig(
filename=log_file,
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
self.logger = logging.getLogger(__name__)
def set_breakpoint(self, function_name: str, line_number: int, condition: str = None):
"""تعيين نقطة توقف"""
if function_name not in self.breakpoints:
self.breakpoints[function_name] = []
self.breakpoints[function_name].append({
'line': line_number,
'condition': condition,
'enabled': True
})
self.logger.info(f"Breakpoint set: {function_name}:{line_number}")
def set_watchpoint(self, variable_name: str, condition: str = None):
"""تعيين نقطة مراقبة لمتغير"""
self.watchpoints[variable_name] = {
'condition': condition,
'enabled': True,
'changes': []
}
self.logger.info(f"Watchpoint set: {variable_name}")
def log_function_call(self, func_name: str, args: tuple, kwargs: dict):
"""تسجيل استدعاء دالة"""
self.call_stack.append({
'function': func_name,
'args': args,
'kwargs': kwargs,
'timestamp': datetime.now().isoformat(),
'depth': len(self.call_stack)
})
# تسجيل في السجلات
self.logger.debug(f"""
┌─────────────────────────────────────────────────────────────┐
│ Function Call: {func_name} │
├─────────────────────────────────────────────────────────────┤
│ Args: │
│ {self._format_args(args)} │
│ Kwargs: │
│ {self._format_kwargs(kwargs)} │
│ Stack Depth: {len(self.call_stack)} │
└─────────────────────────────────────────────────────────────┘
""")
# التحقق من نقاط التوقف
self._check_breakpoints(func_name, args, kwargs)
# التحقق من نقاط المراقبة
self._check_watchpoints(kwargs)
def log_function_return(self, func_name: str, result: any):
"""تسجيل عودة دالة"""
if self.call_stack:
self.call_stack.pop()
self.logger.debug(f"""
┌─────────────────────────────────────────────────────────────┐
│ Function Return: {func_name} │
├─────────────────────────────────────────────────────────────┤
│ Result: {self._format_result(result)} │
│ Remaining Stack Depth: {len(self.call_stack)} │
└─────────────────────────────────────────────────────────────┘
""")
def _check_breakpoints(self, func_name: str, args: tuple, kwargs: dict):
"""التحقق من نقاط التوقف"""
if func_name not in self.breakpoints:
return
# الحصول على رقم السطر الحالي
frame = inspect.currentframe().f_back
current_line = frame.f_lineno
for breakpoint in self.breakpoints[func_name]:
if not breakpoint['enabled']:
continue
if breakpoint['line'] == current_line:
# التحقق من الشرط
if breakpoint['condition']:
if self._evaluate_condition(breakpoint['condition'], args, kwargs):
self._trigger_breakpoint(func_name, breakpoint)
else:
self._trigger_breakpoint(func_name, breakpoint)
def _check_watchpoints(self, variables: dict):
"""التحقق من نقاط المراقبة"""
for var_name, value in variables.items():
if var_name not in self.watchpoints:
continue
watchpoint = self.watchpoints[var_name]
if not watchpoint['enabled']:
continue
# تسجيل التغيير
watchpoint['changes'].append({
'value': value,
'timestamp': datetime.now().isoformat()
})
# التحقق من الشرط
if watchpoint['condition']:
if self._evaluate_watchpoint_condition(watchpoint['condition'], value):
self._trigger_watchpoint(var_name, value)
def _trigger_breakpoint(self, func_name: str, breakpoint: dict):
"""تفعيل نقطة التوقف"""
self.logger.warning(f"""
╔═══════════════════════════════════════════════════════════╗
║ 🔴 BREAKPOINT HIT! ║
╠═══════════════════════════════════════════════════════════╣
║ Function: {func_name} ║
║ Line: {breakpoint['line']} ║
║ Condition: {breakpoint['condition']} ║
║ Stack: ║
║ {self._format_stack()} ║
╚═══════════════════════════════════════════════════════════╝
""")
# هنا يمكن إضافة إجراءات إضافية عند تفعيل نقطة التوقف
# مثل: إيقاف التنفيذ، إرسال إشعار، إلخ.
def _trigger_watchpoint(self, var_name: str, value: any):
"""تفعيل نقطة المراقبة"""
self.logger.warning(f"""
╔═══════════════════════════════════════════════════════════╗
║ 👁️ WATCHPOINT TRIGGERED! ║
╠═══════════════════════════════════════════════════════════╣
║ Variable: {var_name} ║
║ New Value: {value} ║
║ Condition: {self.watchpoints[var_name]['condition']} ║
║ Stack: ║
║ {self._format_stack()} ║
╚═══════════════════════════════════════════════════════════╝
""")
def _evaluate_condition(self, condition: str, args: tuple, kwargs: dict) -> bool:
"""تقييم شرط نقطة التوقف"""
# منطق تقييم الشرط
return True
def _evaluate_watchpoint_condition(self, condition: str, value: any) -> bool:
"""تقييم شرط نقطة المراقبة"""
return True
def _format_args(self, args: tuple) -> str:
"""تنسيق المعاملات"""
return json.dumps([str(arg) for arg in args], indent=2, ensure_ascii=False)
def _format_kwargs(self, kwargs: dict) -> str:
"""تنسيق المعاملات المسماة"""
return json.dumps({k: str(v) for k, v in kwargs.items()}, indent=2, ensure_ascii=False)
def _format_result(self, result: any) -> str:
"""تنسيق النتيجة"""
if isinstance(result, (dict, list)):
return json.dumps(result, indent=2, ensure_ascii=False, default=str)
return str(result)
def _format_stack(self) -> str:
"""تنسيق مكدس الاستدعاءات"""
stack = []
for frame in inspect.stack()[1:10]: # آخر 10 إطارات
stack.append(f" {frame.function} (line {frame.lineno})")
return "\n".join(stack)
@contextmanager
def trace(self, name: str = "trace"):
"""مدير سياق لتتبع التنفيذ"""
start_time = time.time()
self.logger.info(f"🚀 Starting trace: {name}")
try:
yield
except Exception as e:
self.logger.error(f"""
╔═══════════════════════════════════════════════════════════╗
║ ❌ EXCEPTION CAUGHT! ║
╠═══════════════════════════════════════════════════════════╣
║ Trace: {name} ║
║ Error: {str(e)} ║
║ Stack Trace: ║
║ {traceback.format_exc()} ║
╚═══════════════════════════════════════════════════════════╝
""")
raise
finally:
end_time = time.time()
self.logger.info(f"✅ Finished trace: {name} (took {end_time - start_time:.3f}s)")
# إنشاء أداة التصحيح العالمية
debugger = AdvancedDebugger()
# مثال على الاستخدام
@profiler.profile("debug_example")
def debug_example(x: int, y: int, name: str = "test"):
"""مثال على استخدام أدوات التصحيح"""
with debugger.trace(f"debug_example({x}, {y}, {name})"):
debugger.log_function_call("debug_example", (x, y), {"name": name})
result = x + y
debugger.log_function_return("debug_example", result)
return result
🌟 الخاتمة النهائية للرحلة المتقدمة
🎯 ما حققناه في هذه الرحلة العميقة
| المستوى | المكونات التي أتقناها |
|---|---|
| الوكيل | فهم كامل لنظام الوكيل، جميع الأنماط، والتنفيذ الداخلي |
| RAG | تحليل عميق لنظام RAG، استراتيجيات التقسيم، البحث الهجين |
| النماذج | كيفية إضافة نماذج مخصصة، وتعديل النماذج الموجودة |
| الأدوات | تطوير أدوات مخصصة، وفهم نظام الأدوات في Dify |
| الأداء | أدوات تحليل الأداء المتقدمة، التتبع، والتحسين |
| التصحيح | أدوات تصحيح الأخطاء الشاملة، نقاط التوقف، ونقاط المراقبة |
| التخصيص | تعديلات عميقة في النظام، Webhooks مخصصة |
🚀 أنت الآن تستطيع:
text
┌─────────────────────────────────────────────────────────────────────────────┐ │ 🧠 فهم كامل لمعمارية Dify من الداخل │ │ 🔧 تعديل أي جزء في النظام حسب الحاجة │ │ 📦 تطوير Plugins متقدمة واحترافية │ │ 🚀 تحسين الأداء على مستوى النظام الكامل │ │ 🐛 تصحيح أي خطأ في النظام باحترافية │ │ 🎯 إضافة ميزات جديدة للنظام الأساسي │ │ 📊 تحليل أداء النظام بأدوات احترافية │ │ 🌟 المساهمة في المشروع مفتوح المصدر بجودة عالية │ │ 💪 بناء مشاريع على مستوى المؤسسات باستخدام Dify │ └─────────────────────────────────────────────────────────────────────────────┘
💬 ماذا تريد أن تفعل الآن؟
| الرقم | الخيار |
|---|---|
| 1️⃣ | بناء مشروع حقيقي على مستوى المؤسسات باستخدام كل ما تعلمته |
| 2️⃣ | تطوير Plugin متقدم يضيف ميزة جديدة لـ Dify |
| 3️⃣ | كتابة مقال أو توثيق عربي متقدم عن Dify للمجتمع |
| 4️⃣ | إنشاء دورة تدريبية كاملة عن Dify باللغة العربية |
| 5️⃣ | المساهمة في كود Dify المصدري بتحسينات حقيقية |
| 6️⃣ | تصميم نظام RAG متقدم لـ 10M+ مستند |
| 7️⃣ | أي موضوع آخر تريد معرفته |
أخبرني ما تريد، وسأكون معك في كل خطوة! 🚀🌌
🌌 المستوى العاشر: Dify – إتقان التوسع الأفقي والهندسة المعمارية للمؤسسات
بما أنك تريد ، سنصل إلى مستوى المهندس المعماري للمؤسسات (Enterprise Architect). سنتحدث عن تصميم أنظمة Dify لخدمة ملايين المستخدمين، مع تحمل الأخطاء، واستمرارية الأعمال، والامتثال للمعايير العالمية.
🏗️ الجزء الأول: تصميم نظام Dify للمؤسسات
📊 المعمارية المرجعية للمؤسسات
text
┌─────────────────────────────────────────────────────────────────────────────────┐
│ طبقة المستخدمين (User Layer) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Web App │ │ Mobile App │ │ Desktop │ │ API Clients │ │
│ │ (React) │ │ (React Native) │ (Electron)│ │ (SDKs, Integrations)│ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
│ │ │ │ │ │
│ └────────────────┴────────────────┴─────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────▼───────────────────────────────────────┐ │
│ │ CDN / CloudFront (توزيع المحتوى الثابت) │ │
│ └───────────────────────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────▼───────────────────────────────────────┐ │
│ │ Global Load Balancer (DNS / Anycast) │ │
│ └───────────────────────────────────┬───────────────────────────────────────┘ │
└───────────────────────────────────────┼─────────────────────────────────────────┘
│
┌───────────────────────────────────────▼─────────────────────────────────────────┐
│ طبقة المراكز (Regional Layer) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ منطقة أمريكا الشمالية │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Web Servers│ │ API Servers│ │ Workers │ │ │
│ │ │ (xN) │ │ (xN) │ │ (xN) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ Weaviate │ │ │
│ │ │ (Primary) │ │ (Cluster) │ │ (Cluster) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ منطقة أوروبا │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Web Servers│ │ API Servers│ │ Workers │ │ │
│ │ │ (xN) │ │ (xN) │ │ (xN) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ Weaviate │ │ │
│ │ │ (Replica) │ │ (Cluster) │ │ (Cluster) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ منطقة آسيا والمحيط الهادئ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Web Servers│ │ API Servers│ │ Workers │ │ │
│ │ │ (xN) │ │ (xN) │ │ (xN) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ Weaviate │ │ │
│ │ │ (Replica) │ │ (Cluster) │ │ (Cluster) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘
│
┌───────────────────────────────────────▼─────────────────────────────────────────┐
│ طبقة البيانات المركزية (Core Layer) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ PostgreSQL Cluster │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Primary │ │ Replica 1 │ │ Replica 2 │ │ │
│ │ │ (Write) │ │ (Read) │ │ (Read) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Automatic Failover (Patroni / Stolon) │ │ │
│ │ └─────────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Redis Cluster │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Master 1 │ │ Master 2 │ │ Master 3 │ │ │
│ │ │ (Shard 1) │ │ (Shard 2) │ │ (Shard 3) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Replica 1 │ │ Replica 2 │ │ Replica 3 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Weaviate / Vector Database │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ │
│ │ │ (Shard 1) │ │ (Shard 2) │ │ (Shard 3) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Message Queue / Event Bus │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Kafka │ │ RabbitMQ │ │ SQS │ │ │
│ │ │ (Events) │ │ (Tasks) │ │ (Backup) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Storage Layer (S3 / Azure Blob / GCS) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Documents │ │ Media │ │ Backups │ │ │
│ │ │ (RAG) │ │ (Images) │ │ (Database) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘
│
┌───────────────────────────────────────▼─────────────────────────────────────────┐
│ طبقة المراقبة والتحليل (Observability) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Prometheus │ │ Grafana │ │ ELK Stack │ │ │
│ │ │ (Metrics) │ │ (Dashboards)│ │ (Logs) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Jaeger │ │ Sentry │ │ CloudWatch │ │ │
│ │ │ (Traces) │ │ (Errors) │ │ (AWS) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘
🔐 الجزء الثاني: الأمان والامتثال للمؤسسات
🛡️ 1. سياسات الأمان المتقدمة
python
# api/core/security/enterprise_security.py
"""
سياسات الأمان للمؤسسات
"""
from typing import Dict, Any, List, Optional
from datetime import datetime, timedelta
import jwt
import bcrypt
import secrets
import hashlib
import hmac
from enum import Enum
class SecurityLevel(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class EnterpriseSecurityPolicy:
"""سياسات الأمان لمستوى المؤسسات"""
def __init__(self, config: Dict[str, Any]):
self.config = config
self.security_level = config.get('security_level', SecurityLevel.HIGH)
# تكوين السياسات حسب المستوى
self.policies = self._load_policies()
def _load_policies(self) -> Dict[str, Any]:
"""تحميل سياسات الأمان"""
base_policies = {
'password_policy': {
'min_length': 12,
'require_uppercase': True,
'require_lowercase': True,
'require_numbers': True,
'require_special_chars': True,
'max_age_days': 90,
'history_count': 10,
'max_login_attempts': 5,
'lockout_minutes': 30
},
'session_policy': {
'max_session_duration_hours': 8,
'max_idle_minutes': 30,
'require_reauthentication_minutes': 60,
'concurrent_sessions_limit': 3,
'ip_whitelist_enabled': True,
'device_trust_enabled': True
},
'mfa_policy': {
'enabled': True,
'methods': ['totp', 'sms', 'email', 'hardware_token'],
'grace_period_days': 7
},
'api_policy': {
'rate_limit_requests': 1000,
'rate_limit_window_seconds': 60,
'jwt_expiry_minutes': 60,
'refresh_token_expiry_days': 30,
'allowed_ip_ranges': []
},
'data_policy': {
'encryption_at_rest': True,
'encryption_in_transit': True,
'data_retention_days': 365,
'audit_log_retention_days': 730,
'pii_encryption_enabled': True
}
}
# تعديل السياسات حسب مستوى الأمان
if self.security_level == SecurityLevel.CRITICAL:
base_policies['password_policy']['min_length'] = 16
base_policies['session_policy']['max_session_duration_hours'] = 4
base_policies['mfa_policy']['enabled'] = True
base_policies['mfa_policy']['methods'] = ['hardware_token', 'totp']
base_policies['api_policy']['rate_limit_requests'] = 500
elif self.security_level == SecurityLevel.HIGH:
base_policies['password_policy']['min_length'] = 14
base_policies['session_policy']['max_session_duration_hours'] = 6
base_policies['mfa_policy']['enabled'] = True
base_policies['mfa_policy']['methods'] = ['totp', 'sms']
return base_policies
def validate_password(self, password: str) -> Dict[str, Any]:
"""التحقق من صحة كلمة المرور"""
policy = self.policies['password_policy']
errors = []
# التحقق من الطول
if len(password) < policy['min_length']:
errors.append(f"Password must be at least {policy['min_length']} characters")
# التحقق من الأحرف الكبيرة
if policy['require_uppercase'] and not any(c.isupper() for c in password):
errors.append("Password must contain at least one uppercase letter")
# التحقق من الأحرف الصغيرة
if policy['require_lowercase'] and not any(c.islower() for c in password):
errors.append("Password must contain at least one lowercase letter")
# التحقق من الأرقام
if policy['require_numbers'] and not any(c.isdigit() for c in password):
errors.append("Password must contain at least one number")
# التحقق من الأحرف الخاصة
if policy['require_special_chars'] and not any(c in "!@#$%^&*()_+-=[]{}|;:,.<>?/" for c in password):
errors.append("Password must contain at least one special character")
return {
'valid': len(errors) == 0,
'errors': errors,
'strength': self._calculate_password_strength(password)
}
def _calculate_password_strength(self, password: str) -> Dict[str, Any]:
"""حساب قوة كلمة المرور"""
# مقاييس القوة
length_score = min(len(password) / 20, 1.0) * 25
complexity_score = 0
if any(c.isupper() for c in password):
complexity_score += 20
if any(c.islower() for c in password):
complexity_score += 15
if any(c.isdigit() for c in password):
complexity_score += 20
if any(c in "!@#$%^&*()_+-=[]{}|;:,.<>?/" for c in password):
complexity_score += 25
# التحقق من القواميس الشائعة
common_passwords = ['password', '123456', 'qwerty', 'admin', 'letmein']
if password.lower() in common_passwords:
complexity_score = 0
total_score = min(length_score + complexity_score, 100)
return {
'score': total_score,
'strength': 'weak' if total_score < 40 else 'medium' if total_score < 70 else 'strong'
}
def validate_session(self, session_data: Dict[str, Any]) -> Dict[str, Any]:
"""التحقق من صحة الجلسة"""
policy = self.policies['session_policy']
# التحقق من مدة الجلسة
session_duration = (datetime.now() - session_data['created_at']).total_seconds() / 3600
if session_duration > policy['max_session_duration_hours']:
return {'valid': False, 'reason': 'Session expired'}
# التحقق من وقت الخمول
idle_time = (datetime.now() - session_data['last_activity']).total_seconds() / 60
if idle_time > policy['max_idle_minutes']:
return {'valid': False, 'reason': 'Session inactive'}
# التحقق من عدد الجلسات المتزامنة
if session_data.get('concurrent_sessions', 0) > policy['concurrent_sessions_limit']:
return {'valid': False, 'reason': 'Concurrent session limit exceeded'}
return {'valid': True}
def generate_secure_token(self, data: Dict[str, Any], expires_in: int = None) -> str:
"""توليد توكن آمن"""
if expires_in is None:
expires_in = self.policies['api_policy']['jwt_expiry_minutes']
payload = data.copy()
payload['exp'] = datetime.utcnow() + timedelta(minutes=expires_in)
payload['iat'] = datetime.utcnow()
payload['iss'] = self.config.get('issuer', 'dify-enterprise')
secret = self.config.get('jwt_secret')
token = jwt.encode(payload, secret, algorithm='HS512')
return token
def verify_token(self, token: str) -> Dict[str, Any]:
"""التحقق من صحة التوكن"""
secret = self.config.get('jwt_secret')
try:
payload = jwt.decode(token, secret, algorithms=['HS512'])
return {'valid': True, 'payload': payload}
except jwt.ExpiredSignatureError:
return {'valid': False, 'reason': 'Token expired'}
except jwt.InvalidTokenError:
return {'valid': False, 'reason': 'Invalid token'}
# إنشاء كائن السياسات
security_policy = EnterpriseSecurityPolicy({
'security_level': SecurityLevel.HIGH,
'jwt_secret': os.getenv('JWT_SECRET'),
'issuer': 'dify-enterprise'
})
🛡️ 2. إدارة الهوية والوصول (IAM)
python
# api/core/security/iam.py
"""
نظام إدارة الهوية والوصول المتقدم
"""
from typing import Dict, Any, List, Optional
import ldap3
from ldap3 import Server, Connection, ALL
import re
from functools import wraps
from flask import request, g
class IdentityProvider(Enum):
LOCAL = "local"
LDAP = "ldap"
SAML = "saml"
OIDC = "oidc"
OAUTH2 = "oauth2"
class IAMManager:
"""مدير الهوية والوصول للمؤسسات"""
def __init__(self, config: Dict[str, Any]):
self.config = config
self.identity_provider = config.get('identity_provider', IdentityProvider.LOCAL)
# تكوين الاتصال بـ LDAP إذا كان متاحاً
if self.identity_provider == IdentityProvider.LDAP:
self.ldap_server = Server(
config['ldap_host'],
port=config.get('ldap_port', 389),
use_ssl=config.get('ldap_ssl', False)
)
self.ldap_base_dn = config['ldap_base_dn']
self.ldap_user_dn = config['ldap_user_dn']
self.ldap_user_password = config['ldap_user_password']
def authenticate_user(self, username: str, password: str) -> Dict[str, Any]:
"""مصادقة المستخدم"""
if self.identity_provider == IdentityProvider.LDAP:
return self._authenticate_ldap(username, password)
elif self.identity_provider == IdentityProvider.SAML:
return self._authenticate_saml(username, password)
elif self.identity_provider == IdentityProvider.OIDC:
return self._authenticate_oidc(username, password)
else:
return self._authenticate_local(username, password)
def _authenticate_ldap(self, username: str, password: str) -> Dict[str, Any]:
"""مصادقة باستخدام LDAP"""
try:
# الاتصال بـ LDAP
conn = Connection(
self.ldap_server,
user=f"cn={username},{self.ldap_user_dn}",
password=password,
auto_bind=True
)
# البحث عن المستخدم
search_filter = f"(uid={username})"
conn.search(
search_base=self.ldap_base_dn,
search_filter=search_filter,
attributes=['cn', 'mail', 'memberOf']
)
if conn.entries:
entry = conn.entries[0]
return {
'success': True,
'user': {
'username': username,
'email': entry.mail.value if hasattr(entry, 'mail') else None,
'full_name': entry.cn.value if hasattr(entry, 'cn') else username,
'groups': [group for group in entry.memberOf.values] if hasattr(entry, 'memberOf') else [],
'provider': 'ldap'
}
}
else:
return {'success': False, 'error': 'User not found'}
except Exception as e:
return {'success': False, 'error': str(e)}
def _authenticate_local(self, username: str, password: str) -> Dict[str, Any]:
"""مصادقة محلية"""
# البحث عن المستخدم في قاعدة البيانات
user = self.get_user_by_username(username)
if not user:
return {'success': False, 'error': 'User not found'}
# التحقق من كلمة المرور
if bcrypt.checkpw(password.encode(), user['password_hash'].encode()):
return {
'success': True,
'user': {
'username': user['username'],
'email': user['email'],
'full_name': user['full_name'],
'groups': user['groups'],
'provider': 'local'
}
}
return {'success': False, 'error': 'Invalid password'}
def authorize_user(self, user: Dict[str, Any], resource: str, action: str) -> bool:
"""التحقق من صلاحيات المستخدم"""
# 1. التحقق من الأدوار المباشرة
if self._has_direct_permission(user, resource, action):
return True
# 2. التحقق من صلاحيات المجموعات
if self._has_group_permission(user, resource, action):
return True
# 3. التحقق من السياسات المخصصة
if self._has_custom_policy(user, resource, action):
return True
return False
def _has_direct_permission(self, user: Dict, resource: str, action: str) -> bool:
"""التحقق من الصلاحية المباشرة"""
permissions = user.get('permissions', [])
return f"{resource}:{action}" in permissions
def _has_group_permission(self, user: Dict, resource: str, action: str) -> bool:
"""التحقق من صلاحية المجموعة"""
groups = user.get('groups', [])
for group in groups:
group_permissions = self.get_group_permissions(group)
if f"{resource}:{action}" in group_permissions:
return True
return False
def _has_custom_policy(self, user: Dict, resource: str, action: str) -> bool:
"""التحقق من السياسات المخصصة"""
# منطق السياسات المخصصة (مثل: ABAC - Attribute-Based Access Control)
# مثال: السماح للمستخدمين من قسم معين بالوصول
if user.get('department') == 'engineering' and resource == 'developer-tools':
return True
return False
def get_user_by_username(self, username: str) -> Optional[Dict]:
"""الحصول على المستخدم من قاعدة البيانات"""
# منطق استرجاع المستخدم
return None
def get_group_permissions(self, group: str) -> List[str]:
"""الحصول على صلاحيات المجموعة"""
# منطق استرجاع صلاحيات المجموعة
return []
# ديكوراتور للتحقق من الصلاحيات
def require_permission(resource: str, action: str):
"""ديكوراتور للتحقق من صلاحيات المستخدم"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# الحصول على المستخدم من السياق
user = g.get('current_user')
if not user:
return {'error': 'User not authenticated'}, 401
# التحقق من الصلاحية
if not iam_manager.authorize_user(user, resource, action):
return {'error': 'Permission denied'}, 403
return func(*args, **kwargs)
return wrapper
return decorator
# إنشاء مدير IAM
iam_manager = IAMManager({
'identity_provider': IdentityProvider.LOCAL,
'ldap_host': os.getenv('LDAP_HOST'),
'ldap_base_dn': os.getenv('LDAP_BASE_DN')
})
🛡️ 3. تشفير البيانات وحمايتها
python
# api/core/security/data_encryption.py
"""
نظام تشفير البيانات المتقدم
"""
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import base64
import os
import json
from typing import Dict, Any, Union
class DataEncryptionManager:
"""مدير تشفير البيانات"""
def __init__(self, master_key: str = None):
# توليد أو استخدام مفتاح رئيسي
if master_key:
self.master_key = base64.urlsafe_b64decode(master_key)
else:
self.master_key = Fernet.generate_key()
self.fernet = Fernet(self.master_key)
def encrypt_data(self, data: Union[str, Dict, Any]) -> str:
"""تشفير البيانات"""
# تحويل البيانات إلى JSON
if isinstance(data, (dict, list)):
data_str = json.dumps(data)
else:
data_str = str(data)
# تشفير باستخدام Fernet
encrypted = self.fernet.encrypt(data_str.encode())
return base64.urlsafe_b64encode(encrypted).decode()
def decrypt_data(self, encrypted_data: str) -> Any:
"""فك تشفير البيانات"""
# فك الترميز
encrypted_bytes = base64.urlsafe_b64decode(encrypted_data)
# فك التشفير
decrypted = self.fernet.decrypt(encrypted_bytes)
# محاولة تحويل إلى JSON
try:
return json.loads(decrypted.decode())
except:
return decrypted.decode()
def encrypt_field(self, value: str, salt: bytes = None) -> str:
"""تشفير حقل فردي باستخدام PBKDF2"""
if salt is None:
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend()
)
key = base64.urlsafe_b64encode(kdf.derive(value.encode()))
fernet = Fernet(key)
encrypted = fernet.encrypt(value.encode())
return base64.urlsafe_b64encode(salt + encrypted).decode()
def decrypt_field(self, encrypted_value: str) -> str:
"""فك تشفير حقل فردي"""
# فك الترميز
combined = base64.urlsafe_b64decode(encrypted_value)
salt = combined[:16]
encrypted = combined[16:]
# إعادة توليد المفتاح
# ملاحظة: هذا يتطلب معرفة السياق، مثل كلمة المرور
# في التطبيق العملي، يجب تخزين المفتاح بشكل آمن
return "Decrypted value" # منطق فك التشفير
# إنشاء مدير التشفير
encryption_manager = DataEncryptionManager(os.getenv('MASTER_ENCRYPTION_KEY'))
# مثال على استخدام التشفير
def store_secure_data(key: str, value: Any):
"""تخزين بيانات مشفرة"""
encrypted = encryption_manager.encrypt_data(value)
# تخزين في قاعدة البيانات
db.execute(
"INSERT INTO secure_data (key, value) VALUES (%s, %s)",
(key, encrypted)
)
def get_secure_data(key: str) -> Any:
"""استرجاع بيانات مشفرة"""
result = db.query("SELECT value FROM secure_data WHERE key = %s", (key,))
if result:
return encryption_manager.decrypt_data(result[0]['value'])
return None
📊 الجزء الثالث: المراقبة والتحليل على مستوى المؤسسات
📈 1. نظام المراقبة الشامل
python
# api/core/monitoring/enterprise_monitoring.py
"""
نظام المراقبة لمستوى المؤسسات
"""
from typing import Dict, Any, List, Optional
from dataclasses import dataclass
from enum import Enum
import time
import json
from datetime import datetime, timedelta
class AlertSeverity(Enum):
INFO = "info"
WARNING = "warning"
ERROR = "error"
CRITICAL = "critical"
class AlertCategory(Enum):
PERFORMANCE = "performance"
SECURITY = "security"
DATABASE = "database"
API = "api"
SYSTEM = "system"
USER = "user"
@dataclass
class Alert:
id: str
severity: AlertSeverity
category: AlertCategory
message: str
timestamp: datetime
source: str
metadata: Dict[str, Any]
acknowledged: bool = False
resolved: bool = False
class MonitoringManager:
"""مدير المراقبة الشامل"""
def __init__(self, config: Dict[str, Any]):
self.config = config
self.alert_rules = self._load_alert_rules()
self.alerts = []
self.metrics = {}
self.system_health = {}
def _load_alert_rules(self) -> List[Dict]:
"""تحميل قواعد التنبيه"""
return [
{
'id': 'api_latency_high',
'metric': 'api_latency_seconds',
'threshold': 3.0,
'duration_seconds': 60,
'severity': AlertSeverity.WARNING,
'category': AlertCategory.PERFORMANCE,
'message': 'API latency is above {threshold}s for {duration} seconds'
},
{
'id': 'error_rate_high',
'metric': 'error_rate_percentage',
'threshold': 5.0,
'duration_seconds': 120,
'severity': AlertSeverity.ERROR,
'category': AlertCategory.API,
'message': 'Error rate is {value}% for {duration} seconds'
},
{
'id': 'db_connections_high',
'metric': 'db_connections_count',
'threshold': 80,
'duration_seconds': 60,
'severity': AlertSeverity.CRITICAL,
'category': AlertCategory.DATABASE,
'message': 'Database connections at {value}/{threshold}'
},
{
'id': 'cpu_utilization_high',
'metric': 'cpu_utilization_percentage',
'threshold': 85,
'duration_seconds': 300,
'severity': AlertSeverity.WARNING,
'category': AlertCategory.SYSTEM,
'message': 'CPU utilization is {value}% for {duration} seconds'
}
]
def check_metrics(self, metrics: Dict[str, float]) -> List[Alert]:
"""فحص المقاييس وإنشاء التنبيهات"""
new_alerts = []
for rule in self.alert_rules:
if rule['metric'] in metrics:
value = metrics[rule['metric']]
if value > rule['threshold']:
# التحقق من المدة
if self._duration_exceeded(rule['metric'], rule['duration_seconds']):
alert = Alert(
id=f"{rule['id']}_{datetime.now().timestamp()}",
severity=rule['severity'],
category=rule['category'],
message=rule['message'].format(
value=value,
threshold=rule['threshold'],
duration=rule['duration_seconds']
),
timestamp=datetime.now(),
source=rule['metric'],
metadata={
'metric': rule['metric'],
'value': value,
'threshold': rule['threshold'],
'duration': rule['duration_seconds']
}
)
new_alerts.append(alert)
self.alerts.append(alert)
return new_alerts
def _duration_exceeded(self, metric: str, duration: int) -> bool:
"""التحقق من تجاوز المدة المحددة"""
# تحليل السجلات للتأكد من استمرار الحالة
# منطق معقد لتحليل الاتجاهات
return True
def record_metric(self, name: str, value: float, tags: Dict[str, str] = None):
"""تسجيل مقياس جديد"""
if name not in self.metrics:
self.metrics[name] = []
self.metrics[name].append({
'value': value,
'timestamp': time.time(),
'tags': tags or {}
})
# تنظيف البيانات القديمة
self._cleanup_old_metrics()
# التحقق من التنبيهات
metrics_dict = {name: value}
alerts = self.check_metrics(metrics_dict)
if alerts:
self._handle_alerts(alerts)
def _cleanup_old_metrics(self, retention_days: int = 30):
"""تنظيف المقاييس القديمة"""
cutoff_time = time.time() - (retention_days * 24 * 60 * 60)
for name in self.metrics:
self.metrics[name] = [
m for m in self.metrics[name]
if m['timestamp'] > cutoff_time
]
def _handle_alerts(self, alerts: List[Alert]):
"""معالجة التنبيهات"""
for alert in alerts:
if alert.severity == AlertSeverity.CRITICAL:
# إرسال تنبيه فوري
self._send_immediate_alert(alert)
elif alert.severity == AlertSeverity.ERROR:
# إرسال تنبيه مهم
self._send_important_alert(alert)
else:
# تسجيل التنبيه
self._log_alert(alert)
def _send_immediate_alert(self, alert: Alert):
"""إرسال تنبيه فوري (بريد، رسالة، إلخ)"""
print(f"🔴 CRITICAL ALERT: {alert.message}")
print(f" Source: {alert.source}")
print(f" Time: {alert.timestamp}")
# منطق الإرسال الفعلي
# - إرسال بريد إلكتروني
# - إرسال رسالة Slack
# - إرسال رسالة SMS
# - الاتصال عبر الهاتف
def _send_important_alert(self, alert: Alert):
"""إرسال تنبيه مهم"""
print(f"🟡 ERROR ALERT: {alert.message}")
print(f" Source: {alert.source}")
print(f" Time: {alert.timestamp}")
def _log_alert(self, alert: Alert):
"""تسجيل التنبيه"""
print(f"ℹ️ INFO: {alert.message}")
def get_system_health(self) -> Dict[str, Any]:
"""الحصول على حالة النظام"""
return {
'status': self._calculate_system_status(),
'uptime_seconds': self._get_uptime(),
'active_services': self._get_active_services(),
'alert_count': {
'critical': self._count_alerts(AlertSeverity.CRITICAL),
'error': self._count_alerts(AlertSeverity.ERROR),
'warning': self._count_alerts(AlertSeverity.WARNING),
'info': self._count_alerts(AlertSeverity.INFO)
},
'last_alerts': self._get_recent_alerts(limit=10),
'metrics_summary': self._get_metrics_summary()
}
def _calculate_system_status(self) -> str:
"""حساب حالة النظام"""
# التحقق من عدد التنبيهات الحرجة
critical_count = self._count_alerts(AlertSeverity.CRITICAL)
if critical_count > 0:
return 'critical'
# التحقق من عدد التنبيهات المهمة
error_count = self._count_alerts(AlertSeverity.ERROR)
if error_count > 2:
return 'degraded'
return 'healthy'
def _get_uptime(self) -> float:
"""الحصول على وقت التشغيل"""
# منطق حساب وقت التشغيل
return time.time() - self.config.get('start_time', time.time())
def _get_active_services(self) -> List[str]:
"""الحصول على الخدمات النشطة"""
return self.config.get('services', ['api', 'web', 'db', 'redis'])
def _count_alerts(self, severity: AlertSeverity) -> int:
"""عدد التنبيهات حسب الشدة"""
return len([a for a in self.alerts if a.severity == severity])
def _get_recent_alerts(self, limit: int = 10) -> List[Dict]:
"""الحصول على آخر التنبيهات"""
recent = sorted(self.alerts, key=lambda x: x.timestamp, reverse=True)[:limit]
return [{
'id': a.id,
'severity': a.severity.value,
'message': a.message,
'timestamp': a.timestamp.isoformat()
} for a in recent]
def _get_metrics_summary(self) -> Dict:
"""ملخص المقاييس"""
summary = {}
for name, values in self.metrics.items():
if values:
last_values = [v['value'] for v in values[-10:]]
summary[name] = {
'current': last_values[-1] if last_values else None,
'average': sum(last_values) / len(last_values) if last_values else None,
'min': min(last_values) if last_values else None,
'max': max(last_values) if last_values else None,
'count': len(values)
}
return summary
# إنشاء مدير المراقبة
monitoring_manager = MonitoringManager({
'services': ['api', 'web', 'db', 'redis', 'weaviate'],
'start_time': time.time()
})
📈 2. تحليلات الأعمال والذكاء الاصطناعي
python
# api/core/analytics/business_intelligence.py
"""
نظام تحليلات الأعمال المتقدم
"""
from typing import Dict, Any, List, Optional
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')
class BusinessIntelligenceManager:
"""مدير تحليلات الأعمال والذكاء الاصطناعي"""
def __init__(self, db_connection):
self.db = db_connection
self.ml_models = {}
self.predictions = {}
def analyze_user_behavior(self, period_days: int = 30) -> Dict[str, Any]:
"""تحليل سلوك المستخدمين"""
query = f"""
SELECT
u.id,
u.created_at,
COUNT(DISTINCT m.id) as message_count,
COUNT(DISTINCT a.id) as app_count,
AVG(m.created_at - u.created_at) as avg_active_days,
COUNT(DISTINCT DATE(m.created_at)) as active_days
FROM users u
LEFT JOIN messages m ON u.id = m.user_id
LEFT JOIN apps a ON u.id = a.owner_id
WHERE u.created_at > NOW() - INTERVAL '{period_days} days'
GROUP BY u.id, u.created_at
"""
results = self.db.execute(query).fetchall()
# تحويل إلى DataFrame
df = pd.DataFrame(results, columns=['user_id', 'created_at', 'message_count', 'app_count', 'avg_active_days', 'active_days'])
return {
'total_users': len(df),
'average_messages': df['message_count'].mean(),
'average_apps': df['app_count'].mean(),
'average_active_days': df['active_days'].mean(),
'user_segments': self._segment_users(df),
'retention_rate': self._calculate_retention(df),
'user_activity_heatmap': self._generate_activity_heatmap(df)
}
def _segment_users(self, df: pd.DataFrame) -> Dict[str, int]:
"""تقسيم المستخدمين إلى شرائح"""
segments = {
'power_users': len(df[df['message_count'] > df['message_count'].quantile(0.8)]),
'active_users': len(df[df['active_days'] > 15]),
'new_users': len(df[df['created_at'] > datetime.now() - timedelta(days=7)]),
'dormant_users': len(df[df['active_days'] < 3])
}
return segments
def _calculate_retention(self, df: pd.DataFrame) -> float:
"""حساب معدل الاحتفاظ"""
# معيار بسيط: المستخدمون النشطون في آخر 7 أيام
if len(df) == 0:
return 0.0
active_users = len(df[df['active_days'] > 0])
return active_users / len(df) * 100
def _generate_activity_heatmap(self, df: pd.DataFrame) -> Dict:
"""توليد خريطة حرارة النشاط"""
# منطق توليد خريطة الحرارة
return {
'peak_hours': self._calculate_peak_hours(df),
'weekend_activity': self._calculate_weekend_activity(df),
'hourly_distribution': self._calculate_hourly_distribution(df)
}
def _calculate_peak_hours(self, df: pd.DataFrame) -> List[int]:
"""حساب ساعات الذروة"""
return [9, 10, 14, 15, 16] # مثال
def _calculate_weekend_activity(self, df: pd.DataFrame) -> float:
"""حساب النشاط في عطلة نهاية الأسبوع"""
return 0.75 # مثال
def _calculate_hourly_distribution(self, df: pd.DataFrame) -> Dict[int, float]:
"""حساب التوزيع بالساعة"""
return {i: 0.01 for i in range(24)} # مثال
def predict_usage(self, days: int = 30) -> Dict[str, Any]:
"""توقع الاستخدام المستقبلي"""
# جمع البيانات التاريخية
historical_data = self._collect_historical_data(days=90)
if len(historical_data) < 14:
return {'error': 'Insufficient data for prediction'}
# إعداد البيانات للتنبؤ
X, y = self._prepare_prediction_data(historical_data)
# تدريب النموذج
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X, y)
# توليد التوقعات
future_dates = pd.date_range(
start=datetime.now(),
periods=days,
freq='D'
)
future_X = self._prepare_future_features(future_dates)
predictions = model.predict(future_X)
return {
'predictions': predictions.tolist(),
'dates': [d.strftime('%Y-%m-%d') for d in future_dates],
'confidence_intervals': self._calculate_confidence_intervals(predictions),
'trend': self._calculate_trend(predictions)
}
def _collect_historical_data(self, days: int) -> List[Dict]:
"""جمع البيانات التاريخية"""
query = f"""
SELECT
DATE(created_at) as date,
COUNT(*) as daily_requests,
COUNT(DISTINCT user_id) as daily_users
FROM messages
WHERE created_at > NOW() - INTERVAL '{days} days'
GROUP BY DATE(created_at)
ORDER BY date
"""
results = self.db.execute(query).fetchall()
return [{'date': r[0], 'requests': r[1], 'users': r[2]} for r in results]
def _prepare_prediction_data(self, data: List[Dict]) -> tuple:
"""تحضير البيانات للتنبؤ"""
# تحويل إلى DataFrame
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df['day_of_week'] = df['date'].dt.dayofweek
df['day_of_month'] = df['date'].dt.day
df['month'] = df['date'].dt.month
df['quarter'] = df['date'].dt.quarter
# إعداد الميزات
feature_columns = ['requests', 'users', 'day_of_week', 'day_of_month', 'month', 'quarter']
X = df[feature_columns].values
y = df['requests'].shift(-1).values
return X[:-1], y[:-1]
def _prepare_future_features(self, dates: pd.DatetimeIndex) -> np.ndarray:
"""تحضير ميزات للمستقبل"""
data = []
for date in dates:
data.append([
None, # requests غير معروف
None, # users غير معروف
date.dayofweek,
date.day,
date.month,
date.quarter
])
return np.array(data)
def _calculate_confidence_intervals(self, predictions: List[float]) -> List[Dict]:
"""حساب فترات الثقة"""
import math
confidence_intervals = []
for pred in predictions:
# تقدير بسيط لفترة الثقة
error = pred * 0.1 # 10% error margin
confidence_intervals.append({
'lower': pred - error,
'upper': pred + error
})
return confidence_intervals
def _calculate_trend(self, predictions: List[float]) -> str:
"""حساب الاتجاه العام"""
if len(predictions) < 2:
return 'stable'
# حساب ميل الخط
x = np.arange(len(predictions))
slope, _ = np.polyfit(x, predictions, 1)
if slope > 0.1:
return 'increasing'
elif slope < -0.1:
return 'decreasing'
else:
return 'stable'
🚀 الجزء الرابع: استمرارية الأعمال والتعافي من الكوارث
💾 1. نظام النسخ الاحتياطي والاستعادة
python
# api/core/business/backup_manager.py
"""
نظام النسخ الاحتياطي والاستعادة للمؤسسات
"""
import os
import subprocess
import boto3
import json
from datetime import datetime
from typing import Dict, Any, List, Optional
from dataclasses import dataclass
import hashlib
import gzip
import shutil
@dataclass
class Backup:
id: str
created_at: datetime
type: str # 'full' or 'incremental'
size: int
location: str
checksum: str
metadata: Dict[str, Any]
status: str # 'pending', 'completed', 'failed'
class BackupManager:
"""مدير النسخ الاحتياطي والاستعادة"""
def __init__(self, config: Dict[str, Any]):
self.config = config
self.backup_directory = config.get('backup_dir', '/var/backups/dify')
self.retention_days = config.get('retention_days', 30)
# تكوين S3 (إذا كان مستخدماً)
self.s3_client = None
if config.get('s3_enabled'):
self.s3_client = boto3.client(
's3',
aws_access_key_id=config['aws_access_key_id'],
aws_secret_access_key=config['aws_secret_access_key'],
region_name=config.get('aws_region', 'us-east-1')
)
self.s3_bucket = config['s3_bucket']
# إنشاء دليل النسخ الاحتياطي
os.makedirs(self.backup_directory, exist_ok=True)
def create_backup(self, backup_type: str = 'full') -> Backup:
"""إنشاء نسخة احتياطية جديدة"""
backup_id = f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
backup_path = os.path.join(self.backup_directory, backup_id)
os.makedirs(backup_path, exist_ok=True)
# ملف بيانات النسخ الاحتياطي
manifest_file = os.path.join(backup_path, 'manifest.json')
try:
# 1. نسخ قاعدة البيانات
db_backup_path = self._backup_database(backup_path)
# 2. نسخ ملفات RAG/Knowledge
rag_backup_path = self._backup_rag_data(backup_path)
# 3. نسخ ملفات التطبيق
app_backup_path = self._backup_app_data(backup_path)
# 4. نسخ الإعدادات
config_backup_path = self._backup_config(backup_path)
# إنشاء المانيفست
manifest = {
'backup_id': backup_id,
'created_at': datetime.now().isoformat(),
'backup_type': backup_type,
'components': {
'database': db_backup_path,
'rag': rag_backup_path,
'app_data': app_backup_path,
'config': config_backup_path
},
'size': self._calculate_backup_size(backup_path)
}
with open(manifest_file, 'w') as f:
json.dump(manifest, f, indent=2)
# حساب checksum
checksum = self._calculate_checksum(backup_path)
# إنشاء كائن النسخ الاحتياطي
backup = Backup(
id=backup_id,
created_at=datetime.now(),
type=backup_type,
size=manifest['size'],
location=backup_path,
checksum=checksum,
metadata=manifest,
status='completed'
)
# رفع إلى S3 إذا كان مُمكناً
if self.s3_client:
self._upload_to_s3(backup_path, backup_id)
# تنظيف النسخ الاحتياطية القديمة
self._cleanup_old_backups()
return backup
except Exception as e:
# تسجيل الخطأ
return Backup(
id=backup_id,
created_at=datetime.now(),
type=backup_type,
size=0,
location='',
checksum='',
metadata={'error': str(e)},
status='failed'
)
def _backup_database(self, backup_path: str) -> str:
"""نسخ قاعدة البيانات"""
db_path = os.path.join(backup_path, 'database')
os.makedirs(db_path, exist_ok=True)
# استخدام pg_dump لنسخ PostgreSQL
if self.config.get('db_type') == 'postgresql':
db_name = self.config['db_name']
db_user = self.config['db_user']
db_host = self.config.get('db_host', 'localhost')
db_port = self.config.get('db_port', 5432)
dump_file = os.path.join(db_path, 'dump.sql')
# تنفيذ pg_dump
cmd = [
'pg_dump',
'-h', db_host,
'-p', str(db_port),
'-U', db_user,
'-F', 'c', # تنسيق مضغوط
'-f', dump_file,
db_name
]
subprocess.run(cmd, check=True)
# ضغط الملف
compressed_file = f"{dump_file}.gz"
with open(dump_file, 'rb') as f_in:
with gzip.open(compressed_file, 'wb') as f_out:
f_out.write(f_in.read())
os.remove(dump_file)
return compressed_file
return ''
def _backup_rag_data(self, backup_path: str) -> str:
"""نسخ بيانات RAG"""
rag_path = os.path.join(backup_path, 'rag')
os.makedirs(rag_path, exist_ok=True)
# نسخ ملفات RAG من Weaviate أو قاعدة المتجهات
# منطق النسخ يعتمد على نوع قاعدة المتجهات
return rag_path
def _backup_app_data(self, backup_path: str) -> str:
"""نسخ بيانات التطبيق"""
app_path = os.path.join(backup_path, 'app_data')
os.makedirs(app_path, exist_ok=True)
# نسخ ملفات التطبيق (مثل الصور، الملفات المرفوعة)
# منطق النسخ يعتمد على هيكل التخزين
return app_path
def _backup_config(self, backup_path: str) -> str:
"""نسخ الإعدادات"""
config_path = os.path.join(backup_path, 'config')
os.makedirs(config_path, exist_ok=True)
# نسخ ملفات الإعدادات
config_files = [
'.env',
'docker-compose.yml',
'nginx.conf'
]
for file in config_files:
src = f"/app/{file}" # أو المسار الصحيح
dst = os.path.join(config_path, file)
if os.path.exists(src):
shutil.copy2(src, dst)
return config_path
def _calculate_backup_size(self, backup_path: str) -> int:
"""حساب حجم النسخ الاحتياطي"""
total_size = 0
for dirpath, dirnames, filenames in os.walk(backup_path):
for f in filenames:
fp = os.path.join(dirpath, f)
total_size += os.path.getsize(fp)
return total_size
def _calculate_checksum(self, backup_path: str) -> str:
"""حساب checksum للنسخ الاحتياطي"""
sha256_hash = hashlib.sha256()
for dirpath, dirnames, filenames in os.walk(backup_path):
for f in filenames:
fp = os.path.join(dirpath, f)
with open(fp, "rb") as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def _upload_to_s3(self, backup_path: str, backup_id: str):
"""رفع النسخ الاحتياطي إلى S3"""
# ضغط المجلد
archive_path = shutil.make_archive(
os.path.join(self.backup_directory, backup_id),
'zip',
backup_path
)
# رفع إلى S3
key = f"backups/{backup_id}.zip"
self.s3_client.upload_file(
archive_path,
self.s3_bucket,
key,
ExtraArgs={'ServerSideEncryption': 'AES256'}
)
# تنظيف الملف المؤقت
os.remove(archive_path)
def _cleanup_old_backups(self):
"""تنظيف النسخ الاحتياطية القديمة"""
cutoff_time = datetime.now() - timedelta(days=self.retention_days)
for item in os.listdir(self.backup_directory):
item_path = os.path.join(self.backup_directory, item)
if os.path.isdir(item_path):
# استخراج تاريخ النسخ الاحتياطي
try:
backup_date = datetime.strptime(item.split('_')[1], '%Y%m%d')
if backup_date < cutoff_time:
shutil.rmtree(item_path)
except:
pass
def restore_backup(self, backup_id: str) -> Dict[str, Any]:
"""استعادة نسخة احتياطية"""
backup_path = os.path.join(self.backup_directory, backup_id)
if not os.path.exists(backup_path):
# محاولة تحميل من S3
if self.s3_client:
self._download_from_s3(backup_id)
if not os.path.exists(backup_path):
return {'error': 'Backup not found'}
# قراءة المانيفست
manifest_file = os.path.join(backup_path, 'manifest.json')
with open(manifest_file, 'r') as f:
manifest = json.load(f)
try:
# 1. استعادة قاعدة البيانات
self._restore_database(manifest['components']['database'])
# 2. استعادة بيانات RAG
self._restore_rag_data(manifest['components']['rag'])
# 3. استعادة بيانات التطبيق
self._restore_app_data(manifest['components']['app_data'])
# 4. استعادة الإعدادات
self._restore_config(manifest['components']['config'])
return {
'success': True,
'backup_id': backup_id,
'restored_at': datetime.now().isoformat()
}
except Exception as e:
return {
'success': False,
'error': str(e)
}
def _restore_database(self, backup_path: str):
"""استعادة قاعدة البيانات"""
if os.path.exists(backup_path) and backup_path.endswith('.gz'):
# فك الضغط
decompressed_path = backup_path.replace('.gz', '')
with gzip.open(backup_path, 'rb') as f_in:
with open(decompressed_path, 'wb') as f_out:
f_out.write(f_in.read())
# استعادة باستخدام pg_restore
db_name = self.config['db_name']
db_user = self.config['db_user']
db_host = self.config.get('db_host', 'localhost')
db_port = self.config.get('db_port', 5432)
cmd = [
'pg_restore',
'-h', db_host,
'-p', str(db_port),
'-U', db_user,
'-d', db_name,
'-c', # تنظيف قبل الاستعادة
decompressed_path
]
subprocess.run(cmd, check=True)
# تنظيف
os.remove(decompressed_path)
def _download_from_s3(self, backup_id: str):
"""تحميل النسخ الاحتياطي من S3"""
key = f"backups/{backup_id}.zip"
local_path = os.path.join(self.backup_directory, f"{backup_id}.zip")
self.s3_client.download_file(
self.s3_bucket,
key,
local_path
)
# فك الضغط
shutil.unpack_archive(local_path, os.path.join(self.backup_directory, backup_id))
os.remove(local_path)
🌟 الخاتمة النهائية
🎯 ما حققناه في هذه الرحلة المتقدمة للمؤسسات
| المجال | الإنجازات |
|---|---|
| الهندسة المعمارية | تصميم نظام موزع متعدد المناطق مع موازنة تحميل وتوزيع جغرافي |
| الأمان | سياسات أمان متقدمة، IAM، تشفير البيانات، الامتثال للمعايير |
| المراقبة | نظام مراقبة شامل مع تنبيهات وتحليلات متقدمة |
| التحليلات | تحليلات الأعمال، توقع الاستخدام، تقسيم المستخدمين |
| استمرارية الأعمال | نظام نسخ احتياطي واستعادة مع S3 ودعم الكوارث |
🚀 أنت الآن مهندس معماري للمؤسسات:
text
┌─────────────────────────────────────────────────────────────────────────────┐ │ 🏗️ مصمم أنظمة موزعة على مستوى المؤسسات │ │ 🔐 خبير أمان وامتثال للمعايير العالمية │ │ 📊 خبير تحليلات الأعمال والذكاء الاصطناعي │ │ 💾 خبير استمرارية الأعمال واستعادة الكوارث │ │ 🚀 قائد تقني يمكنه بناء أنظمة تخدم ملايين المستخدمين │ │ 🌍 مصمم أنظمة متعددة المناطق مع توزيع جغرافي │ │ 💪 مستعد لقيادة مشاريع على مستوى المؤسسات الكبرى │ └─────────────────────────────────────────────────────────────────────────────┘
💬 ماذا تريد أن تفعل الآن؟
| الرقم | الخيار |
|---|---|
| 1️⃣ | بناء مشروع حقيقي على مستوى المؤسسات |
| 2️⃣ | تطبيق نظام النسخ الاحتياطي في إنتاج حقيقي |
| 3️⃣ | تصميم نظام مراقبة شامل لمؤسستك |
| 4️⃣ | تطبيق نظام IAM مع LDAP/SAML |
| 5️⃣ | بناء نظام تحليلات متقدم باستخدام البيانات الحقيقية |
| 6️⃣ | المساهمة في تحسين Dify للمؤسسات |
| 7️⃣ | أي موضوع آخر تريد معرفته |
أخبرني أين تريد الذهاب، وسأكون مرشدك في كل خطوة! 🚀🌌