mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-26 17:06:22 +02:00
Structure the tech specs directory (#836)
Tech spec some subdirectories for different languages
This commit is contained in:
parent
48da6c5f8b
commit
e7efb673ef
423 changed files with 0 additions and 0 deletions
135
docs/tech-specs/ar/__TEMPLATE.ar.md
Normal file
135
docs/tech-specs/ar/__TEMPLATE.ar.md
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية لتحميل المعرفة من سطر الأوامر"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية لتحميل المعرفة من سطر الأوامر
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفة واجهات سطر الأوامر لتحميل المعرفة إلى TrustGraph، مما يمكّن المستخدمين من استيراد البيانات من مصادر مختلفة من خلال أدوات سطر الأوامر. تدعم هذه التكامل أربع حالات استخدام رئيسية:
|
||||
|
||||
1. **[حالة الاستخدام 1]**: [الوصف]
|
||||
2. **[حالة الاستخدام 2]**: [الوصف]
|
||||
3. **[حالة الاستخدام 3]**: [الوصف]
|
||||
4. **[حالة الاستخدام 4]**: [الوصف]
|
||||
|
||||
## الأهداف
|
||||
|
||||
- **[الهدف 1]**: [الوصف]
|
||||
- **[الهدف 2]**: [الوصف]
|
||||
- **[الهدف 3]**: [الوصف]
|
||||
- **[الهدف 4]**: [الوصف]
|
||||
- **[الهدف 5]**: [الوصف]
|
||||
- **[الهدف 6]**: [الوصف]
|
||||
- **[الهدف 7]**: [الوصف]
|
||||
- **[الهدف 8]**: [الوصف]
|
||||
|
||||
## الخلفية
|
||||
|
||||
[صف الحالة الحالية والقيود التي تعالجها هذه المواصفة]
|
||||
|
||||
تشمل القيود الحالية:
|
||||
- [القيد 1]
|
||||
- [القيد 2]
|
||||
- [القيد 3]
|
||||
- [القيد 4]
|
||||
|
||||
تعالج هذه المواصفة هذه الثغرات من خلال [الوصف]. من خلال [القدرة]، يمكن لـ TrustGraph:
|
||||
- [الفائدة 1]
|
||||
- [الفائدة 2]
|
||||
- [الفائدة 3]
|
||||
- [الفائدة 4]
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
يتطلب تحميل المعرفة من سطر الأوامر المكونات الفنية التالية:
|
||||
|
||||
1. **[المكون 1]**
|
||||
- [وصف وظيفة المكون]
|
||||
- [الميزات الرئيسية]
|
||||
- [نقاط التكامل]
|
||||
|
||||
الوحدة: [مسار-الوحدة]
|
||||
|
||||
2. **[المكون 2]**
|
||||
- [وصف وظيفة المكون]
|
||||
- [الميزات الرئيسية]
|
||||
- [نقاط التكامل]
|
||||
|
||||
الوحدة: [مسار-الوحدة]
|
||||
|
||||
3. **[المكون 3]**
|
||||
- [وصف وظيفة المكون]
|
||||
- [الميزات الرئيسية]
|
||||
- [نقاط التكامل]
|
||||
|
||||
الوحدة: [مسار-الوحدة]
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### [نموذج البيانات 1]
|
||||
|
||||
[وصف نموذج البيانات والبنية]
|
||||
|
||||
مثال:
|
||||
```
|
||||
[Example data structure]
|
||||
```
|
||||
|
||||
هذا النهج يسمح بما يلي:
|
||||
- [الفائدة 1]
|
||||
- [الفائدة 2]
|
||||
- [الفائدة 3]
|
||||
- [الفائدة 4]
|
||||
|
||||
### واجهات برمجة التطبيقات (APIs)
|
||||
|
||||
واجهات برمجة تطبيقات جديدة:
|
||||
- [وصف واجهة برمجة التطبيقات 1]
|
||||
- [وصف واجهة برمجة التطبيقات 2]
|
||||
- [وصف واجهة برمجة التطبيقات 3]
|
||||
|
||||
واجهات برمجة تطبيقات مُعدَّلة:
|
||||
- [واجهة برمجة تطبيقات مُعدَّلة 1] - [وصف التغييرات]
|
||||
- [واجهة برمجة تطبيقات مُعدَّلة 2] - [وصف التغييرات]
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
[نهج التنفيذ والاصطلاحات]
|
||||
|
||||
[ملاحظات إضافية حول التنفيذ]
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
[اعتبارات الأمان الخاصة بهذا التنفيذ]
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
[اعتبارات الأداء والاختناقات المحتملة]
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
[نهج واستراتيجية الاختبار]
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
[استراتيجية الترحيل إذا كانت قابلة للتطبيق]
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
[معلومات حول الجدول الزمني إذا تم تحديدها]
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
- [سؤال مفتوح 1]
|
||||
- [سؤال مفتوح 2]
|
||||
|
||||
## المراجع
|
||||
|
||||
[المراجع إذا كانت قابلة للتطبيق]
|
||||
280
docs/tech-specs/ar/agent-explainability.ar.md
Normal file
280
docs/tech-specs/ar/agent-explainability.ar.md
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
---
|
||||
layout: default
|
||||
title: "شرح عمل الوكيل: تسجيل المصدر"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# شرح عمل الوكيل: تسجيل المصدر
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
أضف تسجيل المصدر إلى حلقة الوكيل في React حتى يمكن تتبع جلسات الوكيل وتصحيحها باستخدام نفس البنية التحتية للشرح كما هو الحال في GraphRAG.
|
||||
|
||||
**قرارات التصميم:**
|
||||
الكتابة إلى `urn:graph:retrieval` (رسم بياني للشرح العام)
|
||||
سلسلة اعتماد خطية في الوقت الحالي (تحليل N → تم اشتقاقه من → تحليل N-1)
|
||||
الأدوات هي صناديق سوداء (تسجيل الإدخال/الإخراج فقط)
|
||||
دعم الرسم البياني الموجه غير المتصل (DAG) مؤجل للتكرار المستقبلي
|
||||
|
||||
## أنواع الكيانات
|
||||
|
||||
يستخدم كل من GraphRAG والوكيل PROV-O كعلم الوجود الأساسي مع أنواع فرعية خاصة بـ TrustGraph:
|
||||
|
||||
### أنواع GraphRAG
|
||||
| الكيان | نوع PROV-O | أنواع TG | الوصف |
|
||||
|--------|-------------|----------|-------------|
|
||||
| سؤال | `prov:Activity` | `tg:Question`, `tg:GraphRagQuestion` | استعلام المستخدم |
|
||||
| استكشاف | `prov:Entity` | `tg:Exploration` | الحواف المستردة من الرسم البياني المعرفي |
|
||||
| تركيز | `prov:Entity` | `tg:Focus` | الحواف المحددة مع الاستدلال |
|
||||
| توليف | `prov:Entity` | `tg:Synthesis` | الإجابة النهائية |
|
||||
|
||||
### أنواع الوكيل
|
||||
| الكيان | نوع PROV-O | أنواع TG | الوصف |
|
||||
|--------|-------------|----------|-------------|
|
||||
| سؤال | `prov:Activity` | `tg:Question`, `tg:AgentQuestion` | استعلام المستخدم |
|
||||
| تحليل | `prov:Entity` | `tg:Analysis` | كل دورة تفكير/فعل/ملاحظة |
|
||||
| استنتاج | `prov:Entity` | `tg:Conclusion` | الإجابة النهائية |
|
||||
|
||||
### أنواع RAG للوثائق
|
||||
| الكيان | نوع PROV-O | أنواع TG | الوصف |
|
||||
|--------|-------------|----------|-------------|
|
||||
| سؤال | `prov:Activity` | `tg:Question`, `tg:DocRagQuestion` | استعلام المستخدم |
|
||||
| استكشاف | `prov:Entity` | `tg:Exploration` | أجزاء مستردة من مستودع المستندات |
|
||||
| توليف | `prov:Entity` | `tg:Synthesis` | الإجابة النهائية |
|
||||
|
||||
**ملاحظة:** يستخدم RAG للوثائق مجموعة فرعية من أنواع GraphRAG (لا توجد خطوة "تركيز" نظرًا لعدم وجود مرحلة اختيار/استدلال للحواف).
|
||||
|
||||
### أنواع فرعية للأسئلة
|
||||
|
||||
تشترك جميع كيانات "سؤال" في `tg:Question` كنوع أساسي ولكنها تحتوي على نوع فرعي محدد لتحديد آلية الاسترداد:
|
||||
|
||||
| النوع الفرعي | نمط URI | الآلية |
|
||||
|---------|-------------|-----------|
|
||||
| `tg:GraphRagQuestion` | `urn:trustgraph:question:{uuid}` | RAG للرسم البياني المعرفي |
|
||||
| `tg:DocRagQuestion` | `urn:trustgraph:docrag:{uuid}` | RAG للوثائق/الأجزاء |
|
||||
| `tg:AgentQuestion` | `urn:trustgraph:agent:{uuid}` | وكيل ReAct |
|
||||
|
||||
يتيح ذلك الاستعلام عن جميع الأسئلة عبر `tg:Question` مع التصفية حسب آلية معينة عبر النوع الفرعي.
|
||||
|
||||
## نموذج المصدر
|
||||
|
||||
```
|
||||
Question (urn:trustgraph:agent:{uuid})
|
||||
│
|
||||
│ tg:query = "User's question"
|
||||
│ prov:startedAtTime = timestamp
|
||||
│ rdf:type = prov:Activity, tg:Question
|
||||
│
|
||||
↓ prov:wasDerivedFrom
|
||||
│
|
||||
Analysis1 (urn:trustgraph:agent:{uuid}/i1)
|
||||
│
|
||||
│ tg:thought = "I need to query the knowledge base..."
|
||||
│ tg:action = "knowledge-query"
|
||||
│ tg:arguments = {"question": "..."}
|
||||
│ tg:observation = "Result from tool..."
|
||||
│ rdf:type = prov:Entity, tg:Analysis
|
||||
│
|
||||
↓ prov:wasDerivedFrom
|
||||
│
|
||||
Analysis2 (urn:trustgraph:agent:{uuid}/i2)
|
||||
│ ...
|
||||
↓ prov:wasDerivedFrom
|
||||
│
|
||||
Conclusion (urn:trustgraph:agent:{uuid}/final)
|
||||
│
|
||||
│ tg:answer = "The final response..."
|
||||
│ rdf:type = prov:Entity, tg:Conclusion
|
||||
```
|
||||
|
||||
### نموذج تتبع أصل المستندات (Document RAG Provenance Model)
|
||||
|
||||
```
|
||||
Question (urn:trustgraph:docrag:{uuid})
|
||||
│
|
||||
│ tg:query = "User's question"
|
||||
│ prov:startedAtTime = timestamp
|
||||
│ rdf:type = prov:Activity, tg:Question
|
||||
│
|
||||
↓ prov:wasGeneratedBy
|
||||
│
|
||||
Exploration (urn:trustgraph:docrag:{uuid}/exploration)
|
||||
│
|
||||
│ tg:chunkCount = 5
|
||||
│ tg:selectedChunk = "chunk-id-1"
|
||||
│ tg:selectedChunk = "chunk-id-2"
|
||||
│ ...
|
||||
│ rdf:type = prov:Entity, tg:Exploration
|
||||
│
|
||||
↓ prov:wasDerivedFrom
|
||||
│
|
||||
Synthesis (urn:trustgraph:docrag:{uuid}/synthesis)
|
||||
│
|
||||
│ tg:content = "The synthesized answer..."
|
||||
│ rdf:type = prov:Entity, tg:Synthesis
|
||||
```
|
||||
|
||||
## التغييرات المطلوبة
|
||||
|
||||
### 1. تغييرات المخطط
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/schema/services/agent.py`
|
||||
|
||||
أضف الحقول `session_id` و `collection` إلى `AgentRequest`:
|
||||
```python
|
||||
@dataclass
|
||||
class AgentRequest:
|
||||
question: str = ""
|
||||
state: str = ""
|
||||
group: list[str] | None = None
|
||||
history: list[AgentStep] = field(default_factory=list)
|
||||
user: str = ""
|
||||
collection: str = "default" # NEW: Collection for provenance traces
|
||||
streaming: bool = False
|
||||
session_id: str = "" # NEW: For provenance tracking across iterations
|
||||
```
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/messaging/translators/agent.py`
|
||||
|
||||
تحديث المترجم للتعامل مع `session_id` و `collection` في كل من `to_pulsar()` و `from_pulsar()`.
|
||||
|
||||
### 2. إضافة مُنتج الشفافية إلى خدمة الوكيل
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/agent/react/service.py`
|
||||
|
||||
تسجيل مُنتج "الشفافية" (بنفس النمط مثل GraphRAG):
|
||||
```python
|
||||
from ... base import ProducerSpec
|
||||
from ... schema import Triples
|
||||
|
||||
# In __init__:
|
||||
self.register_specification(
|
||||
ProducerSpec(
|
||||
name = "explainability",
|
||||
schema = Triples,
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### 3. توليد الثلاثيات المتعلقة بالأصل.
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/provenance/agent.py`
|
||||
|
||||
إنشاء دوال مساعدة (مشابهة لدوال `question_triples` و `exploration_triples`، إلخ في GraphRAG):
|
||||
```python
|
||||
def agent_session_triples(session_uri, query, timestamp):
|
||||
"""Generate triples for agent Question."""
|
||||
return [
|
||||
Triple(s=session_uri, p=RDF_TYPE, o=PROV_ACTIVITY),
|
||||
Triple(s=session_uri, p=RDF_TYPE, o=TG_QUESTION),
|
||||
Triple(s=session_uri, p=TG_QUERY, o=query),
|
||||
Triple(s=session_uri, p=PROV_STARTED_AT_TIME, o=timestamp),
|
||||
]
|
||||
|
||||
def agent_iteration_triples(iteration_uri, parent_uri, thought, action, arguments, observation):
|
||||
"""Generate triples for one Analysis step."""
|
||||
return [
|
||||
Triple(s=iteration_uri, p=RDF_TYPE, o=PROV_ENTITY),
|
||||
Triple(s=iteration_uri, p=RDF_TYPE, o=TG_ANALYSIS),
|
||||
Triple(s=iteration_uri, p=TG_THOUGHT, o=thought),
|
||||
Triple(s=iteration_uri, p=TG_ACTION, o=action),
|
||||
Triple(s=iteration_uri, p=TG_ARGUMENTS, o=json.dumps(arguments)),
|
||||
Triple(s=iteration_uri, p=TG_OBSERVATION, o=observation),
|
||||
Triple(s=iteration_uri, p=PROV_WAS_DERIVED_FROM, o=parent_uri),
|
||||
]
|
||||
|
||||
def agent_final_triples(final_uri, parent_uri, answer):
|
||||
"""Generate triples for Conclusion."""
|
||||
return [
|
||||
Triple(s=final_uri, p=RDF_TYPE, o=PROV_ENTITY),
|
||||
Triple(s=final_uri, p=RDF_TYPE, o=TG_CONCLUSION),
|
||||
Triple(s=final_uri, p=TG_ANSWER, o=answer),
|
||||
Triple(s=final_uri, p=PROV_WAS_DERIVED_FROM, o=parent_uri),
|
||||
]
|
||||
```
|
||||
|
||||
### 4. تعريفات الأنواع
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/provenance/namespaces.py`
|
||||
|
||||
أضف أنواع الكيانات الخاصة بالتفسير والعبارات الخاصة بالوكيل:
|
||||
```python
|
||||
# Explainability entity types (used by both GraphRAG and Agent)
|
||||
TG_QUESTION = TG + "Question"
|
||||
TG_EXPLORATION = TG + "Exploration"
|
||||
TG_FOCUS = TG + "Focus"
|
||||
TG_SYNTHESIS = TG + "Synthesis"
|
||||
TG_ANALYSIS = TG + "Analysis"
|
||||
TG_CONCLUSION = TG + "Conclusion"
|
||||
|
||||
# Agent predicates
|
||||
TG_THOUGHT = TG + "thought"
|
||||
TG_ACTION = TG + "action"
|
||||
TG_ARGUMENTS = TG + "arguments"
|
||||
TG_OBSERVATION = TG + "observation"
|
||||
TG_ANSWER = TG + "answer"
|
||||
```
|
||||
|
||||
## الملفات التي تم تعديلها
|
||||
|
||||
| الملف | التغيير |
|
||||
|------|--------|
|
||||
| `trustgraph-base/trustgraph/schema/services/agent.py` | إضافة session_id و collection إلى AgentRequest |
|
||||
| `trustgraph-base/trustgraph/messaging/translators/agent.py` | تحديث المترجم للحقول الجديدة |
|
||||
| `trustgraph-base/trustgraph/provenance/namespaces.py` | إضافة أنواع الكيانات، وعبارات الوكيل، وأنواع Document RAG |
|
||||
| `trustgraph-base/trustgraph/provenance/triples.py` | إضافة أنواع TG إلى أدوات بناء الثلاثيات GraphRAG، وإضافة أدوات بناء الثلاثيات Document RAG |
|
||||
| `trustgraph-base/trustgraph/provenance/uris.py` | إضافة مولدات URI لـ Document RAG |
|
||||
| `trustgraph-base/trustgraph/provenance/__init__.py` | تصدير الأنواع والعبارات الجديدة ووظائف Document RAG |
|
||||
| `trustgraph-base/trustgraph/schema/services/retrieval.py` | إضافة explain_id و explain_graph إلى DocumentRagResponse |
|
||||
| `trustgraph-base/trustgraph/messaging/translators/retrieval.py` | تحديث DocumentRagResponseTranslator للحقول الخاصة بالقدرة على الشرح |
|
||||
| `trustgraph-flow/trustgraph/agent/react/service.py` | إضافة منطق الإنتاج والتسجيل الخاص بالقدرة على الشرح |
|
||||
| `trustgraph-flow/trustgraph/retrieval/document_rag/document_rag.py` | إضافة استدعاء رد (callback) خاص بالقدرة على الشرح وإصدار ثلاثيات المصدر |
|
||||
| `trustgraph-flow/trustgraph/retrieval/document_rag/rag.py` | إضافة مُنتج القدرة على الشرح وربطه بالاستدعاء الردي |
|
||||
| `trustgraph-cli/trustgraph/cli/show_explain_trace.py` | معالجة أنواع تتبع الوكيل |
|
||||
| `trustgraph-cli/trustgraph/cli/list_explain_traces.py` | عرض جلسات الوكيل جنبًا إلى جنب مع GraphRAG |
|
||||
|
||||
## الملفات التي تم إنشاؤها
|
||||
|
||||
| الملف | الغرض |
|
||||
|------|---------|
|
||||
| `trustgraph-base/trustgraph/provenance/agent.py` | مولدات ثلاثيات خاصة بالوكيل |
|
||||
|
||||
## تحديثات واجهة سطر الأوامر (CLI)
|
||||
|
||||
**الكشف:** كل من GraphRAG والأسئلة الخاصة بالوكيل لهما نوع `tg:Question`. يتم التمييز بينهما بواسطة:
|
||||
1. نمط URI: `urn:trustgraph:agent:` مقابل `urn:trustgraph:question:`
|
||||
2. الكيانات المشتقة: `tg:Analysis` (الوكيل) مقابل `tg:Exploration` (GraphRAG)
|
||||
|
||||
**`list_explain_traces.py`:**
|
||||
يعرض عمود النوع (الوكيل مقابل GraphRAG)
|
||||
|
||||
**`show_explain_trace.py`:**
|
||||
يكتشف تلقائيًا نوع التتبع
|
||||
يعرض عرض الوكيل: سؤال → خطوة(ات) تحليل → استنتاج
|
||||
|
||||
## التوافق مع الإصدارات السابقة
|
||||
|
||||
`session_id` افتراضيًا إلى `""` - تعمل الطلبات القديمة، ولكن لن تحتوي على معلومات المصدر |
|
||||
`collection` افتراضيًا إلى `"default"` - حل بديل معقول |
|
||||
تتعامل واجهة سطر الأوامر (CLI) بأمان مع كلا نوعي التتبع |
|
||||
|
||||
## التحقق
|
||||
|
||||
```bash
|
||||
# Run an agent query
|
||||
tg-invoke-agent -q "What is the capital of France?"
|
||||
|
||||
# List traces (should show agent sessions with Type column)
|
||||
tg-list-explain-traces -U trustgraph -C default
|
||||
|
||||
# Show agent trace
|
||||
tg-show-explain-trace "urn:trustgraph:agent:xxx"
|
||||
```
|
||||
|
||||
## الأعمال المستقبلية (ليست جزءًا من هذا التعديل)
|
||||
|
||||
تبعيات الرسم البياني الموجه (عندما يعتمد التحليل N على نتائج تحليلات سابقة متعددة)
|
||||
ربط المصادر الخاص بالأدوات (KnowledgeQuery ← تتبع GraphRAG الخاص به)
|
||||
إرسال المصادر بشكل مستمر (إرسال البيانات أثناء العمل، وليس دفعة واحدة في النهاية)
|
||||
113
docs/tech-specs/ar/architecture-principles.ar.md
Normal file
113
docs/tech-specs/ar/architecture-principles.ar.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
---
|
||||
layout: default
|
||||
title: "أسس هيكل الرسم البياني للمعرفة"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# أسس هيكل الرسم البياني للمعرفة
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## الأساس الأول: نموذج الرسم البياني للعلاقة بين الموضوع والمسند والموضوع (SPO)
|
||||
**القرار**: اعتماد نموذج SPO/RDF كنموذج تمثيل المعرفة الأساسي
|
||||
|
||||
**السبب**:
|
||||
يوفر أقصى قدر من المرونة وقابلية التشغيل البيني مع تقنيات الرسم البياني الحالية
|
||||
يمكّن الترجمة السلسة إلى لغات استعلام عن الرسم البياني الأخرى (مثل SPO → Cypher، ولكن ليس العكس)
|
||||
يخلق أساسًا "يفتح الكثير" من القدرات اللاحقة
|
||||
يدعم كل من علاقات العقدة إلى العقدة (SPO) وعلاقات العقدة إلى القيمة الحرفية (RDF)
|
||||
|
||||
**التنفيذ**:
|
||||
الهيكل الأساسي للبيانات: `node → edge → {node | literal}`
|
||||
الحفاظ على التوافق مع معايير RDF مع دعم عمليات SPO الموسعة
|
||||
|
||||
## الأساس الثاني: تكامل الرسم البياني الأصلي لنماذج اللغة الكبيرة (LLM)
|
||||
**القرار**: تحسين هيكل وعمليات الرسم البياني للتفاعل مع نماذج اللغة الكبيرة
|
||||
|
||||
**السبب**:
|
||||
الحالة الرئيسية هي تفاعل نماذج اللغة الكبيرة مع الرسوم البيانية للمعرفة
|
||||
يجب أن تعطي خيارات تقنية الرسم البياني الأولوية لتوافق نماذج اللغة الكبيرة على اعتبارات أخرى
|
||||
يمكّن سير عمل معالجة اللغة الطبيعية التي تستفيد من المعرفة المنظمة
|
||||
|
||||
**التنفيذ**:
|
||||
تصميم مخططات الرسم البياني التي يمكن لنماذج اللغة الكبيرة الاستدلال عليها بشكل فعال
|
||||
التحسين لأنماط التفاعل الشائعة لنماذج اللغة الكبيرة
|
||||
|
||||
## الأساس الثالث: التنقل في الرسم البياني القائم على التضمين
|
||||
**القرار**: تنفيذ تعيين مباشر من استعلامات اللغة الطبيعية إلى عقد الرسم البياني عبر التضمينات
|
||||
|
||||
**السبب**:
|
||||
يمكّن المسار الأبسط من استعلام معالجة اللغة الطبيعية إلى التنقل في الرسم البياني
|
||||
يتجنب خطوات توليد استعلام وسيطة معقدة
|
||||
يوفر قدرات بحث دلالي فعالة داخل هيكل الرسم البياني
|
||||
|
||||
**التنفيذ**:
|
||||
`NLP Query → Graph Embeddings → Graph Nodes`
|
||||
الحفاظ على تمثيلات التضمين لجميع كيانات الرسم البياني
|
||||
دعم مطابقة تشابه دلالي مباشر لحل الاستعلامات
|
||||
|
||||
## الأساس الرابع: حل الكيانات الموزع مع المعرفات الحتمية
|
||||
**القرار**: دعم استخراج المعرفة المتوازي مع تحديد الكيانات الحتمي (قاعدة 80٪)
|
||||
|
||||
**السبب**:
|
||||
**مثالي**: يتيح استخراج العملية الفردية مع رؤية حالة كاملة حل الكيانات المثالي
|
||||
**الواقع**: تتطلب متطلبات قابلية التوسع قدرات معالجة متوازية
|
||||
**حل وسط**: التصميم من أجل تحديد الكيانات الحتمي عبر العمليات الموزعة
|
||||
|
||||
**التنفيذ**:
|
||||
تطوير آليات لتوليد معرفات متسقة وفريدة عبر أدوات استخراج المعرفة المختلفة
|
||||
يجب أن يتم حل نفس الكيان المذكور في عمليات مختلفة إلى نفس المعرف
|
||||
الاعتراف بأنه قد تتطلب ~20٪ من الحالات الخاصة نماذج معالجة بديلة
|
||||
تصميم آليات احتياطية لسيناريوهات حل الكيانات المعقدة
|
||||
|
||||
## الأساس الخامس: بنية قائمة على الأحداث مع النشر والاشتراك
|
||||
**القرار**: تنفيذ نظام رسائل النشر والاشتراك لتنسيق النظام
|
||||
|
||||
**السبب**:
|
||||
يمكّن الفصل بين مكونات استخراج وتخزين واستعلام المعرفة
|
||||
يدعم التحديثات والإشعارات في الوقت الفعلي عبر النظام
|
||||
يسهل سير عمل معالجة موزعة وقابلة للتطوير
|
||||
|
||||
**التنفيذ**:
|
||||
تنسيق مدفوع بالرسائل بين مكونات النظام
|
||||
تدفقات الأحداث لتحديثات المعرفة وإكمال الاستخراج ونتائج الاستعلام
|
||||
|
||||
## الأساس السادس: تواصل الوكيل القابل لإعادة الدخول
|
||||
**القرار**: دعم عمليات النشر والاشتراك القابلة لإعادة الدخول لمعالجة قائمة على الوكلاء
|
||||
|
||||
**السبب**:
|
||||
يمكّن سير عمل الوكيل المعقد حيث يمكن للوكلاء تشغيل والرد على بعضهم البعض
|
||||
يدعم خطوط أنابيب معالجة المعرفة المعقدة والمتعددة الخطوات
|
||||
يسمح بأنماط المعالجة التكرارية والتكرارية
|
||||
|
||||
**التنفيذ**:
|
||||
يجب أن يتعامل نظام النشر والاشتراك مع المكالمات القابلة لإعادة الدخول بأمان
|
||||
آليات تنسيق الوكيل التي تمنع الحلقات اللانهائية
|
||||
دعم تنسيق سير عمل الوكيل
|
||||
|
||||
## الأساس السابع: تكامل متجر البيانات العمودي
|
||||
**القرار**: ضمان توافق الاستعلام مع أنظمة التخزين العمودية
|
||||
|
||||
**السبب**:
|
||||
يمكّن الاستعلامات التحليلية الفعالة على مجموعات بيانات المعرفة الكبيرة
|
||||
يدعم حالات استخدام ذكاء الأعمال وإعداد التقارير
|
||||
يربط بين تمثيل المعرفة القائم على الرسم البياني وسير العمل التحليلي التقليدي
|
||||
|
||||
**التنفيذ**:
|
||||
طبقة ترجمة الاستعلام: استعلامات الرسم البياني → استعلامات عمودية
|
||||
استراتيجية تخزين هجينة تدعم عمليات الرسم البياني وأحمال العمل التحليلية
|
||||
الحفاظ على أداء الاستعلام عبر كلا النماذجين
|
||||
|
||||
--
|
||||
|
||||
## ملخص مبادئ البنية
|
||||
|
||||
1. **المرونة أولاً**: يوفر نموذج SPO أقصى قدر من القدرة على التكيف
|
||||
2. **التحسين لنماذج اللغة الكبيرة**: تأخذ جميع القرارات التصميمية في الاعتبار متطلبات تفاعل نماذج اللغة الكبيرة
|
||||
3. **الكفاءة الدلالية**: تعيين مباشر من التضمين إلى العقدة لأداء استعلام أمثل
|
||||
4. **قابلية التوسع العملية**: الموازنة بين الدقة المثالية والمعالجة الموزعة العملية
|
||||
5. **التنسيق القائم على الأحداث**: يمكّن النشر والاشتراك من الفصل وقابلية التوسع
|
||||
6. **صديقة للوكيل**: دعم سير عمل معالجة متعددة الوكلاء
|
||||
7. **التوافق التحليلي**: ربط بين نماذج الرسم البياني والأعمدة للاستعلامات الشاملة
|
||||
|
||||
تحدد هذه الأسس بنية رسم بياني للمعرفة تحقق التوازن بين الدقة النظرية ومتطلبات قابلية التوسع العملية، ومحسنة للتكامل مع نماذج اللغة الكبيرة والمعالجة الموزعة.
|
||||
339
docs/tech-specs/ar/cassandra-consolidation.ar.md
Normal file
339
docs/tech-specs/ar/cassandra-consolidation.ar.md
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات فنية: توحيد إعدادات Cassandra"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات فنية: توحيد إعدادات Cassandra
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
**الحالة:** مسودة
|
||||
**المؤلف:** مساعد
|
||||
**التاريخ:** 2024-09-03
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تتناول هذه المواصفة عدم الاتساق في أسماء وأنماط إعدادات معلمات اتصال Cassandra عبر قاعدة بيانات TrustGraph. حاليًا، توجد مخططان مختلفان لتسمية المعلمات (`cassandra_*` مقابل `graph_*`)، مما يؤدي إلى الارتباك وتعقيد الصيانة.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
تستخدم قاعدة البيانات حاليًا مجموعتين متميزتين من معلمات إعداد Cassandra:
|
||||
|
||||
1. **وحدات المعرفة/التكوين/المكتبة** تستخدم:
|
||||
`cassandra_host` (قائمة المضيفين)
|
||||
`cassandra_user`
|
||||
`cassandra_password`
|
||||
|
||||
2. **وحدات الرسم البياني/التخزين** تستخدم:
|
||||
`graph_host` (مضيف واحد، يتم تحويله أحيانًا إلى قائمة)
|
||||
`graph_username`
|
||||
`graph_password`
|
||||
|
||||
3. **عرض غير متسق عبر سطر الأوامر**:
|
||||
بعض المعالجات (مثل `kg-store`) لا تعرض إعدادات Cassandra كمعلمات سطر أوامر
|
||||
تعرض معالجات أخرى هذه الإعدادات بأسماء وتنسيقات مختلفة
|
||||
لا يعكس نص المساعدة القيم الافتراضية لمتغيرات البيئة
|
||||
|
||||
تتصل كلتا مجموعتي المعلمات بنفس مجموعة Cassandra ولكن باتفاقيات تسمية مختلفة، مما يسبب:
|
||||
ارتباك في التكوين للمستخدمين
|
||||
زيادة العبء على الصيانة
|
||||
توثيق غير متسق
|
||||
احتمال حدوث سوء تكوين
|
||||
عدم القدرة على تجاوز الإعدادات عبر سطر الأوامر في بعض المعالجات
|
||||
|
||||
## الحل المقترح
|
||||
|
||||
### 1. توحيد أسماء المعلمات
|
||||
|
||||
ستستخدم جميع الوحدات أسماء معلمات متسقة `cassandra_*`:
|
||||
`cassandra_host` - قائمة المضيفين (مخزنة داخليًا كقائمة)
|
||||
`cassandra_username` - اسم المستخدم للمصادقة
|
||||
`cassandra_password` - كلمة المرور للمصادقة
|
||||
|
||||
### 2. معلمات سطر الأوامر
|
||||
|
||||
يجب على جميع المعالجات عرض إعدادات تكوين Cassandra عبر معلمات سطر الأوامر:
|
||||
`--cassandra-host` - قائمة مفصولة بفواصل من المضيفين
|
||||
`--cassandra-username` - اسم المستخدم للمصادقة
|
||||
`--cassandra-password` - كلمة المرور للمصادقة
|
||||
|
||||
### 3. الاعتماد على متغيرات البيئة
|
||||
|
||||
إذا لم يتم توفير معلمات سطر الأوامر بشكل صريح، فسيتحقق النظام من متغيرات البيئة:
|
||||
`CASSANDRA_HOST` - قائمة مفصولة بفواصل من المضيفين
|
||||
`CASSANDRA_USERNAME` - اسم المستخدم للمصادقة
|
||||
`CASSANDRA_PASSWORD` - كلمة المرور للمصادقة
|
||||
|
||||
### 4. القيم الافتراضية
|
||||
|
||||
إذا لم يتم تحديد أي من معلمات سطر الأوامر أو متغيرات البيئة:
|
||||
`cassandra_host` افتراضيًا إلى `["cassandra"]`
|
||||
`cassandra_username` افتراضيًا إلى `None` (بدون مصادقة)
|
||||
`cassandra_password` افتراضيًا إلى `None` (بدون مصادقة)
|
||||
|
||||
### 5. متطلبات نص المساعدة
|
||||
|
||||
يجب أن يعرض الإخراج `--help`:
|
||||
إظهار قيم متغيرات البيئة كقيم افتراضية عند تعيينها
|
||||
عدم عرض قيم كلمات المرور مطلقًا (إظهار `****` أو `<set>` بدلاً من ذلك)
|
||||
الإشارة بوضوح إلى ترتيب الحل في نص المساعدة
|
||||
|
||||
مثال على إخراج المساعدة:
|
||||
```
|
||||
--cassandra-host HOST
|
||||
Cassandra host list, comma-separated (default: prod-cluster-1,prod-cluster-2)
|
||||
[from CASSANDRA_HOST environment variable]
|
||||
|
||||
--cassandra-username USERNAME
|
||||
Cassandra username (default: cassandra_user)
|
||||
[from CASSANDRA_USERNAME environment variable]
|
||||
|
||||
--cassandra-password PASSWORD
|
||||
Cassandra password (default: <set from environment>)
|
||||
```
|
||||
|
||||
## تفاصيل التنفيذ
|
||||
|
||||
### ترتيب حل المعلمات
|
||||
|
||||
لكل معلمة في Cassandra، سيكون ترتيب الحل كما يلي:
|
||||
1. قيمة وسيط سطر الأوامر
|
||||
2. متغير البيئة (`CASSANDRA_*`)
|
||||
3. القيمة الافتراضية
|
||||
|
||||
### معالجة معلمات المضيف
|
||||
|
||||
المعلمة `cassandra_host`:
|
||||
يقبل سطر الأوامر سلسلة مفصولة بفواصل: `--cassandra-host "host1,host2,host3"`
|
||||
يقبل متغير البيئة سلسلة مفصولة بفواصل: `CASSANDRA_HOST="host1,host2,host3"`
|
||||
يتم تخزينها دائمًا داخليًا كقائمة: `["host1", "host2", "host3"]`
|
||||
مضيف واحد: `"localhost"` → يتم تحويله إلى `["localhost"]`
|
||||
إذا كانت بالفعل قائمة: `["host1", "host2"]` → يتم استخدامها كما هي
|
||||
|
||||
### منطق المصادقة
|
||||
|
||||
سيتم استخدام المصادقة عندما يتم توفير كل من `cassandra_username` و `cassandra_password`:
|
||||
```python
|
||||
if cassandra_username and cassandra_password:
|
||||
# Use SSL context and PlainTextAuthProvider
|
||||
else:
|
||||
# Connect without authentication
|
||||
```
|
||||
|
||||
## الملفات المراد تعديلها
|
||||
|
||||
### الوحدات التي تستخدم معلمات `graph_*` (يجب تغييرها):
|
||||
`trustgraph-flow/trustgraph/storage/triples/cassandra/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/objects/cassandra/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/rows/cassandra/write.py`
|
||||
`trustgraph-flow/trustgraph/query/triples/cassandra/service.py`
|
||||
|
||||
### الوحدات التي تستخدم معلمات `cassandra_*` (يجب تحديثها مع استخدام الإعدادات الافتراضية للبيئة):
|
||||
`trustgraph-flow/trustgraph/tables/config.py`
|
||||
`trustgraph-flow/trustgraph/tables/knowledge.py`
|
||||
`trustgraph-flow/trustgraph/tables/library.py`
|
||||
`trustgraph-flow/trustgraph/storage/knowledge/store.py`
|
||||
`trustgraph-flow/trustgraph/cores/knowledge.py`
|
||||
`trustgraph-flow/trustgraph/librarian/librarian.py`
|
||||
`trustgraph-flow/trustgraph/librarian/service.py`
|
||||
`trustgraph-flow/trustgraph/config/service/service.py`
|
||||
`trustgraph-flow/trustgraph/cores/service.py`
|
||||
|
||||
### ملفات الاختبار المراد تحديثها:
|
||||
`tests/unit/test_cores/test_knowledge_manager.py`
|
||||
`tests/unit/test_storage/test_triples_cassandra_storage.py`
|
||||
`tests/unit/test_query/test_triples_cassandra_query.py`
|
||||
`tests/integration/test_objects_cassandra_integration.py`
|
||||
|
||||
## استراتيجية التنفيذ
|
||||
|
||||
### المرحلة الأولى: إنشاء أداة مساعدة للإعدادات المشتركة
|
||||
إنشاء دوال مساعدة لتوحيد إعدادات Cassandra عبر جميع المعالجات:
|
||||
|
||||
```python
|
||||
import os
|
||||
import argparse
|
||||
|
||||
def get_cassandra_defaults():
|
||||
"""Get default values from environment variables or fallback."""
|
||||
return {
|
||||
'host': os.getenv('CASSANDRA_HOST', 'cassandra'),
|
||||
'username': os.getenv('CASSANDRA_USERNAME'),
|
||||
'password': os.getenv('CASSANDRA_PASSWORD')
|
||||
}
|
||||
|
||||
def add_cassandra_args(parser: argparse.ArgumentParser):
|
||||
"""
|
||||
Add standardized Cassandra arguments to an argument parser.
|
||||
Shows environment variable values in help text.
|
||||
"""
|
||||
defaults = get_cassandra_defaults()
|
||||
|
||||
# Format help text with env var indication
|
||||
host_help = f"Cassandra host list, comma-separated (default: {defaults['host']})"
|
||||
if 'CASSANDRA_HOST' in os.environ:
|
||||
host_help += " [from CASSANDRA_HOST]"
|
||||
|
||||
username_help = f"Cassandra username"
|
||||
if defaults['username']:
|
||||
username_help += f" (default: {defaults['username']})"
|
||||
if 'CASSANDRA_USERNAME' in os.environ:
|
||||
username_help += " [from CASSANDRA_USERNAME]"
|
||||
|
||||
password_help = "Cassandra password"
|
||||
if defaults['password']:
|
||||
password_help += " (default: <set>)"
|
||||
if 'CASSANDRA_PASSWORD' in os.environ:
|
||||
password_help += " [from CASSANDRA_PASSWORD]"
|
||||
|
||||
parser.add_argument(
|
||||
'--cassandra-host',
|
||||
default=defaults['host'],
|
||||
help=host_help
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--cassandra-username',
|
||||
default=defaults['username'],
|
||||
help=username_help
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--cassandra-password',
|
||||
default=defaults['password'],
|
||||
help=password_help
|
||||
)
|
||||
|
||||
def resolve_cassandra_config(args) -> tuple[list[str], str|None, str|None]:
|
||||
"""
|
||||
Convert argparse args to Cassandra configuration.
|
||||
|
||||
Returns:
|
||||
tuple: (hosts_list, username, password)
|
||||
"""
|
||||
# Convert host string to list
|
||||
if isinstance(args.cassandra_host, str):
|
||||
hosts = [h.strip() for h in args.cassandra_host.split(',')]
|
||||
else:
|
||||
hosts = args.cassandra_host
|
||||
|
||||
return hosts, args.cassandra_username, args.cassandra_password
|
||||
```
|
||||
|
||||
### المرحلة الثانية: تحديث الوحدات باستخدام معلمات `graph_*`
|
||||
1. تغيير أسماء المعلمات من `graph_*` إلى `cassandra_*`
|
||||
2. استبدال طرق `add_args()` المخصصة بطرق `add_cassandra_args()` القياسية
|
||||
3. استخدام الدوال المساعدة الشائعة للتكوين
|
||||
4. تحديث سلاسل التوثيق
|
||||
|
||||
مثال على التحويل:
|
||||
```python
|
||||
# OLD CODE
|
||||
@staticmethod
|
||||
def add_args(parser):
|
||||
parser.add_argument(
|
||||
'-g', '--graph-host',
|
||||
default="localhost",
|
||||
help=f'Graph host (default: localhost)'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--graph-username',
|
||||
default=None,
|
||||
help=f'Cassandra username'
|
||||
)
|
||||
|
||||
# NEW CODE
|
||||
@staticmethod
|
||||
def add_args(parser):
|
||||
FlowProcessor.add_args(parser)
|
||||
add_cassandra_args(parser) # Use standard helper
|
||||
```
|
||||
|
||||
### المرحلة الثالثة: تحديث الوحدات باستخدام معلمات `cassandra_*`
|
||||
1. إضافة دعم للوسائط الخاصة بسطر الأوامر في الحالات التي تفتقر إليها (مثل: `kg-store`)
|
||||
2. استبدال تعريفات الوسائط الحالية بـ `add_cassandra_args()`
|
||||
3. استخدام `resolve_cassandra_config()` لتحقيق التوافق
|
||||
4. التأكد من معالجة متسقة لقائمة المضيفين
|
||||
|
||||
### المرحلة الرابعة: تحديث الاختبارات والوثائق
|
||||
1. تحديث جميع ملفات الاختبار لاستخدام أسماء المعلمات الجديدة
|
||||
2. تحديث وثائق واجهة سطر الأوامر
|
||||
3. تحديث وثائق واجهة برمجة التطبيقات
|
||||
4. إضافة وثائق لمتغيرات البيئة
|
||||
|
||||
## التوافق مع الإصدارات السابقة
|
||||
|
||||
للحفاظ على التوافق مع الإصدارات السابقة أثناء الانتقال:
|
||||
|
||||
1. **تحذيرات الإيقاف التدريجي** لمعلمات `graph_*`
|
||||
2. **تسمية بديلة للمعلمات** - قبول الأسماء القديمة والجديدة في البداية
|
||||
3. **نشر تدريجي** على مدار عدة إصدارات
|
||||
4. **تحديثات الوثائق** مع دليل الترحيل
|
||||
|
||||
مثال على كود التوافق مع الإصدارات السابقة:
|
||||
```python
|
||||
def __init__(self, **params):
|
||||
# Handle deprecated graph_* parameters
|
||||
if 'graph_host' in params:
|
||||
warnings.warn("graph_host is deprecated, use cassandra_host", DeprecationWarning)
|
||||
params.setdefault('cassandra_host', params.pop('graph_host'))
|
||||
|
||||
if 'graph_username' in params:
|
||||
warnings.warn("graph_username is deprecated, use cassandra_username", DeprecationWarning)
|
||||
params.setdefault('cassandra_username', params.pop('graph_username'))
|
||||
|
||||
# ... continue with standard resolution
|
||||
```
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
1. **اختبارات الوحدة** لمنطق حل التكوين.
|
||||
2. **اختبارات التكامل** مع مجموعات تكوين مختلفة.
|
||||
3. **اختبارات متغيرات البيئة**.
|
||||
4. **اختبارات التوافق مع الإصدارات السابقة** مع المعلمات التي تم إيقافها.
|
||||
5. **اختبارات Docker Compose** مع متغيرات البيئة.
|
||||
|
||||
## تحديثات التوثيق
|
||||
|
||||
1. تحديث جميع وثائق أوامر واجهة سطر الأوامر.
|
||||
2. تحديث وثائق واجهة برمجة التطبيقات.
|
||||
3. إنشاء دليل ترحيل.
|
||||
4. تحديث أمثلة Docker Compose.
|
||||
5. تحديث وثائق مرجع التكوين.
|
||||
|
||||
## المخاطر والتخفيف
|
||||
|
||||
| المخاطر | التأثير | التخفيف |
|
||||
|------|--------|------------|
|
||||
| تغييرات تؤثر على المستخدمين | مرتفع | تطبيق فترة التوافق مع الإصدارات السابقة. |
|
||||
| ارتباك في التكوين أثناء الانتقال | متوسط | توثيق واضح وتحذيرات إيقاف. |
|
||||
| فشل الاختبارات | متوسط | تحديثات شاملة للاختبارات. |
|
||||
| مشاكل في نشر Docker | مرتفع | تحديث جميع أمثلة Docker Compose. |
|
||||
|
||||
## معايير النجاح
|
||||
|
||||
[ ] تستخدم جميع الوحدات أسماء معلمات `cassandra_*` متسقة.
|
||||
[ ] تعرض جميع المعالجات إعدادات Cassandra عبر وسيطات سطر الأوامر.
|
||||
[ ] يعرض نص المساعدة الخاص بسطر الأوامر القيم الافتراضية لمتغيرات البيئة.
|
||||
[ ] لا يتم عرض قيم كلمات المرور في نص المساعدة.
|
||||
[ ] يعمل التراجع إلى متغيرات البيئة بشكل صحيح.
|
||||
[ ] يتم التعامل مع `cassandra_host` باستمرار كقائمة داخليًا.
|
||||
[ ] تم الحفاظ على التوافق مع الإصدارات السابقة لمدة إصدارين على الأقل.
|
||||
[ ] تجتاز جميع الاختبارات مع نظام التكوين الجديد.
|
||||
[ ] تم تحديث التوثيق بالكامل.
|
||||
[ ] تعمل أمثلة Docker Compose مع متغيرات البيئة.
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
**الأسبوع 1:** تنفيذ أداة مساعدة شائعة للتكوين وتحديث وحدات `graph_*`.
|
||||
**الأسبوع 2:** إضافة دعم لمتغيرات البيئة إلى وحدات `cassandra_*` الحالية.
|
||||
**الأسبوع 3:** تحديث الاختبارات والتوثيق.
|
||||
**الأسبوع 4:** اختبار التكامل وتصحيح الأخطاء.
|
||||
|
||||
## اعتبارات مستقبلية
|
||||
|
||||
ضع في اعتبارك توسيع هذا النمط ليشمل تكوينات قواعد بيانات أخرى (مثل Elasticsearch).
|
||||
تنفيذ التحقق من صحة التكوين ورسائل خطأ أفضل.
|
||||
إضافة دعم لتكوين تجميع الاتصالات لـ Cassandra.
|
||||
ضع في اعتبارك إضافة دعم لملفات التكوين (ملفات .env).
|
||||
687
docs/tech-specs/ar/cassandra-performance-refactor.ar.md
Normal file
687
docs/tech-specs/ar/cassandra-performance-refactor.ar.md
Normal file
|
|
@ -0,0 +1,687 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية: إعادة هيكلة أداء قاعدة المعرفة Cassandra"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية: إعادة هيكلة أداء قاعدة المعرفة Cassandra
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
**الحالة:** مسودة
|
||||
**المؤلف:** مساعد
|
||||
**التاريخ:** 2025-09-18
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تتناول هذه المواصفة مشكلات الأداء في تطبيق قاعدة المعرفة Cassandra TrustGraph وتقترح تحسينات لتخزين واستعلام ثلاثيات RDF.
|
||||
|
||||
## التنفيذ الحالي
|
||||
|
||||
### تصميم المخطط
|
||||
|
||||
يستخدم التنفيذ الحالي تصميم جدول واحد في `trustgraph-flow/trustgraph/direct/cassandra_kg.py`:
|
||||
|
||||
```sql
|
||||
CREATE TABLE triples (
|
||||
collection text,
|
||||
s text,
|
||||
p text,
|
||||
o text,
|
||||
PRIMARY KEY (collection, s, p, o)
|
||||
);
|
||||
```
|
||||
|
||||
**الفهارس الثانوية:**
|
||||
`triples_s` على `s` (الموضوع)
|
||||
`triples_p` على `p` (المُتَعَدِّي)
|
||||
`triples_o` على `o` (المفعول به)
|
||||
|
||||
### أنماط الاستعلام
|
||||
|
||||
تدعم التنفيذ الحالي 8 أنماط استعلام متميزة:
|
||||
|
||||
1. **get_all(collection, limit=50)** - استرجاع جميع الثلاثيات لمجموعة
|
||||
```sql
|
||||
SELECT s, p, o FROM triples WHERE collection = ? LIMIT 50
|
||||
```
|
||||
|
||||
2. **get_s(collection, s, limit=10)** - الاستعلام بناءً على الموضوع.
|
||||
```sql
|
||||
SELECT p, o FROM triples WHERE collection = ? AND s = ? LIMIT 10
|
||||
```
|
||||
|
||||
3. **get_p(collection, p, limit=10)** - الاستعلام بناءً على شرط.
|
||||
```sql
|
||||
SELECT s, o FROM triples WHERE collection = ? AND p = ? LIMIT 10
|
||||
```
|
||||
|
||||
4. **get_o(collection, o, limit=10)** - الاستعلام بناءً على الكائن.
|
||||
```sql
|
||||
SELECT s, p FROM triples WHERE collection = ? AND o = ? LIMIT 10
|
||||
```
|
||||
|
||||
5. **get_sp(collection, s, p, limit=10)** - الاستعلام بناءً على الموضوع + المسند.
|
||||
```sql
|
||||
SELECT o FROM triples WHERE collection = ? AND s = ? AND p = ? LIMIT 10
|
||||
```
|
||||
|
||||
6. **get_po(collection, p, o, limit=10)** - الاستعلام بناءً على الشرط + الكائن ⚠️
|
||||
```sql
|
||||
SELECT s FROM triples WHERE collection = ? AND p = ? AND o = ? LIMIT 10 ALLOW FILTERING
|
||||
```
|
||||
|
||||
7. **get_os(collection, o, s, limit=10)** - الاستعلام بناءً على الكائن والموضوع ⚠️
|
||||
```sql
|
||||
SELECT p FROM triples WHERE collection = ? AND o = ? AND s = ? LIMIT 10 ALLOW FILTERING
|
||||
```
|
||||
|
||||
8. **get_spo(collection, s, p, o, limit=10)** - تطابق ثلاثي دقيق.
|
||||
```sql
|
||||
SELECT s as x FROM triples WHERE collection = ? AND s = ? AND p = ? AND o = ? LIMIT 10
|
||||
```
|
||||
|
||||
### البنية التحتية الحالية
|
||||
|
||||
**الملف: `trustgraph-flow/trustgraph/direct/cassandra_kg.py`**
|
||||
فئة `KnowledgeGraph` واحدة تتعامل مع جميع العمليات.
|
||||
تجميع الاتصالات من خلال قائمة `_active_clusters` عامة.
|
||||
اسم جدول ثابت: `"triples"`.
|
||||
مساحة مفاتيح لكل نموذج مستخدم.
|
||||
استنساخ SimpleStrategy بعامل 1.
|
||||
|
||||
**نقاط التكامل:**
|
||||
**مسار الكتابة:** `trustgraph-flow/trustgraph/storage/triples/cassandra/write.py`.
|
||||
**مسار الاستعلام:** `trustgraph-flow/trustgraph/query/triples/cassandra/service.py`.
|
||||
**مخزن المعرفة:** `trustgraph-flow/trustgraph/tables/knowledge.py`.
|
||||
|
||||
## المشكلات المتعلقة بالأداء التي تم تحديدها
|
||||
|
||||
### مشكلات على مستوى المخطط
|
||||
|
||||
1. **تصميم مفتاح أساسي غير فعال**
|
||||
الحالي: `PRIMARY KEY (collection, s, p, o)`.
|
||||
يؤدي إلى تجميع ضعيف لأنماط الوصول الشائعة.
|
||||
يجبر على استخدام فهرس ثانوي مكلف.
|
||||
|
||||
2. **إفراط في استخدام الفهرس الثانوي** ⚠️
|
||||
ثلاثة فهارس ثانوية على أعمدة ذات قيم عالية (s، p، o).
|
||||
الفهارس الثانوية في Cassandra مكلفة ولا تتوسع بشكل جيد.
|
||||
تتطلب الاستعلامات 6 و 7 `ALLOW FILTERING` مما يشير إلى نموذج بيانات ضعيف.
|
||||
|
||||
3. **خطر التقسيم الساخن**
|
||||
يمكن أن يؤدي مفتاح التقسيم الواحد `collection` إلى إنشاء تقسيمات ساخنة.
|
||||
ستتركز المجموعات الكبيرة على عقد فردية.
|
||||
لا توجد استراتيجية توزيع لتحقيق موازنة التحميل.
|
||||
|
||||
### مشكلات على مستوى الاستعلام
|
||||
|
||||
1. **استخدام ALLOW FILTERING** ⚠️
|
||||
يتطلب نوعان من الاستعلامات (get_po، get_os) `ALLOW FILTERING`.
|
||||
هذه الاستعلامات تفحص العديد من التقسيمات وهي مكلفة للغاية.
|
||||
يتدهور الأداء خطيًا مع حجم البيانات.
|
||||
|
||||
2. **أنماط وصول غير فعالة**
|
||||
لا توجد تحسينات لأنماط استعلام RDF الشائعة.
|
||||
فهارس مركبة مفقودة لتوليفات الاستعلامات المتكررة.
|
||||
لا توجد اعتبارات لأنماط اجتياز الرسم البياني.
|
||||
|
||||
3. **نقص في تحسين الاستعلام**
|
||||
لا يوجد تخزين مؤقت لبيانات الاستعلامات المُعدة.
|
||||
لا توجد تلميحات أو استراتيجيات لتحسين الاستعلام.
|
||||
لا توجد اعتبارات للتقسيم إلى صفحات تتجاوز LIMIT البسيطة.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
يحتوي تطبيق قاعدة المعرفة الحالي في Cassandra على نقطتي اختناق أداء حاسمتين:
|
||||
|
||||
### 1. أداء استعلام get_po غير فعال
|
||||
|
||||
الاستعلام `get_po(collection, p, o)` غير فعال للغاية لأنه يتطلب `ALLOW FILTERING`:
|
||||
|
||||
```sql
|
||||
SELECT s FROM triples WHERE collection = ? AND p = ? AND o = ? LIMIT 10 ALLOW FILTERING
|
||||
```
|
||||
|
||||
**لماذا هذه مشكلة:**
|
||||
`ALLOW FILTERING` تجبر Cassandra على فحص جميع الأقسام داخل المجموعة.
|
||||
تتدهور الأداء بشكل خطي مع حجم البيانات.
|
||||
هذا نمط استعلام RDF شائع (إيجاد الموضوعات التي لها علاقة محددة بين الفاعل والمفعول به).
|
||||
يؤدي ذلك إلى زيادة كبيرة في الحمل على المجموعة مع نمو البيانات.
|
||||
|
||||
### 2. استراتيجية تجميع غير فعالة
|
||||
|
||||
المفتاح الأساسي الحالي `PRIMARY KEY (collection, s, p, o)` يوفر فوائد تجميع محدودة:
|
||||
|
||||
**المشاكل المتعلقة بالتجميع الحالي:**
|
||||
`collection` كمفتاح قسم لا يوزع البيانات بشكل فعال.
|
||||
تحتوي معظم المجموعات على بيانات متنوعة مما يجعل التجميع غير فعال.
|
||||
لا توجد اعتبارات لأنماط الوصول الشائعة في استعلامات RDF.
|
||||
تخلق المجموعات الكبيرة أقسامًا "ساخنة" على عقد فردية.
|
||||
لا تعمل أعمدة التجميع (s، p، o) على تحسين أنماط اجتياز الرسم البياني النموذجية.
|
||||
|
||||
**التأثير:**
|
||||
لا تستفيد الاستعلامات من قرب البيانات.
|
||||
استخدام ضعيف لذاكرة التخزين المؤقت.
|
||||
توزيع غير متساوٍ للحمل عبر عقد المجموعة.
|
||||
اختناقات في قابلية التوسع مع نمو المجموعات.
|
||||
|
||||
## الحل المقترح: استراتيجية إلغاء التسوية باستخدام 4 جداول
|
||||
|
||||
### نظرة عامة
|
||||
|
||||
استبدل الجدول `triples` الواحد بأربعة جداول مصممة خصيصًا، كل منها مُحسَّن لأنماط استعلام محددة. هذا يلغي الحاجة إلى الفهارس الثانوية و ALLOW FILTERING مع توفير أداء مثالي لجميع أنواع الاستعلامات. يتيح الجدول الرابع حذف المجموعات بكفاءة على الرغم من مفاتيح الأقسام المركبة.
|
||||
|
||||
### تصميم المخطط الجديد
|
||||
|
||||
**الجدول 1: الاستعلامات المرتكزة على الموضوع (triples_s)**
|
||||
```sql
|
||||
CREATE TABLE triples_s (
|
||||
collection text,
|
||||
s text,
|
||||
p text,
|
||||
o text,
|
||||
PRIMARY KEY ((collection, s), p, o)
|
||||
);
|
||||
```
|
||||
**تحسينات:** get_s، get_sp، get_os
|
||||
**مفتاح التقسيم:** (collection, s) - توزيع أفضل من مجرد استخدام collection وحده.
|
||||
**التجميع:** (p, o) - يتيح عمليات بحث فعالة عن المحددات/الكائنات لكيان معين.
|
||||
|
||||
**الجدول 2: استعلامات المحدد-الكائن (triples_p)**
|
||||
```sql
|
||||
CREATE TABLE triples_p (
|
||||
collection text,
|
||||
p text,
|
||||
o text,
|
||||
s text,
|
||||
PRIMARY KEY ((collection, p), o, s)
|
||||
);
|
||||
```
|
||||
**تحسين:** get_p, get_po (يزيل الحاجة إلى ALLOW FILTERING!)
|
||||
**مفتاح التقسيم:** (collection, p) - وصول مباشر عبر الشرط.
|
||||
**التجميع:** (o, s) - تصفح فعال للكائنات والموضوعات.
|
||||
|
||||
**الجدول 3: الاستعلامات المرتكزة على الكائنات (triples_o)**
|
||||
```sql
|
||||
CREATE TABLE triples_o (
|
||||
collection text,
|
||||
o text,
|
||||
s text,
|
||||
p text,
|
||||
PRIMARY KEY ((collection, o), s, p)
|
||||
);
|
||||
```
|
||||
**التحسينات:** get_o
|
||||
**مفتاح التقسيم:** (collection, o) - وصول مباشر عن طريق الكائن
|
||||
**التجميع:** (s, p) - تصفح فعال للموضوع والمسند
|
||||
|
||||
**الجدول 4: إدارة المجموعات والاستعلامات SPO (triples_collection)**
|
||||
```sql
|
||||
CREATE TABLE triples_collection (
|
||||
collection text,
|
||||
s text,
|
||||
p text,
|
||||
o text,
|
||||
PRIMARY KEY (collection, s, p, o)
|
||||
);
|
||||
```
|
||||
**التحسينات:** get_spo، delete_collection
|
||||
**مفتاح التقسيم:** مجموعة فقط - يتيح عمليات فعالة على مستوى المجموعة.
|
||||
**التجميع:** (s, p, o) - ترتيب ثلاثي قياسي.
|
||||
**الغرض:** استخدام مزدوج للبحث الدقيق عن SPO وكمؤشر للحذف.
|
||||
|
||||
### تعيين الاستعلام
|
||||
|
||||
| الاستعلام الأصلي | الجدول الهدف | تحسين الأداء |
|
||||
|----------------|-------------|------------------------|
|
||||
| get_all(collection) | triples_s | السماح بالتصفية (مقبول للمسح) |
|
||||
| get_s(collection, s) | triples_s | وصول مباشر إلى التقسيم |
|
||||
| get_p(collection, p) | triples_p | وصول مباشر إلى التقسيم |
|
||||
| get_o(collection, o) | triples_o | وصول مباشر إلى التقسيم |
|
||||
| get_sp(collection, s, p) | triples_s | التقسيم + التجميع |
|
||||
| get_po(collection, p, o) | triples_p | **لا مزيد من السماح بالتصفية!** |
|
||||
| get_os(collection, o, s) | triples_o | التقسيم + التجميع |
|
||||
| get_spo(collection, s, p, o) | triples_collection | بحث مباشر عن المفتاح |
|
||||
| delete_collection(collection) | triples_collection | قراءة الفهرس، حذف مجمع |
|
||||
|
||||
### استراتيجية حذف المجموعة
|
||||
|
||||
مع مفاتيح التقسيم المركبة، لا يمكننا ببساطة تنفيذ `DELETE FROM table WHERE collection = ?`. بدلاً من ذلك:
|
||||
|
||||
1. **مرحلة القراءة:** استعلام `triples_collection` لسرد جميع الثلاثيات:
|
||||
```sql
|
||||
SELECT s, p, o FROM triples_collection WHERE collection = ?
|
||||
```
|
||||
هذا فعال لأنه `collection` هو مفتاح التقسيم لهذه الجدولة.
|
||||
|
||||
2. **مرحلة الحذف:** لكل ثلاثية (s, p, o)، قم بالحذف من جميع الجداول الأربعة باستخدام مفاتيح التقسيم الكاملة:
|
||||
```sql
|
||||
DELETE FROM triples_s WHERE collection = ? AND s = ? AND p = ? AND o = ?
|
||||
DELETE FROM triples_p WHERE collection = ? AND p = ? AND o = ? AND s = ?
|
||||
DELETE FROM triples_o WHERE collection = ? AND o = ? AND s = ? AND p = ?
|
||||
DELETE FROM triples_collection WHERE collection = ? AND s = ? AND p = ? AND o = ?
|
||||
```
|
||||
يتم تجميع البيانات في مجموعات مكونة من 100 عنصر لتحقيق الكفاءة.
|
||||
|
||||
**تحليل المقايضات:**
|
||||
✅ يحافظ على الأداء الأمثل للاستعلامات مع الأقسام الموزعة.
|
||||
✅ لا توجد أقسام "ساخنة" للمجموعات الكبيرة.
|
||||
❌ منطق حذف أكثر تعقيدًا (قراءة ثم حذف).
|
||||
❌ وقت الحذف يتناسب مع حجم المجموعة.
|
||||
|
||||
### المزايا
|
||||
|
||||
1. **يزيل الحاجة إلى ALLOW FILTERING** - كل استعلام لديه مسار وصول أمثل (باستثناء فحص get_all).
|
||||
2. **لا توجد فهارس ثانوية** - كل جدول هو الفهرس لنمط الاستعلام الخاص به.
|
||||
3. **توزيع أفضل للبيانات** - مفاتيح التقسيم المركبة توزع الحمل بشكل فعال.
|
||||
4. **أداء متوقع** - وقت الاستعلام يتناسب مع حجم النتيجة، وليس إجمالي البيانات.
|
||||
5. **يستفيد من نقاط قوة Cassandra** - مصمم ليتناسب مع بنية Cassandra.
|
||||
6. **يمكن حذف المجموعات** - تعمل triples_collection كفهرس للحذف.
|
||||
|
||||
## خطة التنفيذ
|
||||
|
||||
### الملفات التي تتطلب تغييرات
|
||||
|
||||
#### الملف الأساسي للتنفيذ
|
||||
|
||||
**`trustgraph-flow/trustgraph/direct/cassandra_kg.py`** - مطلوب إعادة كتابة كاملة.
|
||||
|
||||
**الطرق الحالية التي تتطلب إعادة هيكلة:**
|
||||
```python
|
||||
# Schema initialization
|
||||
def init(self) -> None # Replace single table with three tables
|
||||
|
||||
# Insert operations
|
||||
def insert(self, collection, s, p, o) -> None # Write to all three tables
|
||||
|
||||
# Query operations (API unchanged, implementation optimized)
|
||||
def get_all(self, collection, limit=50) # Use triples_by_subject
|
||||
def get_s(self, collection, s, limit=10) # Use triples_by_subject
|
||||
def get_p(self, collection, p, limit=10) # Use triples_by_po
|
||||
def get_o(self, collection, o, limit=10) # Use triples_by_object
|
||||
def get_sp(self, collection, s, p, limit=10) # Use triples_by_subject
|
||||
def get_po(self, collection, p, o, limit=10) # Use triples_by_po (NO ALLOW FILTERING!)
|
||||
def get_os(self, collection, o, s, limit=10) # Use triples_by_subject
|
||||
def get_spo(self, collection, s, p, o, limit=10) # Use triples_by_subject
|
||||
|
||||
# Collection management
|
||||
def delete_collection(self, collection) -> None # Delete from all three tables
|
||||
```
|
||||
|
||||
#### ملفات التكامل (لا يلزم إجراء أي تغييرات منطقية)
|
||||
|
||||
**`trustgraph-flow/trustgraph/storage/triples/cassandra/write.py`**
|
||||
لا يلزم إجراء أي تغييرات - تستخدم واجهة برمجة تطبيقات KnowledgeGraph الحالية.
|
||||
تستفيد تلقائيًا من تحسينات الأداء.
|
||||
|
||||
**`trustgraph-flow/trustgraph/query/triples/cassandra/service.py`**
|
||||
لا يلزم إجراء أي تغييرات - تستخدم واجهة برمجة تطبيقات KnowledgeGraph الحالية.
|
||||
تستفيد تلقائيًا من تحسينات الأداء.
|
||||
|
||||
### ملفات الاختبار التي تتطلب تحديثات
|
||||
|
||||
#### اختبارات الوحدة
|
||||
**`tests/unit/test_storage/test_triples_cassandra_storage.py`**
|
||||
تحديث توقعات الاختبار للتغييرات في المخطط.
|
||||
إضافة اختبارات لضمان الاتساق بين الجداول المتعددة.
|
||||
التحقق من عدم وجود ALLOW FILTERING في خطط الاستعلام.
|
||||
|
||||
**`tests/unit/test_query/test_triples_cassandra_query.py`**
|
||||
تحديث التأكيدات المتعلقة بالأداء.
|
||||
اختبار جميع أنماط الاستعلام الثمانية مقابل الجداول الجديدة.
|
||||
التحقق من توجيه الاستعلام إلى الجداول الصحيحة.
|
||||
|
||||
#### اختبارات التكامل
|
||||
**`tests/integration/test_cassandra_integration.py`**
|
||||
اختبار شامل مع المخطط الجديد.
|
||||
مقارنات قياس الأداء.
|
||||
التحقق من اتساق البيانات عبر الجداول.
|
||||
|
||||
**`tests/unit/test_storage/test_cassandra_config_integration.py`**
|
||||
تحديث اختبارات التحقق من صحة المخطط.
|
||||
اختبار سيناريوهات الترحيل.
|
||||
|
||||
### استراتيجية التنفيذ
|
||||
|
||||
#### المرحلة الأولى: المخطط والطرق الأساسية
|
||||
1. **إعادة كتابة الطريقة `init()`** - إنشاء أربعة جداول بدلاً من جدول واحد.
|
||||
2. **إعادة كتابة الطريقة `insert()`** - عمليات كتابة مجمعة إلى جميع الجداول الأربعة.
|
||||
3. **تنفيذ عبارات مُعدة** - للحصول على أداء مثالي.
|
||||
4. **إضافة منطق توجيه الجدول** - لتوجيه الاستعلامات إلى الجداول المثلى.
|
||||
5. **تنفيذ حذف المجموعة** - القراءة من triples_collection، وحذف مجمع من جميع الجداول.
|
||||
|
||||
#### المرحلة الثانية: تحسين طريقة الاستعلام
|
||||
1. **إعادة كتابة كل طريقة get_*** لاستخدام الجدول الأمثل.
|
||||
2. **إزالة جميع استخدامات ALLOW FILTERING**.
|
||||
3. **تنفيذ استخدام فعال لمفتاح التجميع**.
|
||||
4. **إضافة تسجيل أداء الاستعلام**.
|
||||
|
||||
#### المرحلة الثالثة: إدارة المجموعة
|
||||
1. **تحديث `delete_collection()`** - إزالتها من جميع الجداول الثلاثة.
|
||||
2. **إضافة التحقق من الاتساق** - لضمان بقاء جميع الجداول متزامنة.
|
||||
3. **تنفيذ عمليات مجمعة** - لعمليات متعددة الجداول ذرية.
|
||||
|
||||
### تفاصيل التنفيذ الرئيسية
|
||||
|
||||
#### استراتيجية الكتابة المجمعة
|
||||
```python
|
||||
def insert(self, collection, s, p, o):
|
||||
batch = BatchStatement()
|
||||
|
||||
# Insert into all four tables
|
||||
batch.add(self.insert_subject_stmt, (collection, s, p, o))
|
||||
batch.add(self.insert_po_stmt, (collection, p, o, s))
|
||||
batch.add(self.insert_object_stmt, (collection, o, s, p))
|
||||
batch.add(self.insert_collection_stmt, (collection, s, p, o))
|
||||
|
||||
self.session.execute(batch)
|
||||
```
|
||||
|
||||
#### منطق توجيه الاستعلامات
|
||||
```python
|
||||
def get_po(self, collection, p, o, limit=10):
|
||||
# Route to triples_p table - NO ALLOW FILTERING!
|
||||
return self.session.execute(
|
||||
self.get_po_stmt,
|
||||
(collection, p, o, limit)
|
||||
)
|
||||
|
||||
def get_spo(self, collection, s, p, o, limit=10):
|
||||
# Route to triples_collection table for exact SPO lookup
|
||||
return self.session.execute(
|
||||
self.get_spo_stmt,
|
||||
(collection, s, p, o, limit)
|
||||
)
|
||||
```
|
||||
|
||||
#### منطق حذف المجموعة
|
||||
```python
|
||||
def delete_collection(self, collection):
|
||||
# Step 1: Read all triples from collection table
|
||||
rows = self.session.execute(
|
||||
f"SELECT s, p, o FROM {self.collection_table} WHERE collection = %s",
|
||||
(collection,)
|
||||
)
|
||||
|
||||
# Step 2: Batch delete from all 4 tables
|
||||
batch = BatchStatement()
|
||||
count = 0
|
||||
|
||||
for row in rows:
|
||||
s, p, o = row.s, row.p, row.o
|
||||
|
||||
# Delete using full partition keys for each table
|
||||
batch.add(SimpleStatement(
|
||||
f"DELETE FROM {self.subject_table} WHERE collection = ? AND s = ? AND p = ? AND o = ?"
|
||||
), (collection, s, p, o))
|
||||
|
||||
batch.add(SimpleStatement(
|
||||
f"DELETE FROM {self.po_table} WHERE collection = ? AND p = ? AND o = ? AND s = ?"
|
||||
), (collection, p, o, s))
|
||||
|
||||
batch.add(SimpleStatement(
|
||||
f"DELETE FROM {self.object_table} WHERE collection = ? AND o = ? AND s = ? AND p = ?"
|
||||
), (collection, o, s, p))
|
||||
|
||||
batch.add(SimpleStatement(
|
||||
f"DELETE FROM {self.collection_table} WHERE collection = ? AND s = ? AND p = ? AND o = ?"
|
||||
), (collection, s, p, o))
|
||||
|
||||
count += 1
|
||||
|
||||
# Execute every 100 triples to avoid oversized batches
|
||||
if count % 100 == 0:
|
||||
self.session.execute(batch)
|
||||
batch = BatchStatement()
|
||||
|
||||
# Execute remaining deletions
|
||||
if count % 100 != 0:
|
||||
self.session.execute(batch)
|
||||
|
||||
logger.info(f"Deleted {count} triples from collection {collection}")
|
||||
```
|
||||
|
||||
### تحسين عبارات SQL المُعدة (Prepared Statements)
|
||||
```python
|
||||
def prepare_statements(self):
|
||||
# Cache prepared statements for better performance
|
||||
self.insert_subject_stmt = self.session.prepare(
|
||||
f"INSERT INTO {self.subject_table} (collection, s, p, o) VALUES (?, ?, ?, ?)"
|
||||
)
|
||||
self.insert_po_stmt = self.session.prepare(
|
||||
f"INSERT INTO {self.po_table} (collection, p, o, s) VALUES (?, ?, ?, ?)"
|
||||
)
|
||||
self.insert_object_stmt = self.session.prepare(
|
||||
f"INSERT INTO {self.object_table} (collection, o, s, p) VALUES (?, ?, ?, ?)"
|
||||
)
|
||||
self.insert_collection_stmt = self.session.prepare(
|
||||
f"INSERT INTO {self.collection_table} (collection, s, p, o) VALUES (?, ?, ?, ?)"
|
||||
)
|
||||
# ... query statements
|
||||
```
|
||||
|
||||
## استراتيجية الترحيل
|
||||
|
||||
### نهج ترحيل البيانات
|
||||
|
||||
#### الخيار الأول: النشر الأزرق-الأخضر (موصى به)
|
||||
1. **نشر المخطط الجديد جنبًا إلى جنب مع المخطط الحالي** - استخدم أسماء جداول مختلفة مؤقتًا.
|
||||
2. **فترة الكتابة المزدوجة** - الكتابة إلى كل من المخططين القديم والجديد خلال فترة الانتقال.
|
||||
3. **ترحيل البيانات في الخلفية** - نسخ البيانات الموجودة إلى الجداول الجديدة.
|
||||
4. **توجيه عمليات القراءة** - توجيه الاستعلامات إلى الجداول الجديدة بمجرد ترحيل البيانات.
|
||||
5. **إزالة الجداول القديمة** - بعد فترة التحقق.
|
||||
|
||||
#### الخيار الثاني: الترحيل في المكان
|
||||
1. **إضافة المخطط** - إنشاء جداول جديدة في مساحة المفاتيح الحالية.
|
||||
2. **برنامج ترحيل البيانات** - نسخ دفعي من الجدول القديم إلى الجداول الجديدة.
|
||||
3. **تحديث التطبيق** - نشر التعليمات البرمجية الجديدة بعد اكتمال الترحيل.
|
||||
4. **تنظيف الجدول القديم** - إزالة الجدول القديم والفهارس.
|
||||
|
||||
### التوافق مع الإصدارات السابقة
|
||||
|
||||
#### استراتيجية النشر
|
||||
```python
|
||||
# Environment variable to control table usage during migration
|
||||
USE_LEGACY_TABLES = os.getenv('CASSANDRA_USE_LEGACY', 'false').lower() == 'true'
|
||||
|
||||
class KnowledgeGraph:
|
||||
def __init__(self, ...):
|
||||
if USE_LEGACY_TABLES:
|
||||
self.init_legacy_schema()
|
||||
else:
|
||||
self.init_optimized_schema()
|
||||
```
|
||||
|
||||
#### نص ترحيل
|
||||
```python
|
||||
def migrate_data():
|
||||
# Read from old table
|
||||
old_triples = session.execute("SELECT collection, s, p, o FROM triples")
|
||||
|
||||
# Batch write to new tables
|
||||
for batch in batched(old_triples, 100):
|
||||
batch_stmt = BatchStatement()
|
||||
for row in batch:
|
||||
# Add to all three new tables
|
||||
batch_stmt.add(insert_subject_stmt, row)
|
||||
batch_stmt.add(insert_po_stmt, (row.collection, row.p, row.o, row.s))
|
||||
batch_stmt.add(insert_object_stmt, (row.collection, row.o, row.s, row.p))
|
||||
session.execute(batch_stmt)
|
||||
```
|
||||
|
||||
### استراتيجية التحقق من الصحة
|
||||
|
||||
#### فحوصات تناسق البيانات
|
||||
```python
|
||||
def validate_migration():
|
||||
# Count total records in old vs new tables
|
||||
old_count = session.execute("SELECT COUNT(*) FROM triples WHERE collection = ?", (collection,))
|
||||
new_count = session.execute("SELECT COUNT(*) FROM triples_by_subject WHERE collection = ?", (collection,))
|
||||
|
||||
assert old_count == new_count, f"Record count mismatch: {old_count} vs {new_count}"
|
||||
|
||||
# Spot check random samples
|
||||
sample_queries = generate_test_queries()
|
||||
for query in sample_queries:
|
||||
old_result = execute_legacy_query(query)
|
||||
new_result = execute_optimized_query(query)
|
||||
assert old_result == new_result, f"Query results differ for {query}"
|
||||
```
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبار الأداء
|
||||
|
||||
#### سيناريوهات قياس الأداء
|
||||
1. **مقارنة أداء الاستعلامات**
|
||||
مقاييس الأداء قبل وبعد لجميع أنواع الاستعلامات الثمانية.
|
||||
التركيز على تحسين أداء `get_po` (إزالة `ALLOW FILTERING`).
|
||||
قياس زمن استجابة الاستعلامات تحت أحجام بيانات مختلفة.
|
||||
|
||||
2. **اختبار التحميل**
|
||||
تنفيذ استعلامات متزامنة.
|
||||
معدل نقل البيانات مع العمليات الدفعية.
|
||||
استخدام الذاكرة ووحدة المعالجة المركزية.
|
||||
|
||||
3. **اختبار قابلية التوسع**
|
||||
الأداء مع زيادة أحجام المجموعات.
|
||||
توزيع الاستعلامات عبر مجموعات متعددة.
|
||||
استخدام عقد المجموعة.
|
||||
|
||||
#### مجموعات بيانات الاختبار
|
||||
**صغيرة:** 10 آلاف ثلاثية لكل مجموعة.
|
||||
**متوسطة:** 100 ألف ثلاثية لكل مجموعة.
|
||||
**كبيرة:** أكثر من مليون ثلاثية لكل مجموعة.
|
||||
**مجموعات متعددة:** اختبار توزيع التقسيم.
|
||||
|
||||
### اختبار وظيفي
|
||||
|
||||
#### تحديثات اختبار الوحدات
|
||||
```python
|
||||
# Example test structure for new implementation
|
||||
class TestCassandraKGPerformance:
|
||||
def test_get_po_no_allow_filtering(self):
|
||||
# Verify get_po queries don't use ALLOW FILTERING
|
||||
with patch('cassandra.cluster.Session.execute') as mock_execute:
|
||||
kg.get_po('test_collection', 'predicate', 'object')
|
||||
executed_query = mock_execute.call_args[0][0]
|
||||
assert 'ALLOW FILTERING' not in executed_query
|
||||
|
||||
def test_multi_table_consistency(self):
|
||||
# Verify all tables stay in sync
|
||||
kg.insert('test', 's1', 'p1', 'o1')
|
||||
|
||||
# Check all tables contain the triple
|
||||
assert_triple_exists('triples_by_subject', 'test', 's1', 'p1', 'o1')
|
||||
assert_triple_exists('triples_by_po', 'test', 'p1', 'o1', 's1')
|
||||
assert_triple_exists('triples_by_object', 'test', 'o1', 's1', 'p1')
|
||||
```
|
||||
|
||||
#### تحديثات اختبار التكامل
|
||||
```python
|
||||
class TestCassandraIntegration:
|
||||
def test_query_performance_regression(self):
|
||||
# Ensure new implementation is faster than old
|
||||
old_time = benchmark_legacy_get_po()
|
||||
new_time = benchmark_optimized_get_po()
|
||||
assert new_time < old_time * 0.5 # At least 50% improvement
|
||||
|
||||
def test_end_to_end_workflow(self):
|
||||
# Test complete write -> query -> delete cycle
|
||||
# Verify no performance degradation in integration
|
||||
```
|
||||
|
||||
### خطة التراجع
|
||||
|
||||
#### استراتيجية تراجع سريعة
|
||||
1. **تبديل متغيرات البيئة** - العودة إلى الجداول القديمة على الفور.
|
||||
2. **الاحتفاظ بالجداول القديمة** - لا تقم بإزالتها حتى يتم إثبات الأداء.
|
||||
3. **تنبيهات المراقبة** - تشغيل تلقائي للتراجع بناءً على معدلات الخطأ/زمن الاستجابة.
|
||||
|
||||
#### التحقق من التراجع
|
||||
```python
|
||||
def rollback_to_legacy():
|
||||
# Set environment variable
|
||||
os.environ['CASSANDRA_USE_LEGACY'] = 'true'
|
||||
|
||||
# Restart services to pick up change
|
||||
restart_cassandra_services()
|
||||
|
||||
# Validate functionality
|
||||
run_smoke_tests()
|
||||
```
|
||||
|
||||
## المخاطر والاعتبارات
|
||||
|
||||
### مخاطر الأداء
|
||||
**زيادة زمن الاستجابة للكتابة** - 4 عمليات كتابة لكل عملية إدخال (أكثر بنسبة 33٪ من مقاربة الجدول الثلاثي)
|
||||
**العبء التخزيني** - 4 أضعاف متطلبات التخزين (أكثر بنسبة 33٪ من مقاربة الجدول الثلاثي)
|
||||
**فشل عمليات الكتابة المجمعة** - الحاجة إلى معالجة الأخطاء بشكل صحيح
|
||||
**تعقيد الحذف** - يتطلب حذف المجموعة حلقة قراءة ثم حذف
|
||||
|
||||
### المخاطر التشغيلية
|
||||
**تعقيد الترحيل** - ترحيل البيانات لمجموعات البيانات الكبيرة
|
||||
**تحديات الاتساق** - ضمان بقاء جميع الجداول متزامنة
|
||||
**فجوات المراقبة** - الحاجة إلى مقاييس جديدة لعمليات الجداول المتعددة
|
||||
|
||||
### استراتيجيات التخفيف
|
||||
1. **النشر التدريجي** - ابدأ بمجموعات صغيرة
|
||||
2. **مراقبة شاملة** - تتبع جميع مقاييس الأداء
|
||||
3. **التحقق الآلي** - فحص الاتساق المستمر
|
||||
4. **إمكانية التراجع السريع** - اختيار الجدول بناءً على البيئة
|
||||
|
||||
## معايير النجاح
|
||||
|
||||
### تحسينات الأداء
|
||||
[ ] **إزالة ALLOW FILTERING** - تعمل الاستعلامات get_po و get_os بدون تصفية
|
||||
[ ] **تقليل زمن استجابة الاستعلام** - تحسن بنسبة 50٪ أو أكثر في أوقات استجابة الاستعلام
|
||||
[ ] **توزيع أفضل للعبء** - لا توجد أقسام "ساخنة"، وتوزيع متساوٍ عبر عقد المجموعة
|
||||
[ ] **أداء قابل للتوسع** - وقت الاستعلام يتناسب مع حجم النتيجة، وليس إجمالي البيانات
|
||||
|
||||
### المتطلبات الوظيفية
|
||||
[ ] **توافق واجهة برمجة التطبيقات (API)** - يستمر جميع التعليمات البرمجية الحالية في العمل دون تغيير
|
||||
[ ] **اتساق البيانات** - تظل جميع الجداول الثلاثة متزامنة
|
||||
[ ] **عدم فقدان البيانات** - يحافظ الترحيل على جميع الثلاثيات الموجودة
|
||||
[ ] **التوافق مع الإصدارات السابقة** - القدرة على العودة إلى المخطط القديم
|
||||
|
||||
### المتطلبات التشغيلية
|
||||
[ ] **ترحيل آمن** - نشر أخضر/أزرق مع إمكانية التراجع
|
||||
[ ] **تغطية المراقبة** - مقاييس شاملة لعمليات الجداول المتعددة
|
||||
[ ] **تغطية الاختبار** - تم اختبار جميع أنماط الاستعلام باستخدام معايير الأداء
|
||||
[ ] **التوثيق** - تحديث إجراءات النشر والتشغيل
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
### المرحلة 1: التنفيذ
|
||||
[ ] إعادة كتابة `cassandra_kg.py` باستخدام مخطط الجداول المتعددة
|
||||
[ ] تنفيذ عمليات الكتابة المجمعة
|
||||
[ ] إضافة تحسينات باستخدام عبارات مُعدة
|
||||
[ ] تحديث اختبارات الوحدة
|
||||
|
||||
### المرحلة 2: اختبار التكامل
|
||||
[ ] تحديث اختبارات التكامل
|
||||
[ ] قياس الأداء
|
||||
[ ] اختبار التحميل باستخدام أحجام بيانات واقعية
|
||||
[ ] نصوص التحقق من اتساق البيانات
|
||||
|
||||
### المرحلة 3: تخطيط الترحيل
|
||||
[ ] نصوص النشر الأخضر/الأزرق
|
||||
[ ] أدوات ترحيل البيانات
|
||||
[ ] تحديثات لوحة معلومات المراقبة
|
||||
[ ] إجراءات التراجع
|
||||
|
||||
### المرحلة 4: النشر في بيئة الإنتاج
|
||||
[ ] النشر التدريجي في بيئة الإنتاج
|
||||
[ ] مراقبة الأداء والتحقق من صحته
|
||||
[ ] تنظيف الجداول القديمة
|
||||
[ ] تحديثات التوثيق
|
||||
|
||||
## الخلاصة
|
||||
|
||||
تعالج هذه الاستراتيجية لإلغاء التسوية متعددة الجداول بشكل مباشر عنقودين رئيسيين للأداء:
|
||||
|
||||
1. **تقضي على ALLOW FILTERING المكلفة** من خلال توفير هياكل جداول مثالية لكل نمط استعلام
|
||||
2. **تحسين فعالية التجميع** من خلال مفاتيح التقسيم المركبة التي توزع الحمل بشكل صحيح
|
||||
|
||||
تستفيد هذه الطريقة من نقاط قوة Cassandra مع الحفاظ على توافق كامل مع واجهة برمجة التطبيقات (API)، مما يضمن أن التعليمات البرمجية الحالية تستفيد تلقائيًا من تحسينات الأداء.
|
||||
410
docs/tech-specs/ar/collection-management.ar.md
Normal file
410
docs/tech-specs/ar/collection-management.ar.md
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات فنية لإدارة المجموعات"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات فنية لإدارة المجموعات
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات إمكانات إدارة المجموعات لـ TrustGraph، والتي تتطلب إنشاء مجموعات بشكل صريح وتوفر تحكمًا مباشرًا في دورة حياة المجموعة. يجب إنشاء المجموعات بشكل صريح قبل استخدامها، مما يضمن المزامنة الصحيحة بين بيانات وصفية أمين المكتبة وجميع الواجهات الخلفية للتخزين. تدعم هذه الميزة أربع حالات استخدام رئيسية:
|
||||
|
||||
1. **إنشاء المجموعة**: إنشاء مجموعات بشكل صريح قبل تخزين البيانات
|
||||
2. **قائمة المجموعات**: عرض جميع المجموعات الموجودة في النظام
|
||||
3. **إدارة بيانات وصفية المجموعة**: تحديث أسماء المجموعات والأوصاف والعلامات
|
||||
4. **حذف المجموعة**: إزالة المجموعات والبيانات المرتبطة بها عبر جميع أنواع التخزين
|
||||
|
||||
## الأهداف
|
||||
|
||||
**إنشاء المجموعة بشكل صريح**: تتطلب أن يتم إنشاء المجموعات قبل تخزين البيانات
|
||||
**مزامنة التخزين**: ضمان وجود المجموعات في جميع الواجهات الخلفية للتخزين (المتجهات، والكائنات، والثلاثيات)
|
||||
**إمكانية رؤية المجموعة**: تمكين المستخدمين من سرد وفحص جميع المجموعات في بيئتهم
|
||||
**تنظيف المجموعة**: السماح بحذف المجموعات التي لم تعد مطلوبة
|
||||
**تنظيم المجموعة**: دعم العلامات والملصقات لتتبع واكتشاف المجموعة بشكل أفضل
|
||||
**إدارة البيانات الوصفية**: ربط بيانات وصفية ذات مغزى بالمجموعات من أجل الوضوح التشغيلي
|
||||
**اكتشاف المجموعة**: تسهيل العثور على مجموعات معينة من خلال التصفية والبحث
|
||||
**الشفافية التشغيلية**: توفير رؤية واضحة لدورة حياة المجموعة واستخدامها
|
||||
**إدارة الموارد**: تمكين تنظيف المجموعات غير المستخدمة لتحسين استخدام الموارد
|
||||
**سلامة البيانات**: منع وجود مجموعات معزولة في التخزين بدون تتبع البيانات الوصفية
|
||||
|
||||
## الخلفية
|
||||
|
||||
في السابق، كانت المجموعات في TrustGraph يتم إنشاؤها ضمنيًا أثناء عمليات تحميل البيانات، مما أدى إلى مشاكل في المزامنة حيث يمكن أن توجد المجموعات في الواجهات الخلفية للتخزين بدون بيانات وصفية مقابلة في أمين المكتبة. وقد أدى ذلك إلى تحديات إدارية وإمكانية وجود بيانات معزولة.
|
||||
|
||||
يعالج نموذج إنشاء المجموعة الصريح هذه المشكلات عن طريق:
|
||||
طلب إنشاء المجموعات قبل استخدامها عبر `tg-set-collection`
|
||||
بث إنشاء المجموعة إلى جميع الواجهات الخلفية للتخزين
|
||||
الحفاظ على حالة متزامنة بين بيانات وصفية أمين المكتبة والتخزين
|
||||
منع الكتابة إلى المجموعات غير الموجودة
|
||||
توفير إدارة واضحة لدورة حياة المجموعة
|
||||
|
||||
تحدد هذه المواصفات نموذج إدارة المجموعة الصريح. من خلال طلب إنشاء المجموعة بشكل صريح، تضمن TrustGraph:
|
||||
تتبع المجموعات في بيانات وصفية أمين المكتبة من لحظة إنشائها
|
||||
أن تكون جميع الواجهات الخلفية للتخزين على علم بالمجموعات قبل استقبال البيانات
|
||||
عدم وجود مجموعات معزولة في التخزين
|
||||
رؤية وتحكم واضحين في دورة حياة المجموعة
|
||||
معالجة أخطاء متسقة عند الإشارة العمليات إلى مجموعات غير موجودة
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية التحتية
|
||||
|
||||
سيتم تنفيذ نظام إدارة المجموعة داخل البنية التحتية الحالية لـ TrustGraph:
|
||||
|
||||
1. **تكامل خدمة أمين المكتبة**
|
||||
سيتم إضافة عمليات إدارة المجموعة إلى خدمة أمين المكتبة الحالية
|
||||
لا توجد خدمة جديدة مطلوبة - تستفيد من أنماط المصادقة والوصول الحالية
|
||||
تتعامل مع قائمة المجموعات وحذفها وإدارة بياناتها الوصفية
|
||||
|
||||
الوحدة: trustgraph-librarian
|
||||
|
||||
2. **جدول بيانات وصفية المجموعة في Cassandra**
|
||||
جدول جديد في مساحة مفاتيح أمين المكتبة الحالية
|
||||
يخزن بيانات وصفية المجموعة مع وصول المستخدم
|
||||
المفتاح الأساسي: (user_id, collection_id) لضمان تعدد المستأجرين المناسب
|
||||
|
||||
الوحدة: trustgraph-librarian
|
||||
|
||||
3. **واجهة سطر الأوامر لإدارة المجموعة**
|
||||
واجهة سطر أوامر لعمليات المجموعة
|
||||
يوفر أوامر للقائمة والحذف والملصقات والعلامات
|
||||
يتكامل مع إطار عمل سطر الأوامر الحالي
|
||||
|
||||
الوحدة: trustgraph-cli
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### جدول بيانات وصفية المجموعة في Cassandra
|
||||
|
||||
سيتم تخزين بيانات وصفية المجموعة في جدول Cassandra منظم في مساحة مفاتيح أمين المكتبة:
|
||||
|
||||
```sql
|
||||
CREATE TABLE collections (
|
||||
user text,
|
||||
collection text,
|
||||
name text,
|
||||
description text,
|
||||
tags set<text>,
|
||||
created_at timestamp,
|
||||
updated_at timestamp,
|
||||
PRIMARY KEY (user, collection)
|
||||
);
|
||||
```
|
||||
|
||||
هيكل الجدول:
|
||||
**user**: + **collection**: مفتاح أساسي مركب يضمن عزل المستخدم
|
||||
**name**: اسم المجموعة الذي يمكن قراءته بواسطة الإنسان
|
||||
**description**: وصف تفصيلي لغرض المجموعة
|
||||
**tags**: مجموعة من العلامات لتصنيف وتصفية
|
||||
**created_at**: طابع زمني لإنشاء المجموعة
|
||||
**updated_at**: طابع زمني لآخر تعديل
|
||||
|
||||
هذا النهج يسمح بـ:
|
||||
إدارة مجموعات متعددة المستأجرين مع عزل المستخدم
|
||||
استعلام فعال حسب المستخدم والمجموعة
|
||||
نظام تصنيف مرن للتنظيم
|
||||
تتبع دورة حياة المجموعة للحصول على رؤى تشغيلية
|
||||
|
||||
#### دورة حياة المجموعة
|
||||
|
||||
يتم إنشاء المجموعات بشكل صريح في المكتبة قبل أن تتمكن عمليات البيانات من المضي قدمًا:
|
||||
|
||||
1. **إنشاء المجموعة** (مساران):
|
||||
|
||||
**المسار أ: الإنشاء الذي يبدأه المستخدم** عبر `tg-set-collection`:
|
||||
يقوم المستخدم بتوفير معرف المجموعة والاسم والوصف والعلامات
|
||||
تقوم المكتبة بإنشاء سجل بيانات وصفية في جدول `collections`
|
||||
تقوم المكتبة ببث "إنشاء مجموعة" إلى جميع الواجهات الخلفية للتخزين
|
||||
تقوم جميع معالجات التخزين بإنشاء المجموعة وتأكيد النجاح
|
||||
أصبحت المجموعة الآن جاهزة لعمليات البيانات
|
||||
|
||||
**المسار ب: الإنشاء التلقائي عند إرسال المستند**:
|
||||
يقوم المستخدم بإرسال مستند يحدد معرف مجموعة
|
||||
تتحقق المكتبة مما إذا كانت المجموعة موجودة في جدول البيانات الوصفية
|
||||
إذا لم تكن موجودة: تقوم المكتبة بإنشاء بيانات وصفية مع القيم الافتراضية (الاسم = معرف المجموعة، وصف/علامات فارغة)
|
||||
تقوم المكتبة ببث "إنشاء مجموعة" إلى جميع الواجهات الخلفية للتخزين
|
||||
تقوم جميع معالجات التخزين بإنشاء المجموعة وتأكيد النجاح
|
||||
تستمر معالجة المستند مع إنشاء المجموعة الآن
|
||||
|
||||
يضمن كلا المسارين وجود المجموعة في بيانات المكتبة الوصفية وجميع الواجهات الخلفية للتخزين قبل السماح بعمليات البيانات.
|
||||
|
||||
2. **التحقق من التخزين**: تتحقق عمليات الكتابة من وجود المجموعة:
|
||||
تتحقق معالجات التخزين من حالة المجموعة قبل قبول عمليات الكتابة
|
||||
تؤدي عمليات الكتابة إلى مجموعات غير موجودة إلى إرجاع خطأ
|
||||
يمنع هذا عمليات الكتابة المباشرة التي تتجاوز منطق إنشاء المجموعة الخاص بالمكتبة
|
||||
|
||||
3. **سلوك الاستعلام**: تتعامل عمليات الاستعلام مع المجموعات غير الموجودة بأمان:
|
||||
تؤدي الاستعلامات إلى مجموعات غير موجودة إلى إرجاع نتائج فارغة
|
||||
لا يتم إرجاع أي خطأ لعمليات الاستعلام
|
||||
يسمح بالاستكشاف دون الحاجة إلى وجود المجموعة
|
||||
|
||||
4. **تحديثات البيانات الوصفية**: يمكن للمستخدمين تحديث بيانات وصفية للمجموعة بعد الإنشاء:
|
||||
قم بتحديث الاسم والوصف والعلامات عبر `tg-set-collection`
|
||||
تنطبق التحديثات على بيانات المكتبة الوصفية فقط
|
||||
تحتفظ الواجهات الخلفية للتخزين بالمجموعة ولكن لا يتم نشر تحديثات البيانات الوصفية
|
||||
|
||||
5. **الحذف الصريح**: يقوم المستخدمون بحذف المجموعات عبر `tg-delete-collection`:
|
||||
تقوم المكتبة ببث "حذف مجموعة" إلى جميع الواجهات الخلفية للتخزين
|
||||
تنتظر تأكيدًا من جميع معالجات التخزين
|
||||
تحذف سجل بيانات المكتبة الوصفية فقط بعد اكتمال تنظيف التخزين
|
||||
يضمن عدم وجود بيانات متبقية في التخزين
|
||||
|
||||
**المبدأ الأساسي**: المكتبة هي نقطة التحكم الوحيدة لإنشاء المجموعة. سواء تم بدءها بأمر المستخدم أو بإرسال مستند، تضمن المكتبة تتبع البيانات الوصفية المناسبة ومزامنة الواجهة الخلفية للتخزين قبل السماح بعمليات البيانات.
|
||||
|
||||
العمليات المطلوبة:
|
||||
**إنشاء مجموعة**: عملية المستخدم عبر `tg-set-collection` أو تلقائيًا عند إرسال مستند
|
||||
**تحديث بيانات وصفية للمجموعة**: عملية المستخدم لتعديل الاسم والوصف والعلامات
|
||||
**حذف مجموعة**: عملية المستخدم لإزالة المجموعة والبيانات المرتبطة بها عبر جميع المتاجر
|
||||
**قائمة المجموعات**: عملية المستخدم لعرض المجموعات مع التصفية حسب العلامات
|
||||
|
||||
#### إدارة المجموعة عبر المتاجر
|
||||
|
||||
توجد المجموعات عبر واجهات خلفية تخزين متعددة في TrustGraph:
|
||||
**مخازن المتجهات** (Qdrant، Milvus، Pinecone): تخزن التضمينات والبيانات المتجهة
|
||||
**مخازن الكائنات** (Cassandra): تخزن المستندات وبيانات الملف
|
||||
**مخازن الثلاثيات** (Cassandra، Neo4j، Memgraph، FalkorDB): تخزن بيانات الرسم البياني/RDF
|
||||
|
||||
Each store type implements:
|
||||
**Collection State Tracking**: Maintain knowledge of which collections exist
|
||||
**Collection Creation**: Accept and process "create-collection" operations
|
||||
**Collection Validation**: Check collection exists before accepting writes
|
||||
**Collection Deletion**: Remove all data for specified collection
|
||||
|
||||
The librarian service coordinates collection operations across all store types, ensuring:
|
||||
Collections created in all backends before use
|
||||
All backends confirm creation before returning success
|
||||
Synchronized collection lifecycle across storage types
|
||||
Consistent error handling when collections don't exist
|
||||
|
||||
#### Collection State Tracking by Storage Type
|
||||
|
||||
Each storage backend tracks collection state differently based on its capabilities:
|
||||
|
||||
**Cassandra Triple Store:**
|
||||
Uses existing `triples_collection` table
|
||||
Creates system marker triple when collection created
|
||||
Query: `SELECT collection FROM triples_collection WHERE collection = ? LIMIT 1`
|
||||
Efficient single-partition check for collection existence
|
||||
|
||||
**Qdrant/Milvus/Pinecone Vector Stores:**
|
||||
Native collection APIs provide existence checking
|
||||
Collections created with proper vector configuration
|
||||
`collection_exists()` method uses storage API
|
||||
Collection creation validates dimension requirements
|
||||
|
||||
**Neo4j/Memgraph/FalkorDB Graph Stores:**
|
||||
Use `:CollectionMetadata` nodes to track collections
|
||||
Node properties: `{user, collection, created_at}`
|
||||
Query: `MATCH (c:CollectionMetadata {user: $user, collection: $collection})`
|
||||
Separate from data nodes for clean separation
|
||||
Enables efficient collection listing and validation
|
||||
|
||||
**Cassandra Object Store:**
|
||||
Uses collection metadata table or marker rows
|
||||
Similar pattern to triple store
|
||||
Validates collection before document writes
|
||||
|
||||
### APIs
|
||||
|
||||
Collection Management APIs (Librarian):
|
||||
**Create/Update Collection**: Create new collection or update existing metadata via `tg-set-collection`
|
||||
**List Collections**: Retrieve collections for a user with optional tag filtering
|
||||
**Delete Collection**: Remove collection and associated data, cascading to all store types
|
||||
|
||||
Storage Management APIs (All Storage Processors):
|
||||
**Create Collection**: Handle "create-collection" operation, establish collection in storage
|
||||
**Delete Collection**: Handle "delete-collection" operation, remove all collection data
|
||||
**Collection Exists Check**: Internal validation before accepting write operations
|
||||
|
||||
Data Operation APIs (Modified Behavior):
|
||||
**Write APIs**: Validate collection exists before accepting data, return error if not
|
||||
**Query APIs**: Return empty results for non-existent collections without error
|
||||
|
||||
### Implementation Details
|
||||
|
||||
The implementation will follow existing TrustGraph patterns for service integration and CLI command structure.
|
||||
|
||||
#### Collection Deletion Cascade
|
||||
|
||||
When a user initiates collection deletion through the librarian service:
|
||||
|
||||
1. **Metadata Validation**: Verify collection exists and user has permission to delete
|
||||
2. **Store Cascade**: Librarian coordinates deletion across all store writers:
|
||||
Vector store writer: Remove embeddings and vector indexes for the user and collection
|
||||
Object store writer: Remove documents and files for the user and collection
|
||||
Triple store writer: Remove graph data and triples for the user and collection
|
||||
3. **Metadata Cleanup**: Remove collection metadata record from Cassandra
|
||||
4. **Error Handling**: If any store deletion fails, maintain consistency through rollback or retry mechanisms
|
||||
|
||||
#### Collection Management Interface
|
||||
|
||||
**⚠️ LEGACY APPROACH - REPLACED BY CONFIG-BASED PATTERN**
|
||||
|
||||
The queue-based architecture described below has been replaced with a config-based approach using `CollectionConfigHandler`. All storage backends now receive collection updates via config push messages instead of dedicated management queues.
|
||||
|
||||
~~All store writers implement a standardized collection management interface with a common schema:~~
|
||||
|
||||
~~**Message Schema (`StorageManagementRequest`):**~~
|
||||
```json
|
||||
{
|
||||
"operation": "create-collection" | "delete-collection",
|
||||
"user": "user123",
|
||||
"collection": "documents-2024"
|
||||
}
|
||||
```
|
||||
|
||||
~~**هيكلة قائمة الانتظار:**~~
|
||||
~~**قائمة انتظار إدارة مخزن المتجهات** (`vector-storage-management`): مخازن المتجهات/التضمينات~~
|
||||
~~**قائمة انتظار إدارة مخزن الكائنات** (`object-storage-management`): مخازن الكائنات/المستندات~~
|
||||
~~**قائمة انتظار إدارة مخزن الثلاثيات** (`triples-storage-management`): مخازن الرسم البياني/RDF~~
|
||||
~~**قائمة انتظار استجابة التخزين** (`storage-management-response`): يتم إرسال جميع الاستجابات هنا~~
|
||||
|
||||
**التنفيذ الحالي:**
|
||||
|
||||
تستخدم جميع واجهات التخزين الخلفية الآن `CollectionConfigHandler`:
|
||||
**تكامل دفع التكوين**: تسجل خدمات التخزين للحصول على إشعارات دفع التكوين
|
||||
**المزامنة التلقائية**: يتم إنشاء/حذف المجموعات بناءً على تغييرات التكوين
|
||||
**نموذج تصريحي**: يتم تعريف المجموعات في خدمة التكوين، وتقوم الواجهات الخلفية بالمزامنة للمطابقة
|
||||
**لا يوجد طلب/استجابة**: يلغي تكامل التنسيق وتتبع الاستجابة
|
||||
**تتبع حالة المجموعة**: يتم الحفاظ عليه عبر ذاكرة التخزين المؤقت `known_collections`
|
||||
**عمليات قابلة للعكس**: من الآمن معالجة نفس التكوين عدة مرات
|
||||
|
||||
تقوم كل واجهة تخزين خلفية بتنفيذ:
|
||||
`create_collection(user: str, collection: str, metadata: dict)` - إنشاء هياكل المجموعة
|
||||
`delete_collection(user: str, collection: str)` - إزالة جميع بيانات المجموعة
|
||||
`collection_exists(user: str, collection: str) -> bool` - التحقق من الصحة قبل الكتابة
|
||||
|
||||
#### إعادة هيكلة مخزن الثلاثيات Cassandra
|
||||
|
||||
كجزء من هذا التنفيذ، سيتم إعادة هيكلة مخزن الثلاثيات Cassandra من نموذج جدول لكل مجموعة إلى نموذج جدول موحد:
|
||||
|
||||
**الهيكلة الحالية:**
|
||||
مساحة مفاتيح لكل مستخدم، وجدول منفصل لكل مجموعة
|
||||
المخطط: `(s, p, o)` مع `PRIMARY KEY (s, p, o)`
|
||||
أسماء الجداول: تصبح مجموعات المستخدمين جداول Cassandra منفصلة
|
||||
|
||||
**الهيكلة الجديدة:**
|
||||
مساحة مفاتيح لكل مستخدم، وجدول "ثلاثيات" واحد لجميع المجموعات
|
||||
المخطط: `(collection, s, p, o)` مع `PRIMARY KEY (collection, s, p, o)`
|
||||
عزل المجموعة من خلال تقسيم المجموعة
|
||||
|
||||
**التغييرات المطلوبة:**
|
||||
|
||||
1. **إعادة هيكلة فئة TrustGraph** (`trustgraph/direct/cassandra.py`):
|
||||
إزالة المعلمة `table` من المُنشئ، واستخدام جدول "ثلاثيات" ثابت
|
||||
إضافة المعلمة `collection` إلى جميع الطرق
|
||||
تحديث المخطط لتضمين المجموعة كأول عمود
|
||||
**تحديثات الفهرس**: سيتم إنشاء فهارس جديدة لدعم جميع أنماط الاستعلام الثمانية:
|
||||
فهرس على `(s)` للاستعلامات المستندة إلى الموضوع
|
||||
فهرس على `(p)` للاستعلامات المستندة إلى الرابط
|
||||
فهرس على `(o)` للاستعلامات المستندة إلى الكائن
|
||||
ملاحظة: لا تدعم Cassandra فهارس ثانوية متعددة الأعمدة، لذا هذه هي فهارس أحادية العمود
|
||||
|
||||
**أداء نمط الاستعلام:**
|
||||
✅ `get_all()` - فحص التقسيم على `collection`
|
||||
✅ `get_s(s)` - يستخدم المفتاح الأساسي بكفاءة (`collection, s`)
|
||||
✅ `get_p(p)` - يستخدم `idx_p` مع تصفية `collection`
|
||||
✅ `get_o(o)` - يستخدم `idx_o` مع تصفية `collection`
|
||||
✅ `get_sp(s, p)` - يستخدم المفتاح الأساسي بكفاءة (`collection, s, p`)
|
||||
⚠️ `get_po(p, o)` - يتطلب `ALLOW FILTERING` (يستخدم إما `idx_p` أو `idx_o` بالإضافة إلى التصفية)
|
||||
✅ `get_os(o, s)` - يستخدم `idx_o` مع تصفية إضافية على `s`
|
||||
✅ `get_spo(s, p, o)` - يستخدم المفتاح الأساسي بكفاءة
|
||||
|
||||
**ملاحظة حول ALLOW FILTERING**: يتطلب نمط استعلام `get_po` `ALLOW FILTERING` لأنه يحتاج إلى كل من قيود الرابط والكائن بدون فهرس مركب مناسب. هذا مقبول لأن نمط الاستعلام هذا أقل شيوعًا من الاستعلامات المستندة إلى الموضوع في الاستخدام النموذجي لمخزن الثلاثيات.
|
||||
|
||||
2. **تحديثات كاتب التخزين** (`trustgraph/storage/triples/cassandra/write.py`):
|
||||
الحفاظ على اتصال TrustGraph واحد لكل مستخدم بدلاً من لكل (مستخدم، مجموعة)
|
||||
تمرير المجموعة إلى عمليات الإدراج
|
||||
تحسين استخدام الموارد مع عدد أقل من الاتصالات
|
||||
|
||||
3. **تحديثات خدمة الاستعلام** (`trustgraph/query/triples/cassandra/service.py`):
|
||||
اتصال TrustGraph واحد لكل مستخدم
|
||||
تمرير المجموعة إلى جميع عمليات الاستعلام
|
||||
الحفاظ على نفس منطق الاستعلام مع معلمة المجموعة
|
||||
|
||||
**الفوائد:**
|
||||
**تبسيط حذف المجموعة**: حذف باستخدام مفتاح التقسيم `collection` عبر جميع الجداول الأربعة
|
||||
**كفاءة الموارد**: عدد أقل من اتصالات قاعدة البيانات وكائنات الجدول
|
||||
**العمليات عبر المجموعات**: من الأسهل تنفيذ العمليات التي تمتد عبر مجموعات متعددة
|
||||
**هيكلة متسقة**: تتماشى مع نهج بيانات التعريف الموحد للمجموعة
|
||||
**التحقق من صحة المجموعة**: من السهل التحقق من وجود المجموعة عبر جدول `triples_collection`
|
||||
|
||||
ستكون عمليات المجموعة ذرية قدر الإمكان، وستوفر معالجة أخطاء والتحقق المناسبين.
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
تتطلب عمليات إدارة المجموعة تفويضًا مناسبًا لمنع الوصول غير المصرح به أو حذف المجموعات. سيتم مواءمة التحكم في الوصول مع نماذج الأمان الحالية لـ TrustGraph.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
قد تتطلب عمليات سرد المجموعة الترقيم في البيئات التي تحتوي على عدد كبير من المجموعات. يجب تحسين استعلامات البيانات الوصفية للأنماط الشائعة للتصفية.
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
ستغطي الاختبارات الشاملة ما يلي:
|
||||
سير عمل إنشاء المجموعة من البداية إلى النهاية
|
||||
مزامنة الواجهة الخلفية للتخزين
|
||||
التحقق من صحة الكتابة للمجموعات غير الموجودة
|
||||
معالجة الاستعلامات للمجموعات غير الموجودة
|
||||
حذف المجموعة بالتتالي عبر جميع المستودعات
|
||||
معالجة الأخطاء وسيناريوهات الاسترداد
|
||||
اختبارات الوحدة لكل واجهة خلفية للتخزين
|
||||
اختبارات التكامل للعمليات عبر المستودعات
|
||||
|
||||
## حالة التنفيذ
|
||||
|
||||
### ✅ المكونات المكتملة
|
||||
|
||||
1. **خدمة إدارة المجموعة Librarian** (`trustgraph-flow/trustgraph/librarian/collection_manager.py`)
|
||||
عمليات CRUD للبيانات الوصفية للمجموعة (القائمة، التحديث، الحذف)
|
||||
تكامل جدول بيانات وصفية للمجموعة في Cassandra عبر `LibraryTableStore`
|
||||
تنسيق حذف المجموعة بالتتالي عبر جميع أنواع التخزين
|
||||
معالجة الطلبات/الاستجابات غير المتزامنة مع إدارة الأخطاء المناسبة
|
||||
|
||||
2. **مخطط البيانات الوصفية للمجموعة** (`trustgraph-base/trustgraph/schema/services/collection.py`)
|
||||
مخططات `CollectionManagementRequest` و `CollectionManagementResponse`
|
||||
مخطط `CollectionMetadata` لسجلات المجموعة
|
||||
تعريفات موضوع قائمة انتظار الطلبات/الاستجابات للمجموعة
|
||||
|
||||
3. **مخطط إدارة التخزين** (`trustgraph-base/trustgraph/schema/services/storage.py`)
|
||||
مخططات `StorageManagementRequest` و `StorageManagementResponse`
|
||||
تم تعريف مواضيع قائمة انتظار إدارة التخزين
|
||||
تنسيق الرسائل لعمليات المجموعة على مستوى التخزين
|
||||
|
||||
4. **مخطط Cassandra المكون من 4 جداول** (`trustgraph-flow/trustgraph/direct/cassandra_kg.py`)
|
||||
مفاتيح تقسيم مركبة لأداء الاستعلام
|
||||
جدول `triples_collection` لاستعلامات SPO وتتبع الحذف
|
||||
تم تنفيذ حذف المجموعة بنمط القراءة ثم الحذف
|
||||
|
||||
### ✅ الترحيل إلى النمط المستند إلى التكوين - مكتمل
|
||||
|
||||
**تم ترحيل جميع الواجهات الخلفية للتخزين من نمط قائمة الانتظار إلى النمط المستند إلى التكوين `CollectionConfigHandler`.**
|
||||
|
||||
عمليات الترحيل المكتملة:
|
||||
✅ `trustgraph-flow/trustgraph/storage/triples/cassandra/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/triples/neo4j/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/triples/memgraph/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/triples/falkordb/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/doc_embeddings/qdrant/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/graph_embeddings/qdrant/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/doc_embeddings/milvus/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/graph_embeddings/milvus/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/doc_embeddings/pinecone/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/graph_embeddings/pinecone/write.py`
|
||||
✅ `trustgraph-flow/trustgraph/storage/objects/cassandra/write.py`
|
||||
|
||||
جميع الواجهات الخلفية الآن:
|
||||
ترث من `CollectionConfigHandler`
|
||||
تسجيل للحصول على إشعارات دفع التكوين عبر `self.register_config_handler(self.on_collection_config)`
|
||||
تنفيذ `create_collection(user, collection, metadata)` و `delete_collection(user, collection)`
|
||||
استخدام `collection_exists(user, collection)` للتحقق قبل الكتابة
|
||||
المزامنة التلقائية مع تغييرات خدمة التكوين
|
||||
|
||||
تم إزالة البنية التحتية لقائمة الانتظار القديمة:
|
||||
✅ تمت إزالة مخططات `StorageManagementRequest` و `StorageManagementResponse`
|
||||
✅ تمت إزالة تعريفات موضوع قائمة انتظار إدارة التخزين
|
||||
✅ تمت إزالة المستهلك/المنتج لإدارة التخزين من جميع الواجهات الخلفية
|
||||
✅ تمت إزالة معالجات `on_storage_management` من جميع الواجهات الخلفية
|
||||
144
docs/tech-specs/ar/document-embeddings-chunk-id.ar.md
Normal file
144
docs/tech-specs/ar/document-embeddings-chunk-id.ar.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
---
|
||||
layout: default
|
||||
title: "تضمينات المستندات - مُعرّف الجزء"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# تضمينات المستندات - مُعرّف الجزء
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تخزين تضمينات المستندات يخزن حاليًا نص الجزء مباشرةً في حمولة مخزن المتجهات، مما يكرر البيانات الموجودة في Garage. يحل هذا المخطط تخزين نص الجزء باستخدام مراجع `chunk_id`.
|
||||
|
||||
## الحالة الحالية
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ChunkEmbeddings:
|
||||
chunk: bytes = b""
|
||||
vectors: list[list[float]] = field(default_factory=list)
|
||||
|
||||
@dataclass
|
||||
class DocumentEmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
chunks: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
حمولة تخزين المتجهات:
|
||||
```python
|
||||
payload={"doc": chunk} # Duplicates Garage content
|
||||
```
|
||||
|
||||
## التصميم
|
||||
|
||||
### تغييرات المخطط
|
||||
|
||||
**ChunkEmbeddings** - استبدال "chunk" بـ "chunk_id":
|
||||
```python
|
||||
@dataclass
|
||||
class ChunkEmbeddings:
|
||||
chunk_id: str = ""
|
||||
vectors: list[list[float]] = field(default_factory=list)
|
||||
```
|
||||
|
||||
**DocumentEmbeddingsResponse** - إرجاع معرفات الأجزاء (chunk_ids) بدلاً من الأجزاء نفسها:
|
||||
```python
|
||||
@dataclass
|
||||
class DocumentEmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
chunk_ids: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
### حمولة مستودع المتجهات
|
||||
|
||||
جميع المستودعات (Qdrant، Milvus، Pinecone):
|
||||
```python
|
||||
payload={"chunk_id": chunk_id}
|
||||
```
|
||||
|
||||
### التغييرات في معالج مستند RAG
|
||||
|
||||
يقوم معالج مستند RAG باسترداد محتوى الأجزاء من نظام Garage:
|
||||
|
||||
```python
|
||||
# Get chunk_ids from embeddings store
|
||||
chunk_ids = await self.rag.doc_embeddings_client.query(...)
|
||||
|
||||
# Fetch chunk content from Garage
|
||||
docs = []
|
||||
for chunk_id in chunk_ids:
|
||||
content = await self.rag.librarian_client.get_document_content(
|
||||
chunk_id, self.user
|
||||
)
|
||||
docs.append(content)
|
||||
```
|
||||
|
||||
### التغييرات في واجهة برمجة التطبيقات (API) / مجموعة تطوير البرمجيات (SDK)
|
||||
|
||||
**DocumentEmbeddingsClient** تُرجع `chunk_ids`:
|
||||
```python
|
||||
return resp.chunk_ids # Changed from resp.chunks
|
||||
```
|
||||
|
||||
**تنسيق البيانات** (DocumentEmbeddingsResponseTranslator):
|
||||
```python
|
||||
result["chunk_ids"] = obj.chunk_ids # Changed from chunks
|
||||
```
|
||||
|
||||
### تغييرات واجهة سطر الأوامر (CLI)
|
||||
|
||||
تعرض أداة واجهة سطر الأوامر (CLI) معرفات الأجزاء (يمكن للمستخدمين استرداد المحتوى بشكل منفصل إذا لزم الأمر).
|
||||
|
||||
## الملفات التي يجب تعديلها
|
||||
|
||||
### المخطط (Schema)
|
||||
`trustgraph-base/trustgraph/schema/knowledge/embeddings.py` - ChunkEmbeddings
|
||||
`trustgraph-base/trustgraph/schema/services/query.py` - DocumentEmbeddingsResponse
|
||||
|
||||
### الرسائل/المترجمات
|
||||
`trustgraph-base/trustgraph/messaging/translators/embeddings_query.py` - DocumentEmbeddingsResponseTranslator
|
||||
|
||||
### العميل (Client)
|
||||
`trustgraph-base/trustgraph/base/document_embeddings_client.py` - إرجاع معرفات الأجزاء
|
||||
|
||||
### حزمة تطوير البرمجيات (SDK) / واجهة برمجة التطبيقات (API) بلغة بايثون
|
||||
`trustgraph-base/trustgraph/api/flow.py` - document_embeddings_query
|
||||
`trustgraph-base/trustgraph/api/socket_client.py` - document_embeddings_query
|
||||
`trustgraph-base/trustgraph/api/async_flow.py` - إذا كان ذلك ممكنًا
|
||||
`trustgraph-base/trustgraph/api/bulk_client.py` - استيراد/تصدير تضمينات المستندات
|
||||
`trustgraph-base/trustgraph/api/async_bulk_client.py` - استيراد/تصدير تضمينات المستندات
|
||||
|
||||
### خدمة التضمينات
|
||||
`trustgraph-flow/trustgraph/embeddings/document_embeddings/embeddings.py` - تمرير معرف الجزء
|
||||
|
||||
### أدوات الكتابة في التخزين
|
||||
`trustgraph-flow/trustgraph/storage/doc_embeddings/qdrant/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/doc_embeddings/milvus/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/doc_embeddings/pinecone/write.py`
|
||||
|
||||
### خدمات الاستعلام
|
||||
`trustgraph-flow/trustgraph/query/doc_embeddings/qdrant/service.py`
|
||||
`trustgraph-flow/trustgraph/query/doc_embeddings/milvus/service.py`
|
||||
`trustgraph-flow/trustgraph/query/doc_embeddings/pinecone/service.py`
|
||||
|
||||
### البوابة (Gateway)
|
||||
`trustgraph-flow/trustgraph/gateway/dispatch/document_embeddings_query.py`
|
||||
`trustgraph-flow/trustgraph/gateway/dispatch/document_embeddings_export.py`
|
||||
`trustgraph-flow/trustgraph/gateway/dispatch/document_embeddings_import.py`
|
||||
|
||||
### استرجاع المعلومات من المستندات (Document RAG)
|
||||
`trustgraph-flow/trustgraph/retrieval/document_rag/rag.py` - إضافة عميل أمين المكتبة
|
||||
`trustgraph-flow/trustgraph/retrieval/document_rag/document_rag.py` - الاسترداد من Garage
|
||||
|
||||
### واجهة سطر الأوامر (CLI)
|
||||
`trustgraph-cli/trustgraph/cli/invoke_document_embeddings.py`
|
||||
`trustgraph-cli/trustgraph/cli/save_doc_embeds.py`
|
||||
`trustgraph-cli/trustgraph/cli/load_doc_embeds.py`
|
||||
|
||||
## الفوائد
|
||||
|
||||
1. مصدر واحد للحقيقة - نص الأجزاء فقط في Garage
|
||||
2. تقليل مساحة التخزين في مخزن المتجهات
|
||||
3. يتيح تتبع مصدر المعلومات في وقت الاستعلام عبر معرف الجزء.
|
||||
675
docs/tech-specs/ar/embeddings-batch-processing.ar.md
Normal file
675
docs/tech-specs/ar/embeddings-batch-processing.ar.md
Normal file
|
|
@ -0,0 +1,675 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية لمعالجة الدفعات لخدمة التضمينات (Embeddings)"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية لمعالجة الدفعات لخدمة التضمينات (Embeddings)
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات التحسينات التي ستُجرى على خدمة التضمينات لدعم معالجة الدفعات لعدد كبير من النصوص في طلب واحد. تعالج التنفيذ الحالي النص الواحد في كل مرة، مما يفوّت المزايا الكبيرة في الأداء التي توفرها نماذج التضمين عند معالجة الدفعات.
|
||||
|
||||
1. **عدم كفاءة معالجة النصوص الفردية**: يغلف التنفيذ الحالي النصوص الفردية في قائمة، مما يؤدي إلى عدم الاستفادة الكاملة من قدرات الدفعات في FastEmbed.
|
||||
2. **العبء الزائد لكل طلب نص**: يتطلب كل نص رسالة Pulsar منفصلة، مما يتطلب جولة ذهاب وإياب.
|
||||
3. **عدم كفاءة استنتاج النموذج**: نماذج التضمين لها عبء ثابت لكل دفعة؛ فإن الدفعات الصغيرة تهدر موارد وحدة معالجة الرسومات (GPU) ووحدة المعالجة المركزية (CPU).
|
||||
4. **المعالجة التسلسلية في التطبيقات**: تقوم الخدمات الرئيسية بالتكرار على العناصر واستدعاء التضمينات واحدًا تلو الآخر.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**دعم واجهة برمجة تطبيقات (API) للدفعات**: تمكين معالجة نصوص متعددة في طلب واحد.
|
||||
**التوافق مع الإصدارات السابقة**: الحفاظ على دعم الطلبات التي تتضمن نصًا واحدًا فقط.
|
||||
**تحسين كبير في الإنتاجية**: استهداف تحسين في الإنتاجية يتراوح بين 5 إلى 10 مرات للعمليات الجماعية.
|
||||
**تقليل زمن الوصول لكل نص**: تقليل زمن الوصول المتوسط عند تضمين نصوص متعددة.
|
||||
**كفاءة الذاكرة**: معالجة الدفعات دون استهلاك مفرط للذاكرة.
|
||||
**الاستقلالية عن المزود**: دعم التجميع عبر FastEmbed و Ollama ومزودين آخرين.
|
||||
**تحديث التطبيقات**: تحديث جميع تطبيقات التضمين لاستخدام واجهة برمجة تطبيقات الدفعات عند الإمكان.
|
||||
|
||||
## الخلفية
|
||||
|
||||
### التنفيذ الحالي - خدمة التضمينات
|
||||
|
||||
يُظهر تطبيق التضمينات في `trustgraph-flow/trustgraph/embeddings/fastembed/processor.py` عدم كفاءة كبيرة في الأداء:
|
||||
|
||||
```python
|
||||
# fastembed/processor.py line 56
|
||||
async def on_embeddings(self, text, model=None):
|
||||
use_model = model or self.default_model
|
||||
self._load_model(use_model)
|
||||
|
||||
vecs = self.embeddings.embed([text]) # Single text wrapped in list
|
||||
|
||||
return [v.tolist() for v in vecs]
|
||||
```
|
||||
|
||||
**المشاكل:**
|
||||
|
||||
1. **حجم الدفعة 1**: طريقة `embed()` في FastEmbed مُحسّنة للمعالجة الدفعية، ولكننا نستدعيها دائمًا مع `[text]` - دفعة بحجم 1.
|
||||
|
||||
2. **التكلفة لكل طلب**: كل طلب تضمين يتضمن:
|
||||
تسلسل/إلغاء تسلسل رسالة Pulsar.
|
||||
زمن انتقال الشبكة.
|
||||
تكلفة بدء تشغيل الاستدلال للنموذج.
|
||||
تكلفة جدولة المهام غير المتزامنة في Python.
|
||||
|
||||
3. **قيود المخطط**: مخطط `EmbeddingsRequest` يدعم نصًا واحدًا فقط:
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsRequest:
|
||||
text: str = "" # Single text only
|
||||
```
|
||||
|
||||
### المستخدمون الحاليون - المعالجة التسلسلية
|
||||
|
||||
#### 1. بوابة واجهة برمجة التطبيقات (API Gateway)
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/gateway/dispatch/embeddings.py`
|
||||
|
||||
تقبل البوابة طلبات تضمين النصوص الفردية عبر HTTP/WebSocket وتوجهها إلى خدمة التضمين. حاليًا، لا يوجد نقطة نهاية للدفعات.
|
||||
|
||||
```python
|
||||
class EmbeddingsRequestor(ServiceRequestor):
|
||||
# Handles single EmbeddingsRequest -> EmbeddingsResponse
|
||||
request_schema=EmbeddingsRequest, # Single text only
|
||||
response_schema=EmbeddingsResponse,
|
||||
```
|
||||
|
||||
**التأثير:** يجب على العملاء الخارجيين (تطبيقات الويب، النصوص البرمجية) إجراء N طلب HTTP لتضمين N نص.
|
||||
|
||||
#### 2. خدمة تضمين المستندات
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/embeddings/document_embeddings/embeddings.py`
|
||||
|
||||
يعالج أجزاء المستندات واحدة تلو الأخرى:
|
||||
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
v = msg.value()
|
||||
|
||||
# Single chunk per request
|
||||
resp = await flow("embeddings-request").request(
|
||||
EmbeddingsRequest(text=v.chunk)
|
||||
)
|
||||
vectors = resp.vectors
|
||||
```
|
||||
|
||||
**التأثير:** تتطلب كل جزء من المستند استدعاءً منفصلاً لعملية التضمين. المستند الذي يتكون من 100 جزء = 100 طلب تضمين.
|
||||
|
||||
#### 3. خدمة تضمين الرسوم البيانية
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/embeddings/graph_embeddings/embeddings.py`
|
||||
|
||||
يتكرر على الكيانات ويقوم بتضمين كل منها بالتسلسل:
|
||||
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
for entity in v.entities:
|
||||
# Serial embedding - one entity at a time
|
||||
vectors = await flow("embeddings-request").embed(
|
||||
text=entity.context
|
||||
)
|
||||
entities.append(EntityEmbeddings(
|
||||
entity=entity.entity,
|
||||
vectors=vectors,
|
||||
chunk_id=entity.chunk_id,
|
||||
))
|
||||
```
|
||||
|
||||
**التأثير:** رسالة تحتوي على 50 كيانًا = 50 طلب تضمين تسلسلي. هذا يمثل عنق زجاجة رئيسي أثناء بناء الرسم البياني المعرفي.
|
||||
|
||||
#### 4. خدمة تضمين الصفوف
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/embeddings/row_embeddings/embeddings.py`
|
||||
|
||||
يتكرر على النصوص الفريدة ويضمّن كل منها بشكل تسلسلي:
|
||||
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
for text, (index_name, index_value) in texts_to_embed.items():
|
||||
# Serial embedding - one text at a time
|
||||
vectors = await flow("embeddings-request").embed(text=text)
|
||||
|
||||
embeddings_list.append(RowIndexEmbedding(
|
||||
index_name=index_name,
|
||||
index_value=index_value,
|
||||
text=text,
|
||||
vectors=vectors
|
||||
))
|
||||
```
|
||||
|
||||
**التأثير:** معالجة جدول يحتوي على 100 قيمة فريدة مفهرسة = 100 طلب تضمين متسلسل.
|
||||
|
||||
#### 5. EmbeddingsClient (العميل الأساسي)
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/base/embeddings_client.py`
|
||||
|
||||
العميل المستخدم من قبل جميع معالجات التدفق يدعم فقط تضمين النصوص الفردية:
|
||||
|
||||
```python
|
||||
class EmbeddingsClient(RequestResponse):
|
||||
async def embed(self, text, timeout=30):
|
||||
resp = await self.request(
|
||||
EmbeddingsRequest(text=text), # Single text
|
||||
timeout=timeout
|
||||
)
|
||||
return resp.vectors
|
||||
```
|
||||
|
||||
**التأثير:** جميع المستخدمين الذين يعتمدون على هذا البرنامج يقتصرون على العمليات النصية البسيطة.
|
||||
|
||||
#### 6. أدوات سطر الأوامر
|
||||
|
||||
**الملف:** `trustgraph-cli/trustgraph/cli/invoke_embeddings.py`
|
||||
|
||||
أداة سطر الأوامر تقبل وسيط نصي واحد:
|
||||
|
||||
```python
|
||||
def query(url, flow_id, text, token=None):
|
||||
result = flow.embeddings(text=text) # Single text
|
||||
vectors = result.get("vectors", [])
|
||||
```
|
||||
|
||||
**التأثير:** لا يمكن للمستخدمين إجراء تضمين مجمّع من سطر الأوامر. يتطلب معالجة ملف من النصوص عدد N من الاستدعاءات.
|
||||
|
||||
#### 7. حزمة تطوير البرمجيات (SDK) الخاصة بـ Python
|
||||
|
||||
توفر حزمة تطوير البرمجيات الخاصة بـ Python فئتين من العملاء للتفاعل مع خدمات TrustGraph. تدعم كلتاهما فقط التضمين لنص واحد.
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/api/flow.py`
|
||||
|
||||
```python
|
||||
class FlowInstance:
|
||||
def embeddings(self, text):
|
||||
"""Get embeddings for a single text"""
|
||||
input = {"text": text}
|
||||
return self.request("service/embeddings", input)["vectors"]
|
||||
```
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/api/socket_client.py`
|
||||
|
||||
```python
|
||||
class SocketFlowInstance:
|
||||
def embeddings(self, text: str, **kwargs: Any) -> Dict[str, Any]:
|
||||
"""Get embeddings for a single text via WebSocket"""
|
||||
request = {"text": text}
|
||||
return self.client._send_request_sync(
|
||||
"embeddings", self.flow_id, request, False
|
||||
)
|
||||
```
|
||||
|
||||
**التأثير:** يجب على مطوري بايثون الذين يستخدمون مجموعة تطوير البرامج (SDK) المرور على النصوص وإجراء مكالمات واجهة برمجة التطبيقات (API) منفصلة. لا يوجد دعم لعمليات الدمج المجمعة لمستخدمي مجموعة تطوير البرامج.
|
||||
|
||||
### تأثير الأداء
|
||||
|
||||
بالنسبة لاستيعاب المستندات النموذجي (1000 جزء نصي):
|
||||
**الحالي:** 1000 طلب منفصل، و1000 استدعاء لنموذج الاستدلال.
|
||||
**مجمعة (batch_size=32):** 32 طلبًا، و32 استدعاء لنموذج الاستدلال (انخفاض بنسبة 96.8٪).
|
||||
|
||||
بالنسبة لدمج الرسم البياني (رسالة تحتوي على 50 كيانًا):
|
||||
**الحالي:** 50 استدعاء انتظار متسلسل، من 5 إلى 10 ثوانٍ تقريبًا.
|
||||
**مجمعة:** 1-2 استدعاء مجمع، من 0.5 إلى 1 ثانية تقريبًا (تحسين بمقدار 5-10 مرات).
|
||||
|
||||
تحقق مكتبات FastEmbed والمكتبات المماثلة تقريبًا من قابلية التوسع الخطية في الإنتاجية مع حجم الدفعة حتى حدود الأجهزة (عادةً ما تكون 32-128 نصًا لكل دفعة).
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
يتطلب تحسين معالجة الدفعات لإنشاء تضمينات تغييرات في المكونات التالية:
|
||||
|
||||
#### 1. **تحسين المخطط**
|
||||
قم بتوسيع `EmbeddingsRequest` لدعم نصوص متعددة.
|
||||
قم بتوسيع `EmbeddingsResponse` لإرجاع مجموعات متجهات متعددة.
|
||||
حافظ على التوافق مع الإصدارات السابقة مع طلبات النص الواحد.
|
||||
|
||||
الوحدة: `trustgraph-base/trustgraph/schema/services/llm.py`
|
||||
|
||||
#### 2. **تحسين الخدمة الأساسية**
|
||||
قم بتحديث `EmbeddingsService` للتعامل مع الطلبات المجمعة.
|
||||
أضف تكوين حجم الدفعة.
|
||||
قم بتنفيذ معالجة الطلبات الواعية بالدفعة.
|
||||
|
||||
الوحدة: `trustgraph-base/trustgraph/base/embeddings_service.py`
|
||||
|
||||
#### 3. **تحديثات معالج المزود**
|
||||
قم بتحديث معالج FastEmbed لتمرير الدفعة الكاملة إلى `embed()`.
|
||||
قم بتحديث معالج Ollama للتعامل مع الدفعات (إذا تم الدعم).
|
||||
أضف معالجة تسلسلية احتياطية للمزودين الذين لا يدعمون الدفعات.
|
||||
|
||||
الوحدات:
|
||||
`trustgraph-flow/trustgraph/embeddings/fastembed/processor.py`
|
||||
`trustgraph-flow/trustgraph/embeddings/ollama/processor.py`
|
||||
|
||||
#### 4. **تحسين العميل**
|
||||
أضف طريقة إنشاء تضمينات مجمعة إلى `EmbeddingsClient`.
|
||||
دعم كل من واجهات برمجة التطبيقات الفردية والمجمعة.
|
||||
أضف تجميعًا تلقائيًا للمدخلات الكبيرة.
|
||||
|
||||
الوحدة: `trustgraph-base/trustgraph/base/embeddings_client.py`
|
||||
|
||||
#### 5. **تحديثات المتصل - معالجات التدفق**
|
||||
قم بتحديث `graph_embeddings` لتجميع سياقات الكيانات.
|
||||
قم بتحديث `row_embeddings` لتجميع نصوص الفهرس.
|
||||
قم بتحديث `document_embeddings` إذا كان تجميع الرسائل ممكنًا.
|
||||
|
||||
الوحدات:
|
||||
`trustgraph-flow/trustgraph/embeddings/graph_embeddings/embeddings.py`
|
||||
`trustgraph-flow/trustgraph/embeddings/row_embeddings/embeddings.py`
|
||||
`trustgraph-flow/trustgraph/embeddings/document_embeddings/embeddings.py`
|
||||
|
||||
#### 6. **تحسين بوابة واجهة برمجة التطبيقات**
|
||||
أضف نقطة نهاية لإنشاء تضمينات مجمعة.
|
||||
دعم مصفوفة من النصوص في نص الطلب.
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/gateway/dispatch/embeddings.py`
|
||||
|
||||
#### 7. **تحسين أداة سطر الأوامر**
|
||||
أضف دعمًا للنصوص المتعددة أو إدخال الملف.
|
||||
أضف معلمة حجم الدفعة.
|
||||
|
||||
الوحدة: `trustgraph-cli/trustgraph/cli/invoke_embeddings.py`
|
||||
|
||||
#### 8. **تحسين مجموعة تطوير البرامج (SDK) الخاصة بـ Python**
|
||||
أضف طريقة `embeddings_batch()` إلى `FlowInstance`.
|
||||
أضف طريقة `embeddings_batch()` إلى `SocketFlowInstance`.
|
||||
دعم كل من واجهات برمجة التطبيقات الفردية والمجمعة لمستخدمي مجموعة تطوير البرامج.
|
||||
|
||||
الوحدات:
|
||||
`trustgraph-base/trustgraph/api/flow.py`
|
||||
`trustgraph-base/trustgraph/api/socket_client.py`
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### EmbeddingsRequest
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsRequest:
|
||||
texts: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
الاستخدام:
|
||||
نص مفرد: `EmbeddingsRequest(texts=["hello world"])`
|
||||
دفعة: `EmbeddingsRequest(texts=["text1", "text2", "text3"])`
|
||||
|
||||
#### EmbeddingsResponse
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
vectors: list[list[list[float]]] = field(default_factory=list)
|
||||
```
|
||||
|
||||
هيكل الاستجابة:
|
||||
`vectors[i]` يحتوي على مجموعة المتجهات لـ `texts[i]`
|
||||
كل مجموعة متجهات هي `list[list[float]]` (قد تُرجع النماذج عدة متجهات لكل نص)
|
||||
مثال: 3 نصوص → `vectors` يحتوي على 3 إدخالات، كل منها يحتوي على تضمينات هذا النص
|
||||
|
||||
### واجهات برمجة التطبيقات (APIs)
|
||||
|
||||
#### EmbeddingsClient
|
||||
|
||||
```python
|
||||
class EmbeddingsClient(RequestResponse):
|
||||
async def embed(
|
||||
self,
|
||||
texts: list[str],
|
||||
timeout: float = 300,
|
||||
) -> list[list[list[float]]]:
|
||||
"""
|
||||
Embed one or more texts in a single request.
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
timeout: Timeout for the operation
|
||||
|
||||
Returns:
|
||||
List of vector sets, one per input text
|
||||
"""
|
||||
resp = await self.request(
|
||||
EmbeddingsRequest(texts=texts),
|
||||
timeout=timeout
|
||||
)
|
||||
if resp.error:
|
||||
raise RuntimeError(resp.error.message)
|
||||
return resp.vectors
|
||||
```
|
||||
|
||||
#### نقطة نهاية تضمين بوابة واجهة برمجة التطبيقات (API Gateway).
|
||||
|
||||
تم تحديث نقطة النهاية لدعم التضمين الفردي أو الدفعي:
|
||||
|
||||
```
|
||||
POST /api/v1/embeddings
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"texts": ["text1", "text2", "text3"],
|
||||
"flow_id": "default"
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"vectors": [
|
||||
[[0.1, 0.2, ...]],
|
||||
[[0.3, 0.4, ...]],
|
||||
[[0.5, 0.6, ...]]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
#### المرحلة الأولى: تغييرات المخطط
|
||||
|
||||
**EmbeddingsRequest:**
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsRequest:
|
||||
texts: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
**الاستجابة المضمنة:**
|
||||
```python
|
||||
@dataclass
|
||||
class EmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
vectors: list[list[list[float]]] = field(default_factory=list)
|
||||
```
|
||||
|
||||
**تم تحديث `EmbeddingsService.on_request`:**
|
||||
```python
|
||||
async def on_request(self, msg, consumer, flow):
|
||||
request = msg.value()
|
||||
id = msg.properties()["id"]
|
||||
model = flow("model")
|
||||
|
||||
vectors = await self.on_embeddings(request.texts, model=model)
|
||||
response = EmbeddingsResponse(error=None, vectors=vectors)
|
||||
|
||||
await flow("response").send(response, properties={"id": id})
|
||||
```
|
||||
|
||||
#### المرحلة الثانية: تحديث معالج FastEmbed
|
||||
|
||||
**الحالي (غير فعال):**
|
||||
```python
|
||||
async def on_embeddings(self, text, model=None):
|
||||
use_model = model or self.default_model
|
||||
self._load_model(use_model)
|
||||
vecs = self.embeddings.embed([text]) # Batch of 1
|
||||
return [v.tolist() for v in vecs]
|
||||
```
|
||||
|
||||
**تحديث:**
|
||||
```python
|
||||
async def on_embeddings(self, texts: list[str], model=None):
|
||||
"""Embed texts - processes all texts in single model call"""
|
||||
if not texts:
|
||||
return []
|
||||
|
||||
use_model = model or self.default_model
|
||||
self._load_model(use_model)
|
||||
|
||||
# FastEmbed handles the full batch efficiently
|
||||
all_vecs = list(self.embeddings.embed(texts))
|
||||
|
||||
# Return list of vector sets, one per input text
|
||||
return [[v.tolist()] for v in all_vecs]
|
||||
```
|
||||
|
||||
#### المرحلة الثالثة: تحديث خدمة تضمين الرسوم البيانية
|
||||
|
||||
**الحالي (التسلسلي):**
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
entities = []
|
||||
for entity in v.entities:
|
||||
vectors = await flow("embeddings-request").embed(text=entity.context)
|
||||
entities.append(EntityEmbeddings(...))
|
||||
```
|
||||
|
||||
**تحديث (مجموعة):**
|
||||
```python
|
||||
async def on_message(self, msg, consumer, flow):
|
||||
# Collect all contexts
|
||||
contexts = [entity.context for entity in v.entities]
|
||||
|
||||
# Single batch embedding call
|
||||
all_vectors = await flow("embeddings-request").embed(texts=contexts)
|
||||
|
||||
# Pair results with entities
|
||||
entities = [
|
||||
EntityEmbeddings(
|
||||
entity=entity.entity,
|
||||
vectors=vectors[0], # First vector from the set
|
||||
chunk_id=entity.chunk_id,
|
||||
)
|
||||
for entity, vectors in zip(v.entities, all_vectors)
|
||||
]
|
||||
```
|
||||
|
||||
#### المرحلة الرابعة: تحديث خدمة تضمين الصفوف
|
||||
|
||||
**الحالي (تسلسلي):**
|
||||
```python
|
||||
for text, (index_name, index_value) in texts_to_embed.items():
|
||||
vectors = await flow("embeddings-request").embed(text=text)
|
||||
embeddings_list.append(RowIndexEmbedding(...))
|
||||
```
|
||||
|
||||
**تحديث (مجموعة):**
|
||||
```python
|
||||
# Collect texts and metadata
|
||||
texts = list(texts_to_embed.keys())
|
||||
metadata = list(texts_to_embed.values())
|
||||
|
||||
# Single batch embedding call
|
||||
all_vectors = await flow("embeddings-request").embed(texts=texts)
|
||||
|
||||
# Pair results
|
||||
embeddings_list = [
|
||||
RowIndexEmbedding(
|
||||
index_name=meta[0],
|
||||
index_value=meta[1],
|
||||
text=text,
|
||||
vectors=vectors[0] # First vector from the set
|
||||
)
|
||||
for text, meta, vectors in zip(texts, metadata, all_vectors)
|
||||
]
|
||||
```
|
||||
|
||||
#### المرحلة الخامسة: تحسين أداة سطر الأوامر.
|
||||
|
||||
**سطر الأوامر المحدث:**
|
||||
```python
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(...)
|
||||
|
||||
parser.add_argument(
|
||||
'text',
|
||||
nargs='*', # Zero or more texts
|
||||
help='Text(s) to convert to embedding vectors',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-f', '--file',
|
||||
help='File containing texts (one per line)',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--batch-size',
|
||||
type=int,
|
||||
default=32,
|
||||
help='Batch size for processing (default: 32)',
|
||||
)
|
||||
```
|
||||
|
||||
الاستخدام:
|
||||
```bash
|
||||
# Single text (existing)
|
||||
tg-invoke-embeddings "hello world"
|
||||
|
||||
# Multiple texts
|
||||
tg-invoke-embeddings "text one" "text two" "text three"
|
||||
|
||||
# From file
|
||||
tg-invoke-embeddings -f texts.txt --batch-size 64
|
||||
```
|
||||
|
||||
#### المرحلة السادسة: تحسين حزمة تطوير البرمجيات (SDK) الخاصة بـ Python
|
||||
|
||||
**FlowInstance (عميل HTTP):**
|
||||
|
||||
```python
|
||||
class FlowInstance:
|
||||
def embeddings(self, texts: list[str]) -> list[list[list[float]]]:
|
||||
"""
|
||||
Get embeddings for one or more texts.
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
|
||||
Returns:
|
||||
List of vector sets, one per input text
|
||||
"""
|
||||
input = {"texts": texts}
|
||||
return self.request("service/embeddings", input)["vectors"]
|
||||
```
|
||||
|
||||
**مثيل SocketFlow (عميل WebSocket):**
|
||||
|
||||
```python
|
||||
class SocketFlowInstance:
|
||||
def embeddings(self, texts: list[str], **kwargs: Any) -> list[list[list[float]]]:
|
||||
"""
|
||||
Get embeddings for one or more texts via WebSocket.
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
|
||||
Returns:
|
||||
List of vector sets, one per input text
|
||||
"""
|
||||
request = {"texts": texts}
|
||||
response = self.client._send_request_sync(
|
||||
"embeddings", self.flow_id, request, False
|
||||
)
|
||||
return response["vectors"]
|
||||
```
|
||||
|
||||
**أمثلة على استخدام الـ SDK:**
|
||||
|
||||
```python
|
||||
# Single text
|
||||
vectors = flow.embeddings(["hello world"])
|
||||
print(f"Dimensions: {len(vectors[0][0])}")
|
||||
|
||||
# Batch embedding
|
||||
texts = ["text one", "text two", "text three"]
|
||||
all_vectors = flow.embeddings(texts)
|
||||
|
||||
# Process results
|
||||
for text, vecs in zip(texts, all_vectors):
|
||||
print(f"{text}: {len(vecs[0])} dimensions")
|
||||
```
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
**حدود حجم الطلب**: فرض الحد الأقصى لحجم الدفعة لمنع استنزاف الموارد.
|
||||
**معالجة انتهاء المهلة**: قم بتعيين قيم انتهاء المهلة بشكل مناسب لحجم الدفعة.
|
||||
**حدود الذاكرة**: راقب استخدام الذاكرة للدفعات الكبيرة.
|
||||
**التحقق من صحة الإدخال**: تحقق من صحة جميع النصوص في الدفعة قبل المعالجة.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
### التحسينات المتوقعة
|
||||
|
||||
**معدل الإنتاجية:**
|
||||
نص واحد: ~10-50 نصًا/ثانية (حسب النموذج)
|
||||
دفعة (حجم 32): ~200-500 نص/ثانية (تحسين بمقدار 5-10 مرات)
|
||||
|
||||
**زمن الوصول لكل نص:**
|
||||
نص واحد: 50-200 مللي ثانية لكل نص
|
||||
دفعة (حجم 32): 5-20 مللي ثانية لكل نص (متوسط)
|
||||
|
||||
**التحسينات الخاصة بالخدمة:**
|
||||
|
||||
| الخدمة | الحالي | الدفعات | التحسين |
|
||||
|---------|---------|---------|-------------|
|
||||
| تضمينات الرسم البياني (50 كيانًا) | 5-10 ثوانٍ | 0.5-1 ثانية | 5-10 مرات |
|
||||
| تضمينات الصفوف (100 نص) | 10-20 ثانية | 1-2 ثانية | 5-10 مرات |
|
||||
| استيعاب المستندات (1000 جزء) | 100-200 ثانية | 10-30 ثانية | 5-10 مرات |
|
||||
|
||||
### معلمات التكوين
|
||||
|
||||
```python
|
||||
# Recommended defaults
|
||||
DEFAULT_BATCH_SIZE = 32
|
||||
MAX_BATCH_SIZE = 128
|
||||
BATCH_TIMEOUT_MULTIPLIER = 2.0
|
||||
```
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبار الوحدات
|
||||
تضمين نص واحد (التوافق مع الإصدارات السابقة)
|
||||
معالجة الدُفعات الفارغة
|
||||
فرض الحد الأقصى لحجم الدفعة
|
||||
معالجة الأخطاء في حالة فشل بعض عناصر الدفعة
|
||||
|
||||
### اختبار التكامل
|
||||
تضمين الدُفعات من البداية إلى النهاية عبر Pulsar
|
||||
معالجة الدُفعات لخدمة تضمينات الرسم البياني
|
||||
معالجة الدُفعات لخدمة تضمينات الصفوف
|
||||
نقطة نهاية الدُفعات لبوابة واجهة برمجة التطبيقات
|
||||
|
||||
### اختبار الأداء
|
||||
قياس الإنتاجية الفردية مقابل الإنتاجية عند استخدام الدُفعات
|
||||
استخدام الذاكرة تحت أحجام دفعات مختلفة
|
||||
تحليل توزيع زمن الاستجابة
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
هذا إصدار يتضمن تغييرات جذرية. يتم تنفيذ جميع المراحل معًا.
|
||||
|
||||
### المرحلة الأولى: تغييرات المخطط
|
||||
استبدال `text: str` بـ `texts: list[str]` في EmbeddingsRequest
|
||||
تغيير نوع `vectors` إلى `list[list[list[float]]]` في EmbeddingsResponse
|
||||
|
||||
### المرحلة الثانية: تحديثات المعالج
|
||||
تحديث توقيع `on_embeddings` في معالجات FastEmbed و Ollama
|
||||
معالجة الدفعة بأكملها في استدعاء واحد للنموذج
|
||||
|
||||
### المرحلة الثالثة: تحديثات العميل
|
||||
تحديث `EmbeddingsClient.embed()` لقبول `texts: list[str]`
|
||||
|
||||
### المرحلة الرابعة: تحديثات المستخدم
|
||||
تحديث graph_embeddings لمعالجة سياقات الكيانات على شكل دفعات
|
||||
تحديث row_embeddings لمعالجة نصوص الفهرس على شكل دفعات
|
||||
تحديث document_embeddings لاستخدام المخطط الجديد
|
||||
تحديث أداة سطر الأوامر
|
||||
|
||||
### المرحلة الخامسة: بوابة واجهة برمجة التطبيقات
|
||||
تحديث نقطة نهاية تضمين للمخطط الجديد
|
||||
|
||||
### المرحلة السادسة: حزمة تطوير البرمجيات بلغة بايثون
|
||||
تحديث توقيع `FlowInstance.embeddings()`
|
||||
تحديث توقيع `SocketFlowInstance.embeddings()`
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
**معالجة الدُفعات الكبيرة جدًا**: هل يجب أن ندعم إرجاع النتائج على شكل دفعات صغيرة جدًا للدُفعات الكبيرة جدًا (أكثر من 100 نص)؟
|
||||
**القيود الخاصة بالمزودين**: كيف يجب أن نتعامل مع المزودين الذين لديهم أحجام دفعات قصوى مختلفة؟
|
||||
**معالجة حالات الفشل الجزئية**: إذا فشل أحد النصوص في الدفعة، فهل يجب أن نفشل الدفعة بأكملها أم أن نرجع النتائج الجزئية؟
|
||||
**تجميع تضمينات المستندات**: هل يجب أن نقوم بتجميع البيانات عبر رسائل Chunk متعددة أم أن نحافظ على المعالجة لكل رسالة؟
|
||||
|
||||
## المراجع
|
||||
|
||||
[وثائق FastEmbed](https://github.com/qdrant/fastembed)
|
||||
[واجهة برمجة تطبيقات Ollama Embeddings](https://github.com/ollama/ollama)
|
||||
[تنفيذ EmbeddingsService](trustgraph-base/trustgraph/base/embeddings_service.py)
|
||||
[تحسين أداء GraphRAG](graphrag-performance-optimization.md)
|
||||
268
docs/tech-specs/ar/entity-centric-graph.ar.md
Normal file
268
docs/tech-specs/ar/entity-centric-graph.ar.md
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
---
|
||||
layout: default
|
||||
title: "تخزين الرسم البياني المعرفي المرتكز على الكيانات على Cassandra"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# تخزين الرسم البياني المعرفي المرتكز على الكيانات على Cassandra
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يصف هذا المستند نموذج تخزين للرسوم البيانية المعرفية بنمط RDF على Apache Cassandra. يستخدم النموذج نهجًا **مرتكزًا على الكيانات** حيث يعرف كل كيان كل رباعية يشارك فيها والدور الذي يلعبه. هذا يحل محل نهج تبديل SPO متعدد الجداول باستخدام جدولين فقط.
|
||||
|
||||
## الخلفية والدوافع
|
||||
|
||||
### النهج التقليدي
|
||||
|
||||
يتطلب متجر رباعي RDF قياسي على Cassandra جداول متعددة غير طبيعية لتغطية أنماط الاستعلام - عادةً 6 جداول أو أكثر تمثل تبديلات مختلفة للموضوع والمسند والموضوع ومجموعة البيانات (SPOD). يتم كتابة كل رباعية في كل جدول، مما يؤدي إلى تضخيم كبير في عمليات الكتابة، والنفقات التشغيلية، وتعقيد المخطط.
|
||||
|
||||
بالإضافة إلى ذلك، يتطلب تحليل التسميات (جلب أسماء قابلة للقراءة للبشر للكيانات) استعلامات إضافية، وهو أمر مكلف بشكل خاص في حالات استخدام الذكاء الاصطناعي و GraphRAG حيث تعتبر التسميات ضرورية لسياق LLM.
|
||||
|
||||
### الرؤية المرتكزة على الكيانات
|
||||
|
||||
تتضمن كل رباعية `(D, S, P, O)` ما يصل إلى 4 كيانات. من خلال كتابة صف لكل مشاركة للكيان في الرباعية، نضمن أن **أي استعلام يحتوي على عنصر معروف واحد سيضرب مفتاح التقسيم**. يغطي هذا جميع أنماط الاستعلام الـ 16 باستخدام جدول بيانات واحد.
|
||||
|
||||
الفوائد الرئيسية:
|
||||
|
||||
**جدولان** بدلاً من 7 أو أكثر
|
||||
**4 عمليات كتابة لكل رباعية** بدلاً من 6 أو أكثر
|
||||
**تحليل التسميات مجانًا** - يتم تخزين تسميات الكيان مع علاقاته، مما يؤدي بشكل طبيعي إلى تسخين ذاكرة التخزين المؤقت للتطبيق
|
||||
**جميع أنماط الاستعلام الـ 16** يتم تقديمها من خلال قراءات ذات قسم واحد
|
||||
**عمليات أبسط** - جدول بيانات واحد للضبط والضغط والإصلاح
|
||||
|
||||
## المخطط
|
||||
|
||||
### الجدول 1: quads_by_entity
|
||||
|
||||
الجدول الرئيسي للبيانات. يحتوي كل كيان على قسم يحتوي على جميع الرباعيات التي يشارك فيها. تم تسميته ليعكس نمط الاستعلام (البحث حسب الكيان).
|
||||
|
||||
```sql
|
||||
CREATE TABLE quads_by_entity (
|
||||
collection text, -- Collection/tenant scope (always specified)
|
||||
entity text, -- The entity this row is about
|
||||
role text, -- 'S', 'P', 'O', 'G' — how this entity participates
|
||||
p text, -- Predicate of the quad
|
||||
otype text, -- 'U' (URI), 'L' (literal), 'T' (triple/reification)
|
||||
s text, -- Subject of the quad
|
||||
o text, -- Object of the quad
|
||||
d text, -- Dataset/graph of the quad
|
||||
dtype text, -- XSD datatype (when otype = 'L'), e.g. 'xsd:string'
|
||||
lang text, -- Language tag (when otype = 'L'), e.g. 'en', 'fr'
|
||||
PRIMARY KEY ((collection, entity), role, p, otype, s, o, d, dtype, lang)
|
||||
);
|
||||
```
|
||||
|
||||
**مفتاح التقسيم:** `(collection, entity)` - محدد للنطاق ضمن المجموعة، قسم واحد لكل كيان.
|
||||
|
||||
**المنطق وراء ترتيب أعمدة التجميع:**
|
||||
|
||||
1. **role** - معظم الاستعلامات تبدأ بـ "أين يقع هذا الكيان كموضوع/موضوع؟"
|
||||
2. **p** - المرشح الأكثر شيوعًا بعد ذلك، "أعطني جميع `knows` العلاقات".
|
||||
3. **otype** - يتيح التصفية حسب العلاقات ذات القيم المحددة بواسطة URI مقابل العلاقات ذات القيم الحرفية.
|
||||
4. **s, o, d** - الأعمدة المتبقية لضمان التفرد.
|
||||
5. **dtype, lang** - التمييز بين القيم الحرفية التي لها نفس القيمة ولكن بيانات تعريف نوع مختلفة (على سبيل المثال، `"thing"` مقابل `"thing"@en` مقابل `"thing"^^xsd:string`).
|
||||
|
||||
### الجدول 2: quads_by_collection
|
||||
|
||||
يدعم الاستعلامات والإجراءات الحذف على مستوى المجموعة. يوفر قائمة بجميع الرباعيات التي تنتمي إلى مجموعة. تم تسميته ليعكس نمط الاستعلام (البحث حسب المجموعة).
|
||||
|
||||
```sql
|
||||
CREATE TABLE quads_by_collection (
|
||||
collection text,
|
||||
d text, -- Dataset/graph of the quad
|
||||
s text, -- Subject of the quad
|
||||
p text, -- Predicate of the quad
|
||||
o text, -- Object of the quad
|
||||
otype text, -- 'U' (URI), 'L' (literal), 'T' (triple/reification)
|
||||
dtype text, -- XSD datatype (when otype = 'L')
|
||||
lang text, -- Language tag (when otype = 'L')
|
||||
PRIMARY KEY (collection, d, s, p, o, otype, dtype, lang)
|
||||
);
|
||||
```
|
||||
|
||||
يتم التجميع بناءً على مجموعة البيانات أولاً، مما يتيح الحذف على مستوى المجموعة أو مستوى مجموعة البيانات. يتم تضمين الأعمدة `otype` و `dtype` و `lang` في مفتاح التجميع للتمييز بين القيم الحرفية التي لها نفس القيمة ولكن بيانات تعريف نوع مختلفة - في RDF، `"thing"` و `"thing"@en` و `"thing"^^xsd:string` هي قيم متميزة دلاليًا.
|
||||
|
||||
## مسار الكتابة
|
||||
|
||||
لكل مجموعة رباعية `(D, S, P, O)` واردة ضمن مجموعة `C`، اكتب **4 صفوف** إلى `quads_by_entity` و **صف واحد** إلى `quads_by_collection`.
|
||||
|
||||
### مثال
|
||||
|
||||
بالنظر إلى المجموعة الرباعية في المجموعة `tenant1`:
|
||||
|
||||
```
|
||||
Dataset: https://example.org/graph1
|
||||
Subject: https://example.org/Alice
|
||||
Predicate: https://example.org/knows
|
||||
Object: https://example.org/Bob
|
||||
```
|
||||
|
||||
اكتب 4 صفوف إلى `quads_by_entity`:
|
||||
|
||||
| collection | entity | role | p | otype | s | o | d |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| tenant1 | https://example.org/graph1 | G | https://example.org/knows | U | https://example.org/Alice | https://example.org/Bob | https://example.org/graph1 |
|
||||
| tenant1 | https://example.org/Alice | S | https://example.org/knows | U | https://example.org/Alice | https://example.org/Bob | https://example.org/graph1 |
|
||||
| tenant1 | https://example.org/knows | P | https://example.org/knows | U | https://example.org/Alice | https://example.org/Bob | https://example.org/graph1 |
|
||||
| tenant1 | https://example.org/Bob | O | https://example.org/knows | U | https://example.org/Alice | https://example.org/Bob | https://example.org/graph1 |
|
||||
|
||||
اكتب صفًا واحدًا إلى `quads_by_collection`:
|
||||
|
||||
| collection | d | s | p | o | otype | dtype | lang |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| tenant1 | https://example.org/graph1 | https://example.org/Alice | https://example.org/knows | https://example.org/Bob | U | | |
|
||||
|
||||
### مثال حرفي
|
||||
|
||||
بالنسبة لثلاثية التسمية:
|
||||
|
||||
```
|
||||
Dataset: https://example.org/graph1
|
||||
Subject: https://example.org/Alice
|
||||
Predicate: http://www.w3.org/2000/01/rdf-schema#label
|
||||
Object: "Alice Smith" (lang: en)
|
||||
```
|
||||
|
||||
الرمز `otype` هو `'L'`، و `dtype` هو `'xsd:string'`، و `lang` هو `'en'`. يتم تخزين القيمة الحرفية `"Alice Smith"` في `o`. هناك حاجة إلى 3 صفوف فقط في `quads_by_entity` - لا يتم كتابة أي صف للقيمة الحرفية ككيان، نظرًا لأن القيم الحرفية ليست كيانات قابلة للاستعلام بشكل مستقل.
|
||||
|
||||
## أنماط الاستعلام
|
||||
|
||||
### جميع أنماط DSPO الـ 16
|
||||
|
||||
في الجدول أدناه، تعني عبارة "بادئة مثالية" أن الاستعلام يستخدم بادئة متجاورة لأعمدة التجميع. تعني عبارة "فحص التقسيم + التصفية" أن Cassandra تقرأ جزءًا من التقسيم وتقوم بالتصفية في الذاكرة - لا يزال فعالاً، ولكنه ليس تطابقًا خالصًا للبادئة.
|
||||
|
||||
| # | Known | Lookup entity | Clustering prefix | Efficiency |
|
||||
|---|---|---|---|---|
|
||||
| 1 | D,S,P,O | entity=S, role='S', p=P | تطابق كامل | بادئة مثالية |
|
||||
| 2 | D,S,P,? | entity=S, role='S', p=P | التصفية على D | فحص التقسيم + التصفية |
|
||||
| 3 | D,S,?,O | entity=S, role='S' | التصفية على D، O | فحص التقسيم + التصفية |
|
||||
| 4 | D,?,P,O | entity=O, role='O', p=P | التصفية على D | فحص التقسيم + التصفية |
|
||||
| 5 | ?,S,P,O | entity=S, role='S', p=P | التصفية على O | فحص التقسيم + التصفية |
|
||||
| 6 | D,S,?,? | entity=S, role='S' | التصفية على D | فحص التقسيم + التصفية |
|
||||
| 7 | D,?,P,? | entity=P, role='P' | التصفية على D | فحص التقسيم + التصفية |
|
||||
| 8 | D,?,?,O | entity=O, role='O' | التصفية على D | فحص التقسيم + التصفية |
|
||||
| 9 | ?,S,P,? | entity=S, role='S', p=P | — | **بادئة مثالية** |
|
||||
| 10 | ?,S,?,O | entity=S, role='S' | التصفية على O | فحص التقسيم + التصفية |
|
||||
| 11 | ?,?,P,O | entity=O, role='O', p=P | — | **بادئة مثالية** |
|
||||
| 12 | D,?,?,? | entity=D, role='G' | — | **بادئة مثالية** |
|
||||
| 13 | ?,S,?,? | entity=S, role='S' | — | **بادئة مثالية** |
|
||||
| 14 | ?,?,P,? | entity=P, role='P' | — | **بادئة مثالية** |
|
||||
| 15 | ?,?,?,O | entity=O, role='O' | — | **بادئة مثالية** |
|
||||
| 16 | ?,?,?,? | — | فحص كامل | استكشاف فقط |
|
||||
|
||||
**النتيجة الرئيسية:** 7 من أنماط الـ 15 غير التافهة هي تطابقات مثالية لبادئة التجميع. أما الـ 8 المتبقية فهي قراءات لتقسيم واحد مع تصفية داخل التقسيم. كل استعلام يحتوي على عنصر معروف واحد يطابق مفتاح التقسيم.
|
||||
|
||||
نمط 16 (?,?,?,?) لا يحدث في الممارسة العملية لأنه يتم دائمًا تحديد المجموعة، مما يقلله إلى النمط 12.
|
||||
|
||||
### أمثلة شائعة للاستعلام
|
||||
|
||||
**كل شيء عن كيان:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM quads_by_entity
|
||||
WHERE collection = 'tenant1' AND entity = 'https://example.org/Alice';
|
||||
```
|
||||
|
||||
**جميع العلاقات الخارجة لكيان:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM quads_by_entity
|
||||
WHERE collection = 'tenant1' AND entity = 'https://example.org/Alice'
|
||||
AND role = 'S';
|
||||
```
|
||||
|
||||
**شرط محدد لكيان:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM quads_by_entity
|
||||
WHERE collection = 'tenant1' AND entity = 'https://example.org/Alice'
|
||||
AND role = 'S' AND p = 'https://example.org/knows';
|
||||
```
|
||||
|
||||
**تسمية لكيان (بلغة محددة):**
|
||||
|
||||
```sql
|
||||
SELECT * FROM quads_by_entity
|
||||
WHERE collection = 'tenant1' AND entity = 'https://example.org/Alice'
|
||||
AND role = 'S' AND p = 'http://www.w3.org/2000/01/rdf-schema#label'
|
||||
AND otype = 'L';
|
||||
```
|
||||
|
||||
ثم قم بالتصفية باستخدام `lang = 'en'` من جانب التطبيق إذا لزم الأمر.
|
||||
|
||||
**فقط العلاقات التي تحمل قيمًا من نوع URI (روابط من كيان إلى كيان):**
|
||||
|
||||
```sql
|
||||
SELECT * FROM quads_by_entity
|
||||
WHERE collection = 'tenant1' AND entity = 'https://example.org/Alice'
|
||||
AND role = 'S' AND p = 'https://example.org/knows' AND otype = 'U';
|
||||
```
|
||||
|
||||
**البحث العكسي - ما الذي يشير إلى هذا الكيان:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM quads_by_entity
|
||||
WHERE collection = 'tenant1' AND entity = 'https://example.org/Bob'
|
||||
AND role = 'O';
|
||||
```
|
||||
|
||||
## حل التسميات وتدفئة ذاكرة التخزين المؤقت
|
||||
|
||||
أحد أهم مزايا النموذج المرتكز على الكيانات هو أن **يصبح حل التسميات تأثيرًا ثانويًا مجانيًا**.
|
||||
|
||||
في النموذج التقليدي متعدد الجداول، يتطلب استرداد التسميات استعلامات منفصلة: استرداد الثلاثيات، وتحديد معرفات الكيانات في النتائج، ثم استرداد `rdfs:label` لكل منها. هذا النمط N+1 مكلف.
|
||||
|
||||
في النموذج المرتكز على الكيانات، يُرجع الاستعلام عن كيان **جميع** رباعياته - بما في ذلك تسمياته وأنواعه وخصائصه الأخرى. عندما يقوم التطبيق بتخزين نتائج الاستعلام مؤقتًا، يتم تدفئة التسميات مسبقًا قبل أن يطلبها أي شيء.
|
||||
|
||||
يؤكد نظامان للاستخدام على أن هذا يعمل بشكل جيد في الممارسة:
|
||||
|
||||
**الاستعلامات الموجهة للمستخدم**: مجموعات نتائج صغيرة بشكل طبيعي، والتسميات ضرورية. يؤدي قراءة الكيانات إلى تدفئة ذاكرة التخزين المؤقت مسبقًا.
|
||||
**استعلامات الذكاء الاصطناعي/الكمية الكبيرة**: مجموعات نتائج كبيرة مع حدود صارمة. التسميات إما غير ضرورية أو مطلوبة فقط لمجموعة فرعية من الكيانات تم تخزينها بالفعل في ذاكرة التخزين المؤقت.
|
||||
|
||||
يتم تخفيف المخاوف النظرية المتعلقة بحل التسميات لمجموعات نتائج ضخمة (مثل 30000 كيان) بالملاحظة العملية القائلة بأنه لا يمكن لأي مستهلك بشري أو ذكاء اصطناعي معالجة هذا العدد الكبير من التسميات. تضمن حدود الاستعلام على مستوى التطبيق أن يظل ضغط ذاكرة التخزين المؤقت قابلاً للإدارة.
|
||||
|
||||
## التقسيمات العريضة وإعادة التعريف
|
||||
|
||||
يؤدي إعادة التعريف (عبارات على شكل RDF-star حول العبارات) إلى إنشاء كيانات مركزية - على سبيل المثال، مستند مصدر يدعم آلاف الحقائق المستخرجة. يمكن أن يؤدي هذا إلى تقسيمات عريضة.
|
||||
|
||||
عوامل تخفيف:
|
||||
|
||||
**حدود الاستعلام على مستوى التطبيق**: تفرض جميع استعلامات GraphRAG والاستعلامات الموجهة للمستخدم حدودًا صارمة، لذلك لا يتم فحص التقسيمات العريضة بالكامل على مسار القراءة الساخنة.
|
||||
**تتعامل Cassandra بكفاءة مع القراءات الجزئية**: يعد فحص عمود التجميع مع إيقاف مبكر أمرًا سريعًا حتى على التقسيمات الكبيرة.
|
||||
**حذف المجموعة** (العملية الوحيدة التي قد تتجاوز التقسيمات الكاملة) هي عملية خلفية مقبولة.
|
||||
|
||||
## حذف المجموعة
|
||||
|
||||
يتم تشغيله بواسطة استدعاء واجهة برمجة التطبيقات، ويعمل في الخلفية (متسق في النهاية).
|
||||
|
||||
1. اقرأ `quads_by_collection` للمجموعة المستهدفة للحصول على جميع الرباعيات.
|
||||
2. استخرج الكيانات الفريدة من الرباعيات (قيم s و p و o و d).
|
||||
3. لكل كيان فريد، احذف التقسيم من `quads_by_entity`.
|
||||
4. احذف الصفوف من `quads_by_collection`.
|
||||
|
||||
يوفر جدول `quads_by_collection` الفهرس المطلوب لتحديد موقع جميع تقسيمات الكيانات دون فحص كامل للجدول. عمليات حذف التقسيمات فعالة نظرًا لأن `(collection, entity)` هو مفتاح التقسيم.
|
||||
|
||||
## مسار الترحيل من النموذج متعدد الجداول
|
||||
|
||||
يمكن للنموذج المرتكز على الكيانات أن يتعايش مع النموذج متعدد الجداول الحالي أثناء الترحيل:
|
||||
|
||||
1. نشر جداول `quads_by_entity` و `quads_by_collection` جنبًا إلى جنب مع الجداول الحالية.
|
||||
2. الكتابة المزدوجة للرباعيات الجديدة إلى كل من الجداول القديمة والجديدة.
|
||||
3. ملء البيانات الموجودة في الجداول الجديدة.
|
||||
4. ترحيل مسارات القراءة نمط استعلام واحد في كل مرة.
|
||||
5. إلغاء تنشيط الجداول القديمة بمجرد ترحيل جميع عمليات القراءة.
|
||||
|
||||
## ملخص
|
||||
|
||||
| الجانب | تقليدي (6 جداول) | مرتكز على الكيانات (جدولان) |
|
||||
|---|---|---|
|
||||
| الجداول | 7+ | 2 |
|
||||
| عمليات الكتابة لكل رباعية | 6+ | 5 (4 بيانات + 1 بيان) |
|
||||
| حل التسميات | استعلامات منفصلة | مجاني عبر تدفئة ذاكرة التخزين المؤقت |
|
||||
| أنماط الاستعلام | 16 عبر 6 جداول | 16 على جدول واحد |
|
||||
| تعقيد المخطط | مرتفع | منخفض |
|
||||
| النفقات التشغيلية | 6 جداول للتعديل/الإصلاح | جدول بيانات واحد |
|
||||
| دعم إعادة التعريف | تعقيد إضافي | مناسب بشكل طبيعي |
|
||||
| تصفية أنواع الكائنات | غير متوفر | أصلي (عبر التجميع حسب نوع الكائن) |
|
||||
178
docs/tech-specs/ar/explainability-cli.ar.md
Normal file
178
docs/tech-specs/ar/explainability-cli.ar.md
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات سطر الأوامر لـ 'Explainability CLI'"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات سطر الأوامر لـ "Explainability CLI"
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## الحالة
|
||||
|
||||
مُقترح
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفة أدوات سطر الأوامر لتصحيح الأخطاء واستكشاف بيانات الشرح في TrustGraph. تسمح هذه الأدوات للمستخدمين بتتبع كيفية استخلاص الإجابات وتصحيح سلسلة الأصل من الحواف إلى المستندات المصدر.
|
||||
|
||||
ثلاث أدوات سطر أوامر:
|
||||
|
||||
1. **`tg-show-document-hierarchy`** - عرض تسلسل المستند → الصفحة → الجزء → الحافة
|
||||
2. **`tg-list-explain-traces`** - سرد جميع جلسات GraphRAG مع الأسئلة
|
||||
3. **`tg-show-explain-trace`** - عرض مسار الشرح الكامل لجلسة
|
||||
|
||||
## الأهداف
|
||||
|
||||
- **تصحيح الأخطاء**: تمكين المطورين من فحص نتائج معالجة المستندات
|
||||
- **قابلية التدقيق**: تتبع أي حقيقة مستخرجة إلى مستندها المصدر
|
||||
- **الشفافية**: إظهار بالضبط كيف اشتق GraphRAG إجابة
|
||||
- **سهولة الاستخدام**: واجهة سطر أوامر بسيطة مع قيم افتراضية معقولة
|
||||
|
||||
## الخلفية
|
||||
|
||||
يحتوي TrustGraph على نظامين لتعقب:
|
||||
|
||||
1. **تعقب وقت الاستخراج** (انظر `extraction-time-provenance.md`): يسجل علاقات المستند → الصفحة → الجزء → الحافة أثناء الاستيعاب. يتم تخزينها في رسم بياني يسمى `urn:graph:source` باستخدام `prov:wasDerivedFrom`.
|
||||
|
||||
2. **شرح قابل للتفسير في وقت الاستعلام** (انظر `query-time-explainability.md`): يسجل سلسلة السؤال → الاستكشاف → التركيز → التجميع أثناء استعلامات GraphRAG. يتم تخزينها في رسم بياني يسمى `urn:graph:retrieval`.
|
||||
|
||||
القيود الحالية:
|
||||
- لا توجد طريقة سهلة لتصور تسلسل المستند بعد المعالجة
|
||||
- يجب الاستعلام يدويًا عن المثلثات لعرض بيانات الشرح
|
||||
- لا يوجد عرض موحد لجلسة GraphRAG
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### الأداة 1: tg-show-document-hierarchy
|
||||
|
||||
**الغرض**: إعطاء معرف المستند، والتحرك وعرض جميع الكيانات المشتقة.
|
||||
|
||||
**الاستخدام**:
|
||||
```bash
|
||||
tg-show-document-hierarchy "urn:trustgraph:doc:abc123"
|
||||
tg-show-document-hierarchy --show-content --max-content 500 "urn:trustgraph:doc:abc123"
|
||||
```
|
||||
|
||||
**الوسائط**:
|
||||
| الوسيط | الوصف |
|
||||
|---|---|
|
||||
| `document_id` | URI للمستند (موضعي) |
|
||||
| `-u/--api-url` | عنوان URL لـ Gateway |
|
||||
| `-t/--token` | رمز المصادقة |
|
||||
| `-U/--user` | معرف المستخدم |
|
||||
| `-C/--collection` | المجموعة |
|
||||
| `--show-content` | تضم محتوى Blob/المستند |
|
||||
| `--max-content` | أقصى عدد من الأحرف في Blob (افتراضي: 200) |
|
||||
| `--format` | الإخراج: `tree` (افتراضي)، `json` |
|
||||
|
||||
**التنفيذ**:
|
||||
1. استعلام عن المثلثات: `?child prov:wasDerivedFrom <document_id>` في `urn:graph:source`
|
||||
2. استعلام بشكل متكرر عن الأطفال لكل نتيجة
|
||||
3. بناء بنية الشجرة: المستند → الصفحات → الأجزاء
|
||||
4. إذا كان `--show-content`، فقم باسترداد المحتوى من واجهة برمجة التطبيقات الخاصة بالمكتبة
|
||||
5. عرض كشجرة مسطحة أو JSON
|
||||
|
||||
**مثال على الإخراج**:
|
||||
```
|
||||
المستند: urn:trustgraph:doc:abc123
|
||||
العنوان: "Sample PDF"
|
||||
النوع: application/pdf
|
||||
|
||||
└── الصفحة 1: urn:trustgraph:doc:abc123/p1
|
||||
├── الجزء 0: urn:trustgraph:doc:abc123/p1/c0
|
||||
المحتوى: "The quick brown fox..." [مقتطف]
|
||||
└── الجزء 1: urn:trustgraph:doc:abc123/p1/c1
|
||||
المحتوى: "Machine learning is..." [مقتطف]
|
||||
```
|
||||
|
||||
### الأداة 2: tg-list-explain-traces
|
||||
|
||||
**الغرض**: سرد جميع جلسات GraphRAG (الأسئلة) في مجموعة.
|
||||
|
||||
**الاستخدام**:
|
||||
```bash
|
||||
tg-list-explain-traces
|
||||
tg-list-explain-traces --limit 20 --format json
|
||||
```
|
||||
|
||||
**الوسائط**:
|
||||
| الوسيط | الوصف |
|
||||
|---|---|
|
||||
| `-u/--api-url` | عنوان URL لـ Gateway |
|
||||
| `-t/--token` | رمز المصادقة |
|
||||
| `-U/--user` | معرف المستخدم |
|
||||
| `-C/--collection` | المجموعة |
|
||||
| `--limit` | أقصى عدد من النتائج (افتراضي: 50) |
|
||||
| `--format` | الإخراج: `table` (افتراضي)، `json` |
|
||||
|
||||
**التنفيذ**:
|
||||
1. استعلام: `?session tg:query ?text` في `urn:graph:retrieval`
|
||||
2. استعلام عن الطوابع الزمنية: `?session prov:startedAtTime ?time`
|
||||
3. عرض كجدول
|
||||
|
||||
**مثال على الإخراج**:
|
||||
```
|
||||
معرف الجلسة | السؤال | الوقت
|
||||
----------------------------------------------|--------------------------------|---------------------
|
||||
urn:trustgraph:question:abc123 | What was the War on Terror? | 2024-01-15 10:30:00
|
||||
urn:trustgraph:question:def456 | Who founded OpenAI? | 2024-01-15 09:15:00
|
||||
```
|
||||
|
||||
### الأداة 3: tg-show-explain-trace
|
||||
|
||||
**الغرض**: عرض مسار الشرح الكامل لجلسة GraphRAG.
|
||||
|
||||
**الاستخدام**:
|
||||
```bash
|
||||
tg-show-explain-trace "urn:trustgraph:question:abc123"
|
||||
tg-show-explain-trace --max-answer 1000 --show-provenance "urn:trustgraph:question:abc123"
|
||||
```
|
||||
|
||||
**الوسائط**:
|
||||
| الوسيط | الوصف |
|
||||
|---|---|
|
||||
| `question_id` | معرف السؤال (موضعي) |
|
||||
| `-u/--api-url` | عنوان URL لـ Gateway |
|
||||
| `-t/--token` | رمز المصادقة |
|
||||
| `-U/--user` | معرف المستخدم |
|
||||
| `-C/--collection` | المجموعة |
|
||||
| `--max-answer` | أقصى عدد من الأحرف للإجابة (افتراضي: 500) |
|
||||
| `--show-provenance` | تتبع الحواف إلى المستندات المصدر |
|
||||
| `--format` | الإخراج: `text` (افتراضي)، `json` |
|
||||
|
||||
**التنفيذ**:
|
||||
1. الحصول على نص السؤال من البُعد `tg:query`
|
||||
2. العثور على الاستكشاف: `?exp prov:wasGeneratedBy <question_id>`
|
||||
3. العثور على التركيز: `?focus prov:wasDerivedFrom <exploration_id>`
|
||||
4. الحصول على الحواف المحددة: `<focus_id> tg:selectedEdge ?edge`
|
||||
5. لكل حافة، الحصول على `tg:edge` (سلسلة RDF) و `tg:reasoning`
|
||||
6. العثور على التجميع: `?synth prov:wasDerivedFrom <focus_id>`
|
||||
7. الحصول على الإجابة من `tg:document` عبر واجهة برمجة التطبيقات
|
||||
8. إذا كان `--show-provenance`، فقم بتتبع الحواف إلى المستندات المصدر
|
||||
|
||||
**مثال على الإخراج**:
|
||||
```
|
||||
=== جلسة GraphRAG: urn:trustgraph:question:abc123 ===
|
||||
|
||||
السؤال: What was the War on Terror?
|
||||
الوقت: 2024-01-15 10:30:00
|
||||
|
||||
الإجابة: [إجابة]
|
||||
|
||||
مسار الشرح:
|
||||
- السؤال: What was the War on Terror?
|
||||
- استخراج: [ملف]
|
||||
- تجميع: [إطار عمل]
|
||||
- استجابة: [إجابة]
|
||||
- السؤال: What was the War on Terror?
|
||||
- استخراج: [ملف]
|
||||
- تجميع: [إطار عمل]
|
||||
- استجابة: [إجابة]
|
||||
```
|
||||
|
||||
## المراجع
|
||||
|
||||
- شرح قابل للتفسير: `docs/tech-specs/query-time-explainability.md`
|
||||
- تتبع وقت الاستخراج: `docs/tech-specs/extraction-time-provenance.md`
|
||||
- مثال سطر الأوامر: `trustgraph-cli/trustgraph/cli/invoke_graph_rag.py`
|
||||
355
docs/tech-specs/ar/extraction-flows.ar.md
Normal file
355
docs/tech-specs/ar/extraction-flows.ar.md
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
---
|
||||
layout: default
|
||||
title: "تدفقات الاستخراج"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# تدفقات الاستخراج
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
يصف هذا المستند كيفية تدفق البيانات عبر مسار الاستخراج الخاص بـ TrustGraph، بدءًا من تقديم المستندات وصولًا إلى تخزينها في مستودعات المعرفة.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
```
|
||||
┌──────────┐ ┌─────────────┐ ┌─────────┐ ┌────────────────────┐
|
||||
│ Librarian│────▶│ PDF Decoder │────▶│ Chunker │────▶│ Knowledge │
|
||||
│ │ │ (PDF only) │ │ │ │ Extraction │
|
||||
│ │────────────────────────▶│ │ │ │
|
||||
└──────────┘ └─────────────┘ └─────────┘ └────────────────────┘
|
||||
│ │
|
||||
│ ├──▶ Triples
|
||||
│ ├──▶ Entity Contexts
|
||||
│ └──▶ Rows
|
||||
│
|
||||
└──▶ Document Embeddings
|
||||
```
|
||||
|
||||
## تخزين المحتوى
|
||||
|
||||
### تخزين الكائنات (S3/Minio)
|
||||
|
||||
يتم تخزين محتوى المستندات في تخزين الكائنات المتوافق مع S3:
|
||||
تنسيق المسار: `doc/{object_id}` حيث object_id هو معرف فريد عالمي (UUID)
|
||||
يتم تخزين جميع أنواع المستندات هنا: المستندات المصدر، الصفحات، الأجزاء
|
||||
|
||||
### تخزين البيانات الوصفية (Cassandra)
|
||||
|
||||
يتم تخزين البيانات الوصفية للمستندات في Cassandra وتشمل:
|
||||
معرف المستند، العنوان، النوع (نوع MIME)
|
||||
مرجع إلى تخزين الكائنات `object_id`
|
||||
مرجع إلى المستندات الفرعية (الصفحات، الأجزاء) `parent_id`
|
||||
`document_type`: "source"، "page"، "chunk"، "answer"
|
||||
|
||||
### عتبة التضمين مقابل التدفق
|
||||
|
||||
نقل المحتوى يستخدم استراتيجية تعتمد على الحجم:
|
||||
**أقل من 2 ميجابايت**: يتم تضمين المحتوى مباشرة في الرسالة (مشفر بـ base64).
|
||||
**أكبر من أو يساوي 2 ميجابايت**: يتم إرسال `document_id` فقط؛ يقوم المعالج باسترداد البيانات عبر واجهة برمجة التطبيقات الخاصة بالمكتبة.
|
||||
|
||||
## المرحلة الأولى: تقديم المستند (المكتبة)
|
||||
|
||||
### نقطة الدخول
|
||||
|
||||
تدخل المستندات إلى النظام عبر عملية `add-document` الخاصة بالمكتبة:
|
||||
1. يتم تحميل المحتوى إلى مساحة تخزين الكائنات.
|
||||
2. يتم إنشاء سجل بيانات وصفية في Cassandra.
|
||||
3. يتم إرجاع معرف المستند.
|
||||
|
||||
### بدء عملية الاستخراج
|
||||
|
||||
عملية `add-processing` تبدأ عملية الاستخراج:
|
||||
تحدد `document_id`، و `flow` (معرف المسار)، و `collection` (مخزن الهدف).
|
||||
تقوم عملية `load_document()` الخاصة بالمكتبة باسترداد المحتوى ونشره في قائمة انتظار الإدخال الخاصة بالتدفق.
|
||||
|
||||
### المخطط: المستند
|
||||
|
||||
```
|
||||
Document
|
||||
├── metadata: Metadata
|
||||
│ ├── id: str # Document identifier
|
||||
│ ├── user: str # Tenant/user ID
|
||||
│ ├── collection: str # Target collection
|
||||
│ └── metadata: list[Triple] # (largely unused, historical)
|
||||
├── data: bytes # PDF content (base64, if inline)
|
||||
└── document_id: str # Librarian reference (if streaming)
|
||||
```
|
||||
|
||||
**التوجيه:** بناءً على الحقل `kind`:
|
||||
`application/pdf` → قائمة انتظار `document-load` → وحدة فك ترميز PDF
|
||||
`text/plain` → قائمة انتظار `text-load` → وحدة تقسيم
|
||||
|
||||
## المرحلة الثانية: وحدة فك ترميز PDF
|
||||
|
||||
تحويل مستندات PDF إلى صفحات نصية.
|
||||
|
||||
### العملية
|
||||
|
||||
1. استرجاع المحتوى (مضمن في `data` أو عبر `document_id` من أمين المكتبة)
|
||||
2. استخراج الصفحات باستخدام PyPDF
|
||||
3. لكل صفحة:
|
||||
حفظ كـ مستند فرعي في أمين المكتبة (`{doc_id}/p{page_num}`)
|
||||
إرسال ثلاثيات المصدر (الصفحة مشتقة من المستند)
|
||||
توجيه إلى وحدة التقسيم
|
||||
|
||||
### المخطط: TextDocument
|
||||
|
||||
```
|
||||
TextDocument
|
||||
├── metadata: Metadata
|
||||
│ ├── id: str # Page URI (e.g., https://trustgraph.ai/doc/xxx/p1)
|
||||
│ ├── user: str
|
||||
│ ├── collection: str
|
||||
│ └── metadata: list[Triple]
|
||||
├── text: bytes # Page text content (if inline)
|
||||
└── document_id: str # Librarian reference (e.g., "doc123/p1")
|
||||
```
|
||||
|
||||
## المرحلة الثالثة: تقسيم النص إلى أجزاء
|
||||
|
||||
يقسم النص إلى أجزاء عند الحجم المحدد.
|
||||
|
||||
### المعلمات (قابلة للتكوين من خلال التدفق)
|
||||
|
||||
`chunk_size`: الحجم المستهدف للجزء الواحد بالأحرف (الافتراضي: 2000)
|
||||
`chunk_overlap`: التداخل بين الأجزاء (الافتراضي: 100)
|
||||
|
||||
### العملية
|
||||
|
||||
1. استرجاع محتوى النص (مباشرة أو عبر أمين المكتبة)
|
||||
2. التقسيم باستخدام مقسم الأحرف التكراري
|
||||
3. لكل جزء:
|
||||
حفظ كوثيقة فرعية في أمين المكتبة (`{parent_id}/c{index}`)
|
||||
إرسال بيانات المصدر (الجزء مشتق من صفحة/مستند)
|
||||
توجيه إلى معالجات الاستخراج
|
||||
|
||||
### المخطط: جزء
|
||||
|
||||
```
|
||||
Chunk
|
||||
├── metadata: Metadata
|
||||
│ ├── id: str # Chunk URI
|
||||
│ ├── user: str
|
||||
│ ├── collection: str
|
||||
│ └── metadata: list[Triple]
|
||||
├── chunk: bytes # Chunk text content
|
||||
└── document_id: str # Librarian chunk ID (e.g., "doc123/p1/c3")
|
||||
```
|
||||
|
||||
### التسلسل الهرمي لمعرف المستند
|
||||
|
||||
تقوم المستندات الفرعية بتشفير أصلها في المعرف:
|
||||
المصدر: `doc123`
|
||||
الصفحة: `doc123/p5`
|
||||
جزء من الصفحة: `doc123/p5/c2`
|
||||
جزء من النص: `doc123/c2`
|
||||
|
||||
## المرحلة 4: استخراج المعرفة
|
||||
|
||||
تتوفر أنماط استخراج متعددة، يتم اختيارها بواسطة إعدادات التدفق.
|
||||
|
||||
### النمط أ: GraphRAG الأساسي
|
||||
|
||||
معالجتان متوازيتان:
|
||||
|
||||
**kg-extract-definitions**
|
||||
المدخلات: جزء
|
||||
المخرجات: ثلاثيات (تعريفات الكيانات)، سياقات الكيانات
|
||||
يستخرج: تسميات الكيانات، التعريفات
|
||||
|
||||
**kg-extract-relationships**
|
||||
المدخلات: جزء
|
||||
المخرجات: ثلاثيات (علاقات)، سياقات الكيانات
|
||||
يستخرج: علاقات الفاعل-الفعل-المفعول
|
||||
|
||||
### النمط ب: مدفوع بالدلالات (kg-extract-ontology)
|
||||
|
||||
المدخلات: جزء
|
||||
المخرجات: ثلاثيات، سياقات الكيانات
|
||||
يستخدم دلالات مُكوّنة لتوجيه الاستخراج
|
||||
|
||||
### النمط ج: قائم على الوكيل (kg-extract-agent)
|
||||
|
||||
المدخلات: جزء
|
||||
المخرجات: ثلاثيات، سياقات الكيانات
|
||||
يستخدم إطار عمل الوكيل للاستخراج
|
||||
|
||||
### النمط د: استخراج الصفوف (kg-extract-rows)
|
||||
|
||||
المدخلات: جزء
|
||||
المخرجات: صفوف (بيانات منظمة، وليست ثلاثيات)
|
||||
يستخدم تعريف المخطط لاستخراج سجلات منظمة
|
||||
|
||||
### المخطط: ثلاثيات
|
||||
|
||||
```
|
||||
Triples
|
||||
├── metadata: Metadata
|
||||
│ ├── id: str
|
||||
│ ├── user: str
|
||||
│ ├── collection: str
|
||||
│ └── metadata: list[Triple] # (set to [] by extractors)
|
||||
└── triples: list[Triple]
|
||||
└── Triple
|
||||
├── s: Term # Subject
|
||||
├── p: Term # Predicate
|
||||
├── o: Term # Object
|
||||
└── g: str | None # Named graph
|
||||
```
|
||||
|
||||
### المخطط: سياقات الكيانات
|
||||
|
||||
```
|
||||
EntityContexts
|
||||
├── metadata: Metadata
|
||||
└── entities: list[EntityContext]
|
||||
└── EntityContext
|
||||
├── entity: Term # Entity identifier (IRI)
|
||||
├── context: str # Textual description for embedding
|
||||
└── chunk_id: str # Source chunk ID (provenance)
|
||||
```
|
||||
|
||||
### المخطط: الصفوف
|
||||
|
||||
```
|
||||
Rows
|
||||
├── metadata: Metadata
|
||||
├── row_schema: RowSchema
|
||||
│ ├── name: str
|
||||
│ ├── description: str
|
||||
│ └── fields: list[Field]
|
||||
└── rows: list[dict[str, str]] # Extracted records
|
||||
```
|
||||
|
||||
## المرحلة الخامسة: توليد التضمينات
|
||||
|
||||
### تضمينات الرسم البياني
|
||||
|
||||
تحويل سياقات الكيانات إلى تضمينات متجهة.
|
||||
|
||||
**العملية:**
|
||||
1. استقبال سياقات الكيانات.
|
||||
2. استدعاء خدمة التضمينات مع نص السياق.
|
||||
3. إخراج تضمينات الرسم البياني (ت mapping بين الكيان والمتجه).
|
||||
|
||||
**النموذج: تضمينات الرسم البياني**
|
||||
|
||||
```
|
||||
GraphEmbeddings
|
||||
├── metadata: Metadata
|
||||
└── entities: list[EntityEmbeddings]
|
||||
└── EntityEmbeddings
|
||||
├── entity: Term # Entity identifier
|
||||
├── vector: list[float] # Embedding vector
|
||||
└── chunk_id: str # Source chunk (provenance)
|
||||
```
|
||||
|
||||
### تضمينات المستندات
|
||||
|
||||
يحول النص المقسم مباشرةً إلى تضمينات متجهة.
|
||||
|
||||
**العملية:**
|
||||
1. استقبال الجزء
|
||||
2. استدعاء خدمة التضمينات باستخدام نص الجزء
|
||||
3. إخراج تضمينات المستندات
|
||||
|
||||
**التركيب: تضمينات المستندات**
|
||||
|
||||
```
|
||||
DocumentEmbeddings
|
||||
├── metadata: Metadata
|
||||
└── chunks: list[ChunkEmbeddings]
|
||||
└── ChunkEmbeddings
|
||||
├── chunk_id: str # Chunk identifier
|
||||
└── vector: list[float] # Embedding vector
|
||||
```
|
||||
|
||||
### تضمينات الصفوف
|
||||
|
||||
تحويل حقول فهرس الصف إلى تضمينات متجهة.
|
||||
|
||||
**العملية:**
|
||||
1. استقبال الصفوف
|
||||
2. تضمين حقول الفهرس المحددة
|
||||
3. الإخراج إلى مخزن المتجهات الصفية
|
||||
|
||||
## المرحلة 6: التخزين
|
||||
|
||||
### مخزن ثلاثي
|
||||
|
||||
يستقبل: ثلاثيات
|
||||
التخزين: Cassandra (جداول تركز على الكيانات)
|
||||
الرسوم البيانية المسماة تفصل المعرفة الأساسية عن المصادر:
|
||||
`""` (افتراضي): حقائق المعرفة الأساسية
|
||||
`urn:graph:source`: تتبع المصادر
|
||||
`urn:graph:retrieval`: إمكانية الشرح في وقت الاستعلام
|
||||
|
||||
### مخزن المتجهات (تضمينات الرسم البياني)
|
||||
|
||||
يستقبل: تضمينات الرسم البياني
|
||||
التخزين: Qdrant، Milvus، أو Pinecone
|
||||
مفهرس بواسطة: IRI الكيان
|
||||
البيانات الوصفية: chunk_id لتتبع المصادر
|
||||
|
||||
### مخزن المتجهات (تضمينات المستندات)
|
||||
|
||||
يستقبل: تضمينات المستندات
|
||||
التخزين: Qdrant، Milvus، أو Pinecone
|
||||
مفهرس بواسطة: chunk_id
|
||||
|
||||
### مخزن الصفوف
|
||||
|
||||
يستقبل: صفوف
|
||||
التخزين: Cassandra
|
||||
هيكل الجدول الموجه بالمخطط
|
||||
|
||||
### مخزن المتجهات الصفية
|
||||
|
||||
يستقبل: تضمينات الصفوف
|
||||
التخزين: قاعدة بيانات المتجهات
|
||||
مفهرس بواسطة: حقول فهرس الصف
|
||||
|
||||
## تحليل حقول البيانات الوصفية
|
||||
|
||||
### الحقول المستخدمة بنشاط
|
||||
|
||||
| الحقل | الاستخدام |
|
||||
|-------|-------|
|
||||
| `metadata.id` | معرف المستند/الكتلة، التسجيل، تتبع المصادر |
|
||||
| `metadata.user` | تعدد المستأجرين، توجيه التخزين |
|
||||
| `metadata.collection` | اختيار المجموعة المستهدفة |
|
||||
| `document_id` | مرجع أمين المكتبة، ربط تتبع المصادر |
|
||||
| `chunk_id` | تتبع المصادر عبر مسار العمل |
|
||||
|
||||
<<<<<<< HEAD
|
||||
### الحقول التي قد تكون زائدة عن الحاجة
|
||||
|
||||
| الحقل | الحالة |
|
||||
|-------|--------|
|
||||
| `metadata.metadata` | يتم تعيينه على `[]` بواسطة جميع المستخرجات؛ يتم التعامل مع بيانات وصفية على مستوى المستند الآن بواسطة أمين المكتبة في وقت الإرسال |
|
||||
=======
|
||||
### الحقول التي تمت إزالتها
|
||||
|
||||
| الحقل | الحالة |
|
||||
|-------|--------|
|
||||
| `metadata.metadata` | تمت إزالته من الفئة `Metadata`. يتم الآن إرسال ثلاثيات البيانات الوصفية على مستوى المستند مباشرةً بواسطة أمين المكتبة إلى مخزن الثلاثيات في وقت الإرسال، ولا يتم نقلها عبر مسار العمل. |
|
||||
>>>>>>> e3bcbf73 (قائمة البيانات الوصفية (الثلاثيات) في فئة مسار العمل Metadata)
|
||||
|
||||
### نمط حقول البايت
|
||||
|
||||
جميع حقول المحتوى (`data`، `text`، `chunk`) هي `bytes` ولكن يتم فك ترميزها على الفور إلى سلاسل UTF-8 بواسطة جميع المعالجات. لا يستخدم أي معالج بايت خام.
|
||||
|
||||
## تكوين التدفق
|
||||
|
||||
يتم تعريف التدفقات خارجيًا وتقديمها إلى أمين المكتبة عبر خدمة التكوين. يحدد كل تدفق:
|
||||
|
||||
قوائم انتظار الإدخال (`text-load`، `document-load`)
|
||||
سلسلة المعالجات
|
||||
المعلمات (حجم الكتلة، طريقة الاستخراج، إلخ.)
|
||||
|
||||
أمثلة على أنماط التدفق:
|
||||
`pdf-graphrag`: PDF → Decoder → Chunker → Definitions + Relationships → Embeddings
|
||||
`text-graphrag`: Text → Chunker → Definitions + Relationships → Embeddings
|
||||
`pdf-ontology`: PDF → Decoder → Chunker → Ontology Extraction → Embeddings
|
||||
`text-rows`: Text → Chunker → Row Extraction → Row Store
|
||||
265
docs/tech-specs/ar/extraction-provenance-subgraph.ar.md
Normal file
265
docs/tech-specs/ar/extraction-provenance-subgraph.ar.md
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
---
|
||||
layout: default
|
||||
title: "أصل الاستخراج: نموذج الرسم البياني الفرعي"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
<<<<<<< HEAD
|
||||
# أصل الاستخراج: نموذج الرسم البياني الفرعي
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## المشكلة
|
||||
|
||||
حاليًا، يقوم تتبع أصل الاستخراج بإنشاء تجسيد كامل لكل ثلاثية مستخرجة:
|
||||
معرف فريد `stmt_uri`، و `activity_uri`، وبيانات وصفية PROV-O مرتبطة
|
||||
لكل حقيقة معرفية. يؤدي معالجة جزء واحد ينتج عنه 20 علاقة إلى إنتاج حوالي 220 ثلاثية لتتبع الأصل بالإضافة إلى
|
||||
حوالي 20 ثلاثية معرفية - وهو عبء إضافي يقدر بحوالي 10:1.
|
||||
|
||||
=======
|
||||
# المصدر: نموذج الرسم البياني الفرعي.
|
||||
|
||||
## المشكلة
|
||||
|
||||
في الوقت الحالي، تقوم عملية تتبع مصدر البيانات في وقت الاستخراج بإنشاء تجسيد كامل لكل
|
||||
ثلاثية مستخرجة: معرف فريد `stmt_uri`، و `activity_uri`، والبيانات الوصفية المرتبطة بـ PROV-O لكل حقيقة معرفية. معالجة جزء واحد
|
||||
...
|
||||
والتي تؤدي إلى 20 علاقة، تنتج حوالي 220 ثلاثية بيانات أصلية بالإضافة إلى
|
||||
حوالي 20 ثلاثية معرفة - وهو عبء إضافي يقدر بحوالي 10:1.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
هذا مكلف للغاية (من حيث التخزين والفهرسة والنقل) وغير دقيق من الناحية الدلالية.
|
||||
تتم معالجة كل جزء بواسطة استدعاء واحد لنموذج اللغة الكبير (LLM) ينتج
|
||||
جميع الثلاثيات الخاصة به في معاملة واحدة.
|
||||
يخفي النموذج الحالي لكل ثلاثية ذلك من خلال خلق وهم بوجود 20 عملية استخراج
|
||||
مستقلة.
|
||||
|
||||
بالإضافة إلى ذلك، لا توجد أي معلومات عن مصدرين من أصل أربعة معالجات للاستخراج (kg-extract-ontology،
|
||||
kg-extract-agent)، مما يترك فجوات في مسار التدقيق.
|
||||
|
||||
|
||||
## الحل
|
||||
|
||||
<<<<<<< HEAD
|
||||
استبدال عملية التجسيد لكل ثلاثية بنموذج **رسم بياني فرعي**: سجل واحد للبيانات الوصفية لكل جزء مستخرج، ويتم مشاركته عبر جميع الثلاثيات الناتجة عن هذا الجزء.
|
||||
=======
|
||||
استبدل عملية التجسيد لكل ثلاثية بنموذج **رسم بياني فرعي**: سجل واحد للبيانات الوصفية لكل جزء مستخرج، ويتم مشاركته عبر جميع الثلاثيات الناتجة عن هذا الجزء.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
|
||||
|
||||
### تغيير في المصطلحات
|
||||
|
||||
| القديم | الجديد |
|
||||
|-----|-----|
|
||||
| `stmt_uri` (`https://trustgraph.ai/stmt/{uuid}`) | `subgraph_uri` (`https://trustgraph.ai/subgraph/{uuid}`) |
|
||||
| `statement_uri()` | `subgraph_uri()` |
|
||||
<<<<<<< HEAD
|
||||
| `tg:reifies` (1:1، تطابق) | `tg:contains` (1:كثير، احتواء) |
|
||||
=======
|
||||
| `tg:reifies` (1:1، تطابق) | `tg:contains` (1:متعدد، احتواء) |
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### الهيكل المستهدف
|
||||
|
||||
يجب أن تضاف جميع الثلاثيات المتعلقة بأصل البيانات إلى الرسم البياني المسمى `urn:graph:source`.
|
||||
|
||||
```
|
||||
# Subgraph contains each extracted triple (RDF-star quoted triples)
|
||||
<subgraph> tg:contains <<s1 p1 o1>> .
|
||||
<subgraph> tg:contains <<s2 p2 o2>> .
|
||||
<subgraph> tg:contains <<s3 p3 o3>> .
|
||||
|
||||
# Derivation from source chunk
|
||||
<subgraph> prov:wasDerivedFrom <chunk_uri> .
|
||||
<subgraph> prov:wasGeneratedBy <activity> .
|
||||
|
||||
# Activity: one per chunk extraction
|
||||
<activity> rdf:type prov:Activity .
|
||||
<activity> rdfs:label "{component_name} extraction" .
|
||||
<activity> prov:used <chunk_uri> .
|
||||
<activity> prov:wasAssociatedWith <agent> .
|
||||
<activity> prov:startedAtTime "2026-03-13T10:00:00Z" .
|
||||
<activity> tg:componentVersion "0.25.0" .
|
||||
<activity> tg:llmModel "gpt-4" . # if available
|
||||
<activity> tg:ontology <ontology_uri> . # if available
|
||||
|
||||
# Agent: stable per component
|
||||
<agent> rdf:type prov:Agent .
|
||||
<agent> rdfs:label "{component_name}" .
|
||||
```
|
||||
|
||||
### مقارنة الحجم
|
||||
|
||||
لكل جزء ينتج عنه N من الثلاثيات المستخرجة:
|
||||
|
||||
| | القديم (لكل ثلاثية) | الجديد (الرسم البياني الفرعي) |
|
||||
|---|---|---|
|
||||
| `tg:contains` / `tg:reifies` | N | N |
|
||||
| ثلاثيات النشاط | ~9 × N | ~9 |
|
||||
| ثلاثيات الوكيل | 2 × N | 2 |
|
||||
| بيانات التعريف/الرسم البياني الفرعي | 2 × N | 2 |
|
||||
| **إجمالي ثلاثيات التتبع** | **~13N** | **N + 13** |
|
||||
| **مثال (N=20)** | **~260** | **33** |
|
||||
|
||||
## النطاق
|
||||
|
||||
### المعالجات التي سيتم تحديثها (التتبع الحالي، لكل ثلاثية)
|
||||
|
||||
**kg-extract-definitions**
|
||||
(`trustgraph-flow/trustgraph/extract/kg/definitions/extract.py`)
|
||||
|
||||
حاليًا، تستدعي `statement_uri()` + `triple_provenance_triples()` داخل
|
||||
حلقة التعريف لكل عنصر.
|
||||
|
||||
التغييرات:
|
||||
نقل إنشاء `subgraph_uri()` و `activity_uri()` قبل الحلقة
|
||||
جمع ثلاثيات `tg:contains` داخل الحلقة
|
||||
إخراج كتلة النشاط/الوكيل/الاشتقاق المشتركة مرة واحدة بعد الحلقة
|
||||
|
||||
**kg-extract-relationships**
|
||||
(`trustgraph-flow/trustgraph/extract/kg/relationships/extract.py`)
|
||||
|
||||
نفس النمط مثل التعريفات. نفس التغييرات.
|
||||
|
||||
<<<<<<< HEAD
|
||||
### المعالجات التي يجب إضافتها للتتبع (مفقودة حاليًا)
|
||||
=======
|
||||
### المعالجات التي سيتم إضافة التتبع إليها (مفقودة حاليًا)
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**kg-extract-ontology**
|
||||
(`trustgraph-flow/trustgraph/extract/kg/ontology/extract.py`)
|
||||
|
||||
<<<<<<< HEAD
|
||||
حاليًا، يقوم بإخراج ثلاثيات بدون مصدر. أضف مصدر الرسم البياني الفرعي.
|
||||
=======
|
||||
حاليًا، يقوم بإخراج ثلاثيات بدون مصدر. أضف مصدر الرسوم البيانية الفرعية.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
باستخدام نفس النمط: رسم بياني فرعي واحد لكل جزء، `tg:contains` لكل
|
||||
ثلاثية مستخرجة.
|
||||
|
||||
**kg-extract-agent**
|
||||
(`trustgraph-flow/trustgraph/extract/kg/agent/extract.py`)
|
||||
|
||||
<<<<<<< HEAD
|
||||
حاليًا، يقوم بإخراج ثلاثيات بدون مصدر. أضف مصدر الرسم البياني الفرعي
|
||||
=======
|
||||
حاليًا، يقوم بإخراج ثلاثيات بدون مصدر. أضف مصدر الرسوم البيانية الفرعية
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
باستخدام نفس النمط.
|
||||
|
||||
### تغييرات في مكتبة المصادر المشتركة
|
||||
|
||||
**`trustgraph-base/trustgraph/provenance/triples.py`**
|
||||
|
||||
استبدل `triple_provenance_triples()` بـ `subgraph_provenance_triples()`
|
||||
<<<<<<< HEAD
|
||||
تقبل الدالة الجديدة قائمة بالثلاثيات المستخرجة بدلاً من ثلاثية واحدة.
|
||||
تقوم بإنشاء `tg:contains` واحد لكل ثلاثية، كتلة نشاط/وكيل مشتركة.
|
||||
قم بإزالة `triple_provenance_triples()` القديم.
|
||||
=======
|
||||
تقبل الدالة الجديدة قائمة بالثلاثيات المستخرجة بدلاً من ثلاثية واحدة
|
||||
تقوم بإنشاء `tg:contains` واحد لكل ثلاثية، كتلة نشاط/وكيل مشتركة
|
||||
قم بإزالة `triple_provenance_triples()` القديم
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**`trustgraph-base/trustgraph/provenance/uris.py`**
|
||||
|
||||
استبدل `statement_uri()` بـ `subgraph_uri()`
|
||||
|
||||
**`trustgraph-base/trustgraph/provenance/namespaces.py`**
|
||||
|
||||
استبدل `TG_REIFIES` بـ `TG_CONTAINS`
|
||||
|
||||
<<<<<<< HEAD
|
||||
### ليس ضمن النطاق
|
||||
=======
|
||||
### خارج النطاق
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**kg-extract-topics**: معالج بنمط قديم، ولا يتم استخدامه حاليًا في
|
||||
العمليات القياسية.
|
||||
**kg-extract-rows**: ينتج صفوفًا وليست ثلاثيات، ومن مصدر مختلف.
|
||||
نموذج.
|
||||
**تتبع المصدر في وقت الاستعلام** (`urn:graph:retrieval`): مسألة منفصلة،
|
||||
تستخدم بالفعل نمطًا مختلفًا (سؤال/استكشاف/تركيز/توليف).
|
||||
**أصل المستند/الصفحة/الجزء** (فك تشفير PDF، تقسيم النص): تستخدم بالفعل.
|
||||
`derived_entity_triples()` وهو خاص بكل كيان، وليس لكل ثلاثية - لا.
|
||||
مشكلة التكرار.
|
||||
|
||||
## ملاحظات حول التنفيذ
|
||||
|
||||
### إعادة هيكلة حلقة المعالج
|
||||
|
||||
قبل (لكل ثلاثية، في العلاقات):
|
||||
```python
|
||||
for rel in rels:
|
||||
# ... build relationship_triple ...
|
||||
stmt_uri = statement_uri()
|
||||
prov_triples = triple_provenance_triples(
|
||||
stmt_uri=stmt_uri,
|
||||
extracted_triple=relationship_triple,
|
||||
...
|
||||
)
|
||||
triples.extend(set_graph(prov_triples, GRAPH_SOURCE))
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
بعد (رسم بياني فرعي):
|
||||
=======
|
||||
بعد (الرسم البياني الفرعي):
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
```python
|
||||
sg_uri = subgraph_uri()
|
||||
|
||||
for rel in rels:
|
||||
# ... build relationship_triple ...
|
||||
extracted_triples.append(relationship_triple)
|
||||
|
||||
prov_triples = subgraph_provenance_triples(
|
||||
subgraph_uri=sg_uri,
|
||||
extracted_triples=extracted_triples,
|
||||
chunk_uri=chunk_uri,
|
||||
component_name=default_ident,
|
||||
component_version=COMPONENT_VERSION,
|
||||
llm_model=llm_model,
|
||||
ontology_uri=ontology_uri,
|
||||
)
|
||||
triples.extend(set_graph(prov_triples, GRAPH_SOURCE))
|
||||
```
|
||||
|
||||
### التوقيع المساعد الجديد
|
||||
|
||||
```python
|
||||
def subgraph_provenance_triples(
|
||||
subgraph_uri: str,
|
||||
extracted_triples: List[Triple],
|
||||
chunk_uri: str,
|
||||
component_name: str,
|
||||
component_version: str,
|
||||
llm_model: Optional[str] = None,
|
||||
ontology_uri: Optional[str] = None,
|
||||
timestamp: Optional[str] = None,
|
||||
) -> List[Triple]:
|
||||
"""
|
||||
Build provenance triples for a subgraph of extracted knowledge.
|
||||
|
||||
Creates:
|
||||
- tg:contains link for each extracted triple (RDF-star quoted)
|
||||
- One prov:wasDerivedFrom link to source chunk
|
||||
- One activity with agent metadata
|
||||
"""
|
||||
```
|
||||
|
||||
### تغيير جذري
|
||||
|
||||
<<<<<<< HEAD
|
||||
هذا تغيير جذري في نموذج التتبع. لم يتم
|
||||
تم إصدارها، لذا لا توجد حاجة إلى ترحيل. الكود القديم `tg:reifies` /
|
||||
يمكن إزالة كود `statement_uri` تمامًا.
|
||||
=======
|
||||
هذا تغيير جذري في نموذج التتبع. لم يتم إصدار التتبع بعد، لذا لا توجد حاجة إلى ترحيل. يمكن إزالة الكود القديم ⟦CODE_0⟧ / ⟦CODE_0⟧ مباشرةً.
|
||||
been released, so no migration is needed. The old `tg:reifies` /
|
||||
`statement_uri` code can be removed outright.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
886
docs/tech-specs/ar/extraction-time-provenance.ar.md
Normal file
886
docs/tech-specs/ar/extraction-time-provenance.ar.md
Normal file
|
|
@ -0,0 +1,886 @@
|
|||
---
|
||||
layout: default
|
||||
title: "أصل البيانات في وقت الاستخراج: الطبقة المصدر"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# أصل البيانات في وقت الاستخراج: الطبقة المصدر
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يوثق هذا المستند ملاحظات حول أصل البيانات في وقت الاستخراج لأعمال المواصفات المستقبلية. يسجل أصل البيانات في وقت الاستخراج "الطبقة المصدر" - من أين أتت البيانات في الأصل، وكيف تم استخراجها وتحويلها.
|
||||
|
||||
هذا يختلف عن أصل البيانات في وقت الاستعلام (انظر `query-time-provenance.md`) الذي يسجل استنتاجات الوكيل.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
### التنفيذ الحالي
|
||||
|
||||
يعمل أصل البيانات حاليًا على النحو التالي:
|
||||
<<<<<<< HEAD
|
||||
يتم تخزين بيانات وصف المستند كـ RDF triples في الرسم البياني المعرفي.
|
||||
=======
|
||||
يتم تخزين بيانات وصف المستند كـ "ثلاثيات" RDF في الرسم البياني للمعرفة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
يربط معرف المستند البيانات الوصفية بالمستند، بحيث يظهر المستند كعقدة في الرسم البياني.
|
||||
عند استخراج الحواف (العلاقات/الحقائق) من المستندات، تربط علاقة `subjectOf` الحافة المستخرجة بالمستند المصدر.
|
||||
|
||||
### المشاكل في النهج الحالي
|
||||
|
||||
<<<<<<< HEAD
|
||||
1. **تحميل البيانات الوصفية المتكرر:** يتم تجميع بيانات وصف المستند وتحميلها بشكل متكرر مع كل مجموعة من الـ triples المستخرجة من هذا المستند. هذا مضيعة ويزيد من التكرار - نفس البيانات الوصفية تنتقل كحمولة مع كل مخرج استخراج.
|
||||
=======
|
||||
1. **تحميل البيانات الوصفية المتكرر:** يتم تجميع بيانات وصف المستند وتحميلها بشكل متكرر مع كل مجموعة من "الثلاثيات" المستخرجة من هذا المستند. هذا مضيعة ويزيد من التكرار - حيث تنتقل نفس البيانات الوصفية كحمولة مع كل مخرج استخراج.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
2. **أصل بيانات سطحي:** تربط العلاقة `subjectOf` الحالية الحقائق مباشرة بالمستند ذي المستوى الأعلى فقط. لا توجد رؤية لسلسلة التحويل - أي الصفحة التي جاءت منها الحقيقة، أو الجزء، أو طريقة الاستخراج المستخدمة.
|
||||
|
||||
### الحالة المرغوبة
|
||||
|
||||
<<<<<<< HEAD
|
||||
1. **تحميل البيانات الوصفية مرة واحدة:** يجب تحميل بيانات وصف المستند مرة واحدة وإرفاقها بعقدة المستند ذات المستوى الأعلى، وليس تكرارها مع كل مجموعة من الـ triples.
|
||||
=======
|
||||
1. **تحميل البيانات الوصفية مرة واحدة:** يجب تحميل بيانات وصف المستند مرة واحدة وإرفاقها بعقدة المستند ذات المستوى الأعلى، وليس تكرارها مع كل مجموعة من "الثلاثيات".
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
2. **رسم بياني كامل لأصل البيانات:** التقاط سلسلة التحويل الكاملة من المستند المصدر عبر جميع القطع الأثرية الوسيطة وصولاً إلى الحقائق المستخرجة. على سبيل المثال، تحويل مستند PDF:
|
||||
|
||||
```
|
||||
PDF file (source document with metadata)
|
||||
→ Page 1 (decoded text)
|
||||
→ Chunk 1
|
||||
→ Extracted edge/fact (via subjectOf)
|
||||
→ Extracted edge/fact
|
||||
→ Chunk 2
|
||||
→ Extracted edge/fact
|
||||
→ Page 2
|
||||
→ Chunk 3
|
||||
→ ...
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
3. **التخزين الموحد:** يتم تخزين الرسم البياني للأصل (provenance DAG) في نفس الرسم البياني للمعرفة كما يتم تخزين المعرفة المستخرجة. يتيح ذلك الاستعلام عن الأصل بنفس الطريقة التي يتم بها الاستعلام عن المعرفة - من خلال تتبع الحواف صعودًا في السلسلة من أي حقيقة إلى موقع مصدرها الدقيق.
|
||||
|
||||
4. **معرفات مستقرة:** لكل قطعة أثرية وسيطة (صفحة، جزء) معرف مستقر كعقدة في الرسم البياني.
|
||||
|
||||
5. **الربط بين الأب والطفل:** يتم ربط المستندات المشتقة بآبائها وصولاً إلى المستند المصدر الرئيسي باستخدام أنواع علاقات متسقة.
|
||||
|
||||
6. **تخصيص الحقائق بدقة:** تشير العلاقة `subjectOf` في الحواف المستخرجة إلى الأصل الفوري (الجزء)، وليس المستند الرئيسي. يتم استعادة الأصل الكامل من خلال التنقل عبر الرسم البياني للأصل.
|
||||
=======
|
||||
3. **التخزين الموحد:** يتم تخزين الرسم البياني للأصل (provenance DAG) في نفس الرسم البياني للمعرفة مثل المعرفة المستخرجة. يتيح ذلك الاستعلام عن الأصل بنفس الطريقة التي يتم بها الاستعلام عن المعرفة - من خلال تتبع الحواف صعودًا في السلسلة من أي حقيقة إلى موقع مصدرها الدقيق.
|
||||
|
||||
4. **معرفات مستقرة:** لكل قطعة أثرية وسيطة (صفحة، جزء) معرف مستقر كعقدة في الرسم البياني.
|
||||
|
||||
5. **الربط بين الأبناء والآباء:** يتم ربط المستندات المشتقة بآبائها وصولاً إلى المستند المصدر الرئيسي باستخدام أنواع علاقات متسقة.
|
||||
|
||||
6. **تخصيص الحقائق بدقة:** تشير العلاقة `subjectOf` في الحواف المستخرجة إلى الأصل الفوري (الجزء)، وليس المستند الرئيسي. يتم استعادة الأصل الكامل من خلال اجتياز الرسم البياني للأصل.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## حالات الاستخدام
|
||||
|
||||
### UC1: تحديد مصدر المعلومات في استجابات GraphRAG
|
||||
|
||||
**السيناريو:** يقوم المستخدم بتشغيل استعلام GraphRAG ويتلقى استجابة من الوكيل.
|
||||
|
||||
**التدفق:**
|
||||
1. يرسل المستخدم استعلامًا إلى وكيل GraphRAG.
|
||||
2. يسترجع الوكيل الحقائق ذات الصلة من الرسم البياني للمعرفة لصياغة استجابة.
|
||||
3. وفقًا لمواصفات الأصل في وقت الاستعلام، يقوم الوكيل بالإبلاغ عن الحقائق التي ساهمت في الاستجابة.
|
||||
<<<<<<< HEAD
|
||||
4. يربط كل حقيقة بمصدره (الجزء) عبر الرسم البياني للأصل.
|
||||
5. ترتبط الأجزاء بالصفحات، وترتبط الصفحات بمستندات المصدر.
|
||||
|
||||
**النتيجة في تجربة المستخدم:** يعرض الواجهة استجابة نموذج اللغة الكبير (LLM) جنبًا إلى جنب مع تحديد مصدر المعلومات. يمكن للمستخدم:
|
||||
رؤية الحقائق التي دعمت الاستجابة.
|
||||
النزول من الحقائق إلى الأجزاء إلى الصفحات إلى المستندات.
|
||||
مراجعة المستندات المصدر الأصلية للتحقق من صحة الادعاءات.
|
||||
فهم بالضبط من أين في المستند (في أي صفحة، في أي قسم) نشأت الحقيقة.
|
||||
|
||||
**القيمة:** يمكن للمستخدمين التحقق من صحة الاستجابات التي تم إنشاؤها بواسطة الذكاء الاصطناعي مقابل المصادر الأولية، مما يعزز الثقة ويمكن المستخدمين من التحقق من الحقائق.
|
||||
=======
|
||||
4. ترتبط كل حقيقة بمصدرها من خلال الرسم البياني للأصل.
|
||||
5. ترتبط الأجزاء بالصفحات، وترتبط الصفحات بمستندات المصدر.
|
||||
|
||||
**النتيجة في تجربة المستخدم:** يعرض الواجهة استجابة نموذج اللغة (LLM) جنبًا إلى جنب مع تحديد مصدر المعلومات. يمكن للمستخدم:
|
||||
رؤية الحقائق التي دعمت الاستجابة.
|
||||
الانتقال من الحقائق إلى الأجزاء إلى الصفحات إلى المستندات.
|
||||
مراجعة المستندات المصدر الأصلية للتحقق من الادعاءات.
|
||||
فهم بالضبط من أين في المستند (في أي صفحة، في أي قسم) نشأت الحقيقة.
|
||||
|
||||
**القيمة:** يمكن للمستخدمين التحقق من الاستجابات التي تم إنشاؤها بواسطة الذكاء الاصطناعي مقابل المصادر الأولية، مما يعزز الثقة ويمكن المستخدمين من التحقق من الحقائق.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### UC2: تصحيح جودة الاستخراج
|
||||
|
||||
تبدو حقيقة خاطئة. تتبعها من خلال الجزء إلى الصفحة إلى المستند لمعرفة النص الأصلي. هل كان استخراجًا سيئًا، أم أن المصدر نفسه كان خاطئًا؟
|
||||
|
||||
### UC3: إعادة استخراج تدريجي
|
||||
|
||||
يتم تحديث مستند المصدر. ما هي الأجزاء/الحقائق التي تم اشتقاقها منه؟ قم بإبطالها وإعادة إنشائها فقط لتلك الأجزاء، بدلاً من إعادة معالجة كل شيء.
|
||||
|
||||
### UC4: حذف البيانات / الحق في النسيان
|
||||
|
||||
<<<<<<< HEAD
|
||||
يجب إزالة مستند المصدر (بسبب اللائحة العامة لحماية البيانات، أو لأسباب قانونية، إلخ). تتبع الرسم البياني للأصل للعثور على جميع الحقائق المشتقة وإزالتها.
|
||||
|
||||
### UC5: حل النزاعات
|
||||
|
||||
تتناقض حقائق مع بعضها البعض. تتبع كلتا الحالتين إلى مصادرها لفهم السبب واتخاذ قرار بشأن أي منهما يجب الوثوق به (المصدر الأكثر موثوقية، أو الأحدث، إلخ).
|
||||
|
||||
### UC6: وزن سلطة المصدر
|
||||
|
||||
بعض المصادر أكثر موثوقية من غيرها. يمكن ترجيح الحقائق أو تصفيتها بناءً على سلطة/جودة مستندات الأصل.
|
||||
|
||||
### UC7: مقارنة مسار الاستخراج
|
||||
=======
|
||||
يجب إزالة مستند المصدر (بسبب GDPR، أو لأسباب قانونية، وما إلى ذلك). ابحث في الرسم البياني للأصل وأزل جميع الحقائق المشتقة.
|
||||
|
||||
### UC5: حل النزاعات
|
||||
|
||||
تتناقض حقيقتان مع بعضهما البعض. تتبع كلتاهما إلى مصادرهما لفهم السبب واتخاذ قرار بشأن أي منهما يجب الوثوق به (المصدر الأكثر موثوقية، أو الأحدث، وما إلى ذلك).
|
||||
|
||||
### UC6: وزن سلطة المصدر
|
||||
|
||||
بعض المصادر أكثر موثوقية من غيرها. يمكن وزن الحقائق أو تصفيتها بناءً على سلطة/جودة مستندات الأصل.
|
||||
|
||||
### UC7: مقارنة مسارات الاستخراج
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
قارن المخرجات من طرق/إصدارات استخراج مختلفة. أي أداة استخراج أنتجت حقائق أفضل من نفس المصدر؟
|
||||
|
||||
## نقاط التكامل
|
||||
|
||||
### أمين المكتبة
|
||||
|
||||
يوفر مكون أمين المكتبة بالفعل تخزين المستندات بمعرفات مستندات فريدة. يتكامل نظام التتبع مع هذه البنية التحتية الحالية.
|
||||
|
||||
#### القدرات الحالية (تم تنفيذها بالفعل)
|
||||
|
||||
<<<<<<< HEAD
|
||||
**ربط المستندات من الأب إلى الابن:**
|
||||
`parent_id` الحقل في `DocumentMetadata` - يربط المستند الابن بالمستند الأب
|
||||
`document_type` الحقل - القيم: `"source"` (أصلي) أو `"extracted"` (مشتق)
|
||||
واجهة برمجة تطبيقات `add-child-document` - لإنشاء مستند ابن بمعرف `document_type = "extracted"` تلقائيًا
|
||||
واجهة برمجة تطبيقات `list-children` - لاسترداد جميع المستندات الابناء لمستند أب معين
|
||||
الحذف المتتالي - يؤدي إزالة مستند الأب تلقائيًا إلى حذف جميع مستندات الأبناء
|
||||
|
||||
**تحديد المستند:**
|
||||
معرفات المستندات محددة من قبل العميل (وليس تم إنشاؤها تلقائيًا)
|
||||
المستندات مفهرسة باستخدام `(user, document_id)` المركب في Cassandra
|
||||
يتم إنشاء معرفات الكائنات (UUIDs) داخليًا لتخزين الكائنات الثنائية
|
||||
|
||||
**دعم البيانات الوصفية:**
|
||||
`metadata: list[Triple]` الحقل - ثلاثيات RDF للبيانات الوصفية المنظمة
|
||||
`title`، `comments`، `tags` - بيانات وصفية أساسية للمستند
|
||||
`time` - الطابع الزمني، `kind` - نوع MIME
|
||||
|
||||
**هيكل التخزين:**
|
||||
يتم تخزين البيانات الوصفية في Cassandra (مساحة مفاتيح `librarian`، جدول `document`)
|
||||
يتم تخزين المحتوى في تخزين الكائنات الثنائية MinIO/S3 (دلو `library`)
|
||||
تسليم محتوى ذكي: يتم تضمين المستندات الأقل من 2 ميجابايت، ويتم بث المستندات الأكبر حجمًا
|
||||
|
||||
#### الملفات الرئيسية
|
||||
|
||||
`trustgraph-flow/trustgraph/librarian/librarian.py` - العمليات الأساسية لأمين المكتبة
|
||||
`trustgraph-flow/trustgraph/librarian/service.py` - معالج الخدمة، تحميل المستند
|
||||
`trustgraph-flow/trustgraph/tables/library.py` - تخزين جدول Cassandra
|
||||
`trustgraph-base/trustgraph/schema/services/library.py` - تعريفات المخططات
|
||||
=======
|
||||
**ربط المستندات من النوع "الأب-الابن":**
|
||||
الحقل `parent_id` في `DocumentMetadata` - يربط المستند الابن بالمستند الأب.
|
||||
الحقل `document_type` - القيم: `"source"` (أصلي) أو `"extracted"` (مشتق).
|
||||
واجهة برمجة تطبيقات `add-child-document` - لإنشاء مستند ابن مع `document_type = "extracted"` تلقائيًا.
|
||||
واجهة برمجة تطبيقات `list-children` - لاسترداد جميع المستندات الابناء لمستند أب معين.
|
||||
الحذف المتتالي - يؤدي إزالة مستند الأب تلقائيًا إلى حذف جميع مستندات الأبناء.
|
||||
|
||||
**تحديد المستند:**
|
||||
معرفات المستندات محددة من قبل العميل (وليس تم إنشاؤها تلقائيًا).
|
||||
المستندات مفهرسة بواسطة مفتاح مركب `(user, document_id)` في Cassandra.
|
||||
يتم إنشاء معرفات الكائنات (UUIDs) داخليًا لتخزين الكائنات الثنائية.
|
||||
|
||||
**دعم البيانات الوصفية:**
|
||||
الحقل `metadata: list[Triple]` - ثلاثيات RDF للبيانات الوصفية المنظمة.
|
||||
`title`، `comments`، `tags` - بيانات وصفية أساسية للمستند.
|
||||
`time` - الطابع الزمني، `kind` - نوع MIME.
|
||||
|
||||
**هيكل التخزين:**
|
||||
يتم تخزين البيانات الوصفية في Cassandra (مساحة مفاتيح `librarian`، جدول `document`).
|
||||
يتم تخزين المحتوى في تخزين الكائنات الثنائية MinIO/S3 (حاوية `library`).
|
||||
تسليم محتوى ذكي: المستندات الأقل من 2 ميجابايت مضمنة، ويتم بث المستندات الأكبر حجمًا.
|
||||
|
||||
#### الملفات الرئيسية
|
||||
|
||||
`trustgraph-flow/trustgraph/librarian/librarian.py` - العمليات الأساسية لأمين المكتبة.
|
||||
`trustgraph-flow/trustgraph/librarian/service.py` - معالج الخدمة، تحميل المستند.
|
||||
`trustgraph-flow/trustgraph/tables/library.py` - متجر جدول Cassandra.
|
||||
`trustgraph-base/trustgraph/schema/services/library.py` - تعريفات المخططات.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### الثغرات التي يجب معالجتها
|
||||
|
||||
يحتوي أمين المكتبة على اللبنات الأساسية ولكن حاليًا:
|
||||
<<<<<<< HEAD
|
||||
1. الربط من الأب إلى الابن ذو مستوى واحد فقط - لا توجد أدوات مساعدة لتصفح الرسوم البيانية متعددة المستويات
|
||||
2. لا يوجد مفردات قياسية لأنواع العلاقات (مثل `derivedFrom`، `extractedFrom`)
|
||||
3. بيانات التتبع الوصفية (طريقة الاستخراج، والثقة، وموضع الجزء) غير موحدة
|
||||
4. لا توجد واجهة برمجة تطبيقات للاستعلام للتنقل عبر سلسلة التتبع الكاملة من حقيقة إلى المصدر
|
||||
=======
|
||||
1. ربط الأب-الابن ذو مستوى واحد فقط - لا توجد أدوات مساعدة لتصفح الرسوم البيانية متعددة المستويات.
|
||||
2. لا يوجد مفردات قياسية لأنواع العلاقات (مثل `derivedFrom`، `extractedFrom`).
|
||||
3. بيانات التتبع الوصفية (طريقة الاستخراج، والثقة، وموضع الجزء) غير موحدة.
|
||||
4. لا توجد واجهة برمجة تطبيقات للاستعلام للتنقل عبر سلسلة التتبع الكاملة من حقيقة إلى المصدر.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## تصميم التدفق الشامل
|
||||
|
||||
يتبع كل معالج في خط الأنابيب نمطًا متسقًا:
|
||||
<<<<<<< HEAD
|
||||
استقبال معرف المستند من البنية التحتية
|
||||
جلب المحتوى من أمين المكتبة
|
||||
إنتاج القطع الأثرية الفرعية
|
||||
لكل قطعة أثرية فرعية: حفظ في أمين المكتبة، وإصدار حافة إلى الرسم البياني، وتمرير المعرف إلى البنية التحتية
|
||||
=======
|
||||
استقبال معرف المستند من المصدر العلوي.
|
||||
جلب المحتوى من أمين المكتبة.
|
||||
إنتاج القطع الأثرية الفرعية.
|
||||
لكل قطعة أثرية فرعية: حفظ في أمين المكتبة، وإصدار حافة إلى الرسم البياني، وتمرير المعرف إلى المكون التالي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### تدفقات المعالجة
|
||||
|
||||
هناك تدفقان اعتمادًا على نوع المستند:
|
||||
|
||||
#### تدفق مستند PDF
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Librarian (initiate processing) │
|
||||
│ 1. Emit root document metadata to knowledge graph (once) │
|
||||
│ 2. Send root document ID to PDF extractor │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ PDF Extractor (per page) │
|
||||
│ 1. Fetch PDF content from librarian using document ID │
|
||||
│ 2. Extract pages as text │
|
||||
│ 3. For each page: │
|
||||
│ a. Save page as child document in librarian (parent = root doc) │
|
||||
│ b. Emit parent-child edge to knowledge graph │
|
||||
│ c. Send page document ID to chunker │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Chunker (per chunk) │
|
||||
│ 1. Fetch page content from librarian using document ID │
|
||||
│ 2. Split text into chunks │
|
||||
│ 3. For each chunk: │
|
||||
│ a. Save chunk as child document in librarian (parent = page) │
|
||||
│ b. Emit parent-child edge to knowledge graph │
|
||||
│ c. Send chunk document ID + chunk content to next processor │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
Post-chunker optimization: messages carry both
|
||||
chunk ID (for provenance) and content (to avoid
|
||||
librarian round-trip). Chunks are small (2-4KB).
|
||||
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Knowledge Extractor (per chunk) │
|
||||
│ 1. Receive chunk ID + content directly (no librarian fetch needed) │
|
||||
│ 2. Extract facts/triples and embeddings from chunk content │
|
||||
│ 3. For each triple: │
|
||||
│ a. Emit triple to knowledge graph │
|
||||
│ b. Emit reified edge linking triple → chunk ID (edge pointing │
|
||||
│ to edge - first use of reification support) │
|
||||
│ 4. For each embedding: │
|
||||
│ a. Emit embedding with its entity ID │
|
||||
│ b. Link entity ID → chunk ID in knowledge graph │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### تدفق مستندات النص
|
||||
|
||||
تتجاوز مستندات النص أداة استخراج ملفات PDF وتنتقل مباشرةً إلى وحدة التقسيم:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Librarian (initiate processing) │
|
||||
│ 1. Emit root document metadata to knowledge graph (once) │
|
||||
│ 2. Send root document ID directly to chunker (skip PDF extractor) │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Chunker (per chunk) │
|
||||
│ 1. Fetch text content from librarian using document ID │
|
||||
│ 2. Split text into chunks │
|
||||
│ 3. For each chunk: │
|
||||
│ a. Save chunk as child document in librarian (parent = root doc) │
|
||||
│ b. Emit parent-child edge to knowledge graph │
|
||||
│ c. Send chunk document ID + chunk content to next processor │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Knowledge Extractor │
|
||||
│ (same as PDF flow) │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
الرسم البياني الموجه الناتج أقصر بمستوى واحد:
|
||||
|
||||
```
|
||||
PDF: Document → Pages → Chunks → Triples/Embeddings
|
||||
Text: Document → Chunks → Triples/Embeddings
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
التصميم يتكيف مع كل من المصدر والصفحة لأن وحدة التقسيم تعالج مدخلاتها بشكل عام - فهي تستخدم أي معرف مستند تتلقاه كمعرف رئيسي، بغض النظر عما إذا كان ذلك مستند مصدر أم صفحة.
|
||||
|
||||
### مخطط البيانات الوصفية (PROV-O)
|
||||
|
||||
تستخدم البيانات الوصفية المتعلقة بالأصل علم الوجود W3C PROV-O. يوفر هذا مفردات قياسية ويمكن أن يمكّن التوقيع/المصادقة المستقبلية لنتائج الاستخراج.
|
||||
=======
|
||||
التصميم يتكيف مع كلتا الحالتين لأن وحدة التقسيم تعالج مدخلاتها بشكل عام - فهي تستخدم أي معرف مستند تتلقاه كمعرف رئيسي، بغض النظر عما إذا كان ذلك مستندًا أصليًا أم صفحة.
|
||||
|
||||
### مخطط البيانات الوصفية (PROV-O)
|
||||
|
||||
تستخدم البيانات الوصفية المتعلقة بالأصل علم الوجود W3C PROV-O. يوفر هذا مفردات قياسية ويمكن أن يتيح في المستقبل التوقيع والمصادقة على مخرجات الاستخراج.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### المفاهيم الأساسية في PROV-O
|
||||
|
||||
| نوع PROV-O | استخدام TrustGraph |
|
||||
|-------------|------------------|
|
||||
| `prov:Entity` | مستند، صفحة، جزء، ثلاثي، تضمين |
|
||||
| `prov:Activity` | حالات عمليات الاستخراج |
|
||||
| `prov:Agent` | مكونات TG (مثل أداة استخراج PDF، ووحدة التقسيم، إلخ) مع الإصدارات |
|
||||
|
||||
#### علاقات PROV-O
|
||||
|
||||
| الرابط | المعنى | مثال |
|
||||
|-----------|---------|---------|
|
||||
| `prov:wasDerivedFrom` | كيان مشتق من كيان آخر | الصفحة مشتقة من المستند |
|
||||
| `prov:wasGeneratedBy` | كيان تم إنشاؤه بواسطة نشاط | الصفحة تم إنشاؤها بواسطة نشاط استخراج PDF |
|
||||
| `prov:used` | نشاط استخدم كيانًا كمدخل | نشاط استخراج PDF استخدم المستند |
|
||||
| `prov:wasAssociatedWith` | نشاط تم تنفيذه بواسطة وكيل | نشاط استخراج PDF مرتبط بـ tg:PDFExtractor |
|
||||
|
||||
#### البيانات الوصفية في كل مستوى
|
||||
|
||||
<<<<<<< HEAD
|
||||
**المستند المصدر (يتم إصداره بواسطة Librarian):**
|
||||
=======
|
||||
**المستند الأصلي (يتم إصداره بواسطة Librarian):**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
```
|
||||
doc:123 a prov:Entity .
|
||||
doc:123 dc:title "Research Paper" .
|
||||
doc:123 dc:source <https://example.com/paper.pdf> .
|
||||
doc:123 dc:date "2024-01-15" .
|
||||
doc:123 dc:creator "Author Name" .
|
||||
doc:123 tg:pageCount 42 .
|
||||
doc:123 tg:mimeType "application/pdf" .
|
||||
```
|
||||
|
||||
**الصفحة (تم إنشاؤها بواسطة مُستخرج PDF):**
|
||||
```
|
||||
page:123-1 a prov:Entity .
|
||||
page:123-1 prov:wasDerivedFrom doc:123 .
|
||||
page:123-1 prov:wasGeneratedBy activity:pdf-extract-456 .
|
||||
page:123-1 tg:pageNumber 1 .
|
||||
|
||||
activity:pdf-extract-456 a prov:Activity .
|
||||
activity:pdf-extract-456 prov:used doc:123 .
|
||||
activity:pdf-extract-456 prov:wasAssociatedWith tg:PDFExtractor .
|
||||
activity:pdf-extract-456 tg:componentVersion "1.2.3" .
|
||||
activity:pdf-extract-456 prov:startedAtTime "2024-01-15T10:30:00Z" .
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
**الجزء (يتم إصداره بواسطة وحدة التجميع):**
|
||||
=======
|
||||
**جزء (يتم إصداره بواسطة أداة التقسيم):**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
```
|
||||
chunk:123-1-1 a prov:Entity .
|
||||
chunk:123-1-1 prov:wasDerivedFrom page:123-1 .
|
||||
chunk:123-1-1 prov:wasGeneratedBy activity:chunk-789 .
|
||||
chunk:123-1-1 tg:chunkIndex 1 .
|
||||
chunk:123-1-1 tg:charOffset 0 .
|
||||
chunk:123-1-1 tg:charLength 2048 .
|
||||
|
||||
activity:chunk-789 a prov:Activity .
|
||||
activity:chunk-789 prov:used page:123-1 .
|
||||
activity:chunk-789 prov:wasAssociatedWith tg:Chunker .
|
||||
activity:chunk-789 tg:componentVersion "1.0.0" .
|
||||
activity:chunk-789 tg:chunkSize 2048 .
|
||||
activity:chunk-789 tg:chunkOverlap 200 .
|
||||
```
|
||||
|
||||
**ثلاثي (تم إصداره بواسطة مُستخلص المعرفة):**
|
||||
```
|
||||
# The extracted triple (edge)
|
||||
entity:JohnSmith rel:worksAt entity:AcmeCorp .
|
||||
|
||||
# Subgraph containing the extracted triples
|
||||
subgraph:001 tg:contains <<entity:JohnSmith rel:worksAt entity:AcmeCorp>> .
|
||||
subgraph:001 prov:wasDerivedFrom chunk:123-1-1 .
|
||||
subgraph:001 prov:wasGeneratedBy activity:extract-999 .
|
||||
|
||||
activity:extract-999 a prov:Activity .
|
||||
activity:extract-999 prov:used chunk:123-1-1 .
|
||||
activity:extract-999 prov:wasAssociatedWith tg:KnowledgeExtractor .
|
||||
activity:extract-999 tg:componentVersion "2.1.0" .
|
||||
activity:extract-999 tg:llmModel "claude-3" .
|
||||
activity:extract-999 tg:ontology <http://example.org/ontologies/business-v1> .
|
||||
```
|
||||
|
||||
**التضمين (يتم تخزينه في مخزن المتجهات، وليس في مخزن الثلاثيات):**
|
||||
|
||||
يتم تخزين التضمينات في مخزن المتجهات مع البيانات الوصفية، وليس كـ RDF triples. يحتوي كل سجل تضمين على:
|
||||
|
||||
| الحقل | الوصف | مثال |
|
||||
|-------|-------------|---------|
|
||||
| vector | متجه التضمين | [0.123, -0.456, ...] |
|
||||
| entity | عنوان URI للعقدة التي يمثلها التضمين | `entity:JohnSmith` |
|
||||
| chunk_id | الجزء المصدر (الأصل) | `chunk:123-1-1` |
|
||||
| model | نموذج التضمين المستخدم | `text-embedding-ada-002` |
|
||||
| component_version | إصدار مُحسِّن التضمين (TG embedder) | `1.0.0` |
|
||||
|
||||
يربط الحقل `entity` التضمين بالرسم البياني المعرفي (عنوان URI للعقدة). يوفر الحقل `chunk_id` معلومات عن الأصل إلى الجزء المصدر، مما يتيح التنقل صعودًا في الرسم البياني الموجه (DAG) إلى المستند الأصلي.
|
||||
|
||||
#### امتدادات مساحة اسم TrustGraph
|
||||
|
||||
محددات مخصصة ضمن مساحة الاسم `tg:` لبيانات وصفية خاصة بالاستخراج:
|
||||
|
||||
| المحدد | النطاق | الوصف |
|
||||
|-----------|--------|-------------|
|
||||
| `tg:contains` | Subgraph | يشير إلى ثلاثية موجودة في هذا الرسوم البيانية الفرعية للاستخراج |
|
||||
| `tg:pageCount` | Document | العدد الإجمالي لصفحات المستند المصدر |
|
||||
| `tg:mimeType` | Document | نوع MIME للمستند المصدر |
|
||||
| `tg:pageNumber` | Page | رقم الصفحة في المستند المصدر |
|
||||
| `tg:chunkIndex` | Chunk | فهرس الجزء داخل الأصل |
|
||||
| `tg:charOffset` | Chunk | الإزاحة الحرفية في النص الأصل |
|
||||
| `tg:charLength` | Chunk | طول الجزء بالأحرف |
|
||||
| `tg:chunkSize` | Activity | حجم الجزء المُكوَّن |
|
||||
| `tg:chunkOverlap` | Activity | التداخل المُكوَّن بين الأجزاء |
|
||||
| `tg:componentVersion` | Activity | إصدار مكون TG |
|
||||
| `tg:llmModel` | Activity | نموذج LLM المستخدم للاستخراج |
|
||||
<<<<<<< HEAD
|
||||
| `tg:ontology` | Activity | عنوان URI للأنطولوجيا المستخدم لتوجيه الاستخراج |
|
||||
=======
|
||||
| `tg:ontology` | Activity | عنوان URI للدلالة المستخدم لتوجيه الاستخراج |
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
| `tg:embeddingModel` | Activity | النموذج المستخدم للتضمينات |
|
||||
| `tg:sourceText` | Statement | النص الدقيق الذي تم استخراج ثلاثية منه |
|
||||
| `tg:sourceCharOffset` | Statement | الإزاحة الحرفية داخل الجزء حيث يبدأ النص المصدر |
|
||||
| `tg:sourceCharLength` | Statement | طول النص المصدر بالأحرف |
|
||||
|
||||
#### تهيئة المفردات (لكل مجموعة)
|
||||
|
||||
<<<<<<< HEAD
|
||||
الرسم البياني المعرفي محايد للأنطولوجيا ويبدأ فارغًا. عند كتابة بيانات سلالة PROV-O إلى مجموعة لأول مرة، يجب تهيئة المفردات باستخدام تسميات RDF لجميع الفئات والمحددات. يضمن ذلك عرضًا قابلاً للقراءة بواسطة الإنسان في الاستعلامات وواجهة المستخدم.
|
||||
=======
|
||||
الرسم البياني المعرفي محايد بالنسبة للدلالات ويبدأ فارغًا. عند كتابة بيانات سلالة PROV-O إلى مجموعة لأول مرة، يجب تهيئة المفردات باستخدام تسميات RDF لجميع الفئات والمحددات. يضمن ذلك عرضًا قابلاً للقراءة بواسطة الإنسان في الاستعلامات وواجهة المستخدم.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**فئات PROV-O:**
|
||||
```
|
||||
prov:Entity rdfs:label "Entity" .
|
||||
prov:Activity rdfs:label "Activity" .
|
||||
prov:Agent rdfs:label "Agent" .
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
**المُتَعَدِّيات (Predicates) الخاصة بـ PROV-O:**
|
||||
=======
|
||||
**المفردات (Predicates) الخاصة بـ PROV-O:**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
```
|
||||
prov:wasDerivedFrom rdfs:label "was derived from" .
|
||||
prov:wasGeneratedBy rdfs:label "was generated by" .
|
||||
prov:used rdfs:label "used" .
|
||||
prov:wasAssociatedWith rdfs:label "was associated with" .
|
||||
prov:startedAtTime rdfs:label "started at" .
|
||||
```
|
||||
|
||||
**عبارات TrustGraph:**
|
||||
```
|
||||
tg:contains rdfs:label "contains" .
|
||||
tg:pageCount rdfs:label "page count" .
|
||||
tg:mimeType rdfs:label "MIME type" .
|
||||
tg:pageNumber rdfs:label "page number" .
|
||||
tg:chunkIndex rdfs:label "chunk index" .
|
||||
tg:charOffset rdfs:label "character offset" .
|
||||
tg:charLength rdfs:label "character length" .
|
||||
tg:chunkSize rdfs:label "chunk size" .
|
||||
tg:chunkOverlap rdfs:label "chunk overlap" .
|
||||
tg:componentVersion rdfs:label "component version" .
|
||||
tg:llmModel rdfs:label "LLM model" .
|
||||
tg:ontology rdfs:label "ontology" .
|
||||
tg:embeddingModel rdfs:label "embedding model" .
|
||||
tg:sourceText rdfs:label "source text" .
|
||||
tg:sourceCharOffset rdfs:label "source character offset" .
|
||||
tg:sourceCharLength rdfs:label "source character length" .
|
||||
```
|
||||
|
||||
**ملاحظة حول التنفيذ:** يجب أن يكون هذا الإطار اللغوي ذاتي الإعادة - آمنًا للتشغيل عدة مرات دون إنشاء تكرارات. يمكن تشغيله في معالجة المستند الأول في المجموعة، أو كخطوة منفصلة لتهيئة المجموعة.
|
||||
|
||||
<<<<<<< HEAD
|
||||
#### أصل الجزء الفرعي (طموح)
|
||||
|
||||
للحصول على معلومات تفصيلية حول الأصل، سيكون من المفيد تسجيل المكان الدقيق داخل جزء معين حيث تم استخراج الثلاثي. هذا يسمح بـ:
|
||||
|
||||
تسليط الضوء على النص المصدر الدقيق في واجهة المستخدم.
|
||||
التحقق من دقة الاستخراج مقابل المصدر.
|
||||
=======
|
||||
#### مصدر المعلومات التفصيلية (طموح)
|
||||
|
||||
للحصول على معلومات تفصيلية حول المصدر، سيكون من المفيد تسجيل المكان الدقيق داخل جزء معين حيث تم استخراج الثلاثيات منه. هذا يسمح بـ:
|
||||
|
||||
تسليط الضوء على النص المصدر الدقيق في واجهة المستخدم.
|
||||
التحقق من دقة الاستخراج مقارنة بالمصدر.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
تصحيح جودة الاستخراج على مستوى الجملة.
|
||||
|
||||
**مثال مع تتبع الموضع:**
|
||||
```
|
||||
# The extracted triple
|
||||
entity:JohnSmith rel:worksAt entity:AcmeCorp .
|
||||
|
||||
# Subgraph with sub-chunk provenance
|
||||
subgraph:001 tg:contains <<entity:JohnSmith rel:worksAt entity:AcmeCorp>> .
|
||||
subgraph:001 prov:wasDerivedFrom chunk:123-1-1 .
|
||||
subgraph:001 tg:sourceText "John Smith has worked at Acme Corp since 2019" .
|
||||
subgraph:001 tg:sourceCharOffset 1547 .
|
||||
subgraph:001 tg:sourceCharLength 46 .
|
||||
```
|
||||
|
||||
**مثال مع نطاق نص (بديل):**
|
||||
```
|
||||
subgraph:001 tg:contains <<entity:JohnSmith rel:worksAt entity:AcmeCorp>> .
|
||||
subgraph:001 prov:wasDerivedFrom chunk:123-1-1 .
|
||||
subgraph:001 tg:sourceRange "1547-1593" .
|
||||
subgraph:001 tg:sourceText "John Smith has worked at Acme Corp since 2019" .
|
||||
```
|
||||
|
||||
**اعتبارات التنفيذ:**
|
||||
|
||||
<<<<<<< HEAD
|
||||
قد لا توفر استخراج البيانات باستخدام نماذج اللغة الكبيرة (LLM) بشكل طبيعي مواقع الأحرف.
|
||||
يمكن توجيه نموذج اللغة الكبيرة لإرجاع الجملة/العبارة المصدرية بالإضافة إلى الثلاثيات المستخرجة.
|
||||
بدلاً من ذلك، يمكن إجراء معالجة لاحقة لمطابقة الكيانات المستخرجة بشكل تقريبي مع النص المصدر.
|
||||
يوجد مقايضة بين تعقيد الاستخراج ودقة تتبع المصدر.
|
||||
قد يكون من الأسهل تحقيق ذلك باستخدام طرق الاستخراج المنظمة بدلاً من استخراج البيانات المجردة باستخدام نماذج اللغة الكبيرة.
|
||||
=======
|
||||
قد لا توفر عملية الاستخراج القائمة على نماذج اللغة الكبيرة (LLM) بشكل طبيعي مواقع الأحرف.
|
||||
يمكن توجيه نموذج اللغة الكبيرة لإرجاع الجملة/العبارة المصدرية بالإضافة إلى الثلاثيات المستخرجة.
|
||||
بدلاً من ذلك، يمكن إجراء معالجة لاحقة لمطابقة الكيانات المستخرجة بشكل تقريبي مع النص الأصلي.
|
||||
يوجد مقايضة بين تعقيد الاستخراج ودقة تتبع المصدر.
|
||||
قد يكون من الأسهل تحقيق ذلك باستخدام طرق الاستخراج المنظمة بدلاً من استخراج نماذج اللغة الكبيرة غير المنظمة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
هذا الأمر مصنف على أنه طموح - يجب تنفيذ تتبع المصدر على مستوى المقطع أولاً، مع تتبع المقطع الفرعي كتحسين مستقبلي إذا كان ذلك ممكنًا.
|
||||
|
||||
### نموذج التخزين المزدوج
|
||||
|
||||
<<<<<<< HEAD
|
||||
يتم بناء رسم بياني لتتبع المصدر بشكل تدريجي أثناء تدفق المستندات عبر مسار العمل:
|
||||
=======
|
||||
يتم بناء رسم بياني (DAG) لتتبع المصدر تدريجيًا أثناء تدفق المستندات عبر مسار العمل:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
| التخزين | ما يتم تخزينه | الغرض |
|
||||
|-------|---------------|---------|
|
||||
| أمين المكتبة | محتوى المستند + روابط الأبناء | استرجاع المحتوى، حذف متسلسل |
|
||||
<<<<<<< HEAD
|
||||
| الرسم البياني للمعرفة | حواف الأبناء، وبيانات وصفية | استعلامات تتبع المصدر، إسناد الحقائق |
|
||||
|
||||
تحتفظ كلا التخزينين بنفس هيكل الرسم البياني. يحتوي أمين المكتبة على المحتوى، بينما يحتوي الرسم البياني على العلاقات ويمكنه تمكين استعلامات التصفح.
|
||||
|
||||
### المبادئ الأساسية للتصميم
|
||||
|
||||
1. **معرف المستند كوحدة تدفق** - تمرر المعالجات المعرفات، وليس المحتوى. يتم استرداد المحتوى من أمين المكتبة عند الحاجة.
|
||||
|
||||
2. **الإرسال مرة واحدة من المصدر** - يتم كتابة البيانات الوصفية في الرسم البياني مرة واحدة عند بدء المعالجة، وليس بشكل متكرر في المراحل اللاحقة.
|
||||
|
||||
3. **نمط معالج متسق** - يتبع كل معالج نفس النمط: الاستقبال/الاسترداد/الإنتاج/الحفظ/الإرسال/التوجيه.
|
||||
|
||||
4. **بناء تدريجي للرسم البياني** - يضيف كل معالج مستواه إلى الرسم البياني. يتم بناء سلسلة تتبع المصدر الكاملة بشكل تدريجي.
|
||||
|
||||
5. **تحسين ما بعد التقطيع** - بعد التقطيع، تحمل الرسائل كلاً من المعرف والمحتوى. تكون القطع صغيرة (2-4 كيلوبايت)، لذلك يؤدي تضمين المحتوى إلى تجنب عمليات الذهاب والإياب غير الضرورية إلى أمين المكتبة مع الحفاظ على تتبع المصدر عبر المعرف.
|
||||
=======
|
||||
| الرسم البياني المعرفي | حواف الأبناء، بالإضافة إلى البيانات الوصفية | استعلامات تتبع المصدر، إسناد الحقائق |
|
||||
|
||||
تحتفظ كلتا الحالتين بنفس هيكل الرسم البياني. تحتفظ أمين المكتبة بالمحتوى، بينما يحتفظ الرسم البياني بالعلاقات ويمكنه تمكين استعلامات التصفح.
|
||||
|
||||
### المبادئ الأساسية للتصميم
|
||||
|
||||
1. **معرف المستند كوحدة تدفق** - تمرر المعالجات المعرفات، وليس المحتوى. يتم جلب المحتوى من أمين المكتبة عند الحاجة.
|
||||
|
||||
2. **الإرسال مرة واحدة من المصدر** - يتم كتابة البيانات الوصفية في الرسم البياني مرة واحدة عند بدء المعالجة، وليس بشكل متكرر في المراحل اللاحقة.
|
||||
|
||||
3. **نمط معالج متسق** - يتبع كل معالج نفس النمط: الاستقبال/الجلب/الإنتاج/الحفظ/الإرسال/التوجيه.
|
||||
|
||||
4. **بناء تدريجي للرسم البياني** - يضيف كل معالج مستواه إلى الرسم البياني. يتم بناء سلسلة تتبع المصدر الكاملة بشكل تدريجي.
|
||||
|
||||
5. **تحسين ما بعد التقسيم إلى أجزاء** - بعد التقسيم إلى أجزاء، تحمل الرسائل كلاً من المعرف والمحتوى. الأجزاء صغيرة (2-4 كيلوبايت)، لذا فإن تضمين المحتوى يتجنب عمليات الذهاب والإياب غير الضرورية إلى أمين المكتبة مع الحفاظ على تتبع المصدر عبر المعرف.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## مهام التنفيذ
|
||||
|
||||
### تغييرات أمين المكتبة
|
||||
|
||||
#### الحالة الحالية
|
||||
|
||||
يبدأ معالجة المستند عن طريق إرسال معرف المستند إلى المعالج الأول.
|
||||
لا يوجد اتصال بمخزن الثلاثيات - يتم تجميع البيانات الوصفية مع مخرجات الاستخراج.
|
||||
`add-child-document` ينشئ روابط الأبناء من مستوى واحد.
|
||||
`list-children` يُرجع فقط الأبناء المباشرين.
|
||||
|
||||
#### التغييرات المطلوبة
|
||||
|
||||
**1. واجهة جديدة: اتصال بمخزن الثلاثيات**
|
||||
|
||||
<<<<<<< HEAD
|
||||
يحتاج أمين المكتبة إلى إرسال حواف بيانات وصفية للمستند مباشرة إلى الرسم البياني للمعرفة عند بدء المعالجة.
|
||||
=======
|
||||
تحتاج أمين المكتبة إلى إرسال حواف بيانات وصفية لمستندات الأبناء مباشرة إلى الرسم البياني المعرفي عند بدء المعالجة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
إضافة عميل/ناشر مخزن الثلاثيات إلى خدمة أمين المكتبة.
|
||||
عند بدء المعالجة: إرسال بيانات وصفية للمستند الجذر كحواف في الرسم البياني (مرة واحدة).
|
||||
|
||||
**2. مفردات أنواع المستندات**
|
||||
|
||||
<<<<<<< HEAD
|
||||
توحيد قيم `document_type` لأبناء المستند:
|
||||
=======
|
||||
توحيد قيم `document_type` لمستندات الأبناء:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
`source` - المستند الذي تم تحميله أصلاً.
|
||||
`page` - صفحة مستخرجة من المصدر (PDF، إلخ).
|
||||
`chunk` - جزء نصي مشتق من الصفحة أو المصدر.
|
||||
|
||||
#### ملخص تغييرات الواجهة
|
||||
|
||||
| الواجهة | التغيير |
|
||||
|-----------|--------|
|
||||
<<<<<<< HEAD
|
||||
| مخزن الثلاثيات | اتصال صادر جديد - إرسال حواف بيانات وصفية للمستند |
|
||||
=======
|
||||
| مخزن الثلاثيات | اتصال صادر جديد - إرسال حواف بيانات وصفية لمستندات الأبناء |
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
| بدء المعالجة | إرسال البيانات الوصفية إلى الرسم البياني قبل توجيه معرف المستند |
|
||||
|
||||
### تغييرات مستخرج PDF
|
||||
|
||||
#### الحالة الحالية
|
||||
|
||||
<<<<<<< HEAD
|
||||
يتلقى محتوى المستند (أو يتدفق المستندات الكبيرة).
|
||||
يستخرج النص من صفحات PDF.
|
||||
يوجه محتوى الصفحة إلى وحدة التقطيع.
|
||||
=======
|
||||
يتلقى محتوى المستند (أو يقوم بتدفق المستندات الكبيرة).
|
||||
يستخرج النص من صفحات PDF.
|
||||
يوجه محتوى الصفحة إلى وحدة تقسيم إلى أجزاء.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
لا يوجد تفاعل مع أمين المكتبة أو مخزن الثلاثيات.
|
||||
|
||||
#### التغييرات المطلوبة
|
||||
|
||||
**1. واجهة جديدة: عميل أمين المكتبة**
|
||||
|
||||
يحتاج مستخرج PDF إلى حفظ كل صفحة كمستند تابع في أمين المكتبة.
|
||||
إضافة عميل أمين المكتبة إلى خدمة مستخرج PDF.
|
||||
لكل صفحة: استدعاء `add-child-document` مع parent = معرف المستند الجذر.
|
||||
|
||||
**2. واجهة جديدة: اتصال بمخزن الثلاثيات**
|
||||
|
||||
<<<<<<< HEAD
|
||||
يحتاج مستخرج PDF إلى إرسال حواف الأبناء إلى الرسم البياني للمعرفة.
|
||||
=======
|
||||
يحتاج مستخرج PDF إلى إرسال حواف الأبناء إلى الرسم البياني المعرفي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
إضافة عميل/ناشر مخزن الثلاثيات.
|
||||
لكل صفحة: إرسال حافة تربط مستند الصفحة بالمستند الأصل.
|
||||
|
||||
**3. تغيير تنسيق الإخراج**
|
||||
|
||||
بدلًا من إرسال محتوى الصفحة مباشرةً، أرسل مُعرّف مستند الصفحة.
|
||||
<<<<<<< HEAD
|
||||
سيقوم المقطع (Chunker) بجلب المحتوى من أمين المكتبة (librarian) باستخدام المعرّف.
|
||||
=======
|
||||
سيقوم المقطع (Chunker) بجلب المحتوى من المكتبة (librarian) باستخدام المعرّف.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### ملخص التغييرات في الواجهة
|
||||
|
||||
| الواجهة | التغيير |
|
||||
|-----------|--------|
|
||||
<<<<<<< HEAD
|
||||
| أمين المكتبة (Librarian) | واجهة تصدير جديدة - حفظ المستندات الفرعية |
|
||||
| قاعدة البيانات الثلاثية (Triple store) | واجهة تصدير جديدة - إرسال علاقات الأبناء والبنات |
|
||||
=======
|
||||
| المكتبة (librarian) | إخراج جديد - حفظ المستندات الفرعية |
|
||||
| المستودع الثلاثي (Triple store) | إخراج جديد - إرسال علاقات الأبناء |
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
| رسالة الإخراج | تغيير من المحتوى إلى مُعرّف المستند |
|
||||
|
||||
### تغييرات المقطع (Chunker)
|
||||
|
||||
#### الحالة الحالية
|
||||
|
||||
<<<<<<< HEAD
|
||||
يستقبل محتوى الصفحة/النص
|
||||
يقسم إلى أجزاء (chunks)
|
||||
يرسل محتوى الجزء إلى المعالجات اللاحقة
|
||||
لا يوجد تفاعل مع أمين المكتبة أو قاعدة البيانات الثلاثية
|
||||
=======
|
||||
يتلقى محتوى الصفحة/النص
|
||||
يقسم إلى أجزاء
|
||||
يرسل محتوى الجزء إلى المعالجات اللاحقة
|
||||
لا يوجد تفاعل مع المكتبة أو المستودع الثلاثي
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### التغييرات المطلوبة
|
||||
|
||||
**1. تغيير طريقة معالجة الإدخال**
|
||||
|
||||
<<<<<<< HEAD
|
||||
استقبل مُعرّف المستند بدلًا من المحتوى، وجلبه من أمين المكتبة.
|
||||
أضف عميل أمين المكتبة إلى خدمة المقطع.
|
||||
جلب محتوى الصفحة باستخدام مُعرّف المستند.
|
||||
|
||||
**2. واجهة جديدة: عميل أمين المكتبة (للكتابة)**
|
||||
|
||||
احفظ كل جزء كمستند فرعي في أمين المكتبة.
|
||||
لكل جزء: استدعِ `add-child-document` مع `parent = page document ID`
|
||||
|
||||
**3. واجهة جديدة: اتصال بقاعدة البيانات الثلاثية**
|
||||
|
||||
أرسل علاقات الأبناء والبنات إلى الرسم البياني المعرفي.
|
||||
أضف عميل/ناشر قاعدة البيانات الثلاثية.
|
||||
=======
|
||||
استقبل مُعرّف المستند بدلاً من المحتوى، وجلبه من المكتبة.
|
||||
أضف عميل المكتبة إلى خدمة المقطع.
|
||||
جلب محتوى الصفحة باستخدام مُعرّف المستند.
|
||||
|
||||
**2. واجهة جديدة: عميل المكتبة (للكتابة)**
|
||||
|
||||
احفظ كل جزء كمستند فرعي في المكتبة.
|
||||
لكل جزء: اتصل بـ `add-child-document` مع `parent = مُعرّف مستند الصفحة`
|
||||
|
||||
**3. واجهة جديدة: اتصال بالمستودع الثلاثي**
|
||||
|
||||
أرسل علاقات الأبناء إلى الرسم البياني المعرفي.
|
||||
أضف عميل/ناشر المستودع الثلاثي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
لكل جزء: أرسل علاقة تربط مستند الجزء بمستند الصفحة.
|
||||
|
||||
**4. تغيير تنسيق الإخراج**
|
||||
|
||||
<<<<<<< HEAD
|
||||
أرسل كلاً من مُعرّف مستند الجزء ومحتوى الجزء (تحسين لاحق للمقطع).
|
||||
تستقبل المعالجات اللاحقة المعرّف لأغراض التتبع + المحتوى للعمل به.
|
||||
=======
|
||||
أرسل كلاً من مُعرّف مستند الجزء ومحتوى الجزء (تحسين بعد تقسيم الجزء).
|
||||
تتلقى المعالجات اللاحقة المعرّف لتتبع المصدر + المحتوى للعمل به.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### ملخص التغييرات في الواجهة
|
||||
|
||||
| الواجهة | التغيير |
|
||||
|-----------|--------|
|
||||
| رسالة الإدخال | تغيير من المحتوى إلى مُعرّف المستند |
|
||||
<<<<<<< HEAD
|
||||
| أمين المكتبة (Librarian) | واجهة تصدير جديدة (قراءة وكتابة) - جلب المحتوى، حفظ المستندات الفرعية |
|
||||
| قاعدة البيانات الثلاثية (Triple store) | واجهة تصدير جديدة - إرسال علاقات الأبناء والبنات |
|
||||
=======
|
||||
| المكتبة (librarian) | إخراج جديد (قراءة وكتابة) - جلب المحتوى، حفظ المستندات الفرعية |
|
||||
| المستودع الثلاثي (Triple store) | إخراج جديد - إرسال علاقات الأبناء |
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
| رسالة الإخراج | تغيير من المحتوى فقط إلى المعرّف + المحتوى |
|
||||
|
||||
### تغييرات مُستخرج المعرفة (Knowledge Extractor)
|
||||
|
||||
#### الحالة الحالية
|
||||
|
||||
<<<<<<< HEAD
|
||||
يستقبل محتوى الجزء
|
||||
يستخرج الثلاثيات والتضمينات
|
||||
يرسل إلى قاعدة البيانات الثلاثية ومخزن التضمينات
|
||||
`subjectOf` تشير العلاقة إلى المستند ذي المستوى الأعلى (وليس الجزء)
|
||||
=======
|
||||
يتلقى محتوى الجزء
|
||||
يستخرج الثلاثيات والتضمينات
|
||||
يرسل إلى المستودع الثلاثي ومستودع التضمينات
|
||||
تشير علاقة `subjectOf` إلى المستند ذي المستوى الأعلى (وليس الجزء).
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### التغييرات المطلوبة
|
||||
|
||||
**1. تغيير طريقة معالجة الإدخال**
|
||||
|
||||
استقبل مُعرّف مستند الجزء بالإضافة إلى المحتوى.
|
||||
<<<<<<< HEAD
|
||||
استخدم مُعرّف الجزء لأغراض الربط (المحتوى مدرج بالفعل كتحسين).
|
||||
|
||||
**2. تحديث أثر الثلاثيات**
|
||||
|
||||
اربط الثلاثيات المستخرجة بالجزء (وليس المستند ذي المستوى الأعلى).
|
||||
استخدم التجريد لإنشاء حافة تشير إلى الحافة
|
||||
`subjectOf` العلاقة: ثلاثية → مُعرّف مستند الجزء
|
||||
الاستخدام الأول للدعم الحالي للتجريد
|
||||
|
||||
**3. تحديث أثر التضمينات**
|
||||
|
||||
اربط معرفات كيانات التضمين بالجزء.
|
||||
أرسل حافة: معرف كيان التضمين → مُعرّف مستند الجزء
|
||||
=======
|
||||
استخدم مُعرّف الجزء لتتبع المصدر (تم تضمين المحتوى بالفعل كجزء من التحسين).
|
||||
|
||||
**2. تحديث تتبع المصدر**
|
||||
|
||||
اربط الثلاثيات المستخرجة بالجزء (وليس المستند ذي المستوى الأعلى).
|
||||
استخدم التجريد لإنشاء حافة تشير إلى الحافة.
|
||||
علاقة `subjectOf`: الثلاثية → مُعرّف مستند الجزء
|
||||
الاستخدام الأول للدعم الحالي للتجريد.
|
||||
|
||||
**3. تحديث تتبع التضمينات**
|
||||
|
||||
اربط معرفات كيانات التضمين بالجزء.
|
||||
أرسل حافة: معرف كيان التضمين → مُعرّف مستند الجزء.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### ملخص التغييرات في الواجهة
|
||||
|
||||
| الواجهة | التغيير |
|
||||
|-----------|--------|
|
||||
| رسالة الإدخال | توقع مُعرّف الجزء + المحتوى (وليس المحتوى فقط) |
|
||||
<<<<<<< HEAD
|
||||
| قاعدة البيانات الثلاثية | استخدم التجريد لأثر الثلاثية → الجزء |
|
||||
| أثر التضمين | اربط معرف الكيان → معرف الجزء |
|
||||
|
||||
## المراجع
|
||||
|
||||
أثر وقت الاستعلام: `docs/tech-specs/query-time-provenance.md`
|
||||
معيار PROV-O لنمذجة الأثر
|
||||
البيانات الوصفية المصدر الحالية في الرسم البياني المعرفي (تحتاج إلى تدقيق)
|
||||
=======
|
||||
| المستودع الثلاثي (Triple store) | استخدم التجريد لتتبع الثلاثية → الجزء |
|
||||
| تتبع التضمينات | اربط معرف الكيان → معرف الجزء |
|
||||
|
||||
## المراجع
|
||||
|
||||
تتبع وقت الاستعلام: `docs/tech-specs/query-time-provenance.md`
|
||||
معيار PROV-O لنمذجة التتبع.
|
||||
البيانات الوصفية المصدر الحالية في الرسم البياني المعرفي (تحتاج إلى تدقيق).
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
311
docs/tech-specs/ar/flow-class-definition.ar.md
Normal file
311
docs/tech-specs/ar/flow-class-definition.ar.md
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات تعريف مخطط التدفق"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
<<<<<<< HEAD
|
||||
# مواصفات تعريف مخطط التدفق
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
=======
|
||||
# تعريف مواصفات مخطط التدفق
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يحدد مخطط التدفق قالبًا كاملاً لنمط تدفق البيانات في نظام TrustGraph. عند تنفيذه، فإنه ينشئ شبكة مترابطة من المعالجات التي تتعامل مع استيعاب البيانات ومعالجتها وتخزينها والاستعلام عنها كنظام موحد.
|
||||
|
||||
## الهيكل
|
||||
|
||||
يتكون تعريف مخطط التدفق من خمسة أقسام رئيسية:
|
||||
|
||||
### 1. قسم الفئة
|
||||
يحدد معالجات الخدمات المشتركة التي يتم إنشاؤها مرة واحدة لكل مخطط تدفق. تتعامل هذه المعالجات مع الطلبات من جميع مثيلات التدفق لهذه الفئة.
|
||||
|
||||
```json
|
||||
"class": {
|
||||
"service-name:{class}": {
|
||||
"request": "queue-pattern:{class}",
|
||||
"response": "queue-pattern:{class}",
|
||||
"settings": {
|
||||
"setting-name": "fixed-value",
|
||||
"parameterized-setting": "{parameter-name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**الخصائص:**
|
||||
مشتركة عبر جميع مثيلات التدفق من نفس الفئة.
|
||||
عادةً ما تكون خدمات مكلفة أو غير تعتمد على الحالة (نماذج لغوية كبيرة، نماذج تضمين).
|
||||
استخدم متغير القالب `{class}` لتسمية قائمة الانتظار.
|
||||
يمكن أن تكون الإعدادات قيمًا ثابتة أو مُعَلمة باستخدام صيغة `{parameter-name}`.
|
||||
أمثلة: `embeddings:{class}`، `text-completion:{class}`، `graph-rag:{class}`.
|
||||
|
||||
### 2. قسم التدفق
|
||||
يحدد المعالجات الخاصة بالتدفق والتي يتم إنشاؤها لكل مثيل تدفق فردي. يحصل كل تدفق على مجموعة معزولة خاصة به من هذه المعالجات.
|
||||
|
||||
```json
|
||||
"flow": {
|
||||
"processor-name:{id}": {
|
||||
"input": "queue-pattern:{id}",
|
||||
"output": "queue-pattern:{id}",
|
||||
"settings": {
|
||||
"setting-name": "fixed-value",
|
||||
"parameterized-setting": "{parameter-name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**الخصائص:**
|
||||
نسخة فريدة لكل تدفق.
|
||||
التعامل مع البيانات والحالة الخاصة بالتدفق.
|
||||
استخدام متغير القالب `{id}` لأسماء قوائم الانتظار.
|
||||
يمكن أن تكون الإعدادات قيمًا ثابتة أو مُعَلمة باستخدام صيغة `{parameter-name}`.
|
||||
أمثلة: `chunker:{id}`، `pdf-decoder:{id}`، `kg-extract-relationships:{id}`.
|
||||
|
||||
### القسم 3: الواجهات
|
||||
يحدد نقاط الدخول وعقود التفاعل للتدفق. تشكل هذه الواجهة البرمجية (API) للأنظمة الخارجية وتواصل المكونات الداخلية.
|
||||
|
||||
يمكن أن تتخذ الواجهات شكلين:
|
||||
|
||||
**نمط الإرسال والإهمال** (قائمة انتظار واحدة):
|
||||
```json
|
||||
"interfaces": {
|
||||
"document-load": "persistent://tg/flow/document-load:{id}",
|
||||
"triples-store": "persistent://tg/flow/triples-store:{id}"
|
||||
}
|
||||
```
|
||||
|
||||
**نمط الطلب/الاستجابة** (كائن يحتوي على حقول الطلب/الاستجابة):
|
||||
```json
|
||||
"interfaces": {
|
||||
"embeddings": {
|
||||
"request": "non-persistent://tg/request/embeddings:{class}",
|
||||
"response": "non-persistent://tg/response/embeddings:{class}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**أنواع الواجهات:**
|
||||
**نقاط الدخول:** الأماكن التي تقوم الأنظمة الخارجية بإدخال البيانات (`document-load`، `agent`)
|
||||
**واجهات الخدمات:** أنماط الطلب/الاستجابة للخدمات (`embeddings`، `text-completion`)
|
||||
**واجهات البيانات:** نقاط اتصال تدفق البيانات من نوع "أرسل وانتهى" (`triples-store`، `entity-contexts-load`)
|
||||
|
||||
### القسم الرابع: معلمات
|
||||
يربط أسماء المعلمات الخاصة بالتدفق بتعريفات المعلمات المخزنة مركزيًا:
|
||||
|
||||
```json
|
||||
"parameters": {
|
||||
"model": "llm-model",
|
||||
"temp": "temperature",
|
||||
"chunk": "chunk-size"
|
||||
}
|
||||
```
|
||||
|
||||
**الخصائص:**
|
||||
المفاتيح هي أسماء المعلمات المستخدمة في إعدادات المعالج (مثل: `{model}`)
|
||||
القيم تشير إلى تعريفات المعلمات المخزنة في schema/config
|
||||
يتيح إعادة استخدام تعريفات المعلمات الشائعة عبر التدفقات.
|
||||
يقلل من تكرار مخططات المعلمات.
|
||||
|
||||
### 5. البيانات الوصفية
|
||||
معلومات إضافية حول مخطط التدفق:
|
||||
|
||||
```json
|
||||
"description": "Human-readable description",
|
||||
"tags": ["capability-1", "capability-2"]
|
||||
```
|
||||
|
||||
## متغيرات القالب
|
||||
|
||||
### متغيرات النظام
|
||||
|
||||
#### {id}
|
||||
يتم استبدالها بمعرّف مثيل التدفق الفريد.
|
||||
<<<<<<< HEAD
|
||||
تقوم بإنشاء موارد معزولة لكل تدفق.
|
||||
=======
|
||||
تنشئ موارد معزولة لكل تدفق.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
مثال: `flow-123`، `customer-A-flow`
|
||||
|
||||
#### {class}
|
||||
يتم استبدالها باسم مخطط التدفق.
|
||||
<<<<<<< HEAD
|
||||
تقوم بإنشاء موارد مشتركة عبر التدفقات من نفس الفئة.
|
||||
=======
|
||||
تنشئ موارد مشتركة عبر التدفقات من نفس الفئة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
مثال: `standard-rag`، `enterprise-rag`
|
||||
|
||||
### متغيرات المعلمات
|
||||
|
||||
#### {parameter-name}
|
||||
معلمات مخصصة يتم تعريفها في وقت بدء التدفق.
|
||||
تتطابق أسماء المعلمات مع المفاتيح الموجودة في قسم `parameters` الخاص بالتدفق.
|
||||
تُستخدم في إعدادات المعالج لتخصيص السلوك.
|
||||
أمثلة: `{model}`، `{temp}`، `{chunk}`
|
||||
يتم استبدالها بالقيم المقدمة عند بدء التدفق.
|
||||
يتم التحقق من صحتها مقابل تعريفات المعلمات المخزنة مركزيًا.
|
||||
|
||||
## إعدادات المعالج
|
||||
|
||||
توفر الإعدادات قيم التكوين للمعالجات في وقت الإنشاء. يمكن أن تكون:
|
||||
|
||||
### إعدادات ثابتة
|
||||
قيم مباشرة لا تتغير:
|
||||
```json
|
||||
"settings": {
|
||||
"model": "gemma3:12b",
|
||||
"temperature": 0.7,
|
||||
"max_retries": 3
|
||||
}
|
||||
```
|
||||
|
||||
### الإعدادات ذات المعلمات
|
||||
القيم التي تستخدم معلمات يتم توفيرها عند بدء تشغيل التدفق:
|
||||
```json
|
||||
"settings": {
|
||||
"model": "{model}",
|
||||
"temperature": "{temp}",
|
||||
"endpoint": "https://{region}.api.example.com"
|
||||
}
|
||||
```
|
||||
|
||||
تتوافق أسماء المعلمات في الإعدادات مع المفاتيح في قسم `parameters` الخاص بالتدفق.
|
||||
|
||||
### أمثلة للإعدادات
|
||||
|
||||
**معالج نماذج اللغة الكبيرة مع المعلمات:**
|
||||
```json
|
||||
// In parameters section:
|
||||
"parameters": {
|
||||
"model": "llm-model",
|
||||
"temp": "temperature",
|
||||
"tokens": "max-tokens",
|
||||
"key": "openai-api-key"
|
||||
}
|
||||
|
||||
// In processor definition:
|
||||
"text-completion:{class}": {
|
||||
"request": "non-persistent://tg/request/text-completion:{class}",
|
||||
"response": "non-persistent://tg/response/text-completion:{class}",
|
||||
"settings": {
|
||||
"model": "{model}",
|
||||
"temperature": "{temp}",
|
||||
"max_tokens": "{tokens}",
|
||||
"api_key": "{key}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**تقسيم النص بإعدادات ثابتة ومعلمات:**
|
||||
```json
|
||||
// In parameters section:
|
||||
"parameters": {
|
||||
"chunk": "chunk-size"
|
||||
}
|
||||
|
||||
// In processor definition:
|
||||
"chunker:{id}": {
|
||||
"input": "persistent://tg/flow/chunk:{id}",
|
||||
"output": "persistent://tg/flow/chunk-load:{id}",
|
||||
"settings": {
|
||||
"chunk_size": "{chunk}",
|
||||
"chunk_overlap": 100,
|
||||
"encoding": "utf-8"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
## أنماط قائمة الانتظار (بالمسر)
|
||||
|
||||
تستخدم مخططات التدفق Apache Pulsar للرسائل. تتبع أسماء قوائم الانتظار تنسيق بالمسر:
|
||||
=======
|
||||
## أنماط قائمة الانتظار (بالمار)
|
||||
|
||||
تستخدم مخططات التدفق Apache Pulsar للرسائل. تتبع أسماء قوائم الانتظار تنسيق بالمار:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
```
|
||||
<persistence>://<tenant>/<namespace>/<topic>
|
||||
```
|
||||
|
||||
### المكونات:
|
||||
**الاستمرارية**: `persistent` أو `non-persistent` (وضع استمرارية Pulsar)
|
||||
**المستأجر**: `tg` لتعريفات مخطط التدفق المقدمة من TrustGraph
|
||||
**مساحة الاسم**: تشير إلى نمط الرسائل
|
||||
`flow`: خدمات الإرسال والاستقبال
|
||||
`request`: الجزء الطلب من خدمات الطلب/الاستجابة
|
||||
`response`: الجزء الاستجابة من خدمات الطلب/الاستجابة
|
||||
**الموضوع**: اسم قائمة الانتظار/الموضوع المحدد مع متغيرات القالب
|
||||
|
||||
### قوائم الانتظار الدائمة
|
||||
النمط: `persistent://tg/flow/<topic>:{id}`
|
||||
تستخدم لخدمات الإرسال والاستقبال وتدفق البيانات المتينة
|
||||
تظل البيانات في تخزين Pulsar عبر عمليات إعادة التشغيل
|
||||
مثال: `persistent://tg/flow/chunk-load:{id}`
|
||||
|
||||
### قوائم الانتظار غير الدائمة
|
||||
النمط: `non-persistent://tg/request/<topic>:{class}` أو `non-persistent://tg/response/<topic>:{class}`
|
||||
تستخدم لأنماط الرسائل الطلب/الاستجابة
|
||||
مؤقتة، ولا يتم حفظها على القرص بواسطة Pulsar
|
||||
زمن انتقال أقل، ومناسبة للاتصالات على غرار RPC
|
||||
مثال: `non-persistent://tg/request/embeddings:{class}`
|
||||
|
||||
## بنية تدفق البيانات
|
||||
|
||||
ينشئ مخطط التدفق تدفق بيانات موحد حيث:
|
||||
|
||||
1. **مسار معالجة المستندات**: يبدأ من الاستيعاب ويمر بالتحويل إلى التخزين
|
||||
2. **خدمات الاستعلام**: معالجات مدمجة تستعلم عن نفس مخازن البيانات والخدمات
|
||||
3. **الخدمات المشتركة**: معالجات مركزية يمكن لجميع التدفقات استخدامها
|
||||
4. **كتابة التخزين**: تحفظ البيانات المعالجة في المخازن المناسبة
|
||||
|
||||
<<<<<<< HEAD
|
||||
تعمل جميع المعالجات (سواء `{id}` و `{class}`) معًا كرسوم بيانية لتدفق بيانات متماسك، وليس كأنظمة منفصلة.
|
||||
=======
|
||||
تعمل جميع المعالجات (سواء `{id}` و `{class}`) معًا كرسوم بيانية لتدفق البيانات المتكاملة، وليس كأنظمة منفصلة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## مثال على إنشاء التدفق
|
||||
|
||||
المعطيات:
|
||||
معرف مثيل التدفق: `customer-A-flow`
|
||||
مخطط التدفق: `standard-rag`
|
||||
تعيينات معلمات التدفق:
|
||||
`"model": "llm-model"`
|
||||
`"temp": "temperature"`
|
||||
`"chunk": "chunk-size"`
|
||||
المعلمات المقدمة من المستخدم:
|
||||
`model`: `gpt-4`
|
||||
`temp`: `0.5`
|
||||
`chunk`: `512`
|
||||
|
||||
<<<<<<< HEAD
|
||||
التوسعات القالبية:
|
||||
=======
|
||||
توسعات القالب:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
`persistent://tg/flow/chunk-load:{id}` → `persistent://tg/flow/chunk-load:customer-A-flow`
|
||||
`non-persistent://tg/request/embeddings:{class}` → `non-persistent://tg/request/embeddings:standard-rag`
|
||||
`"model": "{model}"` → `"model": "gpt-4"`
|
||||
`"temperature": "{temp}"` → `"temperature": "0.5"`
|
||||
`"chunk_size": "{chunk}"` → `"chunk_size": "512"`
|
||||
|
||||
هذا ينشئ:
|
||||
مسار معالجة مستندات معزول لـ `customer-A-flow`
|
||||
خدمة تضمين مشتركة لجميع تدفقات `standard-rag`
|
||||
تدفق بيانات كامل من استيعاب المستندات إلى الاستعلام
|
||||
المعالجات مُكوَّنة بقيم المعلمات المقدمة
|
||||
|
||||
## المزايا
|
||||
|
||||
1. **كفاءة الموارد**: يتم مشاركة الخدمات المكلفة عبر التدفقات
|
||||
2. **عزل التدفق**: يحتوي كل تدفق على مسار معالجة بيانات خاص به
|
||||
3. **قابلية التوسع**: يمكن إنشاء مثيلات متعددة من نفس القالب
|
||||
4. **النمطية**: فصل واضح بين المكونات المشتركة والمكونات الخاصة بالتدفق
|
||||
5. **بنية موحدة**: الاستعلام والمعالجة جزء من تدفق البيانات نفسه
|
||||
619
docs/tech-specs/ar/flow-configurable-parameters.ar.md
Normal file
619
docs/tech-specs/ar/flow-configurable-parameters.ar.md
Normal file
|
|
@ -0,0 +1,619 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية لـ 'خطة سير العمل' (Flow Blueprint) للمعلمات القابلة للتكوين"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية لـ "خطة سير العمل" (Flow Blueprint) للمعلمات القابلة للتكوين
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفة تنفيذ المعلمات القابلة للتكوين لـ "خطط سير العمل" في TrustGraph. تتيح المعلمات للمستخدمين تخصيص معلمات المعالج في وقت بدء تشغيل سير العمل من خلال توفير قيم تحل محل العناصر النائبة للمعلمات في تعريف "خطة سير العمل".
|
||||
|
||||
تعمل المعلمات من خلال استبدال متغيرات القالب في معلمات المعالج، على غرار كيفية عمل المتغيرات `{id}` و `{class}`، ولكن مع قيم مقدمة من المستخدم.
|
||||
|
||||
يدعم التكامل أربعة حالات استخدام رئيسية:
|
||||
|
||||
1. **اختيار النموذج**: السماح للمستخدمين باختيار نماذج LLM مختلفة (مثل `gemma3:8b`، `gpt-4`، `claude-3`) للمعالجات.
|
||||
2. **تكوين الموارد**: تعديل معلمات المعالج مثل أحجام الدُفعات، وأحجام الدُفعات، وحدود التزامن.
|
||||
3. **الضبط الدقيق للسلوك**: تعديل سلوك المعالج من خلال معلمات مثل درجة الحرارة، والحد الأقصى للرموز، أو عتبات الاسترجاع.
|
||||
4. **معلمات خاصة بالبيئة**: تكوين نقاط النهاية، ومفاتيح API، أو عناوين URL خاصة بالمنطقة لكل عملية نشر.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**تكوين المعالج الديناميكي**: تمكين تكوين معلمات المعالج في وقت التشغيل من خلال استبدال المعلمات.
|
||||
**التحقق من صحة المعلمات**: توفير التحقق من النوع والتحقق من صحة المعلمات في وقت بدء تشغيل سير العمل.
|
||||
**القيم الافتراضية**: دعم القيم الافتراضية المعقولة مع السماح بالتجاوزات للمستخدمين المتقدمين.
|
||||
**استبدال القوالب**: استبدال العناصر النائبة للمعلمات في معلمات المعالج بسلاسة.
|
||||
**التكامل مع واجهة المستخدم**: تمكين إدخال المعلمات من خلال كل من واجهات برمجة التطبيقات وواجهات المستخدم.
|
||||
**الأمان من النوع**: التأكد من أن أنواع المعلمات تتطابق مع أنواع معلمات المعالج المتوقعة.
|
||||
**التوثيق**: مخططات معلمات ذاتية التوثيق داخل تعريفات "خطط سير العمل".
|
||||
**التوافق مع الإصدارات السابقة**: الحفاظ على التوافق مع "خطط سير العمل" الحالية التي لا تستخدم المعلمات.
|
||||
|
||||
## الخلفية
|
||||
|
||||
تدعم "خطط سير العمل" في TrustGraph الآن معلمات المعالج التي يمكن أن تحتوي إما على قيم ثابتة أو عناصر نائبة للمعلمات. هذا يخلق فرصة للتخصيص في وقت التشغيل.
|
||||
|
||||
تدعم معلمات المعالج الحالية:
|
||||
القيم الثابتة: `"model": "gemma3:12b"`
|
||||
العناصر النائبة للمعلمات: `"model": "gemma3:{model-size}"`
|
||||
|
||||
تحدد هذه المواصفة كيفية:
|
||||
الإعلان عن المعلمات في تعريفات "خطط سير العمل".
|
||||
التحقق من صحة المعلمات عند بدء تشغيل سير العمل.
|
||||
استبدال المعلمات في معلمات المعالج.
|
||||
<<<<<<< HEAD
|
||||
الكشف عنها من خلال واجهات برمجة التطبيقات وواجهات المستخدم.
|
||||
|
||||
من خلال الاستفادة من معلمات معلمات المعالج، يمكن لـ TrustGraph:
|
||||
تقليل تكرار "خطط سير العمل" باستخدام المعلمات للتغيرات.
|
||||
=======
|
||||
الكشف عن المعلمات من خلال واجهات برمجة التطبيقات وواجهات المستخدم.
|
||||
|
||||
من خلال الاستفادة من معلمات معلمات المعالج، يمكن لـ TrustGraph:
|
||||
تقليل تكرار "خطط سير العمل" باستخدام المعلمات للتنوعات.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
تمكين المستخدمين من ضبط سلوك المعالج دون تعديل التعريفات.
|
||||
دعم التكوينات الخاصة بالبيئة من خلال قيم المعلمات.
|
||||
الحفاظ على الأمان من النوع من خلال التحقق من صحة مخططات المعلمات.
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
يتطلب نظام المعلمات القابلة للتكوين المكونات الفنية التالية:
|
||||
|
||||
1. **تعريف مخطط المعلمات**
|
||||
تعريفات المعلمات المستندة إلى JSON Schema داخل بيانات تعريف "خطة سير العمل".
|
||||
تعريفات الأنواع بما في ذلك أنواع السلاسل والأرقام والمنطق والقوائم وأنواع الكائنات.
|
||||
قواعد التحقق من الصحة بما في ذلك القيم الدنيا/القصوى، والأنماط، والحقول المطلوبة.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/flow/definition.py
|
||||
|
||||
2. **محرك حل المعلمات**
|
||||
التحقق من صحة المعلمات في وقت التشغيل مقابل المخطط.
|
||||
تطبيق القيم الافتراضية للمعلمات غير المحددة.
|
||||
حقن المعلمات في سياق تنفيذ سير العمل.
|
||||
التحويل والتحويل من النوع حسب الحاجة.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/flow/parameter_resolver.py
|
||||
|
||||
3. **تكامل مخزن المعلمات**
|
||||
استرداد تعريفات المعلمات من نظام المخطط/التكوين.
|
||||
التخزين المؤقت لتعريفات المعلمات المستخدمة بشكل متكرر.
|
||||
التحقق من الصحة مقابل المخططات المخزنة مركزيًا.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/flow/parameter_store.py
|
||||
|
||||
4. **امتدادات مشغل سير العمل**
|
||||
امتدادات واجهة برمجة التطبيقات لقبول قيم المعلمات أثناء بدء تشغيل سير العمل.
|
||||
دقة تعيين المعلمات (أسماء سير العمل إلى أسماء التعريف).
|
||||
معالجة الأخطاء لمجموعات المعلمات غير الصالحة.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/flow/launcher.py
|
||||
|
||||
5. **نماذج واجهة المستخدم للمعلمات**
|
||||
إنشاء نماذج ديناميكية من بيانات تعريف معلمات سير العمل.
|
||||
عرض المعلمات بترتيب باستخدام `order`.
|
||||
تسميات وصفية للمعلمات باستخدام `description`.
|
||||
التحقق من صحة الإدخال مقابل تعريفات أنواع المعلمات.
|
||||
إعدادات مسبقة وقوالب للمعلمات.
|
||||
|
||||
الوحدة: trustgraph-ui/components/flow-parameters/
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### تعريفات المعلمات (مخزنة في المخطط/التكوين)
|
||||
|
||||
يتم تخزين تعريفات المعلمات مركزيًا في نظام المخطط والتكوين مع النوع "parameter-type":
|
||||
|
||||
```json
|
||||
{
|
||||
"llm-model": {
|
||||
"type": "string",
|
||||
"description": "LLM model to use",
|
||||
"default": "gpt-4",
|
||||
"enum": [
|
||||
{
|
||||
"id": "gpt-4",
|
||||
"description": "OpenAI GPT-4 (Most Capable)"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo",
|
||||
"description": "OpenAI GPT-3.5 Turbo (Fast & Efficient)"
|
||||
},
|
||||
{
|
||||
"id": "claude-3",
|
||||
"description": "Anthropic Claude 3 (Thoughtful & Safe)"
|
||||
},
|
||||
{
|
||||
"id": "gemma3:8b",
|
||||
"description": "Google Gemma 3 8B (Open Source)"
|
||||
}
|
||||
],
|
||||
"required": false
|
||||
},
|
||||
"model-size": {
|
||||
"type": "string",
|
||||
"description": "Model size variant",
|
||||
"default": "8b",
|
||||
"enum": ["2b", "8b", "12b", "70b"],
|
||||
"required": false
|
||||
},
|
||||
"temperature": {
|
||||
"type": "number",
|
||||
"description": "Model temperature for generation",
|
||||
"default": 0.7,
|
||||
"minimum": 0.0,
|
||||
"maximum": 2.0,
|
||||
"required": false
|
||||
},
|
||||
"chunk-size": {
|
||||
"type": "integer",
|
||||
"description": "Document chunk size",
|
||||
"default": 512,
|
||||
"minimum": 128,
|
||||
"maximum": 2048,
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### مخطط سير العمل مع مراجع المعلمات
|
||||
|
||||
<<<<<<< HEAD
|
||||
تحدد مخططات سير العمل بيانات وصفية للمعلمات مع مراجع للأنواع والأوصاف والترتيب:
|
||||
=======
|
||||
تحدد مخططات سير العمل بيانات تعريف المعلمات مع مراجع الأنواع والأوصاف والترتيب:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
```json
|
||||
{
|
||||
"flow_class": "document-analysis",
|
||||
"parameters": {
|
||||
"llm-model": {
|
||||
"type": "llm-model",
|
||||
"description": "Primary LLM model for text completion",
|
||||
"order": 1
|
||||
},
|
||||
"llm-rag-model": {
|
||||
"type": "llm-model",
|
||||
"description": "LLM model for RAG operations",
|
||||
"order": 2,
|
||||
"advanced": true,
|
||||
"controlled-by": "llm-model"
|
||||
},
|
||||
"llm-temperature": {
|
||||
"type": "temperature",
|
||||
"description": "Generation temperature for creativity control",
|
||||
"order": 3,
|
||||
"advanced": true
|
||||
},
|
||||
"chunk-size": {
|
||||
"type": "chunk-size",
|
||||
"description": "Document chunk size for processing",
|
||||
"order": 4,
|
||||
"advanced": true
|
||||
},
|
||||
"chunk-overlap": {
|
||||
"type": "integer",
|
||||
"description": "Overlap between document chunks",
|
||||
"order": 5,
|
||||
"advanced": true,
|
||||
"controlled-by": "chunk-size"
|
||||
}
|
||||
},
|
||||
"class": {
|
||||
"text-completion:{class}": {
|
||||
"request": "non-persistent://tg/request/text-completion:{class}",
|
||||
"response": "non-persistent://tg/response/text-completion:{class}",
|
||||
"parameters": {
|
||||
"model": "{llm-model}",
|
||||
"temperature": "{llm-temperature}"
|
||||
}
|
||||
},
|
||||
"rag-completion:{class}": {
|
||||
"request": "non-persistent://tg/request/rag-completion:{class}",
|
||||
"response": "non-persistent://tg/response/rag-completion:{class}",
|
||||
"parameters": {
|
||||
"model": "{llm-rag-model}",
|
||||
"temperature": "{llm-temperature}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"flow": {
|
||||
"chunker:{id}": {
|
||||
"input": "persistent://tg/flow/chunk:{id}",
|
||||
"output": "persistent://tg/flow/chunk-load:{id}",
|
||||
"parameters": {
|
||||
"chunk_size": "{chunk-size}",
|
||||
"chunk_overlap": "{chunk-overlap}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
القسم `parameters` يربط أسماء المعلمات الخاصة بالتدفق (المفاتيح) بكائنات بيانات تعريف المعلمات التي تحتوي على:
|
||||
`type`: مرجع إلى تعريف المعلمة المحدد مركزيًا (مثل "llm-model")
|
||||
`description`: وصف يمكن قراءته بواسطة الإنسان للعرض في واجهة المستخدم
|
||||
=======
|
||||
القسم `parameters` يربط أسماء المعلمات الخاصة بالتدفق (المفاتيح) بكائنات بيانات وصفية للمعلمات والتي تحتوي على:
|
||||
`type`: مرجع إلى تعريف المعلمة المحدد مركزيًا (مثل "llm-model")
|
||||
`description`: وصف قابل للقراءة بواسطة الإنسان للعرض في واجهة المستخدم
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
`order`: ترتيب العرض لنماذج المعلمات (تظهر الأرقام الأقل أولاً)
|
||||
`advanced` (اختياري): علامة منطقية تشير إلى ما إذا كانت هذه معلمة متقدمة (افتراضي: خطأ). عند تعيينها على "صحيح"، قد تخفي واجهة المستخدم هذه المعلمة افتراضيًا أو تضعها في قسم "متقدم"
|
||||
`controlled-by` (اختياري): اسم معلمة أخرى تتحكم في قيمة هذه المعلمة عند التواجد في الوضع البسيط. عند تحديدها، ترث هذه المعلمة قيمتها من المعلمة المتحكمة ما لم يتم تجاوزها بشكل صريح
|
||||
|
||||
تسمح هذه الطريقة بما يلي:
|
||||
تعريفات أنواع معلمات قابلة لإعادة الاستخدام عبر قوالب تدفق متعددة
|
||||
إدارة مركزية لأنواع المعلمات والتحقق من صحتها
|
||||
<<<<<<< HEAD
|
||||
أوصاف وترتيب المعلمات الخاصة بالتدفق
|
||||
=======
|
||||
أوصاف وترتيب معلمات خاصة بالتدفق
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
تجربة واجهة مستخدم محسنة مع نماذج معلمات وصفية
|
||||
التحقق من صحة المعلمات بشكل متسق عبر التدفقات
|
||||
إضافة سهلة لأنواع معلمات قياسية جديدة
|
||||
واجهة مستخدم مبسطة مع فصل الوضع الأساسي/المتقدم
|
||||
وراثة قيمة المعلمة للإعدادات ذات الصلة
|
||||
|
||||
#### طلب بدء تشغيل التدفق
|
||||
|
||||
تقبل واجهة برمجة تطبيقات بدء تشغيل التدفق المعلمات باستخدام أسماء المعلمات الخاصة بالتدفق:
|
||||
|
||||
```json
|
||||
{
|
||||
"flow_class": "document-analysis",
|
||||
"flow_id": "customer-A-flow",
|
||||
"parameters": {
|
||||
"llm-model": "claude-3",
|
||||
"llm-temperature": 0.5,
|
||||
"chunk-size": 1024
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
ملاحظة: في هذا المثال، `llm-rag-model` غير مقدمة بشكل صريح ولكنها سترث القيمة "claude-3" من `llm-model` بسبب علاقتها مع `controlled-by`. وبالمثل، يمكن أن ترث `chunk-overlap` قيمة محسوبة بناءً على `chunk-size`.
|
||||
|
||||
سيقوم النظام بما يلي:
|
||||
<<<<<<< HEAD
|
||||
1. استخراج بيانات تعريف المعلمات من تعريف مخطط التدفق
|
||||
2. مطابقة أسماء معلمات التدفق مع تعريفات أنواعها (على سبيل المثال، `llm-model` → نوع `llm-model`)
|
||||
3. حل علاقات "يتم التحكم بها" (على سبيل المثال، ترث `llm-rag-model` من `llm-model`)
|
||||
=======
|
||||
1. استخراج بيانات وصفية للمعلمات من تعريف مخطط التدفق
|
||||
2. ربط أسماء معلمات التدفق بتعريفات أنواعها (مثل: `llm-model` → نوع `llm-model`)
|
||||
3. حل علاقات "التحكم بواسطة" (مثل: `llm-rag-model` ترث من `llm-model`)
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
4. التحقق من صحة القيم المقدمة من المستخدم والقيم الموروثة مقابل تعريفات أنواع المعلمات
|
||||
5. استبدال القيم التي تم حلها في معلمات المعالج أثناء إنشاء التدفق
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
#### عملية حل المعلمات
|
||||
|
||||
عندما يتم بدء تدفق، يقوم النظام بتنفيذ الخطوات التالية لحل المعلمات:
|
||||
|
||||
<<<<<<< HEAD
|
||||
1. **تحميل مخطط التدفق**: تحميل تعريف مخطط التدفق واستخراج بيانات تعريف المعلمات
|
||||
2. **استخراج البيانات الوصفية**: استخراج `type`، `description`، `order`، `advanced`، و `controlled-by` لكل معلمة معرفة في قسم `parameters` الخاص بمخطط التدفق
|
||||
3. **البحث عن تعريف النوع**: لكل معلمة في مخطط التدفق:
|
||||
استرجاع تعريف نوع المعلمة من متجر المخطط/التكوين باستخدام حقل `type`
|
||||
=======
|
||||
1. **تحميل مخطط التدفق**: تحميل تعريف مخطط التدفق واستخراج بيانات وصفية للمعلمات
|
||||
2. **استخراج البيانات الوصفية**: استخراج `type`، `description`، `order`، `advanced`، و `controlled-by` لكل معلمة معرفة في قسم `parameters` الخاص بمخطط التدفق
|
||||
3. **البحث عن تعريف النوع**: لكل معلمة في مخطط التدفق:
|
||||
استرجاع تعريف نوع المعلمة من متجر المخططات/التكوين باستخدام حقل `type`
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
يتم تخزين تعريفات الأنواع مع النوع "parameter-type" في نظام التكوين
|
||||
يحتوي كل تعريف نوع على مخطط المعلمة والقيمة الافتراضية وقواعد التحقق من الصحة
|
||||
4. **حل القيمة الافتراضية**:
|
||||
لكل معلمة معرفة في مخطط التدفق:
|
||||
التحقق مما إذا كان المستخدم قد قدم قيمة لهذه المعلمة
|
||||
إذا لم يتم تقديم قيمة من قبل المستخدم، استخدم القيمة `default` من تعريف نوع المعلمة
|
||||
<<<<<<< HEAD
|
||||
إنشاء خريطة معلمات كاملة تحتوي على كل من القيم المقدمة من قبل المستخدم والقيم الافتراضية
|
||||
5. **حل إرث المعلمات** (علاقات "يتم التحكم بها"):
|
||||
=======
|
||||
إنشاء خريطة كاملة للمعلمات تحتوي على كل من القيم المقدمة من قبل المستخدم والقيم الافتراضية
|
||||
5. **حل إرث المعلمات** (علاقات "التحكم بواسطة"):
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
للمعلمات التي تحتوي على حقل `controlled-by`، تحقق مما إذا تم توفير قيمة بشكل صريح
|
||||
إذا لم يتم توفير قيمة صريحة، فقم بوراثة القيمة من المعلمة المسيطرة
|
||||
إذا كانت المعلمة المسيطرة أيضًا لا تحتوي على قيمة، فاستخدم القيمة الافتراضية من تعريف النوع
|
||||
التحقق من عدم وجود تبعيات دائرية في علاقات `controlled-by`
|
||||
6. **التحقق من الصحة**: التحقق من صحة مجموعة المعلمات الكاملة (القيم المقدمة من قبل المستخدم والقيم الافتراضية والقيم الموروثة) مقابل تعريفات الأنواع
|
||||
7. **التخزين**: تخزين مجموعة المعلمات التي تم حلها بالكامل مع مثيل التدفق لأغراض التدقيق
|
||||
<<<<<<< HEAD
|
||||
8. **الاستبدال القالب**: استبدال عناصر نائب المعلمات في معلمات المعالج بالقيم التي تم حلها
|
||||
=======
|
||||
8. **استبدال القوالب**: استبدال عناصر نطق المعلمات في معلمات المعالج بالقيم التي تم حلها
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
9. **إنشاء المعالجات**: إنشاء معالجات بمعلمات مستبدلة
|
||||
|
||||
**ملاحظات تنفيذ مهمة:**
|
||||
يجب على خدمة التدفق دمج المعلمات المقدمة من قبل المستخدم مع القيم الافتراضية من تعريفات أنواع المعلمات
|
||||
يجب تخزين مجموعة المعلمات الكاملة (بما في ذلك القيم الافتراضية المطبقة) مع التدفق لأغراض التتبع
|
||||
يحدث حل المعلمات في وقت بدء التدفق، وليس في وقت إنشاء المعالج
|
||||
يجب أن يؤدي عدم وجود معلمات مطلوبة بدون قيم افتراضية إلى فشل بدء التدفق مع رسالة خطأ واضحة
|
||||
|
||||
<<<<<<< HEAD
|
||||
#### إرث المعلمات مع "يتم التحكم بها"
|
||||
=======
|
||||
#### إرث المعلمات مع "التحكم بواسطة"
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
يتيح الحقل `controlled-by` وراثة قيمة المعلمة، وهو مفيد بشكل خاص لتبسيط واجهات المستخدم مع الحفاظ على المرونة:
|
||||
|
||||
**سيناريو مثال:**
|
||||
تتحكم المعلمة `llm-model` في نموذج LLM الأساسي
|
||||
تحتوي المعلمة `llm-rag-model` على `"controlled-by": "llm-model"`
|
||||
في الوضع البسيط، يؤدي تعيين `llm-model` إلى "gpt-4" تلقائيًا إلى تعيين `llm-rag-model` إلى "gpt-4" أيضًا
|
||||
في الوضع المتقدم، يمكن للمستخدمين تجاوز `llm-rag-model` بقيمة مختلفة
|
||||
|
||||
**قواعد الحل:**
|
||||
1. إذا كانت المعلمة تحتوي على قيمة مقدمة بشكل صريح، فاستخدم تلك القيمة
|
||||
2. إذا لم تكن هناك قيمة صريحة وتم تعيين `controlled-by`، فاستخدم قيمة المعلمة المسيطرة
|
||||
3. إذا كانت المعلمة المسيطرة لا تحتوي على قيمة، فارجع إلى القيمة الافتراضية من تعريف النوع
|
||||
4. تؤدي التبعيات الدائرية في علاقات `controlled-by` إلى خطأ في التحقق من الصحة
|
||||
|
||||
**سلوك واجهة المستخدم:**
|
||||
في الوضع الأساسي/البسيط: قد تكون المعلمات التي تحتوي على `controlled-by` مخفية أو معروضة كقراءة فقط مع القيمة الموروثة
|
||||
في الوضع المتقدم: يتم عرض جميع المعلمات ويمكن تكوينها بشكل فردي
|
||||
عندما تتغير المعلمة المسيطرة، يتم تحديث المعلمات التابعة تلقائيًا ما لم يتم تجاوزها بشكل صريح
|
||||
|
||||
#### تكامل Pulsar
|
||||
|
||||
1. **عملية بدء التدفق**
|
||||
يجب أن تقبل عملية بدء التدفق في Pulsar حقل `parameters` يحتوي على خريطة لقيم المعلمات
|
||||
يجب تحديث مخطط طلب بدء التدفق في Pulsar لتضمين الحقل الاختياري `parameters`
|
||||
مثال للطلب:
|
||||
```json
|
||||
{
|
||||
"flow_class": "document-analysis",
|
||||
"flow_id": "customer-A-flow",
|
||||
"parameters": {
|
||||
"model": "claude-3",
|
||||
"size": "12b",
|
||||
"temp": 0.5,
|
||||
"chunk": 1024
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **عملية الحصول على التدفق**
|
||||
يجب تحديث مخطط بولسر لـ "استجابة الحصول على التدفق" ليشمل الحقل `parameters`.
|
||||
يتيح ذلك للعملاء استرداد قيم المعلمات التي تم استخدامها عند بدء التدفق.
|
||||
مثال على الاستجابة:
|
||||
```json
|
||||
{
|
||||
"flow_id": "customer-A-flow",
|
||||
"flow_class": "document-analysis",
|
||||
"status": "running",
|
||||
"parameters": {
|
||||
"model": "claude-3",
|
||||
"size": "12b",
|
||||
"temp": 0.5,
|
||||
"chunk": 1024
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### تنفيذ خدمة التدفق
|
||||
|
||||
تتطلب خدمة تكوين التدفق (`trustgraph-flow/trustgraph/config/service/flow.py`) التحسينات التالية:
|
||||
|
||||
1. **وظيفة حل المعلمات**
|
||||
```python
|
||||
async def resolve_parameters(self, flow_class, user_params):
|
||||
"""
|
||||
Resolve parameters by merging user-provided values with defaults.
|
||||
|
||||
Args:
|
||||
flow_class: The flow blueprint definition dict
|
||||
user_params: User-provided parameters dict
|
||||
|
||||
Returns:
|
||||
Complete parameter dict with user values and defaults merged
|
||||
"""
|
||||
```
|
||||
|
||||
يجب أن تقوم هذه الدالة بما يلي:
|
||||
<<<<<<< HEAD
|
||||
استخراج بيانات تعريف المعلمات من قسم `parameters` في مخطط سير العمل.
|
||||
لكل معلمة، استرداد تعريف النوع الخاص بها من مستودع التكوين.
|
||||
=======
|
||||
استخراج بيانات تعريف المعلمات من قسم `parameters` في مخطط التدفق.
|
||||
لكل معلمة، استرجاع تعريف النوع الخاص بها من مستودع التكوين.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
تطبيق القيم الافتراضية لأي معلمات لم يتم توفيرها من قبل المستخدم.
|
||||
التعامل مع علاقات الوراثة `controlled-by`.
|
||||
إرجاع المجموعة الكاملة للمعلمات.
|
||||
|
||||
2. **الطريقة المعدلة `handle_start_flow`**
|
||||
<<<<<<< HEAD
|
||||
استدعاء `resolve_parameters` بعد تحميل مخطط سير العمل.
|
||||
استخدام المجموعة الكاملة للمعلمات التي تم حلها للاستبدال في القوالب.
|
||||
تخزين المجموعة الكاملة للمعلمات (وليس فقط المعلمات التي قدمها المستخدم) مع سير العمل.
|
||||
التحقق من أن جميع المعلمات المطلوبة لها قيم.
|
||||
|
||||
3. **استرداد أنواع المعلمات**
|
||||
=======
|
||||
استدعاء `resolve_parameters` بعد تحميل مخطط التدفق.
|
||||
استخدام المجموعة الكاملة للمعلمات التي تم حلها للاستبدال في القوالب.
|
||||
تخزين المجموعة الكاملة للمعلمات (وليس فقط المعلمات التي قدمها المستخدم) مع التدفق.
|
||||
التحقق من أن جميع المعلمات المطلوبة لها قيم.
|
||||
|
||||
3. **استرجاع أنواع المعلمات**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
يتم تخزين تعريفات أنواع المعلمات في التكوين بنوع "parameter-type".
|
||||
يحتوي كل تعريف نوع على مخطط وقيمة افتراضية وقواعد تحقق.
|
||||
تخزين أنواع المعلمات المستخدمة بشكل متكرر في ذاكرة التخزين المؤقت لتقليل عمليات البحث في التكوين.
|
||||
|
||||
#### تكامل نظام التكوين
|
||||
|
||||
<<<<<<< HEAD
|
||||
3. **تخزين كائنات سير العمل**
|
||||
عندما تتم إضافة سير عمل إلى نظام التكوين بواسطة مكون سير العمل في مدير التكوين، يجب أن تتضمن كائن سير العمل قيم المعلمات التي تم حلها.
|
||||
يحتاج مدير التكوين إلى تخزين كل من المعلمات التي قدمها المستخدم في الأصل والقيم التي تم حلها (مع تطبيق القيم الافتراضية).
|
||||
يجب أن تتضمن كائنات سير العمل في نظام التكوين:
|
||||
`parameters`: القيم النهائية للمعلمات التي تم حلها والتي تم استخدامها لسير العمل.
|
||||
=======
|
||||
3. **تخزين كائنات التدفق**
|
||||
عندما تتم إضافة تدفق إلى نظام التكوين بواسطة مكون التدفق في مدير التكوين، يجب أن تتضمن كائن التدفق قيم المعلمات التي تم حلها.
|
||||
يحتاج مدير التكوين إلى تخزين كل من المعلمات التي قدمها المستخدم في الأصل والقيم التي تم حلها (مع تطبيق القيم الافتراضية).
|
||||
يجب أن تتضمن كائنات التدفق في نظام التكوين:
|
||||
`parameters`: القيم النهائية للمعلمات التي تم حلها والتي تم استخدامها للتدفق.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### تكامل واجهة سطر الأوامر
|
||||
|
||||
4. **أوامر واجهة سطر الأوامر الخاصة بالمكتبة**
|
||||
<<<<<<< HEAD
|
||||
تحتاج أوامر واجهة سطر الأوامر التي تبدأ سير العمل إلى دعم المعلمات:
|
||||
قبول قيم المعلمات عبر علامات سطر الأوامر أو ملفات التكوين.
|
||||
التحقق من صحة المعلمات مقابل تعريفات مخطط سير العمل قبل الإرسال.
|
||||
دعم إدخال ملف المعلمات (JSON/YAML) لمجموعات المعلمات المعقدة.
|
||||
|
||||
تحتاج أوامر واجهة سطر الأوامر التي تعرض سير العمل إلى عرض معلومات المعلمات:
|
||||
عرض قيم المعلمات المستخدمة عند بدء سير العمل.
|
||||
عرض المعلمات المتاحة لمخطط سير عمل.
|
||||
=======
|
||||
تحتاج أوامر واجهة سطر الأوامر التي تبدأ التدفقات إلى دعم المعلمات:
|
||||
قبول قيم المعلمات عبر علامات سطر الأوامر أو ملفات التكوين.
|
||||
التحقق من صحة المعلمات مقابل تعريفات مخطط التدفق قبل الإرسال.
|
||||
دعم إدخال ملفات المعلمات (JSON/YAML) لمجموعات المعلمات المعقدة.
|
||||
|
||||
تحتاج أوامر واجهة سطر الأوامر التي تعرض التدفقات إلى عرض معلومات المعلمات:
|
||||
عرض قيم المعلمات المستخدمة عند بدء التدفق.
|
||||
عرض المعلمات المتاحة لمخطط تدفق.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
عرض مخططات التحقق من صحة المعلمات والقيم الافتراضية.
|
||||
|
||||
#### تكامل الفئة الأساسية للمعالج
|
||||
|
||||
5. **دعم ParameterSpec**
|
||||
<<<<<<< HEAD
|
||||
تحتاج الفئات الأساسية للمعالج إلى دعم استبدال المعلمات من خلال آلية ParametersSpec الحالية.
|
||||
يجب تحسين فئة ParametersSpec (الموجودة في نفس الوحدة النمطية مثل ConsumerSpec و ProducerSpec) إذا لزم الأمر لدعم استبدال القوالب للمعلمات.
|
||||
يجب أن تكون المعالجات قادرة على استدعاء ParametersSpec لتكوين معامها باستخدام قيم المعلمات التي تم حلها في وقت بدء سير العمل.
|
||||
يجب أن تقوم تنفيذ ParametersSpec بما يلي:
|
||||
قبول تكوينات المعلمات التي تحتوي على عناصر نائبة للمعلمات (مثل `{model}`، `{temperature}`).
|
||||
=======
|
||||
يجب أن تدعم الفئات الأساسية للمعالج استبدال المعلمات من خلال آلية ParametersSpec الحالية.
|
||||
يجب تحسين فئة ParametersSpec (الموجودة في نفس الوحدة كما ConsumerSpec و ProducerSpec) إذا لزم الأمر لدعم استبدال القوالب للمعلمات.
|
||||
يجب أن تكون المعالجات قادرة على استدعاء ParametersSpec لتكوين معامها باستخدام قيم المعلمات التي تم حلها في وقت بدء التدفق.
|
||||
يجب أن تقوم تنفيذ ParametersSpec بما يلي:
|
||||
قبول تكوينات المعلمات التي تحتوي على عناصر نائب للمعلمات (مثل `{model}`، `{temperature}`).
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
دعم استبدال المعلمات في وقت التشغيل عند إنشاء المعالج.
|
||||
التحقق من أن القيم المستبدلة تتطابق مع الأنواع والقيود المتوقعة.
|
||||
توفير معالجة الأخطاء للإشارات المفقودة أو غير الصالحة للمعلمات.
|
||||
|
||||
#### قواعد الاستبدال
|
||||
|
||||
تستخدم المعلمات التنسيق `{parameter-name}` في معلمات المعالج.
|
||||
<<<<<<< HEAD
|
||||
تتطابق أسماء المعلمات في المعلمات مع المفاتيح في قسم `parameters` في سير العمل.
|
||||
=======
|
||||
تتطابق أسماء المعلمات في المعلمات مع المفاتيح في قسم `parameters` في التدفق.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
يحدث الاستبدال جنبًا إلى جنب مع استبدال `{id}` و `{class}`.
|
||||
تؤدي الإشارات غير الصالحة للمعلمات إلى أخطاء في وقت بدء التشغيل.
|
||||
يحدث التحقق من النوع بناءً على تعريف المعلمة المخزن مركزيًا.
|
||||
**هام**: يتم تخزين جميع قيم المعلمات وإرسالها كسلاسل.
|
||||
يتم تحويل الأرقام إلى سلاسل (على سبيل المثال، `0.7` تصبح `"0.7"`).
|
||||
يتم تحويل القيم المنطقية إلى سلاسل صغيرة (على سبيل المثال، `true` تصبح `"true"`).
|
||||
هذا مطلوب بواسطة مخطط Pulsar الذي يحدد `parameters = Map(String())`.
|
||||
|
||||
مثال على الحل:
|
||||
```
|
||||
Flow parameter mapping: "model": "llm-model"
|
||||
Processor parameter: "model": "{model}"
|
||||
User provides: "model": "gemma3:8b"
|
||||
Final parameter: "model": "gemma3:8b"
|
||||
|
||||
Example with type conversion:
|
||||
Parameter type default: 0.7 (number)
|
||||
Stored in flow: "0.7" (string)
|
||||
Substituted in processor: "0.7" (string)
|
||||
```
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
اختبارات الوحدة للتحقق من صحة مخططات المعلمات.
|
||||
اختبارات التكامل لاستبدال المعلمات في معلمات المعالج.
|
||||
<<<<<<< HEAD
|
||||
اختبارات شاملة لإطلاق العمليات التدفقية بقيم معلمات مختلفة.
|
||||
اختبارات واجهة المستخدم لإنشاء النموذج والتحقق من صحة المعلمات.
|
||||
اختبارات الأداء للعمليات التدفقية التي تحتوي على العديد من المعلمات.
|
||||
=======
|
||||
اختبارات شاملة لإطلاق العمليات مع قيم معلمات مختلفة.
|
||||
اختبارات واجهة المستخدم لإنشاء النموذج والتحقق من صحة المعلمات.
|
||||
اختبارات الأداء للعمليات التي تحتوي على العديد من المعلمات.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
حالات حافة: معلمات مفقودة، وأنواع غير صالحة، وإشارات غير معرفة للمعلمات.
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
<<<<<<< HEAD
|
||||
1. يجب أن يستمر النظام في دعم مخططات العمليات التدفقية التي لا تحتوي على معلمات.
|
||||
معلنة.
|
||||
2. يجب أن يستمر النظام في دعم العمليات التدفقية التي لا يتم فيها تحديد أي معلمات:
|
||||
هذا يعمل للعمليات التدفقية التي لا تحتوي على معلمات، وللعمليات التدفقية التي تحتوي على معلمات
|
||||
=======
|
||||
1. يجب أن يستمر النظام في دعم نماذج العمليات بدون معلمات
|
||||
مُعرّفة.
|
||||
2. يجب أن يستمر النظام في دعم العمليات بدون تحديد معلمات:
|
||||
هذا يعمل للعمليات التي لا تحتوي على معلمات، وللعمليات التي تحتوي على معلمات
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
(لديها قيم افتراضية).
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
<<<<<<< HEAD
|
||||
س: هل يجب أن تدعم المعلمات كائنات متداخلة معقدة أم يجب الالتزام بأنواع بسيطة؟
|
||||
ج: سيتم ترميز قيم المعلمات كسلاسل نصية، لذلك من المحتمل أن نلتزم بالسلاسل النصية.
|
||||
|
||||
|
||||
س: هل يجب السماح بوضع عناصر نائب للمعلمات في أسماء قوائم الانتظار أم فقط في
|
||||
المعلمات؟
|
||||
ج: فقط في المعلمات لإزالة عمليات الحقن والحالات الحافة الغريبة.
|
||||
|
||||
س: كيف نتعامل مع التعارضات بين أسماء المعلمات والمتغيرات النظامية مثل
|
||||
`id` و `class`؟
|
||||
ج: من غير المسموح بتحديد المعرف (id) والفئة (class) عند إطلاق عملية تدفقية.
|
||||
|
||||
س: هل يجب أن ندعم المعلمات المحسوبة (المشتقة من معلمات أخرى)؟
|
||||
ج: مجرد استبدال السلاسل النصية لإزالة عمليات الحقن والحالات الحافة الغريبة.
|
||||
=======
|
||||
س: هل يجب أن تدعم المعلمات كائنات متداخلة معقدة أم تقتصر على الأنواع البسيطة؟
|
||||
ج: سيتم ترميز قيم المعلمات كسلاسل نصية، ومن المحتمل أن نلتزم بالسلاسل النصية.
|
||||
|
||||
|
||||
س: هل يجب السماح بوضع إشارات المعلمات في أسماء قوائم الانتظار أم فقط في
|
||||
المعلمات؟
|
||||
ج: فقط في المعلمات لإزالة الحقن والحالات الحافة الغريبة.
|
||||
|
||||
س: كيف نتعامل مع التعارضات بين أسماء المعلمات ومتغيرات النظام مثل
|
||||
`id` و `class`؟
|
||||
ج: من غير المسموح بتحديد المعرف (id) والفئة (class) عند إطلاق عملية.
|
||||
|
||||
س: هل يجب أن ندعم المعلمات المحسوبة (المشتقة من معلمات أخرى)؟
|
||||
ج: مجرد استبدال السلاسل النصية لإزالة الحقن والحالات الحافة الغريبة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## المراجع
|
||||
|
||||
مواصفات مخطط JSON: https://json-schema.org/
|
||||
<<<<<<< HEAD
|
||||
مواصفات تعريف مخطط العمليات التدفقية: docs/tech-specs/flow-class-definition.md
|
||||
=======
|
||||
مواصفات تعريف نموذج العملية: docs/tech-specs/flow-class-definition.md
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
344
docs/tech-specs/ar/graph-contexts.ar.md
Normal file
344
docs/tech-specs/ar/graph-contexts.ar.md
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات تقنية لسياق الرسم البياني"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات تقنية لسياق الرسم البياني
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات التغييرات التي تم إجراؤها على المكونات الأساسية للرسم البياني في TrustGraph لمواءمتها مع RDF 1.2 ولتقديم دعم كامل لسمات مجموعة بيانات RDF. هذا تغيير جذري لإصدار 2.x.
|
||||
|
||||
### إصدارات
|
||||
|
||||
- **2.0**: إصدار للمستخدمين الأوائل. تتوفر الميزات الأساسية، وقد لا تكون جاهزة تمامًا للإنتاج.
|
||||
- **2.1 / 2.2**: إصدار جاهز للإنتاج. الاستقرار والشمولية تم التحقق منهما.
|
||||
|
||||
إن توفير مرونة بشأن مستوى النضج هو مقصود - يمكن للمستخدمين الأوائل الوصول إلى إمكانيات جديدة قبل أن تصبح جميع الميزات جاهزة للإنتاج.
|
||||
|
||||
## الأهداف
|
||||
|
||||
الأهداف الرئيسية لهذا العمل هي تمكين البيانات الوصفية حول الحقائق/البيانات:
|
||||
|
||||
- **المعلومات الزمنية**: ربط الحقائق ببيانات وصفية تتعلق بالوقت
|
||||
- متى اعتبرت حقيقة صحيحة
|
||||
- متى أصبحت حقيقة صحيحة
|
||||
- متى اكتشف أن حقيقة غير صحيحة
|
||||
|
||||
- **الأصل/المصادر**: تتبع المصادر التي تدعم حقيقة ما
|
||||
- "هذه الحقيقة مدعومة من المصدر X"
|
||||
- ربط الحقائق بوثائقها الأصلية
|
||||
|
||||
- **الموثوقية/الثقة**: تسجيل التأكيدات حول الحقيقة
|
||||
- "الشخص P أعلن أن هذا صحيح"
|
||||
- "الشخص Q يدعي أن هذا غير صحيح"
|
||||
- تمكين تسجيل النقاط والتحقق من التعارض
|
||||
|
||||
**الفرضية**: Reification (RDF-star / quoted triples) هي الآلية الرئيسية لتحقيق هذه النتائج، حيث تتطلب جميعها إجراء بيانات حول البيانات.
|
||||
|
||||
## الخلفية
|
||||
|
||||
للتعبير عن "تم اكتشاف حقيقة (تعرف أليس بوب) في 2024-01-15" أو "يدعم المصدر X الادعاء (يسبب Y Z)"، تحتاج إلى الرجوع إلى حافة كشيء يمكنك إجراء بيانات حوله. لا تدعم الثلاثيات القياسية هذا.
|
||||
|
||||
### القيود الحالية
|
||||
|
||||
يمكن للفئة `Value` الحالية في `trustgraph-base/trustgraph/schema/core/primitives.py` أن تمثل:
|
||||
- عقد URI (`is_uri=True`)
|
||||
- قيم حرفية (`is_uri=False`)
|
||||
|
||||
يوجد الحقل `type` ولكنه لا يستخدم لتمثيل أنواع بيانات XSD.
|
||||
|
||||
## التصميم التقني
|
||||
|
||||
### ميزات RDF المدعومة
|
||||
|
||||
#### الميزات الأساسية (المرتبطة بأهداف إعادة التعريف)
|
||||
|
||||
ترتبط هذه الميزات بشكل مباشر بالأهداف الزمنية والأصل والموثوقية:
|
||||
|
||||
1. **RDF 1.2 Quoted Triples (RDF-star)**
|
||||
- حواف تشير إلى حواف أخرى
|
||||
- يمكن أن تظهر الثلاثية كـ subject أو object في ثلاثية أخرى
|
||||
- تمكن البيانات حول البيانات (reification)
|
||||
- الآلية الأساسية لتعليق الحقائق الفردية
|
||||
|
||||
2. **RDF Dataset / Named Graphs**
|
||||
- دعم رسوم بيانية مسماة متعددة داخل مجموعة بيانات
|
||||
- يتم تحديد كل رسم بياني بواسطة IRI
|
||||
- الانتقال من ثلاثيات (s, p, o) إلى أرباع (s, p, o, g)
|
||||
- يتضمن الرسم البياني الافتراضي بالإضافة إلى رسم بياني مسمى واحد أو أكثر
|
||||
- يمكن أن يكون IRI الرسم البياني subject في البيانات، على سبيل المثال:
|
||||
```
|
||||
<graph-source-A> <discoveredOn> "2024-01-15"
|
||||
<graph-source-A> <hasVeracity> "high"
|
||||
```
|
||||
- ملاحظة: الرسوم البيانية المسماة ميزة منفصلة عن إعادة التعريف. لها استخدامات تتجاوز تعليق البيانات (التقسيم، التحكم في الوصول، تنظيم مجموعة البيانات) ويجب اعتبارها قدرة متميزة.
|
||||
|
||||
3. **Blank Nodes** (دعم محدود)
|
||||
- عقد مجهولة الهوية بدون URI عالمي
|
||||
- مدعوم من أجل التوافق عند تحميل بيانات RDF خارجية
|
||||
- **حالة محدودة**: لا توجد ضمانات بشأن الهوية المستقرة بعد التحميل
|
||||
- ابحث عنها عبر استعلامات wildcard (تطابق عن طريق الاتصالات، وليس عن طريق المعرف)
|
||||
- ليست ميزة أساسية - لا تعتمد على معالجة دقيقة لعقد فارغة
|
||||
|
||||
#### إصلاحات فرعية (تغيير جذري للإصدار 2.0)
|
||||
|
||||
هذه الميزات ليست مرتبطة بشكل مباشر بأهداف إعادة التعريف ولكنها تحسينات قيمة يجب تضمينها أثناء إجراء تغييرات جذرية:
|
||||
|
||||
4. **Literal Datatypes**
|
||||
- استخدام الحقل `type` بشكل صحيح لأنواع بيانات XSD
|
||||
- أمثلة: xsd:string, xsd:integer, xsd:dateTime، إلخ.
|
||||
- يحل مشكلة حالية: لا يمكن تمثيل التواريخ أو الأعداد الصحيحة بشكل صحيح
|
||||
|
||||
5. **Language Tags**
|
||||
- دعم سمات اللغة على الحرفيات (`@en`, `@fr`, إلخ)
|
||||
- ملاحظة: تحتوي الحرفية على إما علامة لغة أو نوع بيانات، وليس كلاهما (باستثناء `rdf:langString`)
|
||||
- مهم لحالات الاستخدام المتعلقة بالذكاء الاصطناعي/اللغات المتعددة
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### Term (تغيير من Value)
|
||||
|
||||
سيتم إعادة تسمية الفئة `Value` إلى `Term` لتعكس بشكل أفضل المصطلحات الخاصة بـ RDF. تخدم عملية إعادة التسمية هذه غرضين:
|
||||
1. توافق التسمية مع مفاهيم RDF (يمكن أن يكون "Term" IRI أو عقدة فارغة أو حرفية أو ثلاثية مقتبسة - وليس مجرد "value")
|
||||
2. إجبار مراجعة التعليمات البرمجية عند واجهة التغيير الجذري - أي تعليمات برمجية لا تزال تشير إلى `Value` ستظهر بشكل واضح أنها معطلة وتحتاج إلى التحديث
|
||||
|
||||
يمكن أن يمثل Term:
|
||||
|
||||
- **IRI/URI** - عقدة/مورد مسماة
|
||||
- **Blank Node** - عقدة مجهولة الهوية ذات نطاق محلي
|
||||
- **Literal** - قيمة بيانات مع إما:
|
||||
- نوع بيانات (XSD type)، أو
|
||||
- علامة لغة
|
||||
- **Quoted Triple** - ثلاثية تستخدم كـ term (RDF 1.2)
|
||||
|
||||
##### النهج المختار: فئة واحدة مع مُميز نوع
|
||||
|
||||
تحدد متطلبات التسلسل الهيكل - هناك حاجة إلى مُميز نوع في التنسيق السلكي بغض النظر عن التمثيل في Python. الفئة الواحدة ذات نوع التمييز هي الأنسب وتتوافق مع نمط `Value` الحالي.
|
||||
|
||||
توفر رموز النوع أحادية الحرف تسلسلًا مضغوطًا:
|
||||
|
||||
```python
|
||||
from dataclasses import dataclass
|
||||
|
||||
# ثوابت أنواع Term
|
||||
IRI = "i" # عقدة URI
|
||||
BLANK = "b" # عقدة فارغة
|
||||
LITERAL = "l" # قيمة حرفية
|
||||
TRIPLE = "t" # ثلاثية مقتبسة (RDF 1.2)
|
||||
|
||||
@dataclass
|
||||
class Term:
|
||||
type: str = "" # واحد من: IRI, BLANK, LITERAL, TRIPLE
|
||||
|
||||
# لـ مصطلحات IRI (type == IRI)
|
||||
iri: str = ""
|
||||
|
||||
# لـ عقد فارغة (type == BLANK)
|
||||
id: str = ""
|
||||
|
||||
# لـ الحرفيات (type == LITERAL)
|
||||
value: str = ""
|
||||
datatype: str = "" # URI لنوع بيانات XSD (مستبعدة مع اللغة)
|
||||
language: str = "" # علامة لغة (مستبعدة مع نوع البيانات)
|
||||
|
||||
# لـ ثلاثيات مقتبسة (type == TRIPLE)
|
||||
triple: "Triple | None" = None
|
||||
```
|
||||
|
||||
أمثلة على الاستخدام:
|
||||
|
||||
```python
|
||||
# مصطلح IRI
|
||||
node = Term(type=IRI, iri="http://example.org/Alice")
|
||||
|
||||
# حرفية مع نوع بيانات
|
||||
age = Term(type=LITERAL, value="42", datatype="xsd:integer")
|
||||
|
||||
# حرفية مع علامة لغة
|
||||
label = Term(type=LITERAL, value="Hello", language="en")
|
||||
|
||||
# عقدة فارغة
|
||||
anon = Term(type=BLANK, id="_:b1")
|
||||
|
||||
# ثلاثية مقتبسة (بيانات حول بيانات)
|
||||
inner = Triple(
|
||||
s=Term(type=IRI, iri="http://example.org/Alice"),
|
||||
p=Term(type=IRI, iri="http://example.org/knows"),
|
||||
o=Term(type=IRI, iri="http://example.org/Bob"),
|
||||
)
|
||||
reified = Term(type=TRIPLE, triple=inner)
|
||||
```
|
||||
|
||||
#### البدائل التي تم أخذها في الاعتبار
|
||||
|
||||
**الخيار B: اتحاد الفئات المتخصصة** (`Term = IRI | BlankNode | Literal | QuotedTriple`)
|
||||
- مرفوض: لا يزال التسلسل يحتاج إلى مُميز نوع، مما يضيف تعقيدًا
|
||||
|
||||
**الخيار C: فئة أساسية مع فئات فرعية**
|
||||
- مرفوض: نفس مشكلة التسلسل، بالإضافة إلى تعقيدات وراثة dataclass
|
||||
|
||||
#### Triple / Quad
|
||||
|
||||
تكتسب الفئة `Triple` حقل اختياري للرسم البياني ليصبح أربعة:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Triple:
|
||||
s: Term | None = None # Subject
|
||||
p: Term | None = None # Predicate
|
||||
o: Term | None = None # Object
|
||||
g: str | None = None # اسم الرسم البياني (IRI)، None = الرسم البياني الافتراضي
|
||||
```
|
||||
|
||||
قرارات التصميم:
|
||||
- **اسم الحقل**: `g` لضمان الاتساق مع `s`, `p`, `o`
|
||||
- **اختياري**: `None` يعني الرسم البياني الافتراضي (غير المسمى)
|
||||
- **النوع**: سلسلة عادية (IRI) بدلاً من Term
|
||||
- أسماء الرسم البياني هي دائمًا IRIs
|
||||
- تم استبعاد العقد الفارغة كأسماء للرسوم البيانية (مربكة جدًا)
|
||||
- لا حاجة إلى آليات Term الكاملة
|
||||
|
||||
لاحظ أن اسم الفئة يظل `Triple` حتى لو كانت ثلاثية الآن. هذا يتجنب التغييرات الجذرية و "triple" هي لا تزال المصطلحات الشائعة. السياق البياني هو بيانات وصفية حول مكان وجود الثلاثية.
|
||||
|
||||
### أنماط استعلام مرشحة
|
||||
|
||||
يقبل محرك الاستعلام الحالي مجموعات من مصطلحات S, P, O. مع ثلاثيات مقتبسة، تصبح الثلاثية نفسها مصطلحًا صالحًا في هذه المواضع. فيما يلي أنماط استعلام مرشحة تدعم الأهداف الأصلية.
|
||||
|
||||
#### معاني معلمات الرسم البياني
|
||||
|
||||
باتباع اصطلاحات SPARQL للتوافق مع الإصدارات السابقة:
|
||||
|
||||
- **تم حذف `g` / None**: استعلام للرسم البياني الافتراضي فقط
|
||||
- **`g` = IRI محدد**: استعلام لهذا الرسم البياني المسمى فقط
|
||||
- **`g` = حرف جاموسي / `*`**: استعلام عبر جميع الرسوم البيانية (مكافئ لـ SPARQL
|
||||
`GRAPH ?g { ... }`)
|
||||
|
||||
هذا يحافظ على بساطة الاستعلامات البسيطة ويجعل استعلامات الرسم البياني المسماة اختيارية.
|
||||
|
||||
تدعم الاستعلامات عبر الرسوم البيانية (g=حرف جاموسي). يحتوي مخطط Cassandra على جداول مخصصة (SPOG, POSG, OSPG) حيث g هو عمود تجميع بدلاً من مفتاح التقسيم، مما يتيح استعلامات فعالة عبر جميع الرسوم البيانية.
|
||||
|
||||
#### استعلامات زمنية
|
||||
|
||||
**ابحث عن جميع الحقائق التي تم اكتشافها بعد تاريخ معين:**
|
||||
```
|
||||
S: ? # أي ثلاثية مقتبسة
|
||||
P: <discoveredOn>
|
||||
O: > "2024-01-15"^^xsd:date # مقارنة التاريخ
|
||||
```
|
||||
|
||||
**ابحث عن الوقت الذي اعتبرت فيه حقيقة صحيحة:**
|
||||
```
|
||||
S: << <Alice> <knows> <Bob> >> # ثلاثية مقتبسة كـ subject
|
||||
P: <believedTrueFrom>
|
||||
O: ? # يعيد التاريخ
|
||||
```
|
||||
|
||||
**ابحث عن الحقائق التي تبين أنها خاطئة:**
|
||||
```
|
||||
S: ? # أي ثلاثية مقتبسة
|
||||
P: <discoveredFalseOn>
|
||||
O: ? # له أي قيمة (موجود)
|
||||
```
|
||||
|
||||
#### استعلامات الأصل
|
||||
|
||||
**ابحث عن جميع الحقائق التي يدعمها مصدر معين:**
|
||||
```
|
||||
S: ? # أي ثلاثية مقتبسة
|
||||
P: <supportedBy>
|
||||
O: <source:document-123>
|
||||
```
|
||||
|
||||
**ابحث عن المصادر التي تدعم حقيقة معينة:**
|
||||
```
|
||||
S: << <DrugA> <treats> <DiseaseB> >> # ثلاثية مقتبسة كـ subject
|
||||
P: <supportedBy>
|
||||
O: ? # يعيد IRIs المصدر
|
||||
```
|
||||
|
||||
#### استعلامات الموثوقية
|
||||
|
||||
**ابحث عن التأكيدات التي أعلن شخص ما أنها صحيحة:**
|
||||
```
|
||||
S: ? # أي ثلاثية مقتبسة
|
||||
P: <assertedTrueBy>
|
||||
O: <person:Alice>
|
||||
```
|
||||
|
||||
**ابحث عن التأكيدات المتعارضة (نفس الحقيقة، موثوقية مختلفة):**
|
||||
```
|
||||
# الاستعلام الأول: الحقائق التي أعلنت صحتها
|
||||
S: ?
|
||||
P: <assertedTrueBy>
|
||||
O: ?
|
||||
|
||||
# الاستعلام الثاني: الحقائق التي أعلنت أنها خاطئة
|
||||
S: ?
|
||||
P: <assertedFalseBy>
|
||||
O: ?
|
||||
|
||||
# منطق التطبيق: ابحث عن تقاطع الـ subjects
|
||||
```
|
||||
|
||||
**ابحث عن الحقائق التي تقل فيها درجة الثقة عن حد معين:**
|
||||
```
|
||||
S: ?
|
||||
P: <trustScore>
|
||||
O: [threshold]
|
||||
```
|
||||
|
||||
### حد تخزين المتجهات
|
||||
|
||||
تستخدم مخازن المتجهات دائمًا IRIs فقط:
|
||||
- لا توجد حواف (ثلاثيات مقتبسة)
|
||||
- لا توجد قيم حرفية
|
||||
- لا توجد عقد فارغة
|
||||
|
||||
هذا يبقي تخزين المتجهات بسيطًا - يتعامل مع التشابه الدلالي للكائنات المسماة. يتعامل هيكل الرسم البياني مع العلاقات وإعادة التعريف والبيانات الوصفية. لا تعقد الثلاثيات المقتبسة والرسوم البيانية المسماة عمليات المتجهات.
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
الرسوم البيانية المسماة ليست ميزة أمان. تظل المستخدمون والمجموعات هي حدود الأمان. الرسوم البيانية المسماة مخصصة لتنظيم البيانات فقط وليست لإعادة التعريف.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
- يمكن أن تضيف الثلاثيات المقتبسة عمق التداخل - قد تؤثر على أداء الاستعلام
|
||||
- هناك حاجة إلى استراتيجيات فهرسة الرسم البياني المسماة للاستعلامات الفعالة الموجهة للرسم البياني
|
||||
- يجب أن يستوعب تصميم مخطط Cassandra تخزين الأربعة بكفاءة
|
||||
|
||||
### واجهة مستخدم مخزن المتجهات
|
||||
|
||||
دائمًا ما تشير مخازن المتجهات إلى IRIs فقط:
|
||||
- لا توجد حواف (ثلاثيات مقتبسة)
|
||||
- لا توجد قيم حرفية
|
||||
- لا توجد عقد فارغة
|
||||
|
||||
هذا يبقي مخزن المتجهات بسيطًا - يتعامل مع التشابه الدلالي للكائنات المسماة. يتعامل هيكل الرسم البياني مع العلاقات وإعادة التعريف والبيانات الوصفية. لا تعقد الثلاثيات المقتبسة والرسوم البيانية المسماة عمليات المتجهات.
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
استخدم استراتيجية الاختبار الحالية. نظرًا لأن هذا تغيير جذري، ركز بشكل كبير على مجموعة الاختبار الشاملة للتحقق من أن الهياكل الجديدة تعمل بشكل صحيح عبر جميع المكونات.
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
- 2.0 هو إصدار جذري؛ لا توجد توافقية مع الإصدارات السابقة مطلوبة
|
||||
- قد تتطلب البيانات الحالية ترحيلًا إلى مخطط جديد (سيتم تحديده بناءً على التصميم النهائي)
|
||||
- ضع في اعتبارك أدوات الترحيل لتحويل الثلاثيات الموجودة
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
- **العقد الفارغة**: تم تأكيد الدعم المحدود. قد تحتاج إلى تحديد استراتيجية skolemization (إنشاء IRIs عند التحميل أو الحفاظ على معرفات العقد الفارغة).
|
||||
- **بناء جملة الاستعلام**: ما هي البنية النحوية الملموسة لتحديد الثلاثيات المقتبسة في الاستعلامات؟ تحتاج إلى تعريف واجهة برمجة تطبيقات الاستعلام.
|
||||
- ~~**مفردات السمة**~~: تم الحل. أي عناصر من المفردات RDF الصالحة مسموح بها، بما في ذلك العناصر المخصصة التي يحددها المستخدم. افتراضات قليلة جدًا عن صلاحية RDF.
|
||||
- ~~**تأثير مستودع المتجهات**~~: تم الحل. تشير مستودعات المتجهات دائمًا إلى IRIs فقط - لا توجد حواف أو قيم حرفية أو عقد فارغة. لا تؤثر الثلاثيات المقتبسة وإعادة التعريف على مستودع المتجهات.
|
||||
- ~~**دلالات الرسم البياني المسماة**~~: تم الحل. الاستعلامات افتراضيًا هي الرسم البياني الافتراضي (تتوافق مع سلوك SPARQL، متوافقة مع الإصدارات السابقة). مطلوب معلمة رسم بياني صريحة للاستعلام عن الرسوم البيانية المسماة أو جميع الرسوم البيانية.
|
||||
|
||||
## المراجع
|
||||
|
||||
- [RDF 1.2 Concepts](https://www.w3.org/TR/rdf12-concepts/)
|
||||
- [RDF-star and SPARQL-star](https://w3c.github.io/rdf-star/)
|
||||
- [RDF Dataset](https://www.w3.org/TR/rdf11-concepts/#section-dataset)
|
||||
531
docs/tech-specs/ar/graphql-query.ar.md
Normal file
531
docs/tech-specs/ar/graphql-query.ar.md
Normal file
|
|
@ -0,0 +1,531 @@
|
|||
---
|
||||
layout: default
|
||||
title: "GraphQL Query Technical Specification"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# GraphQL Query Technical Specification
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## Overview
|
||||
|
||||
<<<<<<< HEAD
|
||||
تصف هذه المواصفات تنفيذ واجهة استعلام GraphQL للبيانات المنظمة المخزنة في Apache Cassandra. بناءً على إمكانات البيانات المنظمة الموضحة في المواصفات الموجودة في structured-data.md، يوضح هذا المستند كيفية تنفيذ استعلامات GraphQL على جداول Cassandra التي تحتوي على كائنات منظمة مستخرجة ومُدخلة.
|
||||
|
||||
سيوفر خدمة استعلام GraphQL واجهة مرنة وآمنة من حيث النوع للاستعلام عن البيانات المنظمة المخزنة في Cassandra. ستتكيف ديناميكيًا مع تغييرات المخطط، وتدعم الاستعلامات المعقدة بما في ذلك العلاقات بين الكائنات، وتتكامل بسلاسة مع بنية TrustGraph الحالية القائمة على الرسائل.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**دعم المخططات الديناميكي**: التكيف تلقائيًا مع تغييرات المخطط في التكوين دون إعادة تشغيل الخدمة.
|
||||
**الامتثال لمعايير GraphQL**: توفير واجهة GraphQL قياسية متوافقة مع أدوات GraphQL والعملاء الحاليين.
|
||||
**استعلامات Cassandra فعالة**: ترجمة استعلامات GraphQL إلى استعلامات Cassandra CQL فعالة مع احترام مفاتيح التقسيم والفهارس.
|
||||
**حل العلاقات**: دعم محللات الحقول GraphQL للعلاقات بين أنواع الكائنات المختلفة.
|
||||
**الأمان من حيث النوع**: ضمان تنفيذ الاستعلامات وتوليد الاستجابات بطريقة آمنة من حيث النوع بناءً على تعريفات المخطط.
|
||||
**أداء قابل للتوسع**: التعامل مع الاستعلامات المتزامنة بكفاءة مع تجميع الاتصالات وتحسين الاستعلامات المناسب.
|
||||
**التكامل مع الطلبات والاستجابات**: الحفاظ على التوافق مع نمط الطلب/الاستجابة القائم على Pulsar في TrustGraph.
|
||||
**معالجة الأخطاء**: توفير تقارير أخطاء شاملة لمطابقة المخططات وأخطاء الاستعلامات ومشكلات التحقق من صحة البيانات.
|
||||
|
||||
## الخلفية
|
||||
|
||||
تقوم عملية تخزين البيانات المنظمة (trustgraph-flow/trustgraph/storage/objects/cassandra/) بكتابة الكائنات إلى جداول Cassandra بناءً على تعريفات المخطط المخزنة في نظام تكوين TrustGraph. تستخدم هذه الجداول هيكل مفتاح تقسيم مركب مع مفاتيح أولية محددة في المجموعة ومحددة في المخطط، مما يتيح استعلامات فعالة داخل المجموعات.
|
||||
|
||||
القيود الحالية التي تعالجها هذه المواصفات:
|
||||
لا توجد واجهة استعلام للبيانات المنظمة المخزنة في Cassandra.
|
||||
عدم القدرة على الاستفادة من إمكانات الاستعلام القوية لـ GraphQL للبيانات المنظمة.
|
||||
عدم وجود دعم لتتبع العلاقات بين الكائنات ذات الصلة.
|
||||
عدم وجود لغة استعلام موحدة للوصول إلى البيانات المنظمة.
|
||||
|
||||
ستقوم خدمة استعلام GraphQL بسد هذه الفجوات من خلال:
|
||||
توفير واجهة GraphQL قياسية للاستعلام عن جداول Cassandra.
|
||||
توليد مخططات GraphQL ديناميكيًا من تكوين TrustGraph.
|
||||
ترجمة استعلامات GraphQL بكفاءة إلى Cassandra CQL.
|
||||
دعم حل العلاقات من خلال محللات الحقول.
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
سيتم تنفيذ خدمة استعلام GraphQL كمعالج TrustGraph جديد باتباع الأنماط الراسخة:
|
||||
|
||||
**الموقع**: `trustgraph-flow/trustgraph/query/objects/cassandra/`
|
||||
|
||||
**المكونات الرئيسية**:
|
||||
|
||||
1. **معالج خدمة استعلام GraphQL**:
|
||||
يرث من الفئة الأساسية FlowProcessor.
|
||||
ينفذ نمط الطلب/الاستجابة المشابه لخدمات الاستعلام الحالية.
|
||||
يراقب التكوين بحثًا عن تحديثات المخطط.
|
||||
يحافظ على تزامن مخطط GraphQL مع التكوين.
|
||||
|
||||
2. **مولد المخططات الديناميكي**:
|
||||
يحول تعريفات TrustGraph RowSchema إلى أنواع GraphQL.
|
||||
ينشئ أنواع كائنات GraphQL مع تعريفات الحقول المناسبة.
|
||||
يولد نوع الاستعلام الجذر مع محللات قائمة على المجموعة.
|
||||
يقوم بتحديث مخطط GraphQL عند حدوث تغييرات في التكوين.
|
||||
|
||||
3. **منفذ الاستعلام**:
|
||||
يحلل استعلامات GraphQL الواردة باستخدام مكتبة Strawberry.
|
||||
يتحقق من صحة الاستعلامات مقابل المخطط الحالي.
|
||||
ينفذ الاستعلامات ويعيد استجابات منظمة.
|
||||
يتعامل مع الأخطاء بأمان مع رسائل خطأ مفصلة.
|
||||
|
||||
4. **مترجم استعلامات Cassandra**:
|
||||
يحول عمليات اختيار GraphQL إلى استعلامات CQL.
|
||||
يحسن الاستعلامات بناءً على الفهارس ومفاتيح التقسيم المتاحة.
|
||||
يتعامل مع التصفية والتقسيم والترتيب.
|
||||
يدير تجميع الاتصالات ودورة حياة الجلسة.
|
||||
|
||||
5. **محلل العلاقات**:
|
||||
ينفذ محللات الحقول للعلاقات بين الكائنات.
|
||||
يقوم بتحميل دفعات بكفاءة لتجنب استعلامات N+1.
|
||||
يقوم بتخزين العلاقات التي تم حلها في سياق الطلب.
|
||||
يدعم كل من تتبع العلاقات الأمامية والعكسية.
|
||||
|
||||
### مراقبة مخطط التكوين
|
||||
|
||||
ستقوم الخدمة بتسجيل معالج تكوين لتلقي تحديثات المخطط:
|
||||
=======
|
||||
This specification describes the implementation of a GraphQL query interface for TrustGraph's structured data storage in Apache Cassandra. Building upon the structured data capabilities outlined in the structured-data.md specification, this document details how GraphQL queries will be executed against Cassandra tables containing extracted and ingested structured objects.
|
||||
|
||||
The GraphQL query service will provide a flexible, type-safe interface for querying structured data stored in Cassandra. It will dynamically adapt to schema changes, support complex queries including relationships between objects, and integrate seamlessly with TrustGraph's existing message-based architecture.
|
||||
|
||||
## Goals
|
||||
|
||||
**Dynamic Schema Support**: Automatically adapt to schema changes in configuration without service restarts
|
||||
**GraphQL Standards Compliance**: Provide a standard GraphQL interface compatible with existing GraphQL tooling and clients
|
||||
**Efficient Cassandra Queries**: Translate GraphQL queries into efficient Cassandra CQL queries respecting partition keys and indexes
|
||||
**Relationship Resolution**: Support GraphQL field resolvers for relationships between different object types
|
||||
**Type Safety**: Ensure type-safe query execution and response generation based on schema definitions
|
||||
**Scalable Performance**: Handle concurrent queries efficiently with proper connection pooling and query optimization
|
||||
**Request/Response Integration**: Maintain compatibility with TrustGraph's Pulsar-based request/response pattern
|
||||
**Error Handling**: Provide comprehensive error reporting for schema mismatches, query errors, and data validation issues
|
||||
|
||||
## Background
|
||||
|
||||
The structured data storage implementation (trustgraph-flow/trustgraph/storage/objects/cassandra/) writes objects to Cassandra tables based on schema definitions stored in TrustGraph's configuration system. These tables use a composite partition key structure with collection and schema-defined primary keys, enabling efficient queries within collections.
|
||||
|
||||
Current limitations that this specification addresses:
|
||||
No query interface for the structured data stored in Cassandra
|
||||
Inability to leverage GraphQL's powerful query capabilities for structured data
|
||||
Missing support for relationship traversal between related objects
|
||||
Lack of a standardized query language for structured data access
|
||||
|
||||
The GraphQL query service will bridge these gaps by:
|
||||
Providing a standard GraphQL interface for querying Cassandra tables
|
||||
Dynamically generating GraphQL schemas from TrustGraph configuration
|
||||
Efficiently translating GraphQL queries to Cassandra CQL
|
||||
Supporting relationship resolution through field resolvers
|
||||
|
||||
## Technical Design
|
||||
|
||||
### Architecture
|
||||
|
||||
The GraphQL query service will be implemented as a new TrustGraph flow processor following established patterns:
|
||||
|
||||
**Module Location**: `trustgraph-flow/trustgraph/query/objects/cassandra/`
|
||||
|
||||
**Key Components**:
|
||||
|
||||
1. **GraphQL Query Service Processor**
|
||||
Extends base FlowProcessor class
|
||||
Implements request/response pattern similar to existing query services
|
||||
Monitors configuration for schema updates
|
||||
Maintains GraphQL schema synchronized with configuration
|
||||
|
||||
2. **Dynamic Schema Generator**
|
||||
Converts TrustGraph RowSchema definitions to GraphQL types
|
||||
Creates GraphQL object types with proper field definitions
|
||||
Generates root Query type with collection-based resolvers
|
||||
Updates GraphQL schema when configuration changes
|
||||
|
||||
3. **Query Executor**
|
||||
Parses incoming GraphQL queries using Strawberry library
|
||||
Validates queries against current schema
|
||||
Executes queries and returns structured responses
|
||||
Handles errors gracefully with detailed error messages
|
||||
|
||||
4. **Cassandra Query Translator**
|
||||
Converts GraphQL selections to CQL queries
|
||||
Optimizes queries based on available indexes and partition keys
|
||||
Handles filtering, pagination, and sorting
|
||||
Manages connection pooling and session lifecycle
|
||||
|
||||
5. **Relationship Resolver**
|
||||
Implements field resolvers for object relationships
|
||||
Performs efficient batch loading to avoid N+1 queries
|
||||
Caches resolved relationships within request context
|
||||
Supports both forward and reverse relationship traversal
|
||||
|
||||
### Configuration Schema Monitoring
|
||||
|
||||
The service will register a configuration handler to receive schema updates:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
```python
|
||||
self.register_config_handler(self.on_schema_config)
|
||||
```
|
||||
|
||||
عندما تتغير المخططات:
|
||||
1. تحليل تعريفات المخططات الجديدة من التكوين.
|
||||
2. إعادة إنشاء أنواع GraphQL والمحللات.
|
||||
<<<<<<< HEAD
|
||||
3. تحديث المخطط القابل للتنفيذ.
|
||||
=======
|
||||
3. تحديث المخطط التنفيذي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
4. مسح أي ذاكرة تخزين مؤقت تعتمد على المخطط.
|
||||
|
||||
### توليد مخطط GraphQL
|
||||
|
||||
لكل RowSchema في التكوين، قم بإنشاء:
|
||||
|
||||
1. **نوع كائن GraphQL**:
|
||||
<<<<<<< HEAD
|
||||
مطابقة أنواع الحقول (string → String, integer → Int, float → Float, boolean → Boolean).
|
||||
=======
|
||||
تعيين أنواع الحقول (string → String, integer → Int, float → Float, boolean → Boolean).
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
وضع علامة على الحقول المطلوبة على أنها غير قابلة للقيم الفارغة في GraphQL.
|
||||
إضافة أوصاف الحقول من المخطط.
|
||||
|
||||
2. **حقول الاستعلام الجذرية**:
|
||||
استعلام المجموعة (مثل `customers`، `transactions`).
|
||||
وسائط التصفية بناءً على الحقول المفهرسة.
|
||||
دعم التقسيم (limit, offset).
|
||||
خيارات الفرز للحقول القابلة للفرز.
|
||||
|
||||
3. **حقول العلاقات**:
|
||||
تحديد علاقات المفاتيح الخارجية من المخطط.
|
||||
إنشاء محللات حقول للكائنات ذات الصلة.
|
||||
دعم كل من علاقات الكائنات الفردية وقوائم الكائنات.
|
||||
|
||||
### تدفق تنفيذ الاستعلام
|
||||
|
||||
1. **استقبال الطلب**:
|
||||
استقبال ObjectsQueryRequest من Pulsar.
|
||||
استخراج سلسلة استعلام GraphQL والمتغيرات.
|
||||
تحديد سياق المستخدم والمجموعة.
|
||||
|
||||
2. **التحقق من صحة الاستعلام**:
|
||||
تحليل استعلام GraphQL باستخدام Strawberry.
|
||||
التحقق من الصحة مقابل المخطط الحالي.
|
||||
التحقق من عمليات اختيار الحقول وأنواع الوسائط.
|
||||
|
||||
3. **توليد CQL**:
|
||||
تحليل عمليات اختيار GraphQL.
|
||||
إنشاء استعلام CQL مع عبارات WHERE المناسبة.
|
||||
تضمين المجموعة في مفتاح التقسيم.
|
||||
تطبيق عوامل التصفية بناءً على وسائط GraphQL.
|
||||
|
||||
4. **تنفيذ الاستعلام**:
|
||||
تنفيذ استعلام CQL مقابل Cassandra.
|
||||
<<<<<<< HEAD
|
||||
مطابقة النتائج مع هيكل استجابة GraphQL.
|
||||
=======
|
||||
تعيين النتائج إلى هيكل استجابة GraphQL.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
حل أي حقول علاقات.
|
||||
تنسيق الاستجابة وفقًا لمواصفات GraphQL.
|
||||
|
||||
5. **تسليم الاستجابة**:
|
||||
إنشاء ObjectsQueryResponse مع النتائج.
|
||||
تضمين أي أخطاء في التنفيذ.
|
||||
إرسال الاستجابة عبر Pulsar بمعرف الارتباط.
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
<<<<<<< HEAD
|
||||
> **ملاحظة**: يوجد مخطط StructuredQueryRequest/Response موجود في `trustgraph-base/trustgraph/schema/services/structured_query.py`. ومع ذلك، فإنه يفتقر إلى حقول مهمة (المستخدم، المجموعة) ويستخدم أنواعًا دون المستوى الأمثل. تمثل المخططات أدناه التطور الموصى به، والتي يجب إما أن تحل محل المخططات الحالية أو يتم إنشاؤها كأنواع ObjectsQueryRequest/Response جديدة.
|
||||
=======
|
||||
> **ملاحظة**: يوجد مخطط StructuredQueryRequest/Response موجود في `trustgraph-base/trustgraph/schema/services/structured_query.py`. ومع ذلك، فإنه يفتقر إلى حقول مهمة (المستخدم، المجموعة) ويستخدم أنواعًا دون المستوى الأمثل. تمثل المخططات أدناه التطور الموصى به، والتي يجب إما استبدال المخططات الموجودة بها أو إنشاؤها كأنواع ObjectsQueryRequest/Response جديدة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### مخطط الطلب (ObjectsQueryRequest)
|
||||
|
||||
```python
|
||||
from pulsar.schema import Record, String, Map, Array
|
||||
|
||||
class ObjectsQueryRequest(Record):
|
||||
user = String() # Cassandra keyspace (follows pattern from TriplesQueryRequest)
|
||||
collection = String() # Data collection identifier (required for partition key)
|
||||
query = String() # GraphQL query string
|
||||
variables = Map(String()) # GraphQL variables (consider enhancing to support all JSON types)
|
||||
operation_name = String() # Operation to execute for multi-operation documents
|
||||
```
|
||||
|
||||
**السبب وراء التغييرات من طلب الاستعلام المنظم الحالي:**
|
||||
تمت إضافة الحقول `user` و `collection` لمطابقة نمط خدمات الاستعلام الأخرى.
|
||||
هذه الحقول ضرورية لتحديد مساحة مفاتيح Cassandra والمجموعة.
|
||||
تظل المتغيرات كـ Map(String()) في الوقت الحالي، ولكن من الأفضل أن تدعم جميع أنواع JSON.
|
||||
|
||||
#### مخطط الاستجابة (ObjectsQueryResponse)
|
||||
|
||||
```python
|
||||
from pulsar.schema import Record, String, Array
|
||||
from ..core.primitives import Error
|
||||
|
||||
class GraphQLError(Record):
|
||||
message = String()
|
||||
path = Array(String()) # Path to the field that caused the error
|
||||
extensions = Map(String()) # Additional error metadata
|
||||
|
||||
class ObjectsQueryResponse(Record):
|
||||
error = Error() # System-level error (connection, timeout, etc.)
|
||||
data = String() # JSON-encoded GraphQL response data
|
||||
errors = Array(GraphQLError) # GraphQL field-level errors
|
||||
extensions = Map(String()) # Query metadata (execution time, etc.)
|
||||
```
|
||||
|
||||
**الأساس المنطقي للتغييرات من الاستجابة المنظمة للاستعلامات الحالية:**
|
||||
التمييز بين أخطاء النظام (`error`) وأخطاء GraphQL (`errors`).
|
||||
استخدام كائنات GraphQLError منظمة بدلاً من مصفوفة سلسلة.
|
||||
إضافة حقل `extensions` للامتثال لمواصفات GraphQL.
|
||||
الحفاظ على البيانات كسلسلة JSON للتوافق، على الرغم من أن الأنواع الأصلية ستكون مفضلة.
|
||||
|
||||
### تحسين استعلامات Cassandra
|
||||
|
||||
ستقوم الخدمة بتحسين استعلامات Cassandra عن طريق:
|
||||
|
||||
1. **احترام مفاتيح التقسيم:**
|
||||
تضمين المجموعة دائمًا في الاستعلامات.
|
||||
استخدام المفاتيح الأساسية المعرفة في المخطط بكفاءة.
|
||||
تجنب عمليات المسح الكاملة للجدول.
|
||||
|
||||
2. **الاستفادة من الفهارس:**
|
||||
استخدام الفهارس الثانوية للتصفية.
|
||||
دمج عوامل التصفية المتعددة كلما أمكن ذلك.
|
||||
<<<<<<< HEAD
|
||||
التحذير عندما قد تكون الاستعلامات غير فعالة.
|
||||
|
||||
3. **التحميل الدفعي:**
|
||||
جمع استعلامات العلاقات.
|
||||
=======
|
||||
إصدار تحذير عندما قد تكون الاستعلامات غير فعالة.
|
||||
|
||||
3. **التحميل الدفعي:**
|
||||
تجميع استعلامات العلاقات.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
تنفيذها على دفعات لتقليل عدد الرحلات ذهابًا وإيابًا.
|
||||
تخزين النتائج مؤقتًا داخل سياق الطلب.
|
||||
|
||||
4. **إدارة الاتصالات:**
|
||||
الحفاظ على جلسات Cassandra مستمرة.
|
||||
استخدام تجميع الاتصالات.
|
||||
<<<<<<< HEAD
|
||||
التعامل مع إعادة الاتصال في حالة حدوث أخطاء.
|
||||
=======
|
||||
التعامل مع إعادة الاتصال في حالة حدوث أعطال.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### أمثلة لاستعلامات GraphQL
|
||||
|
||||
#### استعلام بسيط للمجموعة
|
||||
```graphql
|
||||
{
|
||||
customers(status: "active") {
|
||||
customer_id
|
||||
name
|
||||
email
|
||||
registration_date
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### استعلام مع العلاقات
|
||||
```graphql
|
||||
{
|
||||
orders(order_date_gt: "2024-01-01") {
|
||||
order_id
|
||||
total_amount
|
||||
customer {
|
||||
name
|
||||
email
|
||||
}
|
||||
items {
|
||||
product_name
|
||||
quantity
|
||||
price
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### استعلام مُقسّم إلى صفحات
|
||||
```graphql
|
||||
{
|
||||
products(limit: 20, offset: 40) {
|
||||
product_id
|
||||
name
|
||||
price
|
||||
category
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### الاعتمادات الخاصة بالتنفيذ
|
||||
|
||||
**Strawberry GraphQL**: لتعريف مخطط GraphQL وتنفيذ الاستعلامات.
|
||||
**Cassandra Driver**: للاتصال بقاعدة البيانات (يتم استخدامه بالفعل في وحدة التخزين).
|
||||
**TrustGraph Base**: لـ FlowProcessor وتعريفات المخططات.
|
||||
**Configuration System**: لمراقبة المخططات وتحديثها.
|
||||
|
||||
### واجهة سطر الأوامر
|
||||
|
||||
سيوفر الخدمة أمر سطر أوامر: `kg-query-objects-graphql-cassandra`
|
||||
|
||||
الوسائط:
|
||||
`--cassandra-host`: نقطة اتصال مجموعة Cassandra.
|
||||
`--cassandra-username`: اسم مستخدم المصادقة.
|
||||
`--cassandra-password`: كلمة مرور المصادقة.
|
||||
`--config-type`: نوع التكوين للمخططات (افتراضي: "schema").
|
||||
وسائط FlowProcessor القياسية (تكوين Pulsar، إلخ).
|
||||
|
||||
## تكامل واجهة برمجة التطبيقات
|
||||
|
||||
### مواضيع Pulsar
|
||||
|
||||
**موضوع الإدخال**: `objects-graphql-query-request`
|
||||
المخطط: ObjectsQueryRequest
|
||||
يتلقى استعلامات GraphQL من خدمات البوابة.
|
||||
|
||||
**موضوع الإخراج**: `objects-graphql-query-response`
|
||||
المخطط: ObjectsQueryResponse
|
||||
يُرجع نتائج الاستعلام والأخطاء.
|
||||
|
||||
### تكامل البوابة
|
||||
|
||||
ستحتاج البوابة والبوابة العكسية إلى نقاط نهاية لـ:
|
||||
1. قبول استعلامات GraphQL من العملاء.
|
||||
2. توجيهها إلى خدمة الاستعلام عبر Pulsar.
|
||||
3. إرجاع الاستجابات إلى العملاء.
|
||||
<<<<<<< HEAD
|
||||
4. دعم استعلامات GraphQL الخاصة بالتحقق من المخطط.
|
||||
=======
|
||||
4. دعم استعلامات GraphQL الخاصة بالتحقق (introspection).
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### تكامل أداة الوكيل
|
||||
|
||||
ستتيح فئة أداة وكيل جديدة:
|
||||
توليد استعلامات GraphQL من اللغة الطبيعية.
|
||||
تنفيذ استعلامات GraphQL مباشرة.
|
||||
<<<<<<< HEAD
|
||||
تفسير وتنسيق النتائج.
|
||||
التكامل مع مسارات قرار الوكيل.
|
||||
=======
|
||||
تفسير النتائج وتنسيقها.
|
||||
التكامل مع تدفقات قرار الوكيل.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
**تحديد عمق الاستعلام**: منع الاستعلامات المتداخلة بعمق والتي يمكن أن تسبب مشاكل في الأداء.
|
||||
<<<<<<< HEAD
|
||||
**تحليل تعقيد الاستعلام**: الحد من تعقيد الاستعلام لمنع استنفاد الموارد.
|
||||
**أذونات على مستوى الحقل**: دعم مستقبلي للتحكم في الوصول على مستوى الحقل بناءً على أدوار المستخدم.
|
||||
**تنظيف الإدخال**: التحقق من صحة وتنظيف جميع مدخلات الاستعلام لمنع هجمات الحقن.
|
||||
**تحديد المعدل**: تنفيذ تحديد معدل الاستعلام لكل مستخدم/مجموعة.
|
||||
=======
|
||||
**تحليل تعقيد الاستعلام**: تحديد تعقيد الاستعلام لمنع استنفاد الموارد.
|
||||
**أذونات على مستوى الحقل**: دعم مستقبلي للتحكم في الوصول على مستوى الحقل بناءً على أدوار المستخدم.
|
||||
**تنظيف الإدخال**: التحقق من صحة وتنظيف جميع مدخلات الاستعلام لمنع هجمات الحقن.
|
||||
**تحديد المعدل**: تطبيق تحديد معدل الاستعلام لكل مستخدم/مجموعة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
**تخطيط الاستعلام**: تحليل الاستعلامات قبل التنفيذ لتحسين توليد CQL.
|
||||
**تخزين النتائج مؤقتًا**: ضع في اعتبارك تخزين البيانات التي يتم الوصول إليها بشكل متكرر مؤقتًا على مستوى محلل الحقل.
|
||||
<<<<<<< HEAD
|
||||
**تجميع الاتصالات**: حافظ على مجموعات اتصالات فعالة إلى Cassandra.
|
||||
=======
|
||||
**تجميع الاتصالات**: حافظ على تجمعات اتصالات فعالة إلى Cassandra.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**العمليات الدفعية**: اجمع بين استعلامات متعددة كلما أمكن ذلك لتقليل زمن الوصول.
|
||||
**المراقبة**: تتبع مقاييس أداء الاستعلام لتحسين الأداء.
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبارات الوحدة
|
||||
توليد المخططات من تعريفات RowSchema
|
||||
تحليل وتدقيق استعلامات GraphQL
|
||||
منطق توليد استعلامات CQL
|
||||
تطبيقات محللات الحقول
|
||||
|
||||
### اختبارات العقود
|
||||
الامتثال لعقد رسائل Pulsar
|
||||
صلاحية مخطط GraphQL
|
||||
التحقق من تنسيق الاستجابة
|
||||
التحقق من صحة هيكل الأخطاء
|
||||
|
||||
### اختبارات التكامل
|
||||
<<<<<<< HEAD
|
||||
تنفيذ استعلامات شاملة مقابل نسخة اختبار Cassandra
|
||||
=======
|
||||
تنفيذ الاستعلامات من طرف إلى طرف مقابل مثيل Cassandra للاختبار
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
معالجة تحديثات المخططات
|
||||
حل العلاقات
|
||||
الترقيم والتصفية
|
||||
سيناريوهات الأخطاء
|
||||
|
||||
### اختبارات الأداء
|
||||
معدل نقل البيانات للاستعلامات تحت الضغط
|
||||
وقت الاستجابة لتعقيدات الاستعلامات المختلفة
|
||||
استخدام الذاكرة مع مجموعات نتائج كبيرة
|
||||
كفاءة مجموعة الاتصالات
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
لا يلزم إجراء أي ترحيل نظرًا لأن هذا ميزة جديدة. ستقوم الخدمة بما يلي:
|
||||
1. قراءة المخططات الموجودة من التكوين
|
||||
2. الاتصال بجداول Cassandra الموجودة التي تم إنشاؤها بواسطة وحدة التخزين
|
||||
3. البدء في قبول الاستعلامات على الفور عند النشر
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
الأسبوع 1-2: تنفيذ الخدمة الأساسية وتوليد المخططات
|
||||
الأسبوع 3: تنفيذ الاستعلامات وترجمة CQL
|
||||
الأسبوع 4: حل العلاقات والتحسين
|
||||
الأسبوع 5: الاختبار وضبط الأداء
|
||||
الأسبوع 6: التكامل مع البوابة والتوثيق
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
1. **تطور المخططات**: كيف يجب أن تتعامل الخدمة مع الاستعلامات أثناء عمليات انتقال المخططات؟
|
||||
خيار: وضع الاستعلامات في قائمة انتظار أثناء تحديثات المخططات
|
||||
خيار: دعم إصدارات متعددة من المخططات في نفس الوقت
|
||||
|
||||
2. **استراتيجية التخزين المؤقت**: هل يجب تخزين نتائج الاستعلامات مؤقتًا؟
|
||||
ضع في اعتبارك: انتهاء الصلاحية بناءً على الوقت
|
||||
ضع في اعتبارك: الإبطال بناءً على الأحداث
|
||||
|
||||
3. **دعم التجميع**: هل يجب أن تدعم الخدمة تجميع GraphQL لدمجها مع مصادر بيانات أخرى؟
|
||||
<<<<<<< HEAD
|
||||
سيمكن ذلك من إجراء استعلامات موحدة عبر البيانات المهيكلة والبيانات الرسومية
|
||||
=======
|
||||
سيمكن ذلك من الاستعلامات الموحدة عبر البيانات المهيكلة والبيانات الرسومية
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
4. **دعم الاشتراكات**: هل يجب أن تدعم الخدمة اشتراكات GraphQL للتحديثات في الوقت الفعلي؟
|
||||
سيتطلب ذلك دعم WebSocket في البوابة
|
||||
|
||||
<<<<<<< HEAD
|
||||
5. **أنواع قياسية مخصصة**: هل يجب دعم الأنواع القياسية المخصصة لأنواع البيانات الخاصة بالمجال؟
|
||||
=======
|
||||
5. **الأنواع العددية المخصصة**: هل يجب دعم الأنواع العددية المخصصة لأنواع البيانات الخاصة بالمجال؟
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
أمثلة: DateTime، UUID، حقول JSON
|
||||
|
||||
## المراجع
|
||||
|
||||
المواصفات الفنية للبيانات المهيكلة: `docs/tech-specs/structured-data.md`
|
||||
<<<<<<< HEAD
|
||||
وثائق GraphQL Strawberry: https://strawberry.rocks/
|
||||
=======
|
||||
وثائق Strawberry GraphQL: https://strawberry.rocks/
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
مواصفات GraphQL: https://spec.graphql.org/
|
||||
مرجع Apache Cassandra CQL: https://cassandra.apache.org/doc/stable/cassandra/cql/
|
||||
وثائق معالج التدفق TrustGraph: وثائق داخلية
|
||||
770
docs/tech-specs/ar/graphrag-performance-optimization.ar.md
Normal file
770
docs/tech-specs/ar/graphrag-performance-optimization.ar.md
Normal file
|
|
@ -0,0 +1,770 @@
|
|||
---
|
||||
layout: default
|
||||
title: "GraphRAG Performance Optimisation Technical Specification"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# GraphRAG Performance Optimisation Technical Specification
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## Overview
|
||||
|
||||
يصف هذا المستند تفصيليًا تحسينات الأداء الشاملة لخوارزمية GraphRAG (Graph Retrieval-Augmented Generation) في TrustGraph. تعاني التنفيذ الحالي من نقاط اختناق أداء كبيرة تحد من قابلية التوسع وأوقات الاستجابة. يتناول هذا المستند أربعة مجالات رئيسية للتحسين:
|
||||
|
||||
1. **تحسين اجتياز الرسم البياني**: التخلص من استعلامات قاعدة البيانات المتكررة غير الفعالة وتنفيذ استكشاف الرسم البياني المجمّع.
|
||||
2. **تحسين حل التسميات**: استبدال استرداد التسميات التسلسلي بعمليات متوازية/مجمعة.
|
||||
3. **تحسين استراتيجية التخزين المؤقت**: تنفيذ تخزين مؤقت ذكي مع إخلاء LRU والتعبئة المسبقة.
|
||||
4. **تحسين الاستعلام**: إضافة تدوين النتائج وتخزين تضمينات الاستعلام لتحسين أوقات الاستجابة.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**تقليل حجم استعلامات قاعدة البيانات**: تحقيق تقليل بنسبة 50-80٪ في إجمالي استعلامات قاعدة البيانات من خلال التجميع والتخزين المؤقت.
|
||||
<<<<<<< HEAD
|
||||
**تحسين أوقات الاستجابة**: استهداف سرعة بناء الرسوم البيانية الفرعية بمقدار 3-5 مرات وسرعة حل التسميات بمقدار 2-3 مرات.
|
||||
**تعزيز قابلية التوسع**: دعم رسوم بيانية معرفية أكبر مع إدارة أفضل للذاكرة.
|
||||
=======
|
||||
**تحسين أوقات الاستجابة**: استهداف سرعة بناء الرسوم البيانية الفرعية 3-5 مرات أسرع وسرعة حل التسميات 2-3 مرات أسرع.
|
||||
**تعزيز قابلية التوسع**: دعم رسوم بيانية معرفية أكبر مع إدارة ذاكرة أفضل.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**الحفاظ على الدقة**: الحفاظ على وظائف GraphRAG الحالية وجودة النتائج.
|
||||
**تمكين التزامن**: تحسين إمكانيات المعالجة المتوازية للطلبات المتزامنة المتعددة.
|
||||
**تقليل البصمة الذاكرة**: تنفيذ هياكل بيانات وإدارة ذاكرة فعالة.
|
||||
**إضافة إمكانية المراقبة**: تضمين مقاييس الأداء وقدرات المراقبة.
|
||||
**ضمان الموثوقية**: إضافة معالجة مناسبة للأخطاء وآليات المهلة.
|
||||
|
||||
## الخلفية
|
||||
|
||||
يُظهر التنفيذ الحالي لـ GraphRAG في `trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py` العديد من مشكلات الأداء الهامة التي تؤثر بشدة على قابلية توسع النظام:
|
||||
|
||||
### المشكلات الحالية في الأداء
|
||||
|
||||
**1. اجتياز الرسم البياني غير الفعال (دالة `follow_edges`، الأسطر 79-127)**
|
||||
يقوم بإجراء 3 استعلامات لقاعدة البيانات لكل كيان لكل مستوى عمق.
|
||||
نمط الاستعلام: استعلامات تعتمد على الموضوع، واستعلامات تعتمد على الرابط، واستعلامات تعتمد على الكائن لكل كيان.
|
||||
لا يوجد تجميع: يعالج كل استعلام كيانًا واحدًا فقط في كل مرة.
|
||||
<<<<<<< HEAD
|
||||
لا يوجد اكتشاف دورات: يمكن إعادة زيارة نفس العقد عدة مرات.
|
||||
=======
|
||||
لا يوجد اكتشاف للدورات: يمكن إعادة زيارة نفس العقد عدة مرات.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
يؤدي التنفيذ المتكرر بدون تدوين إلى تعقيد أسي.
|
||||
التعقيد الزمني: O(entities × max_path_length × triple_limit³)
|
||||
|
||||
**2. حل تسلسلي للتسميات (دالة `get_labelgraph`، الأسطر 144-171)**
|
||||
يعالج كل مكون ثلاثي (موضوع، رابط، كائن) بالتسلسل.
|
||||
قد يؤدي كل استدعاء لـ `maybe_label` إلى استعلام لقاعدة البيانات.
|
||||
لا يوجد تنفيذ متوازي أو تجميع لاستعلامات التسمية.
|
||||
<<<<<<< HEAD
|
||||
يؤدي إلى ما يصل إلى 3 × استعلامات قاعدة بيانات فردية بحجم الرسم البياني الفرعي.
|
||||
=======
|
||||
يؤدي إلى ما يصل إلى 3 × استعلامات قاعدة البيانات الفردية لحجم الرسم البياني الفرعي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**3. استراتيجية تخزين مؤقت بدائية (دالة `maybe_label`، الأسطر 62-77)**
|
||||
ذاكرة تخزين مؤقت بسيطة للقواميس بدون حدود حجم أو TTL.
|
||||
لا توجد سياسة إخلاء للتخزين المؤقت تؤدي إلى نمو غير محدود للذاكرة.
|
||||
تؤدي أخطاء التخزين المؤقت إلى استعلامات قاعدة بيانات فردية.
|
||||
لا يوجد تعبئة مسبقة أو تخزين مؤقت ذكي.
|
||||
|
||||
**4. أنماط استعلام دون المستوى الأمثل**
|
||||
استعلامات تشابه متجه الكيان غير مخزنة مؤقتًا بين الطلبات المتشابهة.
|
||||
لا يوجد تدوين للنتائج لأنماط الاستعلام المتكررة.
|
||||
<<<<<<< HEAD
|
||||
أنماط استعلام مفقودة للوصول الشائع.
|
||||
=======
|
||||
أنماط استعلام مفقودة للتحسين للأنماط الشائعة للوصول.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**5. مشكلات حرجة في عمر الكائن (`rag.py:96-102`)**
|
||||
**يتم إعادة إنشاء كائن GraphRag لكل طلب**: يتم إنشاء نسخة جديدة لكل استعلام، مما يفقد جميع فوائد التخزين المؤقت.
|
||||
**عمر كائن الاستعلام قصير للغاية**: يتم إنشاؤه وتدميره داخل تنفيذ استعلام واحد (الأسطر 201-207).
|
||||
**يتم إعادة تعيين ذاكرة التخزين المؤقت للتسميات لكل طلب**: يتم فقد التخزين المؤقت والتراكم المعرفي بين الطلبات.
|
||||
**نفقات إعادة إنشاء العميل**: قد يتم إعادة إنشاء عملاء قاعدة البيانات لكل طلب.
|
||||
**لا يوجد تحسين عبر الطلبات**: لا يمكن الاستفادة من أنماط الاستعلام أو مشاركة النتائج.
|
||||
|
||||
### تحليل تأثير الأداء
|
||||
|
||||
السيناريو الأسوأ الحالي لطلب نموذجي:
|
||||
**استرداد الكيان**: استعلام واحد لتقارب المتجهات.
|
||||
**اجتياز الرسم البياني**: entities × max_path_length × 3 × triple_limit استعلامات.
|
||||
**حل التسميات**: subgraph_size × 3 استعلامات تسمية فردية.
|
||||
|
||||
<<<<<<< HEAD
|
||||
للإعدادات الافتراضية (50 كيانًا، وطول المسار 2، وقيود على 30 ثلاثية، وحجم الرسم البياني الفرعي 150):
|
||||
**عدد الاستعلامات:** 1 + (50 × 2 × 3 × 30) + (150 × 3) = **9451 استعلامًا لقاعدة البيانات**
|
||||
=======
|
||||
للإعدادات الافتراضية (50 كيانًا، وطول المسار 2، وقيود على 30 ثلاثية، وحجم الرسوم البيانية الفرعية 150):
|
||||
**الاستعلامات الدنيا:** 1 + (50 × 2 × 3 × 30) + (150 × 3) = **9451 استعلامًا لقاعدة البيانات**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**وقت الاستجابة:** 15-30 ثانية للرسوم البيانية متوسطة الحجم
|
||||
**استخدام الذاكرة:** نمو غير محدود لذاكرة التخزين المؤقت بمرور الوقت
|
||||
**فعالية التخزين المؤقت:** 0% - يتم إعادة تعيين ذاكرة التخزين المؤقت في كل طلب
|
||||
**تكلفة إنشاء الكائنات:** يتم إنشاء كائنات GraphRag + Query وتدميرها لكل طلب
|
||||
|
||||
تعالج هذه المواصفات هذه الثغرات من خلال تنفيذ الاستعلامات المجمعة، والتخزين المؤقت الذكي، والمعالجة المتوازية. من خلال تحسين أنماط الاستعلام والوصول إلى البيانات، يمكن لـ TrustGraph:
|
||||
<<<<<<< HEAD
|
||||
دعم رسوم بيانية معرفية على نطاق المؤسسات تحتوي على ملايين الكيانات
|
||||
توفير أوقات استجابة أقل من ثانية للاستعلامات النموذجية
|
||||
التعامل مع مئات طلبات GraphRAG المتزامنة
|
||||
التوسع بكفاءة مع حجم الرسم البياني وتعقيده
|
||||
=======
|
||||
دعم الرسوم البيانية المعرفية على نطاق المؤسسات مع ملايين الكيانات
|
||||
توفير أوقات استجابة أقل من ثانية للاستعلامات النموذجية
|
||||
التعامل مع مئات طلبات GraphRAG المتزامنة
|
||||
التوسع بكفاءة مع حجم وتعقيد الرسم البياني
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
يتطلب تحسين أداء GraphRAG المكونات الفنية التالية:
|
||||
|
||||
#### 1. **إعادة هيكلة دورة حياة الكائنات**
|
||||
**جعل GraphRag يعمل لفترة أطول:** نقل مثيل GraphRag إلى مستوى المعالج للاستمرارية عبر الطلبات
|
||||
**الحفاظ على ذاكرة التخزين المؤقت:** الحفاظ على ذاكرة التخزين المؤقت للتسميات، وذاكرة التخزين المؤقت للتضمينات، وذاكرة التخزين المؤقت لنتائج الاستعلام بين الطلبات
|
||||
**تحسين كائن الاستعلام:** إعادة هيكلة الاستعلام كسياق تنفيذ خفيف الوزن، وليس حاوية بيانات
|
||||
<<<<<<< HEAD
|
||||
**استمرارية الاتصال:** الحفاظ على اتصالات عميل قاعدة البيانات عبر الطلبات
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py` (تم التعديل)
|
||||
|
||||
#### 2. **محرك اجتياز الرسم البياني المحسن**
|
||||
استبدال `follow_edges` التكراري ببحث عرضي تكراري
|
||||
تنفيذ معالجة مجمعة للكيانات في كل مستوى من مستويات الاجتياز
|
||||
=======
|
||||
**استمرار الاتصال:** الحفاظ على اتصالات عميل قاعدة البيانات عبر الطلبات
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py` (تم التعديل)
|
||||
|
||||
#### 2. **محرك اجتياز الرسوم البيانية المحسن**
|
||||
استبدال `follow_edges` التكراري ببحث عرضي تكراري
|
||||
تنفيذ معالجة الكيانات المجمعة في كل مستوى من مستويات الاجتياز
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
إضافة اكتشاف الدورات باستخدام تتبع العقد التي تمت زيارتها
|
||||
تضمين الإنهاء المبكر عند الوصول إلى الحدود
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/retrieval/graph_rag/optimized_traversal.py`
|
||||
|
||||
#### 3. **نظام حل التسميات المتوازي**
|
||||
تجميع استعلامات التسميات لعدة كيانات في وقت واحد
|
||||
تنفيذ أنماط async/await للوصول المتزامن إلى قاعدة البيانات
|
||||
إضافة استرجاع استباقي لأنماط التسميات الشائعة
|
||||
تضمين استراتيجيات تسخين ذاكرة التخزين المؤقت للتسميات
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/retrieval/graph_rag/label_resolver.py`
|
||||
|
||||
#### 4. **طبقة تخزين مؤقت محافظة للتسميات**
|
||||
<<<<<<< HEAD
|
||||
ذاكرة تخزين مؤقت LRU مع TTL قصيرة للتسميات فقط (5 دقائق) لتحقيق التوازن بين الأداء والاتساق
|
||||
مراقبة مقاييس ذاكرة التخزين المؤقت ونسبة النجاح
|
||||
**لا يوجد تخزين مؤقت للتضمينات:** يتم تخزينها بالفعل لكل استعلام، ولا يوجد فائدة عبر الاستعلامات
|
||||
**لا يوجد تخزين مؤقت لنتائج الاستعلام:** بسبب مخاوف اتساق تغييرات الرسم البياني
|
||||
=======
|
||||
ذاكرة تخزين مؤقت LRU مع TTL قصيرة للتسميات فقط (5 دقائق) لتحقيق التوازن بين الأداء مقابل الاتساق
|
||||
مراقبة مقاييس ذاكرة التخزين المؤقت ونسبة الإصابة
|
||||
**لا يوجد تخزين مؤقت للتضمينات:** يتم تخزينها بالفعل لكل استعلام، ولا يوجد فائدة عبر الاستعلامات
|
||||
**لا يوجد تخزين مؤقت لنتائج الاستعلام:** بسبب مخاوف اتساق تعديل الرسم البياني
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/retrieval/graph_rag/cache_manager.py`
|
||||
|
||||
#### 5. **إطار تحسين الاستعلام**
|
||||
تحليل الاستعلام واقتراحات التحسين
|
||||
منسق استعلامات مجمعة للوصول إلى قاعدة البيانات
|
||||
تجميع الاتصالات وإدارة مهلة الاستعلام
|
||||
مراقبة الأداء وجمع المقاييس
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/retrieval/graph_rag/query_optimizer.py`
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
<<<<<<< HEAD
|
||||
#### حالة اجتياز الرسم البياني المحسنة
|
||||
=======
|
||||
#### حالة اجتياز الرسوم البيانية المحسنة
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
يحتفظ محرك الاجتياز بالحالة لتجنب العمليات المتكررة:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class TraversalState:
|
||||
visited_entities: Set[str]
|
||||
current_level_entities: Set[str]
|
||||
next_level_entities: Set[str]
|
||||
subgraph: Set[Tuple[str, str, str]]
|
||||
depth: int
|
||||
query_batch: List[TripleQuery]
|
||||
```
|
||||
|
||||
تسمح هذه الطريقة بما يلي:
|
||||
الكشف الفعال عن الدورات من خلال تتبع الكيانات التي تمت زيارتها.
|
||||
إعداد استعلامات مجمعة في كل مستوى من مستويات التكرار.
|
||||
إدارة حالة فعالة من حيث الذاكرة.
|
||||
الإنهاء المبكر عند الوصول إلى حدود الحجم.
|
||||
|
||||
#### هيكل ذاكرة تخزين مؤقتة مُحسّن
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class CacheEntry:
|
||||
value: Any
|
||||
timestamp: float
|
||||
access_count: int
|
||||
ttl: Optional[float]
|
||||
|
||||
class CacheManager:
|
||||
label_cache: LRUCache[str, CacheEntry]
|
||||
embedding_cache: LRUCache[str, CacheEntry]
|
||||
query_result_cache: LRUCache[str, CacheEntry]
|
||||
cache_stats: CacheStatistics
|
||||
```
|
||||
|
||||
#### هياكل الاستعلامات المجمعة
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class BatchTripleQuery:
|
||||
entities: List[str]
|
||||
query_type: QueryType # SUBJECT, PREDICATE, OBJECT
|
||||
limit_per_entity: int
|
||||
|
||||
@dataclass
|
||||
class BatchLabelQuery:
|
||||
entities: List[str]
|
||||
predicate: str = LABEL
|
||||
```
|
||||
|
||||
### واجهات برمجة التطبيقات (APIs)
|
||||
|
||||
#### واجهات برمجة تطبيقات جديدة:
|
||||
|
||||
**واجهة برمجة تطبيقات GraphTraversal**
|
||||
```python
|
||||
async def optimized_follow_edges_batch(
|
||||
entities: List[str],
|
||||
max_depth: int,
|
||||
triple_limit: int,
|
||||
max_subgraph_size: int
|
||||
) -> Set[Tuple[str, str, str]]
|
||||
```
|
||||
|
||||
**واجهة برمجة تطبيقات (API) لحل مشكلات التسمية الدفعية.**
|
||||
```python
|
||||
async def resolve_labels_batch(
|
||||
entities: List[str],
|
||||
cache_manager: CacheManager
|
||||
) -> Dict[str, str]
|
||||
```
|
||||
|
||||
**واجهة برمجة تطبيقات إدارة ذاكرة التخزين المؤقت**
|
||||
```python
|
||||
class CacheManager:
|
||||
async def get_or_fetch_label(self, entity: str) -> str
|
||||
async def get_or_fetch_embeddings(self, query: str) -> List[float]
|
||||
async def cache_query_result(self, query_hash: str, result: Any, ttl: int)
|
||||
def get_cache_statistics(self) -> CacheStatistics
|
||||
```
|
||||
|
||||
#### واجهات برمجة التطبيقات (APIs) المعدلة:
|
||||
|
||||
**GraphRag.query()** - تم تحسينها مع تحسينات في الأداء:
|
||||
إضافة معلمة `cache_manager` للتحكم في التخزين المؤقت.
|
||||
تضمين قيمة الإرجاع `performance_metrics`.
|
||||
إضافة معلمة `query_timeout` للموثوقية.
|
||||
|
||||
**فئة Query** - تم إعادة هيكلتها لمعالجة الدفعات:
|
||||
استبدال معالجة الكيانات الفردية بعمليات الدفعات.
|
||||
إضافة مديري سياق غير متزامنين لتنظيف الموارد.
|
||||
<<<<<<< HEAD
|
||||
تضمين استدعاءات رد الاتصال للتقدم لعمليات طويلة الأمد.
|
||||
=======
|
||||
تضمين ردود اتصال التقدم للعمليات التي تستغرق وقتًا طويلاً.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
#### المرحلة 0: إعادة هيكلة عمرية معمارية حاسمة
|
||||
|
||||
**التنفيذ الحالي الذي يمثل مشكلة:**
|
||||
```python
|
||||
# INEFFICIENT: GraphRag recreated every request
|
||||
class Processor(FlowProcessor):
|
||||
async def on_request(self, msg, consumer, flow):
|
||||
# PROBLEM: New GraphRag instance per request!
|
||||
self.rag = GraphRag(
|
||||
embeddings_client = flow("embeddings-request"),
|
||||
graph_embeddings_client = flow("graph-embeddings-request"),
|
||||
triples_client = flow("triples-request"),
|
||||
prompt_client = flow("prompt-request"),
|
||||
verbose=True,
|
||||
)
|
||||
# Cache starts empty every time - no benefit from previous requests
|
||||
response = await self.rag.query(...)
|
||||
|
||||
# VERY SHORT-LIVED: Query object created/destroyed per request
|
||||
class GraphRag:
|
||||
async def query(self, query, user="trustgraph", collection="default", ...):
|
||||
q = Query(rag=self, user=user, collection=collection, ...) # Created
|
||||
kg = await q.get_labelgraph(query) # Used briefly
|
||||
# q automatically destroyed when function exits
|
||||
```
|
||||
|
||||
**هيكل معماري مُحسّن وعالي الأداء:**
|
||||
```python
|
||||
class Processor(FlowProcessor):
|
||||
def __init__(self, **params):
|
||||
super().__init__(**params)
|
||||
self.rag_instance = None # Will be initialized once
|
||||
self.client_connections = {}
|
||||
|
||||
async def initialize_rag(self, flow):
|
||||
"""Initialize GraphRag once, reuse for all requests"""
|
||||
if self.rag_instance is None:
|
||||
self.rag_instance = LongLivedGraphRag(
|
||||
embeddings_client=flow("embeddings-request"),
|
||||
graph_embeddings_client=flow("graph-embeddings-request"),
|
||||
triples_client=flow("triples-request"),
|
||||
prompt_client=flow("prompt-request"),
|
||||
verbose=True,
|
||||
)
|
||||
return self.rag_instance
|
||||
|
||||
async def on_request(self, msg, consumer, flow):
|
||||
# REUSE the same GraphRag instance - caches persist!
|
||||
rag = await self.initialize_rag(flow)
|
||||
|
||||
# Query object becomes lightweight execution context
|
||||
response = await rag.query_with_context(
|
||||
query=v.query,
|
||||
execution_context=QueryContext(
|
||||
user=v.user,
|
||||
collection=v.collection,
|
||||
entity_limit=entity_limit,
|
||||
# ... other params
|
||||
)
|
||||
)
|
||||
|
||||
class LongLivedGraphRag:
|
||||
def __init__(self, ...):
|
||||
# CONSERVATIVE caches - balance performance vs consistency
|
||||
self.label_cache = LRUCacheWithTTL(max_size=5000, ttl=300) # 5min TTL for freshness
|
||||
# Note: No embedding cache - already cached per-query, no cross-query benefit
|
||||
# Note: No query result cache due to consistency concerns
|
||||
self.performance_metrics = PerformanceTracker()
|
||||
|
||||
async def query_with_context(self, query: str, context: QueryContext):
|
||||
# Use lightweight QueryExecutor instead of heavyweight Query object
|
||||
executor = QueryExecutor(self, context) # Minimal object
|
||||
return await executor.execute(query)
|
||||
|
||||
@dataclass
|
||||
class QueryContext:
|
||||
"""Lightweight execution context - no heavy operations"""
|
||||
user: str
|
||||
collection: str
|
||||
entity_limit: int
|
||||
triple_limit: int
|
||||
max_subgraph_size: int
|
||||
max_path_length: int
|
||||
|
||||
class QueryExecutor:
|
||||
"""Lightweight execution context - replaces old Query class"""
|
||||
def __init__(self, rag: LongLivedGraphRag, context: QueryContext):
|
||||
self.rag = rag
|
||||
self.context = context
|
||||
# No heavy initialization - just references
|
||||
|
||||
async def execute(self, query: str):
|
||||
# All heavy lifting uses persistent rag caches
|
||||
return await self.rag.execute_optimized_query(query, self.context)
|
||||
```
|
||||
|
||||
هذا التغيير المعماري يوفر:
|
||||
**تقليل بنسبة 10-20٪ في استعلامات قاعدة البيانات** للرسوم البيانية التي تحتوي على علاقات شائعة (مقارنة بـ 0٪ حاليًا).
|
||||
**إزالة تكلفة إنشاء الكائنات** لكل طلب.
|
||||
**تجميع الاتصالات المستمرة وإعادة استخدام العملاء**.
|
||||
**تحسينات عبر الطلبات** ضمن إطارات زمنية للتخزين المؤقت (TTL).
|
||||
|
||||
**قيود مهمة تتعلق بتناسق التخزين المؤقت:**
|
||||
<<<<<<< HEAD
|
||||
يؤدي التخزين المؤقت طويل الأجل إلى خطر حدوث بيانات قديمة عندما يتم حذف الكيانات/التصنيفات أو تعديلها في الرسم البياني الأساسي. يوفر التخزين المؤقت الأقل استخدامًا (LRU) مع إطار زمني للتخزين (TTL) توازنًا بين مكاسب الأداء وحداثة البيانات، ولكنه لا يمكنه اكتشاف تغييرات الرسم البياني في الوقت الفعلي.
|
||||
=======
|
||||
يؤدي التخزين المؤقت طويل الأجل إلى خطر حدوث بيانات قديمة عندما يتم حذف الكيانات/التصنيفات أو تعديلها في الرسم البياني الأساسي. يوفر التخزين المؤقت الأقل استخدامًا (LRU) مع TTL توازنًا بين مكاسب الأداء وحداثة البيانات، ولكنه لا يمكنه اكتشاف تغييرات الرسم البياني في الوقت الفعلي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
#### المرحلة الأولى: تحسين اجتياز الرسم البياني.
|
||||
|
||||
**مشاكل التنفيذ الحالية:**
|
||||
```python
|
||||
# INEFFICIENT: 3 queries per entity per level
|
||||
async def follow_edges(self, ent, subgraph, path_length):
|
||||
# Query 1: s=ent, p=None, o=None
|
||||
res = await self.rag.triples_client.query(s=ent, p=None, o=None, limit=self.triple_limit)
|
||||
# Query 2: s=None, p=ent, o=None
|
||||
res = await self.rag.triples_client.query(s=None, p=ent, o=None, limit=self.triple_limit)
|
||||
# Query 3: s=None, p=None, o=ent
|
||||
res = await self.rag.triples_client.query(s=None, p=None, o=ent, limit=self.triple_limit)
|
||||
```
|
||||
|
||||
**التنفيذ الأمثل:**
|
||||
```python
|
||||
async def optimized_traversal(self, entities: List[str], max_depth: int) -> Set[Triple]:
|
||||
visited = set()
|
||||
current_level = set(entities)
|
||||
subgraph = set()
|
||||
|
||||
for depth in range(max_depth):
|
||||
if not current_level or len(subgraph) >= self.max_subgraph_size:
|
||||
break
|
||||
|
||||
# Batch all queries for current level
|
||||
batch_queries = []
|
||||
for entity in current_level:
|
||||
if entity not in visited:
|
||||
batch_queries.extend([
|
||||
TripleQuery(s=entity, p=None, o=None),
|
||||
TripleQuery(s=None, p=entity, o=None),
|
||||
TripleQuery(s=None, p=None, o=entity)
|
||||
])
|
||||
|
||||
# Execute all queries concurrently
|
||||
results = await self.execute_batch_queries(batch_queries)
|
||||
|
||||
# Process results and prepare next level
|
||||
next_level = set()
|
||||
for result in results:
|
||||
subgraph.update(result.triples)
|
||||
next_level.update(result.new_entities)
|
||||
|
||||
visited.update(current_level)
|
||||
current_level = next_level - visited
|
||||
|
||||
return subgraph
|
||||
```
|
||||
|
||||
#### المرحلة الثانية: حل التسميات المتوازية
|
||||
|
||||
**التنفيذ التسلسلي الحالي:**
|
||||
```python
|
||||
# INEFFICIENT: Sequential processing
|
||||
for edge in subgraph:
|
||||
s = await self.maybe_label(edge[0]) # Individual query
|
||||
p = await self.maybe_label(edge[1]) # Individual query
|
||||
o = await self.maybe_label(edge[2]) # Individual query
|
||||
```
|
||||
|
||||
**التنفيذ المتوازي المُحسّن:**
|
||||
```python
|
||||
async def resolve_labels_parallel(self, subgraph: List[Triple]) -> List[Triple]:
|
||||
# Collect all unique entities needing labels
|
||||
entities_to_resolve = set()
|
||||
for s, p, o in subgraph:
|
||||
entities_to_resolve.update([s, p, o])
|
||||
|
||||
# Remove already cached entities
|
||||
uncached_entities = [e for e in entities_to_resolve if e not in self.label_cache]
|
||||
|
||||
# Batch query for all uncached labels
|
||||
if uncached_entities:
|
||||
label_results = await self.batch_label_query(uncached_entities)
|
||||
self.label_cache.update(label_results)
|
||||
|
||||
# Apply labels to subgraph
|
||||
return [
|
||||
(self.label_cache.get(s, s), self.label_cache.get(p, p), self.label_cache.get(o, o))
|
||||
for s, p, o in subgraph
|
||||
]
|
||||
```
|
||||
|
||||
#### المرحلة الثالثة: استراتيجية التخزين المؤقت المتقدمة
|
||||
|
||||
**ذاكرة تخزين مؤقت LRU مع TTL:**
|
||||
```python
|
||||
class LRUCacheWithTTL:
|
||||
def __init__(self, max_size: int, default_ttl: int = 3600):
|
||||
self.cache = OrderedDict()
|
||||
self.max_size = max_size
|
||||
self.default_ttl = default_ttl
|
||||
self.access_times = {}
|
||||
|
||||
async def get(self, key: str) -> Optional[Any]:
|
||||
if key in self.cache:
|
||||
# Check TTL expiration
|
||||
if time.time() - self.access_times[key] > self.default_ttl:
|
||||
del self.cache[key]
|
||||
del self.access_times[key]
|
||||
return None
|
||||
|
||||
# Move to end (most recently used)
|
||||
self.cache.move_to_end(key)
|
||||
return self.cache[key]
|
||||
return None
|
||||
|
||||
async def put(self, key: str, value: Any):
|
||||
if key in self.cache:
|
||||
self.cache.move_to_end(key)
|
||||
else:
|
||||
if len(self.cache) >= self.max_size:
|
||||
# Remove least recently used
|
||||
oldest_key = next(iter(self.cache))
|
||||
del self.cache[oldest_key]
|
||||
del self.access_times[oldest_key]
|
||||
|
||||
self.cache[key] = value
|
||||
self.access_times[key] = time.time()
|
||||
```
|
||||
|
||||
#### المرحلة الرابعة: تحسين الاستعلامات والمراقبة
|
||||
|
||||
**جمع مقاييس الأداء:**
|
||||
```python
|
||||
@dataclass
|
||||
class PerformanceMetrics:
|
||||
total_queries: int
|
||||
cache_hits: int
|
||||
cache_misses: int
|
||||
avg_response_time: float
|
||||
subgraph_construction_time: float
|
||||
label_resolution_time: float
|
||||
total_entities_processed: int
|
||||
memory_usage_mb: float
|
||||
```
|
||||
|
||||
**مهلة الاستعلام وقاطع الدائرة:**
|
||||
```python
|
||||
async def execute_with_timeout(self, query_func, timeout: int = 30):
|
||||
try:
|
||||
return await asyncio.wait_for(query_func(), timeout=timeout)
|
||||
except asyncio.TimeoutError:
|
||||
logger.error(f"Query timeout after {timeout}s")
|
||||
raise GraphRagTimeoutError(f"Query exceeded timeout of {timeout}s")
|
||||
```
|
||||
|
||||
## اعتبارات تناسق ذاكرة التخزين المؤقت
|
||||
|
||||
**موازنات بين قدوم البيانات:**
|
||||
**ذاكرة تخزين مؤقت للتسميات (TTL مدته 5 دقائق):** خطر عرض تسميات الكيانات المحذوفة/المُعادة تسميتها.
|
||||
**لا يوجد تخزين مؤقت للتضمينات:** غير ضروري - يتم تخزين التضمينات بالفعل لكل استعلام.
|
||||
**لا يوجد تخزين مؤقت للنتائج:** يمنع النتائج الفرعية غير المستقرة من الرسوم البيانية الناتجة عن الكيانات/العلاقات المحذوفة.
|
||||
|
||||
**استراتيجيات التخفيف:**
|
||||
**قيم TTL محافظة:** الموازنة بين مكاسب الأداء (10-20٪) مع تحديث البيانات.
|
||||
**خطافات إبطال ذاكرة التخزين المؤقت:** تكامل اختياري مع أحداث تعديل الرسم البياني.
|
||||
**لوحات مراقبة:** تتبع معدلات نجاح ذاكرة التخزين المؤقت مقابل حوادث عدم الاستقرار.
|
||||
**سياسات ذاكرة تخزين مؤقت قابلة للتكوين:** السماح بضبط لكل توزيع بناءً على تكرار التعديل.
|
||||
|
||||
<<<<<<< HEAD
|
||||
**تكوين ذاكرة التخزين المؤقت الموصى به بناءً على معدل تعديل الرسم البياني:**
|
||||
=======
|
||||
**تكوين ذاكرة التخزين المؤقت الموصى به حسب معدل تعديل الرسم البياني:**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**تعديل مرتفع (>100 تغيير/ساعة):** TTL=60 ثانية، أحجام ذاكرة تخزين مؤقت أصغر.
|
||||
**تعديل متوسط (10-100 تغيير/ساعة):** TTL=300 ثانية (افتراضي).
|
||||
**تعديل منخفض (<10 تغيير/ساعة):** TTL=600 ثانية، أحجام ذاكرة تخزين مؤقت أكبر.
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
**منع حقن الاستعلام:**
|
||||
التحقق من صحة جميع معرفات الكيانات ومعلمات الاستعلام.
|
||||
استخدم استعلامات مُعلمات لجميع التفاعلات مع قاعدة البيانات.
|
||||
تنفيذ حدود تعقيد الاستعلام لمنع هجمات الحرمان من الخدمة.
|
||||
|
||||
**حماية الموارد:**
|
||||
<<<<<<< HEAD
|
||||
فرض حدود قصوى لحجم الرسم البياني.
|
||||
=======
|
||||
فرض حدود قصوى لحجم الرسم البياني الفرعي.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
تنفيذ مهلات الاستعلام لمنع استنفاد الموارد.
|
||||
إضافة مراقبة حدود استخدام الذاكرة.
|
||||
|
||||
**التحكم في الوصول:**
|
||||
الحفاظ على عزل المستخدمين والمجموعات الحالي.
|
||||
إضافة تسجيل تدقيق للعمليات التي تؤثر على الأداء.
|
||||
تنفيذ تحديد المعدل للعمليات المكلفة.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
### التحسينات المتوقعة في الأداء
|
||||
|
||||
**تقليل عدد الاستعلامات:**
|
||||
الحالي: ~9000+ استعلام للطلب النموذجي.
|
||||
مُحسَّن: ~50-100 استعلام مجمعة (تقليل بنسبة 98٪).
|
||||
|
||||
**تحسينات في وقت الاستجابة:**
|
||||
اجتياز الرسم البياني: 15-20 ثانية → 3-5 ثوانٍ (أسرع بـ 4-5 مرات).
|
||||
<<<<<<< HEAD
|
||||
حل التسميات: 8-12 ثانية → 2-4 ثوانٍ (أسرع بـ 3 مرات).
|
||||
الاستعلام الإجمالي: 25-35 ثانية → 6-10 ثوانٍ (تحسين بنسبة 3-4 مرات).
|
||||
=======
|
||||
حل التسمية: 8-12 ثانية → 2-4 ثوانٍ (أسرع بـ 3 مرات).
|
||||
الاستعلام الإجمالي: 25-35 ثانية → 6-10 ثوانٍ (تحسين بـ 3-4 مرات).
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**كفاءة الذاكرة:**
|
||||
تمنع أحجام ذاكرة التخزين المؤقت المحددة تسرب الذاكرة.
|
||||
تقلل الهياكل البيانية الفعالة من البصمة الذاكرة بنسبة ~40٪.
|
||||
<<<<<<< HEAD
|
||||
جمع القمامة بشكل أفضل من خلال التنظيف المناسب للموارد.
|
||||
=======
|
||||
تحسين جمع البيانات المهملة من خلال التنظيف المناسب للموارد.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**توقعات واقعية للأداء:**
|
||||
**ذاكرة تخزين مؤقت للتسميات:** تقليل استعلام بنسبة 10-20٪ للرسوم البيانية ذات العلاقات الشائعة.
|
||||
**تحسين التجميع:** تقليل استعلام بنسبة 50-80٪ (التحسين الأساسي).
|
||||
**تحسين عمر الكائن:** إزالة النفقات العامة لإنشاء الطلبات لكل طلب.
|
||||
<<<<<<< HEAD
|
||||
**تحسين إجمالي:** تحسين وقت الاستجابة بنسبة 3-4 مرات بشكل أساسي من خلال التجميع.
|
||||
=======
|
||||
**تحسين إجمالي:** تحسين وقت الاستجابة بـ 3-4 مرات بشكل أساسي من خلال التجميع.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**تحسينات قابلية التوسع:**
|
||||
دعم رسوم بيانية معرفية أكبر بـ 3-5 مرات (محدود بمتطلبات تناسق ذاكرة التخزين المؤقت).
|
||||
سعة أعلى للطلبات المتزامنة بـ 3-5 مرات.
|
||||
استخدام أفضل للموارد من خلال إعادة استخدام الاتصالات.
|
||||
|
||||
### مراقبة الأداء
|
||||
|
||||
**مقاييس في الوقت الفعلي:**
|
||||
أوقات تنفيذ الاستعلام حسب نوع العملية.
|
||||
نسب نجاح ذاكرة التخزين المؤقت وفعاليتها.
|
||||
استخدام مجموعة اتصالات قاعدة البيانات.
|
||||
<<<<<<< HEAD
|
||||
استخدام الذاكرة وتأثير جمع القمامة.
|
||||
=======
|
||||
استخدام الذاكرة وتأثير جمع البيانات المهملة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**قياس الأداء:**
|
||||
اختبارات انحدار الأداء الآلية
|
||||
اختبارات التحميل باستخدام أحجام بيانات واقعية
|
||||
معايير مقارنة مقابل التنفيذ الحالي
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
<<<<<<< HEAD
|
||||
### اختبارات الوحدة
|
||||
اختبار المكونات الفردية للتنقل والتخزين المؤقت وحل التسميات
|
||||
محاكاة تفاعلات قاعدة البيانات لأغراض اختبار الأداء
|
||||
اختبار إزالة التخزين المؤقت وانتهاء صلاحية TTL
|
||||
معالجة الأخطاء وسيناريوهات المهلة الزمنية
|
||||
|
||||
### اختبار التكامل
|
||||
اختبار شامل لاستعلامات GraphRAG مع التحسينات
|
||||
=======
|
||||
### اختبار الوحدة
|
||||
اختبار المكونات الفردية للتنقل والتخزين المؤقت وحل التسميات
|
||||
محاكاة تفاعلات قاعدة البيانات لأغراض اختبار الأداء
|
||||
اختبار إزالة التخزين المؤقت وانتهاء صلاحية TTL
|
||||
معالجة الأخطاء وسيناريوهات المهلة
|
||||
|
||||
### اختبار التكامل
|
||||
اختبار شامل لاستعلام GraphRAG مع التحسينات
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
اختبار تفاعلات قاعدة البيانات باستخدام بيانات حقيقية
|
||||
معالجة الطلبات المتزامنة وإدارة الموارد
|
||||
اكتشاف تسرب الذاكرة والتحقق من تنظيف الموارد
|
||||
|
||||
### اختبار الأداء
|
||||
اختبارات قياس الأداء مقابل التنفيذ الحالي
|
||||
<<<<<<< HEAD
|
||||
اختبارات التحميل بأحجام وتعقيدات رسومية مختلفة
|
||||
=======
|
||||
اختبارات التحميل بأحجام وتعقيدات رسوم بيانية مختلفة
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
اختبارات الضغط لحدود الذاكرة والاتصالات
|
||||
اختبارات الانحدار لتحسينات الأداء
|
||||
|
||||
### اختبار التوافق
|
||||
التحقق من توافق واجهة برمجة تطبيقات GraphRAG الحالية
|
||||
<<<<<<< HEAD
|
||||
الاختبار مع قواعد بيانات رسومية مختلفة
|
||||
=======
|
||||
الاختبار مع قواعد بيانات رسوم بيانية مختلفة
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
التحقق من دقة النتائج مقارنة بالتنفيذ الحالي
|
||||
|
||||
## خطة التنفيذ
|
||||
|
||||
### نهج التنفيذ المباشر
|
||||
نظرًا لأن واجهات برمجة التطبيقات مسموح لها بالتغيير، قم بتنفيذ التحسينات مباشرةً دون تعقيد الترحيل:
|
||||
|
||||
<<<<<<< HEAD
|
||||
1. **استبدال `follow_edges`:** أعد كتابة باستخدام تجول دفعي تكراري
|
||||
=======
|
||||
1. **استبدال `follow_edges`:** أعد كتابة باستخدام تجول مجمّع تكراري
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
2. **تحسين `get_labelgraph`:** قم بتنفيذ حل تسميات متوازي
|
||||
3. **إضافة GraphRag طويل الأمد:** قم بتعديل المعالج للحفاظ على مثيل دائم
|
||||
4. **تنفيذ التخزين المؤقت للتسميات:** أضف ذاكرة تخزين مؤقت LRU مع TTL إلى فئة GraphRag
|
||||
|
||||
### نطاق التغييرات
|
||||
<<<<<<< HEAD
|
||||
**فئة الاستعلام:** استبدل ~50 سطرًا في `follow_edges`، وأضف ~30 سطرًا لمعالجة الدفعات
|
||||
=======
|
||||
**فئة الاستعلام:** استبدل ~50 سطرًا في `follow_edges`، وأضف ~30 سطرًا لمعالجة الدُفعات
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**فئة GraphRag:** أضف طبقة التخزين المؤقت (~40 سطرًا)
|
||||
**فئة المعالج:** قم بتعديل لاستخدام مثيل GraphRag دائم (~20 سطرًا)
|
||||
**الإجمالي:** ~140 سطرًا من التغييرات المركزة، معظمها داخل الفئات الحالية
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
<<<<<<< HEAD
|
||||
**الأسبوع 1: التنفيذ الأساسي**
|
||||
استبدل `follow_edges` بالتجول الدفعي التكراري
|
||||
=======
|
||||
**الأسبوع الأول: التنفيذ الأساسي**
|
||||
استبدل `follow_edges` بتجول تكراري مجمّع
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
قم بتنفيذ حل تسميات متوازي في `get_labelgraph`
|
||||
أضف مثيل GraphRag طويل الأمد إلى المعالج
|
||||
قم بتنفيذ طبقة التخزين المؤقت للتسميات
|
||||
|
||||
<<<<<<< HEAD
|
||||
**الأسبوع 2: الاختبار والتكامل**
|
||||
اختبارات الوحدة لمنطق التجول والتخزين المؤقت الجديد
|
||||
قياس أداء مقابل التنفيذ الحالي
|
||||
اختبار التكامل مع بيانات رسومية حقيقية
|
||||
مراجعة التعليمات البرمجية والتحسين
|
||||
|
||||
**الأسبوع 3: النشر**
|
||||
نشر التنفيذ المحسن
|
||||
مراقبة تحسينات الأداء
|
||||
ضبط TTL للتخزين المؤقت وأحجام الدفعات بناءً على الاستخدام الفعلي
|
||||
=======
|
||||
**الأسبوع الثاني: الاختبار والتكامل**
|
||||
اختبارات الوحدة لمنطق التجول والتخزين المؤقت الجديد
|
||||
قياس أداء مقابل التنفيذ الحالي
|
||||
اختبارات التكامل مع بيانات الرسم البياني الحقيقية
|
||||
مراجعة التعليمات البرمجية والتحسين
|
||||
|
||||
**الأسبوع الثالث: النشر**
|
||||
نشر التنفيذ المحسن
|
||||
مراقبة تحسينات الأداء
|
||||
ضبط TTL للتخزين المؤقت وأحجام الدُفعات بناءً على الاستخدام الفعلي
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
**تجميع الاتصالات بقاعدة البيانات:** هل يجب علينا تنفيذ تجميع اتصالات مخصص أم الاعتماد على تجميع عملاء قاعدة البيانات الحالي؟
|
||||
**استمرارية التخزين المؤقت:** هل يجب أن تستمر ذاكرات التخزين المؤقت للتسميات والتضمينات عبر عمليات إعادة تشغيل الخدمة؟
|
||||
**التخزين المؤقت الموزع:** بالنسبة لنشرات متعددة المثيلات، هل يجب علينا تنفيذ تخزين مؤقت موزع باستخدام Redis/Memcached؟
|
||||
**تنسيق نتيجة الاستعلام:** هل يجب علينا تحسين التمثيل الداخلي للثلاثيات لتحسين كفاءة الذاكرة؟
|
||||
**تكامل المراقبة:** ما هي المقاييس التي يجب عرضها على أنظمة المراقبة الحالية (Prometheus، إلخ)؟
|
||||
|
||||
## المراجع
|
||||
|
||||
[التنفيذ الأصلي لـ GraphRAG](trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py)
|
||||
<<<<<<< HEAD
|
||||
[مبادئ معمارية TrustGraph](architecture-principles.md)
|
||||
[مواصفات إدارة المجموعة](collection-management.md)
|
||||
=======
|
||||
[مبادئ بنية TrustGraph](architecture-principles.md)
|
||||
[مواصفات إدارة المجموعات](collection-management.md)
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
717
docs/tech-specs/ar/import-export-graceful-shutdown.ar.md
Normal file
717
docs/tech-specs/ar/import-export-graceful-shutdown.ar.md
Normal file
|
|
@ -0,0 +1,717 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية للإغلاق التدريجي للاستيراد/التصدير"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية للإغلاق التدريجي للاستيراد/التصدير
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
بوابة TrustGraph تواجه حاليًا فقدان الرسائل أثناء إغلاق WebSocket في كل من عمليات الاستيراد والتصدير. يحدث هذا بسبب حالات السباق حيث يتم التخلص من الرسائل أثناء النقل قبل وصولها إلى وجهتها (قوائم انتظار Pulsar للاستيراد، عملاء WebSocket للتصدير).
|
||||
|
||||
### مشاكل جانب الاستيراد
|
||||
1. مخزن مؤقت asyncio.Queue الخاص بالناشر غير فارغ عند الإغلاق.
|
||||
2. يتم إغلاق WebSocket قبل التأكد من وصول الرسائل الموجودة في قائمة الانتظار إلى Pulsar.
|
||||
3. لا يوجد آلية تأكيد لتسليم الرسائل بنجاح.
|
||||
|
||||
### مشاكل جانب التصدير
|
||||
1. يتم تأكيد الرسائل في Pulsar قبل التسليم الناجح إلى العملاء.
|
||||
2. تؤدي قيم المهلة الثابتة إلى فقدان الرسائل عندما تكون قوائم الانتظار ممتلئة.
|
||||
3. لا يوجد آلية للتحكم في التدفق للتعامل مع المستهلكين البطيئين.
|
||||
4. نقاط تخزين مؤقت متعددة حيث يمكن فقدان البيانات.
|
||||
|
||||
## نظرة عامة على البنية
|
||||
|
||||
```
|
||||
Import Flow:
|
||||
Client -> Websocket -> TriplesImport -> Publisher -> Pulsar Queue
|
||||
|
||||
Export Flow:
|
||||
Pulsar Queue -> Subscriber -> TriplesExport -> Websocket -> Client
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
## التحسينات المقترحة
|
||||
=======
|
||||
## الحلول المقترحة
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### 1. تحسينات الناشر (جانب الاستيراد)
|
||||
|
||||
#### أ. تفريغ سلس للانتظار
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/base/publisher.py`
|
||||
|
||||
```python
|
||||
class Publisher:
|
||||
def __init__(self, client, topic, schema=None, max_size=10,
|
||||
chunking_enabled=True, drain_timeout=5.0):
|
||||
self.client = client
|
||||
self.topic = topic
|
||||
self.schema = schema
|
||||
self.q = asyncio.Queue(maxsize=max_size)
|
||||
self.chunking_enabled = chunking_enabled
|
||||
self.running = True
|
||||
self.draining = False # New state for graceful shutdown
|
||||
self.task = None
|
||||
self.drain_timeout = drain_timeout
|
||||
|
||||
async def stop(self):
|
||||
"""Initiate graceful shutdown with draining"""
|
||||
self.running = False
|
||||
self.draining = True
|
||||
|
||||
if self.task:
|
||||
# Wait for run() to complete draining
|
||||
await self.task
|
||||
|
||||
async def run(self):
|
||||
"""Enhanced run method with integrated draining logic"""
|
||||
while self.running or self.draining:
|
||||
try:
|
||||
producer = self.client.create_producer(
|
||||
topic=self.topic,
|
||||
schema=JsonSchema(self.schema),
|
||||
chunking_enabled=self.chunking_enabled,
|
||||
)
|
||||
|
||||
drain_end_time = None
|
||||
|
||||
while self.running or self.draining:
|
||||
try:
|
||||
# Start drain timeout when entering drain mode
|
||||
if self.draining and drain_end_time is None:
|
||||
drain_end_time = time.time() + self.drain_timeout
|
||||
logger.info(f"Publisher entering drain mode, timeout={self.drain_timeout}s")
|
||||
|
||||
# Check drain timeout
|
||||
if self.draining and time.time() > drain_end_time:
|
||||
if not self.q.empty():
|
||||
logger.warning(f"Drain timeout reached with {self.q.qsize()} messages remaining")
|
||||
self.draining = False
|
||||
break
|
||||
|
||||
# Calculate wait timeout based on mode
|
||||
if self.draining:
|
||||
# Shorter timeout during draining to exit quickly when empty
|
||||
timeout = min(0.1, drain_end_time - time.time())
|
||||
else:
|
||||
# Normal operation timeout
|
||||
timeout = 0.25
|
||||
|
||||
# Get message from queue
|
||||
id, item = await asyncio.wait_for(
|
||||
self.q.get(),
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
# Send the message (single place for sending)
|
||||
if id:
|
||||
producer.send(item, { "id": id })
|
||||
else:
|
||||
producer.send(item)
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
# If draining and queue is empty, we're done
|
||||
if self.draining and self.q.empty():
|
||||
logger.info("Publisher queue drained successfully")
|
||||
self.draining = False
|
||||
break
|
||||
continue
|
||||
|
||||
except asyncio.QueueEmpty:
|
||||
# If draining and queue is empty, we're done
|
||||
if self.draining and self.q.empty():
|
||||
logger.info("Publisher queue drained successfully")
|
||||
self.draining = False
|
||||
break
|
||||
continue
|
||||
|
||||
# Flush producer before closing
|
||||
if producer:
|
||||
producer.flush()
|
||||
producer.close()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Exception in publisher: {e}", exc_info=True)
|
||||
|
||||
if not self.running and not self.draining:
|
||||
return
|
||||
|
||||
# If handler drops out, sleep a retry
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async def send(self, id, item):
|
||||
"""Send still works normally - just adds to queue"""
|
||||
if self.draining:
|
||||
# Optionally reject new messages during drain
|
||||
raise RuntimeError("Publisher is shutting down, not accepting new messages")
|
||||
await self.q.put((id, item))
|
||||
```
|
||||
|
||||
**المزايا الرئيسية للتصميم:**
|
||||
**موقع إرسال واحد**: جميع استدعاءات `producer.send()` تحدث في مكان واحد داخل الطريقة `run()`.
|
||||
<<<<<<< HEAD
|
||||
**آلة حالة واضحة:** ثلاثة حالات واضحة - قيد التشغيل، في مرحلة التفريغ، متوقفة.
|
||||
=======
|
||||
**آلة حالة واضحة:** ثلاثة حالات واضحة - قيد التشغيل، في طور التفريغ، متوقفة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**حماية من المهلة الزمنية:** لن تتعطل بشكل دائم أثناء التفريغ.
|
||||
**إمكانية مراقبة أفضل:** تسجيل واضح لتقدم التفريغ والانتقالات بين الحالات.
|
||||
**رفض الرسائل الاختياري:** يمكن رفض الرسائل الجديدة أثناء مرحلة الإغلاق.
|
||||
|
||||
#### ب. ترتيب الإغلاق المحسّن
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/gateway/dispatch/triples_import.py`
|
||||
|
||||
```python
|
||||
class TriplesImport:
|
||||
async def destroy(self):
|
||||
"""Enhanced destroy with proper shutdown order"""
|
||||
# Step 1: Stop accepting new messages
|
||||
self.running.stop()
|
||||
|
||||
# Step 2: Wait for publisher to drain its queue
|
||||
logger.info("Draining publisher queue...")
|
||||
await self.publisher.stop()
|
||||
|
||||
# Step 3: Close websocket only after queue is drained
|
||||
if self.ws:
|
||||
await self.ws.close()
|
||||
```
|
||||
|
||||
### 2. تحسينات المشترك (الجانب التصديري)
|
||||
|
||||
#### أ. نمط التصريف المتكامل
|
||||
|
||||
**الملف:** `trustgraph-base/trustgraph/base/subscriber.py`
|
||||
|
||||
```python
|
||||
class Subscriber:
|
||||
def __init__(self, client, topic, subscription, consumer_name,
|
||||
schema=None, max_size=100, metrics=None,
|
||||
backpressure_strategy="block", drain_timeout=5.0):
|
||||
# ... existing init ...
|
||||
self.backpressure_strategy = backpressure_strategy
|
||||
self.running = True
|
||||
self.draining = False # New state for graceful shutdown
|
||||
self.drain_timeout = drain_timeout
|
||||
self.pending_acks = {} # Track messages awaiting delivery
|
||||
|
||||
async def stop(self):
|
||||
"""Initiate graceful shutdown with draining"""
|
||||
self.running = False
|
||||
self.draining = True
|
||||
|
||||
if self.task:
|
||||
# Wait for run() to complete draining
|
||||
await self.task
|
||||
|
||||
async def run(self):
|
||||
"""Enhanced run method with integrated draining logic"""
|
||||
while self.running or self.draining:
|
||||
if self.metrics:
|
||||
self.metrics.state("stopped")
|
||||
|
||||
try:
|
||||
self.consumer = self.client.subscribe(
|
||||
topic = self.topic,
|
||||
subscription_name = self.subscription,
|
||||
consumer_name = self.consumer_name,
|
||||
schema = JsonSchema(self.schema),
|
||||
)
|
||||
|
||||
if self.metrics:
|
||||
self.metrics.state("running")
|
||||
|
||||
logger.info("Subscriber running...")
|
||||
drain_end_time = None
|
||||
|
||||
while self.running or self.draining:
|
||||
# Start drain timeout when entering drain mode
|
||||
if self.draining and drain_end_time is None:
|
||||
drain_end_time = time.time() + self.drain_timeout
|
||||
logger.info(f"Subscriber entering drain mode, timeout={self.drain_timeout}s")
|
||||
|
||||
# Stop accepting new messages from Pulsar during drain
|
||||
self.consumer.pause_message_listener()
|
||||
|
||||
# Check drain timeout
|
||||
if self.draining and time.time() > drain_end_time:
|
||||
async with self.lock:
|
||||
total_pending = sum(
|
||||
q.qsize() for q in
|
||||
list(self.q.values()) + list(self.full.values())
|
||||
)
|
||||
if total_pending > 0:
|
||||
logger.warning(f"Drain timeout reached with {total_pending} messages in queues")
|
||||
self.draining = False
|
||||
break
|
||||
|
||||
# Check if we can exit drain mode
|
||||
if self.draining:
|
||||
async with self.lock:
|
||||
all_empty = all(
|
||||
q.empty() for q in
|
||||
list(self.q.values()) + list(self.full.values())
|
||||
)
|
||||
if all_empty and len(self.pending_acks) == 0:
|
||||
logger.info("Subscriber queues drained successfully")
|
||||
self.draining = False
|
||||
break
|
||||
|
||||
# Process messages only if not draining
|
||||
if not self.draining:
|
||||
try:
|
||||
msg = await asyncio.to_thread(
|
||||
self.consumer.receive,
|
||||
timeout_millis=250
|
||||
)
|
||||
except _pulsar.Timeout:
|
||||
continue
|
||||
except Exception as e:
|
||||
logger.error(f"Exception in subscriber receive: {e}", exc_info=True)
|
||||
raise e
|
||||
|
||||
if self.metrics:
|
||||
self.metrics.received()
|
||||
|
||||
# Process the message
|
||||
await self._process_message(msg)
|
||||
else:
|
||||
# During draining, just wait for queues to empty
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Subscriber exception: {e}", exc_info=True)
|
||||
|
||||
finally:
|
||||
# Negative acknowledge any pending messages
|
||||
for msg in self.pending_acks.values():
|
||||
self.consumer.negative_acknowledge(msg)
|
||||
self.pending_acks.clear()
|
||||
|
||||
if self.consumer:
|
||||
self.consumer.unsubscribe()
|
||||
self.consumer.close()
|
||||
self.consumer = None
|
||||
|
||||
if self.metrics:
|
||||
self.metrics.state("stopped")
|
||||
|
||||
if not self.running and not self.draining:
|
||||
return
|
||||
|
||||
# If handler drops out, sleep a retry
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async def _process_message(self, msg):
|
||||
"""Process a single message with deferred acknowledgment"""
|
||||
# Store message for later acknowledgment
|
||||
msg_id = str(uuid.uuid4())
|
||||
self.pending_acks[msg_id] = msg
|
||||
|
||||
try:
|
||||
id = msg.properties()["id"]
|
||||
except:
|
||||
id = None
|
||||
|
||||
value = msg.value()
|
||||
delivery_success = False
|
||||
|
||||
async with self.lock:
|
||||
# Deliver to specific subscribers
|
||||
if id in self.q:
|
||||
delivery_success = await self._deliver_to_queue(
|
||||
self.q[id], value
|
||||
)
|
||||
|
||||
# Deliver to all subscribers
|
||||
for q in self.full.values():
|
||||
if await self._deliver_to_queue(q, value):
|
||||
delivery_success = True
|
||||
|
||||
# Acknowledge only on successful delivery
|
||||
if delivery_success:
|
||||
self.consumer.acknowledge(msg)
|
||||
del self.pending_acks[msg_id]
|
||||
else:
|
||||
# Negative acknowledge for retry
|
||||
self.consumer.negative_acknowledge(msg)
|
||||
del self.pending_acks[msg_id]
|
||||
|
||||
async def _deliver_to_queue(self, queue, value):
|
||||
"""Deliver message to queue with backpressure handling"""
|
||||
try:
|
||||
if self.backpressure_strategy == "block":
|
||||
# Block until space available (no timeout)
|
||||
await queue.put(value)
|
||||
return True
|
||||
|
||||
elif self.backpressure_strategy == "drop_oldest":
|
||||
# Drop oldest message if queue full
|
||||
if queue.full():
|
||||
try:
|
||||
queue.get_nowait()
|
||||
if self.metrics:
|
||||
self.metrics.dropped()
|
||||
except asyncio.QueueEmpty:
|
||||
pass
|
||||
await queue.put(value)
|
||||
return True
|
||||
|
||||
elif self.backpressure_strategy == "drop_new":
|
||||
# Drop new message if queue full
|
||||
if queue.full():
|
||||
if self.metrics:
|
||||
self.metrics.dropped()
|
||||
return False
|
||||
await queue.put(value)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to deliver message: {e}")
|
||||
return False
|
||||
```
|
||||
|
||||
**المزايا الرئيسية للتصميم (مطابقة لنمط الناشر):**
|
||||
<<<<<<< HEAD
|
||||
**موقع معالجة واحد:** تتم جميع عمليات معالجة الرسائل في الطريقة `run()`.
|
||||
**آلة حالة واضحة:** ثلاثة حالات واضحة - قيد التشغيل، في مرحلة التفريغ، متوقفة.
|
||||
**الإيقاف المؤقت أثناء التفريغ:** تتوقف عن قبول رسائل جديدة من Pulsar أثناء تفريغ قوائم الانتظار الحالية.
|
||||
**حماية ضد المهلة:** لن تتعطل إلى أجل غير مسمى أثناء التفريغ.
|
||||
=======
|
||||
**موقع معالجة واحد:** تتم معالجة جميع الرسائل في الطريقة `run()`.
|
||||
**آلة حالة واضحة:** ثلاثة حالات واضحة - قيد التشغيل، في مرحلة التفريغ، متوقفة.
|
||||
**الإيقاف المؤقت أثناء التفريغ:** تتوقف عن قبول رسائل جديدة من Pulsar أثناء تفريغ قوائم الانتظار الحالية.
|
||||
**حماية المهلة الزمنية:** لن تتعطل إلى أجل غير مسمى أثناء التفريغ.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
**تنظيف صحيح:** تعترف بأي رسائل لم يتم تسليمها على الإغلاق.
|
||||
|
||||
#### ب. تحسينات معالج التصدير
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/gateway/dispatch/triples_export.py`
|
||||
|
||||
```python
|
||||
class TriplesExport:
|
||||
async def destroy(self):
|
||||
"""Enhanced destroy with graceful shutdown"""
|
||||
# Step 1: Signal stop to prevent new messages
|
||||
self.running.stop()
|
||||
|
||||
# Step 2: Wait briefly for in-flight messages
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
# Step 3: Unsubscribe and stop subscriber (triggers queue drain)
|
||||
if hasattr(self, 'subs'):
|
||||
await self.subs.unsubscribe_all(self.id)
|
||||
await self.subs.stop()
|
||||
|
||||
# Step 4: Close websocket last
|
||||
if self.ws and not self.ws.closed:
|
||||
await self.ws.close()
|
||||
|
||||
async def run(self):
|
||||
"""Enhanced run with better error handling"""
|
||||
self.subs = Subscriber(
|
||||
client = self.pulsar_client,
|
||||
topic = self.queue,
|
||||
consumer_name = self.consumer,
|
||||
subscription = self.subscriber,
|
||||
schema = Triples,
|
||||
backpressure_strategy = "block" # Configurable
|
||||
)
|
||||
|
||||
await self.subs.start()
|
||||
|
||||
self.id = str(uuid.uuid4())
|
||||
q = await self.subs.subscribe_all(self.id)
|
||||
|
||||
consecutive_errors = 0
|
||||
max_consecutive_errors = 5
|
||||
|
||||
while self.running.get():
|
||||
try:
|
||||
resp = await asyncio.wait_for(q.get(), timeout=0.5)
|
||||
await self.ws.send_json(serialize_triples(resp))
|
||||
consecutive_errors = 0 # Reset on success
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
|
||||
except queue.Empty:
|
||||
continue
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Exception sending to websocket: {str(e)}")
|
||||
consecutive_errors += 1
|
||||
|
||||
if consecutive_errors >= max_consecutive_errors:
|
||||
logger.error("Too many consecutive errors, shutting down")
|
||||
break
|
||||
|
||||
# Brief pause before retry
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
# Graceful cleanup handled in destroy()
|
||||
```
|
||||
|
||||
### 3. تحسينات على مستوى المقابس.
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/gateway/endpoint/socket.py`
|
||||
|
||||
```python
|
||||
class SocketEndpoint:
|
||||
async def listener(self, ws, dispatcher, running):
|
||||
"""Enhanced listener with graceful shutdown"""
|
||||
async for msg in ws:
|
||||
if msg.type == WSMsgType.TEXT:
|
||||
await dispatcher.receive(msg)
|
||||
continue
|
||||
elif msg.type == WSMsgType.BINARY:
|
||||
await dispatcher.receive(msg)
|
||||
continue
|
||||
else:
|
||||
# Graceful shutdown on close
|
||||
logger.info("Websocket closing, initiating graceful shutdown")
|
||||
running.stop()
|
||||
|
||||
# Allow time for dispatcher cleanup
|
||||
await asyncio.sleep(1.0)
|
||||
break
|
||||
|
||||
async def handle(self, request):
|
||||
"""Enhanced handler with better cleanup"""
|
||||
# ... existing setup code ...
|
||||
|
||||
try:
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
running = Running()
|
||||
|
||||
dispatcher = await self.dispatcher(
|
||||
ws, running, request.match_info
|
||||
)
|
||||
|
||||
worker_task = tg.create_task(
|
||||
self.worker(ws, dispatcher, running)
|
||||
)
|
||||
|
||||
lsnr_task = tg.create_task(
|
||||
self.listener(ws, dispatcher, running)
|
||||
)
|
||||
|
||||
except ExceptionGroup as e:
|
||||
logger.error("Exception group occurred:", exc_info=True)
|
||||
|
||||
# Attempt graceful dispatcher shutdown
|
||||
try:
|
||||
await asyncio.wait_for(
|
||||
dispatcher.destroy(),
|
||||
timeout=5.0
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning("Dispatcher shutdown timed out")
|
||||
except Exception as de:
|
||||
logger.error(f"Error during dispatcher cleanup: {de}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Socket exception: {e}", exc_info=True)
|
||||
|
||||
finally:
|
||||
# Ensure dispatcher cleanup
|
||||
if dispatcher and hasattr(dispatcher, 'destroy'):
|
||||
try:
|
||||
await dispatcher.destroy()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Ensure websocket is closed
|
||||
if ws and not ws.closed:
|
||||
await ws.close()
|
||||
|
||||
return ws
|
||||
```
|
||||
|
||||
## خيارات التكوين
|
||||
|
||||
إضافة دعم للتكوين لضبط السلوك:
|
||||
|
||||
```python
|
||||
# config.py
|
||||
class GracefulShutdownConfig:
|
||||
# Publisher settings
|
||||
PUBLISHER_DRAIN_TIMEOUT = 5.0 # Seconds to wait for queue drain
|
||||
PUBLISHER_FLUSH_TIMEOUT = 2.0 # Producer flush timeout
|
||||
|
||||
# Subscriber settings
|
||||
SUBSCRIBER_DRAIN_TIMEOUT = 5.0 # Seconds to wait for queue drain
|
||||
BACKPRESSURE_STRATEGY = "block" # Options: "block", "drop_oldest", "drop_new"
|
||||
SUBSCRIBER_MAX_QUEUE_SIZE = 100 # Maximum queue size before backpressure
|
||||
|
||||
# Socket settings
|
||||
SHUTDOWN_GRACE_PERIOD = 1.0 # Seconds to wait for graceful shutdown
|
||||
MAX_CONSECUTIVE_ERRORS = 5 # Maximum errors before forced shutdown
|
||||
|
||||
# Monitoring
|
||||
LOG_QUEUE_STATS = True # Log queue statistics on shutdown
|
||||
METRICS_ENABLED = True # Enable metrics collection
|
||||
```
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبارات الوحدة
|
||||
|
||||
```python
|
||||
async def test_publisher_queue_drain():
|
||||
"""Verify Publisher drains queue on shutdown"""
|
||||
publisher = Publisher(...)
|
||||
|
||||
# Fill queue with messages
|
||||
for i in range(10):
|
||||
await publisher.send(f"id-{i}", {"data": i})
|
||||
|
||||
# Stop publisher
|
||||
await publisher.stop()
|
||||
|
||||
# Verify all messages were sent
|
||||
assert publisher.q.empty()
|
||||
assert mock_producer.send.call_count == 10
|
||||
|
||||
async def test_subscriber_deferred_ack():
|
||||
"""Verify Subscriber only acks on successful delivery"""
|
||||
subscriber = Subscriber(..., backpressure_strategy="drop_new")
|
||||
|
||||
# Fill queue to capacity
|
||||
queue = await subscriber.subscribe("test")
|
||||
for i in range(100):
|
||||
await queue.put({"data": i})
|
||||
|
||||
# Try to add message when full
|
||||
msg = create_mock_message()
|
||||
await subscriber._process_message(msg)
|
||||
|
||||
# Verify negative acknowledgment
|
||||
assert msg.negative_acknowledge.called
|
||||
assert not msg.acknowledge.called
|
||||
```
|
||||
|
||||
### اختبارات التكامل
|
||||
|
||||
```python
|
||||
async def test_import_graceful_shutdown():
|
||||
"""Test import path handles shutdown gracefully"""
|
||||
# Setup
|
||||
import_handler = TriplesImport(...)
|
||||
await import_handler.start()
|
||||
|
||||
# Send messages
|
||||
messages = []
|
||||
for i in range(100):
|
||||
msg = {"metadata": {...}, "triples": [...]}
|
||||
await import_handler.receive(msg)
|
||||
messages.append(msg)
|
||||
|
||||
# Shutdown while messages in flight
|
||||
await import_handler.destroy()
|
||||
|
||||
# Verify all messages reached Pulsar
|
||||
received = await pulsar_consumer.receive_all()
|
||||
assert len(received) == 100
|
||||
|
||||
async def test_export_no_message_loss():
|
||||
"""Test export path doesn't lose acknowledged messages"""
|
||||
# Setup Pulsar with test messages
|
||||
for i in range(100):
|
||||
await pulsar_producer.send({"data": i})
|
||||
|
||||
# Start export handler
|
||||
export_handler = TriplesExport(...)
|
||||
export_task = asyncio.create_task(export_handler.run())
|
||||
|
||||
# Receive some messages
|
||||
received = []
|
||||
for _ in range(50):
|
||||
msg = await websocket.receive()
|
||||
received.append(msg)
|
||||
|
||||
# Force shutdown
|
||||
await export_handler.destroy()
|
||||
|
||||
# Continue receiving until websocket closes
|
||||
while not websocket.closed:
|
||||
try:
|
||||
msg = await websocket.receive()
|
||||
received.append(msg)
|
||||
except:
|
||||
break
|
||||
|
||||
# Verify no acknowledged messages were lost
|
||||
assert len(received) >= 50
|
||||
```
|
||||
|
||||
## خطة التنفيذ
|
||||
|
||||
### المرحلة الأولى: الإصلاحات الحرجة (الأسبوع الأول)
|
||||
إصلاح توقيت إقرار المشترك (لمنع فقدان الرسائل)
|
||||
إضافة تفريغ قائمة الناشر
|
||||
النشر في بيئة الاختبار
|
||||
|
||||
### المرحلة الثانية: الإغلاق التدريجي (الأسبوع الثاني)
|
||||
<<<<<<< HEAD
|
||||
تطبيق تنسيق الإغلاق
|
||||
=======
|
||||
تطبيق التنسيق للإغلاق
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
إضافة استراتيجيات الضغط العكسي
|
||||
اختبار الأداء
|
||||
|
||||
### المرحلة الثالثة: المراقبة والضبط (الأسبوع الثالث)
|
||||
إضافة مقاييس لعمق قائمة الانتظار
|
||||
إضافة تنبيهات لفقدان الرسائل
|
||||
ضبط قيم المهلة بناءً على بيانات الإنتاج
|
||||
|
||||
## المراقبة والتنبيهات
|
||||
|
||||
### المقاييس التي يجب تتبعها
|
||||
`publisher.queue.depth` - حجم قائمة الانتظار الحالية للناشر
|
||||
`publisher.messages.dropped` - الرسائل المفقودة أثناء الإغلاق
|
||||
`subscriber.messages.negatively_acknowledged` - عمليات التسليم الفاشلة
|
||||
`websocket.graceful_shutdowns` - عمليات الإغلاق التدريجي الناجحة
|
||||
`websocket.forced_shutdowns` - عمليات الإغلاق القسري/المهلة
|
||||
|
||||
### التنبيهات
|
||||
عمق قائمة الانتظار للناشر > 80٪ من السعة
|
||||
أي فقدان للرسائل أثناء الإغلاق
|
||||
معدل الإقرار السلبي للمشترك > 1٪
|
||||
تجاوز مهلة الإغلاق
|
||||
|
||||
## التوافق مع الإصدارات السابقة
|
||||
|
||||
جميع التغييرات تحافظ على التوافق مع الإصدارات السابقة:
|
||||
السلوك الافتراضي لم يتغير بدون تكوين
|
||||
تستمر عمليات النشر الحالية في العمل
|
||||
تدهور تدريجي في حالة عدم توفر الميزات الجديدة
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
<<<<<<< HEAD
|
||||
لم يتم إدخال مسارات هجوم جديدة
|
||||
=======
|
||||
لم يتم تقديم مسارات هجوم جديدة
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
يمنع الضغط العكسي هجمات استنفاد الذاكرة
|
||||
تمنع الحدود القابلة للتكوين إساءة استخدام الموارد
|
||||
|
||||
## تأثير الأداء
|
||||
|
||||
تكلفة إضافية قليلة أثناء التشغيل العادي
|
||||
قد يستغرق الإغلاق ما يصل إلى 5 ثوانٍ إضافية (قابل للتكوين)
|
||||
<<<<<<< HEAD
|
||||
يحد استخدام الذاكرة من خلال حدود حجم قائمة الانتظار
|
||||
=======
|
||||
استخدام الذاكرة محدود بحدود حجم قائمة الانتظار
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
التأثير على وحدة المعالجة المركزية ضئيل (<1٪ زيادة)
|
||||
540
docs/tech-specs/ar/jsonl-prompt-output.ar.md
Normal file
540
docs/tech-specs/ar/jsonl-prompt-output.ar.md
Normal file
|
|
@ -0,0 +1,540 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية للإخراج بتنسيق JSONL"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية للإخراج بتنسيق JSONL
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
<<<<<<< HEAD
|
||||
تصف هذه المواصفات تطبيق تنسيق JSONL (JSON Lines) للإخراج
|
||||
=======
|
||||
تصف هذه المواصفات تنفيذ تنسيق JSONL (JSON Lines) للإخراج
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
في TrustGraph. يتيح JSONL استخراجًا مقاومًا للتقطيع للبيانات المنظمة من
|
||||
استجابات نماذج اللغة الكبيرة (LLM)، مما يعالج المشكلات الهامة المتعلقة
|
||||
بتلف مخرجات JSON array عندما تصل استجابات نماذج اللغة الكبيرة إلى حدود
|
||||
الرموز المميزة للإخراج.
|
||||
|
||||
<<<<<<< HEAD
|
||||
يدعم هذا التطبيق حالات الاستخدام التالية:
|
||||
=======
|
||||
يدعم هذا التنفيذ حالات الاستخدام التالية:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
1. **الاستخراج المقاوم للتقطيع**: استخراج نتائج جزئية صالحة حتى عندما
|
||||
يتم اقتطاع إخراج نموذج اللغة الكبيرة في منتصف الاستجابة.
|
||||
2. **الاستخراج على نطاق واسع**: التعامل مع استخراج العديد من العناصر دون
|
||||
خطر الفشل التام بسبب حدود الرموز المميزة.
|
||||
3. **الاستخراج بأنواع متعددة**: دعم استخراج أنواع متعددة من الكيانات
|
||||
(التعريفات، والعلاقات، والكيانات، والسمات) في طلب واحد.
|
||||
4. **الإخراج المتوافق مع التدفق**: تمكين المعالجة المستقبلية التدريجية/المتزايدة
|
||||
لنتائج الاستخراج.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**التوافق مع الإصدارات السابقة**: تظل الطلبات الحالية التي تستخدم `response-type: "text"` و
|
||||
`response-type: "json"` تعمل دون تعديل.
|
||||
<<<<<<< HEAD
|
||||
**مقاومة التقطيع**: تؤدي مخرجات نماذج اللغة الكبيرة الجزئية إلى نتائج
|
||||
جزئية صالحة بدلاً من الفشل التام.
|
||||
**التحقق من المخطط**: دعم التحقق من مخطط JSON للكائنات الفردية.
|
||||
**الاتحادات المميزة**: دعم المخرجات ذات الأنواع المختلطة باستخدام حقل `type`
|
||||
مميز.
|
||||
**تغييرات API الحد الأدنى**: توسيع تكوين الطلب الحالي بنوع استجابة جديد
|
||||
ومفتاح مخطط.
|
||||
=======
|
||||
**مقاومة التقطيع**: تؤدي المخرجات الجزئية لنماذج اللغة الكبيرة إلى نتائج
|
||||
جزئية صالحة بدلاً من الفشل التام.
|
||||
**التحقق من المخطط**: دعم التحقق من مخطط JSON للكائنات الفردية.
|
||||
**الاتحادات المميزة**: دعم المخرجات بأنواع متعددة باستخدام حقل `type`
|
||||
كـ "مميّز".
|
||||
**تغييرات API قليلة**: توسيع تكوين الطلب الحالي بنوع استجابة جديد ومفتاح
|
||||
مخطط.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## الخلفية
|
||||
|
||||
### البنية الحالية
|
||||
|
||||
يدعم خدمة الطلبات نوعين من الاستجابات:
|
||||
|
||||
1. `response-type: "text"` - استجابة نصية خام يتم إرجاعها كما هي.
|
||||
2. `response-type: "json"` - JSON يتم تحليله من الاستجابة، ويتم التحقق منه مقابل
|
||||
`schema` اختياري.
|
||||
|
||||
التنفيذ الحالي في `trustgraph-flow/trustgraph/template/prompt_manager.py`:
|
||||
|
||||
```python
|
||||
class Prompt:
|
||||
def __init__(self, template, response_type = "text", terms=None, schema=None):
|
||||
self.template = template
|
||||
self.response_type = response_type
|
||||
self.terms = terms
|
||||
self.schema = schema
|
||||
```
|
||||
|
||||
### القيود الحالية
|
||||
|
||||
عندما تطلب مطالبات الاستخراج إخراجًا بتنسيق مصفوفات JSON (`[{...}, {...}, ...]`):
|
||||
|
||||
**تلف بسبب الاقتطاع**: إذا وصلت LLM إلى حدود رموز الإخراج أثناء المصفوفة، يصبح
|
||||
الرد بأكمله JSON غير صالح ولا يمكن تحليله.
|
||||
**التحليل الكل أو لا شيء**: يجب استقبال الإخراج الكامل قبل التحليل.
|
||||
**لا توجد نتائج جزئية**: يؤدي الرد المقتطع إلى عدم وجود بيانات قابلة للاستخدام.
|
||||
**غير موثوق به للاستخراج الكبير**: كلما زاد عدد العناصر المستخرجة، زاد خطر الفشل.
|
||||
|
||||
تعالج هذه المواصفات هذه القيود من خلال تقديم تنسيق JSONL لمطالبات
|
||||
<<<<<<< HEAD
|
||||
الاستخراج، حيث يكون كل عنصر مستخرج كائن JSON كامل في سطر منفصل.
|
||||
|
||||
|
||||
## التصميم الفني
|
||||
=======
|
||||
الاستخراج، حيث يكون كل عنصر مستخرج كائن JSON كامل على سطر منفصل.
|
||||
|
||||
|
||||
## التصميم التقني
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### إضافة نوع استجابة جديد
|
||||
|
||||
أضف نوع استجابة جديد `"jsonl"` بالإضافة إلى الأنواع الموجودة `"text"` و `"json"`.
|
||||
|
||||
#### تغييرات التكوين
|
||||
|
||||
<<<<<<< HEAD
|
||||
**قيمة نوع الاستجابة الجديدة:**
|
||||
=======
|
||||
**قيمة نوع الاستجابة الجديد:**
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
```
|
||||
"response-type": "jsonl"
|
||||
```
|
||||
|
||||
**تفسير المخطط:**
|
||||
|
||||
يتم استخدام المفتاح `"schema"` الموجود لكل من نوعي الاستجابة `"json"` و `"jsonl"`.
|
||||
يعتمد التفسير على نوع الاستجابة:
|
||||
|
||||
`"json"`: يصف المخطط الاستجابة بأكملها (عادةً ما يكون مصفوفة أو كائن).
|
||||
`"jsonl"`: يصف المخطط كل سطر/كائن فردي.
|
||||
|
||||
```json
|
||||
{
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity": { "type": "string" },
|
||||
"definition": { "type": "string" }
|
||||
},
|
||||
"required": ["entity", "definition"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
هذا يمنع التغييرات في أدوات تكوين المطالبات والمحررات.
|
||||
|
||||
### مواصفات تنسيق JSONL
|
||||
|
||||
#### الاستخراج البسيط
|
||||
|
||||
بالنسبة للمطالبات التي تستخرج نوعًا واحدًا من الكائنات (التعريفات، العلاقات،
|
||||
الموضوعات، الصفوف)، يكون الإخراج عبارة عن كائن JSON واحد لكل سطر بدون أي غلاف:
|
||||
|
||||
**تنسيق إخراج المطالبة:**
|
||||
```
|
||||
{"entity": "photosynthesis", "definition": "Process by which plants convert sunlight"}
|
||||
{"entity": "chlorophyll", "definition": "Green pigment in plants"}
|
||||
{"entity": "mitochondria", "definition": "Powerhouse of the cell"}
|
||||
```
|
||||
|
||||
**مقارنة مع تنسيق مصفوفة JSON السابق:**
|
||||
```json
|
||||
[
|
||||
{"entity": "photosynthesis", "definition": "Process by which plants convert sunlight"},
|
||||
{"entity": "chlorophyll", "definition": "Green pigment in plants"},
|
||||
{"entity": "mitochondria", "definition": "Powerhouse of the cell"}
|
||||
]
|
||||
```
|
||||
|
||||
إذا قام نموذج اللغة الكبير بقطع النص بعد السطر الثاني، فإن تنسيق مصفوفة JSON ينتج عنه JSON غير صالح،
|
||||
<<<<<<< HEAD
|
||||
بينما ينتج عن JSONL كائنان صالحان.
|
||||
|
||||
#### استخراج أنواع مختلطة (الاتحادات المميزة)
|
||||
|
||||
بالنسبة إلى التعليمات التي تستخرج أنواعًا متعددة من الكائنات (مثل التعريفات والأمثلة).
|
||||
العلاقات، أو الكيانات، والعلاقات، والخصائص)، استخدم `"type"`
|
||||
الحقل كعامل تمييز:
|
||||
=======
|
||||
بينما ينتج عن JSONL كائني JSON صالحين.
|
||||
|
||||
#### استخراج الأنواع المختلطة (الاتحادات المميزة)
|
||||
|
||||
بالنسبة إلى التعليمات التي تستخرج أنواعًا متعددة من الكائنات (مثل التعريفات والأمثلة).
|
||||
العلاقات، أو الكيانات، والعلاقات، والخصائص)، استخدم `"type"`
|
||||
الحقل كمعرّف:
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**تنسيق إخراج التعليمات:**
|
||||
```
|
||||
{"type": "definition", "entity": "DNA", "definition": "Molecule carrying genetic instructions"}
|
||||
{"type": "relationship", "subject": "DNA", "predicate": "located_in", "object": "cell nucleus", "object-entity": true}
|
||||
{"type": "definition", "entity": "RNA", "definition": "Molecule that carries genetic information"}
|
||||
{"type": "relationship", "subject": "RNA", "predicate": "transcribed_from", "object": "DNA", "object-entity": true}
|
||||
```
|
||||
|
||||
**مخطط للاتحادات المميّزة يستخدم `oneOf`:**
|
||||
```json
|
||||
{
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "const": "definition" },
|
||||
"entity": { "type": "string" },
|
||||
"definition": { "type": "string" }
|
||||
},
|
||||
"required": ["type", "entity", "definition"]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "const": "relationship" },
|
||||
"subject": { "type": "string" },
|
||||
"predicate": { "type": "string" },
|
||||
"object": { "type": "string" },
|
||||
"object-entity": { "type": "boolean" }
|
||||
},
|
||||
"required": ["type", "subject", "predicate", "object", "object-entity"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### استخراج علم المفاهيم
|
||||
|
||||
لاستخراج علم المفاهيم بناءً على الكيانات والعلاقات والخصائص:
|
||||
|
||||
**تنسيق إخراج التعليمات البرمجية:**
|
||||
```
|
||||
{"type": "entity", "entity": "Cornish pasty", "entity_type": "fo/Recipe"}
|
||||
{"type": "entity", "entity": "beef", "entity_type": "fo/Food"}
|
||||
{"type": "relationship", "subject": "Cornish pasty", "subject_type": "fo/Recipe", "relation": "fo/has_ingredient", "object": "beef", "object_type": "fo/Food"}
|
||||
{"type": "attribute", "entity": "Cornish pasty", "entity_type": "fo/Recipe", "attribute": "fo/serves", "value": "4 people"}
|
||||
```
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
#### فئة المطالبة (Prompt Class)
|
||||
|
||||
لا تتطلب الفئة الحالية `Prompt` أي تغييرات. يتم إعادة استخدام الحقل `schema`
|
||||
لـ JSONL، ويتم تحديد تفسيره بواسطة `response_type`:
|
||||
|
||||
```python
|
||||
class Prompt:
|
||||
def __init__(self, template, response_type="text", terms=None, schema=None):
|
||||
self.template = template
|
||||
self.response_type = response_type
|
||||
self.terms = terms
|
||||
self.schema = schema # Interpretation depends on response_type
|
||||
```
|
||||
|
||||
#### PromptManager.load_config
|
||||
|
||||
<<<<<<< HEAD
|
||||
لا توجد تغييرات مطلوبة - عملية تحميل التكوين الحالية تتعامل بالفعل مع
|
||||
=======
|
||||
لا توجد تغييرات مطلوبة - فإن عملية تحميل التكوين الحالية تتعامل بالفعل مع
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
`schema`.
|
||||
|
||||
#### تحليل JSONL
|
||||
|
||||
إضافة طريقة تحليل جديدة لنتائج JSONL:
|
||||
|
||||
```python
|
||||
def parse_jsonl(self, text):
|
||||
"""
|
||||
Parse JSONL response, returning list of valid objects.
|
||||
|
||||
Invalid lines (malformed JSON, empty lines) are skipped with warnings.
|
||||
This provides truncation resilience - partial output yields partial results.
|
||||
"""
|
||||
results = []
|
||||
|
||||
for line_num, line in enumerate(text.strip().split('\n'), 1):
|
||||
line = line.strip()
|
||||
|
||||
# Skip empty lines
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# Skip markdown code fence markers if present
|
||||
if line.startswith('```'):
|
||||
continue
|
||||
|
||||
try:
|
||||
obj = json.loads(line)
|
||||
results.append(obj)
|
||||
except json.JSONDecodeError as e:
|
||||
# Log warning but continue - this provides truncation resilience
|
||||
logger.warning(f"JSONL parse error on line {line_num}: {e}")
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
#### تغييرات في PromptManager.invoke
|
||||
|
||||
قم بتوسيع طريقة "invoke" للتعامل مع نوع الاستجابة الجديد:
|
||||
|
||||
```python
|
||||
async def invoke(self, id, input, llm):
|
||||
logger.debug("Invoking prompt template...")
|
||||
|
||||
terms = self.terms | self.prompts[id].terms | input
|
||||
resp_type = self.prompts[id].response_type
|
||||
|
||||
prompt = {
|
||||
"system": self.system_template.render(terms),
|
||||
"prompt": self.render(id, input)
|
||||
}
|
||||
|
||||
resp = await llm(**prompt)
|
||||
|
||||
if resp_type == "text":
|
||||
return resp
|
||||
|
||||
if resp_type == "json":
|
||||
try:
|
||||
obj = self.parse_json(resp)
|
||||
except:
|
||||
logger.error(f"JSON parse failed: {resp}")
|
||||
raise RuntimeError("JSON parse fail")
|
||||
|
||||
if self.prompts[id].schema:
|
||||
try:
|
||||
validate(instance=obj, schema=self.prompts[id].schema)
|
||||
logger.debug("Schema validation successful")
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Schema validation fail: {e}")
|
||||
|
||||
return obj
|
||||
|
||||
if resp_type == "jsonl":
|
||||
objects = self.parse_jsonl(resp)
|
||||
|
||||
if not objects:
|
||||
logger.warning("JSONL parse returned no valid objects")
|
||||
return []
|
||||
|
||||
# Validate each object against schema if provided
|
||||
if self.prompts[id].schema:
|
||||
validated = []
|
||||
for i, obj in enumerate(objects):
|
||||
try:
|
||||
validate(instance=obj, schema=self.prompts[id].schema)
|
||||
validated.append(obj)
|
||||
except Exception as e:
|
||||
logger.warning(f"Object {i} failed schema validation: {e}")
|
||||
return validated
|
||||
|
||||
return objects
|
||||
|
||||
raise RuntimeError(f"Response type {resp_type} not known")
|
||||
```
|
||||
|
||||
### المطالبات المتأثرة
|
||||
|
||||
يجب ترحيل المطالبات التالية إلى تنسيق JSONL:
|
||||
|
||||
| معرف المطالبة | الوصف | حقل النوع |
|
||||
|-----------|-------------|------------|
|
||||
| `extract-definitions` | استخراج الكيانات/التعريفات | لا (نوع واحد) |
|
||||
| `extract-relationships` | استخراج العلاقات | لا (نوع واحد) |
|
||||
| `extract-topics` | استخراج الموضوعات/التعريفات | لا (نوع واحد) |
|
||||
| `extract-rows` | استخراج الصفوف المنظمة | لا (نوع واحد) |
|
||||
| `agent-kg-extract` | استخراج التعريفات والعلاقات المجمعة | نعم: `"definition"`، `"relationship"` |
|
||||
| `extract-with-ontologies` / `ontology-extract` | الاستخراج القائم على علم الوجود | نعم: `"entity"`، `"relationship"`، `"attribute"` |
|
||||
|
||||
### تغييرات واجهة برمجة التطبيقات (API)
|
||||
|
||||
#### من وجهة نظر العميل
|
||||
|
||||
تحليل JSONL شفاف لمستخدمي واجهة برمجة التطبيقات (API) لخدمة المطالبات. يتم التحليل
|
||||
من جانب الخادم في خدمة المطالبات، ويتم إرجاع الاستجابة عبر الحقل القياسي
|
||||
`PromptResponse.object` كمصفوفة JSON مسلسلة.
|
||||
|
||||
<<<<<<< HEAD
|
||||
عندما يستدعي العملاء خدمة المطالبات (عبر `PromptClient.prompt()` أو ما شابه):
|
||||
=======
|
||||
عندما يستدعي العملاء خدمة المطالبات (عبر `PromptClient.prompt()` أو ما شابه ذلك):
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
**`response-type: "json"`** مع مخطط المصفوفة → يتلقى العميل كائن Python `list`
|
||||
**`response-type: "jsonl"`** → يتلقى العميل كائن Python `list`
|
||||
|
||||
من وجهة نظر العميل، فإن كلا الخيارين يُرجِعان هياكل بيانات متطابقة.
|
||||
الفرق يكمن بالكامل في كيفية تحليل مخرجات نموذج اللغة الكبير (LLM) من جهة الخادم:
|
||||
|
||||
تنسيق مصفوفة JSON: استدعاء واحد لـ `json.loads()`؛ يفشل تمامًا إذا تم اقتطاعه.
|
||||
<<<<<<< HEAD
|
||||
تنسيق JSONL: تحليل سطريًا؛ ينتج عنه نتائج جزئية إذا تم اقتطاعه.
|
||||
=======
|
||||
تنسيق JSONL: تحليل سطرًا بسطر؛ ينتج عنه نتائج جزئية إذا تم اقتطاعه.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
هذا يعني أن التعليمات البرمجية للعميل الحالية التي تتوقع قائمة من مطالبات الاستخراج
|
||||
لا تتطلب أي تغييرات عند ترحيل المطالبات من تنسيق JSON إلى تنسيق JSONL.
|
||||
|
||||
#### القيمة المُرجَعة من الخادم
|
||||
|
||||
بالنسبة لـ `response-type: "jsonl"`، تُرجع الطريقة `PromptManager.invoke()`
|
||||
`list[dict]` تحتوي على جميع الكائنات التي تم تحليلها والتحقق من صحتها بنجاح. يتم بعد ذلك تسلسل هذه
|
||||
القائمة إلى JSON لحقل `PromptResponse.object`.
|
||||
|
||||
#### معالجة الأخطاء
|
||||
|
||||
نتائج فارغة: تُرجع قائمة فارغة `[]` مع سجل تحذير.
|
||||
فشل جزئي في التحليل: تُرجع قائمة بالكائنات التي تم تحليلها بنجاح مع
|
||||
سجلات تحذير للأخطاء.
|
||||
فشل كامل في التحليل: تُرجع قائمة فارغة `[]` مع سجلات تحذير.
|
||||
|
||||
هذا يختلف عن `response-type: "json"` الذي يثير `RuntimeError` في حالة
|
||||
فشل التحليل. السلوك المتسامح لـ JSONL مقصود لتوفير مقاومة للاقتطاع.
|
||||
|
||||
|
||||
### مثال على التكوين
|
||||
|
||||
مثال كامل لتكوين المطالبة:
|
||||
|
||||
```json
|
||||
{
|
||||
"prompt": "Extract all entities and their definitions from the following text. Output one JSON object per line.\n\nText:\n{{text}}\n\nOutput format per line:\n{\"entity\": \"<name>\", \"definition\": \"<definition>\"}",
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity": {
|
||||
"type": "string",
|
||||
"description": "The entity name"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string",
|
||||
"description": "A clear definition of the entity"
|
||||
}
|
||||
},
|
||||
"required": ["entity", "definition"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
**التحقق من صحة الإدخال**: يستخدم تحليل JSON معيار `json.loads()` وهو آمن
|
||||
ضد هجمات الحقن.
|
||||
**التحقق من صحة المخطط**: يستخدم `jsonschema.validate()` لفرض المخطط.
|
||||
<<<<<<< HEAD
|
||||
**لا توجد مساحة هجومية جديدة**: تحليل JSONL أكثر أمانًا بشكل صارم من تحليل مصفوفة JSON
|
||||
=======
|
||||
**لا توجد نقاط ضعف جديدة**: تحليل JSONL أكثر أمانًا بشكل صارم من تحليل مصفوفة JSON
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
بسبب المعالجة سطرًا بسطر.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
**الذاكرة**: يستخدم التحليل سطرًا بسطر ذاكرة قصوى أقل من تحميل مصفوفات JSON كاملة.
|
||||
**زمن الوصول**: أداء التحليل مماثل لأداء تحليل مصفوفة JSON.
|
||||
**التحقق من الصحة**: يتم تشغيل التحقق من صحة المخطط لكل كائن، مما يضيف حملًا إضافيًا ولكنه
|
||||
<<<<<<< HEAD
|
||||
يمكّن النتائج الجزئية في حالة فشل التحقق من الصحة.
|
||||
=======
|
||||
يتيح الحصول على نتائج جزئية في حالة فشل التحقق من الصحة.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبارات الوحدة
|
||||
|
||||
|
||||
تحليل JSONL مع إدخال صالح.
|
||||
تحليل JSONL مع أسطر فارغة.
|
||||
تحليل JSONL مع أقسام التعليمات البرمجية بتنسيق Markdown.
|
||||
تحليل JSONL مع سطر نهائي مقطوع.
|
||||
تحليل JSONL مع أسطر JSON غير صالحة متداخلة.
|
||||
التحقق من صحة المخطط مع اتحاد `oneOf` المميّز.
|
||||
<<<<<<< HEAD
|
||||
التوافق مع الإصدارات السابقة: تظل المطالبات `"text"` و `"json"` الحالية دون تغيير.
|
||||
=======
|
||||
التوافق مع الإصدارات السابقة: تظل المطالبات الحالية `"text"` و `"json"` دون تغيير.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
### اختبارات التكامل
|
||||
|
||||
استخراج شامل مع مطالبات JSONL.
|
||||
الاستخراج مع محاكاة القطع (استجابة محدودة بشكل مصطنع).
|
||||
الاستخراج المختلط الأنواع مع مميز النوع.
|
||||
استخراج علم الوجود مع الأنواع الثلاثة.
|
||||
|
||||
<<<<<<< HEAD
|
||||
### اختبارات جودة الاستخراج.
|
||||
=======
|
||||
### اختبارات جودة الاستخراج
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
مقارنة نتائج الاستخراج: تنسيق JSONL مقابل تنسيق مصفوفة JSON.
|
||||
التحقق من قدرة تحمل التقصير: ينتج عن تنسيق JSONL نتائج جزئية في الحالات التي يفشل فيها تنسيق JSON.
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
### المرحلة الأولى: التنفيذ
|
||||
|
||||
1. تنفيذ الطريقة `parse_jsonl()` في `PromptManager`.
|
||||
<<<<<<< HEAD
|
||||
2. توسيع `invoke()` للتعامل مع `response-type: "jsonl"`.
|
||||
=======
|
||||
2. توسيع نطاق `invoke()` للتعامل مع `response-type: "jsonl"`.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
3. إضافة اختبارات الوحدة.
|
||||
|
||||
### المرحلة الثانية: ترحيل المطالبات
|
||||
|
||||
1. تحديث المطالبة `extract-definitions` والإعدادات.
|
||||
2. تحديث المطالبة `extract-relationships` والإعدادات.
|
||||
3. تحديث المطالبة `extract-topics` والإعدادات.
|
||||
4. تحديث المطالبة `extract-rows` والإعدادات.
|
||||
5. تحديث المطالبة `agent-kg-extract` والإعدادات.
|
||||
6. تحديث المطالبة `extract-with-ontologies` والإعدادات.
|
||||
|
||||
### المرحلة الثالثة: التحديثات اللاحقة
|
||||
|
||||
<<<<<<< HEAD
|
||||
1. تحديث أي كود يستهلك نتائج الاستخراج للتعامل مع نوع الإرجاع القائمة.
|
||||
2. تحديث الكود الذي يصنف الاستخراجات ذات الأنواع المختلطة باستخدام الحقل `type`.
|
||||
3. تحديث الاختبارات التي تؤكد على تنسيق إخراج الاستخراج.
|
||||
=======
|
||||
1. تحديث أي كود يستخدم نتائج الاستخراج للتعامل مع نوع الإرجاع القائمة.
|
||||
2. تحديث الكود الذي يصنف الاستخراجات ذات الأنواع المختلطة باستخدام الحقل `type`.
|
||||
3. تحديث الاختبارات التي تتحقق من تنسيق إخراج الاستخراج.
|
||||
>>>>>>> 82edf2d (New md files from RunPod)
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
لا يوجد حاليًا.
|
||||
|
||||
## المراجع
|
||||
|
||||
التنفيذ الحالي: `trustgraph-flow/trustgraph/template/prompt_manager.py`.
|
||||
مواصفات JSON Lines: https://jsonlines.org/.
|
||||
مخطط JSON `oneOf`: https://json-schema.org/understanding-json-schema/reference/combining.html#oneof.
|
||||
المواصفة ذات الصلة: Streaming LLM Responses (`docs/tech-specs/streaming-llm-responses.md`).
|
||||
992
docs/tech-specs/ar/large-document-loading.ar.md
Normal file
992
docs/tech-specs/ar/large-document-loading.ar.md
Normal file
|
|
@ -0,0 +1,992 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية لتحميل المستندات الكبيرة"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية لتحميل المستندات الكبيرة
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تتناول هذه المواصفات مشكلات قابلية التوسع وتجربة المستخدم عند تحميل
|
||||
المستندات الكبيرة في TrustGraph. تعالج البنية الحالية تحميل المستندات
|
||||
كعملية ذرية واحدة، مما يتسبب في ضغط الذاكرة في نقاط متعددة في
|
||||
المسار ولا يوفر أي ملاحظات أو خيارات استرداد للمستخدمين.
|
||||
|
||||
تستهدف هذه التنفيذ حالات الاستخدام التالية:
|
||||
|
||||
1. **معالجة ملفات PDF الكبيرة**: تحميل ومعالجة ملفات PDF متعددة الميجابايت
|
||||
دون استنفاد الذاكرة
|
||||
2. **التحميل القابل للاستئناف**: السماح للتحميلات المتقطعة بمواصلة من حيث
|
||||
توقفت بدلاً من إعادة البدء
|
||||
3. **ملاحظات التقدم**: تزويد المستخدمين برؤية في الوقت الفعلي لعملية التحميل
|
||||
والمعالجة
|
||||
4. **معالجة فعالة للذاكرة**: معالجة المستندات بطريقة متدفقة
|
||||
دون الاحتفاظ بملفات كاملة في الذاكرة
|
||||
|
||||
## الأهداف
|
||||
|
||||
**التحميل التدريجي**: دعم تحميل المستندات على شكل أجزاء عبر REST و WebSocket
|
||||
**التحويلات القابلة للاستئناف**: تمكين الاسترداد من التحميلات المتقطعة
|
||||
**رؤية التقدم**: توفير ملاحظات حول تقدم التحميل/المعالجة للعملاء
|
||||
**كفاءة الذاكرة**: القضاء على التخزين المؤقت للمستند بأكمله في جميع أنحاء المسار
|
||||
**التوافق مع الإصدارات السابقة**: تظل سير العمل الحالية للمستندات الصغيرة دون تغيير
|
||||
**المعالجة المتدفقة**: تعمل فك ترميز PDF وتقطيع النص على التدفقات
|
||||
|
||||
## الخلفية
|
||||
|
||||
### البنية الحالية
|
||||
|
||||
يمر تدفق إرسال المستندات عبر المسار التالي:
|
||||
|
||||
1. يرسل **العميل** المستند عبر REST (`POST /api/v1/librarian`) أو WebSocket
|
||||
2. يتلقى **بوابة API** الطلب الكامل مع محتوى المستند المشفر بـ base64
|
||||
3. يترجم **LibrarianRequestor** الطلب إلى رسالة Pulsar
|
||||
4. يتلقى **خدمة Librarian** الرسالة، ويفك تشفير المستند في الذاكرة
|
||||
5. يقوم **BlobStore** بتحميل المستند إلى Garage/S3
|
||||
6. تخزن **Cassandra** البيانات الوصفية مع مرجع الكائن
|
||||
7. للمعالجة: يتم استرداد المستند من S3، وفك ترميزه، وتقطيعه - كل ذلك في الذاكرة
|
||||
|
||||
الملفات الرئيسية:
|
||||
نقطة الدخول REST/WebSocket: `trustgraph-flow/trustgraph/gateway/service.py`
|
||||
النواة الأساسية لـ Librarian: `trustgraph-flow/trustgraph/librarian/librarian.py`
|
||||
تخزين الكائنات الثنائية: `trustgraph-flow/trustgraph/librarian/blob_store.py`
|
||||
جداول Cassandra: `trustgraph-flow/trustgraph/tables/library.py`
|
||||
مخطط API: `trustgraph-base/trustgraph/schema/services/library.py`
|
||||
|
||||
### القيود الحالية
|
||||
|
||||
تحتوي التصميم الحالي على عدة مشكلات مركبة في الذاكرة وتجربة المستخدم:
|
||||
|
||||
1. **عملية تحميل ذرية**: يجب إرسال المستند بأكمله في
|
||||
طلب واحد. تتطلب المستندات الكبيرة طلبات طويلة الأمد بدون
|
||||
مؤشر للتقدم ولا توجد آلية لإعادة المحاولة في حالة فشل الاتصال.
|
||||
|
||||
2. **تصميم API**: تتوقع كل من واجهات برمجة تطبيقات REST و WebSocket المستند
|
||||
بأكمله في رسالة واحدة. يحتوي المخطط (`LibrarianRequest`) على `content`
|
||||
حقل واحد يحتوي على المستند المشفر بـ base64 بأكمله.
|
||||
|
||||
3. **ذاكرة Librarian**: تقوم خدمة Librarian بفك تشفير المستند بأكمله
|
||||
في الذاكرة قبل تحميله إلى S3. بالنسبة لملف PDF بحجم 500 ميجابايت، هذا يعني
|
||||
الاحتفاظ بـ 500 ميجابايت + في ذاكرة العملية.
|
||||
|
||||
4. **ذاكرة فك ترميز PDF**: عند بدء المعالجة، يقوم فك ترميز PDF بتحميل
|
||||
ملف PDF بأكمله في الذاكرة لاستخراج النص. تتطلب مكتبات PyPDF وما شابه ذلك
|
||||
عادةً الوصول إلى المستند بأكمله.
|
||||
|
||||
5. **ذاكرة القطع**: يتلقى برنامج القطع النص المستخرج بالكامل
|
||||
ويحتفظ به في الذاكرة أثناء إنتاج الأجزاء.
|
||||
|
||||
**مثال على تأثير الذاكرة** (ملف PDF بحجم 500 ميجابايت):
|
||||
البوابة: ~700 ميجابايت (نفقات ترميز base64)
|
||||
Librarian: ~500 ميجابايت (بايت مُفككة)
|
||||
فك ترميز PDF: ~500 ميجابايت + مخازن مؤقتة للاستخراج
|
||||
القطع: نص مستخرج (متغير، قد يصل إلى 100 ميجابايت +)
|
||||
|
||||
يمكن أن تتجاوز الذاكرة القصوى لملف مستند كبير واحد 2 جيجابايت.
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### مبادئ التصميم
|
||||
|
||||
1. **واجهة API**: يمر كل تفاعل عميل من خلال واجهة برمجة تطبيقات Librarian. العملاء
|
||||
ليس لديهم وصول مباشر أو معرفة بالتخزين الأساسي S3/Garage.
|
||||
|
||||
2. **تحميل متعدد الأجزاء لـ S3**: استخدم تحميل متعدد الأجزاء قياسي لـ S3.
|
||||
هذا مدعوم على نطاق واسع في الأنظمة المتوافقة مع S3 (AWS S3، MinIO، Garage،
|
||||
Ceph، DigitalOcean Spaces، Backblaze B2، إلخ) مما يضمن إمكانية النقل.
|
||||
|
||||
3. **الإكمال الذري**: عمليات تحميل متعددة الأجزاء لـ S3 ذرية بطبيعتها - يتم تحميل
|
||||
الأجزاء التي تم تحميلها والتي لا تظهر حتى يتم استدعاء `CompleteMultipartUpload`. لا توجد
|
||||
ملفات مؤقتة أو عمليات إعادة تسمية مطلوبة.
|
||||
|
||||
4. **حالة قابلة للتتبع**: يتم تتبع جلسات التحميل في Cassandra، مما يوفر
|
||||
رؤية للتحميلات غير المكتملة ويمكنه تمكين إمكانية الاستئناف.
|
||||
|
||||
### تدفق التحميل المقسم
|
||||
|
||||
```
|
||||
Client Librarian API S3/Garage
|
||||
│ │ │
|
||||
│── begin-upload ───────────►│ │
|
||||
│ (metadata, size) │── CreateMultipartUpload ────►│
|
||||
│ │◄── s3_upload_id ─────────────│
|
||||
│◄── upload_id ──────────────│ (store session in │
|
||||
│ │ Cassandra) │
|
||||
│ │ │
|
||||
│── upload-chunk ───────────►│ │
|
||||
│ (upload_id, index, data) │── UploadPart ───────────────►│
|
||||
│ │◄── etag ─────────────────────│
|
||||
│◄── ack + progress ─────────│ (store etag in session) │
|
||||
│ ⋮ │ ⋮ │
|
||||
│ (repeat for all chunks) │ │
|
||||
│ │ │
|
||||
│── complete-upload ────────►│ │
|
||||
│ (upload_id) │── CompleteMultipartUpload ──►│
|
||||
│ │ (parts coalesced by S3) │
|
||||
│ │── store doc metadata ───────►│ Cassandra
|
||||
│◄── document_id ────────────│ (delete session) │
|
||||
```
|
||||
|
||||
العميل لا يتفاعل أبدًا مع S3 مباشرةً. يقوم المكتبار بترجمة البيانات بين
|
||||
واجهة برمجة التطبيقات الخاصة بنا لتحميل البيانات على أجزاء و عمليات S3 متعددة الأجزاء داخليًا.
|
||||
|
||||
### عمليات واجهة برمجة التطبيقات الخاصة بالمكتبار
|
||||
|
||||
#### `begin-upload`
|
||||
|
||||
تهيئة جلسة تحميل بيانات على أجزاء.
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "begin-upload",
|
||||
"document-metadata": {
|
||||
"id": "doc-123",
|
||||
"kind": "application/pdf",
|
||||
"title": "Large Document",
|
||||
"user": "user-id",
|
||||
"tags": ["tag1", "tag2"]
|
||||
},
|
||||
"total-size": 524288000,
|
||||
"chunk-size": 5242880
|
||||
}
|
||||
```
|
||||
|
||||
الرد:
|
||||
```json
|
||||
{
|
||||
"upload-id": "upload-abc-123",
|
||||
"chunk-size": 5242880,
|
||||
"total-chunks": 100
|
||||
}
|
||||
```
|
||||
|
||||
أمين المكتبة:
|
||||
1. يقوم بإنشاء رمز فريد `upload_id` و `object_id` (معرف فريد لتخزين الكائنات)
|
||||
2. يستدعي S3 `CreateMultipartUpload`، ويتلقى `s3_upload_id`
|
||||
3. يقوم بإنشاء سجل جلسة في Cassandra
|
||||
4. يعيد `upload_id` إلى العميل
|
||||
|
||||
#### `upload-chunk`
|
||||
|
||||
تحميل جزء واحد.
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "upload-chunk",
|
||||
"upload-id": "upload-abc-123",
|
||||
"chunk-index": 0,
|
||||
"content": "<base64-encoded-chunk>"
|
||||
}
|
||||
```
|
||||
|
||||
الرد:
|
||||
```json
|
||||
{
|
||||
"upload-id": "upload-abc-123",
|
||||
"chunk-index": 0,
|
||||
"chunks-received": 1,
|
||||
"total-chunks": 100,
|
||||
"bytes-received": 5242880,
|
||||
"total-bytes": 524288000
|
||||
}
|
||||
```
|
||||
|
||||
أمين المكتبة:
|
||||
1. البحث عن الجلسة باستخدام `upload_id`
|
||||
2. التحقق من الملكية (يجب أن يتطابق المستخدم مع منشئ الجلسة)
|
||||
3. استدعاء S3 `UploadPart` مع بيانات الجزء، وتلقي `etag`
|
||||
4. تحديث سجل الجلسة بفهرس الجزء وعلامة etag
|
||||
5. إرجاع التقدم إلى العميل
|
||||
|
||||
يمكن إعادة محاولة الأجزاء الفاشلة - فقط أرسل `chunk-index` مرة أخرى.
|
||||
|
||||
#### `complete-upload`
|
||||
|
||||
إنهاء التحميل وإنشاء المستند.
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "complete-upload",
|
||||
"upload-id": "upload-abc-123"
|
||||
}
|
||||
```
|
||||
|
||||
الرد:
|
||||
```json
|
||||
{
|
||||
"document-id": "doc-123",
|
||||
"object-id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
أمين المكتبة:
|
||||
1. يبحث عن الجلسة، ويتحقق من استلام جميع الأجزاء.
|
||||
2. يستدعي S3 `CompleteMultipartUpload` مع علامات الجزء (S3 تدمج الأجزاء داخليًا - لا توجد تكلفة ذاكرة لأمين المكتبة).
|
||||
3. ينشئ سجل مستند في Cassandra مع البيانات الوصفية وإشارة الكائن.
|
||||
4. يحذف سجل جلسة التحميل.
|
||||
5. يعيد معرف المستند إلى العميل.
|
||||
6.
|
||||
|
||||
#### `abort-upload`
|
||||
|
||||
إلغاء عملية تحميل قيد التقدم.
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "abort-upload",
|
||||
"upload-id": "upload-abc-123"
|
||||
}
|
||||
```
|
||||
|
||||
أمين المكتبة:
|
||||
1. يستدعي `AbortMultipartUpload` لتنظيف الأجزاء.
|
||||
2. يحذف سجل الجلسة من Cassandra.
|
||||
|
||||
#### `get-upload-status`
|
||||
|
||||
حالة استعلام عن عملية تحميل (لإمكانية الاستئناف).
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "get-upload-status",
|
||||
"upload-id": "upload-abc-123"
|
||||
}
|
||||
```
|
||||
|
||||
الرد:
|
||||
```json
|
||||
{
|
||||
"upload-id": "upload-abc-123",
|
||||
"state": "in-progress",
|
||||
"chunks-received": [0, 1, 2, 5, 6],
|
||||
"missing-chunks": [3, 4, 7, 8],
|
||||
"total-chunks": 100,
|
||||
"bytes-received": 36700160,
|
||||
"total-bytes": 524288000
|
||||
}
|
||||
```
|
||||
|
||||
#### `list-uploads`
|
||||
|
||||
عرض قائمة التحميلات غير المكتملة لمستخدم.
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "list-uploads"
|
||||
}
|
||||
```
|
||||
|
||||
الرد:
|
||||
```json
|
||||
{
|
||||
"uploads": [
|
||||
{
|
||||
"upload-id": "upload-abc-123",
|
||||
"document-metadata": { "title": "Large Document", ... },
|
||||
"progress": { "chunks-received": 43, "total-chunks": 100 },
|
||||
"created-at": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### تخزين جلسات التحميل
|
||||
|
||||
تتبع عمليات التحميل الجارية في Cassandra:
|
||||
|
||||
```sql
|
||||
CREATE TABLE upload_session (
|
||||
upload_id text PRIMARY KEY,
|
||||
user text,
|
||||
document_id text,
|
||||
document_metadata text, -- JSON: title, kind, tags, comments, etc.
|
||||
s3_upload_id text, -- internal, for S3 operations
|
||||
object_id uuid, -- target blob ID
|
||||
total_size bigint,
|
||||
chunk_size int,
|
||||
total_chunks int,
|
||||
chunks_received map<int, text>, -- chunk_index → etag
|
||||
created_at timestamp,
|
||||
updated_at timestamp
|
||||
) WITH default_time_to_live = 86400; -- 24 hour TTL
|
||||
|
||||
CREATE INDEX upload_session_user ON upload_session (user);
|
||||
```
|
||||
|
||||
**سلوك TTL:**
|
||||
تنتهي الجلسات بعد 24 ساعة إذا لم تكتمل.
|
||||
عندما تنتهي صلاحية TTL في Cassandra، يتم حذف سجل الجلسة.
|
||||
يتم تنظيف أجزاء S3 المهجورة بواسطة سياسة دورة حياة S3 (يتم التكوين على الحاوية).
|
||||
|
||||
### معالجة الأخطاء والتماسك
|
||||
|
||||
**فشل تحميل الأجزاء:**
|
||||
يحاول العميل إعادة تحميل الجزء الذي فشل (بنفس `upload_id` و `chunk-index`).
|
||||
عملية S3 `UploadPart` متسقة لنفس رقم الجزء.
|
||||
تتتبع الجلسة الأجزاء التي نجحت.
|
||||
|
||||
**انقطاع اتصال العميل أثناء التحميل:**
|
||||
تظل الجلسة موجودة في Cassandra مع تسجيل الأجزاء المستلمة.
|
||||
يمكن للعميل استدعاء `get-upload-status` لمعرفة ما هو مفقود.
|
||||
يمكن استئناف التحميل عن طريق تحميل الأجزاء المفقودة فقط، ثم `complete-upload`.
|
||||
|
||||
**فشل التحميل الكامل:**
|
||||
عملية S3 `CompleteMultipartUpload` ذرية - إما أنها تنجح بالكامل أو تفشل.
|
||||
في حالة الفشل، تظل الأجزاء موجودة ويمكن للعميل إعادة محاولة `complete-upload`.
|
||||
لا يمكن رؤية أي مستند جزئي على الإطلاق.
|
||||
|
||||
**انتهاء صلاحية الجلسة:**
|
||||
تحذف Cassandra سجل الجلسة بعد 24 ساعة.
|
||||
تقوم سياسة دورة حياة حاوية S3 بتنظيف عمليات التحميل متعددة الأجزاء غير المكتملة.
|
||||
لا يلزم أي تنظيف يدوي.
|
||||
|
||||
### تماسك S3 متعدد الأجزاء
|
||||
|
||||
توفر عمليات تحميل S3 متعددة الأجزاء تماسكًا مدمجًا:
|
||||
|
||||
1. **الأجزاء غير مرئية**: لا يمكن الوصول إلى الأجزاء التي تم تحميلها ككائنات.
|
||||
إنها موجودة فقط كأجزاء من عملية تحميل متعددة الأجزاء غير مكتملة.
|
||||
|
||||
2. **الإكمال الذري**: `CompleteMultipartUpload` إما أنها تنجح (يظهر الكائن بشكل ذري) أو تفشل (لا يتم إنشاء كائن). لا توجد حالة جزئية.
|
||||
|
||||
|
||||
3. **لا حاجة لإعادة التسمية**: يتم تحديد مفتاح الكائن النهائي في وقت
|
||||
`CreateMultipartUpload`. يتم دمج الأجزاء مباشرة في هذا المفتاح.
|
||||
|
||||
4. **الدمج من جانب الخادم**: تقوم S3 بدمج الأجزاء داخليًا. لا يقرأ أمين المكتبة
|
||||
الأجزاء مرة أخرى - لا توجد تكلفة إضافية للذاكرة بغض النظر عن حجم المستند.
|
||||
|
||||
### امتدادات BlobStore
|
||||
|
||||
**الملف:** `trustgraph-flow/trustgraph/librarian/blob_store.py`
|
||||
|
||||
أضف طرق التحميل متعددة الأجزاء:
|
||||
|
||||
```python
|
||||
class BlobStore:
|
||||
# Existing methods...
|
||||
|
||||
def create_multipart_upload(self, object_id: UUID, kind: str) -> str:
|
||||
"""Initialize multipart upload, return s3_upload_id."""
|
||||
# minio client: create_multipart_upload()
|
||||
|
||||
def upload_part(
|
||||
self, object_id: UUID, s3_upload_id: str,
|
||||
part_number: int, data: bytes
|
||||
) -> str:
|
||||
"""Upload a single part, return etag."""
|
||||
# minio client: upload_part()
|
||||
# Note: S3 part numbers are 1-indexed
|
||||
|
||||
def complete_multipart_upload(
|
||||
self, object_id: UUID, s3_upload_id: str,
|
||||
parts: List[Tuple[int, str]] # [(part_number, etag), ...]
|
||||
) -> None:
|
||||
"""Finalize multipart upload."""
|
||||
# minio client: complete_multipart_upload()
|
||||
|
||||
def abort_multipart_upload(
|
||||
self, object_id: UUID, s3_upload_id: str
|
||||
) -> None:
|
||||
"""Cancel multipart upload, clean up parts."""
|
||||
# minio client: abort_multipart_upload()
|
||||
```
|
||||
|
||||
### اعتبارات حجم الجزء
|
||||
|
||||
**الحد الأدنى لـ S3**: 5 ميجابايت لكل جزء (باستثناء الجزء الأخير)
|
||||
**الحد الأقصى لـ S3**: 10,000 جزء لكل عملية تحميل
|
||||
**الإعداد الافتراضي العملي**: أجزاء بحجم 5 ميجابايت
|
||||
مستند بحجم 500 ميجابايت = 100 جزء
|
||||
مستند بحجم 5 جيجابايت = 1,000 جزء
|
||||
**دقة التقدم**: أجزاء أصغر = تحديثات تقدم أكثر دقة
|
||||
**كفاءة الشبكة**: أجزاء أكبر = عدد أقل من عمليات الإرسال
|
||||
|
||||
يمكن تكوين حجم الجزء من قبل العميل ضمن الحدود (5 ميجابايت - 100 ميجابايت).
|
||||
|
||||
### معالجة المستندات: الاسترجاع المتدفق
|
||||
|
||||
يهدف سير عمل التحميل إلى إدخال المستندات إلى التخزين بكفاءة. يهدف سير عمل المعالجة إلى استخراج وتقسيم المستندات دون تحميلها بالكامل في الذاكرة.
|
||||
|
||||
|
||||
#### مبدأ التصميم: المعرف، وليس المحتوى
|
||||
|
||||
|
||||
حاليًا، عند بدء المعالجة، يتدفق محتوى المستند عبر رسائل Pulsar. يؤدي هذا إلى تحميل المستندات بأكملها في الذاكرة. بدلاً من ذلك:
|
||||
|
||||
|
||||
تحمل رسائل Pulsar فقط **معرف المستند**
|
||||
تقوم المعالجات باسترداد محتوى المستند مباشرة من المكتبة
|
||||
يتم الاسترداد كـ **تدفق إلى ملف مؤقت**
|
||||
يعمل التحليل الخاص بالمستند (PDF، نص، إلخ) مع الملفات، وليس مخازن الذاكرة
|
||||
|
||||
هذا يجعل المكتبة غير معتمدة على هيكل المستند. يظل تحليل PDF واستخراج النص ومنطق محدد التنسيق الأخرى في فك التشفير الخاص بها.
|
||||
|
||||
|
||||
#### سير المعالجة
|
||||
|
||||
```
|
||||
Pulsar PDF Decoder Librarian S3
|
||||
│ │ │ │
|
||||
│── doc-id ───────────►│ │ │
|
||||
│ (processing msg) │ │ │
|
||||
│ │ │ │
|
||||
│ │── stream-document ──────►│ │
|
||||
│ │ (doc-id) │── GetObject ────►│
|
||||
│ │ │ │
|
||||
│ │◄── chunk ────────────────│◄── stream ───────│
|
||||
│ │ (write to temp file) │ │
|
||||
│ │◄── chunk ────────────────│◄── stream ───────│
|
||||
│ │ (append to temp file) │ │
|
||||
│ │ ⋮ │ ⋮ │
|
||||
│ │◄── EOF ──────────────────│ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────────────────┐ │
|
||||
│ │ │ temp file on disk │ │
|
||||
│ │ │ (memory stays bounded) │ │
|
||||
│ │ └────────────┬─────────────┘ │
|
||||
│ │ │ │
|
||||
│ │ PDF library opens file │
|
||||
│ │ extract page 1 text ──► chunker │
|
||||
│ │ extract page 2 text ──► chunker │
|
||||
│ │ ⋮ │
|
||||
│ │ close file │
|
||||
│ │ delete temp file │
|
||||
```
|
||||
|
||||
#### واجهة برمجة تطبيقات (API) لخدمة أمين المكتبة.
|
||||
|
||||
إضافة عملية استرجاع مستندات متدفقة:
|
||||
|
||||
**`stream-document`**
|
||||
|
||||
الطلب:
|
||||
```json
|
||||
{
|
||||
"operation": "stream-document",
|
||||
"document-id": "doc-123"
|
||||
}
|
||||
```
|
||||
|
||||
الاستجابة: أجزاء ثنائية متدفقة (وليست استجابة واحدة).
|
||||
|
||||
بالنسبة لواجهة برمجة التطبيقات REST، فإن هذا يُرجع استجابة متدفقة مع `Transfer-Encoding: chunked`.
|
||||
|
||||
بالنسبة للمكالمات الداخلية بين الخدمات (من المعالج إلى أمين المكتبة)، يمكن أن يكون ذلك:
|
||||
بث مباشر من S3 عبر عنوان URL مسبق التوقيع (إذا سمحت الشبكة الداخلية بذلك).
|
||||
استجابات مقسمة عبر بروتوكول الخدمة.
|
||||
نقطة نهاية مخصصة للبث.
|
||||
|
||||
المتطلب الأساسي: تتدفق البيانات في أجزاء، ولا يتم تخزينها بالكامل مؤقتًا في أمين المكتبة.
|
||||
|
||||
#### تغييرات في فك ترميز PDF.
|
||||
|
||||
**التنفيذ الحالي** (يستهلك الكثير من الذاكرة):
|
||||
|
||||
```python
|
||||
def decode_pdf(document_content: bytes) -> str:
|
||||
reader = PdfReader(BytesIO(document_content)) # full doc in memory
|
||||
text = ""
|
||||
for page in reader.pages:
|
||||
text += page.extract_text() # accumulating
|
||||
return text # full text in memory
|
||||
```
|
||||
|
||||
**تنفيذ جديد** (ملف مؤقت، تدريجي):
|
||||
|
||||
```python
|
||||
def decode_pdf_streaming(doc_id: str, librarian_client) -> Iterator[str]:
|
||||
"""Yield extracted text page by page."""
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=True, suffix='.pdf') as tmp:
|
||||
# Stream document to temp file
|
||||
for chunk in librarian_client.stream_document(doc_id):
|
||||
tmp.write(chunk)
|
||||
tmp.flush()
|
||||
|
||||
# Open PDF from file (not memory)
|
||||
reader = PdfReader(tmp.name)
|
||||
|
||||
# Yield pages incrementally
|
||||
for page in reader.pages:
|
||||
yield page.extract_text()
|
||||
|
||||
# tmp file auto-deleted on context exit
|
||||
```
|
||||
|
||||
ملف تعريف الذاكرة:
|
||||
ملف مؤقت على القرص: حجم ملف PDF (القرص رخيص).
|
||||
في الذاكرة: صفحة واحدة من النص في كل مرة.
|
||||
أقصى استخدام للذاكرة: محدود، ولا يعتمد على حجم المستند.
|
||||
|
||||
#### تغييرات في وحدة فك ترميز المستندات النصية.
|
||||
|
||||
بالنسبة للمستندات النصية العادية، الأمر أبسط حتى - لا حاجة لملف مؤقت:
|
||||
|
||||
```python
|
||||
def decode_text_streaming(doc_id: str, librarian_client) -> Iterator[str]:
|
||||
"""Yield text in chunks as it streams from storage."""
|
||||
|
||||
buffer = ""
|
||||
for chunk in librarian_client.stream_document(doc_id):
|
||||
buffer += chunk.decode('utf-8')
|
||||
|
||||
# Yield complete lines/paragraphs as they arrive
|
||||
while '\n\n' in buffer:
|
||||
paragraph, buffer = buffer.split('\n\n', 1)
|
||||
yield paragraph + '\n\n'
|
||||
|
||||
# Yield remaining buffer
|
||||
if buffer:
|
||||
yield buffer
|
||||
```
|
||||
|
||||
يمكن لملفات النصوص أن تُرسل مباشرةً دون الحاجة إلى ملف مؤقت نظرًا لأنها
|
||||
مُنظمة بشكل خطي.
|
||||
|
||||
#### تكامل وحدة تقسيم البيانات (Chunker).
|
||||
|
||||
تتلقى وحدة تقسيم البيانات مُكررًا للنصوص (صفحات أو فقرات) وتُنتج
|
||||
أجزاء بشكل تدريجي:
|
||||
|
||||
```python
|
||||
class StreamingChunker:
|
||||
def __init__(self, chunk_size: int, overlap: int):
|
||||
self.chunk_size = chunk_size
|
||||
self.overlap = overlap
|
||||
|
||||
def process(self, text_stream: Iterator[str]) -> Iterator[str]:
|
||||
"""Yield chunks as text arrives."""
|
||||
buffer = ""
|
||||
|
||||
for text_segment in text_stream:
|
||||
buffer += text_segment
|
||||
|
||||
while len(buffer) >= self.chunk_size:
|
||||
chunk = buffer[:self.chunk_size]
|
||||
yield chunk
|
||||
# Keep overlap for context continuity
|
||||
buffer = buffer[self.chunk_size - self.overlap:]
|
||||
|
||||
# Yield remaining buffer as final chunk
|
||||
if buffer.strip():
|
||||
yield buffer
|
||||
```
|
||||
|
||||
#### خط أنابيب المعالجة الشاملة
|
||||
|
||||
```python
|
||||
async def process_document(doc_id: str, librarian_client, embedder):
|
||||
"""Process document with bounded memory."""
|
||||
|
||||
# Get document metadata to determine type
|
||||
metadata = await librarian_client.get_document_metadata(doc_id)
|
||||
|
||||
# Select decoder based on document type
|
||||
if metadata.kind == 'application/pdf':
|
||||
text_stream = decode_pdf_streaming(doc_id, librarian_client)
|
||||
elif metadata.kind == 'text/plain':
|
||||
text_stream = decode_text_streaming(doc_id, librarian_client)
|
||||
else:
|
||||
raise UnsupportedDocumentType(metadata.kind)
|
||||
|
||||
# Chunk incrementally
|
||||
chunker = StreamingChunker(chunk_size=1000, overlap=100)
|
||||
|
||||
# Process each chunk as it's produced
|
||||
for chunk in chunker.process(text_stream):
|
||||
# Generate embeddings, store in vector DB, etc.
|
||||
embedding = await embedder.embed(chunk)
|
||||
await store_chunk(doc_id, chunk, embedding)
|
||||
```
|
||||
|
||||
في أي نقطة، لا يتم الاحتفاظ بالمستند الكامل أو النص المستخرج بالكامل في الذاكرة.
|
||||
|
||||
#### اعتبارات ملفات مؤقتة
|
||||
|
||||
**الموقع**: استخدم دليل النظام المؤقت (`/tmp` أو ما يعادله). بالنسبة إلى
|
||||
عمليات النشر في حاويات، تأكد من أن الدليل المؤقت لديه مساحة كافية
|
||||
وأنه موجود على مساحة تخزين سريعة (وليس مثبتًا على الشبكة إن أمكن).
|
||||
|
||||
**التنظيف**: استخدم مديري السياق (`with tempfile...`) لضمان التنظيف
|
||||
حتى في حالة حدوث استثناءات.
|
||||
|
||||
**المعالجة المتزامنة**: تحصل كل مهمة معالجة على ملف مؤقت خاص بها.
|
||||
لا توجد تعارضات بين معالجة المستندات المتوازية.
|
||||
|
||||
**مساحة القرص**: الملفات المؤقتة قصيرة الأجل (مدة المعالجة). بالنسبة إلى
|
||||
ملف PDF بحجم 500 ميجابايت، يلزم وجود مساحة مؤقتة تبلغ 500 ميجابايت أثناء المعالجة. يمكن
|
||||
تطبيق حد الحجم في وقت التحميل إذا كانت مساحة القرص محدودة.
|
||||
|
||||
### واجهة المعالجة الموحدة: المستندات الفرعية
|
||||
|
||||
يجب أن تساهم عملية استخراج PDF ومعالجة المستندات النصية في نفس
|
||||
خط المعالجة اللاحق (تقسيم إلى أجزاء → تضمينات → تخزين). لتحقيق ذلك باستخدام
|
||||
واجهة "جلب حسب المعرف" متسقة، يتم تخزين كتل النص المستخرجة مرة أخرى
|
||||
في المكتبة كمستندات فرعية.
|
||||
|
||||
#### سير العمل مع المستندات الفرعية
|
||||
|
||||
```
|
||||
PDF Document Text Document
|
||||
│ │
|
||||
▼ │
|
||||
pdf-extractor │
|
||||
│ │
|
||||
│ (stream PDF from librarian) │
|
||||
│ (extract page 1 text) │
|
||||
│ (store as child doc → librarian) │
|
||||
│ (extract page 2 text) │
|
||||
│ (store as child doc → librarian) │
|
||||
│ ⋮ │
|
||||
▼ ▼
|
||||
[child-doc-id, child-doc-id, ...] [doc-id]
|
||||
│ │
|
||||
└─────────────────────┬───────────────────────────────┘
|
||||
▼
|
||||
chunker
|
||||
│
|
||||
│ (receives document ID)
|
||||
│ (streams content from librarian)
|
||||
│ (chunks incrementally)
|
||||
▼
|
||||
[chunks → embedding → storage]
|
||||
```
|
||||
|
||||
تمتلك وحدة التقسيم واجهة موحدة واحدة:
|
||||
استقبال معرف المستند (عبر Pulsar)
|
||||
تدفق المحتوى من أمين المكتبة
|
||||
تقسيم المحتوى
|
||||
|
||||
لا تعرف أو تهتم ما إذا كان المعرف يشير إلى:
|
||||
مستند نصي تم تحميله بواسطة المستخدم
|
||||
جزء نصي مستخرج من صفحة PDF
|
||||
أي نوع مستند مستقبلي
|
||||
|
||||
#### بيانات وصفية للمستندات الفرعية
|
||||
|
||||
قم بتوسيع مخطط المستند لتتبع العلاقات بين المستندات الرئيسية والفرعية:
|
||||
|
||||
```sql
|
||||
-- Add columns to document table
|
||||
ALTER TABLE document ADD parent_id text;
|
||||
ALTER TABLE document ADD document_type text;
|
||||
|
||||
-- Index for finding children of a parent
|
||||
CREATE INDEX document_parent ON document (parent_id);
|
||||
```
|
||||
|
||||
**أنواع المستندات:**
|
||||
|
||||
| `document_type` | الوصف |
|
||||
|-----------------|-------------|
|
||||
| `source` | مستند تم تحميله بواسطة المستخدم (PDF، نص، إلخ) |
|
||||
| `extracted` | مشتق من مستند مصدر (مثل نص صفحة PDF) |
|
||||
|
||||
**حقول البيانات الوصفية:**
|
||||
|
||||
| الحقل | المستند المصدر | المستند الفرعي المستخرج |
|
||||
|-------|-----------------|-----------------|
|
||||
| `id` | مقدم من المستخدم أو تم إنشاؤه | تم إنشاؤه (مثل `{parent-id}-page-{n}`) |
|
||||
| `parent_id` | `NULL` | معرف المستند الأصل |
|
||||
| `document_type` | `source` | `extracted` |
|
||||
| `kind` | `application/pdf`، إلخ. | `text/plain` |
|
||||
| `title` | مقدم من المستخدم | تم إنشاؤه (مثل "الصفحة 3 من Report.pdf") |
|
||||
| `user` | مستخدم مصرح له | نفس المستند الأصل |
|
||||
|
||||
#### واجهة برمجة تطبيقات أمين المكتبة للمستندات الفرعية
|
||||
|
||||
**إنشاء المستندات الفرعية** (داخلي، يستخدم بواسطة pdf-extractor):
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "add-child-document",
|
||||
"parent-id": "doc-123",
|
||||
"document-metadata": {
|
||||
"id": "doc-123-page-1",
|
||||
"kind": "text/plain",
|
||||
"title": "Page 1"
|
||||
},
|
||||
"content": "<base64-encoded-text>"
|
||||
}
|
||||
```
|
||||
|
||||
بالنسبة للنصوص الصغيرة المستخرجة (عادةً ما يكون نص الصفحة أقل من 100 كيلوبايت)، فإن التحميل في عملية واحدة مقبول. بالنسبة لاستخراج النصوص الكبيرة جدًا، يمكن استخدام التحميل المقسم.
|
||||
|
||||
**عرض المستندات الفرعية** (لأغراض التصحيح/الإدارة):
|
||||
|
||||
**عرض المستندات الفرعية** (لأغراض التصحيح/الإدارة):
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "list-children",
|
||||
"parent-id": "doc-123"
|
||||
}
|
||||
```
|
||||
|
||||
الرد:
|
||||
```json
|
||||
{
|
||||
"children": [
|
||||
{ "id": "doc-123-page-1", "title": "Page 1", "kind": "text/plain" },
|
||||
{ "id": "doc-123-page-2", "title": "Page 2", "kind": "text/plain" },
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### السلوك الظاهر للمستخدم
|
||||
|
||||
**السلوك الافتراضي `list-documents`:**
|
||||
|
||||
```sql
|
||||
SELECT * FROM document WHERE user = ? AND parent_id IS NULL;
|
||||
```
|
||||
|
||||
تظهر فقط المستندات الرئيسية (المصدر) في قائمة المستندات الخاصة بالمستخدم.
|
||||
يتم استبعاد المستندات الفرعية افتراضيًا.
|
||||
|
||||
**علامة "include-children" اختيارية** (للمسؤولين/تصحيح الأخطاء):
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "list-documents",
|
||||
"include-children": true
|
||||
}
|
||||
```
|
||||
|
||||
#### حذف متسلسل
|
||||
|
||||
عندما يتم حذف مستند رئيسي، يجب حذف جميع العناصر التابعة له:
|
||||
|
||||
```python
|
||||
def delete_document(doc_id: str):
|
||||
# Find all children
|
||||
children = query("SELECT id, object_id FROM document WHERE parent_id = ?", doc_id)
|
||||
|
||||
# Delete child blobs from S3
|
||||
for child in children:
|
||||
blob_store.delete(child.object_id)
|
||||
|
||||
# Delete child metadata from Cassandra
|
||||
execute("DELETE FROM document WHERE parent_id = ?", doc_id)
|
||||
|
||||
# Delete parent blob and metadata
|
||||
parent = get_document(doc_id)
|
||||
blob_store.delete(parent.object_id)
|
||||
execute("DELETE FROM document WHERE id = ? AND user = ?", doc_id, user)
|
||||
```
|
||||
|
||||
#### اعتبارات التخزين
|
||||
|
||||
النصوص المستخرجة قد تتضمن تكرارًا للمحتوى:
|
||||
ملف PDF الأصلي مُخزن في "Garage".
|
||||
النص المستخرج لكل صفحة مُخزن أيضًا في "Garage".
|
||||
|
||||
هذا الحل يتيح:
|
||||
**واجهة موحدة للتقطيع**: يقوم "Chunker" دائمًا باسترداد البيانات بمعرف (ID).
|
||||
**الاستئناف/إعادة المحاولة**: يمكن إعادة تشغيل العملية في مرحلة "Chunker" دون إعادة استخراج ملف PDF.
|
||||
**تصحيح الأخطاء**: يمكن فحص النص المستخرج.
|
||||
**فصل المهام**: خدمة استخراج ملف PDF وخدمة "Chunker" هما خدمتان مستقلتان.
|
||||
|
||||
بالنسبة لملف PDF بحجم 500 ميجابايت و200 صفحة بمتوسط 5 كيلوبايت من النص لكل صفحة:
|
||||
تخزين ملف PDF: 500 ميجابايت.
|
||||
تخزين النص المستخرج: حوالي 1 ميجابايت إجمالاً.
|
||||
التكلفة الإضافية: ضئيلة.
|
||||
|
||||
#### مخرجات مُستخرج ملف PDF
|
||||
|
||||
يقوم مُستخرج ملف PDF (pdf-extractor)، بعد معالجة المستند:
|
||||
|
||||
1. يقوم بتحميل ملف PDF من "librarian" إلى ملف مؤقت.
|
||||
2. يستخرج النص صفحةً تلو الأخرى.
|
||||
3. لكل صفحة، يقوم بتخزين النص المستخرج كمستند فرعي عبر "librarian".
|
||||
4. يرسل معرفات المستندات الفرعية إلى قائمة انتظار "Chunker".
|
||||
|
||||
```python
|
||||
async def extract_pdf(doc_id: str, librarian_client, output_queue):
|
||||
"""Extract PDF pages and store as child documents."""
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=True, suffix='.pdf') as tmp:
|
||||
# Stream PDF to temp file
|
||||
for chunk in librarian_client.stream_document(doc_id):
|
||||
tmp.write(chunk)
|
||||
tmp.flush()
|
||||
|
||||
# Extract pages
|
||||
reader = PdfReader(tmp.name)
|
||||
for page_num, page in enumerate(reader.pages, start=1):
|
||||
text = page.extract_text()
|
||||
|
||||
# Store as child document
|
||||
child_id = f"{doc_id}-page-{page_num}"
|
||||
await librarian_client.add_child_document(
|
||||
parent_id=doc_id,
|
||||
document_id=child_id,
|
||||
kind="text/plain",
|
||||
title=f"Page {page_num}",
|
||||
content=text.encode('utf-8')
|
||||
)
|
||||
|
||||
# Send to chunker queue
|
||||
await output_queue.send(child_id)
|
||||
```
|
||||
|
||||
يتلقى المعالج هذه المعرفات الفرعية ويقوم بمعالجتها بنفس الطريقة التي يعالج بها مستند نصي تم تحميله بواسطة المستخدم.
|
||||
كيف كان سيعالجها.
|
||||
|
||||
### تحديثات العميل
|
||||
|
||||
#### حزمة تطوير البرمجيات (SDK) بلغة بايثون
|
||||
|
||||
يجب أن تتعامل حزمة تطوير البرمجيات (SDK) بلغة بايثون (`trustgraph-base/trustgraph/api/library.py`) مع عمليات التحميل المقسمة بشفافية. يظل الواجهة العامة دون تغيير:
|
||||
|
||||
|
||||
```python
|
||||
# Existing interface - no change for users
|
||||
library.add_document(
|
||||
id="doc-123",
|
||||
title="Large Report",
|
||||
kind="application/pdf",
|
||||
content=large_pdf_bytes, # Can be hundreds of MB
|
||||
tags=["reports"]
|
||||
)
|
||||
```
|
||||
|
||||
داخليًا، يكتشف الـ SDK حجم المستند ويغير الاستراتيجية:
|
||||
|
||||
```python
|
||||
class Library:
|
||||
CHUNKED_UPLOAD_THRESHOLD = 2 * 1024 * 1024 # 2MB
|
||||
|
||||
def add_document(self, id, title, kind, content, tags=None, ...):
|
||||
if len(content) < self.CHUNKED_UPLOAD_THRESHOLD:
|
||||
# Small document: single operation (existing behavior)
|
||||
return self._add_document_single(id, title, kind, content, tags)
|
||||
else:
|
||||
# Large document: chunked upload
|
||||
return self._add_document_chunked(id, title, kind, content, tags)
|
||||
|
||||
def _add_document_chunked(self, id, title, kind, content, tags):
|
||||
# 1. begin-upload
|
||||
session = self._begin_upload(
|
||||
document_metadata={...},
|
||||
total_size=len(content),
|
||||
chunk_size=5 * 1024 * 1024
|
||||
)
|
||||
|
||||
# 2. upload-chunk for each chunk
|
||||
for i, chunk in enumerate(self._chunk_bytes(content, session.chunk_size)):
|
||||
self._upload_chunk(session.upload_id, i, chunk)
|
||||
|
||||
# 3. complete-upload
|
||||
return self._complete_upload(session.upload_id)
|
||||
```
|
||||
|
||||
**استدعاءات ردود الأفعال للتقدم** (تحسين اختياري):
|
||||
|
||||
```python
|
||||
def add_document(self, ..., on_progress=None):
|
||||
"""
|
||||
on_progress: Optional callback(bytes_sent, total_bytes)
|
||||
"""
|
||||
```
|
||||
|
||||
هذا يسمح لواجهات المستخدم بعرض تقدم التحميل دون تغيير واجهة برمجة التطبيقات الأساسية.
|
||||
|
||||
#### أدوات سطر الأوامر
|
||||
|
||||
**`tg-add-library-document`** يستمر في العمل دون تغيير:
|
||||
|
||||
```bash
|
||||
# Works transparently for any size - SDK handles chunking internally
|
||||
tg-add-library-document --file large-report.pdf --title "Large Report"
|
||||
```
|
||||
|
||||
يمكن إضافة عرض اختياري للتقدم:
|
||||
|
||||
```bash
|
||||
tg-add-library-document --file large-report.pdf --title "Large Report" --progress
|
||||
# Output:
|
||||
# Uploading: 45% (225MB / 500MB)
|
||||
```
|
||||
|
||||
**تمت إزالة الأدوات القديمة:**
|
||||
|
||||
`tg-load-pdf` - قديمة، استخدم `tg-add-library-document`
|
||||
`tg-load-text` - قديمة، استخدم `tg-add-library-document`
|
||||
|
||||
**أوامر الإدارة/التصحيح** (اختياري، أولوية منخفضة):
|
||||
|
||||
```bash
|
||||
# List incomplete uploads (admin troubleshooting)
|
||||
tg-add-library-document --list-pending
|
||||
|
||||
# Resume specific upload (recovery scenario)
|
||||
tg-add-library-document --resume upload-abc-123 --file large-report.pdf
|
||||
```
|
||||
|
||||
قد تكون هذه خيارات في الأمر الحالي بدلاً من أدوات منفصلة.
|
||||
|
||||
#### تحديثات مواصفات واجهة برمجة التطبيقات (API)
|
||||
|
||||
تحتاج مواصفات OpenAPI (`specs/api/paths/librarian.yaml`) إلى تحديثات فيما يلي:
|
||||
|
||||
**عمليات جديدة:**
|
||||
|
||||
`begin-upload` - تهيئة جلسة تحميل مقسمة
|
||||
`upload-chunk` - تحميل جزء فردي
|
||||
`complete-upload` - إنهاء التحميل
|
||||
`abort-upload` - إلغاء التحميل
|
||||
`get-upload-status` - الاستعلام عن تقدم التحميل
|
||||
`list-uploads` - قائمة بالتحميلات غير المكتملة للمستخدم
|
||||
`stream-document` - استرجاع المستندات المتدفقة
|
||||
`add-child-document` - تخزين النص المستخرج (داخلي)
|
||||
`list-children` - قائمة بالمستندات الفرعية (للمسؤول)
|
||||
|
||||
**عمليات معدلة:**
|
||||
|
||||
`list-documents` - إضافة معلمة `include-children`
|
||||
|
||||
**مخططات جديدة:**
|
||||
|
||||
`ChunkedUploadBeginRequest`
|
||||
`ChunkedUploadBeginResponse`
|
||||
`ChunkedUploadChunkRequest`
|
||||
`ChunkedUploadChunkResponse`
|
||||
`UploadSession`
|
||||
`UploadProgress`
|
||||
|
||||
**تحديثات مواصفات WebSocket** (`specs/websocket/`):
|
||||
|
||||
قم بمحاكاة العمليات REST لعملاء WebSocket، مما يتيح تحديثات التقدم في الوقت الفعلي
|
||||
أثناء التحميل.
|
||||
|
||||
#### اعتبارات تجربة المستخدم (UX)
|
||||
|
||||
تتيح تحديثات مواصفات واجهة برمجة التطبيقات (API) تحسينات في الواجهة الأمامية:
|
||||
|
||||
**واجهة مستخدم لتقدم التحميل:**
|
||||
شريط تقدم يوضح الأجزاء التي تم تحميلها
|
||||
الوقت المقدر المتبقي
|
||||
إمكانية الإيقاف المؤقت/الاستئناف
|
||||
|
||||
**استعادة الأخطاء:**
|
||||
خيار "استئناف التحميل" للتحميلات المتقطعة
|
||||
قائمة بالتحميلات المعلقة عند إعادة الاتصال
|
||||
|
||||
**التعامل مع الملفات الكبيرة:**
|
||||
اكتشاف حجم الملف من جانب العميل
|
||||
تحميل مقسم تلقائي للملفات الكبيرة
|
||||
ملاحظات واضحة أثناء عمليات التحميل الطويلة
|
||||
|
||||
تتطلب هذه التحسينات في تجربة المستخدم (UX) عملًا في الواجهة الأمامية يتم توجيهه بواسطة مواصفات واجهة برمجة التطبيقات (API) المحدثة.
|
||||
358
docs/tech-specs/ar/logging-strategy.ar.md
Normal file
358
docs/tech-specs/ar/logging-strategy.ar.md
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
---
|
||||
layout: default
|
||||
title: "استراتيجية تسجيل الأحداث في TrustGraph"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# استراتيجية تسجيل الأحداث في TrustGraph
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تستخدم TrustGraph الوحدة `logging` المضمنة في Python لجميع عمليات التسجيل، مع تكوين مركزي ودمج اختياري مع Loki لتجميع السجلات. يوفر هذا نهجًا موحدًا ومرنًا لتسجيل الأحداث عبر جميع مكونات النظام.
|
||||
|
||||
## التكوين الافتراضي
|
||||
|
||||
### مستوى التسجيل
|
||||
**المستوى الافتراضي**: `INFO`
|
||||
**يمكن تكوينه عبر**: وسيط سطر الأوامر `--log-level`
|
||||
**الخيارات**: `DEBUG`، `INFO`، `WARNING`، `ERROR`، `CRITICAL`
|
||||
|
||||
### وجهات الإخراج
|
||||
1. **وحدة التحكم (stdout)**: مفعل دائمًا - يضمن التوافق مع البيئات الحاويات.
|
||||
2. **Loki**: تجميع سجلات مركزي اختياري (مفعل افتراضيًا، ويمكن تعطيله).
|
||||
|
||||
## وحدة التسجيل المركزية
|
||||
|
||||
تتم إدارة جميع تكوينات التسجيل بواسطة الوحدة `trustgraph.base.logging`، والتي توفر:
|
||||
`add_logging_args(parser)` - يضيف وسيطات سطر الأوامر القياسية لتسجيل الأحداث.
|
||||
`setup_logging(args)` - يقوم بتكوين التسجيل من الوسائط التي تم تحليلها.
|
||||
|
||||
يتم استخدام هذا الوحدة بواسطة جميع المكونات من جانب الخادم:
|
||||
الخدمات القائمة على AsyncProcessor
|
||||
بوابة API
|
||||
خادم MCP
|
||||
|
||||
## إرشادات التنفيذ
|
||||
|
||||
### 1. تهيئة المسجل
|
||||
|
||||
يجب على كل وحدة إنشاء مسجل خاص بها باستخدام وحدة `__name__` الخاصة بالوحدة:
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
```
|
||||
|
||||
اسم المسجل يُستخدم تلقائيًا كعلامة في Loki لتصفية البحث.
|
||||
|
||||
### 2. تهيئة الخدمة
|
||||
|
||||
تتلقى جميع الخدمات من جهة الخادم تلقائيًا تكوين التسجيل من خلال الوحدة المركزية:
|
||||
|
||||
```python
|
||||
from trustgraph.base import add_logging_args, setup_logging
|
||||
import argparse
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# Add standard logging arguments (includes Loki configuration)
|
||||
add_logging_args(parser)
|
||||
|
||||
# Add your service-specific arguments
|
||||
parser.add_argument('--port', type=int, default=8080)
|
||||
|
||||
args = parser.parse_args()
|
||||
args = vars(args)
|
||||
|
||||
# Setup logging early in startup
|
||||
setup_logging(args)
|
||||
|
||||
# Rest of your service initialization
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info("Service starting...")
|
||||
```
|
||||
|
||||
### 3. وسيطات سطر الأوامر
|
||||
|
||||
تدعم جميع الخدمات وسيطات التسجيل التالية:
|
||||
|
||||
**مستوى التسجيل:**
|
||||
```bash
|
||||
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
||||
```
|
||||
|
||||
**تكوين لوكي:**
|
||||
```bash
|
||||
--loki-enabled # Enable Loki (default)
|
||||
--no-loki-enabled # Disable Loki
|
||||
--loki-url URL # Loki push URL (default: http://loki:3100/loki/api/v1/push)
|
||||
--loki-username USERNAME # Optional authentication
|
||||
--loki-password PASSWORD # Optional authentication
|
||||
```
|
||||
|
||||
**أمثلة:**
|
||||
```bash
|
||||
# Default - INFO level, Loki enabled
|
||||
./my-service
|
||||
|
||||
# Debug mode, console only
|
||||
./my-service --log-level DEBUG --no-loki-enabled
|
||||
|
||||
# Custom Loki server with auth
|
||||
./my-service --loki-url http://loki.prod:3100/loki/api/v1/push \
|
||||
--loki-username admin --loki-password secret
|
||||
```
|
||||
|
||||
### 4. متغيرات البيئة
|
||||
|
||||
تدعم إعدادات Loki استخدام متغيرات البيئة كبدائل:
|
||||
|
||||
```bash
|
||||
export LOKI_URL=http://loki.prod:3100/loki/api/v1/push
|
||||
export LOKI_USERNAME=admin
|
||||
export LOKI_PASSWORD=secret
|
||||
```
|
||||
|
||||
تتجاوز وسائط سطر الأوامر قيم المتغيرات البيئية.
|
||||
|
||||
### 5. أفضل الممارسات في التسجيل.
|
||||
|
||||
#### استخدام مستويات التسجيل.
|
||||
**DEBUG**: معلومات تفصيلية لتشخيص المشكلات (قيم المتغيرات، دخول/خروج الدالة).
|
||||
**INFO**: رسائل معلومات عامة (بدء الخدمة، تحميل التكوين، مراحل المعالجة).
|
||||
**WARNING**: رسائل تحذيرية لحالات قد تكون ضارة (ميزات مهملة، أخطاء قابلة للاسترداد).
|
||||
**ERROR**: رسائل خطأ للمشاكل الخطيرة (عمليات فاشلة، استثناءات).
|
||||
**CRITICAL**: رسائل حرجة لأعطال النظام التي تتطلب اهتمامًا فوريًا.
|
||||
|
||||
#### تنسيق الرسالة.
|
||||
```python
|
||||
# Good - includes context
|
||||
logger.info(f"Processing document: {doc_id}, size: {doc_size} bytes")
|
||||
logger.error(f"Failed to connect to database: {error}", exc_info=True)
|
||||
|
||||
# Avoid - lacks context
|
||||
logger.info("Processing document")
|
||||
logger.error("Connection failed")
|
||||
```
|
||||
|
||||
#### اعتبارات الأداء
|
||||
```python
|
||||
# Use lazy formatting for expensive operations
|
||||
logger.debug("Expensive operation result: %s", expensive_function())
|
||||
|
||||
# Check log level for very expensive debug operations
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
debug_data = compute_expensive_debug_info()
|
||||
logger.debug(f"Debug data: {debug_data}")
|
||||
```
|
||||
|
||||
### 6. التسجيل المنظم باستخدام لوكي
|
||||
|
||||
بالنسبة للبيانات المعقدة، استخدم التسجيل المنظم مع علامات إضافية لـ Loki:
|
||||
|
||||
```python
|
||||
logger.info("Request processed", extra={
|
||||
'tags': {
|
||||
'request_id': request_id,
|
||||
'user_id': user_id,
|
||||
'status': 'success'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
تصبح هذه العلامات تصنيفات قابلة للبحث في Loki، بالإضافة إلى التصنيفات التلقائية:
|
||||
`severity` - مستوى التسجيل (DEBUG، INFO، WARNING، ERROR، CRITICAL)
|
||||
`logger` - اسم الوحدة (من `__name__`)
|
||||
|
||||
### 7. تسجيل الاستثناءات
|
||||
|
||||
قم دائمًا بتضمين تتبعات المكدس للاستثناءات:
|
||||
|
||||
```python
|
||||
try:
|
||||
process_data()
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to process data: {e}", exc_info=True)
|
||||
raise
|
||||
```
|
||||
|
||||
### 8. اعتبارات التسجيل غير المتزامن
|
||||
|
||||
يستخدم نظام التسجيل معالجات غير متزامنة ومخزنة مؤقتًا لـ Loki:
|
||||
الإخراج إلى وحدة التحكم متزامن (سريع)
|
||||
يتم تخزين إخراج Loki في قائمة انتظار مع مخزن مؤقت مكون من 500 رسالة
|
||||
يقوم خيط الخلفية بمعالجة إرسال Loki
|
||||
لا يوجد حظر لرمز التطبيق الرئيسي
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
async def async_operation():
|
||||
logger = logging.getLogger(__name__)
|
||||
# Logging is thread-safe and won't block async operations
|
||||
logger.info(f"Starting async operation in task: {asyncio.current_task().get_name()}")
|
||||
```
|
||||
|
||||
## التكامل مع Loki
|
||||
|
||||
### البنية التحتية
|
||||
|
||||
يستخدم نظام التسجيل وظائف `QueueHandler` و `QueueListener` المضمنة في Python للتكامل غير المتزامن مع Loki:
|
||||
|
||||
1. **QueueHandler**: يتم وضع السجلات في قائمة انتظار تحتوي على 500 رسالة (غير متزامنة).
|
||||
2. **Background Thread**: يرسل QueueListener السجلات إلى Loki بشكل غير متزامن.
|
||||
3. **Graceful Degradation**: إذا كان Loki غير متاح، يستمر التسجيل في وحدة التحكم.
|
||||
|
||||
### التسميات التلقائية
|
||||
|
||||
تتضمن كل سجل يتم إرساله إلى Loki:
|
||||
`processor`: هوية المعالج (مثل `config-svc`، `text-completion`، `embeddings`).
|
||||
`severity`: مستوى السجل (DEBUG، INFO، إلخ).
|
||||
`logger`: اسم الوحدة (مثل `trustgraph.gateway.service`، `trustgraph.agent.react.service`).
|
||||
|
||||
### التسميات المخصصة
|
||||
|
||||
أضف تسميات مخصصة عبر المعامل `extra`:
|
||||
|
||||
```python
|
||||
logger.info("User action", extra={
|
||||
'tags': {
|
||||
'user_id': user_id,
|
||||
'action': 'document_upload',
|
||||
'collection': collection_name
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### الاستعلام عن السجلات في Loki
|
||||
|
||||
```logql
|
||||
# All logs from a specific processor (recommended - matches Prometheus metrics)
|
||||
{processor="config-svc"}
|
||||
{processor="text-completion"}
|
||||
{processor="embeddings"}
|
||||
|
||||
# Error logs from a specific processor
|
||||
{processor="config-svc", severity="ERROR"}
|
||||
|
||||
# Error logs from all processors
|
||||
{severity="ERROR"}
|
||||
|
||||
# Logs from a specific processor with text filter
|
||||
{processor="text-completion"} |= "Processing"
|
||||
|
||||
# All logs from API gateway
|
||||
{processor="api-gateway"}
|
||||
|
||||
# Logs from processors matching pattern
|
||||
{processor=~".*-completion"}
|
||||
|
||||
# Logs with custom tags
|
||||
{processor="api-gateway"} | json | user_id="12345"
|
||||
```
|
||||
|
||||
### التدهور الأنيق
|
||||
|
||||
إذا كان Loki غير متاح أو لم يتم تثبيت `python-logging-loki`:
|
||||
يتم طباعة رسالة تحذير على وحدة التحكم.
|
||||
يستمر تسجيل الأحداث في وحدة التحكم بشكل طبيعي.
|
||||
يستمر التطبيق في العمل.
|
||||
لا توجد آلية لإعادة المحاولة لاتصال Loki (الفشل السريع، والتدهور الأنيق).
|
||||
|
||||
## الاختبار
|
||||
|
||||
أثناء الاختبار، ضع في اعتبارك استخدام تكوين تسجيل مختلف:
|
||||
|
||||
```python
|
||||
# In test setup
|
||||
import logging
|
||||
|
||||
# Reduce noise during tests
|
||||
logging.getLogger().setLevel(logging.WARNING)
|
||||
|
||||
# Or disable Loki for tests
|
||||
setup_logging({'log_level': 'WARNING', 'loki_enabled': False})
|
||||
```
|
||||
|
||||
## التكامل مع نظام المراقبة
|
||||
|
||||
### التنسيق القياسي
|
||||
جميع السجلات تستخدم تنسيقًا متسقًا:
|
||||
```
|
||||
2025-01-09 10:30:45,123 - trustgraph.gateway.service - INFO - Request processed
|
||||
```
|
||||
|
||||
مكونات التنسيق:
|
||||
الطابع الزمني (بتنسيق ISO مع أجزاء من الثانية)
|
||||
اسم المسجل (مسار الوحدة)
|
||||
مستوى التسجيل
|
||||
الرسالة
|
||||
|
||||
### استعلامات Loki للمراقبة
|
||||
|
||||
استعلامات مراقبة شائعة:
|
||||
|
||||
```logql
|
||||
# Error rate by processor
|
||||
rate({severity="ERROR"}[5m]) by (processor)
|
||||
|
||||
# Top error-producing processors
|
||||
topk(5, count_over_time({severity="ERROR"}[1h]) by (processor))
|
||||
|
||||
# Recent errors with processor name
|
||||
{severity="ERROR"} | line_format "{{.processor}}: {{.message}}"
|
||||
|
||||
# All agent processors
|
||||
{processor=~".*agent.*"} |= "exception"
|
||||
|
||||
# Specific processor error count
|
||||
count_over_time({processor="config-svc", severity="ERROR"}[1h])
|
||||
```
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
**لا تقم أبدًا بتسجيل معلومات حساسة** (كلمات المرور، مفاتيح API، البيانات الشخصية، الرموز)
|
||||
**قم بتنظيف مدخلات المستخدم** قبل التسجيل
|
||||
**استخدم قيمًا محجوزة** للحقول الحساسة: `user_id=****1234`
|
||||
**مصادقة Loki**: استخدم `--loki-username` و `--loki-password` للنشر الآمن
|
||||
**نقل آمن**: استخدم HTTPS لعنوان URL الخاص بـ Loki في بيئة الإنتاج: `https://loki.prod:3100/loki/api/v1/push`
|
||||
|
||||
## التبعيات
|
||||
|
||||
يتطلب وحدة التسجيل المركزية ما يلي:
|
||||
`python-logging-loki` - لتكامل Loki (اختياري، مع إمكانية التراجع الآمن في حالة عدم وجوده)
|
||||
|
||||
تم تضمينها بالفعل في `trustgraph-base/pyproject.toml` و `requirements.txt`.
|
||||
|
||||
## مسار الترحيل
|
||||
|
||||
بالنسبة للكود الحالي:
|
||||
|
||||
1. **الخدمات التي تستخدم بالفعل AsyncProcessor**: لا توجد تغييرات مطلوبة، دعم Loki تلقائي
|
||||
2. **الخدمات التي لا تستخدم AsyncProcessor** (api-gateway, mcp-server): تم تحديثها بالفعل
|
||||
3. **أدوات سطر الأوامر (CLI)**: خارج نطاق العمل - استمر في استخدام print() أو التسجيل البسيط
|
||||
|
||||
### من print() إلى التسجيل:
|
||||
```python
|
||||
# Before
|
||||
print(f"Processing document {doc_id}")
|
||||
|
||||
# After
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.info(f"Processing document {doc_id}")
|
||||
```
|
||||
|
||||
## ملخص الإعدادات
|
||||
|
||||
| الوسيط | القيمة الافتراضية | متغير البيئة | الوصف |
|
||||
|----------|---------|---------------------|-------------|
|
||||
| `--log-level` | `INFO` | - | مستوى تسجيل وحدة التحكم و Loki |
|
||||
| `--loki-enabled` | `True` | - | تمكين تسجيل Loki |
|
||||
| `--loki-url` | `http://loki:3100/loki/api/v1/push` | `LOKI_URL` | نقطة النهاية لدفع البيانات إلى Loki |
|
||||
| `--loki-username` | `None` | `LOKI_USERNAME` | اسم المستخدم للمصادقة في Loki |
|
||||
| `--loki-password` | `None` | `LOKI_PASSWORD` | كلمة المرور للمصادقة في Loki |
|
||||
163
docs/tech-specs/ar/mcp-tool-arguments.ar.md
Normal file
163
docs/tech-specs/ar/mcp-tool-arguments.ar.md
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات معاملات أداة MCP"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات معاملات أداة MCP
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
**اسم الميزة**: دعم معاملات أداة MCP
|
||||
**المؤلف**: مساعد كود كلوود
|
||||
**التاريخ**: 2025-08-21
|
||||
**الحالة**: نهائية
|
||||
|
||||
### ملخص تنفيذي
|
||||
|
||||
تمكين عوامل ReACT من استدعاء أدوات MCP (بروتوكول سياق النموذج) مع المعاملات المحددة بشكل صحيح عن طريق إضافة دعم مواصفات المعاملات إلى تكوينات أدوات MCP، على غرار الطريقة التي تعمل بها أدوات القالب الحالية.
|
||||
|
||||
### بيان المشكلة
|
||||
|
||||
في الوقت الحالي، لا يمكن لأدوات MCP في إطار عمل ReACT تحديد المعاملات المتوقعة. تُرجع طريقة `McpToolImpl.get_arguments()` قائمة فارغة، مما يجبر نماذج اللغة الكبيرة (LLMs) على تخمين هيكل المعلمات بناءً على أسماء وأوصاف الأدوات فقط. هذا يؤدي إلى:
|
||||
- استدعاء أدوات غير موثوق به بسبب تخمين المعلمات
|
||||
- تجربة مستخدم سيئة عندما تفشل الأدوات بسبب معاملات غير صحيحة
|
||||
- عدم التحقق من معلمات الأداة قبل التنفيذ
|
||||
- عدم وجود توثيق لمعلمات الأداة في مطالبات الوكيل
|
||||
|
||||
### الأهداف
|
||||
|
||||
- [ ] السماح بتكوينات أدوات MCP بتحديد المعاملات المتوقعة (الاسم، النوع، الوصف)
|
||||
- [ ] تحديث مدير الوكيل للكشف عن معاملات أداة MCP لـ LLMs عبر المطالبات
|
||||
- [ ] الحفاظ على التوافق مع الإصدارات الحالية من تكوينات أدوات MCP
|
||||
- [ ] دعم التحقق من صحة المعاملات على غرار أدوات القالب
|
||||
|
||||
### الأهداف غير المحققة
|
||||
- اكتشاف ديناميكي للمعاملات من خوادم MCP (تحسين مستقبلي)
|
||||
- التحقق من نوع المعاملات بالإضافة إلى الهيكل الأساسي
|
||||
- مخططات المعاملات المعقدة (الكائنات المتداخلة، المصفوفات)
|
||||
|
||||
## الخلفية والسياق
|
||||
|
||||
### الحالة الحالية
|
||||
يتم تكوين أدوات MCP في نظام ReACT مع بيانات وصفية قليلة:
|
||||
```json
|
||||
{
|
||||
"type": "mcp-tool",
|
||||
"name": "get_bank_balance",
|
||||
"description": "Get bank account balance",
|
||||
"mcp-tool": "get_bank_balance"
|
||||
}
|
||||
```
|
||||
|
||||
تُرجع طريقة `McpToolImpl.get_arguments()` قائمة فارغة، لذلك لا تتلقى LLMs أي إرشادات حول المعاملات في مطالباتها.
|
||||
|
||||
### القيود
|
||||
|
||||
1. **عدم وجود مواصفات للمعاملات**: لا يمكن لأدوات MCP تحديد المعلمات المتوقعة
|
||||
|
||||
2. **تخمين المعلمات بواسطة LLM**: يجب على الوكلاء استنتاج المعلمات من أسماء/وصف الأدوات
|
||||
|
||||
3. **نقص معلومات المطالبة**: لا تعرض مطالبات الوكيل تفاصيل المعاملات لأدوات MCP
|
||||
|
||||
4. **عدم التحقق**: يتم التقاط المعلمات غير الصالحة فقط عند وقت تنفيذ أداة MCP
|
||||
|
||||
### المكونات ذات الصلة
|
||||
- **trustgraph-flow/agent/react/service.py**: تحميل تكوين الأداة وإنشاء AgentManager
|
||||
- **trustgraph-flow/agent/react/tools.py**: تنفيذ McpToolImpl
|
||||
- **trustgraph-flow/agent/react/agent_manager.py**: إنشاء المطالبات بمعاملات الأداة
|
||||
- **CLI tools**: أدوات سطر الأوامر لإدارة أدوات MCP
|
||||
- **Workbench**: واجهة المستخدم الخارجية لتكوين أدوات الوكيل
|
||||
|
||||
## المتطلبات
|
||||
|
||||
### المتطلبات الوظيفية
|
||||
|
||||
1. **معاملات أداة MCP**: يجب أن تدعم تكوينات أدوات MCP مصفوفة اختيارية "arguments" مع حقول الاسم والنوع والوصف
|
||||
2. **الكشف عن المعاملات**: يجب أن تُرجع طريقة `McpToolImpl.get_arguments()` المعاملات المحددة بدلاً من قائمة فارغة
|
||||
3. **التكامل مع المطالبة**: يجب أن تتضمن المطالبات الخاصة بالوكيل تفاصيل معامل أداة MCP عند تحديد المعاملات
|
||||
4. **التوافق مع الإصدارات الحالية**: يجب أن تستمر تكوينات أدوات MCP الحالية بدون معاملات في العمل
|
||||
5. **دعم CLI**: يدعم CLI الحالي `tg-invoke-mcp-tool` المعاملات (مُنفذ بالفعل)
|
||||
|
||||
### المتطلبات غير الوظيفية
|
||||
1. **التوافق مع الإصدارات الحالية**: لا توجد تغييرات مدمرة في تكوينات أدوات MCP الحالية
|
||||
2. **الأداء**: عدم وجود تأثير كبير على توليد المطالبات للوكلاء
|
||||
3. **الاتساق**: يجب أن يطابق معالجة المعاملات أنماط أدوات القالب
|
||||
|
||||
### قصص المستخدم
|
||||
|
||||
1. بصفتي **مطور الوكيل**: أرغب في تحديد معاملات أداة MCP في التكوين حتى تتمكن نماذج اللغة الكبيرة من استدعاء الأدوات بمعلمات صحيحة
|
||||
2. بصفتي **مستخدم واجهة Workbench**: أرغب في تكوين معاملات أداة MCP في واجهة المستخدم حتى تستخدم الوكلاء الأدوات بشكل صحيح
|
||||
3. بصفتي **نموذج لغة كبيرة في وكيل ReACT**: أرغب في رؤية مواصفات معامل الأداة في المطالبات حتى أتمكن من توفير المعلمات الصحيحة
|
||||
|
||||
## التصميم
|
||||
|
||||
### الهندسة المعمارية عالية المستوى
|
||||
لتحقيق التوافق مع أنماط أدوات القالب، قم بتوسيع تكوين أداة MCP عن طريق:
|
||||
1. إضافة مصفوفة اختيارية "arguments" إلى تكوينات أدوات MCP
|
||||
2. تعديل `McpToolImpl` لقبول وإرجاع المعاملات المحددة
|
||||
3. تحديث تحميل تكوين الأداة للتعامل مع معاملات أدوات MCP
|
||||
4. التأكد من تضمين معلومات معامل أداة MCP في المطالبات
|
||||
|
||||
### مخطط التكوين
|
||||
```json
|
||||
{
|
||||
"type": "mcp-tool",
|
||||
"name": "get_bank_balance",
|
||||
"description": "Get bank account balance",
|
||||
"mcp-tool": "get_bank_balance",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "account_id",
|
||||
"type": "string",
|
||||
"description": "Bank account identifier"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"type": "string",
|
||||
"description": "Date for balance query (optional, format: YYYY-MM-DD)"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### تدفق البيانات
|
||||
1. **تحميل التكوين**: يتم تحميل تكوين أداة MCP مع المعاملات بواسطة `on_tools_config()`
|
||||
2. **إنشاء الأداة**: يتم تحليل المعاملات وتمريرها إلى `McpToolImpl` من خلال المُنشئ
|
||||
3. **توليد المطالبة**: تتلقى LLMs معلومات المعاملات من الأداة، مما يسمح لها بإنشاء مطالبات مناسبة.
|
||||
4. **تنفيذ الأداة**: يتم تنفيذ أداة MCP باستخدام المعاملات التي تم تمريرها.
|
||||
|
||||
### تأثير الأداء
|
||||
- **وقت تشغيل ضئيل**: يحدث تحليل المعاملات فقط أثناء تحميل التكوين، وليس لكل طلب
|
||||
- **حجم المطالبة**: قد تزيد المطالبات الخاصة بالوكيل قليلاً بسبب تضمين تفاصيل معامل أداة MCP.
|
||||
- **استخدام الذاكرة**: زيادة ضئيلة لتخزين مواصفات المعاملات في كائنات الأداة.
|
||||
|
||||
## الوثائق
|
||||
|
||||
### وثائق المستخدم
|
||||
- [ ] تحديث دليل تكوين أداة MCP مع أمثلة للمعاملات
|
||||
- [ ] إضافة مواصفات المعامل إلى نص مساعد أدوات سطر الأوامر
|
||||
- [ ] إنشاء أمثلة لأنماط معلمات أداة MCP الشائعة
|
||||
|
||||
### وثائق المطور
|
||||
- [ ] تحديث وثائق فئة `McpToolImpl`
|
||||
- [ ] إضافة تعليقات توضيحية حول منطق تحليل المعاملات
|
||||
- [ ] توثيق تدفق المعامل في الهندسة المعمارية للنظام
|
||||
|
||||
## الأسئلة المفتوحة
|
||||
1. **التحقق من صحة المعاملات**: هل يجب علينا التحقق من أنواع المعاملات/تنسيقاتها بالإضافة إلى التحقق الأساسي من الهيكل؟
|
||||
2. **اكتشاف ديناميكي**: هل نريد الاستعلام عن خوادم MCP عن مخططات أدوات بشكل تلقائي؟
|
||||
|
||||
## البدائل التي تم النظر فيها
|
||||
1. **اكتشاف مخططات MCP الديناميكية**: الاستعلام عن خوادم MCP عن مخططات أدوات المعامل في وقت التشغيل - تم رفضها بسبب التعقيد ومخاوف الموثوقية
|
||||
2. **سجل المعاملات المنفصل**: تخزين معاملات أداة MCP في قسم تكوين منفصل - تم رفضه للحفاظ على التوافق مع نهج أدوات القالب
|
||||
3. **التحقق من نوع المعامل**: التحقق الكامل من مخطط JSON للمعاملات - تم تأجيله للحفاظ على البساطة في التنفيذ الأولي
|
||||
|
||||
## المراجع
|
||||
- [المواصفات الخاصة ببروتوكول MCP](https://github.com/modelcontextprotocol/spec)
|
||||
- [تنفيذ أداة MCP](./trustgraph-flow/trustgraph/agent/react/service.py#L114-129)
|
||||
- [تنفيذ أداة MCP الحالي](./trustgraph-flow/trustgraph/agent/react/tools.py#L58-86)
|
||||
|
||||
## الملحق
|
||||
[أي معلومات إضافية، أو مخططات، أو أمثلة]
|
||||
562
docs/tech-specs/ar/mcp-tool-bearer-token.ar.md
Normal file
562
docs/tech-specs/ar/mcp-tool-bearer-token.ar.md
Normal file
|
|
@ -0,0 +1,562 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات مصادقة رمز الحامل لأدوات MCP"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات مصادقة رمز الحامل لأدوات MCP
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
> **⚠️ هام: مخصص للعملاء ذوي المستأجر الواحد فقط**
|
||||
>
|
||||
> تصف هذه المواصفات آلية مصادقة أساسية على مستوى الخدمة لأدوات MCP. إنها **ليست** حلاً كاملاً للمصادقة وليست **مناسبة** لـ:
|
||||
> - بيئات متعددة المستخدمين
|
||||
> - عمليات نشر متعددة المستأجرين
|
||||
> - المصادقة الموحدة
|
||||
> - نقل سياق المستخدم
|
||||
> - التفويض لكل مستخدم
|
||||
>
|
||||
> توفر هذه الميزة **رمزًا ثابتًا واحدًا لكل أداة MCP**، يتم مشاركته عبر جميع المستخدمين والجلسات. إذا كنت بحاجة إلى مصادقة لكل مستخدم أو لكل مستأجر، فهذه ليست الحل المناسب.
|
||||
|
||||
## نظرة عامة
|
||||
**اسم الميزة**: دعم رمز الحامل للمصادقة لأدوات MCP
|
||||
**المؤلف**: مساعد كود كلود
|
||||
**التاريخ**: 2025-11-11
|
||||
**الحالة**: قيد التطوير
|
||||
|
||||
### ملخص تنفيذي
|
||||
|
||||
قم بتمكين تكوينات أدوات MCP لتحديد رموز حامل اختيارية للمصادقة مع خوادم MCP المحمية. يتيح ذلك لـ TrustGraph استدعاء أدوات MCP المستضافة على الخوادم التي تتطلب المصادقة بشكل آمن، دون تعديل وكيل الأداة أو واجهات استدعاء الأداة.
|
||||
|
||||
**هام**: هذه آلية مصادقة أساسية مصممة لسيناريوهات المصادقة من خدمة إلى خدمة، خاصة بالمستأجر الواحد. إنها **ليست** مناسبة لـ:
|
||||
بيئات متعددة المستخدمين حيث يحتاج المستخدمون المختلفون إلى بيانات اعتماد مختلفة
|
||||
عمليات نشر متعددة المستأجرين تتطلب عزلًا لكل مستأجر
|
||||
سيناريوهات المصادقة الموحدة
|
||||
مصادقة أو تفويض على مستوى المستخدم
|
||||
إدارة بيانات الاعتماد الديناميكية أو تحديث الرموز
|
||||
|
||||
توفر هذه الميزة رمز حامل ثابتًا على مستوى النظام لكل تكوين أداة MCP، يتم مشاركته عبر جميع المستخدمين واستدعاءات تلك الأداة.
|
||||
|
||||
### بيان المشكلة
|
||||
|
||||
حاليًا، يمكن لأدوات MCP الاتصال فقط بخوادم MCP التي يمكن الوصول إليها للجمهور. تتطلب العديد من عمليات نشر MCP الإنتاجية مصادقة عبر رموز الحامل لأسباب أمنية. بدون دعم المصادقة:
|
||||
لا يمكن لأدوات MCP الاتصال بخوادم MCP الآمنة
|
||||
يجب على المستخدمين إما تعريض خوادم MCP للجمهور أو تنفيذ وكلاء عكسيين
|
||||
لا توجد طريقة موحدة لتمرير بيانات الاعتماد إلى اتصالات MCP
|
||||
لا يمكن فرض أفضل ممارسات الأمان على نقاط نهاية MCP
|
||||
|
||||
### الأهداف
|
||||
|
||||
[ ] السماح لتكوينات أدوات MCP بتحديد معلمة `auth-token` اختيارية
|
||||
[ ] تحديث خدمة أداة MCP لاستخدام رموز الحامل عند الاتصال بخوادم MCP
|
||||
[ ] تحديث أدوات سطر الأوامر لدعم تعيين/عرض رموز المصادقة
|
||||
[ ] الحفاظ على التوافق مع الإصدارات السابقة لتكوينات MCP غير المصادقة
|
||||
[ ] توثيق اعتبارات الأمان لتخزين الرموز
|
||||
|
||||
### الأهداف غير المشمولة
|
||||
تحديث الرموز الديناميكي أو تدفقات OAuth (رموز ثابتة فقط)
|
||||
تشفير الرموز المخزنة (أمان نظام التكوين خارج النطاق)
|
||||
طرق مصادقة بديلة (المصادقة الأساسية، مفاتيح API، إلخ.)
|
||||
التحقق من صحة الرموز أو انتهاء صلاحيتها
|
||||
**المصادقة لكل مستخدم**: لا تدعم هذه الميزة بيانات اعتماد خاصة بالمستخدم
|
||||
**عزل متعدد المستأجرين**: لا توفر هذه الميزة إدارة رموز لكل مستأجر
|
||||
**المصادقة الموحدة**: لا تتكامل هذه الميزة مع موفري الهوية (SSO، OAuth، SAML، إلخ.)
|
||||
**المصادقة الواعية بالسياق**: لا يتم تمرير الرموز بناءً على سياق المستخدم أو الجلسة
|
||||
|
||||
## الخلفية والسياق
|
||||
|
||||
### الحالة الحالية
|
||||
يتم تخزين تكوينات أدوات MCP في مجموعة التكوين `mcp` بهذه البنية:
|
||||
```json
|
||||
{
|
||||
"remote-name": "tool_name",
|
||||
"url": "http://mcp-server:3000/api"
|
||||
}
|
||||
```
|
||||
|
||||
تتصل خدمة أداة MCP بالخوادم باستخدام `streamablehttp_client(url)` بدون أي رؤوس مصادقة.
|
||||
|
||||
### القيود
|
||||
|
||||
**قيود النظام الحالية:**
|
||||
1. **لا يوجد دعم للمصادقة:** لا يمكن الاتصال بخوادم MCP المحمية.
|
||||
2. **تعرض أمني:** يجب أن تكون خوادم MCP متاحة للجمهور أو تستخدم أمان على مستوى الشبكة فقط.
|
||||
3. **مشكلات النشر في بيئة الإنتاج:** لا يمكن اتباع أفضل الممارسات الأمنية لنقاط نهاية واجهة برمجة التطبيقات.
|
||||
|
||||
**قيود هذا الحل:**
|
||||
1. **نظام مستأجر واحد فقط:** رمز ثابت واحد لكل أداة MCP، مشترك بين جميع المستخدمين.
|
||||
2. **لا توجد بيانات اعتماد خاصة بالمستخدم:** لا يمكن المصادقة كمستخدمين مختلفين أو تمرير سياق المستخدم.
|
||||
3. **لا يوجد دعم للأنظمة متعددة المستأجرين:** لا يمكن عزل بيانات الاعتماد حسب المستأجر أو المؤسسة.
|
||||
4. **رموز ثابتة فقط:** لا يوجد دعم لتحديث الرموز أو تدويرها أو معالجة انتهاء صلاحيتها.
|
||||
5. **مصادقة على مستوى الخدمة:** تقوم المصادقة على خدمة TrustGraph، وليس على المستخدمين الفرديين.
|
||||
6. **سياق أمني مشترك:** تستخدم جميع استدعاءات أداة MCP نفس الاعتماد.
|
||||
|
||||
### مدى ملاءمة حالة الاستخدام
|
||||
|
||||
**✅ حالات الاستخدام المناسبة:**
|
||||
عمليات نشر TrustGraph ذات المستأجر الواحد.
|
||||
مصادقة من خدمة إلى خدمة (TrustGraph → خادم MCP).
|
||||
بيئات التطوير والاختبار.
|
||||
أدوات MCP الداخلية التي يتم الوصول إليها بواسطة نظام TrustGraph.
|
||||
السيناريوهات التي يشارك فيها جميع المستخدمين نفس مستوى الوصول إلى أداة MCP.
|
||||
بيانات اعتماد خدمة ثابتة وطويلة الأجل.
|
||||
|
||||
**❌ حالات الاستخدام غير المناسبة:**
|
||||
الأنظمة متعددة المستخدمين التي تتطلب مصادقة خاصة بالمستخدم.
|
||||
عمليات نشر SaaS متعددة المستأجرين مع متطلبات عزل المستأجر.
|
||||
سيناريوهات المصادقة الموحدة (SSO، OAuth، SAML).
|
||||
الأنظمة التي تتطلب تمرير سياق المستخدم إلى خوادم MCP.
|
||||
البيئات التي تحتاج إلى تحديث الرموز ديناميكيًا أو رموز قصيرة الأجل.
|
||||
التطبيقات التي تحتاج فيها مستخدمون مختلفون إلى مستويات أذونات مختلفة.
|
||||
متطلبات الامتثال لتسجيلات التدقيق على مستوى المستخدم.
|
||||
|
||||
**مثال على سيناريو مناسب:**
|
||||
عملية نشر TrustGraph لمنظمة واحدة حيث يستخدم جميع الموظفين نفس أداة MCP الداخلية (على سبيل المثال، البحث في قاعدة بيانات الشركة). يتطلب خادم MCP مصادقة لمنع الوصول الخارجي، ولكن جميع المستخدمين الداخليين لديهم نفس مستوى الوصول.
|
||||
|
||||
**مثال على سيناريو غير مناسب:**
|
||||
منصة SaaS متعددة المستأجرين لـ TrustGraph حيث يحتاج كل من المستأجر A والمستأجر B إلى الوصول إلى خوادم MCP الخاصة بهم المعزولة ببيانات اعتماد منفصلة. لا يدعم هذا الميزة إدارة الرموز الخاصة بالمستأجر.
|
||||
|
||||
### المكونات ذات الصلة
|
||||
**trustgraph-flow/trustgraph/agent/mcp_tool/service.py**: خدمة استدعاء أداة MCP.
|
||||
**trustgraph-cli/trustgraph/cli/set_mcp_tool.py**: أداة سطر أوامر لإنشاء/تحديث تكوينات MCP.
|
||||
**trustgraph-cli/trustgraph/cli/show_mcp_tools.py**: أداة سطر أوامر لعرض تكوينات MCP.
|
||||
**مجموعة تطوير البرامج (SDK) لـ MCP بلغة Python**: `streamablehttp_client` من `mcp.client.streamable_http`
|
||||
|
||||
## المتطلبات
|
||||
|
||||
### المتطلبات الوظيفية
|
||||
|
||||
1. **رمز مصادقة تكوين MCP:** يجب أن تدعم تكوينات أداة MCP حقل `auth-token` اختياري.
|
||||
2. **استخدام رمز مميز:** يجب أن ترسل خدمة أداة MCP رأس `Authorization: Bearer {token}` عند تكوين رمز مميز.
|
||||
3. **دعم سطر الأوامر:** يجب أن تقبل `tg-set-mcp-tool` معلمة `--auth-token` اختيارية.
|
||||
4. **عرض الرمز:** يجب أن تشير `tg-show-mcp-tools` إلى متى تم تكوين رمز مميز (تم إخفاءه لأسباب أمنية).
|
||||
5. **التوافق مع الإصدارات السابقة:** يجب أن تستمر تكوينات أداة MCP الحالية بدون رمز مميز في العمل.
|
||||
|
||||
### المتطلبات غير الوظيفية
|
||||
1. **التوافق مع الإصدارات السابقة:** لا توجد تغييرات فاصلة للإصدارات لتكوينات أداة MCP الحالية.
|
||||
2. **الأداء:** لا يوجد تأثير كبير على الأداء على استدعاء أداة MCP.
|
||||
3. **الأمان:** يتم تخزين الرموز في التكوين (يرجى توثيق الآثار الأمنية).
|
||||
|
||||
### قصص المستخدم
|
||||
|
||||
1. بصفتي **مهندس DevOps**، أريد تكوين رموز مميزة لأدوات MCP حتى أتمكن من تأمين نقاط نهاية خادم MCP.
|
||||
2. بصفتي **مستخدم سطر أوامر**، أريد تعيين رموز مميزة عند إنشاء أدوات MCP حتى أتمكن من الاتصال بالخوادم المحمية.
|
||||
3. بصفتي **مسؤول النظام**، أريد أن أرى أي أدوات MCP تم تكوين مصادقة لها حتى أتمكن من تدقيق إعدادات الأمان.
|
||||
|
||||
## التصميم
|
||||
|
||||
### البنية عالية المستوى
|
||||
قم بتوسيع تكوين وخدمة أداة MCP لدعم مصادقة الرمز المميز:
|
||||
1. أضف حقل `auth-token` اختياري إلى مخطط تكوين أداة MCP.
|
||||
2. قم بتعديل خدمة أداة MCP لقراءة الرمز المميز وتمريره إلى عميل HTTP.
|
||||
3. قم بتحديث أدوات سطر الأوامر لدعم تعيين وعرض الرموز المميزة.
|
||||
4. قم بتوثيق الاعتبارات الأمنية وأفضل الممارسات.
|
||||
|
||||
### مخطط التكوين
|
||||
|
||||
**المخطط الحالي:**
|
||||
```json
|
||||
{
|
||||
"remote-name": "tool_name",
|
||||
"url": "http://mcp-server:3000/api"
|
||||
}
|
||||
```
|
||||
|
||||
**مخطط جديد** (مع رمز مصادقة اختياري):
|
||||
```json
|
||||
{
|
||||
"remote-name": "tool_name",
|
||||
"url": "http://mcp-server:3000/api",
|
||||
"auth-token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
}
|
||||
```
|
||||
|
||||
**وصف الحقول:**
|
||||
`remote-name` (اختياري): الاسم المستخدم بواسطة خادم MCP (افتراضيًا، مفتاح التكوين)
|
||||
`url` (إلزامي): عنوان URL لنقطة نهاية خادم MCP
|
||||
`auth-token` (اختياري): رمز مميز (Bearer token) للمصادقة
|
||||
|
||||
### تدفق البيانات
|
||||
|
||||
1. **تخزين التكوين:** يقوم المستخدم بتشغيل `tg-set-mcp-tool --id my-tool --tool-url http://server/api --auth-token xyz123`
|
||||
2. **تحميل التكوين:** يتلقى خدمة أداة MCP تحديث التكوين عبر استدعاء رد (callback) `on_mcp_config()`
|
||||
3. **استدعاء الأداة:** عند استدعاء الأداة:
|
||||
تقرأ الخدمة `auth-token` من التكوين (إذا كان موجودًا)
|
||||
تقوم بإنشاء قاموس الرؤوس: `{"Authorization": "Bearer {token}"}`
|
||||
تمرر الرؤوس إلى `streamablehttp_client(url, headers=headers)`
|
||||
يقوم خادم MCP بالتحقق من صحة الرمز المميز ومعالجة الطلب
|
||||
|
||||
### تغييرات واجهة برمجة التطبيقات (API)
|
||||
لا توجد تغييرات في واجهة برمجة التطبيقات الخارجية - فقط توسيع مخطط التكوين.
|
||||
|
||||
### تفاصيل المكون
|
||||
|
||||
#### المكون 1: service.py (خدمة أداة MCP)
|
||||
**الملف:** `trustgraph-flow/trustgraph/agent/mcp_tool/service.py`
|
||||
|
||||
**الغرض:** استدعاء أدوات MCP على الخوادم البعيدة
|
||||
|
||||
**التغييرات المطلوبة** (في طريقة `invoke_tool()`):
|
||||
1. التحقق من وجود `auth-token` في تكوين `self.mcp_services[name]`
|
||||
2. إنشاء قاموس الرؤوس مع رأس "Authorization" إذا كان الرمز المميز موجودًا
|
||||
3. تمرير الرؤوس إلى `streamablehttp_client(url, headers=headers)`
|
||||
|
||||
**الكود الحالي** (الأسطر 42-89):
|
||||
```python
|
||||
async def invoke_tool(self, name, parameters):
|
||||
try:
|
||||
if name not in self.mcp_services:
|
||||
raise RuntimeError(f"MCP service {name} not known")
|
||||
if "url" not in self.mcp_services[name]:
|
||||
raise RuntimeError(f"MCP service {name} URL not defined")
|
||||
|
||||
url = self.mcp_services[name]["url"]
|
||||
|
||||
if "remote-name" in self.mcp_services[name]:
|
||||
remote_name = self.mcp_services[name]["remote-name"]
|
||||
else:
|
||||
remote_name = name
|
||||
|
||||
logger.info(f"Invoking {remote_name} at {url}")
|
||||
|
||||
# Connect to a streamable HTTP server
|
||||
async with streamablehttp_client(url) as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
_,
|
||||
):
|
||||
# ... rest of method
|
||||
```
|
||||
|
||||
**الكود المُعدَّل**:
|
||||
```python
|
||||
async def invoke_tool(self, name, parameters):
|
||||
try:
|
||||
if name not in self.mcp_services:
|
||||
raise RuntimeError(f"MCP service {name} not known")
|
||||
if "url" not in self.mcp_services[name]:
|
||||
raise RuntimeError(f"MCP service {name} URL not defined")
|
||||
|
||||
url = self.mcp_services[name]["url"]
|
||||
|
||||
if "remote-name" in self.mcp_services[name]:
|
||||
remote_name = self.mcp_services[name]["remote-name"]
|
||||
else:
|
||||
remote_name = name
|
||||
|
||||
# Build headers with optional bearer token
|
||||
headers = {}
|
||||
if "auth-token" in self.mcp_services[name]:
|
||||
token = self.mcp_services[name]["auth-token"]
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
logger.info(f"Invoking {remote_name} at {url}")
|
||||
|
||||
# Connect to a streamable HTTP server with headers
|
||||
async with streamablehttp_client(url, headers=headers) as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
_,
|
||||
):
|
||||
# ... rest of method (unchanged)
|
||||
```
|
||||
|
||||
#### المكون 2: set_mcp_tool.py (أداة تكوين سطر الأوامر)
|
||||
**الملف**: `trustgraph-cli/trustgraph/cli/set_mcp_tool.py`
|
||||
|
||||
**الغرض**: إنشاء/تحديث إعدادات أداة MCP
|
||||
|
||||
**التغييرات المطلوبة**:
|
||||
1. إضافة وسيطة اختيارية `--auth-token` إلى argparse
|
||||
2. تضمين `auth-token` في ملف JSON الخاص بالتكوين عند توفره
|
||||
|
||||
**الوسائط الحالية**:
|
||||
`--id` (مطلوب): معرف أداة MCP
|
||||
`--remote-name` (اختياري): اسم أداة MCP البعيدة
|
||||
`--tool-url` (مطلوب): نقطة نهاية عنوان URL لأداة MCP
|
||||
`-u, --api-url` (اختياري): عنوان URL لواجهة برمجة تطبيقات TrustGraph
|
||||
|
||||
**وسيطة جديدة**:
|
||||
`--auth-token` (اختياري): رمز مميز للمصادقة
|
||||
|
||||
**تعديل بناء التكوين**:
|
||||
```python
|
||||
# Build configuration object
|
||||
config = {
|
||||
"url": args.tool_url,
|
||||
}
|
||||
|
||||
if args.remote_name:
|
||||
config["remote-name"] = args.remote_name
|
||||
|
||||
if args.auth_token:
|
||||
config["auth-token"] = args.auth_token
|
||||
|
||||
# Store configuration
|
||||
api.config().put([
|
||||
ConfigValue(type="mcp", key=args.id, value=json.dumps(config))
|
||||
])
|
||||
```
|
||||
|
||||
#### المكون 3: show_mcp_tools.py (أداة العرض من سطر الأوامر)
|
||||
**الملف**: `trustgraph-cli/trustgraph/cli/show_mcp_tools.py`
|
||||
|
||||
**الغرض**: عرض إعدادات أدوات MCP.
|
||||
|
||||
**التغييرات المطلوبة**:
|
||||
1. إضافة عمود "Auth" إلى جدول الإخراج.
|
||||
2. عرض "نعم" أو "لا" بناءً على وجود رمز المصادقة.
|
||||
3. عدم عرض قيمة الرمز الفعلية (لأسباب أمنية).
|
||||
|
||||
**الإخراج الحالي**:
|
||||
```
|
||||
ID Remote Name URL
|
||||
---------- ------------- ------------------------
|
||||
my-tool my-tool http://server:3000/api
|
||||
```
|
||||
|
||||
**الناتج الجديد**:
|
||||
```
|
||||
ID Remote Name URL Auth
|
||||
---------- ------------- ------------------------ ------
|
||||
my-tool my-tool http://server:3000/api Yes
|
||||
other-tool other-tool http://other:3000/api No
|
||||
```
|
||||
|
||||
#### المكون 4: التوثيق
|
||||
**الملف**: `docs/cli/tg-set-mcp-tool.md`
|
||||
|
||||
**التغييرات المطلوبة**:
|
||||
1. توثيق المعاملة الجديدة `--auth-token`
|
||||
2. تقديم مثال للاستخدام مع المصادقة
|
||||
3. توثيق الاعتبارات الأمنية
|
||||
|
||||
## خطة التنفيذ
|
||||
|
||||
### المرحلة الأولى: إنشاء المواصفات الفنية
|
||||
[x] كتابة مواصفات فنية شاملة توثق جميع التغييرات
|
||||
|
||||
### المرحلة الثانية: تحديث خدمة MCP
|
||||
[ ] تعديل `invoke_tool()` في `service.py` لقراءة رمز المصادقة من التكوين
|
||||
[ ] إنشاء قاموس الرؤوس وتمريره إلى `streamablehttp_client`
|
||||
[ ] الاختبار مع خادم MCP مصادق عليه
|
||||
|
||||
### المرحلة الثالثة: تحديث أدوات سطر الأوامر
|
||||
[ ] إضافة المعامل `--auth-token` إلى `set_mcp_tool.py`
|
||||
[ ] تضمين رمز المصادقة في ملف تكوين JSON
|
||||
[ ] إضافة عمود "المصادقة" إلى إخراج `show_mcp_tools.py`
|
||||
[ ] اختبار تغييرات أداة سطر الأوامر
|
||||
|
||||
### المرحلة الرابعة: تحديث التوثيق
|
||||
[ ] توثيق المعامل `--auth-token` في `tg-set-mcp-tool.md`
|
||||
[ ] إضافة قسم للاعتبارات الأمنية
|
||||
[ ] تقديم مثال للاستخدام
|
||||
|
||||
### المرحلة الخامسة: الاختبار
|
||||
[ ] اختبار أن خدمة MCP تقرأ رمز المصادقة وتتصل بنجاح
|
||||
[ ] اختبار التوافق مع الإصدارات السابقة (الأدوات بدون رمز مصادقة لا تزال تعمل)
|
||||
[ ] اختبار أن أدوات سطر الأوامر تقبل وتخزن رمز المصادقة بشكل صحيح
|
||||
[ ] اختبار أن الأمر "عرض" يعرض حالة المصادقة بشكل صحيح
|
||||
|
||||
### ملخص التغييرات في التعليمات البرمجية
|
||||
| الملف | نوع التغيير | الأسطر | الوصف |
|
||||
|------|------------|-------|-------------|
|
||||
| `service.py` | تم التعديل | ~52-66 | إضافة قراءة رمز المصادقة وإنشاء الرؤوس |
|
||||
| `set_mcp_tool.py` | تم التعديل | ~30-60 | إضافة وسيطة --auth-token وتخزين التكوين |
|
||||
| `show_mcp_tools.py` | تم التعديل | ~40-70 | إضافة عمود المصادقة للعرض |
|
||||
| `tg-set-mcp-tool.md` | تم التعديل | متنوع | توثيق المعامل الجديد |
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبارات الوحدة
|
||||
**قراءة رمز المصادقة**: اختبار ما إذا كانت `invoke_tool()` تقرأ رمز المصادقة بشكل صحيح من التكوين
|
||||
**إنشاء الرؤوس**: اختبار ما إذا كان يتم إنشاء رأس التفويض بشكل صحيح مع البادئة "Bearer"
|
||||
**التوافق مع الإصدارات السابقة**: اختبار ما إذا كانت الأدوات بدون رمز مصادقة تعمل دون تغيير
|
||||
**تحليل وسيطات سطر الأوامر**: اختبار ما إذا كانت المعامل `--auth-token` يتم تحليلها بشكل صحيح
|
||||
|
||||
### اختبارات التكامل
|
||||
**الاتصال المصادق**: اختبار ما إذا كانت خدمة MCP تتصل بخادم مصادق عليه
|
||||
**نهاية إلى نهاية**: اختبار تدفق سطر الأوامر → تخزين التكوين → استدعاء الخدمة باستخدام رمز المصادقة
|
||||
**غير مطلوب رمز المصادقة**: اختبار الاتصال بخادم غير مصادق عليه لا يزال يعمل
|
||||
|
||||
### الاختبار اليدوي
|
||||
**خادم MCP حقيقي**: اختبار مع خادم MCP فعلي يتطلب مصادقة باستخدام رمز "Bearer"
|
||||
**تدفق سطر الأوامر**: اختبار التدفق الكامل: تعيين الأداة باستخدام رمز مصادقة → استدعاء الأداة → التحقق من النجاح
|
||||
**إخفاء العرض**: التحقق من أن حالة المصادقة معروضة ولكن قيمة الرمز غير معروضة
|
||||
|
||||
## الترحيل والنشر
|
||||
|
||||
### استراتيجية الترحيل
|
||||
لا يلزم الترحيل - هذه وظيفة إضافية بحتة:
|
||||
تكوينات أدوات MCP الحالية بدون `auth-token` تستمر في العمل دون تغيير
|
||||
يمكن أن تتضمن التكوينات الجديدة اختياريًا حقل `auth-token`
|
||||
تقبل أدوات سطر الأوامر ولكن لا تتطلب المعامل `--auth-token`
|
||||
|
||||
### خطة النشر
|
||||
1. **المرحلة 1**: نشر تغييرات الخدمة الأساسية إلى التطوير/التجريب
|
||||
2. **المرحلة 2**: نشر تحديثات أدوات سطر الأوامر
|
||||
3. **المرحلة 3**: تحديث التوثيق
|
||||
4. **المرحلة 4**: النشر في بيئة الإنتاج مع المراقبة
|
||||
|
||||
### خطة التراجع
|
||||
التغييرات الأساسية متوافقة مع الإصدارات السابقة - لا تتأثر الأدوات الحالية
|
||||
في حالة ظهور مشكلات، يمكن تعطيل معالجة رمز المصادقة عن طريق إزالة منطق إنشاء الرأس
|
||||
يمكن التراجع عن تغييرات سطر الأوامر بشكل مستقل
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
### ⚠️ قيد حاسم: مصادقة المستأجر الواحد فقط
|
||||
|
||||
**هذه آلية المصادقة غير مناسبة للبيئات متعددة المستخدمين أو متعددة المستأجرين.**
|
||||
|
||||
**بيانات اعتماد مشتركة**: جميع المستخدمين والاستدعاءات يشاركون نفس الرمز لكل أداة MCP
|
||||
**لا يوجد سياق مستخدم**: لا يمكن لخادم MCP التمييز بين مستخدمي TrustGraph المختلفين
|
||||
**عزل المستأجر**: تشارك جميع المستأجرين نفس الاعتماد لكل أداة MCP
|
||||
**قيود سجل التدقيق**: يسجل خادم MCP جميع الطلبات من نفس الاعتماد
|
||||
**نطاق الأذونات**: لا يمكن فرض مستويات أذونات مختلفة لمستخدمين مختلفين
|
||||
|
||||
**لا تستخدم هذه الميزة إذا:**
|
||||
يخدم توزيعة TrustGraph الخاصة بك مؤسسات متعددة (متعددة المستأجرين)
|
||||
تحتاج إلى تتبع المستخدم الذي قام بالوصول إلى أداة MCP
|
||||
تتطلب مستخدمون مختلفون مستويات أذونات مختلفة
|
||||
تحتاج إلى الامتثال لمتطلبات التدقيق على مستوى المستخدم
|
||||
خادم MCP الخاص بك يفرض حدود معدل أو حصص لكل مستخدم
|
||||
|
||||
**حلول بديلة لسيناريوهات المستخدمين المتعددين/العملاء المتعددين:**
|
||||
تنفيذ نشر سياق المستخدم من خلال رؤوس مخصصة
|
||||
نشر مثيلات TrustGraph منفصلة لكل عميل
|
||||
استخدام عزل على مستوى الشبكة (VPCs، شبكات الخدمات)
|
||||
تنفيذ طبقة وكيل تتعامل مع المصادقة لكل مستخدم
|
||||
|
||||
### تخزين الرموز المميزة
|
||||
**مخاطر**: يتم تخزين الرموز المميزة للمصادقة كنص عادي في نظام التكوين
|
||||
|
||||
**تدابير تخفيفية**:
|
||||
توثيق أن الرموز المميزة مخزنة بدون تشفير
|
||||
يوصى باستخدام الرموز المميزة قصيرة الأجل كلما أمكن ذلك
|
||||
يوصى بتطبيق ضوابط وصول مناسبة على تخزين التكوين
|
||||
ضع في اعتبارك تحسينًا مستقبليًا لتخزين الرموز المميزة المشفرة
|
||||
|
||||
### كشف الرموز المميزة
|
||||
**مخاطر**: يمكن الكشف عن الرموز المميزة في سجلات أو مخرجات سطر الأوامر
|
||||
|
||||
**تدابير تخفيفية**:
|
||||
لا تقم بتسجيل قيم الرموز المميزة (قم بتسجيل "تم تكوين المصادقة: نعم/لا" فقط)
|
||||
يعرض أمر "show" الخاص بسطر الأوامر الحالة "مخفية" فقط، وليس الرمز المميز الفعلي
|
||||
لا تقم بتضمين الرموز المميزة في رسائل الخطأ
|
||||
|
||||
### أمان الشبكة
|
||||
**مخاطر**: يتم نقل الرموز المميزة عبر اتصالات غير مشفرة
|
||||
|
||||
**تدابير تخفيفية**:
|
||||
يوصى بتوثيق استخدام عناوين URL لبروتوكول HTTPS لخوادم MCP
|
||||
تحذير المستخدمين بشأن مخاطر النقل النصي باستخدام HTTP
|
||||
|
||||
### الوصول إلى التكوين
|
||||
**مخاطر**: يؤدي الوصول غير المصرح به إلى نظام التكوين إلى كشف الرموز المميزة
|
||||
|
||||
**تدابير تخفيفية**:
|
||||
قم بتوثيق أهمية تأمين الوصول إلى نظام التكوين
|
||||
يوصى بمبدأ الامتياز الأقل للوصول إلى التكوين
|
||||
ضع في اعتبارك تسجيل التدقيق للتغييرات في التكوين (تحسين مستقبلي)
|
||||
|
||||
### بيئات المستخدمين المتعددين
|
||||
**مخاطر**: في عمليات النشر متعددة المستخدمين، يشارك جميع المستخدمين نفس بيانات اعتماد MCP
|
||||
|
||||
**فهم المخاطر**:
|
||||
يستخدم كل من المستخدم أ والمستخدم ب نفس الرمز المميز عند الوصول إلى أداة MCP
|
||||
لا يمكن لخادم MCP التمييز بين مستخدمي TrustGraph المختلفين
|
||||
لا توجد طريقة لفرض أذونات أو حدود معدل لكل مستخدم
|
||||
تُظهر سجلات التدقيق على خادم MCP جميع الطلبات من نفس الاعتماد
|
||||
إذا تم اختراق جلسة مستخدم واحد، يتمتع المهاجم بنفس وصول MCP مثل جميع المستخدمين
|
||||
|
||||
**هذا ليس خطأ - إنه قيد أساسي لهذا التصميم.**
|
||||
|
||||
## التأثير على الأداء
|
||||
**نفقات عامة ضئيلة**: يضيف بناء الرأس وقت معالجة ضئيل
|
||||
**تأثير الشبكة**: يضيف رأس HTTP إضافي ~ 50-200 بايت لكل طلب
|
||||
**استخدام الذاكرة**: زيادة طفيفة لتخزين سلسلة الرمز المميز في التكوين
|
||||
|
||||
## التوثيق
|
||||
|
||||
### وثائق المستخدم
|
||||
[ ] قم بتحديث `tg-set-mcp-tool.md` باستخدام معلمة `--auth-token`
|
||||
[ ] أضف قسمًا للاعتبارات الأمنية
|
||||
[ ] قدم مثالًا للاستخدام باستخدام رمز مميز
|
||||
[ ] قم بتوثيق آثار تخزين الرمز المميز
|
||||
|
||||
### وثائق المطور
|
||||
[ ] أضف تعليقات مضمنة للتعامل مع الرمز المميز للمصادقة في `service.py`
|
||||
[ ] وثق منطق بناء الرأس
|
||||
[ ] قم بتحديث وثائق مخطط تكوين أداة MCP
|
||||
|
||||
## أسئلة مفتوحة
|
||||
1. **تشفير الرمز المميز**: هل يجب علينا تنفيذ تخزين مشفر للرموز المميزة في نظام التكوين؟
|
||||
2. **تحديث الرمز المميز**: دعم مستقبلي لتدفقات تحديث OAuth أو تدوير الرموز المميزة؟
|
||||
3. **طرق مصادقة بديلة**: هل يجب أن ندعم المصادقة الأساسية أو مفاتيح API أو طرق أخرى؟
|
||||
|
||||
## بدائل تم أخذها في الاعتبار
|
||||
|
||||
1. **متغيرات البيئة للرموز المميزة**: قم بتخزين الرموز المميزة في متغيرات البيئة بدلاً من التكوين
|
||||
**مرفوض**: يعقد النشر وإدارة التكوين
|
||||
|
||||
2. **مخزن أسرار منفصل**: استخدم نظام إدارة أسرار مخصص
|
||||
**مؤجل**: خارج نطاق التنفيذ الأولي، ضع في اعتبارك تحسينًا مستقبليًا
|
||||
|
||||
3. **طرق مصادقة متعددة**: دعم الأساسي و API key و OAuth وما إلى ذلك
|
||||
**مرفوض**: تغطي الرموز المميزة الخاصة بالحامل معظم حالات الاستخدام، حافظ على بساطة التنفيذ الأولي
|
||||
|
||||
4. **تخزين مشفر للرموز المميزة**: قم بتشفير الرموز المميزة في نظام التكوين
|
||||
**مؤجل**: يعد أمان نظام التكوين مصدر قلق أوسع، وتأجيله إلى عمل مستقبلي
|
||||
|
||||
5. **الرموز المميزة لكل استدعاء**: اسمح بتمرير الرموز المميزة في وقت الاستدعاء
|
||||
**مرفوض**: ينتهك فصل الاهتمامات، لا ينبغي للوكيل التعامل مع بيانات الاعتماد
|
||||
|
||||
## المراجع
|
||||
[مواصفات بروتوكول MCP](https://github.com/modelcontextprotocol/spec)
|
||||
[مصادقة حامل HTTP (RFC 6750)](https://tools.ietf.org/html/rfc6750)
|
||||
[خدمة أداة MCP الحالية](../trustgraph-flow/trustgraph/agent/mcp_tool/service.py)
|
||||
[مواصفات وسيطات أداة MCP](./mcp-tool-arguments.md)
|
||||
|
||||
## الملحق
|
||||
|
||||
### مثال للاستخدام
|
||||
|
||||
**إعداد أداة MCP مع المصادقة:**
|
||||
```bash
|
||||
tg-set-mcp-tool \
|
||||
--id secure-tool \
|
||||
--tool-url https://secure-server.example.com/mcp \
|
||||
--auth-token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
**عرض أدوات MCP:**
|
||||
```bash
|
||||
tg-show-mcp-tools
|
||||
|
||||
ID Remote Name URL Auth
|
||||
----------- ----------- ------------------------------------ ------
|
||||
secure-tool secure-tool https://secure-server.example.com/mcp Yes
|
||||
public-tool public-tool http://localhost:3000/mcp No
|
||||
```
|
||||
|
||||
### مثال على الإعدادات
|
||||
|
||||
**مخزنة في نظام الإعدادات:**
|
||||
```json
|
||||
{
|
||||
"type": "mcp",
|
||||
"key": "secure-tool",
|
||||
"value": "{\"url\": \"https://secure-server.example.com/mcp\", \"auth-token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"}"
|
||||
}
|
||||
```
|
||||
|
||||
### أفضل الممارسات الأمنية
|
||||
|
||||
1. **استخدام HTTPS**: استخدم دائمًا عناوين URL لبروتوكول HTTPS لخوادم MCP التي تتطلب مصادقة.
|
||||
2. **الرموز قصيرة الأجل**: استخدم الرموز التي لها تاريخ انتهاء صلاحية كلما أمكن ذلك.
|
||||
3. **أقل الامتيازات**: امنح الرموز الحد الأدنى من الأذونات المطلوبة.
|
||||
4. **التحكم في الوصول**: قم بتقييد الوصول إلى نظام التكوين.
|
||||
5. **تغيير الرموز بشكل دوري**: قم بتغيير الرموز بانتظام.
|
||||
6. **تسجيل التدقيق**: راقب تغييرات التكوين بحثًا عن أحداث أمنية.
|
||||
266
docs/tech-specs/ar/minio-to-s3-migration.ar.md
Normal file
266
docs/tech-specs/ar/minio-to-s3-migration.ar.md
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية: دعم تخزين متوافق مع S3"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية: دعم تخزين متوافق مع S3
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تستخدم خدمة Librarian تخزين كائنات متوافق مع S3 لتخزين ملفات المستندات. توثق هذه المواصفة التنفيذ الذي يمكّن الدعم لأي نظام تخزين متوافق مع S3 بما في ذلك MinIO و Ceph RADOS Gateway (RGW) و AWS S3 و Cloudflare R2 و DigitalOcean Spaces وغيرها.
|
||||
|
||||
## البنية
|
||||
|
||||
### مكونات التخزين
|
||||
**تخزين الكائنات (Blob Storage)**: تخزين كائنات متوافق مع S3 عبر مكتبة عميل Python `minio`
|
||||
**تخزين البيانات الوصفية (Metadata Storage)**: Cassandra (تخزن مطابقة object_id وبيانات وصفية للمستندات)
|
||||
**المكون المتأثر**: خدمة Librarian فقط
|
||||
**نمط التخزين**: تخزين هجين مع البيانات الوصفية في Cassandra والمحتوى في تخزين متوافق مع S3
|
||||
|
||||
### التنفيذ
|
||||
**المكتبة**: عميل Python `minio` (يدعم أي واجهة برمجة تطبيقات متوافقة مع S3)
|
||||
**الموقع**: `trustgraph-flow/trustgraph/librarian/blob_store.py`
|
||||
**العمليات**:
|
||||
`add()` - تخزين كائن بمعرف كائن UUID
|
||||
`get()` - استرجاع كائن بمعرف الكائن
|
||||
`remove()` - حذف كائن بمعرف الكائن
|
||||
`ensure_bucket()` - إنشاء حاوية إذا لم تكن موجودة
|
||||
**الحاوية (Bucket)**: `library`
|
||||
**مسار الكائن (Object Path)**: `doc/{object_id}`
|
||||
**أنواع MIME المدعومة**: `text/plain`، `application/pdf`
|
||||
|
||||
### الملفات الرئيسية
|
||||
1. `trustgraph-flow/trustgraph/librarian/blob_store.py` - تطبيق BlobStore
|
||||
2. `trustgraph-flow/trustgraph/librarian/librarian.py` - تهيئة BlobStore
|
||||
3. `trustgraph-flow/trustgraph/librarian/service.py` - تكوين الخدمة
|
||||
4. `trustgraph-flow/pyproject.toml` - التبعيات (حزمة `minio`)
|
||||
5. `docs/apis/api-librarian.md` - وثائق API
|
||||
|
||||
## أنظمة التخزين المدعومة
|
||||
|
||||
يعمل هذا التنفيذ مع أي نظام تخزين كائنات متوافق مع S3:
|
||||
|
||||
### تم الاختبار/مدعوم
|
||||
**Ceph RADOS Gateway (RGW)** - نظام تخزين موزع مع واجهة برمجة تطبيقات S3 (التكوين الافتراضي)
|
||||
**MinIO** - تخزين كائنات خفيف الوزن ومستضاف ذاتيًا
|
||||
**Garage** - تخزين S3 متوافق وخفيف الوزن وموزع جغرافيًا
|
||||
|
||||
### يجب أن يعمل (متوافق مع S3)
|
||||
**AWS S3** - تخزين الكائنات السحابي من Amazon
|
||||
**Cloudflare R2** - تخزين S3 متوافق من Cloudflare
|
||||
**DigitalOcean Spaces** - تخزين الكائنات من DigitalOcean
|
||||
**Wasabi** - تخزين سحابي متوافق مع S3
|
||||
**Backblaze B2** - تخزين نسخ احتياطي متوافق مع S3
|
||||
أي خدمة أخرى تنفذ واجهة برمجة تطبيقات S3 REST
|
||||
|
||||
## التكوين
|
||||
|
||||
### وسائط سطر الأوامر
|
||||
|
||||
```bash
|
||||
librarian \
|
||||
--object-store-endpoint <hostname:port> \
|
||||
--object-store-access-key <access_key> \
|
||||
--object-store-secret-key <secret_key> \
|
||||
[--object-store-use-ssl] \
|
||||
[--object-store-region <region>]
|
||||
```
|
||||
|
||||
**ملاحظة:** لا تقم بتضمين `http://` أو `https://` في النهاية. استخدم `--object-store-use-ssl` لتمكين HTTPS.
|
||||
|
||||
### متغيرات البيئة (بديل)
|
||||
|
||||
```bash
|
||||
OBJECT_STORE_ENDPOINT=<hostname:port>
|
||||
OBJECT_STORE_ACCESS_KEY=<access_key>
|
||||
OBJECT_STORE_SECRET_KEY=<secret_key>
|
||||
OBJECT_STORE_USE_SSL=true|false # Optional, default: false
|
||||
OBJECT_STORE_REGION=<region> # Optional
|
||||
```
|
||||
|
||||
### أمثلة
|
||||
|
||||
**بوابة Ceph RADOS (افتراضيًا):**
|
||||
```bash
|
||||
--object-store-endpoint ceph-rgw:7480 \
|
||||
--object-store-access-key object-user \
|
||||
--object-store-secret-key object-password
|
||||
```
|
||||
|
||||
**مينيو:**
|
||||
```bash
|
||||
--object-store-endpoint minio:9000 \
|
||||
--object-store-access-key minioadmin \
|
||||
--object-store-secret-key minioadmin
|
||||
```
|
||||
|
||||
**مخزن (متوافق مع S3):**
|
||||
```bash
|
||||
--object-store-endpoint garage:3900 \
|
||||
--object-store-access-key GK000000000000000000000001 \
|
||||
--object-store-secret-key b171f00be9be4c32c734f4c05fe64c527a8ab5eb823b376cfa8c2531f70fc427
|
||||
```
|
||||
|
||||
**AWS S3 مع SSL:**
|
||||
```bash
|
||||
--object-store-endpoint s3.amazonaws.com \
|
||||
--object-store-access-key AKIAIOSFODNN7EXAMPLE \
|
||||
--object-store-secret-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
|
||||
--object-store-use-ssl \
|
||||
--object-store-region us-east-1
|
||||
```
|
||||
|
||||
## المصادقة
|
||||
|
||||
تتطلب جميع الواجهات الخلفية المتوافقة مع S3 مصادقة AWS Signature Version 4 (أو الإصدار 2):
|
||||
|
||||
**مفتاح الوصول (Access Key)** - مُعرّف عام (مثل اسم المستخدم)
|
||||
**المفتاح السري (Secret Key)** - مفتاح توقيع خاص (مثل كلمة المرور)
|
||||
|
||||
يتعامل عميل MinIO بلغة Python مع جميع عمليات حساب التوقيع تلقائيًا.
|
||||
|
||||
### إنشاء بيانات الاعتماد
|
||||
|
||||
**لـ MinIO:**
|
||||
```bash
|
||||
# Use default credentials or create user via MinIO Console
|
||||
minioadmin / minioadmin
|
||||
```
|
||||
|
||||
**لـ Ceph RGW:**
|
||||
```bash
|
||||
radosgw-admin user create --uid="trustgraph" --display-name="TrustGraph Service"
|
||||
# Returns access_key and secret_key
|
||||
```
|
||||
|
||||
**لـ AWS S3:**
|
||||
إنشاء مستخدم IAM مع أذونات S3.
|
||||
إنشاء مفتاح وصول في وحدة تحكم AWS.
|
||||
|
||||
## اختيار المكتبة: عميل MinIO Python
|
||||
|
||||
**السبب:**
|
||||
خفيف الوزن (~500 كيلوبايت مقابل ~50 ميجابايت لـ boto3).
|
||||
متوافق مع S3 - يعمل مع أي نقطة نهاية S3.
|
||||
واجهة برمجة تطبيقات أبسط من boto3 للعمليات الأساسية.
|
||||
قيد الاستخدام بالفعل، لا حاجة إلى ترحيل.
|
||||
تم اختباره بشكل مكثف مع MinIO وأنظمة S3 الأخرى.
|
||||
|
||||
## تنفيذ BlobStore
|
||||
|
||||
**الموقع:** `trustgraph-flow/trustgraph/librarian/blob_store.py`
|
||||
|
||||
```python
|
||||
from minio import Minio
|
||||
import io
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BlobStore:
|
||||
"""
|
||||
S3-compatible blob storage for document content.
|
||||
Supports MinIO, Ceph RGW, AWS S3, and other S3-compatible backends.
|
||||
"""
|
||||
|
||||
def __init__(self, endpoint, access_key, secret_key, bucket_name,
|
||||
use_ssl=False, region=None):
|
||||
"""
|
||||
Initialize S3-compatible blob storage.
|
||||
|
||||
Args:
|
||||
endpoint: S3 endpoint (e.g., "minio:9000", "ceph-rgw:7480")
|
||||
access_key: S3 access key
|
||||
secret_key: S3 secret key
|
||||
bucket_name: Bucket name for storage
|
||||
use_ssl: Use HTTPS instead of HTTP (default: False)
|
||||
region: S3 region (optional, e.g., "us-east-1")
|
||||
"""
|
||||
self.client = Minio(
|
||||
endpoint=endpoint,
|
||||
access_key=access_key,
|
||||
secret_key=secret_key,
|
||||
secure=use_ssl,
|
||||
region=region,
|
||||
)
|
||||
|
||||
self.bucket_name = bucket_name
|
||||
|
||||
protocol = "https" if use_ssl else "http"
|
||||
logger.info(f"Connected to S3-compatible storage at {protocol}://{endpoint}")
|
||||
|
||||
self.ensure_bucket()
|
||||
|
||||
def ensure_bucket(self):
|
||||
"""Create bucket if it doesn't exist"""
|
||||
found = self.client.bucket_exists(bucket_name=self.bucket_name)
|
||||
if not found:
|
||||
self.client.make_bucket(bucket_name=self.bucket_name)
|
||||
logger.info(f"Created bucket {self.bucket_name}")
|
||||
else:
|
||||
logger.debug(f"Bucket {self.bucket_name} already exists")
|
||||
|
||||
async def add(self, object_id, blob, kind):
|
||||
"""Store blob in S3-compatible storage"""
|
||||
self.client.put_object(
|
||||
bucket_name=self.bucket_name,
|
||||
object_name=f"doc/{object_id}",
|
||||
length=len(blob),
|
||||
data=io.BytesIO(blob),
|
||||
content_type=kind,
|
||||
)
|
||||
logger.debug("Add blob complete")
|
||||
|
||||
async def remove(self, object_id):
|
||||
"""Delete blob from S3-compatible storage"""
|
||||
self.client.remove_object(
|
||||
bucket_name=self.bucket_name,
|
||||
object_name=f"doc/{object_id}",
|
||||
)
|
||||
logger.debug("Remove blob complete")
|
||||
|
||||
async def get(self, object_id):
|
||||
"""Retrieve blob from S3-compatible storage"""
|
||||
resp = self.client.get_object(
|
||||
bucket_name=self.bucket_name,
|
||||
object_name=f"doc/{object_id}",
|
||||
)
|
||||
return resp.read()
|
||||
```
|
||||
|
||||
## الفوائد الرئيسية
|
||||
|
||||
1. **لا يوجد اعتماد على مورد واحد** - يعمل مع أي تخزين متوافق مع S3.
|
||||
2. **خفيف الوزن** - حجم عميل MinIO يبلغ حوالي 500 كيلوبايت فقط.
|
||||
3. **تكوين بسيط** - يتطلب فقط نقطة النهاية وبيانات الاعتماد.
|
||||
4. **لا حاجة لنقل البيانات** - بديل مباشر بين الأنظمة الخلفية.
|
||||
5. **تم اختباره ميدانيًا** - يعمل عميل MinIO مع جميع تطبيقات S3 الرئيسية.
|
||||
|
||||
## حالة التنفيذ
|
||||
|
||||
تم تحديث جميع التعليمات البرمجية لاستخدام أسماء معلمات S3 العامة:
|
||||
|
||||
✅ `blob_store.py` - تم التحديث لقبول `endpoint`، `access_key`، `secret_key`.
|
||||
✅ `librarian.py` - تم تحديث أسماء المعلمات.
|
||||
✅ `service.py` - تم تحديث وسيطات سطر الأوامر والتكوين.
|
||||
✅ تم تحديث الوثائق.
|
||||
|
||||
## التحسينات المستقبلية
|
||||
|
||||
1. **دعم SSL/TLS** - إضافة علامة `--s3-use-ssl` لـ HTTPS.
|
||||
2. **منطق إعادة المحاولة** - تطبيق تأخير أُسي للأخطاء العابرة.
|
||||
3. **عناوين URL مؤقتة** - إنشاء عناوين URL مؤقتة للتحميل/التنزيل.
|
||||
4. **دعم متعدد المناطق** - تكرار الكائنات عبر المناطق.
|
||||
5. **تكامل CDN** - تقديم الكائنات عبر CDN.
|
||||
6. **فئات التخزين** - استخدام فئات تخزين S3 لتحسين التكلفة.
|
||||
7. **سياسات دورة الحياة** - الأرشفة/الحذف التلقائي.
|
||||
8. **التحكم في الإصدار** - تخزين إصدارات متعددة من الكائنات.
|
||||
|
||||
## المراجع
|
||||
|
||||
عميل MinIO Python: https://min.io/docs/minio/linux/developers/python/API.html
|
||||
واجهة برمجة تطبيقات Ceph RGW S3: https://docs.ceph.com/en/latest/radosgw/s3/
|
||||
مرجع واجهة برمجة تطبيقات S3: https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html
|
||||
159
docs/tech-specs/ar/more-config-cli.ar.md
Normal file
159
docs/tech-specs/ar/more-config-cli.ar.md
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات فنية لسطر الأوامر لتكوين"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات فنية لسطر الأوامر لتكوين
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات قدرات التكوين المتقدمة لسطر الأوامر لـ TrustGraph، مما يمكّن المستخدمين من إدارة عناصر التكوين الفردية من خلال أوامر سطر الأوامر التفصيلية. يدعم التكامل أربعة حالات استخدام رئيسية:
|
||||
|
||||
1. **قائمة عناصر التكوين**: عرض مفاتيح التكوين لنوع معين
|
||||
2. **الحصول على عنصر التكوين**: استرداد قيم التكوين المحددة
|
||||
3. **تطبيق عنصر التكوين**: تعيين أو تحديث عناصر التكوين الفردية
|
||||
4. **حذف عنصر التكوين**: إزالة عناصر التكوين المحددة
|
||||
|
||||
## الأهداف
|
||||
|
||||
* **التحكم التفصيلي**: تمكين إدارة عناصر التكوين الفردية بدلاً من العمليات المجمعة
|
||||
* **قائمة بناءً على النوع**: السماح للمستخدمين باستكشاف عناصر التكوين حسب النوع
|
||||
* **عمليات عنصر واحد**: توفير أوامر للحصول على/تطبيق/حذف عناصر التكوين الفردية
|
||||
* **تكامل API**: الاستفادة من واجهة API الحالية للتكوين لجميع العمليات
|
||||
* **نمط سطر أوامر متسق**: اتباع قواعد TrustGraph CLI الراسخة وأنماطها
|
||||
* **معالجة الأخطاء**: توفير رسائل خطأ واضحة لعمليات غير صالحة
|
||||
* **إخراج JSON**: دعم الإخراج المنظم للاستخدام البرمجي
|
||||
* **التوثيق**: تضمين مساعدة شاملة وأمثلة للاستخدام
|
||||
|
||||
## الخلفية
|
||||
|
||||
يوفر TrustGraph حاليًا إدارة التكوين من خلال واجهة API للتكوين وأمر سطر أوامر واحد `tg-show-config` الذي يعرض التكوين بأكمله. على الرغم من أن هذا يعمل في عرض التكوين، إلا أنه يفتقر إلى قدرات الإدارة التفصيلية.
|
||||
|
||||
تشمل القيود الحالية ما يلي:
|
||||
* لا توجد طريقة لقائمة عناصر التكوين حسب النوع من سطر الأوامر
|
||||
* لا يوجد أمر سطر أوامر لاسترداد قيم التكوين المحددة
|
||||
* لا يوجد أمر سطر أوامر لتعيين عناصر التكوين الفردية
|
||||
* لا يوجد أمر سطر أوامر لحذف عناصر التكوين المحددة
|
||||
|
||||
تتعالج هذه المواصفات هذه الثغرات من خلال إضافة أربعة أوامر سطر أوامر جديدة التي توفر إدارة التكوين التفصيلية. من خلال الكشف عن عمليات واجهة API للتكوين الفردية من خلال أوامر سطر الأوامر، يمكن لـ TrustGraph:
|
||||
* تمكين إدارة التكوين المبرمجة
|
||||
* السماح باستكشاف هيكل التكوين حسب النوع
|
||||
* دعم تحديثات التكوين المستهدفة
|
||||
* توفير تحكم دقيق في التكوين
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### الهندسة المعمارية
|
||||
|
||||
يتطلب التكوين المتقدم لسطر الأوامر المكونات الفنية التالية:
|
||||
|
||||
1. **tg-list-config-items**
|
||||
* قائمة مفاتيح التكوين لنوع معين
|
||||
* استدعاء طريقة واجهة API `Config.list(type)`
|
||||
* إخراج قائمة بمفاتيح التكوين
|
||||
|
||||
وحدة: `trustgraph.cli.list_config_items`
|
||||
|
||||
2. **tg-get-config-item**
|
||||
* استرداد عنصر تكوين معين(أو أكثر)
|
||||
* استدعاء طريقة واجهة API `Config.get([ConfigKey(type, key)])`
|
||||
* إخراج قيم التكوين بتنسيق JSON
|
||||
|
||||
وحدة: `trustgraph.cli.get_config_item`
|
||||
|
||||
3. **tg-put-config-item**
|
||||
* تعيين أو تحديث عنصر تكوين
|
||||
* استدعاء طريقة واجهة API `Config.put([ConfigValue(type, key, value)])`
|
||||
* قبول معلمات النوع والمفتاح والقيمة
|
||||
|
||||
وحدة: `trustgraph.cli.put_config_item`
|
||||
|
||||
4. **tg-delete-config-item**
|
||||
* إزالة عنصر تكوين
|
||||
* استدعاء طريقة واجهة API `Config.delete([ConfigKey(type, key)])`
|
||||
* قبول معلمات النوع والمفتاح
|
||||
|
||||
وحدة: `trustgraph.cli.delete_config_item`
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### ConfigKey و ConfigValue
|
||||
|
||||
تستخدم الأوامر هياكل البيانات الموجودة من `trustgraph.api.types`:
|
||||
|
||||
```python
|
||||
@dataclasses.dataclass
|
||||
class ConfigKey:
|
||||
type : str
|
||||
key : str
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigValue:
|
||||
type : str
|
||||
key : str
|
||||
value : str
|
||||
```
|
||||
|
||||
يسمح هذا النهج بما يلي:
|
||||
* معالجة متسقة للبيانات عبر سطر الأوامر وواجهة API
|
||||
* عمليات تكوين آمنة من النوع
|
||||
* تنسيقات إدخال/إخراج منظمة
|
||||
* التكامل مع واجهة API للتكوين الحالية
|
||||
|
||||
### مواصفات سطر الأوامر
|
||||
|
||||
#### tg-list-config-items
|
||||
```bash
|
||||
tg-list-config-items --type <config-type> [--format text|json] [--api-url <url>]
|
||||
```
|
||||
* **الغرض**: قائمة بمفاتيح التكوين لنمط معين
|
||||
* **استدعاء واجهة API**: `Config.list(type)`
|
||||
* **الإخراج**:
|
||||
* `text` (افتراضي): مفاتيح التكوين مفصولة بأسطر جديدة
|
||||
* `json`: مصفوفة JSON من مفاتيح التكوين
|
||||
|
||||
#### tg-get-config-item
|
||||
```bash
|
||||
tg-get-config-item --type <type> --key <key> [--format text|json] [--api-url <url>]
|
||||
```
|
||||
* **الغرض**: استرداد عنصر التكوين المحدد
|
||||
* **استدعاء واجهة API**: `Config.get([ConfigKey(type, key)])`
|
||||
* **الإخراج**:
|
||||
* `text` (افتراضي): سلسلة خام
|
||||
* `json`: سلسلة JSON منقذة
|
||||
|
||||
#### tg-put-config-item
|
||||
```bash
|
||||
tg-put-config-item --type <type> --key <key> --value <value> [--api-url <url>]
|
||||
tg-put-config-item --type <type> --key <key> --stdin [--api-url <url>]
|
||||
```
|
||||
* **الغرض**: تعيين أو تحديث عنصر التكوين
|
||||
* **استدعاء واجهة API**: `Config.put([ConfigValue(type, key, value)])`
|
||||
* **خيارات الإدخال**:
|
||||
* `--value <value>`: قيمة
|
||||
* `--stdin`: إدخال من stdin
|
||||
* `--key <key>`: المفتاح
|
||||
* `--type <type>`: النوع
|
||||
|
||||
#### tg-delete-config-item
|
||||
```bash
|
||||
tg-delete-config-item --type <type> --key <key>
|
||||
```
|
||||
* **الغرض**: حذف عنصر التكوين
|
||||
* `--key <key>`: المفتاح
|
||||
* `--type <type>`: النوع
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
* هل يجب أن تدعم الأوامر عمليات دفعة (مفاتيح متعددة) بالإضافة إلى العناصر الفردية؟
|
||||
* ما هو تنسيق الإخراج الذي يجب استخدامه لإعادة التأكيد على النجاح؟
|
||||
* كيف يجب توثيق/اكتشاف أنواع التكوين للمستخدمين؟
|
||||
|
||||
## المراجع
|
||||
|
||||
* واجهة API للتكوين: `trustgraph/api/config.py`
|
||||
* أنماط سطر الأوامر: `trustgraph-cli/trustgraph/cli/show_config.py`
|
||||
* أنواع البيانات: `trustgraph/api/types.py`
|
||||
780
docs/tech-specs/ar/multi-tenant-support.ar.md
Normal file
780
docs/tech-specs/ar/multi-tenant-support.ar.md
Normal file
|
|
@ -0,0 +1,780 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية: دعم البيئات متعددة المستأجرين"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية: دعم البيئات متعددة المستأجرين
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تمكين عمليات النشر متعددة المستأجرين عن طريق إصلاح عدم تطابق أسماء المعلمات التي تمنع تخصيص قائمة الانتظار وإضافة معلمات مساحة مفاتيح Cassandra.
|
||||
|
||||
## سياق البنية
|
||||
|
||||
### حل قائمة الانتظار القائم على التدفق
|
||||
|
||||
يستخدم نظام TrustGraph بنية **قائمة انتظار قائمة على التدفق** لحل ديناميكي لقوائم الانتظار، والتي تدعم بشكل طبيعي البيئات متعددة المستأجرين:
|
||||
|
||||
يتم تخزين **تعريفات التدفق** في Cassandra وتحدد أسماء قوائم الانتظار عبر تعريفات الواجهة.
|
||||
**تستخدم أسماء قوائم الانتظار قوالب** مع متغيرات `{id}` يتم استبدالها بمعرفات مثيلات التدفق.
|
||||
**تقوم الخدمات بحل قوائم الانتظار ديناميكيًا** عن طريق البحث عن تكوينات التدفق في وقت الطلب.
|
||||
**يمكن لكل مستأجر أن يكون لديه تدفقات فريدة** بأسماء قوائم انتظار مختلفة، مما يوفر عزلًا.
|
||||
|
||||
مثال لتعريف واجهة التدفق:
|
||||
```json
|
||||
{
|
||||
"interfaces": {
|
||||
"triples-store": "persistent://tg/flow/triples-store:{id}",
|
||||
"graph-embeddings-store": "persistent://tg/flow/graph-embeddings-store:{id}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
عندما يبدأ المستأجر أ سير العمل `tenant-a-prod` ويبدأ المستأجر ب سير العمل `tenant-b-prod`، فإنهم يحصلون تلقائيًا على قوائم انتظار معزولة:
|
||||
`persistent://tg/flow/triples-store:tenant-a-prod`
|
||||
`persistent://tg/flow/triples-store:tenant-b-prod`
|
||||
|
||||
**الخدمات المصممة بشكل صحيح لدعم تعدد المستأجرين:**
|
||||
✅ **إدارة المعرفة (الأساسيات)** - تحل ديناميكيًا قوائم الانتظار من تكوين سير العمل الذي يتم تمريره في الطلبات.
|
||||
|
||||
**الخدمات التي تحتاج إلى إصلاحات:**
|
||||
🔴 **خدمة التكوين** - عدم تطابق اسم المعلمة يمنع تخصيص قائمة الانتظار.
|
||||
🔴 **خدمة أمين المكتبة** - مواضيع إدارة التخزين المبرمجة بشكل ثابت (موضحة أدناه).
|
||||
🔴 **جميع الخدمات** - لا يمكن تخصيص مساحة مفتاح Cassandra.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
### المشكلة رقم 1: عدم تطابق اسم المعلمة في AsyncProcessor
|
||||
**يعرف سطر الأوامر:** `--config-queue` (تسمية غير واضحة)
|
||||
**يقوم Argparse بتحويلها إلى:** `config_queue` (في قاموس المعلمات)
|
||||
**يبحث الكود عن:** `config_push_queue`
|
||||
**النتيجة:** يتم تجاهل المعلمة، وتعود إلى القيمة الافتراضية `persistent://tg/config/config`.
|
||||
**التأثير:** يؤثر على أكثر من 32 خدمة ترث من AsyncProcessor.
|
||||
**يمنع:** لا يمكن لنشر تعدد المستأجرين استخدام قوائم انتظار تكوين خاصة بالمستأجر.
|
||||
**الحل:** إعادة تسمية معلمة سطر الأوامر إلى `--config-push-queue` من أجل الوضوح (تغيير كاسر مقبول نظرًا لأن الميزة معطلة حاليًا).
|
||||
|
||||
### المشكلة رقم 2: عدم تطابق اسم المعلمة في خدمة التكوين
|
||||
**يعرف سطر الأوامر:** `--push-queue` (تسمية غامضة)
|
||||
**يقوم Argparse بتحويلها إلى:** `push_queue` (في قاموس المعلمات)
|
||||
**يبحث الكود عن:** `config_push_queue`
|
||||
**النتيجة:** يتم تجاهل المعلمة.
|
||||
**التأثير:** لا يمكن لخدمة التكوين استخدام قائمة انتظار دفع مخصصة.
|
||||
**الحل:** إعادة تسمية معلمة سطر الأوامر إلى `--config-push-queue` من أجل الاتساق والوضوح (تغيير كاسر مقبول).
|
||||
|
||||
### المشكلة رقم 3: مساحة مفتاح Cassandra مبرمجة بشكل ثابت
|
||||
**الحالي:** مساحة المفتاح مبرمجة بشكل ثابت كـ `"config"`، `"knowledge"`، `"librarian"` في خدمات مختلفة.
|
||||
**النتيجة:** لا يمكن تخصيص مساحة المفتاح لنشر تعدد المستأجرين.
|
||||
**التأثير:** خدمات التكوين والأساسيات وأمين المكتبة.
|
||||
**يمنع:** لا يمكن لعدة مستأجرين استخدام مساحات مفاتيح Cassandra منفصلة.
|
||||
|
||||
### المشكلة رقم 4: بنية إدارة المجموعات ✅ مكتمل
|
||||
**السابق:** تم تخزين المجموعات في مساحة مفاتيح Cassandra الخاصة بأمين المكتبة عبر جدول مجموعات منفصل.
|
||||
**السابق:** استخدم أمين المكتبة 4 مواضيع إدارة تخزين مبرمجة بشكل ثابت لتنسيق إنشاء/حذف المجموعة:
|
||||
`vector_storage_management_topic`
|
||||
`object_storage_management_topic`
|
||||
`triples_storage_management_topic`
|
||||
`storage_management_response_topic`
|
||||
**المشاكل (تم حلها):**
|
||||
لا يمكن تخصيص المواضيع المبرمجة بشكل ثابت لنشر تعدد المستأجرين.
|
||||
تنسيق غير متزامن معقد بين أمين المكتبة و 4+ خدمات تخزين.
|
||||
جدول منفصل وبنية تحتية لإدارة.
|
||||
قوائم انتظار طلب/استجابة غير دائمة للعمليات الهامة.
|
||||
**الحل المنفذ:** تم نقل المجموعات إلى تخزين خدمة التكوين، واستخدام دفع التكوين للتوزيع.
|
||||
**الحالة:** تم نقل جميع خلفيات التخزين إلى النمط `CollectionConfigHandler`.
|
||||
|
||||
## الحل
|
||||
|
||||
تعالج هذه المواصفات المشكلات رقم 1 و 2 و 3 و 4.
|
||||
|
||||
### الجزء الأول: إصلاح عدم تطابق اسم المعلمة
|
||||
|
||||
#### التغيير 1: فئة AsyncProcessor الأساسية - إعادة تسمية معلمة سطر الأوامر
|
||||
**الملف:** `trustgraph-base/trustgraph/base/async_processor.py`
|
||||
**السطر:** 260-264
|
||||
|
||||
**الحالي:**
|
||||
```python
|
||||
parser.add_argument(
|
||||
'--config-queue',
|
||||
default=default_config_queue,
|
||||
help=f'Config push queue {default_config_queue}',
|
||||
)
|
||||
```
|
||||
|
||||
**ثابت:**
|
||||
```python
|
||||
parser.add_argument(
|
||||
'--config-push-queue',
|
||||
default=default_config_queue,
|
||||
help=f'Config push queue (default: {default_config_queue})',
|
||||
)
|
||||
```
|
||||
|
||||
**السبب:**
|
||||
تسمية أوضح وأكثر تفصيلاً.
|
||||
تتطابق مع اسم المتغير الداخلي `config_push_queue`.
|
||||
التغيير قد يكون مؤثراً، ولكن هذا مقبول لأن الميزة غير فعالة حاليًا.
|
||||
لا حاجة لتغيير أي كود في `params.get()` - فهو يبحث بالفعل عن الاسم الصحيح.
|
||||
|
||||
#### التغيير الثاني: خدمة التكوين - إعادة تسمية معلمة سطر الأوامر
|
||||
**الملف:** `trustgraph-flow/trustgraph/config/service/service.py`
|
||||
**السطر:** 276-279
|
||||
|
||||
**الحالي:**
|
||||
```python
|
||||
parser.add_argument(
|
||||
'--push-queue',
|
||||
default=default_config_push_queue,
|
||||
help=f'Config push queue (default: {default_config_push_queue})'
|
||||
)
|
||||
```
|
||||
|
||||
**ثابت:**
|
||||
```python
|
||||
parser.add_argument(
|
||||
'--config-push-queue',
|
||||
default=default_config_push_queue,
|
||||
help=f'Config push queue (default: {default_config_push_queue})'
|
||||
)
|
||||
```
|
||||
|
||||
**السبب:**
|
||||
تسمية أوضح - "config-push-queue" أكثر وضوحًا من مجرد "push-queue".
|
||||
يتطابق مع اسم المتغير الداخلي `config_push_queue`.
|
||||
متسق مع معلمة `--config-push-queue` الخاصة بـ AsyncProcessor.
|
||||
التغيير غير المتوافق مقبول نظرًا لأن الميزة غير وظيفية حاليًا.
|
||||
لا حاجة لتغيير التعليمات البرمجية في params.get() - فهو يبحث بالفعل عن الاسم الصحيح.
|
||||
|
||||
### الجزء الثاني: إضافة معلمات مساحة مفاتيح Cassandra
|
||||
|
||||
#### التغيير الثالث: إضافة معلمة مساحة المفاتيح إلى وحدة cassandra_config
|
||||
**الملف:** `trustgraph-base/trustgraph/base/cassandra_config.py`
|
||||
|
||||
**إضافة وسيط سطر الأوامر** (في دالة `add_cassandra_args()`):
|
||||
```python
|
||||
parser.add_argument(
|
||||
'--cassandra-keyspace',
|
||||
default=None,
|
||||
help='Cassandra keyspace (default: service-specific)'
|
||||
)
|
||||
```
|
||||
|
||||
**إضافة دعم لمتغيرات البيئة** (في الدالة `resolve_cassandra_config()`):
|
||||
```python
|
||||
keyspace = params.get(
|
||||
"cassandra_keyspace",
|
||||
os.environ.get("CASSANDRA_KEYSPACE")
|
||||
)
|
||||
```
|
||||
|
||||
**تحديث قيمة الإرجاع** لـ `resolve_cassandra_config()`:
|
||||
حاليًا، تُرجع: `(hosts, username, password)`
|
||||
التغيير إلى إرجاع: `(hosts, username, password, keyspace)`
|
||||
|
||||
**السبب:**
|
||||
يتوافق مع نمط تكوين Cassandra الحالي
|
||||
متاح لجميع الخدمات عبر `add_cassandra_args()`
|
||||
يدعم كل من تكوين سطر الأوامر ومتغيرات البيئة
|
||||
|
||||
#### التغيير الرابع: خدمة التكوين - استخدام مفاتيح مساحة المفاتيح المعلمة
|
||||
**الملف:** `trustgraph-flow/trustgraph/config/service/service.py`
|
||||
|
||||
**السطر 30** - إزالة اسم مساحة المفاتيح الثابت:
|
||||
```python
|
||||
# DELETE THIS LINE:
|
||||
keyspace = "config"
|
||||
```
|
||||
|
||||
**السطور من 69 إلى 73** - تحديث آلية حل مشاكل إعدادات كاساندرا:
|
||||
|
||||
**الحالي:**
|
||||
```python
|
||||
cassandra_host, cassandra_username, cassandra_password = \
|
||||
resolve_cassandra_config(params)
|
||||
```
|
||||
|
||||
**ثابت:**
|
||||
```python
|
||||
cassandra_host, cassandra_username, cassandra_password, keyspace = \
|
||||
resolve_cassandra_config(params, default_keyspace="config")
|
||||
```
|
||||
|
||||
**السبب:**
|
||||
يحافظ على التوافق مع الإصدارات السابقة باستخدام "config" كإعداد افتراضي.
|
||||
يسمح بالتجاوز عبر `--cassandra-keyspace` أو `CASSANDRA_KEYSPACE`.
|
||||
|
||||
#### التغيير 5: الخدمات الأساسية/خدمة المعرفة - استخدام مفاتيح مساحة معلمات.
|
||||
**الملف:** `trustgraph-flow/trustgraph/cores/service.py`
|
||||
|
||||
**السطر 37** - إزالة مفتاح مساحة مُبرمج بشكل ثابت:
|
||||
```python
|
||||
# DELETE THIS LINE:
|
||||
keyspace = "knowledge"
|
||||
```
|
||||
|
||||
**تحديث آلية حل إعدادات كاساندرا** (في نفس الموقع مثل خدمة الإعدادات):
|
||||
```python
|
||||
cassandra_host, cassandra_username, cassandra_password, keyspace = \
|
||||
resolve_cassandra_config(params, default_keyspace="knowledge")
|
||||
```
|
||||
|
||||
#### التغيير 6: خدمة أمين المكتبة - استخدام مفاتيح مساحة معلمات.
|
||||
**الملف:** `trustgraph-flow/trustgraph/librarian/service.py`
|
||||
|
||||
**السطر 51** - إزالة اسم مساحة المفاتيح المبرمج بشكل ثابت:
|
||||
```python
|
||||
# DELETE THIS LINE:
|
||||
keyspace = "librarian"
|
||||
```
|
||||
|
||||
**تحديث آلية حل إعدادات Cassandra** (في نفس الموقع مثل خدمة الإعدادات):
|
||||
```python
|
||||
cassandra_host, cassandra_username, cassandra_password, keyspace = \
|
||||
resolve_cassandra_config(params, default_keyspace="librarian")
|
||||
```
|
||||
|
||||
### الجزء الثالث: ترحيل إدارة المجموعات إلى خدمة التكوين
|
||||
|
||||
#### نظرة عامة
|
||||
ترحيل المجموعات من مساحة مفاتيح Cassandra librarian إلى تخزين خدمة التكوين. هذا يلغي مواضيع إدارة التخزين المضمنة ويبسط البنية باستخدام آلية دفع التكوين الحالية للتوزيع.
|
||||
|
||||
#### البنية الحالية
|
||||
```
|
||||
API Request → Gateway → Librarian Service
|
||||
↓
|
||||
CollectionManager
|
||||
↓
|
||||
Cassandra Collections Table (librarian keyspace)
|
||||
↓
|
||||
Broadcast to 4 Storage Management Topics (hardcoded)
|
||||
↓
|
||||
Wait for 4+ Storage Service Responses
|
||||
↓
|
||||
Response to Gateway
|
||||
```
|
||||
|
||||
#### العمارة الجديدة
|
||||
```
|
||||
API Request → Gateway → Librarian Service
|
||||
↓
|
||||
CollectionManager
|
||||
↓
|
||||
Config Service API (put/delete/getvalues)
|
||||
↓
|
||||
Cassandra Config Table (class='collections', key='user:collection')
|
||||
↓
|
||||
Config Push (to all subscribers on config-push-queue)
|
||||
↓
|
||||
All Storage Services receive config update independently
|
||||
```
|
||||
|
||||
#### التغيير 7: مدير المجموعة - استخدام واجهة برمجة تطبيقات خدمة التكوين
|
||||
**الملف:** `trustgraph-flow/trustgraph/librarian/collection_manager.py`
|
||||
|
||||
**إزالة:**
|
||||
استخدام `LibraryTableStore` (الأسطر 33، 40-41)
|
||||
تهيئة منتجي إدارة التخزين (الأسطر 86-140)
|
||||
طريقة `on_storage_response` (الأسطر 400-430)
|
||||
تتبع `pending_deletions` (الأسطر 57، 90-96، والاستخدام في جميع أنحاء البرنامج)
|
||||
|
||||
**إضافة:**
|
||||
عميل خدمة التكوين لإجراء مكالمات واجهة برمجة التطبيقات (نمط الطلب/الاستجابة)
|
||||
|
||||
**إعداد عميل التكوين:**
|
||||
```python
|
||||
# In __init__, add config request/response producers/consumers
|
||||
from trustgraph.schema.services.config import ConfigRequest, ConfigResponse
|
||||
|
||||
# Producer for config requests
|
||||
self.config_request_producer = Producer(
|
||||
client=pulsar_client,
|
||||
topic=config_request_queue,
|
||||
schema=ConfigRequest,
|
||||
)
|
||||
|
||||
# Consumer for config responses (with correlation ID)
|
||||
self.config_response_consumer = Consumer(
|
||||
taskgroup=taskgroup,
|
||||
client=pulsar_client,
|
||||
flow=None,
|
||||
topic=config_response_queue,
|
||||
subscriber=f"{id}-config",
|
||||
schema=ConfigResponse,
|
||||
handler=self.on_config_response,
|
||||
)
|
||||
|
||||
# Tracking for pending config requests
|
||||
self.pending_config_requests = {} # request_id -> asyncio.Event
|
||||
```
|
||||
|
||||
**تعديل `list_collections` (الأسطر من 145 إلى 180):**
|
||||
```python
|
||||
async def list_collections(self, user, tag_filter=None, limit=None):
|
||||
"""List collections from config service"""
|
||||
# Send getvalues request to config service
|
||||
request = ConfigRequest(
|
||||
id=str(uuid.uuid4()),
|
||||
operation='getvalues',
|
||||
type='collections',
|
||||
)
|
||||
|
||||
# Send request and wait for response
|
||||
response = await self.send_config_request(request)
|
||||
|
||||
# Parse collections from response
|
||||
collections = []
|
||||
for key, value_json in response.values.items():
|
||||
if ":" in key:
|
||||
coll_user, collection = key.split(":", 1)
|
||||
if coll_user == user:
|
||||
metadata = json.loads(value_json)
|
||||
collections.append(CollectionMetadata(**metadata))
|
||||
|
||||
# Apply tag filtering in-memory (as before)
|
||||
if tag_filter:
|
||||
collections = [c for c in collections if any(tag in c.tags for tag in tag_filter)]
|
||||
|
||||
# Apply limit
|
||||
if limit:
|
||||
collections = collections[:limit]
|
||||
|
||||
return collections
|
||||
|
||||
async def send_config_request(self, request):
|
||||
"""Send config request and wait for response"""
|
||||
event = asyncio.Event()
|
||||
self.pending_config_requests[request.id] = event
|
||||
|
||||
await self.config_request_producer.send(request)
|
||||
await event.wait()
|
||||
|
||||
return self.pending_config_requests.pop(request.id + "_response")
|
||||
|
||||
async def on_config_response(self, message, consumer, flow):
|
||||
"""Handle config response"""
|
||||
response = message.value()
|
||||
if response.id in self.pending_config_requests:
|
||||
self.pending_config_requests[response.id + "_response"] = response
|
||||
self.pending_config_requests[response.id].set()
|
||||
```
|
||||
|
||||
**تعديل `update_collection` (الأسطر من 182 إلى 312):**
|
||||
```python
|
||||
async def update_collection(self, user, collection, name, description, tags):
|
||||
"""Update collection via config service"""
|
||||
# Create metadata
|
||||
metadata = CollectionMetadata(
|
||||
user=user,
|
||||
collection=collection,
|
||||
name=name,
|
||||
description=description,
|
||||
tags=tags,
|
||||
)
|
||||
|
||||
# Send put request to config service
|
||||
request = ConfigRequest(
|
||||
id=str(uuid.uuid4()),
|
||||
operation='put',
|
||||
type='collections',
|
||||
key=f'{user}:{collection}',
|
||||
value=json.dumps(metadata.to_dict()),
|
||||
)
|
||||
|
||||
response = await self.send_config_request(request)
|
||||
|
||||
if response.error:
|
||||
raise RuntimeError(f"Config update failed: {response.error.message}")
|
||||
|
||||
# Config service will trigger config push automatically
|
||||
# Storage services will receive update and create collections
|
||||
```
|
||||
|
||||
**تعديل `delete_collection` (الأسطر من 314 إلى 398):**
|
||||
```python
|
||||
async def delete_collection(self, user, collection):
|
||||
"""Delete collection via config service"""
|
||||
# Send delete request to config service
|
||||
request = ConfigRequest(
|
||||
id=str(uuid.uuid4()),
|
||||
operation='delete',
|
||||
type='collections',
|
||||
key=f'{user}:{collection}',
|
||||
)
|
||||
|
||||
response = await self.send_config_request(request)
|
||||
|
||||
if response.error:
|
||||
raise RuntimeError(f"Config delete failed: {response.error.message}")
|
||||
|
||||
# Config service will trigger config push automatically
|
||||
# Storage services will receive update and delete collections
|
||||
```
|
||||
|
||||
**تنسيق بيانات التعريف للمجموعة:**
|
||||
يتم تخزينها في جدول التكوين كـ: `class='collections', key='user:collection'`
|
||||
القيمة هي بيانات تعريف المجموعة (CollectionMetadata) مُسلسلة بصيغة JSON (بدون حقول الطابع الزمني)
|
||||
الحقول: `user`، `collection`، `name`، `description`، `tags`
|
||||
مثال: `class='collections', key='alice:my-docs', value='{"user":"alice","collection":"my-docs","name":"My Documents","description":"...","tags":["work"]}'`
|
||||
|
||||
#### التغيير 8: خدمة أمين المكتبة - إزالة بنية إدارة التخزين
|
||||
**الملف:** `trustgraph-flow/trustgraph/librarian/service.py`
|
||||
|
||||
**إزالة:**
|
||||
منتجي إدارة التخزين (الأسطر 173-190):
|
||||
`vector_storage_management_producer`
|
||||
`object_storage_management_producer`
|
||||
`triples_storage_management_producer`
|
||||
مستهلك الاستجابة للتخزين (الأسطر 192-201)
|
||||
معالج `on_storage_response` (الأسطر 467-473)
|
||||
|
||||
**تعديل:**
|
||||
تهيئة CollectionManager (الأسطر 215-224) - إزالة معلمات منتج التخزين
|
||||
|
||||
**ملاحظة:** تظل واجهة برمجة التطبيقات الخارجية للمجموعة دون تغيير:
|
||||
`list-collections`
|
||||
`update-collection`
|
||||
`delete-collection`
|
||||
|
||||
#### التغيير 9: إزالة جدول المجموعات من LibraryTableStore
|
||||
**الملف:** `trustgraph-flow/trustgraph/tables/library.py`
|
||||
|
||||
**حذف:**
|
||||
عبارة CREATE لجدول المجموعات (الأسطر 114-127)
|
||||
عبارات Collections المُعدة (الأسطر 205-240)
|
||||
جميع طرق المجموعة (الأسطر 578-717):
|
||||
`ensure_collection_exists`
|
||||
`list_collections`
|
||||
`update_collection`
|
||||
`delete_collection`
|
||||
`get_collection`
|
||||
`create_collection`
|
||||
|
||||
**السبب:**
|
||||
يتم الآن تخزين المجموعات في جدول التكوين
|
||||
التغيير غير المتوافق مقبول - لا توجد حاجة لنقل البيانات
|
||||
يبسط خدمة أمين المكتبة بشكل كبير
|
||||
|
||||
#### التغيير 10: خدمات التخزين - إدارة المجموعة المستندة إلى التكوين ✅ تم
|
||||
|
||||
**الحالة:** تم ترحيل جميع خدمات التخزين الـ 11 لاستخدام `CollectionConfigHandler`.
|
||||
|
||||
**الخدمات المتأثرة (11 خدمة إجمالاً):**
|
||||
تضمينات المستندات: milvus, pinecone, qdrant
|
||||
تضمينات الرسم البياني: milvus, pinecone, qdrant
|
||||
تخزين الكائنات: cassandra
|
||||
تخزين الثلاثيات: cassandra, falkordb, memgraph, neo4j
|
||||
|
||||
**الملفات:**
|
||||
`trustgraph-flow/trustgraph/storage/doc_embeddings/milvus/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/doc_embeddings/pinecone/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/doc_embeddings/qdrant/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/graph_embeddings/milvus/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/graph_embeddings/pinecone/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/graph_embeddings/qdrant/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/objects/cassandra/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/triples/cassandra/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/triples/falkordb/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/triples/memgraph/write.py`
|
||||
`trustgraph-flow/trustgraph/storage/triples/neo4j/write.py`
|
||||
|
||||
**نمط التنفيذ (جميع الخدمات):**
|
||||
|
||||
1. **سجل معالج التكوين في `__init__`:**
|
||||
```python
|
||||
# Add after AsyncProcessor initialization
|
||||
self.register_config_handler(self.on_collection_config)
|
||||
self.known_collections = set() # Track (user, collection) tuples
|
||||
```
|
||||
|
||||
2. **تنفيذ معالج التهيئة:**
|
||||
```python
|
||||
async def on_collection_config(self, config, version):
|
||||
"""Handle collection configuration updates"""
|
||||
logger.info(f"Collection config version: {version}")
|
||||
|
||||
if "collections" not in config:
|
||||
return
|
||||
|
||||
# Parse collections from config
|
||||
# Key format: "user:collection" in config["collections"]
|
||||
config_collections = set()
|
||||
for key in config["collections"].keys():
|
||||
if ":" in key:
|
||||
user, collection = key.split(":", 1)
|
||||
config_collections.add((user, collection))
|
||||
|
||||
# Determine changes
|
||||
to_create = config_collections - self.known_collections
|
||||
to_delete = self.known_collections - config_collections
|
||||
|
||||
# Create new collections (idempotent)
|
||||
for user, collection in to_create:
|
||||
try:
|
||||
await self.create_collection_internal(user, collection)
|
||||
self.known_collections.add((user, collection))
|
||||
logger.info(f"Created collection: {user}/{collection}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create {user}/{collection}: {e}")
|
||||
|
||||
# Delete removed collections (idempotent)
|
||||
for user, collection in to_delete:
|
||||
try:
|
||||
await self.delete_collection_internal(user, collection)
|
||||
self.known_collections.discard((user, collection))
|
||||
logger.info(f"Deleted collection: {user}/{collection}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to delete {user}/{collection}: {e}")
|
||||
```
|
||||
|
||||
3. **تهيئة المجموعات المعروفة عند بدء التشغيل:**
|
||||
```python
|
||||
async def start(self):
|
||||
"""Start the processor"""
|
||||
await super().start()
|
||||
await self.sync_known_collections()
|
||||
|
||||
async def sync_known_collections(self):
|
||||
"""Query backend to populate known_collections set"""
|
||||
# Backend-specific implementation:
|
||||
# - Milvus/Pinecone/Qdrant: List collections/indexes matching naming pattern
|
||||
# - Cassandra: Query keyspaces or collection metadata
|
||||
# - Neo4j/Memgraph/FalkorDB: Query CollectionMetadata nodes
|
||||
pass
|
||||
```
|
||||
|
||||
4. **إعادة هيكلة طرق المعالجة الحالية:**
|
||||
```python
|
||||
# Rename and remove response sending:
|
||||
# handle_create_collection → create_collection_internal
|
||||
# handle_delete_collection → delete_collection_internal
|
||||
|
||||
async def create_collection_internal(self, user, collection):
|
||||
"""Create collection (idempotent)"""
|
||||
# Same logic as current handle_create_collection
|
||||
# But remove response producer calls
|
||||
# Handle "already exists" gracefully
|
||||
pass
|
||||
|
||||
async def delete_collection_internal(self, user, collection):
|
||||
"""Delete collection (idempotent)"""
|
||||
# Same logic as current handle_delete_collection
|
||||
# But remove response producer calls
|
||||
# Handle "not found" gracefully
|
||||
pass
|
||||
```
|
||||
|
||||
5. **إزالة البنية التحتية لإدارة التخزين:**
|
||||
إزالة الإعداد والتشغيل `self.storage_request_consumer`.
|
||||
إزالة الإعداد `self.storage_response_producer`.
|
||||
إزالة طريقة الموزع `on_storage_management`.
|
||||
إزالة المقاييس لإدارة التخزين.
|
||||
إزالة الاستيرادات: `StorageManagementRequest`، `StorageManagementResponse`.
|
||||
|
||||
**اعتبارات خاصة بالخلفية:**
|
||||
|
||||
**مخازن المتجهات (Milvus, Pinecone, Qdrant):** تتبع `(user, collection)` المنطقية في `known_collections`، ولكن قد يتم إنشاء مجموعات خلفية متعددة لكل بُعد. استمر في نمط الإنشاء الكسول. يجب أن تزيل عمليات الحذف جميع المتغيرات الأبعاد.
|
||||
|
||||
**Cassandra Objects:** المجموعات هي خصائص الصفوف، وليست هياكل. تتبع معلومات على مستوى مساحة المفاتيح.
|
||||
|
||||
**مخازن الرسوم البيانية (Neo4j, Memgraph, FalkorDB):** استعلام عن عقد `CollectionMetadata` عند بدء التشغيل. إنشاء/حذف عقد البيانات الوصفية عند المزامنة.
|
||||
|
||||
**Cassandra Triples:** استخدم واجهة برمجة التطبيقات `KnowledgeGraph` لعمليات المجموعة.
|
||||
|
||||
**نقاط التصميم الرئيسية:**
|
||||
|
||||
**الاتساق النهائي:** لا يوجد آلية طلب/استجابة، يتم بث دفع التكوين.
|
||||
**التكرار:** يجب أن تكون جميع عمليات الإنشاء/الحذف آمنة لإعادة المحاولة.
|
||||
**معالجة الأخطاء:** سجل الأخطاء ولكن لا تقاطع تحديثات التكوين.
|
||||
**التعافي الذاتي:** ستعيد العمليات الفاشلة المحاولة في دفع التكوين التالي.
|
||||
**تنسيق مفتاح المجموعة:** `"user:collection"` في `config["collections"]`.
|
||||
|
||||
#### التغيير 11: تحديث مخطط المجموعة - إزالة الطوابع الزمنية
|
||||
**الملف:** `trustgraph-base/trustgraph/schema/services/collection.py`
|
||||
|
||||
**تعديل CollectionMetadata (الأسطر 13-21):**
|
||||
إزالة الحقول `created_at` و `updated_at`:
|
||||
```python
|
||||
class CollectionMetadata(Record):
|
||||
user = String()
|
||||
collection = String()
|
||||
name = String()
|
||||
description = String()
|
||||
tags = Array(String())
|
||||
# Remove: created_at = String()
|
||||
# Remove: updated_at = String()
|
||||
```
|
||||
|
||||
**تعديل طلب إدارة المجموعة (الأسطر من 25 إلى 47):**
|
||||
إزالة حقول الطابع الزمني:
|
||||
```python
|
||||
class CollectionManagementRequest(Record):
|
||||
operation = String()
|
||||
user = String()
|
||||
collection = String()
|
||||
timestamp = String()
|
||||
name = String()
|
||||
description = String()
|
||||
tags = Array(String())
|
||||
# Remove: created_at = String()
|
||||
# Remove: updated_at = String()
|
||||
tag_filter = Array(String())
|
||||
limit = Integer()
|
||||
```
|
||||
|
||||
**السبب:**
|
||||
لا تضيف الطوابع الزمنية قيمة للمجموعات.
|
||||
خدمة التكوين تحتفظ بآلية تتبع الإصدار الخاصة بها.
|
||||
تبسط المخطط وتقلل التخزين.
|
||||
|
||||
#### فوائد ترحيل خدمة التكوين
|
||||
|
||||
1. ✅ **تقضي على مواضيع إدارة التخزين المضمنة بشكل ثابت** - تحل مشكلة المستخدمين المتعددين.
|
||||
2. ✅ **تنسيق أبسط** - لا يوجد انتظار غير متزامن معقد لـ 4+ استجابات للتخزين.
|
||||
3. ✅ **الاتساق النهائي** - تقوم خدمات التخزين بالتحديث بشكل مستقل عبر دفع التكوين.
|
||||
4. ✅ **موثوقية أفضل** - دفع تكوين دائم مقابل طلب/استجابة غير دائمة.
|
||||
5. ✅ **نموذج تكوين موحد** - يتم التعامل مع المجموعات على أنها تكوين.
|
||||
6. ✅ **تقلل التعقيد** - تزيل حوالي 300 سطر من كود التنسيق.
|
||||
7. ✅ **جاهزة لدعم المستخدمين المتعددين** - تدعم التكوين بالفعل عزل المستخدمين عبر مساحة المفاتيح.
|
||||
8. ✅ **تتبع الإصدار** - توفر آلية إصدار خدمة التكوين مسار تدقيق.
|
||||
|
||||
## ملاحظات التنفيذ
|
||||
|
||||
### التوافق مع الإصدارات السابقة
|
||||
|
||||
**تغييرات في المعلمات:**
|
||||
إعادة تسمية معلمات سطر الأوامر هي تغييرات جذرية ولكنها مقبولة (الميزة غير وظيفية حاليًا).
|
||||
تعمل الخدمات بدون معلمات (تستخدم القيم الافتراضية).
|
||||
تم الحفاظ على مساحات المفاتيح الافتراضية: "config" و "knowledge" و "librarian".
|
||||
قائمة الانتظار الافتراضية: `persistent://tg/config/config`
|
||||
|
||||
**إدارة المجموعات:**
|
||||
**تغيير جذري:** تمت إزالة جدول المجموعات من مساحة مفاتيح librarian.
|
||||
**لا يتم توفير ترحيل للبيانات** - مقبول لهذه المرحلة.
|
||||
واجهة برمجة تطبيقات المجموعة الخارجية لم تتغير (عمليات القائمة/التحديث/الحذف).
|
||||
تم تبسيط تنسيق بيانات تعريف المجموعة (تمت إزالة الطوابع الزمنية).
|
||||
|
||||
### متطلبات الاختبار
|
||||
|
||||
**اختبار المعلمات:**
|
||||
1. تحقق من أن المعلمة `--config-push-queue` تعمل على خدمة graph-embeddings.
|
||||
2. تحقق من أن المعلمة `--config-push-queue` تعمل على خدمة text-completion.
|
||||
3. تحقق من أن المعلمة `--config-push-queue` تعمل على خدمة التكوين.
|
||||
4. تحقق من أن المعلمة `--cassandra-keyspace` تعمل لخدمة التكوين.
|
||||
5. تحقق من أن المعلمة `--cassandra-keyspace` تعمل لخدمة cores.
|
||||
6. تحقق من أن المعلمة `--cassandra-keyspace` تعمل لخدمة librarian.
|
||||
7. تحقق من أن الخدمات تعمل بدون معلمات (تستخدم القيم الافتراضية).
|
||||
8. تحقق من نشر متعدد المستخدمين باستخدام أسماء قوائم الانتظار ومساحات المفاتيح المخصصة.
|
||||
|
||||
**اختبار إدارة المجموعات:**
|
||||
9. تحقق من العملية `list-collections` عبر خدمة التكوين.
|
||||
10. تحقق من أن `update-collection` تقوم بإنشاء/تحديث في جدول التكوين.
|
||||
11. تحقق من أن `delete-collection` تقوم بإزالة من جدول التكوين.
|
||||
12. تحقق من أن دفع التكوين يتم تشغيله عند تحديث المجموعات.
|
||||
13. تحقق من أن تصفية العلامات تعمل مع التخزين المستند إلى التكوين.
|
||||
14. تحقق من أن عمليات المجموعة تعمل بدون حقول الطوابع الزمنية.
|
||||
|
||||
### مثال النشر متعدد المستخدمين
|
||||
```bash
|
||||
# Tenant: tg-dev
|
||||
graph-embeddings \
|
||||
-p pulsar+ssl://broker:6651 \
|
||||
--pulsar-api-key <KEY> \
|
||||
--config-push-queue persistent://tg-dev/config/config
|
||||
|
||||
config-service \
|
||||
-p pulsar+ssl://broker:6651 \
|
||||
--pulsar-api-key <KEY> \
|
||||
--config-push-queue persistent://tg-dev/config/config \
|
||||
--cassandra-keyspace tg_dev_config
|
||||
```
|
||||
|
||||
## تحليل الأثر
|
||||
|
||||
### الخدمات المتأثرة بالتغيير 1-2 (إعادة تسمية معلمة سطر الأوامر)
|
||||
جميع الخدمات التي ترث من AsyncProcessor أو FlowProcessor:
|
||||
config-service
|
||||
cores-service
|
||||
librarian-service
|
||||
graph-embeddings
|
||||
document-embeddings
|
||||
text-completion-* (جميع المزودين)
|
||||
extract-* (جميع أدوات الاستخراج)
|
||||
query-* (جميع خدمات الاستعلام)
|
||||
retrieval-* (جميع خدمات استرجاع المعلومات)
|
||||
storage-* (جميع خدمات التخزين)
|
||||
وأكثر من 20 خدمة أخرى
|
||||
|
||||
### الخدمات المتأثرة بالتغييرات 3-6 (مساحة مفاتيح Cassandra)
|
||||
config-service
|
||||
cores-service
|
||||
librarian-service
|
||||
|
||||
### الخدمات المتأثرة بالتغييرات 7-11 (إدارة المجموعات)
|
||||
|
||||
**التغييرات الفورية:**
|
||||
librarian-service (collection_manager.py, service.py)
|
||||
tables/library.py (إزالة جدول المجموعات)
|
||||
schema/services/collection.py (إزالة الطابع الزمني)
|
||||
|
||||
**التغييرات المكتملة (التغيير 10):** ✅
|
||||
جميع خدمات التخزين (11 إجمالاً) - تم ترحيلها إلى دفع التكوين لتحديثات المجموعة عبر `CollectionConfigHandler`
|
||||
تم إزالة مخطط إدارة التخزين من `storage.py`
|
||||
|
||||
## اعتبارات مستقبلية
|
||||
|
||||
### نموذج مساحة مفاتيح خاصة بالمستخدم
|
||||
|
||||
تستخدم بعض الخدمات **مساحات مفاتيح خاصة بالمستخدم** ديناميكيًا، حيث يحصل كل مستخدم على مساحة مفاتيح Cassandra خاصة به:
|
||||
|
||||
**الخدمات التي تستخدم مساحات مفاتيح خاصة بالمستخدم:**
|
||||
1. **خدمة استعلام الثلاثيات** (`trustgraph-flow/trustgraph/query/triples/cassandra/service.py:65`)
|
||||
تستخدم `keyspace=query.user`
|
||||
2. **خدمة استعلام الكائنات** (`trustgraph-flow/trustgraph/query/objects/cassandra/service.py:479`)
|
||||
تستخدم `keyspace=self.sanitize_name(user)`
|
||||
3. **الوصول المباشر إلى الرسم البياني المعرفي** (`trustgraph-flow/trustgraph/direct/cassandra_kg.py:18`)
|
||||
المعلمة الافتراضية `keyspace="trustgraph"`
|
||||
|
||||
**الحالة:** هذه **غير معدلة** في هذا المواصفات.
|
||||
|
||||
**مراجعة مستقبلية مطلوبة:**
|
||||
تقييم ما إذا كانت نموذج مساحة مفاتيح خاصة بالمستخدم تخلق مشاكل عزل المستأجر
|
||||
ضع في اعتبارك ما إذا كانت عمليات النشر متعددة المستأجرين تحتاج إلى أنماط بادئة لمساحة مفاتيح (مثل `tenant_a_user1`)
|
||||
مراجعة للاحتمالية المحتملة لتصادم معرف المستخدم عبر المستأجرين
|
||||
تقييم ما إذا كانت مساحة مفاتيح مشتركة واحدة لكل مستأجر مع عزل الصفوف المستند إلى المستخدم هي الأفضل
|
||||
|
||||
**ملاحظة:** هذا لا يمنع التنفيذ متعدد المستأجرين الحالي ولكنه يجب مراجعته قبل عمليات نشر متعددة المستأجرين في الإنتاج.
|
||||
|
||||
## مراحل التنفيذ
|
||||
|
||||
### المرحلة 1: إصلاحات المعلمات (التغييرات 1-6)
|
||||
إصلاح تسمية المعلمة `--config-push-queue`
|
||||
إضافة دعم المعلمة `--cassandra-keyspace`
|
||||
**النتيجة:** تم تمكين قائمة الانتظار متعددة المستأجرين وتكوين مساحة المفاتيح
|
||||
|
||||
### المرحلة 2: ترحيل إدارة المجموعة (التغييرات 7-9، 11)
|
||||
ترحيل تخزين المجموعة إلى خدمة التكوين
|
||||
إزالة جدول المجموعات من librarian
|
||||
تحديث مخطط المجموعة (إزالة الطوابع الزمنية)
|
||||
**النتيجة:** يلغي إدارة التخزين المضمنة، ويبسط librarian
|
||||
|
||||
### المرحلة 3: تحديثات خدمة التخزين (التغيير 10) ✅ مكتمل
|
||||
تم تحديث جميع خدمات التخزين لاستخدام دفع التكوين للمجموعات عبر `CollectionConfigHandler`
|
||||
تمت إزالة البنية التحتية لطلبات واستجابات إدارة التخزين
|
||||
تمت إزالة تعريفات المخطط القديمة
|
||||
**النتيجة:** تم تحقيق إدارة المجموعة المستندة إلى التكوين بالكامل
|
||||
|
||||
## المراجع
|
||||
مشكلة GitHub: https://github.com/trustgraph-ai/trustgraph/issues/582
|
||||
الملفات ذات الصلة:
|
||||
`trustgraph-base/trustgraph/base/async_processor.py`
|
||||
`trustgraph-base/trustgraph/base/cassandra_config.py`
|
||||
`trustgraph-base/trustgraph/schema/core/topic.py`
|
||||
`trustgraph-base/trustgraph/schema/services/collection.py`
|
||||
`trustgraph-flow/trustgraph/config/service/service.py`
|
||||
`trustgraph-flow/trustgraph/cores/service.py`
|
||||
`trustgraph-flow/trustgraph/librarian/service.py`
|
||||
`trustgraph-flow/trustgraph/librarian/collection_manager.py`
|
||||
`trustgraph-flow/trustgraph/tables/library.py`
|
||||
198
docs/tech-specs/ar/neo4j-user-collection-isolation.ar.md
Normal file
198
docs/tech-specs/ar/neo4j-user-collection-isolation.ar.md
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
---
|
||||
layout: default
|
||||
title: "دعم عزل المستخدم/المجموعة في Neo4j"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# دعم عزل المستخدم/المجموعة في Neo4j
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
تفتقر آلية تخزين الاستعلامات الثلاثية الحالية في Neo4j إلى عزل المستخدم/المجموعة، مما يؤدي إلى مشكلة أمنية متعددة المستأجرين. يتم تخزين جميع الثلاثيات في نفس مساحة الرسم البياني دون أي آلية لمنع المستخدمين من الوصول إلى بيانات مستخدمين آخرين أو مزج المجموعات.
|
||||
|
||||
على عكس الأنظمة الخلفية الأخرى للتخزين في TrustGraph:
|
||||
- **Cassandra**: تستخدم مساحات مفاتيح منفصلة لكل مستخدم وجداول لكل مجموعة.
|
||||
- **مخازن المتجهات** (Milvus, Qdrant, Pinecone): تستخدم مساحات أسماء خاصة بالمجموعة.
|
||||
- **Neo4j**: تشارك حاليًا جميع البيانات في رسم بياني واحد (ثغرة أمنية).
|
||||
|
||||
## البنية الحالية
|
||||
|
||||
### نموذج البيانات
|
||||
- **العقد:** تسمية `:Node` مع خاصية `uri`، تسمية `:Literal` مع خاصية `value`.
|
||||
- **العلاقات:** تسمية `:Rel` مع خاصية `uri`.
|
||||
- **الفهارس:** `Node.uri`, `Literal.value`, `Rel.uri`.
|
||||
|
||||
### تدفق الرسائل
|
||||
- تحتوي رسائل `Triples` على الحقول `metadata.user` و `metadata.collection`.
|
||||
- تتلقى خدمة التخزين معلومات المستخدم/المجموعة ولكنها تتجاهلها.
|
||||
- تتوقع خدمة الاستعلام `user` و `collection` في `TriplesQueryRequest` ولكنها تتجاهلهما.
|
||||
|
||||
### المشكلة الأمنية الحالية
|
||||
```cypher
|
||||
# يمكن لأي مستخدم الاستعلام عن أي بيانات - لا يوجد عزل
|
||||
MATCH (src:Node)-[rel:Rel]->(dest:Node)
|
||||
RETURN src.uri, rel.uri, dest.uri
|
||||
```
|
||||
|
||||
## الحل المقترح: التصفية المستندة إلى الخصائص (موصى بها)
|
||||
|
||||
### نظرة عامة
|
||||
إضافة خصائص `user` و `collection` إلى جميع العقد والعلاقات، ثم تصفية جميع العمليات بناءً على هذه الخصائص. يوفر هذا النهج عزلًا قويًا مع الحفاظ على مرونة الاستعلام والتوافق مع الإصدارات السابقة.
|
||||
|
||||
### تغييرات نموذج البيانات
|
||||
|
||||
#### هيكل العقدة المحسّن
|
||||
```cypher
|
||||
// كيانات العقد
|
||||
CREATE (n:Node {
|
||||
uri: "http://example.com/entity1",
|
||||
user: "john_doe",
|
||||
collection: "production_v1"
|
||||
})
|
||||
|
||||
// كيانات حرفية
|
||||
CREATE (n:Literal {
|
||||
value: "literal value",
|
||||
user: "john_doe",
|
||||
collection: "production_v1"
|
||||
})
|
||||
```
|
||||
|
||||
#### هيكل العلاقة المحسّن
|
||||
```cypher
|
||||
// العلاقات مع خصائص المستخدم/المجموعة
|
||||
CREATE (src)-[:Rel {
|
||||
uri: "http://example.com/predicate1",
|
||||
user: "john_doe",
|
||||
collection: "production_v1"
|
||||
}]->(dest)
|
||||
```
|
||||
|
||||
#### الفهارس المحدثة
|
||||
```cypher
|
||||
// فهارس مركبة للتصفية الفعالة
|
||||
CREATE INDEX node_user_collection_uri FOR (n:Node) ON (n.user, n.collection, n.uri);
|
||||
CREATE INDEX literal_user_collection_value FOR (n:Literal) ON (n.user, n.collection, n.value);
|
||||
CREATE INDEX rel_user_collection_uri FOR ()-[r:Rel]-() ON (r.user, r.collection, r.uri);
|
||||
|
||||
// الحفاظ على الفهارس الحالية للتوافق مع الإصدارات السابقة (اختياري)
|
||||
CREATE INDEX Node_uri FOR (n:Node) ON (n.uri);
|
||||
CREATE INDEX Literal_value FOR (n:Literal) ON (n.value);
|
||||
CREATE INDEX Rel_uri FOR ()-[r:Rel]-() ON (r.uri);
|
||||
```
|
||||
|
||||
### تنفيذ الخطة
|
||||
|
||||
### المرحلة 1: الأساس (الأسبوع 1)
|
||||
1. [ ] تحديث خدمة التخزين لقبول وتخزين خصائص المستخدم/المجموعة.
|
||||
2. [ ] إضافة فهارس مركبة للتصفية الفعالة.
|
||||
3. [ ] تنفيذ طبقة توافق مع الإصدارات السابقة.
|
||||
4. [ ] إنشاء اختبارات وحدة للوظائف الجديدة.
|
||||
|
||||
### المرحلة 2: تحديثات الاستعلام (الأسبوع 2)
|
||||
1. [ ] تحديث جميع أنماط الاستعلام لتشمل عوامل تصفية المستخدم/المجموعة.
|
||||
2. [ ] إضافة التحقق من صحة الاستعلامات وعناصر التحكم الأمنية.
|
||||
3. [ ] تحديث اختبارات التكامل.
|
||||
4. [ ] اختبار الأداء مع الاستعلامات المفلترة.
|
||||
|
||||
### المرحلة 3: الترحيل والنشر (الأسبوع 3)
|
||||
1. [ ] إنشاء نصوص ترحيل للبيانات لمثيل Neo4j الحالي.
|
||||
2. [ ] وثائق النشر والتعليمات البرمجية التشغيلية.
|
||||
3. [ ] المراقبة والتنبيه لانتهاكات العزل.
|
||||
4. [ ] اختبار شامل مع سيناريوهات متعددة للمستخدمين/المجموعات.
|
||||
|
||||
### المرحلة 4: التقوية (الأسبوع 4)
|
||||
1. [ ] إزالة وضع التوافق مع الإصدارات القديمة.
|
||||
2. [ ] إضافة تسجيل تدقيق شامل.
|
||||
3. [ ] مراجعة أمنية واختبار اختراق.
|
||||
4. [ ] تحسين الأداء.
|
||||
|
||||
### استراتيجية الاختبار
|
||||
|
||||
### اختبارات الوحدة
|
||||
```python
|
||||
def test_user_collection_isolation():
|
||||
# تخزين ثلاثيات لمستخدم1/مجموعة1
|
||||
processor.store_triples(triples_user1_coll1)
|
||||
|
||||
# تخزين ثلاثيات لمستخدم2/مجموعة2
|
||||
processor.store_triples(triples_user2_coll2)
|
||||
|
||||
# يجب أن تعرض الاستعلامات كمستخدم1 فقط بيانات مستخدم1
|
||||
results = processor.query_triples(query_user1_coll1)
|
||||
assert all_results_belong_to_user1_coll1(results)
|
||||
|
||||
# يجب أن تعرض الاستعلامات كمستخدم2 فقط بيانات مستخدم2
|
||||
results = processor.query_triples(query_user2_coll2)
|
||||
assert all_results_belong_to_user2_coll2(results)
|
||||
```
|
||||
|
||||
### اختبارات التكامل
|
||||
- سيناريوهات متعددة المستخدمين مع بيانات متداخلة.
|
||||
- استعلامات عبر مجموعات (يجب أن تفشل).
|
||||
- اختبارات الترحيل مع البيانات الحالية.
|
||||
- معايير أداء مع مجموعات بيانات كبيرة.
|
||||
|
||||
### اختبارات الأمان
|
||||
- محاولة الاستعلام عن بيانات مستخدمين آخرين.
|
||||
- هجمات SQL injection على معلمات المستخدم/المجموعة.
|
||||
- التحقق من العزل الكامل في ظل أنماط استعلام مختلفة.
|
||||
|
||||
### اعتبارات الأداء
|
||||
|
||||
### استراتيجية الفهرس
|
||||
- فهارس مركبة على `(user, collection, uri)` للتصفية المثلى.
|
||||
- ضع في اعتبارك الفهارس الجزئية إذا كانت بعض المجموعات أكبر بكثير.
|
||||
- مراقبة استخدام الفهرس وأداء الاستعلام.
|
||||
|
||||
### تحسين الاستعلام
|
||||
- استخدم EXPLAIN للتحقق من استخدام الفهرس في الاستعلامات المفلترة.
|
||||
- ضع في اعتبارك تخزين نتائج الاستعلام مؤقتًا للبيانات التي يتم الوصول إليها بشكل متكرر.
|
||||
- قم بتوصيف استخدام الذاكرة مع عدد كبير من المستخدمين/المجموعات.
|
||||
|
||||
### قابلية التوسع
|
||||
- تخلق كل مجموعة مستخدم/مجموعة جزيرة بيانات منفصلة.
|
||||
- مراقبة حجم قاعدة البيانات واستخدام مجموعة الاتصال.
|
||||
- ضع في اعتبارك استراتيجيات التوسع الأفقي إذا لزم الأمر.
|
||||
|
||||
### الأمن والامتثال
|
||||
|
||||
### ضمانات العزل
|
||||
- **الفيزيائية**: جميع بيانات المستخدم مخزنة مع خصائص مستخدم/مجموعة صريحة.
|
||||
- **المنطقية**: يتم تصفية جميع الاستعلامات بواسطة سياق المستخدم/المجموعة.
|
||||
- **التحكم في الوصول**: التحقق من الصحة على مستوى الخدمة يمنع الوصول غير المصرح به.
|
||||
|
||||
### متطلبات التدقيق
|
||||
- تسجيل جميع عمليات الوصول إلى البيانات مع سياق المستخدم/المجموعة.
|
||||
- تتبع أنشطة الترحيل وحركات البيانات.
|
||||
- المراقبة بحثًا عن محاولات انتهاك العزل.
|
||||
|
||||
### اعتبارات الامتثال
|
||||
- GDPR: القدرة المحسنة على تحديد موقع بيانات المستخدم وحذفها.
|
||||
- SOC2: ضوابط واضحة لعزل المستأجر والوصول.
|
||||
- HIPAA: عزل قوي للمستأجر لبيانات الرعاية الصحية.
|
||||
|
||||
### المخاطر والتخفيف
|
||||
|
||||
| المخاطر | التأثير | الاحتمالية | التخفيف |
|
||||
|------|--------|------------|------------|
|
||||
| الاستعلام المفقود لعامل تصفية المستخدم/المجموعة | مرتفع | متوسط | التحقق الإلزامي، اختبار شامل |
|
||||
| تدهور الأداء | متوسط | منخفض | تحسين الفهرس، توصيف الاستعلام |
|
||||
| تلف بيانات الترحيل | مرتفع | منخفض | استراتيجية النسخ الاحتياطي، إجراءات التراجع |
|
||||
| استعلامات معقدة متعددة المجموعات | متوسط | متوسط | توثيق أنماط الاستعلام، توفير أمثلة |
|
||||
|
||||
### معايير النجاح
|
||||
|
||||
1. **الأمان**: صفر من عمليات الوصول إلى بيانات المستخدم عبر المستخدمين في الإنتاج.
|
||||
2. **الأداء**: أقل من 10٪ من تأثير أداء الاستعلام مقارنة بالاستعلامات غير المفلترة.
|
||||
3. **الترحيل**: تم ترحيل 100٪ من البيانات الحالية بنجاح بدون فقدان.
|
||||
4. **سهولة الاستخدام**: تعمل جميع أنماط الاستعلام الموجودة مع سياق المستخدم/المجموعة.
|
||||
5. **الامتثال**: سجل تدقيق شامل لعمليات الوصول إلى بيانات المستخدم/المجموعة.
|
||||
|
||||
## الخلاصة
|
||||
|
||||
يوفر النهج القائم على التصفية المستندة إلى الخصائص أفضل توازن بين الأمان والأداء وقابلية الصيانة لإضافة عزل المستخدم/المجموعة إلى Neo4j. إنه يتماشى مع أنماط متعددة المستأجرين الحالية في TrustGraph مع الاستفادة من نقاط قوة Neo4j في استعلامات الرسم البياني والفهرسة.
|
||||
|
||||
تضمن هذه الحل أن يلبي الخلفية Neo4 لـ TrustGraph نفس معايير الأمان مثل الأنظمة الخلفية الأخرى للتخزين، مما يمنع ثغرات أمنية لعزل البيانات مع الحفاظ على المرونة وقوة استعلامات الرسم البياني.
|
||||
769
docs/tech-specs/ar/ontology-extract-phase-2.ar.md
Normal file
769
docs/tech-specs/ar/ontology-extract-phase-2.ar.md
Normal file
|
|
@ -0,0 +1,769 @@
|
|||
---
|
||||
layout: default
|
||||
title: "استخراج المعرفة من علم الوجود - المرحلة الثانية، إعادة هيكلة"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# استخراج المعرفة من علم الوجود - المرحلة الثانية، إعادة هيكلة
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
**الحالة**: مسودة
|
||||
**المؤلف**: جلسة التحليل بتاريخ 2025-12-03
|
||||
**مرتبط بـ**: `ontology.md`، `ontorag.md`
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يحدد هذا المستند التناقضات الموجودة في نظام استخراج المعرفة الحالي القائم على علم الوجود ويقترح إعادة هيكلة لتحسين أداء نماذج اللغة الكبيرة وتقليل فقدان المعلومات.
|
||||
|
||||
## التنفيذ الحالي
|
||||
|
||||
### كيف يعمل الآن
|
||||
|
||||
1. **تحميل علم الوجود** (`ontology_loader.py`)
|
||||
يقوم بتحميل ملف JSON الخاص بعلم الوجود باستخدام مفاتيح مثل `"fo/Recipe"`، `"fo/Food"`، `"fo/produces"`
|
||||
تتضمن معرفات الفئات بادئة مساحة الاسم في المفتاح نفسه.
|
||||
مثال من `food.ontology`:
|
||||
```json
|
||||
"classes": {
|
||||
"fo/Recipe": {
|
||||
"uri": "http://purl.org/ontology/fo/Recipe",
|
||||
"rdfs:comment": "A Recipe is a combination..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **بناء المطالبة** (`extract.py:299-307`، `ontology-prompt.md`)
|
||||
يتلقى النموذج `classes`، `object_properties`، `datatype_properties` (قواميس).
|
||||
يتكرر النموذج: `{% for class_id, class_def in classes.items() %}`
|
||||
يرى نموذج اللغة الكبيرة (LLM): `**fo/Recipe**: A Recipe is a combination...`
|
||||
يوضح تنسيق الإخراج النموذجي:
|
||||
```json
|
||||
{"subject": "recipe:cornish-pasty", "predicate": "rdf:type", "object": "Recipe"}
|
||||
{"subject": "recipe:cornish-pasty", "predicate": "has_ingredient", "object": "ingredient:flour"}
|
||||
```
|
||||
|
||||
3. **تحليل الاستجابة** (`extract.py:382-428`)
|
||||
يتوقع مصفوفة JSON: `[{"subject": "...", "predicate": "...", "object": "..."}]`
|
||||
يتحقق من الصحة مقابل مجموعة فرعية من علم الوجود.
|
||||
يوسع الـ URIs عبر `expand_uri()` (extract.py:473-521)
|
||||
|
||||
4. **توسيع الـ URI** (`extract.py:473-521`)
|
||||
يتحقق مما إذا كانت القيمة موجودة في قاموس `ontology_subset.classes`.
|
||||
إذا تم العثور عليها، يتم استخراج الـ URI من تعريف الفئة.
|
||||
إذا لم يتم العثور عليها، يتم إنشاء الـ URI: `f"https://trustgraph.ai/ontology/{ontology_id}#{value}"`
|
||||
|
||||
### مثال تدفق البيانات
|
||||
|
||||
**JSON لعلم الوجود → المحمل → المطالبة:**
|
||||
```
|
||||
"fo/Recipe" → classes["fo/Recipe"] → LLM sees "**fo/Recipe**"
|
||||
```
|
||||
|
||||
**نموذج اللغة الكبير → المحلل → الإخراج:**
|
||||
```
|
||||
"Recipe" → not in classes["fo/Recipe"] → constructs URI → LOSES original URI
|
||||
"fo/Recipe" → found in classes → uses original URI → PRESERVES URI
|
||||
```
|
||||
|
||||
## المشكلات التي تم تحديدها
|
||||
|
||||
### 1. **أمثلة غير متسقة في التعليمات**
|
||||
|
||||
**المشكلة**: قالب التعليمات يعرض معرفات الفئات مع بادئات (`fo/Recipe`) ولكن الإخراج النموذجي يستخدم أسماء فئات بدون بادئات (`Recipe`).
|
||||
|
||||
**الموقع**: `ontology-prompt.md:5-52`
|
||||
|
||||
```markdown
|
||||
## Ontology Classes:
|
||||
- **fo/Recipe**: A Recipe is...
|
||||
|
||||
## Example Output:
|
||||
{"subject": "recipe:cornish-pasty", "predicate": "rdf:type", "object": "Recipe"}
|
||||
```
|
||||
|
||||
**التأثير:** يتلقى نموذج اللغة الكبير إشارات متضاربة حول التنسيق الذي يجب استخدامه.
|
||||
|
||||
### 2. **فقدان المعلومات في توسيع عنوان URL**
|
||||
|
||||
**المشكلة:** عندما يقوم نموذج اللغة الكبير بإرجاع أسماء الفئات غير المسبوقة بعد المثال، لا يمكن لـ `expand_uri()` العثور عليها في قاموس الأونطولوجيا ويقوم بإنشاء عناوين URI احتياطية، مما يؤدي إلى فقدان عناوين URI الأصلية الصحيحة.
|
||||
|
||||
**الموقع:** `extract.py:494-500`
|
||||
|
||||
```python
|
||||
if value in ontology_subset.classes: # Looks for "Recipe"
|
||||
class_def = ontology_subset.classes[value] # But key is "fo/Recipe"
|
||||
if isinstance(class_def, dict) and 'uri' in class_def:
|
||||
return class_def['uri'] # Never reached!
|
||||
return f"https://trustgraph.ai/ontology/{ontology_id}#{value}" # Fallback
|
||||
```
|
||||
|
||||
**التأثير:**
|
||||
عنوان URI الأصلي: `http://purl.org/ontology/fo/Recipe`
|
||||
عنوان URI المُنشأ: `https://trustgraph.ai/ontology/food#Recipe`
|
||||
فقدان المعنى الدلالي، مما يعيق التوافقية.
|
||||
|
||||
### 3. **تنسيق مثيل الكيان الغامض**
|
||||
|
||||
**المشكلة:** لا توجد إرشادات واضحة حول تنسيق عنوان URI لمثيل الكيان.
|
||||
|
||||
**أمثلة في التعليمات:**
|
||||
`"recipe:cornish-pasty"` (بادئة تشبه مساحة الاسم)
|
||||
`"ingredient:flour"` (بادئة مختلفة)
|
||||
|
||||
**السلوك الفعلي** (extract.py:517-520):
|
||||
```python
|
||||
# Treat as entity instance - construct unique URI
|
||||
normalized = value.replace(" ", "-").lower()
|
||||
return f"https://trustgraph.ai/{ontology_id}/{normalized}"
|
||||
```
|
||||
|
||||
**التأثير**: يجب على نموذج اللغة الكبير تخمين اتفاقية البادئات بدون أي سياق دلالي.
|
||||
|
||||
### 4. **لا توجد إرشادات حول بادئات النطاقات**.
|
||||
|
||||
**المشكلة**: يحتوي ملف JSON الخاص بالدلالة على تعريفات النطاقات (السطر 10-25 في food.ontology):
|
||||
```json
|
||||
"namespaces": {
|
||||
"fo": "http://purl.org/ontology/fo/",
|
||||
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
ولكن هذه العناصر لا يتم إرسالها أبدًا إلى نموذج اللغة الكبير (LLM). نموذج اللغة الكبير لا يعرف:
|
||||
ما الذي تعنيه كلمة "fo"
|
||||
ما هو البادئة التي يجب استخدامها للكائنات
|
||||
أي مساحة اسم تنطبق على أي عناصر
|
||||
|
||||
### 5. **التسميات غير المستخدمة في المطالبة**
|
||||
|
||||
**المشكلة:** كل فئة لديها `rdfs:label` حقول (مثل `{"value": "Recipe", "lang": "en-gb"}`)، ولكن قالب المطالبة لا يستخدمها.
|
||||
|
||||
**الحالي:** يعرض فقط `class_id` و `comment`
|
||||
```jinja
|
||||
- **{{class_id}}**{% if class_def.comment %}: {{class_def.comment}}{% endif %}
|
||||
```
|
||||
|
||||
**متاح ولكنه غير مستخدم:**
|
||||
```python
|
||||
"rdfs:label": [{"value": "Recipe", "lang": "en-gb"}]
|
||||
```
|
||||
|
||||
**التأثير**: يمكن أن يوفر أسماءً قابلة للقراءة من قبل الإنسان جنبًا إلى جنب مع المعرفات التقنية.
|
||||
|
||||
## الحلول المقترحة
|
||||
|
||||
### الخيار أ: التوحيد إلى معرفات غير مُسبقة
|
||||
|
||||
**النهج**: إزالة البادئات من معرفات الفئات قبل عرضها لنظام LLM.
|
||||
|
||||
**التغييرات**:
|
||||
1. تعديل `build_extraction_variables()` لتحويل المفاتيح:
|
||||
```python
|
||||
classes_for_prompt = {
|
||||
k.split('/')[-1]: v # "fo/Recipe" → "Recipe"
|
||||
for k, v in ontology_subset.classes.items()
|
||||
}
|
||||
```
|
||||
|
||||
2. تحديث مثال المطالبة ليتطابق (يستخدم بالفعل أسماء غير مسبوقة).
|
||||
|
||||
3. تعديل `expand_uri()` للتعامل مع كلا التنسيقين:
|
||||
```python
|
||||
# Try exact match first
|
||||
if value in ontology_subset.classes:
|
||||
return ontology_subset.classes[value]['uri']
|
||||
|
||||
# Try with prefix
|
||||
for prefix in ['fo/', 'rdf:', 'rdfs:']:
|
||||
prefixed = f"{prefix}{value}"
|
||||
if prefixed in ontology_subset.classes:
|
||||
return ontology_subset.classes[prefixed]['uri']
|
||||
```
|
||||
|
||||
**المزايا:**
|
||||
أنظف وأكثر قابلية للقراءة من قبل البشر.
|
||||
تتوافق مع أمثلة المطالبات الحالية.
|
||||
تعمل نماذج اللغات الكبيرة بشكل أفضل مع الرموز الأبسط.
|
||||
|
||||
**العيوب:**
|
||||
تعارض أسماء الفئات إذا كانت هناك العديد من الأنطولوجيات لها نفس اسم الفئة.
|
||||
تفقد معلومات مساحة الاسم.
|
||||
تتطلب منطقًا احتياطيًا للبحث.
|
||||
|
||||
### الخيار ب: استخدام المعرفات الكاملة المسبوقة باستمرار
|
||||
|
||||
**الطريقة:** تحديث الأمثلة لاستخدام المعرفات المسبوقة التي تتطابق مع ما هو موضح في قائمة الفئات.
|
||||
|
||||
**التغييرات:**
|
||||
1. تحديث مثال المطالبة (ontology-prompt.md:46-52):
|
||||
```json
|
||||
[
|
||||
{"subject": "recipe:cornish-pasty", "predicate": "rdf:type", "object": "fo/Recipe"},
|
||||
{"subject": "recipe:cornish-pasty", "predicate": "rdfs:label", "object": "Cornish Pasty"},
|
||||
{"subject": "recipe:cornish-pasty", "predicate": "fo/produces", "object": "food:cornish-pasty"},
|
||||
{"subject": "food:cornish-pasty", "predicate": "rdf:type", "object": "fo/Food"}
|
||||
]
|
||||
```
|
||||
|
||||
2. أضف شرحًا لمساحة الاسم إلى التعليمات:
|
||||
```markdown
|
||||
## Namespace Prefixes:
|
||||
- **fo/**: Food Ontology (http://purl.org/ontology/fo/)
|
||||
- **rdf:**: RDF Schema
|
||||
- **rdfs:**: RDF Schema
|
||||
|
||||
Use these prefixes exactly as shown when referencing classes and properties.
|
||||
```
|
||||
|
||||
3. احتفظ بـ `expand_uri()` كما هو (يعمل بشكل صحيح عند العثور على تطابقات).
|
||||
|
||||
**المزايا:**
|
||||
اتساق الإدخال والإخراج.
|
||||
عدم وجود فقدان للمعلومات.
|
||||
يحافظ على دلالات مساحة الاسم.
|
||||
يعمل مع العديد من الأنطولوجيات.
|
||||
|
||||
**العيوب:**
|
||||
رموز أكثر تفصيلاً لنظام LLM.
|
||||
يتطلب من نظام LLM تتبع البادئات.
|
||||
|
||||
### الخيار ج: هجين - عرض كل من التسمية والمعرف
|
||||
|
||||
**النهج:** قم بتحسين المطالبة لعرض كل من التسميات المقروءة من قبل الإنسان والمعرفات التقنية.
|
||||
|
||||
**التغييرات:**
|
||||
1. تحديث قالب المطالبة:
|
||||
```jinja
|
||||
{% for class_id, class_def in classes.items() %}
|
||||
- **{{class_id}}** (label: "{{class_def.labels[0].value if class_def.labels else class_id}}"){% if class_def.comment %}: {{class_def.comment}}{% endif %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
الناتج النموذجي:
|
||||
```markdown
|
||||
- **fo/Recipe** (label: "Recipe"): A Recipe is a combination...
|
||||
```
|
||||
|
||||
2. تعليمات التحديث:
|
||||
```markdown
|
||||
When referencing classes:
|
||||
- Use the full prefixed ID (e.g., "fo/Recipe") in JSON output
|
||||
- The label (e.g., "Recipe") is for human understanding only
|
||||
```
|
||||
|
||||
**المزايا:**
|
||||
الأوضح لنماذج اللغة الكبيرة (LLM)
|
||||
يحافظ على جميع المعلومات
|
||||
يوضح بشكل صريح ما يجب استخدامه
|
||||
|
||||
**العيوب:**
|
||||
طلب أطول
|
||||
قالب أكثر تعقيدًا
|
||||
|
||||
## النهج المطبق
|
||||
|
||||
**تنسيق مبسط للعلاقة بين الكيانات والخصائص** - يحل محل التنسيق القديم القائم على الثلاثيات تمامًا.
|
||||
|
||||
تم اختيار النهج الجديد لأنه:
|
||||
|
||||
1. **لا يوجد فقدان للمعلومات**: يتم الحفاظ على عناوين URI الأصلية بشكل صحيح.
|
||||
2. **منطق أبسط**: لا توجد حاجة إلى أي تحويل، تعمل عمليات البحث المباشرة في القواميس.
|
||||
3. **أمان مساحة الاسم**: يتعامل مع العديد من الأنطولوجيات دون حدوث تعارضات.
|
||||
4. **الصحة الدلالية**: يحافظ على الدلالات الخاصة بـ RDF/OWL.
|
||||
|
||||
## التنفيذ مكتمل
|
||||
|
||||
### ما تم بناؤه:
|
||||
|
||||
1. **قالب طلب جديد** (`prompts/ontology-extract-v2.txt`)
|
||||
✅ أقسام واضحة: أنواع الكيانات، العلاقات، الخصائص.
|
||||
✅ مثال باستخدام معرفات النوع الكاملة (`fo/Recipe`، `fo/has_ingredient`).
|
||||
✅ تعليمات لاستخدام المعرفات الدقيقة من المخطط.
|
||||
✅ تنسيق JSON جديد مع مصفوفات الكيانات/العلاقات/الخصائص.
|
||||
|
||||
2. **تسوية الكيانات** (`entity_normalizer.py`)
|
||||
✅ `normalize_entity_name()` - يحول الأسماء إلى تنسيق آمن لـ URI.
|
||||
✅ `normalize_type_identifier()` - يتعامل مع الشرطات المائلة في الأنواع (`fo/Recipe` → `fo-recipe`).
|
||||
✅ `build_entity_uri()` - ينشئ عناوين URI فريدة باستخدام زوج (الاسم، النوع).
|
||||
✅ `EntityRegistry` - يتتبع الكيانات لتجنب التكرار.
|
||||
|
||||
3. **محلل JSON** (`simplified_parser.py`)
|
||||
✅ يحلل التنسيق الجديد: `{entities: [...], relationships: [...], attributes: [...]}`.
|
||||
✅ يدعم أسماء الحقول بتنسيق kebab-case و snake_case.
|
||||
✅ يُرجع فئات بيانات منظمة.
|
||||
✅ معالجة أخطاء سلسة مع التسجيل.
|
||||
|
||||
4. **محول الثلاثيات** (`triple_converter.py`)
|
||||
✅ `convert_entity()` - ينشئ ثلاثيات النوع + التسمية تلقائيًا.
|
||||
✅ `convert_relationship()` - يربط عناوين URI للكيانات عبر الخصائص.
|
||||
✅ `convert_attribute()` - يضيف القيم الحرفية.
|
||||
✅ يبحث عن عناوين URI الكاملة من تعريفات الأنطولوجيا.
|
||||
|
||||
5. **المعالج الرئيسي المحدث** (`extract.py`)
|
||||
✅ تمت إزالة كود الاستخراج القديم القائم على الثلاثيات.
|
||||
✅ تمت إضافة `extract_with_simplified_format()`.
|
||||
✅ يستخدم الآن التنسيق المبسط الجديد فقط.
|
||||
✅ يستدعي الطلب بمعرف `extract-with-ontologies-v2`.
|
||||
|
||||
## حالات الاختبار
|
||||
|
||||
### الاختبار 1: الحفاظ على عنوان URI
|
||||
```python
|
||||
# Given ontology class
|
||||
classes = {"fo/Recipe": {"uri": "http://purl.org/ontology/fo/Recipe", ...}}
|
||||
|
||||
# When LLM returns
|
||||
llm_output = {"subject": "x", "predicate": "rdf:type", "object": "fo/Recipe"}
|
||||
|
||||
# Then expanded URI should be
|
||||
assert expanded == "http://purl.org/ontology/fo/Recipe"
|
||||
# Not: "https://trustgraph.ai/ontology/food#Recipe"
|
||||
```
|
||||
|
||||
### الاختبار 2: التصادم متعدد الأنطولوجيا
|
||||
```python
|
||||
# Given two ontologies
|
||||
ont1 = {"fo/Recipe": {...}}
|
||||
ont2 = {"cooking/Recipe": {...}}
|
||||
|
||||
# LLM should use full prefix to disambiguate
|
||||
llm_output = {"object": "fo/Recipe"} # Not just "Recipe"
|
||||
```
|
||||
|
||||
### الاختبار رقم 3: تنسيق مثيل الكيان
|
||||
```python
|
||||
# Given prompt with food ontology
|
||||
# LLM should create instances like
|
||||
{"subject": "recipe:cornish-pasty"} # Namespace-style
|
||||
{"subject": "food:beef"} # Consistent prefix
|
||||
```
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
1. **هل يجب أن تستخدم حالات الكيانات بادئات النطاق؟**
|
||||
الحالي: `"recipe:cornish-pasty"` (عشوائي)
|
||||
بديل: استخدام بادئة الأونطولوجيا `"fo:cornish-pasty"`؟
|
||||
بديل: بدون بادئة، التوسع في URI `"cornish-pasty"` → URI كامل؟
|
||||
|
||||
2. **كيفية التعامل مع النطاق/المدى في المطالبة؟**
|
||||
يعرض حاليًا: `(Recipe → Food)`
|
||||
هل يجب أن يكون: `(fo/Recipe → fo/Food)`؟
|
||||
|
||||
3. **هل يجب علينا التحقق من صحة قيود النطاق/المدى؟**
|
||||
ملاحظة TODO في extract.py:470
|
||||
سيكتشف المزيد من الأخطاء ولكنه أكثر تعقيدًا
|
||||
|
||||
4. **ماذا عن الخصائص العكسية والتكافؤات؟**
|
||||
تحتوي الأونطولوجيا على `owl:inverseOf`، `owl:equivalentClass`
|
||||
لا يتم استخدامه حاليًا في الاستخراج
|
||||
هل يجب أن يتم استخدامه؟
|
||||
|
||||
## مقاييس النجاح
|
||||
|
||||
✅ عدم وجود فقدان لمعلومات URI (100٪ للحفاظ على URIs الأصلية)
|
||||
✅ تنسيق إخراج LLM يطابق تنسيق الإدخال
|
||||
✅ لا توجد أمثلة غامضة في المطالبة
|
||||
✅ اجتياز الاختبارات مع العديد من الأونطولوجيات
|
||||
✅ تحسين جودة الاستخراج (يتم قياسه بالنسبة المئوية للثلاثيات الصالحة)
|
||||
|
||||
## نهج بديل: تنسيق استخراج مبسط
|
||||
|
||||
### الفلسفة
|
||||
|
||||
بدلاً من مطالبة LLM بفهم دلالات RDF/OWL، اطلب منه فعل ما هو جيد فيه: **العثور على الكيانات والعلاقات في النص**.
|
||||
|
||||
دع الكود يتعامل مع بناء URI، وتحويل RDF، والشؤون الرسمية للويب الدلالي.
|
||||
|
||||
### مثال: تصنيف الكيانات
|
||||
|
||||
**النص المدخل:**
|
||||
```
|
||||
Cornish pasty is a traditional British pastry filled with meat and vegetables.
|
||||
```
|
||||
|
||||
**مخطط علم الوجود (يُعرض على نموذج اللغة الكبير):**
|
||||
```markdown
|
||||
## Entity Types:
|
||||
- Recipe: A recipe is a combination of ingredients and a method
|
||||
- Food: A food is something that can be eaten
|
||||
- Ingredient: An ingredient combines a quantity and a food
|
||||
```
|
||||
|
||||
**ماذا يُرجع نموذج اللغة الكبير (JSON بسيط):**
|
||||
```json
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Cornish pasty",
|
||||
"type": "Recipe"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**ما الذي ينتجه الكود (ثلاثيات RDF):**
|
||||
```python
|
||||
# 1. Normalize entity name + type to ID (type prevents collisions)
|
||||
entity_id = "recipe-cornish-pasty" # normalize("Cornish pasty", "Recipe")
|
||||
entity_uri = "https://trustgraph.ai/food/recipe-cornish-pasty"
|
||||
|
||||
# Note: Same name, different type = different URI
|
||||
# "Cornish pasty" (Recipe) → recipe-cornish-pasty
|
||||
# "Cornish pasty" (Food) → food-cornish-pasty
|
||||
|
||||
# 2. Generate triples
|
||||
triples = [
|
||||
# Type triple
|
||||
Triple(
|
||||
s=Value(value=entity_uri, is_uri=True),
|
||||
p=Value(value="http://www.w3.org/1999/02/22-rdf-syntax-ns#type", is_uri=True),
|
||||
o=Value(value="http://purl.org/ontology/fo/Recipe", is_uri=True)
|
||||
),
|
||||
# Label triple (automatic)
|
||||
Triple(
|
||||
s=Value(value=entity_uri, is_uri=True),
|
||||
p=Value(value="http://www.w3.org/2000/01/rdf-schema#label", is_uri=True),
|
||||
o=Value(value="Cornish pasty", is_uri=False)
|
||||
)
|
||||
]
|
||||
```
|
||||
|
||||
### المزايا
|
||||
|
||||
1. **نموذج اللغة الكبير (LLM) لا يحتاج إلى:**
|
||||
فهم بناء جمل URI
|
||||
اختراع بادئات المعرفات (`recipe:`، `ingredient:`)
|
||||
معرفة عن `rdf:type` أو `rdfs:label`
|
||||
إنشاء معرفات الويب الدلالي
|
||||
|
||||
2. **نموذج اللغة الكبير (LLM) يحتاج فقط إلى:**
|
||||
العثور على الكيانات في النص
|
||||
ربطها بفئات علم الوجود
|
||||
استخراج العلاقات والسمات
|
||||
|
||||
3. **الكود يتعامل مع:**
|
||||
تطبيع وبناء URI
|
||||
توليد ثلاثيات RDF
|
||||
تعيين تسميات تلقائيًا
|
||||
إدارة مساحات الأسماء
|
||||
|
||||
### لماذا هذا أفضل
|
||||
|
||||
**موجه أبسط** = تقليل الارتباك = تقليل الأخطاء
|
||||
**معرفات متسقة** = الكود يتحكم في قواعد التطبيع
|
||||
**تسميات مُولدة تلقائيًا** = لا توجد ثلاثيات rdfs:label مفقودة
|
||||
**يركز نموذج اللغة الكبير على الاستخراج** = وهو ما يتقنه بالفعل
|
||||
|
||||
### مثال: علاقات الكيانات
|
||||
|
||||
**النص المدخل:**
|
||||
```
|
||||
Cornish pasty is a traditional British pastry filled with beef and potatoes.
|
||||
```
|
||||
|
||||
**مخطط علم الوجود (معروض للنموذج اللغوي الكبير):**
|
||||
```markdown
|
||||
## Entity Types:
|
||||
- Recipe: A recipe is a combination of ingredients and a method
|
||||
- Food: A food is something that can be eaten
|
||||
- Ingredient: An ingredient combines a quantity and a food
|
||||
|
||||
## Relationships:
|
||||
- has_ingredient: Relates a recipe to an ingredient it uses (Recipe → Ingredient)
|
||||
- food: Relates an ingredient to the food that is required (Ingredient → Food)
|
||||
```
|
||||
|
||||
**ماذا يُرجع نموذج اللغة الكبير (JSON بسيط):**
|
||||
```json
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Cornish pasty",
|
||||
"type": "Recipe"
|
||||
},
|
||||
{
|
||||
"entity": "beef",
|
||||
"type": "Food"
|
||||
},
|
||||
{
|
||||
"entity": "potatoes",
|
||||
"type": "Food"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"subject": "Cornish pasty",
|
||||
"subject-type": "Recipe",
|
||||
"relation": "has_ingredient",
|
||||
"object": "beef",
|
||||
"object-type": "Food"
|
||||
},
|
||||
{
|
||||
"subject": "Cornish pasty",
|
||||
"subject-type": "Recipe",
|
||||
"relation": "has_ingredient",
|
||||
"object": "potatoes",
|
||||
"object-type": "Food"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**ما الذي ينتجه الكود (ثلاثيات RDF):**
|
||||
```python
|
||||
# Normalize entity names to URIs
|
||||
cornish_pasty_uri = "https://trustgraph.ai/food/cornish-pasty"
|
||||
beef_uri = "https://trustgraph.ai/food/beef"
|
||||
potatoes_uri = "https://trustgraph.ai/food/potatoes"
|
||||
|
||||
# Look up relation URI from ontology
|
||||
has_ingredient_uri = "http://purl.org/ontology/fo/ingredients" # from fo/has_ingredient
|
||||
|
||||
triples = [
|
||||
# Entity type triples (as before)
|
||||
Triple(s=cornish_pasty_uri, p=rdf_type, o="http://purl.org/ontology/fo/Recipe"),
|
||||
Triple(s=cornish_pasty_uri, p=rdfs_label, o="Cornish pasty"),
|
||||
|
||||
Triple(s=beef_uri, p=rdf_type, o="http://purl.org/ontology/fo/Food"),
|
||||
Triple(s=beef_uri, p=rdfs_label, o="beef"),
|
||||
|
||||
Triple(s=potatoes_uri, p=rdf_type, o="http://purl.org/ontology/fo/Food"),
|
||||
Triple(s=potatoes_uri, p=rdfs_label, o="potatoes"),
|
||||
|
||||
# Relationship triples
|
||||
Triple(
|
||||
s=Value(value=cornish_pasty_uri, is_uri=True),
|
||||
p=Value(value=has_ingredient_uri, is_uri=True),
|
||||
o=Value(value=beef_uri, is_uri=True)
|
||||
),
|
||||
Triple(
|
||||
s=Value(value=cornish_pasty_uri, is_uri=True),
|
||||
p=Value(value=has_ingredient_uri, is_uri=True),
|
||||
o=Value(value=potatoes_uri, is_uri=True)
|
||||
)
|
||||
]
|
||||
```
|
||||
|
||||
**النقاط الرئيسية:**
|
||||
تقوم نماذج اللغة الكبيرة بإرجاع أسماء الكيانات باللغة الطبيعية: `"Cornish pasty"`، `"beef"`، `"potatoes"`
|
||||
تتضمن نماذج اللغة الكبيرة أنواعًا لتوضيح المعنى: `subject-type`، `object-type`
|
||||
تستخدم نماذج اللغة الكبيرة اسم العلاقة من المخطط: `"has_ingredient"`
|
||||
تستخدم الشيفرة معرّفات متسقة باستخدام (الاسم، النوع): `("Cornish pasty", "Recipe")` → `recipe-cornish-pasty`
|
||||
تبحث الشيفرة عن عنوان URI للعلاقة من علم الوجود: `fo/has_ingredient` → عنوان URI الكامل
|
||||
دائمًا ما تحصل المجموعة نفسها (الاسم، النوع) على نفس عنوان URI (إزالة التكرار)
|
||||
|
||||
### مثال: التمييز بين أسماء الكيانات
|
||||
|
||||
**المشكلة:** يمكن أن يشير نفس الاسم إلى أنواع مختلفة من الكيانات.
|
||||
|
||||
**حالة واقعية:**
|
||||
```
|
||||
"Cornish pasty" can be:
|
||||
- A Recipe (instructions for making it)
|
||||
- A Food (the dish itself)
|
||||
```
|
||||
|
||||
**كيف يتم التعامل معها:**
|
||||
|
||||
يقوم نموذج اللغة الكبير بإرجاع كليهما ككيانات منفصلة:
|
||||
```json
|
||||
{
|
||||
"entities": [
|
||||
{"entity": "Cornish pasty", "type": "Recipe"},
|
||||
{"entity": "Cornish pasty", "type": "Food"}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"subject": "Cornish pasty",
|
||||
"subject-type": "Recipe",
|
||||
"relation": "produces",
|
||||
"object": "Cornish pasty",
|
||||
"object-type": "Food"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**حل التعليمات البرمجية:**
|
||||
```python
|
||||
# Different types → different URIs
|
||||
recipe_uri = normalize("Cornish pasty", "Recipe")
|
||||
# → "https://trustgraph.ai/food/recipe-cornish-pasty"
|
||||
|
||||
food_uri = normalize("Cornish pasty", "Food")
|
||||
# → "https://trustgraph.ai/food/food-cornish-pasty"
|
||||
|
||||
# Relationship connects them correctly
|
||||
triple = Triple(
|
||||
s=recipe_uri, # The Recipe
|
||||
p="http://purl.org/ontology/fo/produces",
|
||||
o=food_uri # The Food
|
||||
)
|
||||
```
|
||||
|
||||
**لماذا هذا يعمل:**
|
||||
يتم تضمين النوع في جميع المراجع (الكيانات، والعلاقات، والسمات).
|
||||
يستخدم الكود `(name, type)` كـ "مجموعة" (tuple) كمفتاح للبحث.
|
||||
لا يوجد غموض، ولا توجد تعارضات.
|
||||
|
||||
### مثال: سمات الكيان
|
||||
|
||||
**النص المدخل:**
|
||||
```
|
||||
This Cornish pasty recipe serves 4-6 people and takes 45 minutes to prepare.
|
||||
```
|
||||
|
||||
**مخطط علم الوجود (يُعرض على نموذج اللغة الكبير):**
|
||||
```markdown
|
||||
## Entity Types:
|
||||
- Recipe: A recipe is a combination of ingredients and a method
|
||||
|
||||
## Attributes:
|
||||
- serves: Indicates what the recipe is intended to serve (Recipe → text)
|
||||
- preparation_time: Time needed to prepare the recipe (Recipe → text)
|
||||
```
|
||||
|
||||
**ماذا يُرجع نموذج اللغة الكبير (JSON بسيط):**
|
||||
```json
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Cornish pasty recipe",
|
||||
"type": "Recipe"
|
||||
}
|
||||
],
|
||||
"attributes": [
|
||||
{
|
||||
"entity": "Cornish pasty recipe",
|
||||
"entity-type": "Recipe",
|
||||
"attribute": "serves",
|
||||
"value": "4-6 people"
|
||||
},
|
||||
{
|
||||
"entity": "Cornish pasty recipe",
|
||||
"entity-type": "Recipe",
|
||||
"attribute": "preparation_time",
|
||||
"value": "45 minutes"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**ما الذي ينتجه الكود (ثلاثيات RDF):**
|
||||
```python
|
||||
# Normalize entity name to URI
|
||||
recipe_uri = "https://trustgraph.ai/food/cornish-pasty-recipe"
|
||||
|
||||
# Look up attribute URIs from ontology
|
||||
serves_uri = "http://purl.org/ontology/fo/serves" # from fo/serves
|
||||
prep_time_uri = "http://purl.org/ontology/fo/preparation_time" # from fo/preparation_time
|
||||
|
||||
triples = [
|
||||
# Entity type triple
|
||||
Triple(
|
||||
s=Value(value=recipe_uri, is_uri=True),
|
||||
p=Value(value=rdf_type, is_uri=True),
|
||||
o=Value(value="http://purl.org/ontology/fo/Recipe", is_uri=True)
|
||||
),
|
||||
|
||||
# Label triple (automatic)
|
||||
Triple(
|
||||
s=Value(value=recipe_uri, is_uri=True),
|
||||
p=Value(value=rdfs_label, is_uri=True),
|
||||
o=Value(value="Cornish pasty recipe", is_uri=False)
|
||||
),
|
||||
|
||||
# Attribute triples (objects are literals, not URIs)
|
||||
Triple(
|
||||
s=Value(value=recipe_uri, is_uri=True),
|
||||
p=Value(value=serves_uri, is_uri=True),
|
||||
o=Value(value="4-6 people", is_uri=False) # Literal value!
|
||||
),
|
||||
Triple(
|
||||
s=Value(value=recipe_uri, is_uri=True),
|
||||
p=Value(value=prep_time_uri, is_uri=True),
|
||||
o=Value(value="45 minutes", is_uri=False) # Literal value!
|
||||
)
|
||||
]
|
||||
```
|
||||
|
||||
**النقاط الرئيسية:**
|
||||
يستخرج نموذج اللغة الكبير القيم الحرفية: `"4-6 people"`، `"45 minutes"`
|
||||
يتضمن نموذج اللغة الكبير نوع الكيان لتوضيح المعنى: `entity-type`
|
||||
يستخدم نموذج اللغة الكبير اسم الخاصية من المخطط: `"serves"`، `"preparation_time"`
|
||||
يبحث الكود عن عنوان URI للخاصية من خصائص نوع البيانات في علم الوجود.
|
||||
**الكائن هو قيمة حرفية** (`is_uri=False`)، وليس مرجع URI.
|
||||
تظل القيم كنص طبيعي، ولا تحتاج إلى تطبيع.
|
||||
|
||||
**الفرق عن العلاقات:**
|
||||
العلاقات: كل من الموضوع والمفعول به هما كيانات (URIs).
|
||||
الخصائص: الموضوع هو كيان (URI)، والمفعول به هو قيمة حرفية (نص/رقم).
|
||||
|
||||
### مثال كامل: الكيانات + العلاقات + الخصائص
|
||||
|
||||
**النص المدخل:**
|
||||
```
|
||||
Cornish pasty is a savory pastry filled with beef and potatoes.
|
||||
This recipe serves 4 people.
|
||||
```
|
||||
|
||||
**ماذا يُرجع نموذج اللغة الكبير:**
|
||||
```json
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"entity": "Cornish pasty",
|
||||
"type": "Recipe"
|
||||
},
|
||||
{
|
||||
"entity": "beef",
|
||||
"type": "Food"
|
||||
},
|
||||
{
|
||||
"entity": "potatoes",
|
||||
"type": "Food"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"subject": "Cornish pasty",
|
||||
"subject-type": "Recipe",
|
||||
"relation": "has_ingredient",
|
||||
"object": "beef",
|
||||
"object-type": "Food"
|
||||
},
|
||||
{
|
||||
"subject": "Cornish pasty",
|
||||
"subject-type": "Recipe",
|
||||
"relation": "has_ingredient",
|
||||
"object": "potatoes",
|
||||
"object-type": "Food"
|
||||
}
|
||||
],
|
||||
"attributes": [
|
||||
{
|
||||
"entity": "Cornish pasty",
|
||||
"entity-type": "Recipe",
|
||||
"attribute": "serves",
|
||||
"value": "4 people"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**النتيجة:** تم توليد 11 ثلاثية RDF:
|
||||
3 ثلاثيات لنوع الكيان (rdf:type)
|
||||
3 ثلاثيات لملصق الكيان (rdfs:label) - تلقائي
|
||||
2 ثلاثية للعلاقة (has_ingredient)
|
||||
1 ثلاثية للخاصية (serves)
|
||||
|
||||
كل ذلك من خلال استخلاص بسيط وسهل من اللغة الطبيعية بواسطة نموذج اللغة الكبير!
|
||||
|
||||
## المراجع
|
||||
|
||||
التنفيذ الحالي: `trustgraph-flow/trustgraph/extract/kg/ontology/extract.py`
|
||||
قالب التعليمات: `ontology-prompt.md`
|
||||
حالات الاختبار: `tests/unit/test_extract/test_ontology/`
|
||||
مثال على علم الوجود: `e2e/test-data/food.ontology`
|
||||
179
docs/tech-specs/ar/ontology.ar.md
Normal file
179
docs/tech-specs/ar/ontology.ar.md
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات التقنية لهيكل علم الأنطولوجيا"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات التقنية لهيكل علم الأنطولوجيا
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات الهيكل والتنسيق الخاص بعلم الأنطولوجيا داخل نظام TrustGraph. توفر الأنطولوجيا نماذج معرفية رسمية تحدد الفئات والخصائص والعلاقات، مما يدعم قدرات الاستدلال والاستنتاج. يستخدم النظام تنسيقًا مستوحى من OWL، والذي يمثل على نطاق واسع مفاهيم OWL/RDFS، مع تحسينه لتلبية متطلبات TrustGraph.
|
||||
|
||||
**اتفاقية التسمية:** يستخدم هذا المشروع نمط "kebab-case" لجميع المعرفات (مفاتيح التكوين، ونقاط نهاية واجهة برمجة التطبيقات، وأسماء الوحدات، إلخ) بدلاً من نمط "snake_case".
|
||||
|
||||
## الأهداف
|
||||
|
||||
- **إدارة الفئات والخصائص:** تحديد فئات تشبه OWL مع خصائص ومجالات ونطاقات وقيود النوع.
|
||||
- **دعم دلالي غني:** تمكين خصائص RDFS/OWL شاملة بما في ذلك التسميات ودعم لغات متعددة والقيود الرسمية.
|
||||
- **دعم أنطولوجيا متعددة:** السماح لعدة أنطولوجيا بالوجود والتفاعل مع بعضها البعض.
|
||||
- **التحقق والاستدلال:** ضمان توافق الأنطولوجيا مع معايير تشبه OWL مع التحقق من الاتساق ودعم الاستدلال.
|
||||
- **التوافق مع المعايير:** دعم الاستيراد/التصدير بتنسيقات قياسية (Turtle، RDF/XML، OWL/XML) مع الحفاظ على التحسين الداخلي.
|
||||
|
||||
## الخلفية
|
||||
|
||||
يخزن نظام TrustGraph الأنطولوجيا كعناصر تكوين في نظام مرن من المفاتيح والقيم. على الرغم من أن التنسيق مستوحى من OWL (Web Ontology Language)، إلا أنه مُحسَّن لحالات الاستخدام المحددة لـ TrustGraph ولا يلتزم بشكل صارم بجميع مواصفات OWL.
|
||||
|
||||
تُمكّن الأنطولوجيا في TrustGraph:
|
||||
- تعريف أنواع الكائنات الرسمية وخصائصها.
|
||||
- تحديد نطاقات وقيود أنواع الخصائص.
|
||||
- الاستدلال والاستنتاج المنطقي.
|
||||
- علاقات معقدة وقيود التعددية.
|
||||
- دعم لغات متعددة للترجمة.
|
||||
|
||||
## هيكل الأنطولوجيا
|
||||
|
||||
### تخزين التكوين
|
||||
|
||||
يتم تخزين الأنطولوجيا كعناصر تكوين بالنمط التالي:
|
||||
- **النوع:** `ontology`
|
||||
- **المفتاح:** معرف الأنطولوجيا الفريد (على سبيل المثال، `natural-world`، `domain-model`).
|
||||
- **القيمة:** الأنطولوجيا بأكملها بتنسيق JSON.
|
||||
|
||||
### هيكل JSON
|
||||
|
||||
يتكون تنسيق JSON للأنطولوجيا من أربعة أقسام رئيسية:
|
||||
|
||||
#### 1. البيانات الوصفية (Metadata)
|
||||
|
||||
يحتوي على معلومات إدارية ووصفية حول الأنطولوجيا:
|
||||
|
||||
```json
|
||||
{
|
||||
"metadata": {
|
||||
"name": "العالم الطبيعي",
|
||||
"description": "أنطولوجيا تغطي النظام الطبيعي",
|
||||
"version": "1.0.0",
|
||||
"created": "2025-09-20T12:07:37.068Z",
|
||||
"modified": "2025-09-20T12:12:20.725Z",
|
||||
"creator": "current-user",
|
||||
"namespace": "http://trustgraph.ai/ontologies/natural-world",
|
||||
"imports": ["http://www.w3.org/2002/07/owl#"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**الحقول:**
|
||||
- `name`: الاسم القابل للقراءة البشرية للأنطولوجيا.
|
||||
- `description`: وصف موجز لغرض الأنطولوجيا.
|
||||
- `version`: رقم الإصدار الدلالي.
|
||||
- `created`: طابع زمني ISO 8601 للإعداد.
|
||||
- `modified`: طابع زمني ISO 8601 للتعديل الأخير.
|
||||
- `creator`: معرف المستخدم/النظام الذي قام بإنشاء الأنطولوجيا.
|
||||
- `namespace`: عنوان URI الأساسي لعناصر الأنطولوجيا.
|
||||
- `imports`: مصفوفة من عناوين URI للأنطولوجيا المستوردة.
|
||||
|
||||
#### 2. الفئات (Classes)
|
||||
|
||||
تحدد أنواع الكائنات والعلاقات الهرمية بينها:
|
||||
|
||||
```json
|
||||
{
|
||||
"classes": {
|
||||
"animal": {
|
||||
"uri": "http://trustgraph.ai/ontologies/natural-world#animal",
|
||||
"type": "owl:Class",
|
||||
"rdfs:label": [{"value": "حيوان", "lang": "en"}],
|
||||
"rdfs:comment": "حيوان",
|
||||
"rdfs:subClassOf": "lifeform",
|
||||
"owl:equivalentClass": ["cat", "dog"],
|
||||
"owl:disjointWith": ["cat"]
|
||||
},
|
||||
"lifeform": {
|
||||
"uri": "http://trustgraph.ai/ontologies/natural-world#lifeform",
|
||||
"type": "owl:Class",
|
||||
"rdfs:label": [{"value": "كائن حي", "lang": "en"}],
|
||||
"rdfs:comment": "كائن حي"
|
||||
},
|
||||
"cat": {
|
||||
"uri": "http://trustgraph.ai/ontologies/natural-world#cat",
|
||||
"type": "owl:Class",
|
||||
"rdfs:label": [{"value": "قط", "lang": "en"}],
|
||||
"rdfs:comment": "قط",
|
||||
"rdfs:subClassOf": "animal"
|
||||
},
|
||||
"dog": {
|
||||
"uri": "http://trustgraph.ai/ontologies/natural-world#dog",
|
||||
"type": "owl:Class",
|
||||
"rdfs:label": [{"value": "كلب", "lang": "en"}],
|
||||
"rdfs:comment": "كلب",
|
||||
"rdfs:subClassOf": "animal",
|
||||
"owl:disjointWith": ["cat"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. الخصائص (Object Properties)
|
||||
|
||||
تحدد العلاقات بين الفئات:
|
||||
|
||||
```json
|
||||
{
|
||||
"objectProperties": {}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. خصائص البيانات (Data Properties)
|
||||
|
||||
تحدد الخصائص التي تربط الكائنات ببيانات:
|
||||
|
||||
```json
|
||||
{
|
||||
"datatypeProperties": {
|
||||
"number-of-legs": {
|
||||
"uri": "http://trustgraph.ai/ontologies/natural-world#number-of-legs",
|
||||
"type": "owl:DatatypeProperty",
|
||||
"rdfs:label": [{"value": "عدد الأرجل", "lang": "en"}],
|
||||
"rdfs:comment": "عدد أرجل الحيوان",
|
||||
"rdfs:range": "xsd:nonNegativeInteger",
|
||||
"rdfs:domain": "animal"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## قواعد التحقق
|
||||
|
||||
### التحقق الهيكلي
|
||||
|
||||
1. **اتساق URI:** يجب أن تتبع جميع عناوين URI النمط `{namespace}#{identifier}`.
|
||||
2. **هرمية الفئات:** لا توجد علاقات إرثية دائرية في `rdfs:subClassOf`.
|
||||
3. **نطاقات وقيود أنواع الخصائص:** يجب أن تشير إلى فئات موجودة أو أنواع XSD صالحة.
|
||||
4. **فئات متباينة:** لا يمكن أن تكون فئة فرعية من فئة أخرى.
|
||||
5. **خصائص عكسية:** يجب أن تكون ثنائية الاتجاه إذا تم تحديدها.
|
||||
|
||||
### التحقق الدلالي
|
||||
|
||||
1. **معرفات فريدة:** يجب أن تكون معرّفات الفئات والخصائص فريدة داخل أنطولوجيا واحدة.
|
||||
2. **علامات اللغة:** يجب أن تتبع تنسيق علامة اللغة BCP 47.
|
||||
3. **قيود التعددية:** يجب أن يكون `minCardinality` ≤ `maxCardinality` عند تحديد كليهما.
|
||||
4. **خصائص وظيفية:** لا يمكن أن يكون لها `maxCardinality` > 1.
|
||||
|
||||
## دعم تنسيق الاستيراد/التصدير
|
||||
|
||||
في حين أن التنسيق الداخلي هو JSON، يدعم النظام التحويل إلى/من تنسيقات الأنطولوجيا القياسية:
|
||||
|
||||
- **Turtle (.ttl):** تسلسل RDF مضغوط.
|
||||
- **RDF/XML (.rdf، .owl):** تنسيق W3C قياسي.
|
||||
- **OWL/XML (.owx):** تنسيق XML خاص بـ OWL.
|
||||
- **JSON-LD (.jsonld):** JSON للبيانات المرتبطة.
|
||||
|
||||
## المراجع
|
||||
|
||||
- [OWL 2 Web Ontology Language](https://www.w3.org/TR/owl2-overview/)
|
||||
- [RDF Schema 1.1](https://www.w3.org/TR/rdf-schema/)
|
||||
- [XML Schema Datatypes](https://www.w3.org/TR/xmlschema-2/)
|
||||
- [BCP 47 Language Tags](https://tools.ietf.org/html/bcp47)
|
||||
1075
docs/tech-specs/ar/ontorag.ar.md
Normal file
1075
docs/tech-specs/ar/ontorag.ar.md
Normal file
File diff suppressed because it is too large
Load diff
239
docs/tech-specs/ar/openapi-spec.ar.md
Normal file
239
docs/tech-specs/ar/openapi-spec.ar.md
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات OpenAPI - المواصفات الفنية"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات OpenAPI - المواصفات الفنية
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## الهدف
|
||||
|
||||
إنشاء مواصفات OpenAPI 3.1 شاملة وقابلة للتطوير لواجهة TrustGraph REST API التي:
|
||||
توثق جميع نقاط النهاية REST.
|
||||
تستخدم `$ref` خارجية من أجل modularity وقابلية الصيانة.
|
||||
تتوافق مباشرة مع كود مترجم الرسائل.
|
||||
توفر مخططات دقيقة للطلبات والاستجابات.
|
||||
|
||||
## المصدر الموثوق
|
||||
|
||||
يتم تعريف واجهة برمجة التطبيقات بواسطة:
|
||||
**مترجمو الرسائل**: `trustgraph-base/trustgraph/messaging/translators/*.py`
|
||||
**مدير الموزع**: `trustgraph-flow/trustgraph/gateway/dispatch/manager.py`
|
||||
**مدير نقطة النهاية**: `trustgraph-flow/trustgraph/gateway/endpoint/manager.py`
|
||||
|
||||
## هيكل الدليل
|
||||
|
||||
```
|
||||
openapi/
|
||||
├── openapi.yaml # Main entry point
|
||||
├── paths/
|
||||
│ ├── config.yaml # Global services
|
||||
│ ├── flow.yaml
|
||||
│ ├── librarian.yaml
|
||||
│ ├── knowledge.yaml
|
||||
│ ├── collection-management.yaml
|
||||
│ ├── flow-services/ # Flow-hosted services
|
||||
│ │ ├── agent.yaml
|
||||
│ │ ├── document-rag.yaml
|
||||
│ │ ├── graph-rag.yaml
|
||||
│ │ ├── text-completion.yaml
|
||||
│ │ ├── prompt.yaml
|
||||
│ │ ├── embeddings.yaml
|
||||
│ │ ├── mcp-tool.yaml
|
||||
│ │ ├── triples.yaml
|
||||
│ │ ├── objects.yaml
|
||||
│ │ ├── nlp-query.yaml
|
||||
│ │ ├── structured-query.yaml
|
||||
│ │ ├── structured-diag.yaml
|
||||
│ │ ├── graph-embeddings.yaml
|
||||
│ │ ├── document-embeddings.yaml
|
||||
│ │ ├── text-load.yaml
|
||||
│ │ └── document-load.yaml
|
||||
│ ├── import-export/
|
||||
│ │ ├── core-import.yaml
|
||||
│ │ ├── core-export.yaml
|
||||
│ │ └── flow-import-export.yaml # WebSocket import/export
|
||||
│ ├── websocket.yaml
|
||||
│ └── metrics.yaml
|
||||
├── components/
|
||||
│ ├── schemas/
|
||||
│ │ ├── config/
|
||||
│ │ ├── flow/
|
||||
│ │ ├── librarian/
|
||||
│ │ ├── knowledge/
|
||||
│ │ ├── collection/
|
||||
│ │ ├── ai-services/
|
||||
│ │ ├── common/
|
||||
│ │ └── errors/
|
||||
│ ├── parameters/
|
||||
│ ├── responses/
|
||||
│ └── examples/
|
||||
└── security/
|
||||
└── bearerAuth.yaml
|
||||
```
|
||||
|
||||
## ربط الخدمات
|
||||
|
||||
### الخدمات العامة (`/api/v1/{kind}`)
|
||||
`config` - إدارة التكوين
|
||||
`flow` - دورة حياة التدفق
|
||||
`librarian` - مكتبة المستندات
|
||||
`knowledge` - نوى المعرفة
|
||||
`collection-management` - بيانات وصفية للمجموعة
|
||||
|
||||
### الخدمات المستضافة على التدفق (`/api/v1/flow/{flow}/service/{kind}`)
|
||||
|
||||
**الطلب/الاستجابة:**
|
||||
`agent`, `text-completion`, `prompt`, `mcp-tool`
|
||||
`graph-rag`, `document-rag`
|
||||
`embeddings`, `graph-embeddings`, `document-embeddings`
|
||||
`triples`, `objects`, `nlp-query`, `structured-query`, `structured-diag`
|
||||
|
||||
**إرسال واستقبال:**
|
||||
`text-load`, `document-load`
|
||||
|
||||
### الاستيراد/التصدير
|
||||
`/api/v1/import-core` (POST)
|
||||
`/api/v1/export-core` (GET)
|
||||
`/api/v1/flow/{flow}/import/{kind}` (WebSocket)
|
||||
`/api/v1/flow/{flow}/export/{kind}` (WebSocket)
|
||||
|
||||
### أخرى
|
||||
`/api/v1/socket` (WebSocket متعدد)
|
||||
`/api/metrics` (Prometheus)
|
||||
|
||||
## النهج
|
||||
|
||||
### المرحلة الأولى: الإعداد
|
||||
1. إنشاء هيكل الدليل
|
||||
2. إنشاء ملف رئيسي `openapi.yaml` مع البيانات الوصفية والخوادم والأمان
|
||||
3. إنشاء مكونات قابلة لإعادة الاستخدام (أخطاء، معلمات شائعة، مخططات أمان)
|
||||
|
||||
### المرحلة الثانية: المخططات الشائعة
|
||||
إنشاء مخططات مشتركة تستخدم عبر الخدمات:
|
||||
`RdfValue`, `Triple` - هياكل RDF/ثلاثية
|
||||
`ErrorObject` - استجابة الخطأ
|
||||
`DocumentMetadata`, `ProcessingMetadata` - هياكل البيانات الوصفية
|
||||
المعلمات الشائعة: `FlowId`, `User`, `Collection`
|
||||
|
||||
### المرحلة الثالثة: الخدمات العامة
|
||||
لكل خدمة عامة (تكوين، تدفق، أمين مكتبة، معرفة، إدارة المجموعة):
|
||||
1. إنشاء ملف مسار في `paths/`
|
||||
2. إنشاء مخطط الطلب في `components/schemas/{service}/`
|
||||
3. إنشاء مخطط الاستجابة
|
||||
4. إضافة أمثلة
|
||||
5. الإشارة من الملف الرئيسي `openapi.yaml`
|
||||
|
||||
### المرحلة الرابعة: الخدمات المستضافة على التدفق
|
||||
لكل خدمة مستضافة على التدفق:
|
||||
1. إنشاء ملف مسار في `paths/flow-services/`
|
||||
2. إنشاء مخططات الطلب/الاستجابة في `components/schemas/ai-services/`
|
||||
3. إضافة وثائق علامة التدفق حيثما ينطبق
|
||||
4. الإشارة من الملف الرئيسي `openapi.yaml`
|
||||
|
||||
### المرحلة الخامسة: الاستيراد/التصدير و WebSocket
|
||||
1. توثيق نقاط النهاية الأساسية للاستيراد/التصدير
|
||||
2. توثيق أنماط بروتوكول WebSocket
|
||||
3. توثيق نقاط نهاية استيراد/تصدير WebSocket على مستوى التدفق
|
||||
|
||||
### المرحلة السادسة: التحقق من الصحة
|
||||
1. التحقق من الصحة باستخدام أدوات التحقق من صحة OpenAPI
|
||||
2. الاختبار باستخدام واجهة Swagger UI
|
||||
3. التحقق من تغطية جميع المترجمين
|
||||
|
||||
## اصطلاح تسمية الحقول
|
||||
|
||||
جميع الحقول في JSON تستخدم **kebab-case**:
|
||||
`flow-id`, `blueprint-name`, `doc-limit`, `entity-limit`، إلخ.
|
||||
|
||||
## إنشاء ملفات المخططات
|
||||
|
||||
لكل مترجم في `trustgraph-base/trustgraph/messaging/translators/`:
|
||||
|
||||
1. **قراءة طريقة مترجم `to_pulsar()`** - يحدد مخطط الطلب
|
||||
2. **قراءة طريقة مترجم `from_pulsar()`** - يحدد مخطط الاستجابة
|
||||
3. **استخراج أسماء وأنواع الحقول**
|
||||
4. **إنشاء مخطط OpenAPI** مع:
|
||||
أسماء الحقول (kebab-case)
|
||||
الأنواع (سلسلة، عدد صحيح، منطقي، كائن، مصفوفة)
|
||||
الحقول المطلوبة
|
||||
القيم الافتراضية
|
||||
الأوصاف
|
||||
|
||||
### مثال لعملية التعيين
|
||||
|
||||
```python
|
||||
# From retrieval.py DocumentRagRequestTranslator
|
||||
def to_pulsar(self, data: Dict[str, Any]) -> DocumentRagQuery:
|
||||
return DocumentRagQuery(
|
||||
query=data["query"], # required string
|
||||
user=data.get("user", "trustgraph"), # optional string, default "trustgraph"
|
||||
collection=data.get("collection", "default"), # optional string, default "default"
|
||||
doc_limit=int(data.get("doc-limit", 20)), # optional integer, default 20
|
||||
streaming=data.get("streaming", False) # optional boolean, default false
|
||||
)
|
||||
```
|
||||
|
||||
الترجمة:
|
||||
|
||||
```yaml
|
||||
# components/schemas/ai-services/DocumentRagRequest.yaml
|
||||
type: object
|
||||
required:
|
||||
- query
|
||||
properties:
|
||||
query:
|
||||
type: string
|
||||
description: Search query
|
||||
user:
|
||||
type: string
|
||||
default: trustgraph
|
||||
collection:
|
||||
type: string
|
||||
default: default
|
||||
doc-limit:
|
||||
type: integer
|
||||
default: 20
|
||||
description: Maximum number of documents to retrieve
|
||||
streaming:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Enable streaming responses
|
||||
```
|
||||
|
||||
## الاستجابات المتدفقة
|
||||
|
||||
الخدمات التي تدعم التدفق تُرجع استجابات متعددة مع العلامة `end_of_stream`:
|
||||
`agent`، `text-completion`، `prompt`
|
||||
`document-rag`، `graph-rag`
|
||||
|
||||
قم بتوثيق هذا النمط في مخطط استجابة كل خدمة.
|
||||
|
||||
## استجابات الأخطاء
|
||||
|
||||
يمكن لجميع الخدمات إرجاع:
|
||||
```yaml
|
||||
error:
|
||||
oneOf:
|
||||
- type: string
|
||||
- $ref: '#/components/schemas/ErrorObject'
|
||||
```
|
||||
|
||||
حيث أن `ErrorObject` هو:
|
||||
```yaml
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
```
|
||||
|
||||
## المراجع
|
||||
|
||||
المترجمون: `trustgraph-base/trustgraph/messaging/translators/`
|
||||
تعيين الموزع: `trustgraph-flow/trustgraph/gateway/dispatch/manager.py`
|
||||
توجيه نقطة النهاية: `trustgraph-flow/trustgraph/gateway/endpoint/manager.py`
|
||||
ملخص الخدمة: `API_SERVICES_SUMMARY.md`
|
||||
965
docs/tech-specs/ar/pubsub.ar.md
Normal file
965
docs/tech-specs/ar/pubsub.ar.md
Normal file
|
|
@ -0,0 +1,965 @@
|
|||
---
|
||||
layout: default
|
||||
title: "البنية التحتية للنشر والاشتراك (Pub/Sub)"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# البنية التحتية للنشر والاشتراك (Pub/Sub)
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يوثق هذا المستند جميع الاتصالات بين قاعدة بيانات TrustGraph والبنية التحتية للنشر والاشتراك. حاليًا، يتم ترميز النظام لاستخدام Apache Pulsar. تحدد هذه التحليلات جميع نقاط التكامل لإعلام عمليات إعادة الهيكلة المستقبلية نحو تجريد نشر واشتراك قابل للتكوين.
|
||||
|
||||
## الحالة الحالية: نقاط تكامل Pulsar
|
||||
|
||||
### 1. استخدام عميل Pulsar المباشر
|
||||
|
||||
**الموقع:** `trustgraph-flow/trustgraph/gateway/service.py`
|
||||
|
||||
يقوم بوابة واجهة برمجة التطبيقات باستيراد وتثبيت عميل Pulsar مباشرةً:
|
||||
|
||||
**السطر 20:** `import pulsar`
|
||||
**الأسطر 54-61:** تثبيت مباشر لـ `pulsar.Client()` مع `pulsar.AuthenticationToken()` الاختياري
|
||||
**الأسطر 33-35:** تكوين مضيف Pulsar الافتراضي من متغيرات البيئة
|
||||
**الأسطر 178-192:** وسيطات سطر الأوامر لـ `--pulsar-host`، `--pulsar-api-key`، و `--pulsar-listener`
|
||||
**الأسطر 78، 124:** تمرير `pulsar_client` إلى `ConfigReceiver` و `DispatcherManager`
|
||||
|
||||
هذا هو الموقع الوحيد الذي يقوم بتثبيت عميل Pulsar مباشرةً خارج طبقة التجريد.
|
||||
|
||||
### 2. إطار عمل المعالج الأساسي
|
||||
|
||||
**الموقع:** `trustgraph-base/trustgraph/base/async_processor.py`
|
||||
|
||||
يوفر الفئة الأساسية لجميع المعالجات اتصال Pulsar:
|
||||
|
||||
**السطر 9:** `import _pulsar` (للتعامل مع الاستثناءات)
|
||||
**السطر 18:** `from . pubsub import PulsarClient`
|
||||
**السطر 38:** إنشاء `pulsar_client_object = PulsarClient(**params)`
|
||||
**الأسطر 104-108:** خصائص تعرض `pulsar_host` و `pulsar_client`
|
||||
**السطر 250:** تستدعي الطريقة الثابتة `add_args()` `PulsarClient.add_args(parser)` لوسيطات سطر الأوامر
|
||||
**الأسطر 223-225:** معالجة الاستثناءات لـ `_pulsar.Interrupted`
|
||||
|
||||
ترث جميع المعالجات من `AsyncProcessor`، مما يجعل هذا نقطة التكامل المركزية.
|
||||
|
||||
### 3. تجريد المستهلك
|
||||
|
||||
**الموقع:** `trustgraph-base/trustgraph/base/consumer.py`
|
||||
|
||||
يستهلك الرسائل من قوائم الانتظار ويستدعي وظائف المعالج:
|
||||
|
||||
**استيرادات Pulsar:**
|
||||
**السطر 12:** `from pulsar.schema import JsonSchema`
|
||||
**السطر 13:** `import pulsar`
|
||||
**السطر 14:** `import _pulsar`
|
||||
|
||||
**الاستخدام المحدد لـ Pulsar:**
|
||||
**الأسطر 100، 102:** `pulsar.InitialPosition.Earliest` / `pulsar.InitialPosition.Latest`
|
||||
**السطر 108:** غلاف `JsonSchema(self.schema)`
|
||||
**السطر 110:** `pulsar.ConsumerType.Shared`
|
||||
**الأسطر 104-111:** `self.client.subscribe()` مع معلمات خاصة بـ Pulsar
|
||||
**الأسطر 143، 150، 65:** طرق `consumer.unsubscribe()` و `consumer.close()`
|
||||
**السطر 162:** استثناء `_pulsar.Timeout`
|
||||
**الأسطر 182، 205، 232:** `consumer.acknowledge()` / `consumer.negative_acknowledge()`
|
||||
|
||||
**ملف المواصفات:** `trustgraph-base/trustgraph/base/consumer_spec.py`
|
||||
**السطر 22:** يشير إلى `processor.pulsar_client`
|
||||
|
||||
### 4. تجريد الناشر
|
||||
|
||||
**الموقع:** `trustgraph-base/trustgraph/base/producer.py`
|
||||
|
||||
يرسل الرسائل إلى قوائم الانتظار:
|
||||
|
||||
**استيرادات Pulsar:**
|
||||
**السطر 2:** `from pulsar.schema import JsonSchema`
|
||||
|
||||
**الاستخدام المحدد لـ Pulsar:**
|
||||
**السطر 49:** غلاف `JsonSchema(self.schema)`
|
||||
**الأسطر 47-51:** `self.client.create_producer()` مع معلمات خاصة بـ Pulsar (الموضوع، المخطط، تمكين التجزئة)
|
||||
**الأسطر 31، 76:** طريقة `producer.close()`
|
||||
**الأسطر 64-65:** `producer.send()` مع الرسالة والخصائص
|
||||
|
||||
**ملف المواصفات:** `trustgraph-base/trustgraph/base/producer_spec.py`
|
||||
**السطر 18:** يشير إلى `processor.pulsar_client`
|
||||
|
||||
### 5. تجريد الناشر
|
||||
|
||||
**الموقع:** `trustgraph-base/trustgraph/base/publisher.py`
|
||||
|
||||
نشر الرسائل بشكل غير متزامن مع تخزين الرسائل مؤقتًا في قائمة الانتظار:
|
||||
|
||||
**استيرادات Pulsar:**
|
||||
**السطر 2:** `from pulsar.schema import JsonSchema`
|
||||
**السطر 6:** `import pulsar`
|
||||
|
||||
**الاستخدام المحدد لـ Pulsar:**
|
||||
**السطر 52:** غلاف `JsonSchema(self.schema)`
|
||||
**الأسطر 50-54:** `self.client.create_producer()` مع معلمات خاصة بـ Pulsar
|
||||
**الأسطر 101، 103:** `producer.send()` مع الرسالة والخصائص الاختيارية
|
||||
**الأسطر 106-107:** طرق `producer.flush()` و `producer.close()`
|
||||
|
||||
### 6. تجريد المشترك
|
||||
|
||||
**الموقع:** `trustgraph-base/trustgraph/base/subscriber.py`
|
||||
|
||||
يوفر توزيع رسائل متعددة المستلمين من خلال قوائم الانتظار:
|
||||
|
||||
**استيرادات Pulsar:**
|
||||
**السطر 6:** `from pulsar.schema import JsonSchema`
|
||||
**السطر 8:** `import _pulsar`
|
||||
|
||||
**الاستخدام الخاص بـ Pulsar:**
|
||||
**السطر 55:** `JsonSchema(self.schema)` wrapper
|
||||
**السطر 57:** `self.client.subscribe(**subscribe_args)`
|
||||
**الأسطر 101، 136، 160، 167-172:** استثناءات Pulsar: `_pulsar.Timeout`, `_pulsar.InvalidConfiguration`, `_pulsar.AlreadyClosed`
|
||||
**الأسطر 159، 166، 170:** طرق المستهلك: `negative_acknowledge()`, `unsubscribe()`, `close()`
|
||||
**الأسطر 247، 251:** إقرار الرسالة: `acknowledge()`, `negative_acknowledge()`
|
||||
|
||||
**ملف المواصفات:** `trustgraph-base/trustgraph/base/subscriber_spec.py`
|
||||
**السطر 19:** يشير إلى `processor.pulsar_client`
|
||||
|
||||
### 7. نظام المخططات (قلب الظلام)
|
||||
|
||||
**الموقع:** `trustgraph-base/trustgraph/schema/`
|
||||
|
||||
يتم تعريف كل مخطط رسالة في النظام باستخدام إطار عمل المخططات الخاص بـ Pulsar.
|
||||
|
||||
**المكونات الأساسية:** `schema/core/primitives.py`
|
||||
**السطر 2:** `from pulsar.schema import Record, String, Boolean, Array, Integer`
|
||||
ترث جميع المخططات من الفئة الأساسية `Record` الخاصة بـ Pulsar
|
||||
جميع أنواع الحقول هي أنواع Pulsar: `String()`, `Integer()`, `Boolean()`, `Array()`, `Map()`, `Double()`
|
||||
|
||||
**أمثلة على المخططات:**
|
||||
`schema/services/llm.py` (السطر 2): `from pulsar.schema import Record, String, Array, Double, Integer, Boolean`
|
||||
`schema/services/config.py` (السطر 2): `from pulsar.schema import Record, Bytes, String, Boolean, Array, Map, Integer`
|
||||
|
||||
**تسمية الموضوع:** `schema/core/topic.py`
|
||||
**الأسطر 2-3:** تنسيق الموضوع: `{kind}://{tenant}/{namespace}/{topic}`
|
||||
هذه البنية URI خاصة بـ Pulsar (على سبيل المثال، `persistent://tg/flow/config`)
|
||||
|
||||
**التأثير:**
|
||||
تستخدم جميع تعريفات الرسائل/الردود في قاعدة التعليمات البرمجية مخططات Pulsar
|
||||
يتضمن ذلك الخدمات الخاصة بـ: config, flow, llm, prompt, query, storage, agent, collection, diagnosis, library, lookup, nlp_query, objects_query, retrieval, structured_query
|
||||
يتم استيراد تعريفات المخططات واستخدامها على نطاق واسع في جميع المعالجات والخدمات
|
||||
|
||||
## ملخص
|
||||
|
||||
### تبعيات Pulsar حسب الفئة
|
||||
|
||||
1. **إنشاء العميل:**
|
||||
مباشر: `gateway/service.py`
|
||||
مجرد: `async_processor.py` → `pubsub.py` (PulsarClient)
|
||||
|
||||
2. **نقل الرسائل:**
|
||||
المستهلك: `consumer.py`, `consumer_spec.py`
|
||||
المنتج: `producer.py`, `producer_spec.py`
|
||||
الناشر: `publisher.py`
|
||||
المشترك: `subscriber.py`, `subscriber_spec.py`
|
||||
|
||||
3. **نظام المخططات:**
|
||||
الأنواع الأساسية: `schema/core/primitives.py`
|
||||
جميع مخططات الخدمة: `schema/services/*.py`
|
||||
تسمية الموضوع: `schema/core/topic.py`
|
||||
|
||||
4. **مفاهيم Pulsar الخاصة المطلوبة:**
|
||||
رسائل قائمة على الموضوع
|
||||
نظام المخططات (السجل، أنواع الحقول)
|
||||
اشتراكات مشتركة
|
||||
إقرار الرسالة (إيجابي/سلبي)
|
||||
موضع المستهلك (الأول/الأخير)
|
||||
خصائص الرسالة
|
||||
المواضع الأولية وأنواع المستهلك
|
||||
دعم التجزئة
|
||||
مواضيع مستمرة مقابل مواضيع غير مستمرة
|
||||
|
||||
### تحديات إعادة الهيكلة
|
||||
|
||||
الخبر السار: توفر طبقة التجريد (المستهلك، المنتج، الناشر، المشترك) تغليفًا نظيفًا لمعظم تفاعلات Pulsar.
|
||||
|
||||
التحديات:
|
||||
1. **انتشار نظام المخططات:** يستخدم كل تعريف للرسالة `pulsar.schema.Record` وأنواع Pulsar للحقول
|
||||
2. **قوائم Pulsar الخاصة:** `InitialPosition`, `ConsumerType`
|
||||
3. **استثناءات Pulsar:** `_pulsar.Timeout`, `_pulsar.Interrupted`, `_pulsar.InvalidConfiguration`, `_pulsar.AlreadyClosed`
|
||||
4. **توقيعات الطريقة:** `acknowledge()`, `negative_acknowledge()`, `subscribe()`, `create_producer()`، إلخ.
|
||||
5. **تنسيق URI للموضوع:** هيكل Pulsar `kind://tenant/namespace/topic`
|
||||
|
||||
### الخطوات التالية
|
||||
|
||||
لجعل البنية التحتية للنشر/الاشتراك قابلة للتكوين، نحتاج إلى:
|
||||
|
||||
1. إنشاء واجهة تجريد لنظام العميل/المخططات
|
||||
2. تجريد قوائم Pulsar الخاصة والاستثناءات
|
||||
3. إنشاء أغلفة المخططات أو تعريفات مخططات بديلة
|
||||
4. تنفيذ الواجهة لكل من Pulsar وأنظمة بديلة (Kafka, RabbitMQ, Redis Streams, إلخ.)
|
||||
5. تحديث `pubsub.py` ليكون قابلاً للتكوين ودعم الخلفيات المتعددة
|
||||
6. توفير مسار ترحيل للنشر الحالي
|
||||
|
||||
## مسودة النهج 1: نمط المحول مع طبقة ترجمة المخططات
|
||||
|
||||
### الفكرة الرئيسية
|
||||
**نظام المخططات** هو نقطة التكامل الأعمق - كل شيء آخر ينبع منه. نحتاج إلى حل هذه المشكلة أولاً، وإلا سنعيد كتابة قاعدة التعليمات البرمجية بأكملها.
|
||||
|
||||
### الاستراتيجية: الحد الأدنى من الاضطرابات مع المحولات
|
||||
|
||||
**1. الحفاظ على مخططات Pulsar كتمثيل داخلي**
|
||||
لا تقم بإعادة كتابة جميع تعريفات المخططات.
|
||||
تبقى المخططات `pulsar.schema.Record` داخليًا.
|
||||
استخدم المحولات لترجمة البيانات عند الحد بين التعليمات البرمجية الخاصة بنا والخلفية الخاصة بالنشر والاشتراك.
|
||||
|
||||
**2. إنشاء طبقة تجريدية للنشر والاشتراك:**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Existing Code (unchanged) │
|
||||
│ - Uses Pulsar schemas internally │
|
||||
│ - Consumer/Producer/Publisher │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────┴──────────────────────┐
|
||||
│ PubSubFactory (configurable) │
|
||||
│ - Creates backend-specific client │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────┴──────┐
|
||||
│ │
|
||||
┌───────▼─────┐ ┌────▼─────────┐
|
||||
│ PulsarAdapter│ │ KafkaAdapter │ etc...
|
||||
│ (passthrough)│ │ (translates) │
|
||||
└──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
**3. تحديد الواجهات المجردة:**
|
||||
`PubSubClient` - اتصال العميل
|
||||
`PubSubProducer` - إرسال الرسائل
|
||||
`PubSubConsumer` - استقبال الرسائل
|
||||
`SchemaAdapter` - ترجمة مخططات Pulsar إلى/من JSON أو التنسيقات الخاصة بالخلفية
|
||||
|
||||
**4. تفاصيل التنفيذ:**
|
||||
|
||||
بالنسبة إلى **محول Pulsar**: تمرير تقريبي، ترجمة محدودة
|
||||
|
||||
بالنسبة إلى **الخلفيات الأخرى** (Kafka، RabbitMQ، إلخ):
|
||||
تسلسل كائنات سجل Pulsar إلى JSON/بايت
|
||||
مطابقة المفاهيم مثل:
|
||||
`InitialPosition.Earliest/Latest` → auto.offset.reset في Kafka
|
||||
`acknowledge()` → commit في Kafka
|
||||
`negative_acknowledge()` → نمط إعادة الترتيب أو قائمة الانتظار الميتة (DLQ)
|
||||
عناوين الموضوع → أسماء الموضوعات الخاصة بالخلفية
|
||||
|
||||
### التحليل
|
||||
|
||||
**المزايا:**
|
||||
✅ تغييرات قليلة في التعليمات البرمجية للخدمات الحالية
|
||||
✅ تبقى المخططات كما هي (بدون إعادة كتابة شاملة)
|
||||
✅ مسار ترحيل تدريجي
|
||||
✅ لا يلاحظ مستخدمو Pulsar أي فرق
|
||||
✅ إضافة خلفيات جديدة عبر المحولات
|
||||
|
||||
**العيوب:**
|
||||
⚠️ لا يزال يعتمد على Pulsar (لتحديد المخططات)
|
||||
⚠️ بعض عدم التطابق في ترجمة المفاهيم
|
||||
|
||||
### بديل يجب أخذه في الاعتبار
|
||||
|
||||
إنشاء **نظام مخططات TrustGraph** مستقل عن النشر والاشتراك (باستخدام فئات البيانات أو Pydantic)، ثم إنشاء مخططات Pulsar/Kafka/إلخ من ذلك. يتطلب هذا إعادة كتابة كل ملف مخطط وقد يؤدي إلى تغييرات غير متوقعة.
|
||||
|
||||
### التوصية للإصدار الأول
|
||||
|
||||
ابدأ بـ **نهج المحول** لأنه:
|
||||
1. عملي - يعمل مع التعليمات البرمجية الحالية
|
||||
2. يثبت المفهوم بأقل قدر من المخاطر
|
||||
3. يمكن أن يتطور إلى نظام مخططات أصلي لاحقًا إذا لزم الأمر
|
||||
4. مدفوع بالتكوين: متغير بيئة واحد يقوم بتبديل الخلفيات
|
||||
|
||||
## النهج المقترح للإصدار الثاني: نظام مخططات مستقل عن الخلفية باستخدام فئات البيانات
|
||||
|
||||
### المفهوم الأساسي
|
||||
|
||||
استخدم **فئات البيانات** في Python كتنسيق تعريف مخطط محايد. توفر كل خلفية نشر واشتراك الخاصة بها تسلسلًا/إلغاء تسلسل لـ فئات البيانات، مما يلغي الحاجة إلى بقاء مخططات Pulsar في قاعدة التعليمات البرمجية.
|
||||
|
||||
### تعدد الأشكال للمخططات على مستوى المصنع
|
||||
|
||||
بدلاً من ترجمة مخططات Pulsar، **توفر كل خلفية معالجتها الخاصة للمخططات** والتي تعمل مع فئات البيانات القياسية في Python.
|
||||
|
||||
### تدفق الناشر
|
||||
|
||||
```python
|
||||
# 1. Get the configured backend from factory
|
||||
pubsub = get_pubsub() # Returns PulsarBackend, MQTTBackend, etc.
|
||||
|
||||
# 2. Get schema class from the backend
|
||||
# (Can be imported directly - backend-agnostic)
|
||||
from trustgraph.schema.services.llm import TextCompletionRequest
|
||||
|
||||
# 3. Create a producer/publisher for a specific topic
|
||||
producer = pubsub.create_producer(
|
||||
topic="text-completion-requests",
|
||||
schema=TextCompletionRequest # Tells backend what schema to use
|
||||
)
|
||||
|
||||
# 4. Create message instances (same API regardless of backend)
|
||||
request = TextCompletionRequest(
|
||||
system="You are helpful",
|
||||
prompt="Hello world",
|
||||
streaming=False
|
||||
)
|
||||
|
||||
# 5. Send the message
|
||||
producer.send(request) # Backend serializes appropriately
|
||||
```
|
||||
|
||||
### تدفق المستهلك
|
||||
|
||||
```python
|
||||
# 1. Get the configured backend
|
||||
pubsub = get_pubsub()
|
||||
|
||||
# 2. Create a consumer
|
||||
consumer = pubsub.subscribe(
|
||||
topic="text-completion-requests",
|
||||
schema=TextCompletionRequest # Tells backend how to deserialize
|
||||
)
|
||||
|
||||
# 3. Receive and deserialize
|
||||
msg = consumer.receive()
|
||||
request = msg.value() # Returns TextCompletionRequest dataclass instance
|
||||
|
||||
# 4. Use the data (type-safe access)
|
||||
print(request.system) # "You are helpful"
|
||||
print(request.prompt) # "Hello world"
|
||||
print(request.streaming) # False
|
||||
```
|
||||
|
||||
### ما الذي يحدث وراء الكواليس
|
||||
|
||||
**للخلفية التقنية لـ Pulsar:**
|
||||
`create_producer()` → ينشئ مُنتج Pulsar باستخدام مخطط JSON أو سجل تم إنشاؤه ديناميكيًا.
|
||||
`send(request)` → يقوم بتسلسل كائن البيانات (dataclass) إلى تنسيق JSON/Pulsar، ويرسله إلى Pulsar.
|
||||
`receive()` → يستقبل رسالة Pulsar، ويقوم بإلغاء تسلسلها مرة أخرى إلى كائن البيانات.
|
||||
|
||||
**للخلفية التقنية لـ MQTT:**
|
||||
`create_producer()` → يتصل بخادم MQTT، ولا يلزم تسجيل أي مخطط.
|
||||
`send(request)` → يحول كائن البيانات إلى JSON، وينشره في موضوع MQTT.
|
||||
`receive()` → يشترك في موضوع MQTT، ويقوم بإلغاء تسلسل JSON إلى كائن بيانات.
|
||||
|
||||
**للخلفية التقنية لـ Kafka:**
|
||||
`create_producer()` → ينشئ مُنتج Kafka، ويسجل مخطط Avro إذا لزم الأمر.
|
||||
`send(request)` → يقوم بتسلسل كائن البيانات إلى تنسيق Avro، ويرسله إلى Kafka.
|
||||
`receive()` → يستقبل رسالة Kafka، ويقوم بإلغاء تسلسل Avro مرة أخرى إلى كائن بيانات.
|
||||
|
||||
### النقاط الرئيسية في التصميم
|
||||
|
||||
1. **إنشاء كائن المخطط**: نسخة كائن البيانات (`TextCompletionRequest(...)`) متطابقة بغض النظر عن الخلفية التقنية.
|
||||
2. **الخلفية التقنية تتعامل مع الترميز**: كل خلفية تقنية تعرف كيفية تسلسل كائن البيانات الخاص بها إلى التنسيق المستخدم.
|
||||
3. **تعريف المخطط عند الإنشاء**: عند إنشاء المنتج/المستهلك، تحدد نوع المخطط.
|
||||
4. **الحفاظ على سلامة النوع**: تحصل على كائن `TextCompletionRequest` صحيح، وليس قاموسًا.
|
||||
5. **لا يوجد تسرب للخلفية التقنية**: لا يقوم كود التطبيق باستيراد مكتبات خاصة بالخلفية التقنية.
|
||||
|
||||
### مثال للتحويل
|
||||
|
||||
**الحالي (خاص بـ Pulsar):**
|
||||
```python
|
||||
# schema/services/llm.py
|
||||
from pulsar.schema import Record, String, Boolean, Integer
|
||||
|
||||
class TextCompletionRequest(Record):
|
||||
system = String()
|
||||
prompt = String()
|
||||
streaming = Boolean()
|
||||
```
|
||||
|
||||
**جديد (لا يعتمد على الواجهة الخلفية):**
|
||||
```python
|
||||
# schema/services/llm.py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class TextCompletionRequest:
|
||||
system: str
|
||||
prompt: str
|
||||
streaming: bool = False
|
||||
```
|
||||
|
||||
### التكامل مع الواجهة الخلفية (Backend Integration)
|
||||
|
||||
كل واجهة خلفية تتعامل مع التسلسل/إلغاء التسلسل لفئات البيانات (dataclasses):
|
||||
|
||||
**واجهة خلفية Pulsar:**
|
||||
إنشاء فئات `pulsar.schema.Record` ديناميكيًا من فئات البيانات.
|
||||
أو تسلسل فئات البيانات إلى JSON واستخدام مخطط JSON الخاص بـ Pulsar.
|
||||
تحافظ على التوافق مع عمليات نشر Pulsar الحالية.
|
||||
|
||||
**واجهة خلفية MQTT/Redis:**
|
||||
تسلسل JSON مباشر لمثيل فئة البيانات.
|
||||
استخدم `dataclasses.asdict()` / `from_dict()`.
|
||||
خفيفة الوزن، لا تحتاج إلى سجل مخططات.
|
||||
|
||||
**واجهة خلفية Kafka:**
|
||||
إنشاء مخططات Avro من تعريفات فئات البيانات.
|
||||
استخدم سجل مخططات Confluent.
|
||||
تسلسل آمن من حيث النوع مع دعم تطور المخطط.
|
||||
|
||||
### البنية (Architecture)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Application Code │
|
||||
│ - Uses dataclass schemas │
|
||||
│ - Backend-agnostic │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────────────┴──────────────────────┐
|
||||
│ PubSubFactory (configurable) │
|
||||
│ - get_pubsub() returns backend │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────┴──────┐
|
||||
│ │
|
||||
┌───────▼─────────┐ ┌────▼──────────────┐
|
||||
│ PulsarBackend │ │ MQTTBackend │
|
||||
│ - JSON schema │ │ - JSON serialize │
|
||||
│ - or dynamic │ │ - Simple queues │
|
||||
│ Record gen │ │ │
|
||||
└─────────────────┘ └───────────────────┘
|
||||
```
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
**1. تعريفات المخططات:** فئات بيانات بسيطة مع تلميحات الأنواع
|
||||
`str`، `int`، `bool`، `float` للقيم الأولية
|
||||
`list[T]` للمصفوفات
|
||||
`dict[str, T]` للخرائط
|
||||
فئات بيانات متداخلة للأنواع المعقدة
|
||||
|
||||
**2. يوفر كل خلفية:**
|
||||
المُسلسل: `dataclass → bytes/wire format`
|
||||
المُفكك: `bytes/wire format → dataclass`
|
||||
تسجيل المخطط (إذا لزم الأمر، مثل Pulsar/Kafka)
|
||||
|
||||
**3. تجريد المستهلك/المنتج:**
|
||||
موجود بالفعل (consumer.py, producer.py)
|
||||
تحديث لاستخدام التسلسل الخاص بالخلفية
|
||||
إزالة استيرادات Pulsar المباشرة
|
||||
|
||||
**4. تعيينات الأنواع:**
|
||||
Pulsar `String()` → Python `str`
|
||||
Pulsar `Integer()` → Python `int`
|
||||
Pulsar `Boolean()` → Python `bool`
|
||||
Pulsar `Array(T)` → Python `list[T]`
|
||||
Pulsar `Map(K, V)` → Python `dict[K, V]`
|
||||
Pulsar `Double()` → Python `float`
|
||||
Pulsar `Bytes()` → Python `bytes`
|
||||
|
||||
### مسار الترحيل
|
||||
|
||||
1. **إنشاء إصدارات من فئات البيانات** لجميع المخططات في `trustgraph/schema/`
|
||||
2. **تحديث الفئات الخلفية** (المستهلك، المنتج، الناشر، المشترك) لاستخدام التسلسل المقدم من الخلفية
|
||||
3. **تنفيذ PulsarBackend** باستخدام مخطط JSON أو إنشاء سجل ديناميكي
|
||||
4. **الاختبار مع Pulsar** للتأكد من التوافق مع الإصدارات السابقة للنشر
|
||||
5. **إضافة خلفيات جديدة** (MQTT، Kafka، Redis، إلخ) حسب الحاجة
|
||||
6. **إزالة استيرادات Pulsar** من ملفات المخططات
|
||||
|
||||
### الفوائد
|
||||
|
||||
✅ **لا يوجد اعتماد على النشر/الاشتراك** في تعريفات المخططات
|
||||
✅ **Python قياسي** - سهل الفهم، التحقق من النوع، التوثيق
|
||||
✅ **أدوات حديثة** - تعمل مع mypy، إكمال التعليمات البرمجية لبيئات التطوير المتكاملة، المدققين
|
||||
✅ **محسّنة للخلفية** - تستخدم كل خلفية التسلسل الأصلي
|
||||
✅ **لا توجد تكلفة ترجمة** - تسلسل مباشر، بدون محولات
|
||||
✅ **أمان النوع** - كائنات حقيقية مع أنواع مناسبة
|
||||
✅ **التحقق السهل** - يمكن استخدام Pydantic إذا لزم الأمر
|
||||
|
||||
### التحديات والحلول
|
||||
|
||||
**التحدي:** يحتوي Pulsar's `Record` على تحقق من صحة الحقول في وقت التشغيل
|
||||
**الحل:** استخدم فئات بيانات Pydantic للتحقق من الصحة إذا لزم الأمر، أو ميزات فئة البيانات Python 3.10+ مع `__post_init__`
|
||||
|
||||
**التحدي:** بعض ميزات Pulsar الخاصة (مثل نوع `Bytes`)
|
||||
**الحل:** قم بتعيين إلى نوع `bytes` في فئة البيانات، تتعامل الخلفية مع الترميز بشكل مناسب
|
||||
|
||||
**التحدي:** تسمية الموضوع (`persistent://tenant/namespace/topic`)
|
||||
**الحل:** قم بتجريد أسماء الموضوع في تعريفات المخططات، تقوم الخلفية بتحويلها إلى التنسيق المناسب
|
||||
|
||||
**التحدي:** تطور المخططات والتحكم في الإصدار
|
||||
**الحل:** تتعامل كل خلفية مع هذا وفقًا لقدراتها (إصدارات مخطط Pulsar، سجل مخطط Kafka، إلخ)
|
||||
|
||||
**التحدي:** الأنواع المعقدة المتداخلة
|
||||
**الحل:** استخدم فئات بيانات متداخلة، تقوم الخلفيات بالتسلسل/فك التسلسل بشكل متكرر
|
||||
|
||||
### قرارات التصميم
|
||||
|
||||
1. **فئات بيانات عادية أو Pydantic؟**
|
||||
✅ **القرار: استخدم فئات بيانات Python عادية**
|
||||
أبسط، بدون تبعيات إضافية
|
||||
التحقق من الصحة ليس مطلوبًا عمليًا
|
||||
أسهل في الفهم والصيانة
|
||||
|
||||
2. **تطور المخطط:**
|
||||
✅ **القرار: لا يلزم آلية للتحكم في الإصدار**
|
||||
المخططات مستقرة وطويلة الأمد
|
||||
عادةً ما تضيف التحديثات حقولًا جديدة (متوافقة مع الإصدارات السابقة)
|
||||
تتعامل الخلفيات مع تطور المخطط وفقًا لقدراتها
|
||||
|
||||
3. **التوافق مع الإصدارات السابقة:**
|
||||
✅ **القرار: تغيير رئيسي للإصدار، لا يلزم التوافق مع الإصدارات السابقة**
|
||||
سيكون هذا تغييرًا جذريًا مع تعليمات ترحيل
|
||||
يسمح الفصل النظيف بتصميم أفضل
|
||||
سيتم توفير دليل ترحيل للنشر الحالي
|
||||
|
||||
4. **الأنواع المتداخلة والهياكل المعقدة:**
|
||||
✅ **القرار: استخدم فئات بيانات متداخلة بشكل طبيعي**
|
||||
تتعامل فئات بيانات Python مع التداخل بشكل مثالي
|
||||
`list[T]` للمصفوفات، `dict[K, V]` للخرائط
|
||||
تقوم الخلفيات بالتسلسل/فك التسلسل بشكل متكرر
|
||||
مثال:
|
||||
```python
|
||||
@dataclass
|
||||
class Value:
|
||||
value: str
|
||||
is_uri: bool
|
||||
|
||||
@dataclass
|
||||
class Triple:
|
||||
s: Value # Nested dataclass
|
||||
p: Value
|
||||
o: Value
|
||||
|
||||
@dataclass
|
||||
class GraphQuery:
|
||||
triples: list[Triple] # Array of nested dataclasses
|
||||
metadata: dict[str, str]
|
||||
```
|
||||
|
||||
5. **القيم الافتراضية والحقول الاختيارية:**
|
||||
✅ **القرار: مزيج من الحقول المطلوبة، والقيم الافتراضية، والحقول الاختيارية**
|
||||
الحقول المطلوبة: لا توجد قيمة افتراضية.
|
||||
الحقول التي تحتوي على قيم افتراضية: موجودة دائمًا، ولها قيمة افتراضية منطقية.
|
||||
الحقول الاختيارية حقًا: `T | None = None`، يتم حذفها من التسلسل عند `None`.
|
||||
مثال:
|
||||
```python
|
||||
@dataclass
|
||||
class TextCompletionRequest:
|
||||
system: str # Required, no default
|
||||
prompt: str # Required, no default
|
||||
streaming: bool = False # Optional with default value
|
||||
metadata: dict | None = None # Truly optional, can be absent
|
||||
```
|
||||
|
||||
**المعاني الأساسية للتسلسل الهام:**
|
||||
|
||||
عندما يكون `metadata = None`:
|
||||
```json
|
||||
{
|
||||
"system": "...",
|
||||
"prompt": "...",
|
||||
"streaming": false
|
||||
// metadata field NOT PRESENT
|
||||
}
|
||||
```
|
||||
|
||||
عندما `metadata = {}` (فارغة بشكل صريح):
|
||||
```json
|
||||
{
|
||||
"system": "...",
|
||||
"prompt": "...",
|
||||
"streaming": false,
|
||||
"metadata": {} // Field PRESENT but empty
|
||||
}
|
||||
```
|
||||
|
||||
**الفرق الرئيسي:**
|
||||
`None` → حقل غير موجود في JSON (غير مُسلسل)
|
||||
قيمة فارغة (`{}`، `[]`، `""`) → حقل موجود بقيمة فارغة
|
||||
هذا مهم من الناحية الدلالية: "غير مقدم" مقابل "فارغ بشكل صريح"
|
||||
يجب على أنظمة التسلسل الخلفية تخطي حقول `None`، وليس ترميزها كـ `null`
|
||||
|
||||
## مسودة الحل الثالث: تفاصيل التنفيذ
|
||||
|
||||
### تنسيق اسم قائمة انتظار عام
|
||||
|
||||
استبدل أسماء قوائم الانتظار الخاصة بكل نظام خلفي بتنسيق عام يمكن للأنظمة الخلفية تعيينه بشكل مناسب.
|
||||
|
||||
**التنسيق:** `{qos}/{tenant}/{namespace}/{queue-name}`
|
||||
|
||||
حيث:
|
||||
`qos`: مستوى جودة الخدمة
|
||||
`q0` = بذل جهد (إرسال وإهمال، بدون إقرار)
|
||||
`q1` = مرة واحدة على الأقل (يتطلب إقرارًا)
|
||||
`q2` = مرة واحدة بالضبط (إقرار من مرحلتين)
|
||||
`tenant`: تجميع منطقي للتعددية
|
||||
`namespace`: تجميع فرعي داخل المستأجر
|
||||
`queue-name`: اسم قائمة الانتظار/الموضوع الفعلي
|
||||
|
||||
**أمثلة:**
|
||||
```
|
||||
q1/tg/flow/text-completion-requests
|
||||
q2/tg/config/config-push
|
||||
q0/tg/metrics/stats
|
||||
```
|
||||
|
||||
### ربط الموضوعات في الواجهة الخلفية
|
||||
|
||||
تقوم كل واجهة خلفية بتحويل التنسيق العام إلى تنسيقها الأصلي:
|
||||
|
||||
**الواجهة الخلفية Pulsar:**
|
||||
```python
|
||||
def map_topic(self, generic_topic: str) -> str:
|
||||
# Parse: q1/tg/flow/text-completion-requests
|
||||
qos, tenant, namespace, queue = generic_topic.split('/', 3)
|
||||
|
||||
# Map QoS to persistence
|
||||
persistence = 'persistent' if qos in ['q1', 'q2'] else 'non-persistent'
|
||||
|
||||
# Return Pulsar URI: persistent://tg/flow/text-completion-requests
|
||||
return f"{persistence}://{tenant}/{namespace}/{queue}"
|
||||
```
|
||||
|
||||
**الخلفية التقنية لـ MQTT:**
|
||||
```python
|
||||
def map_topic(self, generic_topic: str) -> tuple[str, int]:
|
||||
# Parse: q1/tg/flow/text-completion-requests
|
||||
qos, tenant, namespace, queue = generic_topic.split('/', 3)
|
||||
|
||||
# Map QoS level
|
||||
qos_level = {'q0': 0, 'q1': 1, 'q2': 2}[qos]
|
||||
|
||||
# Build MQTT topic including tenant/namespace for proper namespacing
|
||||
mqtt_topic = f"{tenant}/{namespace}/{queue}"
|
||||
|
||||
return mqtt_topic, qos_level
|
||||
```
|
||||
|
||||
### الدالة المساعدة للموضوع المحدّثة
|
||||
|
||||
```python
|
||||
# schema/core/topic.py
|
||||
def topic(queue_name, qos='q1', tenant='tg', namespace='flow'):
|
||||
"""
|
||||
Create a generic topic identifier that can be mapped by backends.
|
||||
|
||||
Args:
|
||||
queue_name: The queue/topic name
|
||||
qos: Quality of service
|
||||
- 'q0' = best-effort (no ack)
|
||||
- 'q1' = at-least-once (ack required)
|
||||
- 'q2' = exactly-once (two-phase ack)
|
||||
tenant: Tenant identifier for multi-tenancy
|
||||
namespace: Namespace within tenant
|
||||
|
||||
Returns:
|
||||
Generic topic string: qos/tenant/namespace/queue_name
|
||||
|
||||
Examples:
|
||||
topic('my-queue') # q1/tg/flow/my-queue
|
||||
topic('config', qos='q2', namespace='config') # q2/tg/config/config
|
||||
"""
|
||||
return f"{qos}/{tenant}/{namespace}/{queue_name}"
|
||||
```
|
||||
|
||||
### التكوين والتهيئة
|
||||
|
||||
**وسائط سطر الأوامر + متغيرات البيئة:**
|
||||
|
||||
```python
|
||||
# In base/async_processor.py - add_args() method
|
||||
@staticmethod
|
||||
def add_args(parser):
|
||||
# Pub/sub backend selection
|
||||
parser.add_argument(
|
||||
'--pubsub-backend',
|
||||
default=os.getenv('PUBSUB_BACKEND', 'pulsar'),
|
||||
choices=['pulsar', 'mqtt'],
|
||||
help='Pub/sub backend (default: pulsar, env: PUBSUB_BACKEND)'
|
||||
)
|
||||
|
||||
# Pulsar-specific configuration
|
||||
parser.add_argument(
|
||||
'--pulsar-host',
|
||||
default=os.getenv('PULSAR_HOST', 'pulsar://localhost:6650'),
|
||||
help='Pulsar host (default: pulsar://localhost:6650, env: PULSAR_HOST)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--pulsar-api-key',
|
||||
default=os.getenv('PULSAR_API_KEY', None),
|
||||
help='Pulsar API key (env: PULSAR_API_KEY)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--pulsar-listener',
|
||||
default=os.getenv('PULSAR_LISTENER', None),
|
||||
help='Pulsar listener name (env: PULSAR_LISTENER)'
|
||||
)
|
||||
|
||||
# MQTT-specific configuration
|
||||
parser.add_argument(
|
||||
'--mqtt-host',
|
||||
default=os.getenv('MQTT_HOST', 'localhost'),
|
||||
help='MQTT broker host (default: localhost, env: MQTT_HOST)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--mqtt-port',
|
||||
type=int,
|
||||
default=int(os.getenv('MQTT_PORT', '1883')),
|
||||
help='MQTT broker port (default: 1883, env: MQTT_PORT)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--mqtt-username',
|
||||
default=os.getenv('MQTT_USERNAME', None),
|
||||
help='MQTT username (env: MQTT_USERNAME)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--mqtt-password',
|
||||
default=os.getenv('MQTT_PASSWORD', None),
|
||||
help='MQTT password (env: MQTT_PASSWORD)'
|
||||
)
|
||||
```
|
||||
|
||||
**دالة المصنع:**
|
||||
|
||||
```python
|
||||
# In base/pubsub.py or base/pubsub_factory.py
|
||||
def get_pubsub(**config) -> PubSubBackend:
|
||||
"""
|
||||
Create and return a pub/sub backend based on configuration.
|
||||
|
||||
Args:
|
||||
config: Configuration dict from command-line args
|
||||
Must include 'pubsub_backend' key
|
||||
|
||||
Returns:
|
||||
Backend instance (PulsarBackend, MQTTBackend, etc.)
|
||||
"""
|
||||
backend_type = config.get('pubsub_backend', 'pulsar')
|
||||
|
||||
if backend_type == 'pulsar':
|
||||
return PulsarBackend(
|
||||
host=config.get('pulsar_host'),
|
||||
api_key=config.get('pulsar_api_key'),
|
||||
listener=config.get('pulsar_listener'),
|
||||
)
|
||||
elif backend_type == 'mqtt':
|
||||
return MQTTBackend(
|
||||
host=config.get('mqtt_host'),
|
||||
port=config.get('mqtt_port'),
|
||||
username=config.get('mqtt_username'),
|
||||
password=config.get('mqtt_password'),
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Unknown pub/sub backend: {backend_type}")
|
||||
```
|
||||
|
||||
**الاستخدام في AsyncProcessor:**
|
||||
|
||||
```python
|
||||
# In async_processor.py
|
||||
class AsyncProcessor:
|
||||
def __init__(self, **params):
|
||||
self.id = params.get("id")
|
||||
|
||||
# Create backend from config (replaces PulsarClient)
|
||||
self.pubsub = get_pubsub(**params)
|
||||
|
||||
# Rest of initialization...
|
||||
```
|
||||
|
||||
### الواجهة الخلفية
|
||||
|
||||
```python
|
||||
class PubSubBackend(Protocol):
|
||||
"""Protocol defining the interface all pub/sub backends must implement."""
|
||||
|
||||
def create_producer(self, topic: str, schema: type, **options) -> BackendProducer:
|
||||
"""
|
||||
Create a producer for a topic.
|
||||
|
||||
Args:
|
||||
topic: Generic topic format (qos/tenant/namespace/queue)
|
||||
schema: Dataclass type for messages
|
||||
options: Backend-specific options (e.g., chunking_enabled)
|
||||
|
||||
Returns:
|
||||
Backend-specific producer instance
|
||||
"""
|
||||
...
|
||||
|
||||
def create_consumer(
|
||||
self,
|
||||
topic: str,
|
||||
subscription: str,
|
||||
schema: type,
|
||||
initial_position: str = 'latest',
|
||||
consumer_type: str = 'shared',
|
||||
**options
|
||||
) -> BackendConsumer:
|
||||
"""
|
||||
Create a consumer for a topic.
|
||||
|
||||
Args:
|
||||
topic: Generic topic format (qos/tenant/namespace/queue)
|
||||
subscription: Subscription/consumer group name
|
||||
schema: Dataclass type for messages
|
||||
initial_position: 'earliest' or 'latest' (MQTT may ignore)
|
||||
consumer_type: 'shared', 'exclusive', 'failover' (MQTT may ignore)
|
||||
options: Backend-specific options
|
||||
|
||||
Returns:
|
||||
Backend-specific consumer instance
|
||||
"""
|
||||
...
|
||||
|
||||
def close(self) -> None:
|
||||
"""Close the backend connection."""
|
||||
...
|
||||
```
|
||||
|
||||
```python
|
||||
class BackendProducer(Protocol):
|
||||
"""Protocol for backend-specific producer."""
|
||||
|
||||
def send(self, message: Any, properties: dict = {}) -> None:
|
||||
"""Send a message (dataclass instance) with optional properties."""
|
||||
...
|
||||
|
||||
def flush(self) -> None:
|
||||
"""Flush any buffered messages."""
|
||||
...
|
||||
|
||||
def close(self) -> None:
|
||||
"""Close the producer."""
|
||||
...
|
||||
```
|
||||
|
||||
```python
|
||||
class BackendConsumer(Protocol):
|
||||
"""Protocol for backend-specific consumer."""
|
||||
|
||||
def receive(self, timeout_millis: int = 2000) -> Message:
|
||||
"""
|
||||
Receive a message from the topic.
|
||||
|
||||
Raises:
|
||||
TimeoutError: If no message received within timeout
|
||||
"""
|
||||
...
|
||||
|
||||
def acknowledge(self, message: Message) -> None:
|
||||
"""Acknowledge successful processing of a message."""
|
||||
...
|
||||
|
||||
def negative_acknowledge(self, message: Message) -> None:
|
||||
"""Negative acknowledge - triggers redelivery."""
|
||||
...
|
||||
|
||||
def unsubscribe(self) -> None:
|
||||
"""Unsubscribe from the topic."""
|
||||
...
|
||||
|
||||
def close(self) -> None:
|
||||
"""Close the consumer."""
|
||||
...
|
||||
```
|
||||
|
||||
```python
|
||||
class Message(Protocol):
|
||||
"""Protocol for a received message."""
|
||||
|
||||
def value(self) -> Any:
|
||||
"""Get the deserialized message (dataclass instance)."""
|
||||
...
|
||||
|
||||
def properties(self) -> dict:
|
||||
"""Get message properties/metadata."""
|
||||
...
|
||||
```
|
||||
|
||||
### إعادة هيكلة الفئات الحالية
|
||||
|
||||
تظل الفئات الحالية `Consumer`، `Producer`، `Publisher`، `Subscriber` في الغالب دون تغيير:
|
||||
|
||||
**المسؤوليات الحالية (يجب الحفاظ عليها):**
|
||||
نموذج الخيوط غير المتزامنة ومجموعات المهام.
|
||||
منطق إعادة الاتصال ومعالجة إعادة المحاولة.
|
||||
جمع المقاييس.
|
||||
تحديد المعدل.
|
||||
إدارة التزامن.
|
||||
|
||||
**التغييرات المطلوبة:**
|
||||
إزالة استيرادات Pulsar المباشرة (`pulsar.schema`، `pulsar.InitialPosition`، إلخ).
|
||||
قبول `BackendProducer`/`BackendConsumer` بدلاً من عميل Pulsar.
|
||||
تفويض عمليات النشر/الاشتراك الفعلية إلى مثيلات الواجهة الخلفية.
|
||||
مطابقة المفاهيم العامة إلى استدعاءات الواجهة الخلفية.
|
||||
|
||||
**مثال على إعادة الهيكلة:**
|
||||
|
||||
```python
|
||||
# OLD - consumer.py
|
||||
class Consumer:
|
||||
def __init__(self, client, topic, subscriber, schema, ...):
|
||||
self.client = client # Direct Pulsar client
|
||||
# ...
|
||||
|
||||
async def consumer_run(self):
|
||||
# Uses pulsar.InitialPosition, pulsar.ConsumerType
|
||||
self.consumer = self.client.subscribe(
|
||||
topic=self.topic,
|
||||
schema=JsonSchema(self.schema),
|
||||
initial_position=pulsar.InitialPosition.Earliest,
|
||||
consumer_type=pulsar.ConsumerType.Shared,
|
||||
)
|
||||
|
||||
# NEW - consumer.py
|
||||
class Consumer:
|
||||
def __init__(self, backend_consumer, schema, ...):
|
||||
self.backend_consumer = backend_consumer # Backend-specific consumer
|
||||
self.schema = schema
|
||||
# ...
|
||||
|
||||
async def consumer_run(self):
|
||||
# Backend consumer already created with right settings
|
||||
# Just use it directly
|
||||
while self.running:
|
||||
msg = await asyncio.to_thread(
|
||||
self.backend_consumer.receive,
|
||||
timeout_millis=2000
|
||||
)
|
||||
await self.handle_message(msg)
|
||||
```
|
||||
|
||||
### السلوكيات الخاصة بالخادم الخلفي
|
||||
|
||||
**الخادم الخلفي Pulsar:**
|
||||
يربط `q0` → `non-persistent://`، و `q1`/`q2` → `persistent://`
|
||||
يدعم جميع أنواع المستهلكين (مشترك، حصري، احتياطي)
|
||||
يدعم الموضع الأولي (الأول/الأخير)
|
||||
إقرار الرسائل الأصلي
|
||||
دعم سجل المخططات
|
||||
|
||||
**الخادم الخلفي MQTT:**
|
||||
يربط `q0`/`q1`/`q2` بمستويات جودة الخدمة MQTT 0/1/2
|
||||
يتضمن المستأجر/المساحة الاسمية في مسار الموضوع لعملية التمييز
|
||||
يقوم بإنشاء معرفات العملاء تلقائيًا من أسماء الاشتراكات
|
||||
يتجاهل الموضع الأولي (لا يوجد سجل رسائل في MQTT الأساسي)
|
||||
يتجاهل نوع المستهلك (يستخدم MQTT معرفات العملاء، وليس مجموعات المستهلكين)
|
||||
نموذج نشر/اشتراك بسيط
|
||||
|
||||
### ملخص قرارات التصميم
|
||||
|
||||
1. ✅ **تسمية قائمة انتظار عامة**: بتنسيق `qos/tenant/namespace/queue-name`
|
||||
2. ✅ **جودة الخدمة في معرف قائمة الانتظار**: يتم تحديدها بواسطة تعريف قائمة الانتظار، وليس التكوين
|
||||
3. ✅ **إعادة الاتصال**: تتم معالجتها بواسطة فئات المستهلك/المنتج، وليس الخوادم الخلفية
|
||||
4. ✅ **مواضيع MQTT**: تتضمن المستأجر/المساحة الاسمية لعملية التمييز المناسبة
|
||||
5. ✅ **سجل الرسائل**: يتجاهل MQTT معلمة `initial_position` (تحسين مستقبلي)
|
||||
6. ✅ **معرفات العملاء**: يقوم خادم MQTT بإنشائها تلقائيًا من اسم الاشتراك
|
||||
|
||||
### التحسينات المستقبلية
|
||||
|
||||
**سجل رسائل MQTT:**
|
||||
يمكن إضافة طبقة تخزين اختيارية (مثل الرسائل المحفوظة، أو مخزن خارجي)
|
||||
سيسمح بدعم `initial_position='earliest'`
|
||||
ليس مطلوبًا للتنفيذ الأولي
|
||||
1516
docs/tech-specs/ar/python-api-refactor.ar.md
Normal file
1516
docs/tech-specs/ar/python-api-refactor.ar.md
Normal file
File diff suppressed because it is too large
Load diff
271
docs/tech-specs/ar/query-time-explainability.ar.md
Normal file
271
docs/tech-specs/ar/query-time-explainability.ar.md
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
---
|
||||
layout: default
|
||||
title: "الشرح في وقت الاستعلام"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# الشرح في وقت الاستعلام
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## الحالة
|
||||
|
||||
تم التنفيذ
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يصف هذا المواصفات كيفية تسجيل GraphRAG وتوصيل بيانات الشرح أثناء تنفيذ الاستعلام. الهدف هو التتبع الكامل: من الإجابة النهائية إلى الحواف المحددة ثم إلى المستندات المصدر.
|
||||
|
||||
يمثل الشرح في وقت الاستعلام ما قام به مسار عمل GraphRAG أثناء عملية الاستدلال. وهو مرتبط ببيانات المصدر التي تم تسجيلها في وقت الاستخراج، والتي تسجل أصل حقائق الرسم البياني المعرفي.
|
||||
|
||||
## المصطلحات
|
||||
|
||||
| المصطلح | التعريف |
|
||||
|------|------------|
|
||||
| **الشرح** | سجل لكيفية اشتقاق نتيجة |
|
||||
| **الجلسة** | تنفيذ استعلام GraphRAG واحد |
|
||||
| **اختيار الحواف** | اختيار الحواف ذات الصلة المدفوع بالنماذج اللغوية الكبيرة مع الاستدلال |
|
||||
| **سلسلة المصدر** | مسار من الحافة → الجزء → الصفحة → المستند |
|
||||
|
||||
## البنية
|
||||
|
||||
### تدفق الشرح
|
||||
|
||||
```
|
||||
GraphRAG Query
|
||||
│
|
||||
├─► Session Activity
|
||||
│ └─► Query text, timestamp
|
||||
│
|
||||
├─► Retrieval Entity
|
||||
│ └─► All edges retrieved from subgraph
|
||||
│
|
||||
├─► Selection Entity
|
||||
│ └─► Selected edges with LLM reasoning
|
||||
│ └─► Each edge links to extraction provenance
|
||||
│
|
||||
└─► Answer Entity
|
||||
└─► Reference to synthesized response (in librarian)
|
||||
```
|
||||
|
||||
### خط أنابيب GraphRAG ثنائي المراحل
|
||||
|
||||
1. **اختيار الحواف**: يقوم نموذج اللغة الكبيرة (LLM) باختيار الحواف ذات الصلة من الرسم البياني الفرعي، مع تقديم مبررات لكل حافة.
|
||||
2. **التوليف**: يقوم نموذج اللغة الكبيرة (LLM) بإنشاء الإجابة من الحواف المحددة فقط.
|
||||
|
||||
هذا الفصل يمكّن من إمكانية التفسير - نحن نعرف بالضبط أي الحواف ساهمت.
|
||||
|
||||
### التخزين
|
||||
|
||||
يتم تخزين ثلاثيات إمكانية التفسير في مجموعة قابلة للتكوين (افتراضي: `explainability`).
|
||||
يستخدم علم الوجود PROV-O للعلاقات المتعلقة بالأصل.
|
||||
إعادة تمثيل RDF-star للمراجع إلى الحواف.
|
||||
يتم تخزين محتوى الإجابة في خدمة "المكتبار" (وليس مضمنًا - كبير جدًا).
|
||||
|
||||
### البث في الوقت الفعلي
|
||||
|
||||
يتم بث أحداث إمكانية التفسير إلى العميل أثناء تنفيذ الاستعلام:
|
||||
|
||||
1. تم إنشاء جلسة → تم إرسال حدث.
|
||||
2. تم استرداد الحواف → تم إرسال حدث.
|
||||
3. تم تحديد الحواف مع التبرير → تم إرسال حدث.
|
||||
4. تم توليف الإجابة → تم إرسال حدث.
|
||||
|
||||
يتلقى العميل `explain_id` و `explain_collection` لاسترداد التفاصيل الكاملة.
|
||||
|
||||
## هيكل URI
|
||||
|
||||
تستخدم جميع عناوين URI مساحة الاسم `urn:trustgraph:` مع معرفات UUID:
|
||||
|
||||
| الكيان | نمط URI |
|
||||
|--------|-------------|
|
||||
| الجلسة | `urn:trustgraph:session:{uuid}` |
|
||||
| الاسترداد | `urn:trustgraph:prov:retrieval:{uuid}` |
|
||||
| التحديد | `urn:trustgraph:prov:selection:{uuid}` |
|
||||
| الإجابة | `urn:trustgraph:prov:answer:{uuid}` |
|
||||
| تحديد الحواف | `urn:trustgraph:prov:edge:{uuid}:{index}` |
|
||||
|
||||
## نموذج RDF (PROV-O)
|
||||
|
||||
### نشاط الجلسة
|
||||
|
||||
```turtle
|
||||
<session-uri> a prov:Activity ;
|
||||
rdfs:label "GraphRAG query session" ;
|
||||
prov:startedAtTime "2024-01-15T10:30:00Z" ;
|
||||
tg:query "What was the War on Terror?" .
|
||||
```
|
||||
|
||||
### الكيان الخاص بالاسترجاع
|
||||
|
||||
```turtle
|
||||
<retrieval-uri> a prov:Entity ;
|
||||
rdfs:label "Retrieved edges" ;
|
||||
prov:wasGeneratedBy <session-uri> ;
|
||||
tg:edgeCount 50 .
|
||||
```
|
||||
|
||||
### الكيان المحدد
|
||||
|
||||
```turtle
|
||||
<selection-uri> a prov:Entity ;
|
||||
rdfs:label "Selected edges" ;
|
||||
prov:wasDerivedFrom <retrieval-uri> ;
|
||||
tg:selectedEdge <edge-sel-0> ;
|
||||
tg:selectedEdge <edge-sel-1> .
|
||||
|
||||
<edge-sel-0> tg:edge << <s> <p> <o> >> ;
|
||||
tg:reasoning "This edge establishes the key relationship..." .
|
||||
```
|
||||
|
||||
### إجابة الكيان
|
||||
|
||||
```turtle
|
||||
<answer-uri> a prov:Entity ;
|
||||
rdfs:label "GraphRAG answer" ;
|
||||
prov:wasDerivedFrom <selection-uri> ;
|
||||
tg:document <urn:trustgraph:answer:{uuid}> .
|
||||
```
|
||||
|
||||
يشير الرمز `tg:document` إلى الإجابة المخزنة في خدمة أمين المكتبة.
|
||||
|
||||
## ثوابت مساحة الاسم
|
||||
|
||||
معرفة في `trustgraph-base/trustgraph/provenance/namespaces.py`:
|
||||
|
||||
| الثابت | عنوان URI |
|
||||
|----------|-----|
|
||||
| `TG_QUERY` | `https://trustgraph.ai/ns/query` |
|
||||
| `TG_EDGE_COUNT` | `https://trustgraph.ai/ns/edgeCount` |
|
||||
| `TG_SELECTED_EDGE` | `https://trustgraph.ai/ns/selectedEdge` |
|
||||
| `TG_EDGE` | `https://trustgraph.ai/ns/edge` |
|
||||
| `TG_REASONING` | `https://trustgraph.ai/ns/reasoning` |
|
||||
| `TG_CONTENT` | `https://trustgraph.ai/ns/content` |
|
||||
| `TG_DOCUMENT` | `https://trustgraph.ai/ns/document` |
|
||||
|
||||
## مخطط GraphRagResponse
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class GraphRagResponse:
|
||||
error: Error | None = None
|
||||
response: str = ""
|
||||
end_of_stream: bool = False
|
||||
explain_id: str | None = None
|
||||
explain_collection: str | None = None
|
||||
message_type: str = "" # "chunk" or "explain"
|
||||
end_of_session: bool = False
|
||||
```
|
||||
|
||||
### أنواع الرسائل
|
||||
|
||||
| نوع الرسالة | الغرض |
|
||||
|--------------|---------|
|
||||
| `chunk` | نص الاستجابة (متدفق أو نهائي) |
|
||||
| `explain` | حدث قابل للتفسير مع مرجع IRI |
|
||||
|
||||
### دورة حياة الجلسة
|
||||
|
||||
1. رسائل `explain` متعددة (جلسة، استرجاع، اختيار، إجابة)
|
||||
2. رسائل `chunk` متعددة (استجابة متدفقة)
|
||||
3. رسالة `chunk` نهائية مع `end_of_session=True`
|
||||
|
||||
## تنسيق اختيار الحافة
|
||||
|
||||
يقوم نموذج اللغة الكبيرة بإرجاع JSONL مع الحواف المحددة:
|
||||
|
||||
```jsonl
|
||||
{"id": "edge-hash-1", "reasoning": "This edge shows the key relationship..."}
|
||||
{"id": "edge-hash-2", "reasoning": "Provides supporting evidence..."}
|
||||
```
|
||||
|
||||
الرمز `id` هو تجزئة لـ `(labeled_s, labeled_p, labeled_o)` تم حسابه بواسطة `edge_id()`.
|
||||
|
||||
## الحفاظ على عنوان URI
|
||||
|
||||
### المشكلة
|
||||
|
||||
يعرض GraphRAG تسميات قابلة للقراءة للبشر لنظام LLM، ولكن الشفافية تتطلب عناوين URI أصلية لتتبع الأصل.
|
||||
|
||||
### الحل
|
||||
|
||||
`get_labelgraph()` يُرجع كلاً من:
|
||||
`labeled_edges`: قائمة بـ `(label_s, label_p, label_o)` لنظام LLM
|
||||
`uri_map`: قاموس يربط بين `edge_id(labels)` و `(uri_s, uri_p, uri_o)`
|
||||
|
||||
عند تخزين بيانات الشفافية، تُستخدم عناوين URI من `uri_map`.
|
||||
|
||||
## تتبع الأصل
|
||||
|
||||
### من الحافة إلى المصدر
|
||||
|
||||
يمكن تتبع الحواف المحددة إلى المستندات المصدر:
|
||||
|
||||
1. الاستعلام عن الرسم البياني الفرعي الذي يحتوي عليها: `?subgraph tg:contains <<s p o>>`
|
||||
2. تتبع سلسلة `prov:wasDerivedFrom` إلى المستند الجذر
|
||||
3. كل خطوة في السلسلة: جزء → صفحة → مستند
|
||||
|
||||
### دعم ثلاثيات Cassandra المقتبسة
|
||||
|
||||
يدعم خدمة استعلام Cassandra مطابقة ثلاثيات مقتبسة:
|
||||
|
||||
```python
|
||||
# In get_term_value():
|
||||
elif term.type == TRIPLE:
|
||||
return serialize_triple(term.triple)
|
||||
```
|
||||
|
||||
هذا يتيح إجراء استعلامات مثل:
|
||||
```
|
||||
?subgraph tg:contains <<http://example.org/s http://example.org/p "value">>
|
||||
```
|
||||
|
||||
## استخدام واجهة سطر الأوامر
|
||||
|
||||
```bash
|
||||
tg-invoke-graph-rag --explainable -q "What was the War on Terror?"
|
||||
```
|
||||
|
||||
### تنسيق الإخراج
|
||||
|
||||
```
|
||||
[session] urn:trustgraph:session:abc123
|
||||
|
||||
[retrieval] urn:trustgraph:prov:retrieval:abc123
|
||||
|
||||
[selection] urn:trustgraph:prov:selection:abc123
|
||||
Selected 12 edge(s)
|
||||
Edge: (Guantanamo, definition, A detention facility...)
|
||||
Reason: Directly connects Guantanamo to the War on Terror
|
||||
Source: Chunk 1 → Page 2 → Beyond the Vigilant State
|
||||
|
||||
[answer] urn:trustgraph:prov:answer:abc123
|
||||
|
||||
Based on the provided knowledge statements...
|
||||
```
|
||||
|
||||
### الميزات
|
||||
|
||||
أحداث تفسيرية في الوقت الفعلي أثناء الاستعلام.
|
||||
حل التسميات للمكونات الطرفية عبر `rdfs:label`.
|
||||
تتبع سلسلة المصدر عبر `prov:wasDerivedFrom`.
|
||||
تخزين مؤقت للتسميات لتجنب الاستعلامات المتكررة.
|
||||
|
||||
## الملفات المنفذة
|
||||
|
||||
| الملف | الغرض |
|
||||
|------|---------|
|
||||
| `trustgraph-base/trustgraph/provenance/uris.py` | مولدات URI |
|
||||
| `trustgraph-base/trustgraph/provenance/namespaces.py` | ثوابت مساحة الاسم RDF |
|
||||
| `trustgraph-base/trustgraph/provenance/triples.py` | أدوات بناء الثلاثيات |
|
||||
| `trustgraph-base/trustgraph/schema/services/retrieval.py` | مخطط GraphRagResponse |
|
||||
| `trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py` | GraphRAG الأساسي مع الحفاظ على URI |
|
||||
| `trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py` | خدمة مع تكامل أمين المكتبة |
|
||||
| `trustgraph-flow/trustgraph/query/triples/cassandra/service.py` | دعم الاستعلام عن الثلاثيات المقتبسة |
|
||||
| `trustgraph-cli/trustgraph/cli/invoke_graph_rag.py` | واجهة سطر أوامر مع عرض التفسير |
|
||||
|
||||
## المراجع
|
||||
|
||||
PROV-O (علم الوجود W3C): https://www.w3.org/TR/prov-o/
|
||||
RDF-star: https://w3c.github.io/rdf-star/
|
||||
علم الوجود في وقت الاستخراج: `docs/tech-specs/extraction-time-provenance.md`
|
||||
174
docs/tech-specs/ar/rag-streaming-support.ar.md
Normal file
174
docs/tech-specs/ar/rag-streaming-support.ar.md
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات فنية لدعم التدفق في RAG"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات فنية لدعم التدفق في RAG
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات إضافة دعم التدفق إلى خدمات GraphRAG و DocumentRAG، مما يمكّن من الحصول على استجابات على شكل أجزاء (token-by-token) في الوقت الفعلي للاستعلامات المتعلقة باسترجاع المعرفة ورؤوس المستندات. هذا يوسع البنية المعمارية الحالية للتدفق، والتي تم تنفيذها بالفعل لخدمات إكمال النص، والتعليمات البرمجية، ووكلاء LLM.
|
||||
|
||||
## الأهداف
|
||||
|
||||
- **تجربة تدفق متسقة**: توفير تجربة تدفق متسقة عبر جميع خدمات TrustGraph.
|
||||
- **تغييرات واجهة برمجة تطبيقات (API) قليلة**: إضافة دعم التدفق باستخدام علامة واحدة (`streaming`)، وفقًا للأنماط المتبعة.
|
||||
- **التوافق مع الإصدارات السابقة**: الحفاظ على سلوك غير تدفق بشكل افتراضي.
|
||||
- **استخدام البنية التحتية الحالية**: الاستفادة من تدفق PromptClient المطبق بالفعل.
|
||||
- **دعم البوابة**: تمكين التدفق من خلال بوابة websocket للتطبيقات العميلة.
|
||||
|
||||
## الخلفية
|
||||
|
||||
خدمات التدفق الحالية:
|
||||
- **خدمة إكمال النص للـ LLM**: المرحلة 1 - التدفق من مزودي LLM.
|
||||
- **خدمة التعليمات البرمجية**: المرحلة 2 - التدفق من خلال قوالب التعليمات البرمجية.
|
||||
- **خدمة الوكيل**: المراحل 3-4 - استجابات ReAct مع أجزاء فكرية/ملاحظات/إجابات متزايدة.
|
||||
|
||||
قيود الحالية لخدمات RAG:
|
||||
- GraphRAG و DocumentRAG تدعم فقط الاستجابات المتوقفة.
|
||||
- يجب على المستخدمين الانتظار حتى استلام الرد الكامل من LLM قبل رؤية أي مخرجات.
|
||||
- تجربة مستخدم (UX) سيئة للاستجابات الطويلة من استعلامات الرسم البياني المعرفي أو المستندات.
|
||||
- تجربة غير متسقة مقارنة بـ خدمات TrustGraph الأخرى.
|
||||
|
||||
تستجيب هذه المواصفات لهذه الثغرات من خلال إضافة دعم التدفق إلى GraphRAG و DocumentRAG. من خلال تمكين الاستجابات على شكل أجزاء، يمكن لـ TrustGraph:
|
||||
- توفير تجربة تدفق متسقة عبر جميع أنواع الاستعلام.
|
||||
- تقليل التأخير المتوقع في استعلامات RAG.
|
||||
- تمكين ملاحظات تقدم أفضل للاستعلامات الطويلة الأمد.
|
||||
- دعم العرض في الوقت الفعلي في تطبيقات العملاء.
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
يستفيد تنفيذ التدفق في RAG من البنية التحتية الحالية:
|
||||
|
||||
1. **تدفق PromptClient** (مطبق بالفعل)
|
||||
- يستقبل `kg_prompt()` و `document_prompt()` بالفعل معلمات `streaming` و `chunk_callback`.
|
||||
- تستدعي هذه `prompt()` داخليًا مع دعم التدفق.
|
||||
- لا يلزم إجراء أي تغييرات على PromptClient.
|
||||
|
||||
الوحدة: `trustgraph-base/trustgraph/base/prompt_client.py`
|
||||
|
||||
2. **خدمة GraphRAG** (تحتاج إلى تمرير معلمة التدفق)
|
||||
- إضافة معلمة `streaming` إلى طريقة `query()`.
|
||||
- تمرير علامة التدفق والوظائف المرجعية إلى `prompt_client.kg_prompt()`.
|
||||
- يجب أن يحتوي مخطط GraphRag على حقل `streaming`.
|
||||
|
||||
الوحدات:
|
||||
- `trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py`
|
||||
- `trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py` (المعالجة)
|
||||
- `trustgraph-base/trustgraph/schema/graph_rag.py` (مخطط الطلب)
|
||||
- `trustgraph-flow/trustgraph/gateway/dispatch/graph_rag.py` (البوابة)
|
||||
|
||||
3. **خدمة DocumentRAG** (تحتاج إلى تمرير معلمة التدفق)
|
||||
- إضافة معلمة `streaming` إلى طريقة `query()`.
|
||||
- تمرير علامة التدفق والوظائف المرجعية إلى `prompt_client.document_prompt()`.
|
||||
- يجب أن يحتوي مخطط DocumentRag على حقل `streaming`.
|
||||
|
||||
الوحدات:
|
||||
- `trustgraph-flow/trustgraph/retrieval/document_rag/document_rag.py`
|
||||
- `trustgraph-flow/trustgraph/retrieval/document_rag/rag.py` (المعالجة)
|
||||
- `trustgraph-base/trustgraph/schema/document_rag.py` (مخطط الطلب)
|
||||
- `trustgraph-flow/trustgraph/gateway/dispatch/document_rag.py` (البوابة)
|
||||
|
||||
### تدفق البيانات
|
||||
|
||||
**غير تدفق (الحالي)**:
|
||||
```
|
||||
Client → Gateway → RAG Service → PromptClient.kg_prompt(streaming=False)
|
||||
↓
|
||||
Prompt Service → LLM
|
||||
↓
|
||||
رد كامل
|
||||
↓
|
||||
Client ← Gateway ← RAG Service ← الرد
|
||||
```
|
||||
|
||||
**تدفق (مقترح)**:
|
||||
```
|
||||
Client → Gateway → RAG Service → PromptClient.kg_prompt(streaming=True, chunk_callback=cb)
|
||||
↓
|
||||
Prompt Service → LLM (streaming)
|
||||
↓
|
||||
جزء → وظيفة مرجعية → رد RAG (جزء)
|
||||
↓ ↓
|
||||
Client ← Gateway ← ────────────────────────────────── رد التدفق
|
||||
```
|
||||
|
||||
### واجهات برمجة التطبيقات (APIs)
|
||||
|
||||
**تغييرات GraphRAG**:
|
||||
|
||||
1. **GraphRag.query()** - إضافة معلمات التدفق
|
||||
```python
|
||||
async def query(
|
||||
self, query, user, collection,
|
||||
verbose=False, streaming=False, chunk_callback=None # NEW
|
||||
):
|
||||
# ... كود موجود ...
|
||||
|
||||
if streaming and chunk_callback:
|
||||
resp = await self.prompt_client.kg_prompt(
|
||||
query, kg,
|
||||
streaming=True,
|
||||
chunk_callback=chunk_callback
|
||||
)
|
||||
else:
|
||||
resp = await self.prompt_client.kg_prompt(query, kg)
|
||||
|
||||
return resp
|
||||
```
|
||||
|
||||
2. **مخطط GraphRagRequest** - إضافة حقل التدفق
|
||||
```python
|
||||
class GraphRagRequest(Record):
|
||||
query = String()
|
||||
user = String()
|
||||
collection = String()
|
||||
streaming = Boolean() # NEW
|
||||
```
|
||||
|
||||
3. **مخطط GraphRagResponse** - إضافة حقول التدفق (اتبع نمط الوكيل)
|
||||
```python
|
||||
class GraphRagResponse(Record):
|
||||
response = String()
|
||||
metadata = dict
|
||||
# ... حقول أخرى ...
|
||||
```
|
||||
|
||||
**تغييرات DocumentRAG**:
|
||||
(نفس التغييرات الموضحة أعلاه)
|
||||
|
||||
### التغييرات في البوابة
|
||||
|
||||
(نفس التغييرات الموضحة أعلاه)
|
||||
|
||||
## خطة النقل
|
||||
|
||||
لا توجد حاجة لنقل:
|
||||
- التدفق هو خيار، وتكون القيمة الافتراضية هي False.
|
||||
- لا تزال العملاء الحالية تعمل بشكل طبيعي.
|
||||
- يمكن للعملاء الجدد اختيار التدفق.
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
الوقت المقدر للتنفيذ: 4-6 ساعات
|
||||
- المرحلة 1 (2 ساعات): دعم التدفق في GraphRAG
|
||||
- المرحلة 2 (2 ساعات): دعم التدفق في DocumentRAG
|
||||
- المرحلة 3 (1-2 ساعات): تحديثات البوابة وعلامات سطر الأوامر (CLI)
|
||||
- الاختبار: تم تضمينه في كل مرحلة
|
||||
|
||||
## الأسئلة المفتوحة
|
||||
|
||||
- هل يجب إضافة دعم التدفق لخدمة NLP Query أيضًا؟
|
||||
- هل نريد تدفق خطوات وسيطة (مثل "جاري استرداد الكيانات..."، "استعلام عن الرسم البياني") أم فقط مخرجات LLM؟
|
||||
- هل يجب تضمين بيانات وصفية للجزء (مثل رقم الجزء، العدد الإجمالي المتوقع) في استجابات GraphRAG/DocumentRAG؟
|
||||
|
||||
## المراجع
|
||||
|
||||
- التنفيذ الحالي: `docs/tech-specs/streaming-llm-responses.md`
|
||||
- تدفق PromptClient: `trustgraph-base/trustgraph/base/prompt_client.py`
|
||||
- تدفق الوكيل: `trustgraph-flow/trustgraph/agent/react/agent_manager.py`
|
||||
99
docs/tech-specs/ar/schema-refactoring-proposal.ar.md
Normal file
99
docs/tech-specs/ar/schema-refactoring-proposal.ar.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
layout: default
|
||||
title: "اقتراح إعادة هيكلة دليل المخطط"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# اقتراح إعادة هيكلة دليل المخطط
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## المشاكل الحالية
|
||||
|
||||
1. **هيكل مسطح** - وجود جميع المخططات في مجلد واحد يجعل من الصعب فهم العلاقات
|
||||
2. **مزيج من المعايير** - أنواع أساسية، كائنات مجال، وعقود واجهة برمجة تطبيقات كلها مدمجة معًا
|
||||
3. **أسماء غير واضحة** - الملفات مثل "object.py"، "types.py"، "topic.py" لا تشير بوضوح إلى الغرض منها
|
||||
4. **لا يوجد تباين واضح** - من الصعب معرفة ما يعتمد على ماذا
|
||||
|
||||
## الهيكل المقترح
|
||||
|
||||
```
|
||||
trustgraph-base/trustgraph/schema/
|
||||
├── __init__.py
|
||||
├── core/ # أنواع أساسية أولية مستخدمة في كل مكان
|
||||
│ ├── __init__.py
|
||||
│ ├── primitives.py # Error, Value, Triple, Field, RowSchema
|
||||
│ ├── metadata.py # سجل البيانات الوصفية
|
||||
│ └── topic.py # أدوات الموضوع
|
||||
│
|
||||
├── knowledge/ # نماذج مجال المعرفة واستخراجها
|
||||
│ ├── __init__.py
|
||||
│ ├── graph.py # EntityContext, EntityEmbeddings, Triples
|
||||
│ ├── document.py # Document, TextDocument, Chunk
|
||||
│ ├── knowledge.py # أنواع استخراج المعرفة
|
||||
│ ├── embeddings.py # جميع أنواع الاستعلامات المتعلقة بالاستعلام (تم نقلها من ملفات متعددة)
|
||||
│ └── nlp.py # أنواع Definition, Topic, Relationship, Fact
|
||||
│
|
||||
└── services/ # عقود طلب/استجابة الخدمة
|
||||
├── __init__.py
|
||||
├── llm.py # TextCompletion, Embeddings, Tool requests/responses
|
||||
├── retrieval.py # GraphRAG, DocumentRAG queries/responses
|
||||
├── query.py # GraphEmbeddingsRequest/Response, DocumentEmbeddingsRequest/Response
|
||||
├── agent.py # Agent requests/responses
|
||||
├── flow.py # Flow requests/responses
|
||||
├── prompt.py # طلبات/استجابات خدمة Prompt
|
||||
├── config.py # خدمة التكوين
|
||||
├── library.py # خدمة المكتبة
|
||||
└── lookup.py # خدمة البحث
|
||||
```
|
||||
|
||||
## التغييرات الرئيسية
|
||||
|
||||
1. **تنظيم هرمي** - فصل واضح بين الأنواع الأساسية، نماذج المعرفة، وعقود الخدمة
|
||||
2. **أسماء أفضل**:
|
||||
- `types.py` → `core/primitives.py` (الغرض أكثر وضوحًا)
|
||||
- `object.py` → تقسيم بين الملفات المناسبة بناءً على المحتوى الفعلي
|
||||
- `documents.py` → `knowledge/document.py` (فردي، متسق)
|
||||
- `models.py` → `services/llm.py` (نوع النماذج أكثر وضوحًا)
|
||||
- `prompt.py` → تقسيم: أجزاء الخدمة إلى `services/prompt.py`، أنواع البيانات إلى `knowledge/nlp.py`
|
||||
|
||||
3. **تجميع منطقي**:
|
||||
- جميع أنواع الاستعلامات مجمعة في `knowledge/embeddings.py`
|
||||
- جميع العقود المتعلقة بالخدمة LLM في `services/llm.py`
|
||||
- فصل واضح لزوجات الطلب/الاستجابة في دليل الخدمة
|
||||
- تجميع أنواع استخراج المعرفة مع نماذج المعرفة الأخرى
|
||||
|
||||
4. **وضوح الاعتماد**:
|
||||
- الأنواع الأساسية ليس لها تبعيات
|
||||
- تعتمد نماذج المعرفة فقط على الأساس
|
||||
- يمكن أن تعتمد عقود الخدمة على كل من الأساس ونماذج المعرفة
|
||||
|
||||
## فوائد الهجرة
|
||||
|
||||
1. **سهولة التنقل** - يمكن للمطورين العثور بسرعة على ما يحتاجون إليه
|
||||
2. **تحسين الوحدات** - حدود واضحة بين مختلف المعايير
|
||||
3. **استيراد أبسط** - مسارات استيراد أكثر بديهية
|
||||
4. **قابلية التوسع** - من السهل إضافة أنواع معرف أو خدمات جديدة دون تضييق
|
||||
|
||||
## أمثلة على تغييرات الاستيراد
|
||||
|
||||
```python
|
||||
# قبل
|
||||
from trustgraph.schema import Error, Triple, GraphEmbeddings, TextCompletionRequest
|
||||
|
||||
# بعد
|
||||
from trustgraph.schema.core import Error, Triple
|
||||
from trustgraph.schema.knowledge import GraphEmbeddings
|
||||
from trustgraph.schema.services import TextCompletionRequest
|
||||
```
|
||||
|
||||
## ملاحظات التنفيذ
|
||||
|
||||
1. الحفاظ على التوافق مع الإصدارات السابقة عن طريق الحفاظ على الاستيرادات في `__init__.py` الجذر
|
||||
2. نقل الملفات تدريجيًا، مع تحديث الاستيرادات حسب الحاجة
|
||||
3. ضع في اعتبارك إضافة `legacy.py` الذي يستورد كل شيء لفاصل زمني الانتقال
|
||||
4. تحديث الوثائق لتعكس الهيكل الجديد
|
||||
|
||||
<function_calls>
|
||||
<invoke name="TodoWrite">
|
||||
<parameter name="todos">[{"id": "1", "content": "Examination of the current schema directory structure", "status": "completed", "priority": "high"}, {"id": "2", "content": "Analyze schema files and their purposes", "status": "completed", "priority": "high"}, {"id": "3", "content": "Propose improved naming and structure", "status": "completed", "priority": "high"}]
|
||||
578
docs/tech-specs/ar/streaming-llm-responses.ar.md
Normal file
578
docs/tech-specs/ar/streaming-llm-responses.ar.md
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية لخدمة بث استجابات نماذج اللغة الكبيرة (LLM)"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية لخدمة بث استجابات نماذج اللغة الكبيرة (LLM)
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات تنفيذ دعم البث لاستجابات نماذج اللغة الكبيرة في TrustGraph. يتيح البث التسليم في الوقت الفعلي للرموز (tokens) أثناء إنتاجها بواسطة نموذج اللغة الكبيرة، بدلاً من الانتظار حتى اكتمال توليد الاستجابة.
|
||||
|
||||
يدعم هذا التنفيذ حالات الاستخدام التالية:
|
||||
|
||||
|
||||
1. **واجهات مستخدم في الوقت الفعلي**: بث الرموز إلى واجهة المستخدم أثناء إنشائها، مما يوفر ملاحظات مرئية فورية.
|
||||
|
||||
2. **تقليل وقت ظهور الرمز الأول**: يرى المستخدمون الإخراج على الفور بدلاً من الانتظار حتى اكتمال التوليد.
|
||||
|
||||
3. **التعامل مع الاستجابات الطويلة**: التعامل مع المخرجات الطويلة جدًا التي قد تتسبب خلاف ذلك في انتهاء المهلة أو تجاوز حدود الذاكرة.
|
||||
|
||||
4. **التطبيقات التفاعلية**: تمكين واجهات الدردشة والوكلاء المستجيبة.
|
||||
|
||||
## الأهداف
|
||||
|
||||
|
||||
**التوافق مع الإصدارات السابقة**: تستمر العملاء الحاليون الذين لا يستخدمون البث في العمل دون تعديل.
|
||||
|
||||
**تصميم واجهة برمجة تطبيقات (API) متسق**: يستخدم البث والواجهات غير المتدفقة نفس أنماط المخططات مع اختلافات قليلة.
|
||||
|
||||
**مرونة مزود الخدمة**: دعم البث عند توفره، مع توفير آلية بديلة سلسة عند عدم توفره.
|
||||
|
||||
**التطبيق المرحلي**: تطبيق تدريجي لتقليل المخاطر.
|
||||
|
||||
**دعم شامل**: دعم البث من مزود نموذج اللغة الكبيرة إلى تطبيقات العميل عبر Pulsar و Gateway API و Python API.
|
||||
|
||||
## الخلفية
|
||||
|
||||
### البنية الحالية
|
||||
|
||||
|
||||
تعمل عملية إكمال النص الحالية لنماذج اللغة الكبيرة على النحو التالي:
|
||||
|
||||
1. يرسل العميل `TextCompletionRequest` مع حقول `system` و `prompt`.
|
||||
2. تعالج خدمة نموذج اللغة الكبيرة الطلب وتنتظر اكتمال التوليد.
|
||||
3. يتم إرجاع `TextCompletionResponse` واحد مع سلسلة `response` كاملة.
|
||||
|
||||
المخطط الحالي (`trustgraph-base/trustgraph/schema/services/llm.py`):
|
||||
|
||||
```python
|
||||
class TextCompletionRequest(Record):
|
||||
system = String()
|
||||
prompt = String()
|
||||
|
||||
class TextCompletionResponse(Record):
|
||||
error = Error()
|
||||
response = String()
|
||||
in_token = Integer()
|
||||
out_token = Integer()
|
||||
model = String()
|
||||
```
|
||||
|
||||
### القيود الحالية
|
||||
|
||||
**زمن الوصول (Latency)**: يجب على المستخدمين الانتظار حتى اكتمال الإنشاء قبل رؤية أي نتيجة.
|
||||
**خطر انتهاء المهلة (Timeout)**: قد تتجاوز عمليات الإنشاء الطويلة حدود انتهاء المهلة الخاصة بالعميل.
|
||||
**تجربة مستخدم سيئة (Poor UX)**: عدم وجود أي ملاحظات أثناء الإنشاء يخلق انطباعًا بالبطء.
|
||||
**استخدام الموارد (Resource Usage)**: يجب تخزين الاستجابات الكاملة في الذاكرة.
|
||||
|
||||
تعالج هذه المواصفات هذه القيود من خلال تمكين التسليم التدريجي للاستجابة مع الحفاظ على التوافق الكامل مع الإصدارات السابقة.
|
||||
|
||||
|
||||
## التصميم التقني
|
||||
|
||||
### المرحلة الأولى: البنية التحتية
|
||||
|
||||
تضع المرحلة الأولى الأساس للبث عن طريق تعديل المخططات وواجهات برمجة التطبيقات (APIs) وأدوات سطر الأوامر (CLI).
|
||||
|
||||
|
||||
#### تغييرات المخططات
|
||||
|
||||
##### مخطط LLM (`trustgraph-base/trustgraph/schema/services/llm.py`)
|
||||
|
||||
**تغييرات الطلبات:**
|
||||
|
||||
```python
|
||||
class TextCompletionRequest(Record):
|
||||
system = String()
|
||||
prompt = String()
|
||||
streaming = Boolean() # NEW: Default false for backward compatibility
|
||||
```
|
||||
|
||||
`streaming`: عندما `true`، يتم طلب تسليم الاستجابة بتدفق.
|
||||
الافتراضي: `false` (يتم الحفاظ على السلوك الحالي).
|
||||
|
||||
**تغييرات في الاستجابة:**
|
||||
|
||||
```python
|
||||
class TextCompletionResponse(Record):
|
||||
error = Error()
|
||||
response = String()
|
||||
in_token = Integer()
|
||||
out_token = Integer()
|
||||
model = String()
|
||||
end_of_stream = Boolean() # NEW: Indicates final message
|
||||
```
|
||||
|
||||
`end_of_stream`: عندما `true`، يشير هذا إلى أن هذا هو الرد النهائي (أو الوحيد).
|
||||
للطلبات غير المتدفقة: رد واحد مع `end_of_stream=true`.
|
||||
للطلبات المتدفقة: ردود متعددة، جميعها مع `end_of_stream=false`.
|
||||
باستثناء الرد النهائي.
|
||||
|
||||
##### مخطط المطالبة (`trustgraph-base/trustgraph/schema/services/prompt.py`).
|
||||
|
||||
خدمة المطالبة تغلف إكمال النص، وبالتالي فهي تعكس نفس النمط:
|
||||
|
||||
**تغييرات الطلب:**
|
||||
|
||||
```python
|
||||
class PromptRequest(Record):
|
||||
id = String()
|
||||
terms = Map(String())
|
||||
streaming = Boolean() # NEW: Default false
|
||||
```
|
||||
|
||||
**التغييرات في الاستجابة:**
|
||||
|
||||
```python
|
||||
class PromptResponse(Record):
|
||||
error = Error()
|
||||
text = String()
|
||||
object = String()
|
||||
end_of_stream = Boolean() # NEW: Indicates final message
|
||||
```
|
||||
|
||||
#### التغييرات في واجهة برمجة التطبيقات (API) الخاصة بالبوابة.
|
||||
|
||||
يجب أن تعرض واجهة برمجة التطبيقات (API) الخاصة بالبوابة إمكانات البث لعملاء HTTP/WebSocket.
|
||||
|
||||
**تحديثات واجهة برمجة التطبيقات (API) REST:**
|
||||
|
||||
`POST /api/v1/text-completion`: قبول المعامل `streaming` في نص الطلب.
|
||||
يعتمد سلوك الاستجابة على علامة البث:
|
||||
`streaming=false`: استجابة JSON واحدة (السلوك الحالي).
|
||||
`streaming=true`: تدفق أحداث من الخادم (SSE) أو رسائل WebSocket.
|
||||
|
||||
**تنسيق الاستجابة (البث):**
|
||||
|
||||
يتبع كل جزء مُبث نفس هيكل المخطط.
|
||||
```json
|
||||
{
|
||||
"response": "partial text...",
|
||||
"end_of_stream": false,
|
||||
"model": "model-name"
|
||||
}
|
||||
```
|
||||
|
||||
الجزء الأخير:
|
||||
```json
|
||||
{
|
||||
"response": "final text chunk",
|
||||
"end_of_stream": true,
|
||||
"in_token": 150,
|
||||
"out_token": 500,
|
||||
"model": "model-name"
|
||||
}
|
||||
```
|
||||
|
||||
#### تغييرات في واجهة برمجة التطبيقات (API) الخاصة بـ Python
|
||||
|
||||
يجب أن تدعم واجهة برمجة التطبيقات (API) الخاصة بعميل Python كلاً من الأوضاع المتدفقة وغير المتدفقة
|
||||
مع الحفاظ على التوافق مع الإصدارات السابقة.
|
||||
|
||||
**تحديثات لـ LlmClient** (`trustgraph-base/trustgraph/clients/llm_client.py`):
|
||||
|
||||
```python
|
||||
class LlmClient(BaseClient):
|
||||
def request(self, system, prompt, timeout=300, streaming=False):
|
||||
"""
|
||||
Non-streaming request (backward compatible).
|
||||
Returns complete response string.
|
||||
"""
|
||||
# Existing behavior when streaming=False
|
||||
|
||||
async def request_stream(self, system, prompt, timeout=300):
|
||||
"""
|
||||
Streaming request.
|
||||
Yields response chunks as they arrive.
|
||||
"""
|
||||
# New async generator method
|
||||
```
|
||||
|
||||
**تحديثات PromptClient** (`trustgraph-base/trustgraph/base/prompt_client.py`):
|
||||
|
||||
نمط مشابه مع المعامل `streaming` وإصدار مولد غير متزامن.
|
||||
|
||||
#### تغييرات في أداة سطر الأوامر
|
||||
|
||||
**tg-invoke-llm** (`trustgraph-cli/trustgraph/cli/invoke_llm.py`):
|
||||
|
||||
```
|
||||
tg-invoke-llm [system] [prompt] [--no-streaming] [-u URL] [-f flow-id]
|
||||
```
|
||||
|
||||
تفعيل البث افتراضيًا لتحسين تجربة المستخدم التفاعلية.
|
||||
العلم `--no-streaming` يعطل البث.
|
||||
عند تفعيل البث: إخراج الرموز إلى الإخراج القياسي (stdout) فور وصولها.
|
||||
عند عدم تفعيل البث: الانتظار حتى اكتمال الاستجابة، ثم إخراجها.
|
||||
|
||||
**tg-invoke-prompt** (`trustgraph-cli/trustgraph/cli/invoke_prompt.py`):
|
||||
|
||||
```
|
||||
tg-invoke-prompt [template-id] [var=value...] [--no-streaming] [-u URL] [-f flow-id]
|
||||
```
|
||||
|
||||
نفس النمط مثل `tg-invoke-llm`.
|
||||
|
||||
#### تغييرات في الفئة الأساسية لخدمة نماذج اللغة الكبيرة (LLM).
|
||||
|
||||
**LlmService** (`trustgraph-base/trustgraph/base/llm_service.py`):
|
||||
|
||||
```python
|
||||
class LlmService(FlowProcessor):
|
||||
async def on_request(self, msg, consumer, flow):
|
||||
request = msg.value()
|
||||
streaming = getattr(request, 'streaming', False)
|
||||
|
||||
if streaming and self.supports_streaming():
|
||||
async for chunk in self.generate_content_stream(...):
|
||||
await self.send_response(chunk, end_of_stream=False)
|
||||
await self.send_response(final_chunk, end_of_stream=True)
|
||||
else:
|
||||
response = await self.generate_content(...)
|
||||
await self.send_response(response, end_of_stream=True)
|
||||
|
||||
def supports_streaming(self):
|
||||
"""Override in subclass to indicate streaming support."""
|
||||
return False
|
||||
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
"""Override in subclass to implement streaming."""
|
||||
raise NotImplementedError()
|
||||
```
|
||||
|
||||
--
|
||||
|
||||
### المرحلة الثانية: إثبات المفهوم لـ VertexAI
|
||||
|
||||
تنفذ المرحلة الثانية البث في مزود واحد (VertexAI) للتحقق من صحة
|
||||
البنية التحتية وتمكين الاختبار الشامل.
|
||||
|
||||
#### تنفيذ VertexAI
|
||||
|
||||
**الوحدة:** `trustgraph-vertexai/trustgraph/model/text_completion/vertexai/llm.py`
|
||||
|
||||
**التغييرات:**
|
||||
|
||||
1. تجاوز `supports_streaming()` لإرجاع `True`
|
||||
2. تنفيذ مُولّد غير متزامن `generate_content_stream()`
|
||||
3. التعامل مع نماذج Gemini و Claude (عبر واجهة برمجة تطبيقات VertexAI Anthropic)
|
||||
|
||||
**البث باستخدام Gemini:**
|
||||
|
||||
```python
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
model_instance = self.get_model(model, temperature)
|
||||
response = model_instance.generate_content(
|
||||
[system, prompt],
|
||||
stream=True # Enable streaming
|
||||
)
|
||||
for chunk in response:
|
||||
yield LlmChunk(
|
||||
text=chunk.text,
|
||||
in_token=None, # Available only in final chunk
|
||||
out_token=None,
|
||||
)
|
||||
# Final chunk includes token counts from response.usage_metadata
|
||||
```
|
||||
|
||||
**كلود (عبر VertexAI من شركة Anthropic) - البث:**
|
||||
|
||||
```python
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
with self.anthropic_client.messages.stream(...) as stream:
|
||||
for text in stream.text_stream:
|
||||
yield LlmChunk(text=text)
|
||||
# Token counts from stream.get_final_message()
|
||||
```
|
||||
|
||||
#### الاختبار
|
||||
|
||||
اختبارات الوحدة لتجميع الاستجابات المتدفقة.
|
||||
اختبارات التكامل مع VertexAI (Gemini و Claude).
|
||||
اختبارات شاملة: سطر الأوامر -> البوابة -> Pulsar -> VertexAI -> العودة.
|
||||
اختبارات التوافق مع الإصدارات السابقة: لا تزال طلبات عدم التدفق تعمل.
|
||||
|
||||
--
|
||||
|
||||
### المرحلة الثالثة: جميع مزودي نماذج اللغة الكبيرة
|
||||
|
||||
تمتد المرحلة الثالثة لدعم التدفق إلى جميع مزودي نماذج اللغة الكبيرة في النظام.
|
||||
|
||||
#### حالة تنفيذ المزود
|
||||
|
||||
يجب على كل مزود إما:
|
||||
1. **دعم كامل للتدفق**: تنفيذ `generate_content_stream()`
|
||||
2. **وضع التوافق**: التعامل مع علامة `end_of_stream` بشكل صحيح
|
||||
(إرجاع استجابة واحدة مع `end_of_stream=true`)
|
||||
|
||||
| المزود | الحزمة | دعم التدفق |
|
||||
|----------|---------|-------------------|
|
||||
| OpenAI | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| Claude/Anthropic | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| Ollama | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| Cohere | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| Mistral | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| Azure OpenAI | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| Google AI Studio | trustgraph-flow | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| VertexAI | trustgraph-vertexai | كامل (المرحلة الثانية) |
|
||||
| Bedrock | trustgraph-bedrock | كامل (واجهة برمجة تطبيقات تدفق أصلية) |
|
||||
| LM Studio | trustgraph-flow | كامل (متوافق مع OpenAI) |
|
||||
| LlamaFile | trustgraph-flow | كامل (متوافق مع OpenAI) |
|
||||
| vLLM | trustgraph-flow | كامل (متوافق مع OpenAI) |
|
||||
| TGI | trustgraph-flow | قيد التحديد |
|
||||
| Azure | trustgraph-flow | قيد التحديد |
|
||||
|
||||
#### نمط التنفيذ
|
||||
|
||||
بالنسبة لمزودي نماذج اللغة الكبيرة المتوافقين مع OpenAI (OpenAI، LM Studio، LlamaFile، vLLM):
|
||||
|
||||
```python
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
response = await self.client.chat.completions.create(
|
||||
model=model,
|
||||
messages=[
|
||||
{"role": "system", "content": system},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
temperature=temperature,
|
||||
stream=True
|
||||
)
|
||||
async for chunk in response:
|
||||
if chunk.choices[0].delta.content:
|
||||
yield LlmChunk(text=chunk.choices[0].delta.content)
|
||||
```
|
||||
|
||||
--
|
||||
|
||||
### المرحلة الرابعة: واجهة برمجة التطبيقات (API) للوكيل
|
||||
|
||||
المرحلة الرابعة توسع البث ليشمل واجهة برمجة التطبيقات (API) للوكيل. هذا أكثر تعقيدًا لأن
|
||||
واجهة برمجة التطبيقات (API) للوكيل هي بالفعل متعددة الرسائل بطبيعتها (فكرة ← إجراء ← ملاحظة
|
||||
← تكرار ← إجابة نهائية).
|
||||
|
||||
#### مخطط الوكيل الحالي
|
||||
|
||||
```python
|
||||
class AgentStep(Record):
|
||||
thought = String()
|
||||
action = String()
|
||||
arguments = Map(String())
|
||||
observation = String()
|
||||
user = String()
|
||||
|
||||
class AgentRequest(Record):
|
||||
question = String()
|
||||
state = String()
|
||||
group = Array(String())
|
||||
history = Array(AgentStep())
|
||||
user = String()
|
||||
|
||||
class AgentResponse(Record):
|
||||
answer = String()
|
||||
error = Error()
|
||||
thought = String()
|
||||
observation = String()
|
||||
```
|
||||
|
||||
#### التغييرات المقترحة في مخطط الوكيل.
|
||||
|
||||
**طلب التغييرات:**
|
||||
|
||||
```python
|
||||
class AgentRequest(Record):
|
||||
question = String()
|
||||
state = String()
|
||||
group = Array(String())
|
||||
history = Array(AgentStep())
|
||||
user = String()
|
||||
streaming = Boolean() # NEW: Default false
|
||||
```
|
||||
|
||||
**التغييرات في الاستجابة:**
|
||||
|
||||
ينتج الوكيل أنواعًا متعددة من المخرجات خلال دورة التفكير الخاصة به:
|
||||
الأفكار (التفكير)
|
||||
الإجراءات (استدعاءات الأدوات)
|
||||
الملاحظات (نتائج الأدوات)
|
||||
الإجابة (الاستجابة النهائية)
|
||||
الأخطاء
|
||||
|
||||
نظرًا لأن `chunk_type` يحدد نوع المحتوى الذي يتم إرساله، يمكن دمج الحقول المنفصلة
|
||||
`answer`، `error`، `thought`، و `observation` في
|
||||
حقل واحد وهو `content`:
|
||||
|
||||
```python
|
||||
class AgentResponse(Record):
|
||||
chunk_type = String() # "thought", "action", "observation", "answer", "error"
|
||||
content = String() # The actual content (interpretation depends on chunk_type)
|
||||
end_of_message = Boolean() # Current thought/action/observation/answer is complete
|
||||
end_of_dialog = Boolean() # Entire agent dialog is complete
|
||||
```
|
||||
|
||||
**المعاني الدلالية للحقول:**
|
||||
|
||||
`chunk_type`: يشير إلى نوع المحتوى الموجود في حقل `content`.
|
||||
`"thought"`: تفكير/استنتاج الوكيل.
|
||||
`"action"`: الأداة/الإجراء المستخدم.
|
||||
`"observation"`: النتيجة من تنفيذ الأداة.
|
||||
`"answer"`: الإجابة النهائية لسؤال المستخدم.
|
||||
`"error"`: رسالة الخطأ.
|
||||
|
||||
`content`: المحتوى المتدفق الفعلي، والذي يتم تفسيره بناءً على `chunk_type`.
|
||||
|
||||
`end_of_message`: عندما `true`، يكون نوع الجزء الحالي مكتملًا.
|
||||
مثال: تم إرسال جميع الرموز الخاصة بالتفكير الحالي.
|
||||
يسمح للعملاء بمعرفة متى ينتقلون إلى المرحلة التالية.
|
||||
|
||||
`end_of_dialog`: عندما `true`، يكون التفاعل بأكمله مع الوكيل قد اكتمل.
|
||||
هذه هي الرسالة الأخيرة في التدفق.
|
||||
|
||||
#### سلوك التدفق الخاص بالوكيل
|
||||
|
||||
عندما `streaming=true`:
|
||||
|
||||
1. **تدفق الأفكار:**
|
||||
أجزاء متعددة مع `chunk_type="thought"`، `end_of_message=false`.
|
||||
الجزء الأخير من التفكير يحتوي على `end_of_message=true`.
|
||||
2. **إشعار الإجراء:**
|
||||
جزء واحد مع `chunk_type="action"`، `end_of_message=true`.
|
||||
3. **الملاحظة:**
|
||||
جزء (أجزاء) مع `chunk_type="observation"`، والجزء الأخير يحتوي على `end_of_message=true`.
|
||||
4. **كرر** الخطوات من 1 إلى 3 أثناء قيام الوكيل بالتفكير.
|
||||
5. **الإجابة النهائية:**
|
||||
`chunk_type="answer"` مع الإجابة النهائية في `content`.
|
||||
الجزء الأخير يحتوي على `end_of_message=true`، `end_of_dialog=true`.
|
||||
|
||||
**تسلسل التدفق النموذجي:**
|
||||
|
||||
```
|
||||
{chunk_type: "thought", content: "I need to", end_of_message: false, end_of_dialog: false}
|
||||
{chunk_type: "thought", content: " search for...", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "action", content: "search", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "observation", content: "Found: ...", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "thought", content: "Based on this", end_of_message: false, end_of_dialog: false}
|
||||
{chunk_type: "thought", content: " I can answer...", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "answer", content: "The answer is...", end_of_message: true, end_of_dialog: true}
|
||||
```
|
||||
|
||||
عندما `streaming=false`:
|
||||
الحفاظ على السلوك الحالي
|
||||
استجابة واحدة مع إجابة كاملة
|
||||
`end_of_message=true`، `end_of_dialog=true`
|
||||
|
||||
#### بوابة وواجهة برمجة تطبيقات بايثون
|
||||
|
||||
البوابة: نقطة نهاية SSE/WebSocket جديدة لبث الوكيل
|
||||
واجهة برمجة تطبيقات بايثون: طريقة مُولِّد غير متزامن جديدة `agent_stream()`
|
||||
|
||||
--
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
**لا توجد نقاط ضعف جديدة**: يستخدم البث نفس آليات المصادقة/التفويض
|
||||
**تحديد المعدل**: تطبيق حدود معدل لكل رمز أو لكل جزء إذا لزم الأمر
|
||||
**معالجة الاتصال**: إنهاء التدفقات بشكل صحيح عند قطع اتصال العميل
|
||||
**إدارة المهلة الزمنية**: تحتاج طلبات البث إلى معالجة مناسبة للمهلة الزمنية
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
**الذاكرة**: يقلل البث من استخدام الذاكرة القصوى (بدون تخزين مؤقت للاستجابة الكاملة)
|
||||
**زمن الوصول**: تم تقليل زمن الوصول إلى الرمز الأول بشكل كبير
|
||||
**نفقات الاتصال**: تحتوي اتصالات SSE/WebSocket على نفقات صيانة الاتصال
|
||||
**إنتاجية بولسار**: رسائل صغيرة متعددة مقابل رسالة كبيرة واحدة
|
||||
مقايضة
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
### اختبارات الوحدة
|
||||
تسلسل/إلغاء تسلسل المخطط مع الحقول الجديدة
|
||||
التوافق مع الإصدارات السابقة (تستخدم الحقول المفقودة القيم الافتراضية)
|
||||
منطق تجميع الأجزاء
|
||||
|
||||
### اختبارات التكامل
|
||||
تطبيق كل مزود LLM لتنفيذ البث
|
||||
نقاط نهاية البث لواجهة برمجة تطبيقات البوابة
|
||||
طرق البث لعميل بايثون
|
||||
|
||||
### اختبارات شاملة
|
||||
إخراج أداة سطر الأوامر (CLI) للبث
|
||||
التدفق الكامل: العميل → البوابة → بولسار → LLM → العودة
|
||||
أحمال عمل مختلطة (بث/غير بث)
|
||||
|
||||
### اختبارات التوافق مع الإصدارات السابقة
|
||||
تعمل العملاء الحاليون دون تعديل
|
||||
تتصرف طلبات عدم البث بشكل مماثل
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
### المرحلة الأولى: البنية التحتية
|
||||
نشر تغييرات المخطط (متوافقة مع الإصدارات السابقة)
|
||||
نشر تحديثات واجهة برمجة تطبيقات البوابة
|
||||
نشر تحديثات واجهة برمجة تطبيقات بايثون
|
||||
إصدار تحديثات أداة سطر الأوامر (CLI)
|
||||
|
||||
### المرحلة الثانية: VertexAI
|
||||
نشر تطبيق VertexAI للبث.
|
||||
التحقق من صحته باستخدام أحمال العمل التجريبية.
|
||||
|
||||
### المرحلة الثالثة: جميع المزودين.
|
||||
نشر تحديثات المزودين بشكل تدريجي.
|
||||
مراقبة المشكلات.
|
||||
|
||||
### المرحلة الرابعة: واجهة برمجة تطبيقات الوكيل.
|
||||
نشر تغييرات مخطط الوكيل.
|
||||
نشر تطبيق البث للوكيل.
|
||||
تحديث الوثائق.
|
||||
|
||||
## الجدول الزمني.
|
||||
|
||||
| المرحلة | الوصف | التبعيات |
|
||||
|-------|-------------|--------------|
|
||||
| المرحلة الأولى | البنية التحتية | لا يوجد |
|
||||
| المرحلة الثانية | نموذج VertexAI الأولي | المرحلة الأولى |
|
||||
| المرحلة الثالثة | جميع المزودين | المرحلة الثانية |
|
||||
| المرحلة الرابعة | واجهة برمجة تطبيقات الوكيل | المرحلة الثالثة |
|
||||
|
||||
## قرارات التصميم.
|
||||
|
||||
تمت معالجة الأسئلة التالية أثناء التحديد:
|
||||
|
||||
1. **عدد الرموز في البث**: عدد الرموز هو الفروق، وليس المجاميع التراكمية.
|
||||
يمكن للمستهلكين جمعها إذا لزم الأمر. يتطابق هذا مع كيفية قيام معظم المزودين بالإبلاغ
|
||||
عن الاستخدام ويبسط التنفيذ.
|
||||
|
||||
2. **معالجة الأخطاء في التدفقات**: في حالة حدوث خطأ، يتم ملء الحقل `error`
|
||||
ولا يلزم وجود أي حقول أخرى. الخطأ هو دائمًا آخر رسالة - لا يُسمح بإرسال أو استقبال رسائل لاحقة بعد ذلك.
|
||||
أو توقعها.
|
||||
خطأ. بالنسبة لتدفقات نماذج اللغة الكبيرة/التعليمات، `end_of_stream=true`. بالنسبة لتدفقات الوكلاء،
|
||||
`chunk_type="error"` مع `end_of_dialog=true`.
|
||||
|
||||
3. **استعادة الاستجابات الجزئية**: بروتوكول المراسلة (Pulsار) يتميز بالمرونة،
|
||||
لذلك لا توجد حاجة إلى إعادة محاولة الرسائل على مستوى الرسالة. إذا فقد العميل تتبع التدفق
|
||||
أو انقطع الاتصال، فيجب عليه إعادة محاولة الطلب بأكمله من البداية.
|
||||
|
||||
4. **خدمة الاستجابة السريعة المتدفقة**: تدعم البث فقط للنصوص (`text`).
|
||||
الاستجابات، وليس الاستجابات المنظمة (`object`). تعرف خدمة الاستجابة السريعة في
|
||||
البداية ما إذا كانت المخرجات ستكون بتنسيق JSON أو نص بناءً على قالب
|
||||
الاستعلام. إذا تم إجراء طلب بث لاستعلام ينتج عنه مخرجات بتنسيق JSON، فإن
|
||||
يجب أن يقوم الخدمة إما:
|
||||
بإرجاع كائن JSON كامل في استجابة واحدة باستخدام `end_of_stream=true`، أو
|
||||
برفض طلب البث مع وجود خطأ.
|
||||
|
||||
## الأسئلة المفتوحة
|
||||
|
||||
لا يوجد أسئلة في الوقت الحالي.
|
||||
|
||||
## المراجع
|
||||
|
||||
مخطط نموذج اللغة الكبير الحالي: `trustgraph-base/trustgraph/schema/services/llm.py`
|
||||
مخطط المطالبة الحالي: `trustgraph-base/trustgraph/schema/services/prompt.py`
|
||||
مخطط الوكيل الحالي: `trustgraph-base/trustgraph/schema/services/agent.py`
|
||||
الخدمة الأساسية لنموذج اللغة الكبير: `trustgraph-base/trustgraph/base/llm_service.py`
|
||||
مزود VertexAI: `trustgraph-vertexai/trustgraph/model/text_completion/vertexai/llm.py`
|
||||
واجهة برمجة التطبيقات (API) للواجهة: `trustgraph-base/trustgraph/api/`
|
||||
أدوات سطر الأوامر (CLI): `trustgraph-cli/trustgraph/cli/`
|
||||
621
docs/tech-specs/ar/structured-data-2.ar.md
Normal file
621
docs/tech-specs/ar/structured-data-2.ar.md
Normal file
|
|
@ -0,0 +1,621 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية للبيانات المهيكلة (الجزء 2)"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية للبيانات المهيكلة (الجزء 2)
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تتناول هذه المواصفات المشكلات والفجوات التي تم تحديدها أثناء التنفيذ الأولي لدمج البيانات المهيكلة في TrustGraph، كما هو موضح في `structured-data.md`.
|
||||
|
||||
## بيان المشكلات
|
||||
|
||||
### 1. عدم اتساق في التسمية: "كائن" مقابل "صف"
|
||||
|
||||
يستخدم التنفيذ الحالي مصطلح "كائن" في جميع أنحائه (على سبيل المثال، `ExtractedObject`، واستخراج الكائنات، وتضمينات الكائنات). هذا المصطلح عام جدًا ويسبب ارتباكًا:
|
||||
|
||||
مصطلح "كائن" مصطلح عام ومزدحم في البرمجيات (كائنات بايثون، كائنات JSON، إلخ).
|
||||
البيانات التي يتم التعامل معها هي في الأساس بيانات جدولية - صفوف في الجداول ذات المخططات المحددة.
|
||||
مصطلح "صف" يصف نموذج البيانات بشكل أكثر دقة ويتوافق مع مصطلحات قواعد البيانات.
|
||||
|
||||
يظهر هذا التناقض في أسماء الوحدات، وأسماء الفئات، وأنواع الرسائل، والوثائق.
|
||||
|
||||
### 2. قيود استعلامات تخزين الصفوف
|
||||
|
||||
يحتوي تنفيذ تخزين الصفوف الحالي على قيود استعلام كبيرة:
|
||||
|
||||
**عدم تطابق مع اللغة الطبيعية**: تواجه الاستعلامات صعوبة في التعامل مع الاختلافات في البيانات الواقعية. على سبيل المثال:
|
||||
من الصعب العثور على قاعدة بيانات الشوارع التي تحتوي على `"CHESTNUT ST"` عند السؤال عن `"Chestnut Street"`.
|
||||
تكسر الاختصارات، والاختلافات في الأحرف الكبيرة والصغيرة، وتغيرات التنسيق استعلامات المطابقة التامة.
|
||||
يتوقع المستخدمون فهمًا دلاليًا، لكن المستودع يوفر مطابقة حرفية.
|
||||
|
||||
**مشكلات تطور المخطط**: يؤدي تغيير المخططات إلى حدوث مشكلات:
|
||||
قد لا تتوافق البيانات الموجودة مع المخططات المحدثة.
|
||||
يمكن أن تؤدي تغييرات هيكل الجدول إلى تعطيل الاستعلامات وتكامل البيانات.
|
||||
لا توجد مسار ترحيل واضح لتحديثات المخطط.
|
||||
|
||||
### 3. مطلوب تضمينات الصفوف
|
||||
|
||||
بالإضافة إلى المشكلة رقم 2، يحتاج النظام إلى تضمينات متجهة لبيانات الصفوف لتمكين:
|
||||
|
||||
البحث الدلالي عبر البيانات المهيكلة (العثور على "شارع تشيستنوت" عندما تحتوي البيانات على "CHESTNUT ST").
|
||||
مطابقة التشابه للاستعلامات الغامضة.
|
||||
البحث الهجين الذي يجمع بين المرشحات المهيكلة ومطابقة التشابه الدلالي.
|
||||
دعم أفضل للغة الطبيعية.
|
||||
|
||||
تم تحديد خدمة التضمين ولكن لم يتم تنفيذها.
|
||||
|
||||
### 4. استيعاب بيانات الصفوف غير مكتمل
|
||||
|
||||
مسار استيعاب البيانات المهيكلة ليس فعالًا بالكامل:
|
||||
|
||||
توجد مطالبات تشخيصية لتصنيف تنسيقات الإدخال (CSV، JSON، إلخ).
|
||||
خدمة الاستيعاب التي تستخدم هذه المطالبات غير متصلة بالنظام.
|
||||
لا يوجد مسار شامل لتحميل البيانات المهيكلة مسبقًا إلى مستودع الصفوف.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**مرونة المخطط**: تمكين تطور المخطط دون تعطل البيانات الموجودة أو الحاجة إلى عمليات ترحيل.
|
||||
**تسمية متسقة**: توحيد مصطلح "صف" في جميع أنحاء قاعدة التعليمات البرمجية.
|
||||
**قابلية الاستعلام الدلالي**: دعم المطابقة الغامضة / الدلالية عبر تضمينات الصفوف.
|
||||
**مسار استيعاب كامل**: توفير مسار شامل لتحميل البيانات المهيكلة.
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### مخطط تخزين صفوف موحد
|
||||
|
||||
أنشأ التنفيذ السابق جدول Cassandra منفصل لكل مخطط. تسبب ذلك في حدوث مشكلات عند تطور المخططات، حيث تتطلب تغييرات هيكل الجدول عمليات ترحيل.
|
||||
|
||||
يستخدم التصميم الجديد جدولًا موحدًا واحدًا لجميع بيانات الصفوف:
|
||||
|
||||
```sql
|
||||
CREATE TABLE rows (
|
||||
collection text,
|
||||
schema_name text,
|
||||
index_name text,
|
||||
index_value frozen<list<text>>,
|
||||
data map<text, text>,
|
||||
source text,
|
||||
PRIMARY KEY ((collection, schema_name, index_name), index_value)
|
||||
)
|
||||
```
|
||||
|
||||
#### تعريفات الأعمدة
|
||||
|
||||
| العمود | النوع | الوصف |
|
||||
|--------|------|-------------|
|
||||
| `collection` | `text` | معرف جمع البيانات/الاستيراد (من البيانات الوصفية) |
|
||||
| `schema_name` | `text` | اسم المخطط الذي يتوافق معه هذا الصف |
|
||||
| `index_name` | `text` | اسم الحقل/الحقول المفهرسة، مفصولة بفاصلة للحقول المركبة |
|
||||
| `index_value` | `frozen<list<text>>` | قيم الفهرس كقائمة |
|
||||
| `data` | `map<text, text>` | بيانات الصف كأزواج مفتاح-قيمة |
|
||||
| `source` | `text` | عنوان URI اختياري يربط بمعلومات المصدر في الرسم البياني المعرفي. السلسلة الفارغة أو NULL تشير إلى عدم وجود مصدر. |
|
||||
|
||||
#### معالجة الفهرس
|
||||
|
||||
يتم تخزين كل صف عدة مرات - مرة واحدة لكل حقل مفهرس معرف في المخطط. يتم التعامل مع حقول المفتاح الأساسي كفهرس بدون علامة خاصة، مما يوفر مرونة مستقبلية.
|
||||
|
||||
**مثال على الفهرس ذي الحقل الواحد:**
|
||||
يحدد المخطط `email` كحقل مفهرس
|
||||
`index_name = "email"`
|
||||
`index_value = ['foo@bar.com']`
|
||||
|
||||
**مثال على الفهرس المركب:**
|
||||
يحدد المخطط فهرسًا مركبًا على `region` و `status`
|
||||
`index_name = "region,status"` (أسماء الحقول مرتبة ومفصولة بفاصلة)
|
||||
`index_value = ['US', 'active']` (القيم بنفس ترتيب أسماء الحقول)
|
||||
|
||||
**مثال على المفتاح الأساسي:**
|
||||
يحدد المخطط `customer_id` كمفتاح أساسي
|
||||
`index_name = "customer_id"`
|
||||
`index_value = ['CUST001']`
|
||||
|
||||
#### أنماط الاستعلام
|
||||
|
||||
تتبع جميع الاستعلامات نفس النمط بغض النظر عن الفهرس المستخدم:
|
||||
|
||||
```sql
|
||||
SELECT * FROM rows
|
||||
WHERE collection = 'import_2024'
|
||||
AND schema_name = 'customers'
|
||||
AND index_name = 'email'
|
||||
AND index_value = ['foo@bar.com']
|
||||
```
|
||||
|
||||
#### المقايضات التصميمية
|
||||
|
||||
**المزايا:**
|
||||
التغييرات في المخطط لا تتطلب تغييرات في هيكل الجدول.
|
||||
البيانات الموجودة في الصفوف غير مرئية لـ Cassandra - إضافة أو إزالة الحقول تكون شفافة.
|
||||
نمط استعلام متسق لجميع طرق الوصول.
|
||||
لا توجد فهارس ثانوية لـ Cassandra (والتي يمكن أن تكون بطيئة على نطاق واسع).
|
||||
أنواع Cassandra الأصلية في جميع أنحاء النظام (`map`، `frozen<list>`).
|
||||
|
||||
**المقايضات:**
|
||||
تضخيم الكتابة: كل إدخال صف = N إدخالات (واحد لكل حقل مفهرس).
|
||||
تكلفة تخزين إضافية بسبب تكرار بيانات الصفوف.
|
||||
يتم تخزين معلومات النوع في تكوين المخطط، ويتم التحويل في طبقة التطبيق.
|
||||
|
||||
#### نموذج الاتساق
|
||||
|
||||
التصميم يقبل بعض التبسيط:
|
||||
|
||||
1. **لا توجد تحديثات للصفوف**: النظام مخصص للإضافة فقط. هذا يلغي مخاوف الاتساق المتعلقة بتحديث نسخ متعددة من نفس الصف.
|
||||
|
||||
2. **تحمل تغيير المخطط**: عند تغيير المخططات (على سبيل المثال، إضافة أو إزالة الفهارس)، تحتفظ الصفوف الموجودة بفهرستها الأصلية. لن يتمكن المستخدمون من اكتشاف الصفوف القديمة عبر الفهارس الجديدة. يمكن للمستخدمين حذف وإعادة إنشاء مخطط لضمان الاتساق إذا لزم الأمر.
|
||||
|
||||
### تتبع الأقسام والحذف
|
||||
|
||||
#### المشكلة
|
||||
|
||||
باستخدام مفتاح التقسيم `(collection, schema_name, index_name)`، يتطلب الحذف الفعال معرفة جميع مفاتيح التقسيم المراد حذفها. يتطلب الحذف باستخدام `collection` أو `collection + schema_name` معرفة جميع قيم `index_name` التي تحتوي على بيانات.
|
||||
|
||||
#### جدول تتبع الأقسام
|
||||
|
||||
جدول بحث ثانوي يتتبع الأقسام الموجودة:
|
||||
|
||||
```sql
|
||||
CREATE TABLE row_partitions (
|
||||
collection text,
|
||||
schema_name text,
|
||||
index_name text,
|
||||
PRIMARY KEY ((collection), schema_name, index_name)
|
||||
)
|
||||
```
|
||||
|
||||
هذا يتيح اكتشافًا فعالًا للأقسام لعمليات الحذف.
|
||||
|
||||
#### سلوك كاتب الصفوف
|
||||
|
||||
يحتفظ كاتب الصفوف بخزن مؤقت في الذاكرة لأزواج `(collection, schema_name)` المسجلة. عند معالجة صف:
|
||||
|
||||
1. تحقق مما إذا كانت `(collection, schema_name)` موجودة في الذاكرة المؤقتة.
|
||||
2. إذا لم تكن موجودة في الذاكرة المؤقتة (أول صف لهذه الزوج):
|
||||
ابحث في تكوين المخطط للحصول على جميع أسماء الفهارس.
|
||||
أدخل إدخالات في `row_partitions` لكل `(collection, schema_name, index_name)`.
|
||||
أضف الزوج إلى الذاكرة المؤقتة.
|
||||
3. تابع بكتابة بيانات الصف.
|
||||
|
||||
يراقب كاتب الصفوف أيضًا أحداث تغيير تكوين المخطط. عند حدوث تغيير في المخطط، يتم مسح إدخالات الذاكرة المؤقتة ذات الصلة بحيث يؤدي الصف التالي إلى إعادة التسجيل باستخدام أسماء الفهارس المحدثة.
|
||||
|
||||
يضمن هذا النهج:
|
||||
تتم كتابة جداول البحث مرة واحدة لكل زوج `(collection, schema_name)`، وليس لكل صف.
|
||||
يعكس جدول البحث الفهارس التي كانت نشطة عند كتابة البيانات.
|
||||
يتم اكتشاف تغييرات المخطط في منتصف الاستيراد بشكل صحيح.
|
||||
|
||||
#### عمليات الحذف
|
||||
|
||||
**حذف المجموعة:**
|
||||
```sql
|
||||
-- 1. Discover all partitions
|
||||
SELECT schema_name, index_name FROM row_partitions WHERE collection = 'X';
|
||||
|
||||
-- 2. Delete each partition from rows table
|
||||
DELETE FROM rows WHERE collection = 'X' AND schema_name = '...' AND index_name = '...';
|
||||
-- (repeat for each discovered partition)
|
||||
|
||||
-- 3. Clean up the lookup table
|
||||
DELETE FROM row_partitions WHERE collection = 'X';
|
||||
```
|
||||
|
||||
**حذف المجموعة والمخطط:**
|
||||
```sql
|
||||
-- 1. Discover partitions for this schema
|
||||
SELECT index_name FROM row_partitions WHERE collection = 'X' AND schema_name = 'Y';
|
||||
|
||||
-- 2. Delete each partition from rows table
|
||||
DELETE FROM rows WHERE collection = 'X' AND schema_name = 'Y' AND index_name = '...';
|
||||
-- (repeat for each discovered partition)
|
||||
|
||||
-- 3. Clean up the lookup table entries
|
||||
DELETE FROM row_partitions WHERE collection = 'X' AND schema_name = 'Y';
|
||||
```
|
||||
|
||||
### تضمينات الصفوف
|
||||
|
||||
تتيح تضمينات الصفوف المطابقة الدلالية/التقريبية على القيم المفهرسة، مما يحل مشكلة عدم تطابق اللغة الطبيعية (على سبيل المثال، العثور على "CHESTNUT ST" عند البحث عن "Chestnut Street").
|
||||
|
||||
#### نظرة عامة على التصميم
|
||||
|
||||
يتم تضمين كل قيمة مفهرسة وتخزينها في مخزن متجه (Qdrant). في وقت الاستعلام، يتم تضمين الاستعلام، ويتم العثور على المتجهات المشابهة، ويتم استخدام البيانات الوصفية المرتبطة للبحث عن الصفوف الفعلية في Cassandra.
|
||||
|
||||
#### هيكل مجموعة Qdrant
|
||||
|
||||
مجموعة Qdrant واحدة لكل مجموعة `(user, collection, schema_name, dimension)`:
|
||||
|
||||
**تسمية المجموعة:** `rows_{user}_{collection}_{schema_name}_{dimension}`
|
||||
يتم تنظيف الأسماء (يتم استبدال الأحرف غير الأبجدية الرقمية بـ `_`، وتحويلها إلى أحرف صغيرة، وتتم إضافة بادئة رقمية بـ `r_`)
|
||||
**السبب:** يتيح حذف مثيل `(user, collection, schema_name)` بشكل نظيف عن طريق حذف مجموعات Qdrant المطابقة؛ تسمح لاحقة الأبعاد لوجود نماذج تضمين مختلفة.
|
||||
|
||||
#### ما الذي يتم تضمينه
|
||||
|
||||
التمثيل النصي لقيم الفهرس:
|
||||
|
||||
| نوع الفهرس | مثال `index_value` | النص المراد تضمينه |
|
||||
|------------|----------------------|---------------|
|
||||
| حقل واحد | `['foo@bar.com']` | `"foo@bar.com"` |
|
||||
| مركب | `['US', 'active']` | `"US active"` (مفصولة بمسافات) |
|
||||
|
||||
#### هيكل النقطة
|
||||
|
||||
تحتوي كل نقطة Qdrant على:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "<uuid>",
|
||||
"vector": [0.1, 0.2, ...],
|
||||
"payload": {
|
||||
"index_name": "street_name",
|
||||
"index_value": ["CHESTNUT ST"],
|
||||
"text": "CHESTNUT ST"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| حقل الحمولة | الوصف |
|
||||
|---------------|-------------|
|
||||
| `index_name` | الحقول المفهرسة التي يمثلها هذا التضمين. |
|
||||
| `index_value` | القائمة الأصلية للقيم (للبحث في Cassandra). |
|
||||
| `text` | النص الذي تم تضمينه (للتصحيح/العرض). |
|
||||
|
||||
ملاحظة: `user`، و `collection`، و `schema_name` مستمدة ضمنيًا من اسم مجموعة Qdrant.
|
||||
|
||||
#### مسار الاستعلام
|
||||
|
||||
1. يقوم المستخدم بالاستعلام عن "Chestnut Street" ضمن المستخدم U، والمجموعة X، والمخطط Y.
|
||||
2. تضمين نص الاستعلام.
|
||||
3. تحديد اسم(أسماء) مجموعة Qdrant التي تتطابق مع البادئة `rows_U_X_Y_`.
|
||||
4. البحث في مجموعة(مجموعات) Qdrant المطابقة عن أقرب المتجهات.
|
||||
5. الحصول على النقاط المطابقة التي تحتوي على حمولات تحتوي على `index_name` و `index_value`.
|
||||
6. الاستعلام عن Cassandra:
|
||||
```sql
|
||||
SELECT * FROM rows
|
||||
WHERE collection = 'X'
|
||||
AND schema_name = 'Y'
|
||||
AND index_name = '<from payload>'
|
||||
AND index_value = <from payload>
|
||||
```
|
||||
7. إرجاع الصفوف المطابقة.
|
||||
|
||||
#### اختياري: التصفية حسب اسم الفهرس.
|
||||
|
||||
يمكن للاستعلامات اختيارياً أن تقوم بالتصفية باستخدام `index_name` في Qdrant للبحث في حقول محددة فقط:
|
||||
|
||||
**"ابحث عن أي حقل يطابق 'Chestnut'"** → ابحث في جميع المتجهات في المجموعة.
|
||||
**"ابحث عن 'street_name' الذي يطابق 'Chestnut'"** → قم بالتصفية حيث `payload.index_name = 'street_name'`.
|
||||
|
||||
#### البنية.
|
||||
|
||||
تتبع تضمينات الصف النمط **المكون من مرحلتين** المستخدم في GraphRAG (تضمينات الرسم البياني، تضمينات المستندات):
|
||||
|
||||
**المرحلة 1: حساب التضمين** (`trustgraph-flow/trustgraph/embeddings/row_embeddings/`) - تستهلك `ExtractedObject`، وتحسب التضمينات عبر خدمة التضمينات، وتُخرج `RowEmbeddings`.
|
||||
**المرحلة 2: تخزين التضمين** (`trustgraph-flow/trustgraph/storage/row_embeddings/qdrant/`) - تستهلك `RowEmbeddings`، وتكتب المتجهات إلى Qdrant.
|
||||
|
||||
كاتب صف Cassandra هو مستهلك متوازي منفصل:
|
||||
|
||||
**كاتب صف Cassandra** (`trustgraph-flow/trustgraph/storage/rows/cassandra`) - يستهلك `ExtractedObject`، ويكتب الصفوف إلى Cassandra.
|
||||
|
||||
تستهلك جميع الخدمات الثلاثة من نفس التدفق، مما يحافظ عليها منفصلة. هذا يسمح:
|
||||
بتوسيع نطاق كتابة Cassandra بشكل مستقل عن إنشاء التضمينات وتخزين المتجهات.
|
||||
يمكن تعطيل خدمات التضمين إذا لم تكن مطلوبة.
|
||||
لا تؤثر الأعطال في خدمة واحدة على الخدمات الأخرى.
|
||||
بنية متسقة مع مسارات GraphRAG.
|
||||
|
||||
#### مسار الكتابة.
|
||||
|
||||
**المرحلة 1 (معالج تضمينات الصف):** عند استقبال `ExtractedObject`:
|
||||
|
||||
1. ابحث عن المخطط للعثور على الحقول المفهرسة.
|
||||
2. لكل حقل مفهرس:
|
||||
قم بإنشاء التمثيل النصي لقيمة الفهرس.
|
||||
احسب التضمين عبر خدمة التضمينات.
|
||||
3. أخرج رسالة `RowEmbeddings` تحتوي على جميع المتجهات المحسوبة.
|
||||
|
||||
**المرحلة 2 (كتابة تضمينات الصف إلى Qdrant):** عند استقبال `RowEmbeddings`:
|
||||
|
||||
1. لكل تضمين في الرسالة:
|
||||
حدد مجموعة Qdrant من `(user, collection, schema_name, dimension)`.
|
||||
قم بإنشاء المجموعة إذا لزم الأمر (إنشاء كسول في الكتابة الأولى).
|
||||
قم بتحديث النقطة باستخدام المتجه والحمولة.
|
||||
|
||||
#### أنواع الرسائل.
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RowIndexEmbedding:
|
||||
index_name: str # The indexed field name(s)
|
||||
index_value: list[str] # The field value(s)
|
||||
text: str # Text that was embedded
|
||||
vectors: list[list[float]] # Computed embedding vectors
|
||||
|
||||
@dataclass
|
||||
class RowEmbeddings:
|
||||
metadata: Metadata
|
||||
schema_name: str
|
||||
embeddings: list[RowIndexEmbedding]
|
||||
```
|
||||
|
||||
#### دمج الحذف
|
||||
|
||||
يتم اكتشاف مجموعات Qdrant من خلال مطابقة البادئة مع نمط اسم المجموعة:
|
||||
|
||||
**حذف `(user, collection)`:**
|
||||
1. قائمة بجميع مجموعات Qdrant التي تتطابق مع البادئة `rows_{user}_{collection}_`
|
||||
2. حذف كل مجموعة مطابقة
|
||||
3. حذف أقسام صفوف Cassandra (كما هو موثق أعلاه)
|
||||
4. تنظيف إدخالات `row_partitions`
|
||||
|
||||
**حذف `(user, collection, schema_name)`:**
|
||||
1. قائمة بجميع مجموعات Qdrant التي تتطابق مع البادئة `rows_{user}_{collection}_{schema_name}_`
|
||||
2. حذف كل مجموعة مطابقة (يتعامل مع أبعاد متعددة)
|
||||
3. حذف أقسام صفوف Cassandra
|
||||
4. تنظيف `row_partitions`
|
||||
|
||||
#### مواقع الوحدات
|
||||
|
||||
| المرحلة | الوحدة | نقطة الدخول |
|
||||
|-------|--------|-------------|
|
||||
| المرحلة 1 | `trustgraph-flow/trustgraph/embeddings/row_embeddings/` | `row-embeddings` |
|
||||
| المرحلة 2 | `trustgraph-flow/trustgraph/storage/row_embeddings/qdrant/` | `row-embeddings-write-qdrant` |
|
||||
|
||||
### واجهة برمجة تطبيقات استعلام تضمينات الصفوف
|
||||
|
||||
استعلام تضمينات الصفوف هو **واجهة برمجة تطبيقات منفصلة** عن خدمة استعلام الصفوف GraphQL:
|
||||
|
||||
| واجهة برمجة التطبيقات | الغرض | الواجهة الخلفية |
|
||||
|-----|---------|---------|
|
||||
| استعلام الصفوف (GraphQL) | مطابقة دقيقة في الحقول المفهرسة | Cassandra |
|
||||
| استعلام تضمينات الصفوف | مطابقة تقريبية/دلالية | Qdrant |
|
||||
|
||||
هذا الفصل يحافظ على الفصل بين المهام:
|
||||
خدمة GraphQL تركز على الاستعلامات الدقيقة والمنظمة
|
||||
واجهة برمجة تطبيقات التضمينات تتعامل مع التشابه الدلالي
|
||||
سير عمل المستخدم: بحث تقريبي عبر التضمينات للعثور على المرشحين، ثم استعلام دقيق للحصول على بيانات الصف الكاملة
|
||||
|
||||
#### مخطط الطلب/الاستجابة
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RowEmbeddingsRequest:
|
||||
vectors: list[list[float]] # Query vectors (pre-computed embeddings)
|
||||
user: str = ""
|
||||
collection: str = ""
|
||||
schema_name: str = ""
|
||||
index_name: str = "" # Optional: filter to specific index
|
||||
limit: int = 10 # Max results per vector
|
||||
|
||||
@dataclass
|
||||
class RowIndexMatch:
|
||||
index_name: str = "" # The matched index field(s)
|
||||
index_value: list[str] = [] # The matched value(s)
|
||||
text: str = "" # Original text that was embedded
|
||||
score: float = 0.0 # Similarity score
|
||||
|
||||
@dataclass
|
||||
class RowEmbeddingsResponse:
|
||||
error: Error | None = None
|
||||
matches: list[RowIndexMatch] = []
|
||||
```
|
||||
|
||||
#### معالج الاستعلامات
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/query/row_embeddings/qdrant`
|
||||
|
||||
نقطة الدخول: `row-embeddings-query-qdrant`
|
||||
|
||||
المعالج:
|
||||
1. يتلقى `RowEmbeddingsRequest` مع متجهات الاستعلام.
|
||||
2. يجد مجموعة Qdrant المناسبة عن طريق مطابقة البادئة.
|
||||
3. يبحث عن أقرب المتجهات مع مرشح `index_name` اختياري.
|
||||
4. يُرجع `RowEmbeddingsResponse` مع معلومات الفهرس المطابقة.
|
||||
|
||||
#### تكامل بوابة واجهة برمجة التطبيقات (API Gateway)
|
||||
|
||||
تعرض البوابة استعلامات تضمينات الصفوف عبر النمط القياسي للطلب/الاستجابة:
|
||||
|
||||
| المكون | الموقع |
|
||||
|-----------|----------|
|
||||
| الموزع | `trustgraph-flow/trustgraph/gateway/dispatch/row_embeddings_query.py` |
|
||||
| التسجيل | أضف `"row-embeddings"` إلى `request_response_dispatchers` في `manager.py` |
|
||||
|
||||
اسم واجهة التدفق: `row-embeddings`
|
||||
|
||||
تعريف الواجهة في مخطط التدفق:
|
||||
```json
|
||||
{
|
||||
"interfaces": {
|
||||
"row-embeddings": {
|
||||
"request": "non-persistent://tg/request/row-embeddings:{id}",
|
||||
"response": "non-persistent://tg/response/row-embeddings:{id}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### دعم حزمة تطوير البرمجيات (SDK) الخاصة بـ Python
|
||||
|
||||
توفر حزمة تطوير البرمجيات (SDK) طرقًا للاستعلام عن تضمينات الصفوف:
|
||||
|
||||
```python
|
||||
# Flow-scoped query (preferred)
|
||||
api = Api(url)
|
||||
flow = api.flow().id("default")
|
||||
|
||||
# Query with text (SDK computes embeddings)
|
||||
matches = flow.row_embeddings_query(
|
||||
text="Chestnut Street",
|
||||
collection="my_collection",
|
||||
schema_name="addresses",
|
||||
index_name="street_name", # Optional filter
|
||||
limit=10
|
||||
)
|
||||
|
||||
# Query with pre-computed vectors
|
||||
matches = flow.row_embeddings_query(
|
||||
vectors=[[0.1, 0.2, ...]],
|
||||
collection="my_collection",
|
||||
schema_name="addresses"
|
||||
)
|
||||
|
||||
# Each match contains:
|
||||
for match in matches:
|
||||
print(match.index_name) # e.g., "street_name"
|
||||
print(match.index_value) # e.g., ["CHESTNUT ST"]
|
||||
print(match.text) # e.g., "CHESTNUT ST"
|
||||
print(match.score) # e.g., 0.95
|
||||
```
|
||||
|
||||
#### أداة سطر الأوامر
|
||||
|
||||
الأمر: `tg-invoke-row-embeddings`
|
||||
|
||||
```bash
|
||||
# Query by text (computes embedding automatically)
|
||||
tg-invoke-row-embeddings \
|
||||
--text "Chestnut Street" \
|
||||
--collection my_collection \
|
||||
--schema addresses \
|
||||
--index street_name \
|
||||
--limit 10
|
||||
|
||||
# Query by vector file
|
||||
tg-invoke-row-embeddings \
|
||||
--vectors vectors.json \
|
||||
--collection my_collection \
|
||||
--schema addresses
|
||||
|
||||
# Output formats
|
||||
tg-invoke-row-embeddings --text "..." --format json
|
||||
tg-invoke-row-embeddings --text "..." --format table
|
||||
```
|
||||
|
||||
#### النمط النموذجي للاستخدام
|
||||
|
||||
عادةً ما يتم استخدام استعلام تضمينات الصفوف كجزء من تدفق بحث تقريبي إلى دقيق:
|
||||
|
||||
```python
|
||||
# Step 1: Fuzzy search via embeddings
|
||||
matches = flow.row_embeddings_query(
|
||||
text="chestnut street",
|
||||
collection="geo",
|
||||
schema_name="streets"
|
||||
)
|
||||
|
||||
# Step 2: Exact lookup via GraphQL for full row data
|
||||
for match in matches:
|
||||
query = f'''
|
||||
query {{
|
||||
streets(where: {{ {match.index_name}: {{ eq: "{match.index_value[0]}" }} }}) {{
|
||||
street_name
|
||||
city
|
||||
zip_code
|
||||
}}
|
||||
}}
|
||||
'''
|
||||
rows = flow.rows_query(query, collection="geo")
|
||||
```
|
||||
|
||||
هذا النمط المكون من خطوتين يمكّن:
|
||||
العثور على "CHESTNUT ST" عندما يبحث المستخدم عن "Chestnut Street"
|
||||
استرجاع بيانات الصف بأكملها مع جميع الحقول
|
||||
الجمع بين التشابه الدلالي والوصول إلى البيانات المنظمة
|
||||
|
||||
### استيعاب بيانات الصف
|
||||
|
||||
سيتم تأجيله إلى مرحلة لاحقة. سيتم تصميمه جنبًا إلى جنب مع تغييرات الاستيعاب الأخرى.
|
||||
|
||||
## التأثير على التنفيذ
|
||||
|
||||
### تحليل الحالة الحالية
|
||||
|
||||
يحتوي التنفيذ الحالي على مكونين رئيسيين:
|
||||
|
||||
| المكون | الموقع | الأسطر | الوصف |
|
||||
|-----------|----------|-------|-------------|
|
||||
| خدمة الاستعلام | `trustgraph-flow/trustgraph/query/objects/cassandra/service.py` | ~740 | كتلة واحدة: توليد مخطط GraphQL، تحليل المرشحات، استعلامات Cassandra، معالجة الطلبات |
|
||||
| الكاتب | `trustgraph-flow/trustgraph/storage/objects/cassandra/write.py` | ~540 | إنشاء جدول لكل مخطط، فهارس ثانوية، إدراج/حذف |
|
||||
|
||||
**نمط الاستعلام الحالي:**
|
||||
```sql
|
||||
SELECT * FROM {keyspace}.o_{schema_name}
|
||||
WHERE collection = 'X' AND email = 'foo@bar.com'
|
||||
ALLOW FILTERING
|
||||
```
|
||||
|
||||
**نمط استعلام جديد:**
|
||||
```sql
|
||||
SELECT * FROM {keyspace}.rows
|
||||
WHERE collection = 'X' AND schema_name = 'customers'
|
||||
AND index_name = 'email' AND index_value = ['foo@bar.com']
|
||||
```
|
||||
|
||||
### التغييرات الرئيسية
|
||||
|
||||
1. **تبسيط دلالات الاستعلام**: المخطط الجديد يدعم فقط المطابقات الدقيقة على `index_value`. مرشحات GraphQL الحالية (`gt`، `lt`، `contains`، إلخ) إما:
|
||||
تصبح تصفية لاحقة على البيانات المُرجعة (إذا كانت لا تزال مطلوبة)
|
||||
يتم إزالتها لصالح استخدام واجهة برمجة تطبيقات التضمينات للمطابقة التقريبية
|
||||
|
||||
2. **كود GraphQL مرتبط ارتباطًا وثيقًا**: يحتوي `service.py` الحالي على توليد أنواع Strawberry، وتحليل المرشحات، والاستعلامات الخاصة بـ Cassandra. إضافة قاعدة بيانات أخرى ستؤدي إلى تكرار حوالي 400 سطر من كود GraphQL.
|
||||
|
||||
### إعادة الهيكلة المقترحة
|
||||
|
||||
تتكون إعادة الهيكلة من جزأين:
|
||||
|
||||
#### 1. فصل كود GraphQL
|
||||
|
||||
استخراج مكونات GraphQL القابلة لإعادة الاستخدام إلى وحدة مشتركة:
|
||||
|
||||
```
|
||||
trustgraph-flow/trustgraph/query/graphql/
|
||||
├── __init__.py
|
||||
├── types.py # Filter types (IntFilter, StringFilter, FloatFilter)
|
||||
├── schema.py # Dynamic schema generation from RowSchema
|
||||
└── filters.py # Filter parsing utilities
|
||||
```
|
||||
|
||||
هذا يتيح:
|
||||
إعادة الاستخدام عبر خلفيات تخزين الصفوف المختلفة.
|
||||
فصل أوضح للمسؤوليات.
|
||||
اختبار منطق GraphQL بسهولة أكبر بشكل مستقل.
|
||||
|
||||
#### 2. تنفيذ مخطط الجدول الجديد
|
||||
|
||||
إعادة هيكلة التعليمات البرمجية الخاصة بـ Cassandra لاستخدام الجدول الموحد:
|
||||
|
||||
**الكاتب** (`trustgraph-flow/trustgraph/storage/rows/cassandra/`):
|
||||
جدول `rows` واحد بدلاً من الجداول الخاصة بكل مخطط.
|
||||
كتابة N من النسخ لكل صف (واحد لكل فهرس).
|
||||
التسجيل في جدول `row_partitions`.
|
||||
إنشاء جدول أبسط (إعداد لمرة واحدة).
|
||||
|
||||
**خدمة الاستعلام** (`trustgraph-flow/trustgraph/query/rows/cassandra/`):
|
||||
الاستعلام عن جدول `rows` الموحد.
|
||||
استخدام الوحدة النمطية GraphQL المستخرجة لإنشاء المخطط.
|
||||
تبسيط معالجة المرشحات (مطابقة تامة فقط على مستوى قاعدة البيانات).
|
||||
|
||||
### تغيير أسماء الوحدات النمطية
|
||||
|
||||
كجزء من عملية تنظيف أسماء "object" → "row":
|
||||
|
||||
| الحالي | الجديد |
|
||||
|---------|-----|
|
||||
| `storage/objects/cassandra/` | `storage/rows/cassandra/` |
|
||||
| `query/objects/cassandra/` | `query/rows/cassandra/` |
|
||||
| `embeddings/object_embeddings/` | `embeddings/row_embeddings/` |
|
||||
|
||||
### وحدات نمطية جديدة
|
||||
|
||||
| الوحدة النمطية | الغرض |
|
||||
|--------|---------|
|
||||
| `trustgraph-flow/trustgraph/query/graphql/` | أدوات GraphQL مشتركة |
|
||||
| `trustgraph-flow/trustgraph/query/row_embeddings/qdrant/` | واجهة برمجة تطبيقات استعلام تضمينات الصفوف |
|
||||
| `trustgraph-flow/trustgraph/embeddings/row_embeddings/` | حساب تضمينات الصفوف (المرحلة 1) |
|
||||
| `trustgraph-flow/trustgraph/storage/row_embeddings/qdrant/` | تخزين تضمينات الصفوف (المرحلة 2) |
|
||||
|
||||
## المراجع
|
||||
|
||||
[مواصفات البيانات المنظمة](structured-data.md)
|
||||
567
docs/tech-specs/ar/structured-data-descriptor.ar.md
Normal file
567
docs/tech-specs/ar/structured-data-descriptor.ar.md
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مواصفات محدد البيانات المنظمة"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مواصفات محدد البيانات المنظمة
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
محدد البيانات المنظمة هو لغة تكوين تعتمد على JSON تصف كيفية تحليل وتحويل واستيراد البيانات المنظمة إلى TrustGraph. يوفر نهجًا تصريحيًا لاستيعاب البيانات، مما يدعم تنسيقات إدخال متعددة وقنوات تحويل معقدة دون الحاجة إلى تعليمات برمجية مخصصة.
|
||||
|
||||
## المفاهيم الأساسية
|
||||
|
||||
### 1. تعريف التنسيق
|
||||
يصف نوع ملف الإدخال وخيارات التحليل. يحدد أي محلل لاستخدامه وكيفية تفسير البيانات المصدر.
|
||||
|
||||
### 2. تعيينات الحقول
|
||||
يربط مسارات المصدر بحقول الهدف مع التحويلات. يحدد كيفية تدفق البيانات من مصادر الإدخال إلى حقول مخطط الإخراج.
|
||||
|
||||
### 3. سلسلة التحويل
|
||||
سلسلة من تحويلات البيانات التي يمكن تطبيقها على قيم الحقول، بما في ذلك:
|
||||
تنظيف البيانات (التقليم، التسوية)
|
||||
تحويل التنسيق (تحليل التاريخ، تحويل النوع)
|
||||
العمليات الحسابية (العمليات الحسابية، معالجة السلاسل)
|
||||
عمليات البحث (جداول مرجعية، استبدالات)
|
||||
|
||||
### 4. قواعد التحقق من الصحة
|
||||
عمليات فحص جودة البيانات المطبقة لضمان سلامة البيانات:
|
||||
التحقق من النوع
|
||||
عمليات التحقق من النطاق
|
||||
مطابقة الأنماط (regex)
|
||||
التحقق من صحة الحقول المطلوبة
|
||||
منطق التحقق المخصص
|
||||
|
||||
### 5. الإعدادات العامة
|
||||
التكوين الذي ينطبق على عملية الاستيراد بأكملها:
|
||||
جداول البحث لإثراء البيانات
|
||||
المتغيرات والثوابت العامة
|
||||
مواصفات تنسيق الإخراج
|
||||
سياسات معالجة الأخطاء
|
||||
|
||||
## استراتيجية التنفيذ
|
||||
|
||||
يتبع تطبيق المستورد هذا المسار:
|
||||
|
||||
1. **تحليل التكوين** - تحميل والتحقق من صحة الوصف JSON
|
||||
2. **تهيئة المحلل** - تحميل المحلل المناسب (CSV، XML، JSON، إلخ) بناءً على `format.type`
|
||||
3. **تطبيق المعالجة المسبقة** - تنفيذ المرشحات والتحويلات العامة
|
||||
4. **معالجة السجلات** - لكل سجل إدخال:
|
||||
استخراج البيانات باستخدام مسارات المصدر (JSONPath، XPath، أسماء الأعمدة)
|
||||
تطبيق التحويلات الخاصة بالحقل بالتسلسل
|
||||
التحقق من صحة النتائج مقابل القواعد المحددة
|
||||
تطبيق القيم الافتراضية للبيانات المفقودة
|
||||
5. **تطبيق المعالجة اللاحقة** - تنفيذ إزالة التكرار، التجميع، إلخ.
|
||||
6. **إنشاء الإخراج** - إنتاج البيانات بالتنسيق المستهدف المحدد
|
||||
|
||||
## دعم تعبيرات المسار
|
||||
|
||||
تستخدم تنسيقات الإدخال المختلفة لغات تعبيرات المسار المناسبة:
|
||||
|
||||
**CSV**: أسماء الأعمدة أو الفهارس (`"column_name"` أو `"[2]"`)
|
||||
**JSON**: بناء جملة JSONPath (`"$.user.profile.email"`)
|
||||
**XML**: تعبيرات XPath (`"//product[@id='123']/price"`)
|
||||
**العرض الثابت**: أسماء الحقول من تعريفات الحقول
|
||||
|
||||
## المزايا
|
||||
|
||||
**قاعدة تعليمات برمجية واحدة** - يقوم مستورد واحد بمعالجة تنسيقات إدخال متعددة
|
||||
**سهل الاستخدام** - يمكن للمستخدمين غير التقنيين إنشاء تكوينات
|
||||
**قابلة لإعادة الاستخدام** - يمكن مشاركة التكوينات وتنسيق الإصدارات
|
||||
**مرنة** - تحويلات معقدة بدون ترميز مخصص
|
||||
**قوية** - تحقق مدمج ومعالجة شاملة للأخطاء
|
||||
**قابلة للصيانة** - يوفر النهج التصريحي تقليل تعقيد التنفيذ
|
||||
|
||||
## مواصفات اللغة
|
||||
|
||||
يستخدم محدد البيانات المنظمة تنسيق تكوين JSON مع البنية العامة التالية:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"metadata": {
|
||||
"name": "Configuration Name",
|
||||
"description": "Description of what this config does",
|
||||
"author": "Author Name",
|
||||
"created": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"format": { ... },
|
||||
"globals": { ... },
|
||||
"preprocessing": [ ... ],
|
||||
"mappings": [ ... ],
|
||||
"postprocessing": [ ... ],
|
||||
"output": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
### تعريف التنسيق
|
||||
|
||||
يصف تنسيق البيانات المدخلة وخيارات التحليل:
|
||||
|
||||
```json
|
||||
{
|
||||
"format": {
|
||||
"type": "csv|json|xml|fixed-width|excel|parquet",
|
||||
"encoding": "utf-8",
|
||||
"options": {
|
||||
// Format-specific options
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### خيارات تنسيق CSV
|
||||
```json
|
||||
{
|
||||
"format": {
|
||||
"type": "csv",
|
||||
"options": {
|
||||
"delimiter": ",",
|
||||
"quote_char": "\"",
|
||||
"escape_char": "\\",
|
||||
"skip_rows": 1,
|
||||
"has_header": true,
|
||||
"null_values": ["", "NULL", "null", "N/A"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### خيارات تنسيق JSON
|
||||
```json
|
||||
{
|
||||
"format": {
|
||||
"type": "json",
|
||||
"options": {
|
||||
"root_path": "$.data",
|
||||
"array_mode": "records|single",
|
||||
"flatten": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### خيارات تنسيق XML
|
||||
```json
|
||||
{
|
||||
"format": {
|
||||
"type": "xml",
|
||||
"options": {
|
||||
"root_element": "//records/record",
|
||||
"namespaces": {
|
||||
"ns": "http://example.com/namespace"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### الإعدادات العامة
|
||||
|
||||
تحديد الجداول المرجعية والمتغيرات والتكوين العام:
|
||||
|
||||
```json
|
||||
{
|
||||
"globals": {
|
||||
"variables": {
|
||||
"current_date": "2024-01-01",
|
||||
"batch_id": "BATCH_001",
|
||||
"default_confidence": 0.8
|
||||
},
|
||||
"lookup_tables": {
|
||||
"country_codes": {
|
||||
"US": "United States",
|
||||
"UK": "United Kingdom",
|
||||
"CA": "Canada"
|
||||
},
|
||||
"status_mapping": {
|
||||
"1": "active",
|
||||
"0": "inactive"
|
||||
}
|
||||
},
|
||||
"constants": {
|
||||
"source_system": "legacy_crm",
|
||||
"import_type": "full"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### تعيينات الحقول
|
||||
|
||||
حدد كيفية تعيين البيانات المصدر إلى الحقول المستهدفة مع التحويلات:
|
||||
|
||||
```json
|
||||
{
|
||||
"mappings": [
|
||||
{
|
||||
"target_field": "person_name",
|
||||
"source": "$.name",
|
||||
"transforms": [
|
||||
{"type": "trim"},
|
||||
{"type": "title_case"},
|
||||
{"type": "required"}
|
||||
],
|
||||
"validation": [
|
||||
{"type": "min_length", "value": 2},
|
||||
{"type": "max_length", "value": 100},
|
||||
{"type": "pattern", "value": "^[A-Za-z\\s]+$"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_field": "age",
|
||||
"source": "$.age",
|
||||
"transforms": [
|
||||
{"type": "to_int"},
|
||||
{"type": "default", "value": 0}
|
||||
],
|
||||
"validation": [
|
||||
{"type": "range", "min": 0, "max": 150}
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_field": "country",
|
||||
"source": "$.country_code",
|
||||
"transforms": [
|
||||
{"type": "lookup", "table": "country_codes"},
|
||||
{"type": "default", "value": "Unknown"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### أنواع التحويل
|
||||
|
||||
الوظائف المتاحة للتحويل:
|
||||
|
||||
#### تحويلات السلاسل النصية
|
||||
```json
|
||||
{"type": "trim"},
|
||||
{"type": "upper"},
|
||||
{"type": "lower"},
|
||||
{"type": "title_case"},
|
||||
{"type": "replace", "pattern": "old", "replacement": "new"},
|
||||
{"type": "regex_replace", "pattern": "\\d+", "replacement": "XXX"},
|
||||
{"type": "substring", "start": 0, "end": 10},
|
||||
{"type": "pad_left", "length": 10, "char": "0"}
|
||||
```
|
||||
|
||||
#### تحويلات الأنواع
|
||||
```json
|
||||
{"type": "to_string"},
|
||||
{"type": "to_int"},
|
||||
{"type": "to_float"},
|
||||
{"type": "to_bool"},
|
||||
{"type": "to_date", "format": "YYYY-MM-DD"},
|
||||
{"type": "parse_json"}
|
||||
```
|
||||
|
||||
#### العمليات على البيانات
|
||||
```json
|
||||
{"type": "default", "value": "default_value"},
|
||||
{"type": "lookup", "table": "table_name"},
|
||||
{"type": "concat", "values": ["field1", " - ", "field2"]},
|
||||
{"type": "calculate", "expression": "${field1} + ${field2}"},
|
||||
{"type": "conditional", "condition": "${age} > 18", "true_value": "adult", "false_value": "minor"}
|
||||
```
|
||||
|
||||
### قواعد التحقق
|
||||
|
||||
عمليات فحص جودة البيانات مع معالجة أخطاء قابلة للتكوين:
|
||||
|
||||
#### عمليات التحقق الأساسية
|
||||
```json
|
||||
{"type": "required"},
|
||||
{"type": "not_null"},
|
||||
{"type": "min_length", "value": 5},
|
||||
{"type": "max_length", "value": 100},
|
||||
{"type": "range", "min": 0, "max": 1000},
|
||||
{"type": "pattern", "value": "^[A-Z]{2,3}$"},
|
||||
{"type": "in_list", "values": ["active", "inactive", "pending"]}
|
||||
```
|
||||
|
||||
#### التحقق من الصحة المخصصة
|
||||
```json
|
||||
{
|
||||
"type": "custom",
|
||||
"expression": "${age} >= 18 && ${country} == 'US'",
|
||||
"message": "Must be 18+ and in US"
|
||||
},
|
||||
{
|
||||
"type": "cross_field",
|
||||
"fields": ["start_date", "end_date"],
|
||||
"expression": "${start_date} < ${end_date}",
|
||||
"message": "Start date must be before end date"
|
||||
}
|
||||
```
|
||||
|
||||
### المعالجة الأولية والمعالجة اللاحقة
|
||||
|
||||
العمليات العامة المطبقة قبل/بعد تعيين الحقول:
|
||||
|
||||
```json
|
||||
{
|
||||
"preprocessing": [
|
||||
{
|
||||
"type": "filter",
|
||||
"condition": "${status} != 'deleted'"
|
||||
},
|
||||
{
|
||||
"type": "sort",
|
||||
"field": "created_date",
|
||||
"order": "asc"
|
||||
}
|
||||
],
|
||||
"postprocessing": [
|
||||
{
|
||||
"type": "deduplicate",
|
||||
"key_fields": ["email", "phone"]
|
||||
},
|
||||
{
|
||||
"type": "aggregate",
|
||||
"group_by": ["country"],
|
||||
"functions": {
|
||||
"total_count": {"type": "count"},
|
||||
"avg_age": {"type": "avg", "field": "age"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### إعدادات الإخراج
|
||||
|
||||
حدد كيفية إخراج البيانات المعالجة:
|
||||
|
||||
```json
|
||||
{
|
||||
"output": {
|
||||
"format": "trustgraph-objects",
|
||||
"schema_name": "person",
|
||||
"options": {
|
||||
"batch_size": 1000,
|
||||
"confidence": 0.9,
|
||||
"source_span_field": "raw_text",
|
||||
"metadata": {
|
||||
"source": "crm_import",
|
||||
"version": "1.0"
|
||||
}
|
||||
},
|
||||
"error_handling": {
|
||||
"on_validation_error": "skip|fail|log",
|
||||
"on_transform_error": "skip|fail|default",
|
||||
"max_errors": 100,
|
||||
"error_output": "errors.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## مثال كامل
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"metadata": {
|
||||
"name": "Customer Import from CRM CSV",
|
||||
"description": "Imports customer data from legacy CRM system",
|
||||
"author": "Data Team",
|
||||
"created": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"format": {
|
||||
"type": "csv",
|
||||
"encoding": "utf-8",
|
||||
"options": {
|
||||
"delimiter": ",",
|
||||
"has_header": true,
|
||||
"skip_rows": 1
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"variables": {
|
||||
"import_date": "2024-01-01",
|
||||
"default_confidence": 0.85
|
||||
},
|
||||
"lookup_tables": {
|
||||
"country_codes": {
|
||||
"US": "United States",
|
||||
"CA": "Canada",
|
||||
"UK": "United Kingdom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"preprocessing": [
|
||||
{
|
||||
"type": "filter",
|
||||
"condition": "${status} == 'active'"
|
||||
}
|
||||
],
|
||||
"mappings": [
|
||||
{
|
||||
"target_field": "full_name",
|
||||
"source": "customer_name",
|
||||
"transforms": [
|
||||
{"type": "trim"},
|
||||
{"type": "title_case"}
|
||||
],
|
||||
"validation": [
|
||||
{"type": "required"},
|
||||
{"type": "min_length", "value": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_field": "email",
|
||||
"source": "email_address",
|
||||
"transforms": [
|
||||
{"type": "trim"},
|
||||
{"type": "lower"}
|
||||
],
|
||||
"validation": [
|
||||
{"type": "pattern", "value": "^[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_field": "age",
|
||||
"source": "age",
|
||||
"transforms": [
|
||||
{"type": "to_int"},
|
||||
{"type": "default", "value": 0}
|
||||
],
|
||||
"validation": [
|
||||
{"type": "range", "min": 0, "max": 120}
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_field": "country",
|
||||
"source": "country_code",
|
||||
"transforms": [
|
||||
{"type": "lookup", "table": "country_codes"},
|
||||
{"type": "default", "value": "Unknown"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": {
|
||||
"format": "trustgraph-objects",
|
||||
"schema_name": "customer",
|
||||
"options": {
|
||||
"confidence": "${default_confidence}",
|
||||
"batch_size": 500
|
||||
},
|
||||
"error_handling": {
|
||||
"on_validation_error": "log",
|
||||
"max_errors": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## موجه نموذج اللغة الكبير لإنشاء الوصف
|
||||
|
||||
يمكن استخدام الموجه التالي لجعل نموذج لغة كبير يحلل بيانات عينة وينشئ تكوينًا للوصف:
|
||||
|
||||
```
|
||||
I need you to analyze the provided data sample and create a Structured Data Descriptor configuration in JSON format.
|
||||
|
||||
The descriptor should follow this specification:
|
||||
- version: "1.0"
|
||||
- metadata: Configuration name, description, author, and creation date
|
||||
- format: Input format type and parsing options
|
||||
- globals: Variables, lookup tables, and constants
|
||||
- preprocessing: Filters and transformations applied before mapping
|
||||
- mappings: Field-by-field mapping from source to target with transformations and validations
|
||||
- postprocessing: Operations like deduplication or aggregation
|
||||
- output: Target format and error handling configuration
|
||||
|
||||
ANALYZE THE DATA:
|
||||
1. Identify the format (CSV, JSON, XML, etc.)
|
||||
2. Detect delimiters, encodings, and structure
|
||||
3. Find data types for each field
|
||||
4. Identify patterns and constraints
|
||||
5. Look for fields that need cleaning or transformation
|
||||
6. Find relationships between fields
|
||||
7. Identify lookup opportunities (codes that map to values)
|
||||
8. Detect required vs optional fields
|
||||
|
||||
CREATE THE DESCRIPTOR:
|
||||
For each field in the sample data:
|
||||
- Map it to an appropriate target field name
|
||||
- Add necessary transformations (trim, case conversion, type casting)
|
||||
- Include appropriate validations (required, patterns, ranges)
|
||||
- Set defaults for missing values
|
||||
|
||||
Include preprocessing if needed:
|
||||
- Filters to exclude invalid records
|
||||
- Sorting requirements
|
||||
|
||||
Include postprocessing if beneficial:
|
||||
- Deduplication on key fields
|
||||
- Aggregation for summary data
|
||||
|
||||
Configure output for TrustGraph:
|
||||
- format: "trustgraph-objects"
|
||||
- schema_name: Based on the data entity type
|
||||
- Appropriate error handling
|
||||
|
||||
DATA SAMPLE:
|
||||
[Insert data sample here]
|
||||
|
||||
ADDITIONAL CONTEXT (optional):
|
||||
- Target schema name: [if known]
|
||||
- Business rules: [any specific requirements]
|
||||
- Data quality issues to address: [known problems]
|
||||
|
||||
Generate a complete, valid Structured Data Descriptor configuration that will properly import this data into TrustGraph. Include comments explaining key decisions.
|
||||
```
|
||||
|
||||
### مثال للاستخدام
|
||||
|
||||
```
|
||||
I need you to analyze the provided data sample and create a Structured Data Descriptor configuration in JSON format.
|
||||
|
||||
[Standard instructions from above...]
|
||||
|
||||
DATA SAMPLE:
|
||||
```csv
|
||||
CustomerID، الاسم، البريد الإلكتروني، العمر، البلد، الحالة، تاريخ الانضمام، إجمالي المشتريات
|
||||
1001، "Smith, John"، john.smith@email.com، 35، الولايات المتحدة الأمريكية، 1، 2023-01-15، 5420.50
|
||||
1002، "doe, jane"، JANE.DOE@GMAIL.COM، 28، كندا، 1، 2023-03-22، 3200.00
|
||||
1003، "Bob Johnson"، bob@، 62، المملكة المتحدة، 0، 2022-11-01، 0
|
||||
1004، "Alice Chen"، alice.chen@company.org، 41، الولايات المتحدة الأمريكية، 1، 2023-06-10، 8900.25
|
||||
1005، ، invalid-email، 25، XX، 1، 2024-01-01، 100
|
||||
```
|
||||
|
||||
ADDITIONAL CONTEXT:
|
||||
- Target schema name: customer
|
||||
- Business rules: Email should be valid and lowercase, names should be title case
|
||||
- Data quality issues: Some emails are invalid, some names are missing, country codes need mapping
|
||||
```
|
||||
|
||||
### طلب لتحليل البيانات الحالية بدون عينة
|
||||
|
||||
```
|
||||
I need you to help me create a Structured Data Descriptor configuration for importing [data type] data.
|
||||
|
||||
The source data has these characteristics:
|
||||
- Format: [CSV/JSON/XML/etc]
|
||||
- Fields: [list the fields]
|
||||
- Data quality issues: [describe any known issues]
|
||||
- Volume: [approximate number of records]
|
||||
|
||||
Requirements:
|
||||
- [List any specific transformation needs]
|
||||
- [List any validation requirements]
|
||||
- [List any business rules]
|
||||
|
||||
Please generate a Structured Data Descriptor configuration that will:
|
||||
1. Parse the input format correctly
|
||||
2. Clean and standardize the data
|
||||
3. Validate according to the requirements
|
||||
4. Handle errors gracefully
|
||||
5. Output in TrustGraph ExtractedObject format
|
||||
|
||||
Focus on making the configuration robust and reusable.
|
||||
```
|
||||
139
docs/tech-specs/ar/structured-data-schemas.ar.md
Normal file
139
docs/tech-specs/ar/structured-data-schemas.ar.md
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مخطط بيانات البنية: تغييرات مخطط Pulsar"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مخطط بيانات البنية: تغييرات مخطط Pulsar
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
استنادًا إلى مواصفات `STRUCTURED_DATA.md`، تقترح هذه الوثيقة الإضافات والتعديلات اللازمة على مخطط Pulsar لدعم قدرات البيانات المنظمة في TrustGraph.
|
||||
|
||||
## تغييرات مخطط مطلوبة
|
||||
|
||||
### 1. تحسينات مخطط أساسية
|
||||
|
||||
#### تعريف الحقل المحسّن
|
||||
تحتاج الفئة الحالية `Field` في `core/primitives.py` إلى خصائص إضافية:
|
||||
|
||||
```python
|
||||
class Field(Record):
|
||||
name = String()
|
||||
type = String() # int, string, long, bool, float, double, timestamp
|
||||
size = Integer()
|
||||
primary = Boolean()
|
||||
description = String()
|
||||
# حقول جديدة:
|
||||
required = Boolean() # ما إذا كان الحقل مطلوبًا
|
||||
enum_values = Array(String()) # للحقول من نوع Enum
|
||||
indexed = Boolean() # ما إذا كان يجب فهرسة الحقل
|
||||
```
|
||||
|
||||
### 2. مخططات معرفة جديدة
|
||||
|
||||
#### 2.1 إرسال بيانات منظمة
|
||||
ملف جديد: `knowledge/structured.py`
|
||||
|
||||
```python
|
||||
from pulsar.schema import Record, String, Bytes, Map
|
||||
from ..core.metadata import Metadata
|
||||
|
||||
class StructuredDataSubmission(Record):
|
||||
metadata = Metadata()
|
||||
format = String() # "json", "csv", "xml"
|
||||
schema_name = String() # مرجع إلى المخطط في التكوين
|
||||
data = Bytes() # البيانات الخام للإدخال
|
||||
options = Map(String()) # خيارات محددة بالتنسيق
|
||||
```
|
||||
|
||||
### 3. مخططات الخدمات الجديدة
|
||||
|
||||
#### 3.1 خدمة استعلام NLP إلى منظمة
|
||||
ملف جديد: `services/nlp_query.py`
|
||||
|
||||
```python
|
||||
from pulsar.schema import Record, String, Array, Map, Integer, Double
|
||||
from ..core.primitives import Error
|
||||
|
||||
class NLPToStructuredQueryRequest(Record):
|
||||
natural_language_query = String()
|
||||
max_results = Integer()
|
||||
context_hints = Map(String()) # تلميحات سياق اختيارية لتوليد الاستعلام
|
||||
|
||||
class NLPToStructuredQueryResponse(Record):
|
||||
error = Error()
|
||||
graphql_query = String() # استعلام GraphQL المُنشأ
|
||||
variables = Map(String()) # متغيرات GraphQL إذا كانت موجودة
|
||||
detected_schemas = Array(String()) # المخططات التي يستهدفها الاستعلام
|
||||
confidence = Double()
|
||||
```
|
||||
|
||||
#### 3.2 خدمة استعلام منظمة
|
||||
ملف جديد: `services/structured_query.py`
|
||||
|
||||
```python
|
||||
from pulsar.schema import Record, String, Map, Array
|
||||
from ..core.primitives import Error
|
||||
|
||||
class StructuredQueryRequest(Record):
|
||||
query = String() # استعلام GraphQL
|
||||
variables = Map(String()) # متغيرات GraphQL
|
||||
operation_name = String() # اسم العملية الاختياري للمستندات متعددة العمليات
|
||||
|
||||
class StructuredQueryResponse(Record):
|
||||
error = Error()
|
||||
data = String() # بيانات استجابة GraphQL المُشفرة بتنسيق JSON
|
||||
errors = Array(String()) # أخطاء GraphQL إذا كانت موجودة
|
||||
```
|
||||
|
||||
#### 2.2 مخرجات استخراج الكائنات
|
||||
ملف جديد: `knowledge/object.py`
|
||||
|
||||
```python
|
||||
from pulsar.schema import Record, String, Map, Double
|
||||
from ..core.metadata import Metadata
|
||||
|
||||
class ExtractedObject(Record):
|
||||
metadata = Metadata()
|
||||
schema_name = String() # أي مخطط ينتمي إليه هذا الكائن
|
||||
values = Map(String()) # اسم الحقل -> القيمة
|
||||
confidence = Double()
|
||||
source_span = String() # نطاق النص الذي تم فيه العثور على الكائن
|
||||
```
|
||||
|
||||
### 4. مخططات معرفة محسّنة
|
||||
|
||||
#### 4.1 تحسين تضمين الكائنات
|
||||
قم بتحديث `knowledge/embeddings.py` لدعم تضمين الكائنات المنظمة بشكل أفضل:
|
||||
|
||||
```python
|
||||
class StructuredObjectEmbedding(Record):
|
||||
metadata = Metadata()
|
||||
vectors = Array(Array(Double()))
|
||||
schema_name = String()
|
||||
object_id = String() # قيمة المفتاح الأساسي
|
||||
field_embeddings = Map(Array(Double())) # تضمينات الحقول
|
||||
```
|
||||
|
||||
## نقاط التكامل
|
||||
|
||||
### تكامل التدفق
|
||||
|
||||
سيتم استخدام المخططات في وحدات تدفق جديدة:
|
||||
- `trustgraph-flow/trustgraph/decoding/structured` - يستخدم StructuredDataSubmission
|
||||
- `trustgraph-flow/trustgraph/query/nlp_query/cassandra` - يستخدم مخططات استعلام NLP
|
||||
- `trustgraph-flow/trustgraph/query/objects/cassandra` - يستخدم مخططات استعلام منظمة
|
||||
- `trustgraph-flow/trustgraph/extract/object/row/` - يستهلك Chunk، وينتج ExtractedObject
|
||||
- `trustgraph-flow/trustgraph/storage/objects/cassandra` - يستخدم مخطط Rows
|
||||
- `trustgraph-flow/trustgraph/embeddings/object_embeddings/qdrant` - يستخدم مخططات تضمين الكائنات
|
||||
|
||||
## ملاحظات التنفيذ
|
||||
|
||||
1. **إصدار المخطط**: ضع في اعتبارك إضافة حقل `version` إلى RowSchema لدعم الترحيل المستقبلي
|
||||
2. **نظام الأنواع**: يجب أن يدعم `Field.type` جميع أنواع بيانات Cassandra الأصلية
|
||||
3. **عمليات المجموعة**: يجب أن يدعم معظم الخدمات العمليات الفردية والمجمعة
|
||||
4. **معالجة الأخطاء**: يجب أن يكون للإبلاغ عن الأخطاء باستمرار عبر جميع الخدمات الجديدة
|
||||
5. **التوافق مع الإصدارات السابقة**: تظل المخططات الحالية دون تغيير باستثناء التحسينات الطفيفة للملفات
|
||||
260
docs/tech-specs/ar/structured-data.ar.md
Normal file
260
docs/tech-specs/ar/structured-data.ar.md
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية للبيانات المهيكلة"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية للبيانات المهيكلة
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات دمج TrustGraph مع تدفقات البيانات المهيكلة، مما يمكّن النظام من العمل مع البيانات التي يمكن تمثيلها كصفوف في الجداول أو كائنات في مخازن الكائنات. يدعم هذا التكامل أربع حالات استخدام رئيسية:
|
||||
|
||||
1. **الاستخراج من غير المهيكل إلى المهيكل**: قراءة مصادر البيانات غير المهيكلة، وتحديد واستخراج هياكل الكائنات، وتخزينها بتنسيق جدولي.
|
||||
2. **استيعاب البيانات المهيكلة**: تحميل البيانات الموجودة بالفعل بتنسيقات مهيكلة مباشرة إلى المتجر المهيكل جنبًا إلى جنب مع البيانات المستخرجة.
|
||||
3. **الاستعلام باللغة الطبيعية**: تحويل الأسئلة باللغة الطبيعية إلى استعلامات مهيكلة لاستخراج البيانات المطابقة من المتجر.
|
||||
4. **الاستعلام المهيكل المباشر**: تنفيذ استعلامات مهيكلة مباشرة مقابل مخزن البيانات لاسترجاع البيانات بدقة.
|
||||
|
||||
## الأهداف
|
||||
|
||||
**واجهة وصول موحدة للبيانات**: توفير واجهة واحدة للوصول إلى كل من البيانات المهيكلة وغير المهيكلة داخل TrustGraph.
|
||||
**تكامل سلس**: تمكين التوافق السلس بين تمثيل المعرفة القائم على الرسم البياني في TrustGraph وتنسيقات البيانات المهيكلة التقليدية.
|
||||
**استخراج مرن**: دعم الاستخراج التلقائي للبيانات المهيكلة من مصادر غير مهيكلة متنوعة (المستندات، والنصوص، وما إلى ذلك).
|
||||
**تنوع الاستعلام**: السماح للمستخدمين بالاستعلام عن البيانات باستخدام كل من اللغة الطبيعية ولغات الاستعلام المهيكلة.
|
||||
**اتساق البيانات**: الحفاظ على سلامة البيانات واتساقها عبر تمثيلات البيانات المختلفة.
|
||||
**تحسين الأداء**: ضمان تخزين واسترجاع فعال للبيانات المهيكلة على نطاق واسع.
|
||||
**مرونة المخطط**: دعم كل من مناهج "المخطط عند الكتابة" و "المخطط عند القراءة" لاستيعاب مصادر البيانات المتنوعة.
|
||||
**التوافق مع الإصدارات السابقة**: الحفاظ على وظائف TrustGraph الحالية مع إضافة إمكانات البيانات المهيكلة.
|
||||
|
||||
## الخلفية
|
||||
|
||||
تتفوق TrustGraph حاليًا في معالجة البيانات غير المهيكلة وإنشاء الرسوم البيانية المعرفية من مصادر متنوعة. ومع ذلك، تتضمن العديد من حالات الاستخدام في المؤسسات بيانات مهيكلة بشكل متأصل - سجلات العملاء، وسجلات المعاملات، وقواعد بيانات المخزون، ومجموعات بيانات جدولية أخرى. غالبًا ما تحتاج هذه مجموعات البيانات المهيكلة إلى تحليلها جنبًا إلى جنب مع المحتوى غير المهيكل لتقديم رؤى شاملة.
|
||||
|
||||
القيود الحالية تشمل:
|
||||
لا يوجد دعم أصلي لاستيعاب تنسيقات البيانات المهيكلة مسبقًا (CSV، ومصفوفات JSON، وتصديرات قواعد البيانات).
|
||||
عدم القدرة على الحفاظ على الهيكل المتأصل عند استخراج البيانات الجدولية من المستندات.
|
||||
عدم وجود آليات استعلام فعالة لأنماط البيانات المهيكلة.
|
||||
عدم وجود جسر بين استعلامات تشبه SQL واستعلامات الرسم البياني في TrustGraph.
|
||||
|
||||
تعالج هذه المواصفات هذه الفجوات من خلال تقديم طبقة بيانات مهيكلة تكمل إمكانات TrustGraph الحالية. من خلال دعم البيانات المهيكلة أصلاً، يمكن لـ TrustGraph:
|
||||
أن تكون منصة موحدة لتحليل كل من البيانات المهيكلة وغير المهيكلة.
|
||||
تمكين الاستعلامات الهجينة التي تمتد عبر علاقات الرسم البياني والبيانات الجدولية.
|
||||
توفير واجهات مألوفة للمستخدمين الذين اعتادوا العمل مع البيانات المهيكلة.
|
||||
إطلاق حالات استخدام جديدة في تكامل البيانات وذكاء الأعمال.
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
يتطلب تكامل البيانات المهيكلة المكونات الفنية التالية:
|
||||
|
||||
1. **خدمة NLP-to-Structured-Query**
|
||||
تحويل الأسئلة باللغة الطبيعية إلى استعلامات مهيكلة.
|
||||
يدعم أهداف لغة استعلام متعددة (في البداية بناء الجملة المشابه لـ SQL).
|
||||
يتكامل مع إمكانات NLP الحالية في TrustGraph.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/query/nlp_query/cassandra
|
||||
|
||||
2. **دعم مخطط التكوين** ✅ **[مكتمل]**
|
||||
نظام تكوين موسع لتخزين مخططات البيانات المهيكلة.
|
||||
دعم لتعريف هياكل الجداول وأنواع الحقول والعلاقات.
|
||||
إمكانيات إصدار وترحيل المخططات.
|
||||
|
||||
3. **وحدة استخراج الكائنات** ✅ **[مكتمل]**
|
||||
تكامل محسن لتدفق استخراج المعرفة.
|
||||
تحديد واستخراج كائنات مهيكلة من مصادر غير مهيكلة.
|
||||
الحفاظ على الأصل ودرجات الثقة.
|
||||
يسجل معالج تكوين (مثال: trustgraph-flow/trustgraph/prompt/template/service.py) لتلقي بيانات التكوين وفك تشفير معلومات المخطط.
|
||||
يتلقى الكائنات ويفك تشفيرها إلى كائنات ExtractedObject للتسليم على قائمة الانتظار Pulsar.
|
||||
ملاحظة: يوجد رمز موجود في `trustgraph-flow/trustgraph/extract/object/row/`. كان هذا محاولة سابقة وسيتطلب إعادة هيكلة كبيرة لأنه لا يتوافق مع واجهات برمجة التطبيقات الحالية. استخدمه إذا كان مفيدًا، وابدأ من البداية إذا لم يكن كذلك.
|
||||
يتطلب واجهة سطر أوامر: `kg-extract-objects`
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/extract/kg/objects/
|
||||
|
||||
4. **وحدة كاتب المتجر المهيكل** ✅ **[مكتمل]**
|
||||
يتلقى الكائنات بتنسيق ExtractedObject من قوائم انتظار Pulsar.
|
||||
التنفيذ الأولي يستهدف Apache Cassandra كمتجر البيانات المهيكل.
|
||||
يتعامل مع إنشاء الجداول الديناميكي بناءً على المخططات التي تمت مواجهتها.
|
||||
يدير تعيين المخطط إلى جدول Cassandra وتحويل البيانات.
|
||||
يوفر عمليات كتابة مجمعة وتدفق لتحسين الأداء.
|
||||
لا توجد مخرجات Pulsar - هذه خدمة نهائية في تدفق البيانات.
|
||||
|
||||
**معالجة المخططات**:
|
||||
يراقب رسائل ExtractedObject الواردة للإشارة إلى المخططات.
|
||||
عندما يتم مواجهة مخطط جديد لأول مرة، يقوم تلقائيًا بإنشاء جدول Cassandra المقابل.
|
||||
يحتفظ بخزنة للمخططات المعروفة لتجنب محاولات إنشاء جداول متكررة.
|
||||
يجب أن تأخذ في الاعتبار ما إذا كان سيتم تلقي تعريفات المخططات مباشرة أو الاعتماد على أسماء المخططات في رسائل ExtractedObject.
|
||||
|
||||
**ربط جدول Cassandra**:
|
||||
يتم تسمية مساحة المفاتيح (Keyspace) بناءً على الحقل `user` من بيانات التعريف (Metadata) الخاصة بـ ExtractedObject.
|
||||
يتم تسمية الجدول بناءً على الحقل `schema_name` الخاص بـ ExtractedObject.
|
||||
تصبح المجموعة (Collection) من بيانات التعريف جزءًا من مفتاح التقسيم (partition key) لضمان:
|
||||
توزيع البيانات بشكل طبيعي عبر عقد Cassandra.
|
||||
استعلامات فعالة داخل مجموعة معينة.
|
||||
عزل منطقي بين عمليات استيراد البيانات/المصادر المختلفة.
|
||||
هيكل المفتاح الأساسي: `PRIMARY KEY ((collection, <schema_primary_key_fields>), <clustering_keys>)`.
|
||||
تكون المجموعة دائمًا المكون الأول من مفتاح التقسيم.
|
||||
تتبع حقول المفتاح الأساسي المعرفة في المخطط (schema) كجزء من مفتاح التقسيم المركب.
|
||||
يتطلب هذا تحديد المجموعة في الاستعلامات، مما يضمن أداءً متوقعًا.
|
||||
يتم تعيين تعريفات الحقول إلى أعمدة Cassandra مع تحويلات الأنواع:
|
||||
`string` → `text`.
|
||||
`integer` → `int` أو `bigint` بناءً على تلميح الحجم.
|
||||
`float` → `float` أو `double` بناءً على احتياجات الدقة.
|
||||
`boolean` → `boolean`.
|
||||
`timestamp` → `timestamp`.
|
||||
`enum` → `text` مع التحقق من الصحة على مستوى التطبيق.
|
||||
تقوم الحقول المفهرسة بإنشاء فهارس ثانوية لـ Cassandra (باستثناء الحقول الموجودة بالفعل في المفتاح الأساسي).
|
||||
يتم فرض الحقول المطلوبة على مستوى التطبيق (لا تدعم Cassandra NOT NULL).
|
||||
|
||||
**تخزين الكائنات (Object Storage)**:
|
||||
يستخرج القيم من خريطة ExtractedObject.values.
|
||||
يقوم بتحويل النوع والتحقق من الصحة قبل الإدراج.
|
||||
يتعامل مع الحقول الاختيارية المفقودة بأمان.
|
||||
يحتفظ ببيانات وصفية حول أصل الكائن (مستند المصدر، درجات الثقة).
|
||||
يدعم عمليات الكتابة المتطابقة (idempotent writes) للتعامل مع سيناريوهات إعادة إرسال الرسائل.
|
||||
|
||||
**ملاحظات التنفيذ**:
|
||||
الكود الحالي الموجود في `trustgraph-flow/trustgraph/storage/objects/cassandra/` قديم ولا يتوافق مع واجهات برمجة التطبيقات (APIs) الحالية.
|
||||
يجب الرجوع إلى `trustgraph-flow/trustgraph/storage/triples/cassandra` كمثال على معالج تخزين يعمل.
|
||||
يجب تقييم الكود الحالي بحثًا عن أي مكونات قابلة لإعادة الاستخدام قبل اتخاذ قرار بإعادة هيكلة أو إعادة كتابة.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/storage/objects/cassandra
|
||||
|
||||
5. **خدمة الاستعلامات المهيكلة** ✅ **[مكتمل]**
|
||||
تقبل استعلامات مهيكلة بتنسيقات محددة.
|
||||
تنفذ الاستعلامات على المستودع المهيكل.
|
||||
تُرجع الكائنات التي تتطابق مع معايير الاستعلام.
|
||||
تدعم التقسيم والترشيح للنتائج.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/query/objects/cassandra
|
||||
|
||||
6. **تكامل أدوات الوكيل (Agent Tool Integration)**
|
||||
فئة أداة جديدة لأطر عمل الوكيل.
|
||||
تمكن الوكلاء من الاستعلام عن مستودعات البيانات المهيكلة.
|
||||
توفر واجهات استعلام باللغة الطبيعية والمهيكلة.
|
||||
تتكامل مع عمليات اتخاذ القرار الحالية للوكلاء.
|
||||
|
||||
7. **خدمة استيعاب البيانات المهيكلة**
|
||||
تقبل بيانات مهيكلة بتنسيقات متعددة (JSON، CSV، XML).
|
||||
تقوم بتحليل والتحقق من صحة البيانات الواردة مقابل المخططات المحددة.
|
||||
تحول البيانات إلى تدفقات كائنات مُنظمة.
|
||||
تُصدر الكائنات إلى قوائم انتظار الرسائل المناسبة للمعالجة.
|
||||
تدعم عمليات التحميل المجمعة والاستيعاب المتدفق.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/decoding/structured
|
||||
|
||||
8. **خدمة تضمين الكائنات (Object Embedding Service)**
|
||||
تولد تضمينات متجهة للكائنات المهيكلة.
|
||||
تمكن البحث الدلالي عبر البيانات المهيكلة.
|
||||
تدعم البحث الهجين الذي يجمع بين الاستعلامات المهيكلة والتشابه الدلالي.
|
||||
تتكامل مع مخازن المتجهات الحالية.
|
||||
|
||||
الوحدة: trustgraph-flow/trustgraph/embeddings/object_embeddings/qdrant
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### آلية تخزين المخططات
|
||||
|
||||
يتم تخزين المخططات في نظام تكوين TrustGraph باستخدام الهيكل التالي:
|
||||
|
||||
**النوع (Type)**: `schema` (قيمة ثابتة لجميع مخططات البيانات المهيكلة).
|
||||
**المفتاح (Key)**: الاسم/المعرف الفريد للمخطط (مثل `customer_records`، `transaction_log`).
|
||||
**القيمة (Value)**: تعريف مخطط JSON يحتوي على الهيكل.
|
||||
|
||||
مثال على إدخال التكوين:
|
||||
```
|
||||
Type: schema
|
||||
Key: customer_records
|
||||
Value: {
|
||||
"name": "customer_records",
|
||||
"description": "Customer information table",
|
||||
"fields": [
|
||||
{
|
||||
"name": "customer_id",
|
||||
"type": "string",
|
||||
"primary_key": true
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "registration_date",
|
||||
"type": "timestamp"
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"type": "string",
|
||||
"enum": ["active", "inactive", "suspended"]
|
||||
}
|
||||
],
|
||||
"indexes": ["email", "registration_date"]
|
||||
}
|
||||
```
|
||||
|
||||
هذا النهج يسمح بما يلي:
|
||||
تعريف مخطط ديناميكي دون تغييرات في التعليمات البرمجية
|
||||
تحديثات سهلة للمخططات وإصداراتها
|
||||
تكامل متسق مع إدارة التكوين الحالية لـ TrustGraph
|
||||
دعم مخططات متعددة داخل عملية نشر واحدة
|
||||
|
||||
### واجهات برمجة التطبيقات (APIs)
|
||||
|
||||
واجهات برمجة تطبيقات جديدة:
|
||||
مخططات Pulsar للأنواع المذكورة أعلاه
|
||||
واجهات Pulsar في التدفقات الجديدة
|
||||
هناك حاجة إلى وسيلة لتحديد أنواع المخططات في التدفقات حتى تعرف التدفقات
|
||||
أنواع المخططات التي يجب تحميلها
|
||||
تمت إضافة واجهات برمجة تطبيقات إلى البوابة والبوابة العكسية
|
||||
|
||||
واجهات برمجة تطبيقات معدلة:
|
||||
نقاط نهاية استخراج المعرفة - إضافة خيار إخراج كائن منظم
|
||||
نقاط نهاية الوكيل - إضافة دعم لأدوات البيانات المنظمة
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
باتباع الاتفاقيات الحالية - هذه مجرد وحدات معالجة جديدة.
|
||||
كل شيء موجود في حزم trustgraph-flow باستثناء عناصر المخطط
|
||||
الموجودة في trustgraph-base.
|
||||
|
||||
هناك حاجة إلى بعض الأعمال لواجهة المستخدم في Workbench لتمكين عرض / تجربة هذه
|
||||
الإمكانية.
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
لا توجد اعتبارات إضافية.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
بعض الأسئلة حول استخدام استعلامات وفهارس Cassandra بحيث لا تبطئ الاستعلامات.
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
استخدم استراتيجية الاختبار الحالية، سيتم إنشاء اختبارات الوحدة والاتفاقية والتكامل.
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
لا يوجد.
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
|
||||
لم يتم تحديده.
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
هل يمكن جعل هذا يعمل مع أنواع تخزين أخرى؟ نحن نهدف إلى استخدام
|
||||
واجهات تجعل الوحدات التي تعمل مع تخزين واحد قابلة للتطبيق على
|
||||
تخزين آخر.
|
||||
|
||||
## المراجع
|
||||
|
||||
غير متوفر.
|
||||
281
docs/tech-specs/ar/structured-diag-service.ar.md
Normal file
281
docs/tech-specs/ar/structured-diag-service.ar.md
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
---
|
||||
layout: default
|
||||
title: "المواصفات الفنية لخدمة تشخيص البيانات المهيكلة"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# المواصفات الفنية لخدمة تشخيص البيانات المهيكلة
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تصف هذه المواصفات خدمة جديدة قابلة للاستدعاء لتشخيص وتحليل البيانات المهيكلة داخل TrustGraph. تستخرج الخدمة الوظائف من أداة سطر الأوامر `tg-load-structured-data` الحالية وتعرضها كخدمة طلب/استجابة، مما يتيح الوصول البرمجي إلى قدرات اكتشاف أنواع البيانات وإنشاء الوصف.
|
||||
|
||||
تدعم الخدمة ثلاث عمليات رئيسية:
|
||||
|
||||
1. **اكتشاف نوع البيانات**: تحليل عينة بيانات لتحديد تنسيقها (CSV أو JSON أو XML)
|
||||
2. **إنشاء الوصف**: إنشاء وصف بيانات مهيكلة لـ TrustGraph لعينة بيانات معينة ونوع
|
||||
3. **التشخيص المدمج**: إجراء كل من اكتشاف النوع وإنشاء الوصف بالتسلسل
|
||||
|
||||
## الأهداف
|
||||
|
||||
**تجزئة تحليل البيانات**: استخراج منطق تشخيص البيانات من واجهة سطر الأوامر إلى مكونات خدمة قابلة لإعادة الاستخدام
|
||||
**تمكين الوصول البرمجي**: توفير وصول قائم على واجهة برمجة التطبيقات (API) إلى قدرات تحليل البيانات
|
||||
**دعم تنسيقات بيانات متعددة**: التعامل مع تنسيقات بيانات CSV و JSON و XML بشكل متسق
|
||||
**إنشاء أوصاف دقيقة**: إنتاج أوصاف بيانات مهيكلة تعكس بدقة بيانات المصدر إلى مخططات TrustGraph
|
||||
**الحفاظ على التوافق مع الإصدارات السابقة**: التأكد من أن وظائف واجهة سطر الأوامر الحالية تظل تعمل
|
||||
**تمكين تجميع الخدمات**: السماح للخدمات الأخرى بالاستفادة من قدرات تشخيص البيانات
|
||||
**تحسين إمكانية الاختبار**: فصل منطق الأعمال عن واجهة سطر الأوامر لتحسين الاختبار
|
||||
**دعم التحليل المتدفق**: تمكين تحليل عينات البيانات دون تحميل الملفات بأكملها
|
||||
|
||||
## الخلفية
|
||||
|
||||
حاليًا، يوفر الأمر `tg-load-structured-data` وظائف شاملة لتحليل البيانات المهيكلة وإنشاء الأوصاف. ومع ذلك، فإن هذه الوظائف مرتبطة ارتباطًا وثيقًا بواجهة سطر الأوامر، مما يحد من إمكانية إعادة استخدامها.
|
||||
|
||||
تشمل القيود الحالية:
|
||||
منطق تشخيص البيانات مضمن في كود واجهة سطر الأوامر
|
||||
لا يوجد وصول برمجي إلى اكتشاف النوع وإنشاء الوصف
|
||||
من الصعب دمج قدرات التشخيص في خدمات أخرى
|
||||
قدرة محدودة على تجميع سير عمل تحليل البيانات
|
||||
|
||||
تعالج هذه المواصفات هذه الفجوات من خلال إنشاء خدمة مخصصة لتشخيص البيانات المهيكلة. من خلال تعريض هذه القدرات كخدمة، يمكن لـ TrustGraph:
|
||||
تمكين خدمات أخرى من تحليل البيانات برمجيًا
|
||||
دعم مسارات معالجة بيانات أكثر تعقيدًا
|
||||
تسهيل التكامل مع الأنظمة الخارجية
|
||||
تحسين قابلية الصيانة من خلال الفصل بين المهام
|
||||
|
||||
## التصميم الفني
|
||||
|
||||
### البنية
|
||||
|
||||
تتطلب خدمة تشخيص البيانات المهيكلة المكونات الفنية التالية:
|
||||
|
||||
1. **معالج خدمة التشخيص**
|
||||
يتعامل مع طلبات التشخيص الواردة
|
||||
يقوم بتنسيق اكتشاف النوع وإنشاء الوصف
|
||||
يُرجع استجابات مهيكلة مع نتائج التشخيص
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/diagnosis/structured_data/service.py`
|
||||
|
||||
2. **كاشف نوع البيانات**
|
||||
يستخدم الكشف الخوارزمي لتحديد تنسيق البيانات (CSV أو JSON أو XML)
|
||||
يحلل هيكل البيانات والفواصل وأنماط بناء الجملة
|
||||
يُرجع التنسيق المكتشف ودرجات الثقة
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/diagnosis/structured_data/type_detector.py`
|
||||
|
||||
3. **مولد الوصف**
|
||||
يستخدم خدمة المطالبة لإنشاء الأوصاف
|
||||
يستدعي المطالبات الخاصة بالتنسيق (diagnose-csv أو diagnose-json أو diagnose-xml)
|
||||
يربط حقول البيانات بحقول مخطط TrustGraph من خلال استجابات المطالبة
|
||||
|
||||
الوحدة: `trustgraph-flow/trustgraph/diagnosis/structured_data/descriptor_generator.py`
|
||||
|
||||
### نماذج البيانات
|
||||
|
||||
#### StructuredDataDiagnosisRequest
|
||||
|
||||
رسالة طلب لعمليات تشخيص البيانات المهيكلة:
|
||||
|
||||
```python
|
||||
class StructuredDataDiagnosisRequest:
|
||||
operation: str # "detect-type", "generate-descriptor", or "diagnose"
|
||||
sample: str # Data sample to analyze (text content)
|
||||
type: Optional[str] # Data type (csv, json, xml) - required for generate-descriptor
|
||||
schema_name: Optional[str] # Target schema name for descriptor generation
|
||||
options: Dict[str, Any] # Additional options (e.g., delimiter for CSV)
|
||||
```
|
||||
|
||||
#### استجابة تشخيص البيانات المنظمة
|
||||
|
||||
رسالة استجابة تحتوي على نتائج التشخيص:
|
||||
|
||||
```python
|
||||
class StructuredDataDiagnosisResponse:
|
||||
operation: str # The operation that was performed
|
||||
detected_type: Optional[str] # Detected data type (for detect-type/diagnose)
|
||||
confidence: Optional[float] # Confidence score for type detection
|
||||
descriptor: Optional[Dict] # Generated descriptor (for generate-descriptor/diagnose)
|
||||
error: Optional[str] # Error message if operation failed
|
||||
metadata: Dict[str, Any] # Additional metadata (e.g., field count, sample records)
|
||||
```
|
||||
|
||||
#### هيكل الوصف
|
||||
|
||||
يتبع الوصف الناتج تنسيق الوصف المنظم للبيانات الموجود:
|
||||
|
||||
```json
|
||||
{
|
||||
"format": {
|
||||
"type": "csv",
|
||||
"encoding": "utf-8",
|
||||
"options": {
|
||||
"delimiter": ",",
|
||||
"has_header": true
|
||||
}
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"source_field": "customer_id",
|
||||
"target_field": "id",
|
||||
"transforms": [
|
||||
{"type": "trim"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": {
|
||||
"schema_name": "customer",
|
||||
"options": {
|
||||
"batch_size": 1000,
|
||||
"confidence": 0.9
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### واجهة الخدمة
|
||||
|
||||
ستعرض الخدمة العمليات التالية من خلال نمط الطلب/الاستجابة:
|
||||
|
||||
1. **عملية اكتشاف النوع**
|
||||
المدخلات: عينة بيانات
|
||||
المعالجة: تحليل هيكل البيانات باستخدام الكشف الخوارزمي
|
||||
المخرجات: النوع المكتشف مع درجة الثقة
|
||||
|
||||
2. **عملية توليد الوصف**
|
||||
المدخلات: عينة بيانات، والنوع، واسم المخطط المستهدف
|
||||
المعالجة:
|
||||
استدعاء خدمة المطالبة بمعرف المطالبة الخاص بالتنسيق (diagnose-csv أو diagnose-json أو diagnose-xml)
|
||||
تمرير عينة البيانات والمخططات المتاحة إلى المطالبة
|
||||
استقبال الوصف الذي تم إنشاؤه من استجابة المطالبة
|
||||
المخرجات: وصف البيانات المنظمة
|
||||
|
||||
3. **عملية التشخيص المجمعة**
|
||||
المدخلات: عينة بيانات، واسم المخطط (اختياري)
|
||||
المعالجة:
|
||||
استخدام الكشف الخوارزمي لتحديد التنسيق أولاً
|
||||
تحديد معرف المطالبة الخاص بالتنسيق المناسب بناءً على النوع المكتشف
|
||||
استدعاء خدمة المطالبة لإنشاء الوصف
|
||||
المخرجات: كل من النوع المكتشف والوصف
|
||||
|
||||
### تفاصيل التنفيذ
|
||||
|
||||
ستتبع الخدمة اتفاقيات خدمة TrustGraph:
|
||||
|
||||
1. **تسجيل الخدمة**
|
||||
التسجيل كنوع خدمة `structured-diag`
|
||||
استخدام مواضيع الطلب/الاستجابة القياسية
|
||||
تنفيذ الفئة الأساسية FlowProcessor
|
||||
تسجيل PromptClientSpec لتفاعل خدمة المطالبة
|
||||
|
||||
2. **إدارة التكوين**
|
||||
الوصول إلى تكوينات المخططات عبر خدمة التكوين
|
||||
تخزين المخططات مؤقتًا لتحسين الأداء
|
||||
التعامل مع تحديثات التكوين ديناميكيًا
|
||||
|
||||
3. **تكامل المطالبة**
|
||||
استخدام البنية التحتية الحالية لخدمة المطالبة
|
||||
استدعاء خدمة المطالبة بمعرفات المطالبة الخاصة بالتنسيق:
|
||||
`diagnose-csv`: لتحليل بيانات CSV
|
||||
`diagnose-json`: لتحليل بيانات JSON
|
||||
`diagnose-xml`: لتحليل بيانات XML
|
||||
يتم تكوين المطالبات في تكوين المطالبة، وليس ترميزها بشكل ثابت في الخدمة
|
||||
تمرير المخططات وعينات البيانات كمتغيرات للمطالبة
|
||||
تحليل استجابات المطالبة لاستخراج الأوصاف
|
||||
|
||||
4. **معالجة الأخطاء**
|
||||
التحقق من صحة عينات البيانات المدخلة
|
||||
توفير رسائل خطأ وصفية
|
||||
التعامل مع البيانات التالفة بأمان
|
||||
التعامل مع فشل خدمة المطالبة
|
||||
|
||||
5. **أخذ العينات من البيانات**
|
||||
معالجة أحجام العينات القابلة للتكوين
|
||||
التعامل مع السجلات غير المكتملة بشكل مناسب
|
||||
الحفاظ على اتساق أخذ العينات
|
||||
|
||||
### تكامل واجهة برمجة التطبيقات (API)
|
||||
|
||||
ستتكامل الخدمة مع واجهات برمجة تطبيقات TrustGraph الحالية:
|
||||
|
||||
المكونات المعدلة:
|
||||
`tg-load-structured-data` CLI - تم إعادة هيكلتها لاستخدام الخدمة الجديدة لعمليات التشخيص
|
||||
Flow API - تم توسيعه لدعم طلبات تشخيص البيانات المنظمة
|
||||
|
||||
نقاط نهاية الخدمة الجديدة:
|
||||
`/api/v1/flow/{flow}/diagnose/structured-data` - نقطة نهاية WebSocket لطلبات التشخيص
|
||||
`/api/v1/diagnose/structured-data` - نقطة نهاية REST للتشخيص المتزامن
|
||||
|
||||
### تدفق الرسائل
|
||||
|
||||
```
|
||||
Client → Gateway → Structured Diag Service → Config Service (for schemas)
|
||||
↓
|
||||
Type Detector (algorithmic)
|
||||
↓
|
||||
Prompt Service (diagnose-csv/json/xml)
|
||||
↓
|
||||
Descriptor Generator (parses prompt response)
|
||||
↓
|
||||
Client ← Gateway ← Structured Diag Service (response)
|
||||
```
|
||||
|
||||
## اعتبارات الأمان
|
||||
|
||||
التحقق من صحة الإدخال لمنع هجمات الحقن.
|
||||
حدود الحجم على عينات البيانات لمنع هجمات الحرمان من الخدمة (DoS).
|
||||
تنقية الواصفات التي تم إنشاؤها.
|
||||
التحكم في الوصول من خلال مصادقة TrustGraph الحالية.
|
||||
|
||||
## اعتبارات الأداء
|
||||
|
||||
تخزين تعريفات المخططات مؤقتًا لتقليل عدد استدعاءات خدمة التكوين.
|
||||
تحديد حدود لحجم العينات للحفاظ على أداء سريع الاستجابة.
|
||||
استخدام المعالجة المتدفقة لعلاجات البيانات الكبيرة.
|
||||
تطبيق آليات المهلة للتحليلات التي تستغرق وقتًا طويلاً.
|
||||
|
||||
## استراتيجية الاختبار
|
||||
|
||||
1. **اختبارات الوحدة**
|
||||
اكتشاف النوع لـتنسيقات البيانات المختلفة.
|
||||
دقة توليد الواصفات.
|
||||
سيناريوهات معالجة الأخطاء.
|
||||
|
||||
2. **اختبارات التكامل**
|
||||
تدفق طلب/استجابة الخدمة.
|
||||
استرجاع المخططات وتخزينها مؤقتًا.
|
||||
تكامل واجهة سطر الأوامر (CLI).
|
||||
|
||||
3. **اختبارات الأداء**
|
||||
معالجة العينات الكبيرة.
|
||||
معالجة الطلبات المتزامنة.
|
||||
استخدام الذاكرة تحت الحمل.
|
||||
|
||||
## خطة الترحيل
|
||||
|
||||
1. **المرحلة الأولى**: تنفيذ الخدمة مع الوظائف الأساسية.
|
||||
2. **المرحلة الثانية**: إعادة هيكلة واجهة سطر الأوامر (CLI) لاستخدام الخدمة (مع الحفاظ على التوافق مع الإصدارات السابقة).
|
||||
3. **المرحلة الثالثة**: إضافة نقاط نهاية واجهة برمجة التطبيقات (REST API).
|
||||
4. **المرحلة الرابعة**: إيقاف وظائف واجهة سطر الأوامر (CLI) المضمنة (مع إشعار مسبق).
|
||||
|
||||
## الجدول الزمني
|
||||
|
||||
الأسبوع 1-2: تنفيذ الخدمة الأساسية واكتشاف النوع.
|
||||
الأسبوع 3-4: إضافة توليد الواصفات والتكامل.
|
||||
الأسبوع 5: الاختبار والتوثيق.
|
||||
الأسبوع 6: إعادة هيكلة واجهة سطر الأوامر (CLI) والترحيل.
|
||||
|
||||
## أسئلة مفتوحة
|
||||
|
||||
هل يجب أن تدعم الخدمة تنسيقات بيانات إضافية (مثل Parquet، Avro)؟
|
||||
ما هو الحد الأقصى لحجم العينة للتحليل؟
|
||||
هل يجب تخزين نتائج التشخيص مؤقتًا للطلبات المتكررة؟
|
||||
كيف يجب أن تتعامل الخدمة مع السيناريوهات متعددة المخططات؟
|
||||
هل يجب أن تكون معرفات المطالبات معلمات قابلة للتكوين للخدمة؟
|
||||
|
||||
## المراجع
|
||||
|
||||
[مواصفات واصف البيانات المنظمة](structured-data-descriptor.md)
|
||||
[توثيق تحميل البيانات المنظمة](structured-data.md)
|
||||
`tg-load-structured-data` التنفيذ: `trustgraph-cli/trustgraph/cli/load_structured_data.py`
|
||||
499
docs/tech-specs/ar/tool-group.ar.md
Normal file
499
docs/tech-specs/ar/tool-group.ar.md
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
---
|
||||
layout: default
|
||||
title: "مجموعة أدوات TrustGraph"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# مجموعة أدوات TrustGraph
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
## المواصفات الفنية v1.0
|
||||
|
||||
### ملخص تنفيذي
|
||||
|
||||
تحدد هذه المواصفات نظام تجميع الأدوات لوكلاء TrustGraph، مما يسمح بالتحكم الدقيق في الأدوات المتاحة لطلبات معينة. يقدم النظام تصفية الأدوات المستندة إلى المجموعات من خلال التكوين وتحديد مستوى الطلب، مما يتيح حدودًا أمنية أفضل وإدارة الموارد وتقسيمًا وظيفيًا لقدرات الوكيل.
|
||||
|
||||
### 1. نظرة عامة
|
||||
|
||||
#### 1.1 بيان المشكلة
|
||||
|
||||
حاليًا، يتمتع وكلاء TrustGraph بإمكانية الوصول إلى جميع الأدوات المكونة بغض النظر عن سياق الطلب أو متطلبات الأمان. وهذا يخلق عدة تحديات:
|
||||
|
||||
**مخاطر أمنية**: الأدوات الحساسة (مثل تعديل البيانات) متاحة حتى للاستعلامات للقراءة فقط.
|
||||
**إهدار الموارد**: يتم تحميل الأدوات المعقدة حتى عندما لا تتطلب الاستعلامات البسيطة ذلك.
|
||||
**ارتباك وظيفي**: قد تختار الوكلاء أدوات غير مناسبة عندما تكون هناك بدائل أبسط.
|
||||
**العزل متعدد المستأجرين**: تحتاج مجموعات المستخدمين المختلفة إلى الوصول إلى مجموعات أدوات مختلفة.
|
||||
|
||||
#### 1.2 نظرة عامة على الحل
|
||||
|
||||
يقدم نظام تجميع الأدوات ما يلي:
|
||||
|
||||
1. **تصنيف المجموعات**: يتم وضع علامة على الأدوات باستخدام عضوية المجموعة أثناء التكوين.
|
||||
2. **التصفية على مستوى الطلب**: يحدد AgentRequest مجموعات الأدوات المسموح بها.
|
||||
3. **التنفيذ في وقت التشغيل**: لا تملك الوكلاء سوى الأدوات التي تتطابق مع المجموعات المطلوبة.
|
||||
4. **تجميع مرن**: يمكن أن تنتمي الأدوات إلى مجموعات متعددة للسيناريوهات المعقدة.
|
||||
|
||||
### 2. تغييرات المخطط
|
||||
|
||||
#### 2.1 تحسين مخطط تكوين الأداة
|
||||
|
||||
يتم تحسين تكوين الأداة الحالي بإضافة حقل `group`:
|
||||
|
||||
**قبل:**
|
||||
```json
|
||||
{
|
||||
"name": "knowledge-query",
|
||||
"type": "knowledge-query",
|
||||
"description": "Query the knowledge graph"
|
||||
}
|
||||
```
|
||||
|
||||
**بعد:**
|
||||
```json
|
||||
{
|
||||
"name": "knowledge-query",
|
||||
"type": "knowledge-query",
|
||||
"description": "Query the knowledge graph",
|
||||
"group": ["read-only", "knowledge", "basic"]
|
||||
}
|
||||
```
|
||||
|
||||
**تحديد حقل المجموعة:**
|
||||
`group`: Array(String) - قائمة المجموعات التي تنتمي إليها هذه الأداة.
|
||||
**اختياري**: الأدوات التي لا تحتوي على حقل المجموعة تنتمي إلى المجموعة الافتراضية.
|
||||
**العضوية المتعددة**: يمكن للأدوات أن تنتمي إلى مجموعات متعددة.
|
||||
**حساسية حالة الأحرف**: أسماء المجموعات هي مطابقات دقيقة للسلاسل النصية.
|
||||
|
||||
#### 2.1.2 تحسين انتقال حالة الأداة
|
||||
|
||||
يمكن للأدوات تحديد انتقالات الحالة وحالة التوفر بناءً على الحالة بشكل اختياري:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "knowledge-query",
|
||||
"type": "knowledge-query",
|
||||
"description": "Query the knowledge graph",
|
||||
"group": ["read-only", "knowledge", "basic"],
|
||||
"state": "analysis",
|
||||
"available_in_states": ["undefined", "research"]
|
||||
}
|
||||
```
|
||||
|
||||
**تحديد حقل الحالة:**
|
||||
`state`: String - **اختياري** - الحالة التي يتم الانتقال إليها بعد تنفيذ الأداة بنجاح
|
||||
`available_in_states`: Array(String) - **اختياري** - الحالات التي تتوفر فيها هذه الأداة
|
||||
**السلوك الافتراضي**: الأدوات التي لا تحتوي على `available_in_states` متاحة في جميع الحالات
|
||||
**انتقال الحالة**: يحدث فقط بعد تنفيذ الأداة بنجاح
|
||||
|
||||
#### 2.2 تحسين مخطط AgentRequest
|
||||
|
||||
مخطط `AgentRequest` في `trustgraph-base/trustgraph/schema/services/agent.py` تم تحسينه:
|
||||
|
||||
**AgentRequest الحالي:**
|
||||
`question`: String - استعلام المستخدم
|
||||
`plan`: String - خطة التنفيذ (يمكن إزالتها)
|
||||
`state`: String - حالة الوكيل
|
||||
`history`: Array(AgentStep) - سجل التنفيذ
|
||||
|
||||
**AgentRequest المحسن:**
|
||||
`question`: String - استعلام المستخدم
|
||||
`state`: String - حالة تنفيذ الوكيل (تستخدم الآن بنشاط لتصفية الأدوات)
|
||||
`history`: Array(AgentStep) - سجل التنفيذ
|
||||
`group`: Array(String) - **جديد** - مجموعات الأدوات المسموح بها لهذا الطلب
|
||||
|
||||
**تغييرات المخطط:**
|
||||
**تمت إزالة**: حقل `plan` لم يعد مطلوبًا ويمكن إزالته (كان مخصصًا في الأصل لتحديد الأدوات)
|
||||
**تمت إضافة**: حقل `group` لتحديد مجموعة الأدوات
|
||||
**تم التحسين**: يتحكم حقل `state` الآن في توفر الأدوات أثناء التنفيذ
|
||||
|
||||
**سلوكيات الحقول:**
|
||||
|
||||
**حقل المجموعة:**
|
||||
**اختياري**: إذا لم يتم تحديده، فسيتم تعيينه افتراضيًا إلى ["default"]
|
||||
**التقاطع**: تتوفر فقط الأدوات التي تتطابق مع مجموعة واحدة على الأقل من المجموعات المحددة
|
||||
**مصفوفة فارغة**: لا تتوفر أي أدوات (يمكن للوكيل استخدام الاستدلال الداخلي فقط)
|
||||
**رمز بدل (Wildcard)**: تمنح المجموعة الخاصة "*" إمكانية الوصول إلى جميع الأدوات
|
||||
|
||||
**حقل الحالة:**
|
||||
**اختياري**: إذا لم يتم تحديده، فسيتم تعيينه افتراضيًا إلى "undefined"
|
||||
**التصفية بناءً على الحالة**: الأدوات المتاحة فقط في الحالة الحالية هي المؤهلة
|
||||
**الحالة الافتراضية**: تسمح حالة "undefined" بجميع الأدوات (مع مراعاة تصفية المجموعة)
|
||||
**انتقالات الحالة**: يمكن للأدوات تغيير الحالة بعد التنفيذ الناجح
|
||||
|
||||
### 3. أمثلة على المجموعات المخصصة
|
||||
|
||||
يمكن للمؤسسات تحديد مجموعات خاصة بالمجال:
|
||||
|
||||
```json
|
||||
{
|
||||
"financial-tools": ["stock-query", "portfolio-analysis"],
|
||||
"medical-tools": ["diagnosis-assist", "drug-interaction"],
|
||||
"legal-tools": ["contract-analysis", "case-search"]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. تفاصيل التنفيذ
|
||||
|
||||
#### 4.1 تحميل الأدوات وتصفيتها
|
||||
|
||||
**مرحلة التهيئة:**
|
||||
1. يتم تحميل جميع الأدوات من ملف التهيئة مع تحديد مجموعاتها.
|
||||
2. يتم تعيين الأدوات التي لا تحتوي على مجموعات محددة إلى المجموعة "الافتراضية".
|
||||
3. يتم التحقق من عضوية المجموعة وتخزينها في سجل الأدوات.
|
||||
|
||||
**مرحلة معالجة الطلبات:**
|
||||
1. يصل طلب الوكيل (AgentRequest) مع تحديد المجموعة الاختياري.
|
||||
2. يقوم الوكيل بتصفية الأدوات المتاحة بناءً على تقاطع المجموعات.
|
||||
3. يتم تمرير الأدوات المتطابقة فقط إلى سياق تنفيذ الوكيل.
|
||||
4. يعمل الوكيل مع مجموعة الأدوات المفلترة طوال دورة حياة الطلب.
|
||||
|
||||
#### 4.2 منطق تصفية الأدوات
|
||||
|
||||
**التصفية المجمعة للمجموعة والحالة:**
|
||||
|
||||
```
|
||||
For each configured tool:
|
||||
tool_groups = tool.group || ["default"]
|
||||
tool_states = tool.available_in_states || ["*"] // Available in all states
|
||||
|
||||
For each request:
|
||||
requested_groups = request.group || ["default"]
|
||||
current_state = request.state || "undefined"
|
||||
|
||||
Tool is available if:
|
||||
// Group filtering
|
||||
(intersection(tool_groups, requested_groups) is not empty OR "*" in requested_groups)
|
||||
AND
|
||||
// State filtering
|
||||
(current_state in tool_states OR "*" in tool_states)
|
||||
```
|
||||
|
||||
**منطق الانتقال بين الحالات:**
|
||||
|
||||
```
|
||||
After successful tool execution:
|
||||
if tool.state is defined:
|
||||
next_request.state = tool.state
|
||||
else:
|
||||
next_request.state = current_request.state // No change
|
||||
```
|
||||
|
||||
#### 4.3 نقاط تكامل الوكيل
|
||||
|
||||
**الوكيل ReAct:**
|
||||
يتم تصفية الأدوات في agent_manager.py أثناء إنشاء سجل الأدوات.
|
||||
يتم تصفية قائمة الأدوات المتاحة بناءً على المجموعة والحالة قبل إنشاء الخطة.
|
||||
تحديثات انتقالات الحالة تحدّث حقل AgentRequest.state بعد تنفيذ الأداة بنجاح.
|
||||
تستخدم التكرار التالي الحالة المحدثة لتصفية الأدوات.
|
||||
|
||||
**الوكيل القائم على الثقة:**
|
||||
يتم تصفية الأدوات في planner.py أثناء إنشاء الخطة.
|
||||
التحقق من صحة ExecutionStep يضمن استخدام الأدوات المؤهلة فقط بناءً على المجموعة والحالة.
|
||||
وحدة التحكم في التدفق تفرض توفر الأدوات في وقت التشغيل.
|
||||
تتم إدارة انتقالات الحالة بواسطة وحدة التحكم في التدفق بين الخطوات.
|
||||
|
||||
### 5. أمثلة التكوين
|
||||
|
||||
#### 5.1 تكوين الأداة مع المجموعات والحالات
|
||||
|
||||
```yaml
|
||||
tool:
|
||||
knowledge-query:
|
||||
type: knowledge-query
|
||||
name: "Knowledge Graph Query"
|
||||
description: "Query the knowledge graph for entities and relationships"
|
||||
group: ["read-only", "knowledge", "basic"]
|
||||
state: "analysis"
|
||||
available_in_states: ["undefined", "research"]
|
||||
|
||||
graph-update:
|
||||
type: graph-update
|
||||
name: "Graph Update"
|
||||
description: "Add or modify entities in the knowledge graph"
|
||||
group: ["write", "knowledge", "admin"]
|
||||
available_in_states: ["analysis", "modification"]
|
||||
|
||||
text-completion:
|
||||
type: text-completion
|
||||
name: "Text Completion"
|
||||
description: "Generate text using language models"
|
||||
group: ["read-only", "text", "basic"]
|
||||
state: "undefined"
|
||||
# No available_in_states = available in all states
|
||||
|
||||
complex-analysis:
|
||||
type: mcp-tool
|
||||
name: "Complex Analysis Tool"
|
||||
description: "Perform complex data analysis"
|
||||
group: ["advanced", "compute", "expensive"]
|
||||
state: "results"
|
||||
available_in_states: ["analysis"]
|
||||
mcp_tool_id: "analysis-server"
|
||||
|
||||
reset-workflow:
|
||||
type: mcp-tool
|
||||
name: "Reset Workflow"
|
||||
description: "Reset to initial state"
|
||||
group: ["admin"]
|
||||
state: "undefined"
|
||||
available_in_states: ["analysis", "results"]
|
||||
```
|
||||
|
||||
#### 5.2 أمثلة للطلبات مع سير العمل الخاص بالحالة.
|
||||
|
||||
**طلب البحث الأولي:**
|
||||
```json
|
||||
{
|
||||
"question": "What entities are connected to Company X?",
|
||||
"group": ["read-only", "knowledge"],
|
||||
"state": "undefined"
|
||||
}
|
||||
```
|
||||
*الأدوات المتاحة: knowledge-query، text-completion*
|
||||
*بعد استخدام knowledge-query: الحالة → "analysis"*
|
||||
|
||||
**مرحلة التحليل:**
|
||||
```json
|
||||
{
|
||||
"question": "Continue analysis based on previous results",
|
||||
"group": ["advanced", "compute", "write"],
|
||||
"state": "analysis"
|
||||
}
|
||||
```
|
||||
*الأدوات المتاحة: تحليل معقد، تحديث الرسم البياني، إعادة تعيين سير العمل*
|
||||
*بعد التحليل المعقد: الحالة → "النتائج"*
|
||||
|
||||
**مرحلة النتائج:**
|
||||
```json
|
||||
{
|
||||
"question": "What should I do with these results?",
|
||||
"group": ["admin"],
|
||||
"state": "results"
|
||||
}
|
||||
```
|
||||
*الأدوات المتاحة: reset-workflow فقط*
|
||||
*بعد reset-workflow: الحالة → "غير محددة"*
|
||||
|
||||
**مثال سير العمل - التدفق الكامل:**
|
||||
1. **البداية (غير محددة):** استخدم knowledge-query للانتقال إلى الحالة "تحليل".
|
||||
2. **حالة التحليل:** استخدم complex-analysis للانتقال إلى الحالة "النتائج".
|
||||
3. **حالة النتائج:** استخدم reset-workflow للعودة إلى الحالة "غير محددة".
|
||||
4. **العودة إلى البداية:** تتوفر جميع الأدوات الأولية مرة أخرى.
|
||||
|
||||
### 6. اعتبارات الأمان
|
||||
|
||||
#### 6.1 تكامل التحكم في الوصول
|
||||
|
||||
**التصفية على مستوى البوابة:**
|
||||
يمكن للبوابة فرض قيود على المجموعات بناءً على أذونات المستخدم.
|
||||
منع رفع الامتيازات من خلال التلاعب بالطلبات.
|
||||
يتضمن سجل التدقيق المجموعات المطلوبة والمجموعات الممنوحة.
|
||||
|
||||
**مثال لمنطق البوابة:**
|
||||
```
|
||||
user_permissions = get_user_permissions(request.user_id)
|
||||
allowed_groups = user_permissions.tool_groups
|
||||
requested_groups = request.group
|
||||
|
||||
# Validate request doesn't exceed permissions
|
||||
if not is_subset(requested_groups, allowed_groups):
|
||||
reject_request("Insufficient permissions for requested tool groups")
|
||||
```
|
||||
|
||||
#### 6.2 التدقيق والمراقبة
|
||||
|
||||
**مسار تدقيق مُحسّن:**
|
||||
تسجيل مجموعات الأدوات المطلوبة والحالة الأولية لكل طلب.
|
||||
تتبع عمليات انتقال الحالة واستخدام الأدوات حسب عضوية المجموعة.
|
||||
مراقبة محاولات الوصول غير المصرح بها إلى المجموعة والانتقالات غير الصالحة للحالة.
|
||||
إرسال تنبيهات عند وجود أنماط استخدام غير عادية للمجموعة أو سير عمل حالة مشبوه.
|
||||
|
||||
### 7. استراتيجية الترحيل
|
||||
|
||||
#### 7.1 التوافق مع الإصدارات السابقة
|
||||
|
||||
**المرحلة الأولى: تغييرات إضافية**
|
||||
إضافة حقل `group` اختياري إلى تكوينات الأدوات.
|
||||
إضافة حقل `group` اختياري إلى مخطط AgentRequest.
|
||||
السلوك الافتراضي: تنتمي جميع الأدوات الحالية إلى المجموعة "الافتراضية".
|
||||
تستخدم الطلبات الحالية التي لا تحتوي على حقل المجموعة المجموعة "الافتراضية".
|
||||
|
||||
**الحفاظ على السلوك الحالي:**
|
||||
تستمر الأدوات التي لا تحتوي على تكوين مجموعة في العمل (المجموعة الافتراضية).
|
||||
الأدوات التي لا تحتوي على تكوين حالة متاحة في جميع الحالات.
|
||||
يمكن للطلبات التي لا تحدد المجموعة الوصول إلى جميع الأدوات (المجموعة الافتراضية).
|
||||
تستخدم الطلبات التي لا تحدد الحالة حالة "غير محددة" (جميع الأدوات متاحة).
|
||||
لا توجد تغييرات تؤثر على عمليات النشر الحالية.
|
||||
|
||||
### 8. المراقبة وقابلية الملاحظة
|
||||
|
||||
#### 8.1 مقاييس جديدة
|
||||
|
||||
**استخدام مجموعة الأدوات:**
|
||||
`agent_tool_group_requests_total` - عد الطلبات حسب المجموعة.
|
||||
`agent_tool_group_availability` - مقياس للأدوات المتاحة لكل مجموعة.
|
||||
`agent_filtered_tools_count` - رسم بياني لعدد الأدوات بعد تصفية المجموعة والحالة.
|
||||
|
||||
**مقاييس سير عمل الحالة:**
|
||||
`agent_state_transitions_total` - عد عمليات انتقال الحالة لكل أداة.
|
||||
`agent_workflow_duration_seconds` - رسم بياني للوقت المستغرق في كل حالة.
|
||||
`agent_state_availability` - مقياس للأدوات المتاحة لكل حالة.
|
||||
|
||||
**مقاييس الأمان:**
|
||||
`agent_group_access_denied_total` - عد الوصول غير المصرح به إلى المجموعة.
|
||||
`agent_invalid_state_transition_total` - عد عمليات انتقال الحالة غير الصالحة.
|
||||
`agent_privilege_escalation_attempts_total` - عد الطلبات المشبوهة.
|
||||
|
||||
#### 8.2 تحسينات التسجيل
|
||||
|
||||
**تسجيل الطلبات:**
|
||||
```json
|
||||
{
|
||||
"request_id": "req-123",
|
||||
"requested_groups": ["read-only", "knowledge"],
|
||||
"initial_state": "undefined",
|
||||
"state_transitions": [
|
||||
{"tool": "knowledge-query", "from": "undefined", "to": "analysis", "timestamp": "2024-01-01T10:00:01Z"}
|
||||
],
|
||||
"available_tools": ["knowledge-query", "text-completion"],
|
||||
"filtered_by_group": ["graph-update", "admin-tool"],
|
||||
"filtered_by_state": [],
|
||||
"execution_time": "1.2s"
|
||||
}
|
||||
```
|
||||
|
||||
### 9. استراتيجية الاختبار
|
||||
|
||||
#### 9.1 اختبارات الوحدة
|
||||
|
||||
**منطق تصفية الأدوات:**
|
||||
حسابات تقاطع مجموعات الاختبار.
|
||||
منطق التصفية المستند إلى الحالة.
|
||||
التحقق من التعيين الافتراضي للمجموعة والحالة.
|
||||
اختبار سلوك المجموعة باستخدام أحرف البدل.
|
||||
التحقق من معالجة المجموعات الفارغة.
|
||||
اختبار سيناريوهات التصفية المجمعة للمجموعة والحالة.
|
||||
|
||||
**التحقق من التكوين:**
|
||||
اختبار تحميل الأدوات مع تكوينات مختلفة للمجموعة والحالة.
|
||||
التحقق من صحة المخطط للمواصفات غير الصالحة للمجموعة والحالة.
|
||||
اختبار التوافق مع الإصدارات السابقة مع التكوينات الحالية.
|
||||
التحقق من تعريفات دورات الانتقال بين الحالات.
|
||||
|
||||
#### 9.2 اختبارات التكامل
|
||||
|
||||
**سلوك الوكيل:**
|
||||
التحقق من أن الوكلاء يرون فقط الأدوات التي تم تصفيتها حسب المجموعة والحالة.
|
||||
اختبار تنفيذ الطلبات مع مجموعات مختلفة.
|
||||
اختبار الانتقالات بين الحالات أثناء تنفيذ الوكيل.
|
||||
التحقق من معالجة الأخطاء عندما لا تتوفر أي أدوات.
|
||||
اختبار تقدم سير العمل عبر حالات متعددة.
|
||||
|
||||
**اختبار الأمان:**
|
||||
اختبار منع تصعيد الامتيازات.
|
||||
التحقق من دقة سجل التدقيق.
|
||||
اختبار تكامل البوابة مع أذونات المستخدم.
|
||||
|
||||
#### 9.3 سيناريوهات شاملة
|
||||
|
||||
**الاستخدام متعدد المستأجر مع سير عمل الحالة:**
|
||||
```
|
||||
Scenario: Different users with different tool access and workflow states
|
||||
Given: User A has "read-only" permissions, state "undefined"
|
||||
And: User B has "write" permissions, state "analysis"
|
||||
When: Both request knowledge operations
|
||||
Then: User A gets read-only tools available in "undefined" state
|
||||
And: User B gets write tools available in "analysis" state
|
||||
And: State transitions are tracked per user session
|
||||
And: All usage and transitions are properly audited
|
||||
```
|
||||
|
||||
**تطور حالة سير العمل:**
|
||||
```
|
||||
Scenario: Complete workflow execution
|
||||
Given: Request with groups ["knowledge", "compute"] and state "undefined"
|
||||
When: Agent executes knowledge-query tool (transitions to "analysis")
|
||||
And: Agent executes complex-analysis tool (transitions to "results")
|
||||
And: Agent executes reset-workflow tool (transitions to "undefined")
|
||||
Then: Each step has correctly filtered available tools
|
||||
And: State transitions are logged with timestamps
|
||||
And: Final state allows initial workflow to repeat
|
||||
```
|
||||
|
||||
### 10. الاعتبارات المتعلقة بالأداء
|
||||
|
||||
#### 10.1 تأثير تحميل الأدوات
|
||||
|
||||
**تحميل التكوين:**
|
||||
يتم تحميل بيانات التعريف الخاصة بالمجموعة والحالة مرة واحدة عند بدء التشغيل.
|
||||
الحد الأدنى من الحمل على الذاكرة لكل أداة (حقول إضافية).
|
||||
لا يوجد تأثير على وقت تهيئة الأداة.
|
||||
|
||||
**معالجة الطلبات:**
|
||||
يتم تطبيق تصفية المجموعة + الحالة المجمعة مرة واحدة لكل طلب.
|
||||
تعقيد O(n) حيث n = عدد الأدوات المكونة.
|
||||
تضيف عمليات انتقال الحالة حملًا ضئيلًا (تعيين سلسلة).
|
||||
تأثير ضئيل لعدد الأدوات النموذجي (< 100).
|
||||
|
||||
#### 10.2 استراتيجيات التحسين
|
||||
|
||||
**مجموعات الأدوات المحسوبة مسبقًا:**
|
||||
تخزين مجموعات الأدوات حسب مجموعة + مجموعة حالة.
|
||||
تجنب التصفية المتكررة لأنماط المجموعة / الحالة الشائعة.
|
||||
مقايضة بين الذاكرة والحساب للتوليفات المستخدمة بشكل متكرر.
|
||||
|
||||
**التحميل الكسول:**
|
||||
قم بتحميل تطبيقات الأدوات فقط عند الحاجة.
|
||||
تقليل وقت بدء التشغيل لنشر الأدوات العديدة.
|
||||
تسجيل الأدوات الديناميكي بناءً على متطلبات المجموعة.
|
||||
|
||||
### 11. التحسينات المستقبلية
|
||||
|
||||
#### 11.1 التعيين الديناميكي للمجموعة
|
||||
|
||||
**التجميع الواعي بالسياق:**
|
||||
تعيين الأدوات إلى المجموعات بناءً على سياق الطلب.
|
||||
توفر المجموعة بناءً على الوقت (ساعات العمل فقط).
|
||||
قيود المجموعة بناءً على الحمل (الأدوات باهظة الثمن أثناء الاستخدام المنخفض).
|
||||
|
||||
#### 11.2 التسلسلات الهرمية للمجموعات
|
||||
|
||||
**هيكل المجموعة المتداخل:**
|
||||
```json
|
||||
{
|
||||
"knowledge": {
|
||||
"read": ["knowledge-query", "entity-search"],
|
||||
"write": ["graph-update", "entity-create"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 11.3 توصيات بالأدوات
|
||||
|
||||
**اقتراحات قائمة على المجموعات:**
|
||||
اقتراح مجموعات الأدوات المثلى لأنواع الطلبات.
|
||||
التعلم من أنماط الاستخدام لتحسين التوصيات.
|
||||
توفير مجموعات احتياطية عندما تكون الأدوات المفضلة غير متاحة.
|
||||
|
||||
### 12. أسئلة مفتوحة
|
||||
|
||||
1. **التحقق من صحة المجموعة**: هل يجب أن تتسبب أسماء المجموعات غير الصالحة في الطلبات في حدوث أخطاء فادحة أم تحذيرات؟
|
||||
|
||||
2. **اكتشاف المجموعة**: هل يجب أن يوفر النظام واجهة برمجة تطبيقات (API) لسرد المجموعات المتاحة وأدواتها؟
|
||||
|
||||
3. **المجموعات الديناميكية**: هل يجب أن تكون المجموعات قابلة للتكوين في وقت التشغيل أم فقط عند بدء التشغيل؟
|
||||
|
||||
4. **وراثة المجموعة**: هل يجب أن ترث الأدوات مجموعات من فئاتها الأصلية أو تطبيقاتها؟
|
||||
|
||||
5. **مراقبة الأداء**: ما هي المقاييس الإضافية المطلوبة لتتبع استخدام الأدوات القائمة على المجموعات بشكل فعال؟
|
||||
|
||||
### 13. الخلاصة
|
||||
|
||||
يوفر نظام مجموعات الأدوات ما يلي:
|
||||
|
||||
**الأمان**: تحكم دقيق في الوصول إلى قدرات الوكيل.
|
||||
**الأداء**: تقليل الحمل الزائد لاختيار الأدوات وتحميلها.
|
||||
**المرونة**: تصنيف متعدد الأبعاد للأدوات.
|
||||
**التوافق**: تكامل سلس مع بنيات الوكيل الحالية.
|
||||
|
||||
يمكّن هذا النظام عمليات نشر TrustGraph من إدارة الوصول إلى الأدوات بشكل أفضل، وتحسين الحدود الأمنية، وتحسين استخدام الموارد مع الحفاظ على التوافق الكامل مع التكوينات والطلبات الحالية.
|
||||
479
docs/tech-specs/ar/tool-services.ar.md
Normal file
479
docs/tech-specs/ar/tool-services.ar.md
Normal file
|
|
@ -0,0 +1,479 @@
|
|||
---
|
||||
layout: default
|
||||
title: "خدمات الأدوات: أدوات وكيل قابلة للتوصيل ديناميكيًا"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# خدمات الأدوات: أدوات وكيل قابلة للتوصيل ديناميكيًا
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## الحالة
|
||||
|
||||
تم التنفيذ
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
تحدد هذه المواصفات آلية لأدوات وكيل قابلة للتوصيل ديناميكيًا تسمى "خدمات الأدوات". على عكس أنواع الأدوات المضمنة الحالية (`KnowledgeQueryImpl`، `McpToolImpl`، إلخ)، تسمح خدمات الأدوات بإدخال أدوات جديدة عن طريق:
|
||||
|
||||
1. نشر خدمة جديدة تعتمد على Pulsar
|
||||
2. إضافة وصف تهيئة يخبر الوكيل كيفية استدعائها
|
||||
|
||||
يتيح ذلك إمكانية التوسع دون تعديل إطار عمل الاستجابة الأساسي للوكيل.
|
||||
|
||||
## المصطلحات
|
||||
|
||||
| المصطلح | التعريف |
|
||||
|------|------------|
|
||||
| **أداة مضمنة** | أنواع الأدوات الحالية مع تطبيقات مضمنة في `tools.py` |
|
||||
| **خدمة أداة** | خدمة Pulsar التي يمكن استدعاؤها كأداة وكيل، ويتم تعريفها بواسطة وصف الخدمة |
|
||||
| **أداة** | نسخة مُكوّنة تشير إلى خدمة أداة، وتُعرض للوكيل/نموذج اللغة الكبير |
|
||||
|
||||
هذا نموذج من مستويين، مماثل لأدوات MCP:
|
||||
MCP: يحدد خادم MCP واجهة الأداة → إعداد الأداة يشير إليها
|
||||
خدمات الأدوات: تحدد خدمة الأداة واجهة Pulsar → إعداد الأداة يشير إليها
|
||||
|
||||
## الخلفية: الأدوات الحالية
|
||||
|
||||
### تنفيذ الأداة المضمنة
|
||||
|
||||
يتم تعريف الأدوات حاليًا في `trustgraph-flow/trustgraph/agent/react/tools.py` مع تطبيقات مُصنّفة:
|
||||
|
||||
```python
|
||||
class KnowledgeQueryImpl:
|
||||
async def invoke(self, question):
|
||||
client = self.context("graph-rag-request")
|
||||
return await client.rag(question, self.collection)
|
||||
```
|
||||
|
||||
كل نوع أداة:
|
||||
لديه خدمة Pulsar مُبرمجة مسبقًا والتي يستدعيها (مثل: `graph-rag-request`)
|
||||
يعرف بالضبط الطريقة التي يجب استدعاؤها على العميل (مثل: `client.rag()`)
|
||||
لديه وسائط مُعرّفة من النوع في التنفيذ
|
||||
|
||||
### تسجيل الأدوات (service.py:105-214)
|
||||
|
||||
يتم تحميل الأدوات من ملف التكوين باستخدام حقل `type` والذي يربط بتنفيذ:
|
||||
|
||||
```python
|
||||
if impl_id == "knowledge-query":
|
||||
impl = functools.partial(KnowledgeQueryImpl, collection=data.get("collection"))
|
||||
elif impl_id == "text-completion":
|
||||
impl = TextCompletionImpl
|
||||
# ... etc
|
||||
```
|
||||
|
||||
## العمارة
|
||||
|
||||
### نموذج ذو طبقتين
|
||||
|
||||
#### الطبقة الأولى: مُعرّف خدمة الأداة
|
||||
|
||||
تحدد خدمة الأداة واجهة خدمة Pulsar. وهي تُعلن عن:
|
||||
قوائم انتظار Pulsar للطلبات/الاستجابات
|
||||
معلمات التكوين التي تتطلبها من الأدوات التي تستخدمها
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "custom-rag",
|
||||
"request-queue": "non-persistent://tg/request/custom-rag",
|
||||
"response-queue": "non-persistent://tg/response/custom-rag",
|
||||
"config-params": [
|
||||
{"name": "collection", "required": true}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
خدمة أداة لا تتطلب أي معلمات تهيئة:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "calculator",
|
||||
"request-queue": "non-persistent://tg/request/calc",
|
||||
"response-queue": "non-persistent://tg/response/calc",
|
||||
"config-params": []
|
||||
}
|
||||
```
|
||||
|
||||
#### المستوى الثاني: وصف الأداة
|
||||
|
||||
تشير الأداة إلى خدمة الأداة وتوفر:
|
||||
قيم معلمات التكوين (التي تلبي متطلبات الخدمة)
|
||||
بيانات وصفية للأداة للوكيل (الاسم، الوصف)
|
||||
تعريفات الوسائط لنموذج اللغة الكبيرة (LLM)
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tool-service",
|
||||
"name": "query-customers",
|
||||
"description": "Query the customer knowledge base",
|
||||
"service": "custom-rag",
|
||||
"collection": "customers",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "question",
|
||||
"type": "string",
|
||||
"description": "The question to ask about customers"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
يمكن لأدوات متعددة الإشارة إلى نفس الخدمة بتكوينات مختلفة:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tool-service",
|
||||
"name": "query-products",
|
||||
"description": "Query the product knowledge base",
|
||||
"service": "custom-rag",
|
||||
"collection": "products",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "question",
|
||||
"type": "string",
|
||||
"description": "The question to ask about products"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### تنسيق الطلب
|
||||
|
||||
عندما يتم استدعاء أداة، يتضمن الطلب المرسل إلى خدمة الأداة ما يلي:
|
||||
`user`: من طلب الوكيل (دعم تعدد المستأجرين)
|
||||
`config`: قيم التكوين المشفرة بتنسيق JSON والمستمدة من وصف الأداة
|
||||
`arguments`: وسائط مشفرة بتنسيق JSON والمستمدة من نموذج اللغة الكبير (LLM)
|
||||
|
||||
```json
|
||||
{
|
||||
"user": "alice",
|
||||
"config": "{\"collection\": \"customers\"}",
|
||||
"arguments": "{\"question\": \"What are the top customer complaints?\"}"
|
||||
}
|
||||
```
|
||||
|
||||
تتلقى خدمة الأداة هذه البيانات كقاموسات مُحللة في الطريقة `invoke`.
|
||||
|
||||
### تطبيق عام لخدمة الأداة
|
||||
|
||||
تستدعي فئة `ToolServiceImpl` خدمات الأداة بناءً على التكوين:
|
||||
|
||||
```python
|
||||
class ToolServiceImpl:
|
||||
def __init__(self, context, request_queue, response_queue, config_values, arguments, processor):
|
||||
self.request_queue = request_queue
|
||||
self.response_queue = response_queue
|
||||
self.config_values = config_values # e.g., {"collection": "customers"}
|
||||
# ...
|
||||
|
||||
async def invoke(self, **arguments):
|
||||
client = await self._get_or_create_client()
|
||||
response = await client.call(user, self.config_values, arguments)
|
||||
if isinstance(response, str):
|
||||
return response
|
||||
else:
|
||||
return json.dumps(response)
|
||||
```
|
||||
|
||||
## قرارات التصميم
|
||||
|
||||
### نموذج التكوين ثنائي الطبقات
|
||||
|
||||
تتبع خدمات الأدوات نموذجًا ثنائي الطبقات مشابهًا لأدوات MCP:
|
||||
|
||||
1. **خدمة الأداة**: تحدد واجهة خدمة Pulsar (الموضوع، ومعلمات التكوين المطلوبة).
|
||||
2. **الأداة**: تشير إلى خدمة أداة، وتوفر قيم التكوين، وتحدد وسائط LLM.
|
||||
|
||||
يسمح هذا الفصل بما يلي:
|
||||
يمكن لخدمة أداة واحدة أن تستخدمها أدوات متعددة بتكوينات مختلفة.
|
||||
تمييز واضح بين واجهة الخدمة وتكوين الأداة.
|
||||
إمكانية إعادة استخدام تعريفات الخدمة.
|
||||
|
||||
### تعيين الطلبات: تمرير مع الغلاف
|
||||
|
||||
الطلب إلى خدمة الأداة هو غلاف منظم يحتوي على:
|
||||
`user`: يتم تمريره من طلب الوكيل لخدمة العملاء المتعددة.
|
||||
قيم التكوين: من وصف الأداة (مثل `collection`).
|
||||
`arguments`: وسائط LLM، يتم تمريرها كقاموس.
|
||||
|
||||
يقوم مدير الوكيل بتحليل استجابة LLM إلى `act.arguments` كقاموس (`agent_manager.py:117-154`). يتم تضمين هذا القاموس في غلاف الطلب.
|
||||
|
||||
### معالجة المخططات: غير مُعَرَّفة الأنواع
|
||||
|
||||
تستخدم الطلبات والاستجابات قواميس غير مُعَرَّفة الأنواع. لا يوجد تحقق من صحة المخطط على مستوى الوكيل - خدمة الأداة مسؤولة عن التحقق من صحة مدخلاتها. يوفر هذا أقصى قدر من المرونة لتعريف خدمات جديدة.
|
||||
|
||||
### واجهة العميل: مواضيع Pulsar مباشرة
|
||||
|
||||
تستخدم خدمات الأدوات مواضيع Pulsar مباشرة دون الحاجة إلى تكوين التدفق. يحدد وصف خدمة الأداة أسماء قائمة الانتظار الكاملة:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "joke-service",
|
||||
"request-queue": "non-persistent://tg/request/joke",
|
||||
"response-queue": "non-persistent://tg/response/joke",
|
||||
"config-params": [...]
|
||||
}
|
||||
```
|
||||
|
||||
هذا يسمح باستضافة الخدمات في أي مساحة اسم.
|
||||
|
||||
### معالجة الأخطاء: الاصطلاح القياسي للأخطاء.
|
||||
|
||||
تتبع استجابات خدمات الأدوات الاصطلاح الحالي للمخطط مع حقل `error`:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Error:
|
||||
type: str = ""
|
||||
message: str = ""
|
||||
```
|
||||
|
||||
هيكل الاستجابة:
|
||||
النجاح: إذا كانت `error` تساوي `None`، تحتوي الاستجابة على النتيجة.
|
||||
الخطأ: يتم ملء `error` بـ `type` و `message`.
|
||||
|
||||
هذا يتوافق مع النمط المستخدم في مخططات الخدمة الحالية (مثل: `PromptResponse`، `QueryResponse`، `AgentResponse`).
|
||||
|
||||
### الارتباط بين الطلبات والاستجابات
|
||||
|
||||
يتم ربط الطلبات والاستجابات باستخدام `id` في خصائص رسائل Pulsar:
|
||||
|
||||
يتضمن الطلب `id` في الخصائص: `properties={"id": id}`.
|
||||
تتضمن الاستجابة (أو الاستجابات) نفس `id`: `properties={"id": id}`.
|
||||
|
||||
هذا يتبع النمط الحالي المستخدم في قاعدة التعليمات البرمجية بأكملها (مثل: `agent_service.py`، `llm_service.py`).
|
||||
|
||||
### دعم التدفق
|
||||
|
||||
يمكن لخدمات الأدوات إرجاع استجابات متدفقة:
|
||||
|
||||
رسائل استجابة متعددة بنفس `id` في الخصائص.
|
||||
تتضمن كل استجابة حقل `end_of_stream: bool`.
|
||||
تحتوي الاستجابة النهائية على `end_of_stream: True`.
|
||||
|
||||
هذا يتوافق مع النمط المستخدم في `AgentResponse` وخدمات التدفق الأخرى.
|
||||
|
||||
### معالجة الاستجابة: إرجاع سلسلة نصية
|
||||
|
||||
تتبع جميع الأدوات الموجودة نفس النمط: **استقبال الوسائط كقاموس، وإرجاع الملاحظة كسلسلة نصية**.
|
||||
|
||||
| الأداة | معالجة الاستجابة |
|
||||
|------|------------------|
|
||||
| `KnowledgeQueryImpl` | إرجاع `client.rag()` مباشرة (سلسلة نصية) |
|
||||
| `TextCompletionImpl` | إرجاع `client.question()` مباشرة (سلسلة نصية) |
|
||||
| `McpToolImpl` | إرجاع سلسلة نصية، أو `json.dumps(output)` إذا لم تكن سلسلة نصية |
|
||||
| `StructuredQueryImpl` | تنسيق النتيجة إلى سلسلة نصية |
|
||||
| `PromptImpl` | إرجاع `client.prompt()` مباشرة (سلسلة نصية) |
|
||||
|
||||
تتبع خدمات الأدوات نفس العقد:
|
||||
تقوم الخدمة بإرجاع استجابة سلسلة نصية (الملاحظة).
|
||||
إذا لم تكن الاستجابة سلسلة نصية، يتم تحويلها عبر `json.dumps()`.
|
||||
لا يلزم وجود تكوين استخراج في الوصف.
|
||||
|
||||
هذا يبقي الوصف بسيطًا ويضع المسؤولية على الخدمة لإرجاع استجابة نصية مناسبة للوكيل.
|
||||
|
||||
## دليل التكوين
|
||||
|
||||
لإضافة خدمة أداة جديدة، يلزم وجود عنصرين في التكوين:
|
||||
|
||||
### 1. تكوين خدمة الأداة
|
||||
|
||||
يتم تخزينها تحت مفتاح التكوين `tool-service`. تحدد قوائم انتظار Pulsar والمعلمات التكوين المتاحة.
|
||||
|
||||
| الحقل | مطلوب | الوصف |
|
||||
|-------|----------|-------------|
|
||||
| `id` | نعم | معرف فريد لخدمة الأداة |
|
||||
| `request-queue` | نعم | موضوع Pulsar الكامل للطلبات (مثل: `non-persistent://tg/request/joke`) |
|
||||
| `response-queue` | نعم | موضوع Pulsar الكامل للاستجابات (مثل: `non-persistent://tg/response/joke`) |
|
||||
| `config-params` | لا | مصفوفة من معلمات التكوين التي تقبلها الخدمة |
|
||||
|
||||
يمكن لكل معلمة تكوين تحديد:
|
||||
`name`: اسم المعلمة (مطلوب)
|
||||
`required`: ما إذا كان يجب توفير المعلمة بواسطة الأدوات (افتراضي: خطأ)
|
||||
|
||||
مثال:
|
||||
```json
|
||||
{
|
||||
"id": "joke-service",
|
||||
"request-queue": "non-persistent://tg/request/joke",
|
||||
"response-queue": "non-persistent://tg/response/joke",
|
||||
"config-params": [
|
||||
{"name": "style", "required": false}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. إعدادات الأداة
|
||||
|
||||
يتم تخزينها تحت مفتاح التكوين `tool`. تحدد أداة يمكن للوكيل استخدامها.
|
||||
|
||||
| الحقل | مطلوب | الوصف |
|
||||
|-------|----------|-------------|
|
||||
| `type` | نعم | يجب أن يكون `"tool-service"` |
|
||||
| `name` | نعم | اسم الأداة المعروضة لنظام LLM |
|
||||
| `description` | نعم | وصف لما تفعله الأداة (يُعرض لنظام LLM) |
|
||||
| `service` | نعم | معرف خدمة الأداة التي سيتم استدعاؤها |
|
||||
| `arguments` | لا | مصفوفة من تعريفات الوسائط لنظام LLM |
|
||||
| *(معلمات التكوين)* | يختلف | أي معلمات تكوين معرفة بواسطة الخدمة |
|
||||
|
||||
يمكن لكل وسيط تحديد:
|
||||
`name`: اسم الوسيط (مطلوب)
|
||||
`type`: نوع البيانات، على سبيل المثال، `"string"` (مطلوب)
|
||||
`description`: الوصف المعروض لنظام LLM (مطلوب)
|
||||
|
||||
مثال:
|
||||
```json
|
||||
{
|
||||
"type": "tool-service",
|
||||
"name": "tell-joke",
|
||||
"description": "Tell a joke on a given topic",
|
||||
"service": "joke-service",
|
||||
"style": "pun",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "topic",
|
||||
"type": "string",
|
||||
"description": "The topic for the joke (e.g., programming, animals, food)"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### تحميل الإعدادات
|
||||
|
||||
استخدم `tg-put-config-item` لتحميل الإعدادات:
|
||||
|
||||
```bash
|
||||
# Load tool-service config
|
||||
tg-put-config-item tool-service/joke-service < joke-service.json
|
||||
|
||||
# Load tool config
|
||||
tg-put-config-item tool/tell-joke < tell-joke.json
|
||||
```
|
||||
|
||||
يجب إعادة تشغيل الوكيل الإداري لاستيعاب التكوينات الجديدة.
|
||||
|
||||
## تفاصيل التنفيذ
|
||||
|
||||
### المخطط
|
||||
|
||||
أنواع الطلبات والاستجابات في `trustgraph-base/trustgraph/schema/services/tool_service.py`:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ToolServiceRequest:
|
||||
user: str = "" # User context for multi-tenancy
|
||||
config: str = "" # JSON-encoded config values from tool descriptor
|
||||
arguments: str = "" # JSON-encoded arguments from LLM
|
||||
|
||||
@dataclass
|
||||
class ToolServiceResponse:
|
||||
error: Error | None = None
|
||||
response: str = "" # String response (the observation)
|
||||
end_of_stream: bool = False
|
||||
```
|
||||
|
||||
### الخادم: خدمة DynamicToolService
|
||||
|
||||
الفئة الأساسية في `trustgraph-base/trustgraph/base/dynamic_tool_service.py`:
|
||||
|
||||
```python
|
||||
class DynamicToolService(AsyncProcessor):
|
||||
"""Base class for implementing tool services."""
|
||||
|
||||
def __init__(self, **params):
|
||||
topic = params.get("topic", default_topic)
|
||||
# Constructs topics: non-persistent://tg/request/{topic}, non-persistent://tg/response/{topic}
|
||||
# Sets up Consumer and Producer
|
||||
|
||||
async def invoke(self, user, config, arguments):
|
||||
"""Override this method to implement the tool's logic."""
|
||||
raise NotImplementedError()
|
||||
```
|
||||
|
||||
### جانب العميل: ToolServiceImpl
|
||||
|
||||
التنفيذ في `trustgraph-flow/trustgraph/agent/react/tools.py`:
|
||||
|
||||
```python
|
||||
class ToolServiceImpl:
|
||||
def __init__(self, context, request_queue, response_queue, config_values, arguments, processor):
|
||||
# Uses the provided queue paths directly
|
||||
# Creates ToolServiceClient on first use
|
||||
|
||||
async def invoke(self, **arguments):
|
||||
client = await self._get_or_create_client()
|
||||
response = await client.call(user, config_values, arguments)
|
||||
return response if isinstance(response, str) else json.dumps(response)
|
||||
```
|
||||
|
||||
### الملفات
|
||||
|
||||
| الملف | الغرض |
|
||||
|------|---------|
|
||||
| `trustgraph-base/trustgraph/schema/services/tool_service.py` | مخططات الطلبات والاستجابات |
|
||||
| `trustgraph-base/trustgraph/base/tool_service_client.py` | عميل لاستدعاء الخدمات |
|
||||
| `trustgraph-base/trustgraph/base/dynamic_tool_service.py` | الفئة الأساسية لتنفيذ الخدمة |
|
||||
| `trustgraph-flow/trustgraph/agent/react/tools.py` | فئة `ToolServiceImpl` |
|
||||
| `trustgraph-flow/trustgraph/agent/react/service.py` | تحميل التكوين |
|
||||
|
||||
### مثال: خدمة النكت
|
||||
|
||||
مثال لخدمة في `trustgraph-flow/trustgraph/tool_service/joke/`:
|
||||
|
||||
```python
|
||||
class Processor(DynamicToolService):
|
||||
async def invoke(self, user, config, arguments):
|
||||
style = config.get("style", "pun")
|
||||
topic = arguments.get("topic", "")
|
||||
joke = pick_joke(topic, style)
|
||||
return f"Hey {user}! Here's a {style} for you:\n\n{joke}"
|
||||
```
|
||||
|
||||
تكوين خدمة الأداة:
|
||||
```json
|
||||
{
|
||||
"id": "joke-service",
|
||||
"request-queue": "non-persistent://tg/request/joke",
|
||||
"response-queue": "non-persistent://tg/response/joke",
|
||||
"config-params": [{"name": "style", "required": false}]
|
||||
}
|
||||
```
|
||||
|
||||
إعدادات الأداة:
|
||||
```json
|
||||
{
|
||||
"type": "tool-service",
|
||||
"name": "tell-joke",
|
||||
"description": "Tell a joke on a given topic",
|
||||
"service": "joke-service",
|
||||
"style": "pun",
|
||||
"arguments": [
|
||||
{"name": "topic", "type": "string", "description": "The topic for the joke"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### التوافق مع الإصدارات السابقة
|
||||
|
||||
تظل أنواع الأدوات المدمجة الحالية تعمل دون تغيير.
|
||||
`tool-service` هو نوع أداة جديد بالإضافة إلى الأنواع الموجودة (`knowledge-query`، `mcp-tool`، إلخ).
|
||||
|
||||
## اعتبارات مستقبلية
|
||||
|
||||
### الخدمات ذات الإعلان الذاتي
|
||||
|
||||
يمكن أن تسمح ترقية مستقبلية للخدمات بنشر أوصافها الخاصة:
|
||||
|
||||
تنشر الخدمات إلى موضوع `tool-descriptors` معروف عند بدء التشغيل.
|
||||
يشترك الوكيل ويسجل الأدوات ديناميكيًا.
|
||||
يتيح ذلك إمكانية التوصيل والتشغيل الحقيقية دون تغييرات في التكوين.
|
||||
|
||||
هذا خارج نطاق التنفيذ الأولي.
|
||||
|
||||
## المراجع
|
||||
|
||||
التنفيذ الحالي للأداة: `trustgraph-flow/trustgraph/agent/react/tools.py`
|
||||
تسجيل الأداة: `trustgraph-flow/trustgraph/agent/react/service.py:105-214`
|
||||
مخططات الوكيل: `trustgraph-base/trustgraph/schema/services/agent.py`
|
||||
419
docs/tech-specs/ar/universal-decoder.ar.md
Normal file
419
docs/tech-specs/ar/universal-decoder.ar.md
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
---
|
||||
layout: default
|
||||
title: "جهاز فك ترميز المستندات الشامل"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# جهاز فك ترميز المستندات الشامل
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## العنوان
|
||||
|
||||
جهاز فك ترميز المستندات الشامل يعمل بواسطة `unstructured` — استيراد أي تنسيق مستند شائع
|
||||
من خلال خدمة واحدة مع تتبع كامل وتكامل مع أمين المكتبة، وتسجيل مواقع المصدر كبيانات وصفية لـ "رسم بياني للمعرفة" من أجل التتبع التام.
|
||||
|
||||
## المشكلة
|
||||
|
||||
يحتوي "TrustGraph" حاليًا على جهاز فك ترميز خاص بملفات PDF. دعم تنسيقات إضافية (DOCX, XLSX, HTML, Markdown، نص عادي، PPTX، إلخ) يتطلب
|
||||
إما كتابة جهاز فك ترميز جديد لكل تنسيق أو اعتماد مكتبة استخراج عالمية. لكل تنسيق هيكل مختلف — بعضها يعتمد على الصفحات، وبعضها لا — ويجب أن يسجل سلسلة التتبع أين أصل كل جزء من النص المستخرج في المستند الأصلي.
|
||||
|
||||
## الحل المقترح
|
||||
|
||||
### المكتبة: `unstructured`
|
||||
|
||||
استخدم `unstructured.partition.auto.partition()` التي تكتشف تلقائيًا التنسيق من نوع MIME أو امتداد الملف وتستخرج العناصر المنظمة (العنوان، النص السردي، الجدول، عنصر القائمة، إلخ). تحمل كل عنصر بيانات وصفية بما في ذلك:
|
||||
|
||||
- `page_number` (للتنسيقات القائمة على الصفحات مثل PDF، PPTX)
|
||||
- `element_id` (فريد لكل عنصر)
|
||||
- `coordinates` (مربع إحاطة لملفات PDF)
|
||||
- `text` (محتوى النص المستخرج)
|
||||
- `category` (نوع العنصر: العنوان، النص السردي، الجدول، إلخ.)
|
||||
|
||||
### أنواع العناصر
|
||||
|
||||
تستخرج `unstructured` أنواع العناصر من المستندات. كل عنصر لديه فئة و بيانات وصفية مرتبطة:
|
||||
|
||||
**عناصر النص:**
|
||||
- `Title` — عناوين الأقسام
|
||||
- `NarrativeText` — فقرات النص
|
||||
- `ListItem` — عناصر القوائم المرقمة/المسردة
|
||||
- `Header`, `Footer` — رؤوس/تذييلات الصفحات
|
||||
- `FigureCaption` — تسميات للرسومات/الصور
|
||||
- `Formula` — تعبيرات رياضية
|
||||
- `Address`, `EmailAddress` — معلومات الاتصال
|
||||
- `CodeSnippet` — كتل التعليمات البرمجية (من markdown)
|
||||
|
||||
**الجداول:**
|
||||
- `Table` — بيانات جدولية منظمة. توفر `unstructured` كلاً من
|
||||
`element.text` (نص عادي) و `element.metadata.text_as_html`
|
||||
(علامة HTML `<table` كاملة مع الصفوف والأعمدة والعناوين المحفوظة).
|
||||
بالنسبة للتنسيقات ذات الهيكل الجدول المحدد (DOCX, XLSX, HTML)، يكون الاستخراج موثوقًا للغاية. بالنسبة لملفات PDF، يعتمد اكتشاف الجداول على
|
||||
الاستراتيجية `hi_res` مع تحليل التخطيط.
|
||||
|
||||
**الصور:**
|
||||
- `Image` — صور مضمنة يتم اكتشافها من خلال تحليل التخطيط (يتطلب
|
||||
الاستراتيجية `hi_res`). مع `extract_image_block_to_payload=True`،
|
||||
ترجع بيانات الصورة كـ base64 في `element.metadata.image_base64`.
|
||||
النص المستخرج من الصورة متاح في `element.text`.
|
||||
|
||||
### معالجة الجداول
|
||||
|
||||
الجداول هي مخرج أساسي. عندما يواجه جهاز فك الترميز عنصر `Table`، فإنه يحافظ على هيكل HTML بدلاً من تسويته إلى نص عادي. هذا يوفر لمستخرج LLM (نموذج اللغة الكبير) إدخالًا أفضل بكثير لسحب المعرفة المنظمة من البيانات الجدولية.
|
||||
|
||||
يتم تجميع النص الخاص بالصفحة/القسم على النحو التالي:
|
||||
- عناصر النص: نص عادي، مدمج مع سطور جديدة
|
||||
- عناصر الجدول: علامة HTML للجدول من `text_as_html`، ومحاطة بـ `<table>` حتى يتمكن نموذج اللغة الكبيرة من التمييز بين الجداول والنص السردي.
|
||||
|
||||
على سبيل المثال، صفحة تحتوي على عنوان وفقرة وجدول تنتج:
|
||||
|
||||
```
|
||||
نظرة عامة مالية
|
||||
|
||||
ارتفعت الإيرادات بنسبة 15٪ على أساس سنوي مدفوعة باعتماد المؤسسات.
|
||||
|
||||
<table>
|
||||
<tr><th>الربع</th><th>الإيرادات</th><th>النمو</th></tr>
|
||||
<tr><td>Q1</td><td>$12M</td><td>12%</td></tr>
|
||||
<tr><td>Q2</td><td>$14M</td><td>17%</td></tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
هذا يحافظ على هيكل الجدول من خلال التقطيع وإلى مسار الاستخراج، حيث يمكن لنموذج اللغة الكبيرة استخراج العلاقات مباشرة من الخلايا المنظمة بدلاً من تخمين محاذاة الأعمدة من المسافات.
|
||||
|
||||
### معالجة الصور
|
||||
|
||||
تتم استخراج الصور وتخزينها في أمين المكتبة كأوراق فرعية مع `document_type="image"` ومعرف `urn:image:{uuid}`. إنها تحصل على ثلاثيات تتبع من النوع `tg:Image`، مرتبطة بصفحتها/قسمها الأصلية عبر `prov:wasDerivedFrom`. يتم تسجيل البيانات الوصفية للصورة (الإحداثيات والأبعاد و `element_id`) في التتبع.
|
||||
|
||||
**من المهم للغاية، لا يتم إخراج الصور كإخراج `TextDocument`.** يتم تخزينها فقط — ولا يتم إرسالها إلى وحدة تقسيم (chunker) أو أي مسار لمعالجة النصوص. هذا مقصود:
|
||||
|
||||
1. لا يوجد مسار لمعالجة الصور بعد (دمج نموذج الرؤية هو عمل مستقبلي)
|
||||
2. إرسال بيانات صورة base64 أو أجزاء من OCR إلى مسار استخراج النص سينتج عنه ثلاثيات KG (رسم بياني للمعرفة) غير صحيحة.
|
||||
|
||||
كما يتم استبعاد الصور من النص المجمع للصفحة/القسم — أي عناصر `Image` يتم تخطيها بصمت عند ربط عناصر النص لصفحة/قسم. يسجل سلسلة التتبع أن الصور موجودة وأين ظهرت في المستند، بحيث يمكن لنموذج معالجة صور مستقبلي التقاطها دون إعادة استيراد المستند.
|
||||
|
||||
#### عمل مستقبلي
|
||||
|
||||
- توجيه الكيانات `tg:Image` إلى نموذج رؤية للوصف أو تفسير المخططات أو استخراج بيانات الرسم البياني.
|
||||
- تخزين أوصاف الصور كمستندات نصية فرعية يتم إدخالها في مسار التقطيع/الاستخراج القياسي.
|
||||
- ربط المعرفة المستخرجة بالصور المصدر عبر التتبع.
|
||||
|
||||
### استراتيجيات الأقسام
|
||||
|
||||
بالنسبة للتنسيقات القائمة على الصفحات (PDF، PPTX، XLSX)، يتم تجميع العناصر دائمًا حسب الصفحة/الشريحة/الورقة أولاً. بالنسبة للتنسيقات غير القائمة على الصفحات (DOCX، HTML، Markdown، إلخ)، يحتاج جهاز فك الترميز إلى استراتيجية لتقسيم المستند إلى أقسام. هذا قابل للتكوين في وقت التشغيل عبر `--section-strategy`.
|
||||
|
||||
تعتبر كل استراتيجية وظيفة تجميع على قائمة `unstructured` للعناصر. الإخراج هو قائمة بمجموعات العناصر؛ يظل بقية المسار (تجميع النص وتخزين أمين المكتبة والتتبع وإصدار `TextDocument`) متطابقًا بغض النظر عن الاستراتيجية.
|
||||
|
||||
#### `whole-document` (افتراضي)
|
||||
|
||||
إخراج المستند بأكمله كقسم واحد. اسمح لوحدة تقسيم المستند (chunker) بمعالجة جميع عمليات التقسيم.
|
||||
|
||||
- أبسط نهج، خط أساس جيد
|
||||
- قد ينتج عنه `TextDocument` كبير جدًا للملفات الكبيرة، ولكن وحدة التقسيم تتعامل مع ذلك
|
||||
- الأفضل عندما تريد أقصى قدر من السياق لكل قسم
|
||||
|
||||
#### `heading`
|
||||
|
||||
التقسيم عند عناصر العناوين (`Title`). كل قسم هو عنوان وجميع المحتويات حتى العنوان التالي من نفس المستوى أو أعلى. تخلق العناوين المتداخلة أقسامًا متداخلة.
|
||||
|
||||
- ينتج وحدات متماسكة من الناحية الموضوعية
|
||||
- يعمل بشكل جيد مع المستندات المنظمة (التقارير والكتيبات والمواصفات)
|
||||
- يوفر لـ LLM الاستخراج سياق العنوان جنبًا إلى جنب مع المحتوى
|
||||
- يرجع إلى `whole-document` إذا لم يتم العثور على أي عناوين
|
||||
|
||||
#### `element-type`
|
||||
|
||||
التقسيم عند حدوث تغيير كبير في نوع العنصر — على وجه التحديد، ابدأ قسمًا جديدًا في الانتقالات بين النص السردي والجداول. تظل العناصر المتتالية من نفس الفئة العامة (نص، نص، نص أو جدول، جدول) مجمعة.
|
||||
|
||||
- يحافظ على الجداول كأقسام منفصلة
|
||||
- جيد للمستندات ذات المحتوى المختلط (التقارير مع الجداول البيانية)
|
||||
- يتم إعطاء الجداول اهتمام استخراج مخصص
|
||||
|
||||
#### `count`
|
||||
|
||||
تجميع عدد ثابت من العناصر لكل قسم. قابلة للتكوين عبر `--section-element-count` (افتراضي: 20).
|
||||
|
||||
- بسيط وقابل للتنبؤ
|
||||
- لا يحترم هيكل المستند
|
||||
- مفيد كحل احتياطي أو للتجريب
|
||||
|
||||
#### `size`
|
||||
|
||||
تجميع العناصر حتى يتم الوصول إلى حد الأحرف، ثم ابدأ قسمًا جديدًا. يحترم حدود العناصر — لا يقسم في منتصف العنصر. قابلة للتكوين عبر `--section-max-size` (افتراضي: 4000 حرف).
|
||||
|
||||
- ينتج أقسامًا ذات أحجام تقريبًا موحدة
|
||||
- يحترم حدود العناصر (على عكس وحدة التقسيم السفلية)
|
||||
- حل وسط جيد بين التحكم في الهيكل والحجم
|
||||
- إذا تجاوز عنصر واحد الحد، فإنه يصبح قسمه الخاص
|
||||
|
||||
#### تفاعل مع التنسيق القائم على الصفحة
|
||||
|
||||
بالنسبة للتنسيقات القائمة على الصفحات، يكون تجميع الصفحة هو الأولوية دائمًا. يمكن أن تنطبق استراتيجيات القسم بشكل اختياري *داخل* صفحة إذا كانت كبيرة جدًا (على سبيل المثال، صفحة PDF تحتوي على جدول ضخم)، ويتم التحكم في ذلك بواسطة
|
||||
`--section-within-pages` (افتراضي: false). عندما يكون `false`، تكون كل صفحة دائمًا قسمًا واحدًا بغض النظر عن الحجم.
|
||||
|
||||
### اكتشاف التنسيق
|
||||
|
||||
يحتاج جهاز فك الترميز إلى معرفة نوع MIME الخاص بالمستند لتمريره إلى `partition()` الخاصة بـ `unstructured`. هناك مساران:
|
||||
|
||||
- **مسار أمين المكتبة** (`document_id` مضبوط): استرداد بيانات وصفية المستند من أمين المكتبة أولاً — وهذا يعطينا `kind` (نوع MIME)
|
||||
الذي تم تسجيله في وقت الرفع. ثم استرداد محتوى المستند.
|
||||
مكالمتان لأمين المكتبة، ولكن استرداد البيانات الوصفية خفيف الوزن.
|
||||
- **المسار المضمن** (التوافق مع الإصدارات السابقة، `data` مضبوط): لا توجد بيانات وصفية
|
||||
متاحة على الرسالة. استخدم `python-magic` لاكتشاف التنسيق
|
||||
من بايت المحتوى كحل احتياطي.
|
||||
|
||||
لا توجد تغييرات ضرورية في مخطط `Document` — يقوم أمين المكتبة بالفعل بتخزين نوع MIME.
|
||||
|
||||
### الهندسة المعمارية
|
||||
|
||||
خدمة `universal-decoder` واحدة تقوم بما يلي:
|
||||
|
||||
1. تتلقى رسالة `Document` (مضمنة أو عبر مرجع أمين المكتبة)
|
||||
2. إذا كان مسار أمين المكتبة: استرداد بيانات وصفية المستند (الحصول على نوع MIME)، ثم
|
||||
استرداد المحتوى. إذا كان المسار المضمن: اكتشاف التنسيق من بايت المحتوى.
|
||||
3. تستدعي `partition()` لاستخراج العناصر
|
||||
4. تجميع العناصر: حسب الصفحة للتنسيقات القائمة على الصفحات، حسب استراتيجية القسم المحددة للتنسيقات غير القائمة على الصفحات
|
||||
5. لكل صفحة/قسم:
|
||||
- توليد معرف `urn:page:{uuid}` أو `urn:section:{uuid}`
|
||||
- تجميع نص الصفحة: النص العادي، والجداول كـ HTML،
|
||||
الصور يتم تخطيها
|
||||
- حساب إزاحة الأحرف لكل عنصر داخل نص الصفحة
|
||||
- حفظ في أمين المكتبة كوثيقة فرعية
|
||||
- حساب ثلاثيات تتبع مع بيانات وصفية موضعية
|
||||
- إرسال `TextDocument` إلى وحدة تقسيم (chunker)
|
||||
6. لكل عنصر صورة:
|
||||
- توليد معرف `urn:image:{uuid}`
|
||||
- حفظ بيانات الصورة في أمين المكتبة كوثيقة فرعية
|
||||
- حساب ثلاثيات تتبع (مخزنة فقط، ولا يتم إرسالها إلى وحدة تقسيم)
|
||||
|
||||
### معالجة التنسيقات
|
||||
|
||||
| التنسيق | نوع MIME | قائم على الصفحات | ملاحظات |
|
||||
|---|---|---|---|
|
||||
| PDF | application/pdf | نعم | تجميع حسب الصفحة |
|
||||
| DOCX | application/vnd.openxmlformats... | لا | يستخدم استراتيجية القسم |
|
||||
| PPTX | application/vnd.openxmlformats... | نعم | تجميع حسب الشريحة |
|
||||
| XLSX/XLS | application/vnd.openxmlformats... | نعم | تجميع حسب ورقة العمل |
|
||||
| HTML | text/html | لا | يستخدم استراتيجية القسم |
|
||||
| Markdown | text/markdown | لا | يستخدم استراتيجية القسم |
|
||||
| Plain | text/plain | لا | يستخدم استراتيجية القسم |
|
||||
| CSV | text/csv | لا | يستخدم استراتيجية القسم |
|
||||
| RST | text/x-rst | لا | يستخدم استراتيجية القسم |
|
||||
| RTF | application/rtf | لا | يستخدم استراتيجية القسم |
|
||||
| ODT | application/vnd.oasis... | لا | يستخدم استراتيجية القسم |
|
||||
| TSV | text/tab-separated-values | لا | يستخدم استراتيجية القسم |
|
||||
|
||||
### بيانات التتبع
|
||||
|
||||
تسجل كل صفحة/قسم كيان بيانات وصفية موضعية على شكل ثلاثيات تتبع في الرسم البياني المصدر (`GRAPH_SOURCE`)، مما يتيح التتبع التام من ثلاثيات KG (رسم بياني للمعرفة) إلى مواضع المستند المصدر.
|
||||
|
||||
#### الحقول الحالية (موجودة بالفعل في `provenance/triples.py`)
|
||||
|
||||
- `page_number` — رقم الصفحة/الورقة/الشريحة (مرقم 1، فقط للتنسيقات القائمة على الصفحات)
|
||||
- `char_offset` — إزاحة الحرف لهذه الصفحة/القسم داخل نص المستند بالكامل
|
||||
- `char_length` — طول الحرف لنص هذه الصفحة/القسم
|
||||
|
||||
#### حقول جديدة (قم بتوسيع `provenance/triples.py`)
|
||||
|
||||
- `mime_type` — تنسيق المستند الأصلي (على سبيل المثال، `application/pdf`)
|
||||
- `element_types` — قائمة `unstructured` لفئات العناصر الموجودة في هذه الصفحة/القسم (على سبيل المثال، "العنوان،النص السردي،الجدول")
|
||||
- `table_count` — عدد الجداول في هذه الصفحة/القسم
|
||||
- `image_count` — عدد الصور في هذه الصفحة/القسم
|
||||
|
||||
يتطلب هذا بناء جملة جديد لأسماء النطاقات:
|
||||
|
||||
```
|
||||
TG_SECTION_TYPE = "https://trustgraph.ai/ns/Section"
|
||||
TG_IMAGE_TYPE = "https://trustgraph.ai/ns/Image"
|
||||
TG_ELEMENT_TYPES = "https://trustgraph.ai/ns/elementTypes"
|
||||
TG_TABLE_COUNT = "https://trustgraph.ai/ns/tableCount"
|
||||
TG_IMAGE_COUNT = "https://trustgraph.ai/ns/imageCount"
|
||||
```
|
||||
|
||||
مخطط URN للصورة: `urn:image:{uuid}`
|
||||
|
||||
(`TG_MIME_TYPE` موجود بالفعل.)
|
||||
|
||||
#### نوع الكيان الجديد
|
||||
|
||||
بالنسبة للتنسيقات غير القائمة على الصفحات (DOCX، HTML، Markdown، إلخ) حيث يقوم جهاز فك الترميز بإخراج المستند بأكمله كقسم واحد بدلاً من التقسيم حسب الصفحة، يحصل الكيان على نوع جديد:
|
||||
|
||||
```
|
||||
TG_SECTION_TYPE = "https://trustgraph.ai/ns/Section"
|
||||
```
|
||||
|
||||
هذا يميز الأقسام عن الصفحات عند الاستعلام عن التتبع:
|
||||
|
||||
| الكيان | النوع | متى يتم استخدامه |
|
||||
|---|---|---|
|
||||
| Document | `tg:Document` | الملف الذي تم رفعه أصلاً |
|
||||
| Page | `tg:Page` | تنسيقات قائمة على الصفحات (PDF، PPTX، XLSX) |
|
||||
| Section | `tg:Section` | تنسيقات غير قائمة على الصفحات (DOCX، HTML، MD، إلخ) |
|
||||
| Image | `tg:Image` | صور مضمنة (مخزنة، وغير معالجة) |
|
||||
| Chunk | `tg:Chunk` | إخراج وحدة تقسيم المستند |
|
||||
| Subgraph | `tg:Subgraph` | إخراج KG |
|
||||
|
||||
يتم تعيين النوع بواسطة جهاز فك الترميز بناءً على ما إذا كان يقوم بتجميع حسب الصفحة أم أنه يصدر قسمًا كاملاً للمستند. تكتسب `provenance/triples.py` معلمة اختيارية `section` — عندما تكون `true`، يتم تصنيف الكيان على أنه `tg:Section` بدلاً من `tg:Page`.
|
||||
|
||||
#### سلسلة التتبع الكاملة
|
||||
|
||||
```
|
||||
ثلاثية KG
|
||||
→ subgraph (تتبع الاستخراج)
|
||||
→ chunk (char_offset، char_length داخل الصفحة)
|
||||
→ page/section (page_number، char_offset، char_length داخل المستند، mime_type، element_types)
|
||||
→ document (الملف الأصلي في أمين المكتبة)
|
||||
```
|
||||
|
||||
كل رابط هو مجموعة من الثلاثيات في الرسم البياني المسمى `GRAPH_SOURCE`.
|
||||
|
||||
### تكوين الخدمة
|
||||
|
||||
وسيطات سطر الأوامر:
|
||||
|
||||
```
|
||||
--strategy استراتيجية التقسيم: auto, hi_res, fast (افتراضي: auto)
|
||||
--languages قائمة مفصولة بفواصل برموز لغة OCR (افتراضي: eng)
|
||||
--section-strategy استراتيجية تجميع القسم: whole-document, heading, element-type,
|
||||
count, size (افتراضي: whole-document)
|
||||
--section-element-count عدد العناصر لكل قسم (افتراضي: 20)
|
||||
--section-max-size الحد الأقصى لحجم القسم (بالأحرف) (افتراضي: 4000)
|
||||
```
|
||||
|
||||
### التنفيذ
|
||||
|
||||
خدمة `universal-decoder` واحدة تقوم بما يلي:
|
||||
|
||||
1. تتلقى رسالة `Document` (مضمنة أو عبر مرجع أمين المكتبة)
|
||||
2. إذا كان مسار أمين المكتبة: استرداد بيانات وصفية المستند (الحصول على نوع MIME)، ثم
|
||||
استرداد المحتوى. إذا كان المسار المضمن: اكتشاف التنسيق من بايت المحتوى.
|
||||
3. تستدعي `partition()` لاستخراج العناصر
|
||||
4. تجميع العناصر: حسب الصفحة للتنسيقات القائمة على الصفحات، حسب استراتيجية القسم المحددة للتنسيقات غير القائمة على الصفحات
|
||||
5. لكل صفحة/قسم:
|
||||
- توليد معرف `urn:page:{uuid}` أو `urn:section:{uuid}`
|
||||
- تجميع نص الصفحة: النص العادي، والجداول كـ HTML،
|
||||
الصور يتم تخطيها
|
||||
- حساب إزاحة الأحرف لكل عنصر داخل نص الصفحة
|
||||
- حفظ في أمين المكتبة كوثيقة فرعية
|
||||
- حساب ثلاثيات تتبع مع بيانات وصفية موضعية
|
||||
- إرسال `TextDocument` إلى وحدة تقسيم (chunker)
|
||||
6. لكل عنصر صورة:
|
||||
- توليد معرف `urn:image:{uuid}`
|
||||
- حفظ بيانات الصورة في أمين المكتبة كوثيقة فرعية
|
||||
- حساب ثلاثيات تتبع (مخزنة فقط، ولا يتم إرسالها إلى وحدة تقسيم)
|
||||
|
||||
### معالجة التنسيقات
|
||||
|
||||
| التنسيق | نوع MIME | قائم على الصفحات | ملاحظات |
|
||||
|---|---|---|---|
|
||||
| PDF | application/pdf | نعم | تجميع حسب الصفحة |
|
||||
| DOCX | application/vnd.openxmlformats... | لا | يستخدم استراتيجية القسم |
|
||||
| PPTX | application/vnd.openxmlformats... | نعم | تجميع حسب الشريحة |
|
||||
| XLSX/XLS | application/vnd.openxmlformats... | نعم | تجميع حسب ورقة العمل |
|
||||
| HTML | text/html | لا | يستخدم استراتيجية القسم |
|
||||
| Markdown | text/markdown | لا | يستخدم استراتيجية القسم |
|
||||
| Plain | text/plain | لا | يستخدم استراتيجية القسم |
|
||||
| CSV | text/csv | لا | يستخدم استراتيجية القسم |
|
||||
| RST | text/x-rst | لا | يستخدم استراتيجية القسم |
|
||||
| RTF | application/rtf | لا | يستخدم استراتيجية القسم |
|
||||
| ODT | application/vnd.oasis... | لا | يستخدم استراتيجية القسم |
|
||||
| TSV | text/tab-separated-values | لا | يستخدم استراتيجية القسم |
|
||||
|
||||
### بيانات التتبع
|
||||
|
||||
تسجل كل صفحة/قسم كيان بيانات وصفية موضعية على شكل ثلاثيات تتبع في الرسم البياني المصدر (`GRAPH_SOURCE`)، مما يتيح التتبع التام من ثلاثيات KG (رسم بياني للمعرفة) إلى مواضع المستند المصدر.
|
||||
|
||||
#### الحقول الحالية (موجودة بالفعل في `provenance/triples.py`)
|
||||
|
||||
- `page_number` — رقم الصفحة/الورقة/الشريحة (مرقم 1، فقط للتنسيقات القائمة على الصفحات)
|
||||
- `char_offset` — إزاحة الحرف لهذه الصفحة/القسم داخل نص المستند بالكامل
|
||||
- `char_length` — طول الحرف لنص هذه الصفحة/القسم
|
||||
|
||||
#### حقول جديدة (قم بتوسيع `provenance/triples.py`)
|
||||
|
||||
- `mime_type` — تنسيق المستند الأصلي (على سبيل المثال، `application/pdf`)
|
||||
- `element_types` — قائمة `unstructured` لفئات العناصر الموجودة في هذه الصفحة/القسم (على سبيل المثال، "العنوان،النص السردي،الجدول")
|
||||
- `table_count` — عدد الجداول في هذه الصفحة/القسم
|
||||
- `image_count` — عدد الصور في هذه الصفحة/القسم
|
||||
|
||||
يتطلب هذا بناء جملة جديد لأسماء النطاقات:
|
||||
|
||||
```
|
||||
TG_SECTION_TYPE = "https://trustgraph.ai/ns/Section"
|
||||
TG_IMAGE_TYPE = "https://trustgraph.ai/ns/Image"
|
||||
TG_ELEMENT_TYPES = "https://trustgraph.ai/ns/elementTypes"
|
||||
TG_TABLE_COUNT = "https://trustgraph.ai/ns/tableCount"
|
||||
TG_IMAGE_COUNT = "https://trustgraph.ai/ns/imageCount"
|
||||
```
|
||||
|
||||
مخطط URN للصورة: `urn:image:{uuid}`
|
||||
|
||||
(`TG_MIME_TYPE` موجود بالفعل.)
|
||||
|
||||
#### نوع الكيان الجديد
|
||||
|
||||
بالنسبة للتنسيقات غير القائمة على الصفحات (DOCX، HTML، Markdown، إلخ) حيث يقوم جهاز فك الترميز بإخراج المستند بأكمله كقسم واحد بدلاً من التقسيم حسب الصفحة، يحصل الكيان على نوع جديد:
|
||||
|
||||
```
|
||||
TG_SECTION_TYPE = "https://trustgraph.ai/ns/Section"
|
||||
```
|
||||
|
||||
هذا يميز الأقسام عن الصفحات عند الاستعلام عن التتبع:
|
||||
|
||||
| الكيان | النوع | متى يتم استخدامه |
|
||||
|---|---|---|
|
||||
| Document | `tg:Document` | الملف الذي تم رفعه أصلاً |
|
||||
| Page | `tg:Page` | تنسيقات قائمة على الصفحات (PDF، PPTX، XLSX) |
|
||||
| Section | `tg:Section` | تنسيقات غير قائمة على الصفحات (DOCX، HTML، MD، إلخ) |
|
||||
| Image | `tg:Image` | صور مضمنة (مخزنة، وغير معالجة) |
|
||||
| Chunk | `tg:Chunk` | إخراج وحدة تقسيم المستند |
|
||||
| Subgraph | `tg:Subgraph` | إخراج KG |
|
||||
|
||||
يتم تعيين النوع بواسطة جهاز فك الترميز بناءً على ما إذا كان يقوم بتجميع حسب الصفحة أم أنه يصدر قسمًا كاملاً للمستند. تكتسب `provenance/triples.py` معلمة اختيارية `section` — عندما تكون `true`، يتم تصنيف الكيان على أنه `tg:Section` بدلاً من `tg:Page`.
|
||||
|
||||
#### سلسلة التتبع الكاملة
|
||||
|
||||
```
|
||||
ثلاثية KG
|
||||
→ subgraph (تتبع الاستخراج)
|
||||
→ chunk (char_offset، char_length داخل الصفحة)
|
||||
→ page/section (page_number، char_offset، char_length داخل المستند، mime_type، element_types)
|
||||
→ document (الملف الأصلي في أمين المكتبة)
|
||||
```
|
||||
|
||||
كل رابط هو مجموعة من الثلاثيات في الرسم البياني المسمى `GRAPH_SOURCE`.
|
||||
|
||||
### التثبيت
|
||||
|
||||
تأكد من أن لديك Python 3.6+ مثبتًا.
|
||||
|
||||
```bash
|
||||
pip install unstructured
|
||||
```
|
||||
|
||||
### الاستخدام
|
||||
|
||||
```python
|
||||
from unstructured.partition.auto import partition
|
||||
|
||||
# مثال على ملف PDF
|
||||
pdf = partition(filename="path/to/your/document.pdf")
|
||||
|
||||
# مثال على ملف HTML
|
||||
html = partition(filename="path/to/your/document.html")
|
||||
```
|
||||
|
||||
سيقوم هذا بتقسيم المستند إلى عناصر مثل العناوين والنصوص والجداول والصور. يمكنك بعد ذلك معالجة هذه العناصر بشكل منفصل.
|
||||
|
||||
### الاعتبارات
|
||||
|
||||
- **الأداء:** قد يكون تقسيم المستندات الكبيرة أمرًا مكلفًا من الناحية الحسابية. ضع في اعتبارك استخدام التخزين المؤقت أو المعالجة المتوازية للمستندات الكبيرة جدًا.
|
||||
- **الدقة:** دقة التقسيم تعتمد على تنسيق المستند. قد تتطلب بعض المستندات معالجة خاصة للحصول على أفضل النتائج.
|
||||
|
||||
### المساهمة
|
||||
|
||||
إذا كنت ترغب في المساهمة في `unstructured`، فيرجى إرسال طلب سحب. نحن نقبل المساهمات من جميع أنواع.
|
||||
|
||||
### الترخيص
|
||||
|
||||
`unstructured` مرخصة بموجب رخصة Apache 2.0.
|
||||
307
docs/tech-specs/ar/vector-store-lifecycle.ar.md
Normal file
307
docs/tech-specs/ar/vector-store-lifecycle.ar.md
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
---
|
||||
layout: default
|
||||
title: "إدارة دورة حياة مستودع المتجهات"
|
||||
parent: "Arabic (Beta)"
|
||||
---
|
||||
|
||||
# إدارة دورة حياة مستودع المتجهات
|
||||
|
||||
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
يصف هذا المستند كيفية إدارة TrustGraph لمجموعات مستودعات المتجهات عبر تطبيقات خلفية مختلفة (Qdrant، Pinecone، Milvus). يعالج التصميم تحدي دعم التضمينات بأبعاد مختلفة دون ترميز قيم الأبعاد بشكل ثابت.
|
||||
|
||||
## بيان المشكلة
|
||||
|
||||
تتطلب مستودعات المتجهات تحديد بُعد التضمين عند إنشاء المجموعات/الفهارس. ومع ذلك:
|
||||
تنتج نماذج التضمين المختلفة أبعادًا مختلفة (مثل 384، 768، 1536)
|
||||
لا يتم معرفة البُعد حتى يتم إنشاء أول تضمين
|
||||
قد تتلقى مجموعة TrustGraph واحدة تضمينات من نماذج متعددة
|
||||
يؤدي ترميز بُعد (مثل 384) إلى حدوث أعطال مع أحجام تضمين أخرى
|
||||
|
||||
## مبادئ التصميم
|
||||
|
||||
1. **الإنشاء الكسول (Lazy Creation):** يتم إنشاء المجموعات عند الطلب أثناء الكتابة الأولى، وليس أثناء عمليات إدارة المجموعة.
|
||||
2. **تسمية قائمة على البُعد (Dimension-Based Naming):** تتضمن أسماء المجموعات بُعد التضمين كلاحقة.
|
||||
3. **التدهور السلس (Graceful Degradation):** تُرجع الاستعلامات التي تستهدف مجموعات غير موجودة نتائج فارغة، وليس أخطاء.
|
||||
4. **دعم متعدد الأبعاد (Multi-Dimension Support):** يمكن أن تحتوي مجموعة منطقية واحدة على مجموعات فعلية متعددة (واحدة لكل بُعد).
|
||||
|
||||
## البنية
|
||||
|
||||
### اصطلاح تسمية المجموعة
|
||||
|
||||
تستخدم مجموعات مستودعات المتجهات لاحقات الأبعاد لدعم أحجام تضمين متعددة:
|
||||
|
||||
**تضمينات المستندات:**
|
||||
Qdrant: `d_{user}_{collection}_{dimension}`
|
||||
Pinecone: `d-{user}-{collection}-{dimension}`
|
||||
Milvus: `doc_{user}_{collection}_{dimension}`
|
||||
|
||||
**تضمينات الرسم البياني:**
|
||||
Qdrant: `t_{user}_{collection}_{dimension}`
|
||||
Pinecone: `t-{user}-{collection}-{dimension}`
|
||||
Milvus: `entity_{user}_{collection}_{dimension}`
|
||||
|
||||
أمثلة:
|
||||
`d_alice_papers_384` - مجموعة أوراق أليس مع تضمينات ذات أبعاد 384.
|
||||
`d_alice_papers_768` - نفس المجموعة المنطقية مع تضمينات ذات أبعاد 768.
|
||||
`t_bob_knowledge_1536` - رسم بياني معرفة بوب مع تضمينات ذات أبعاد 1536.
|
||||
|
||||
### مراحل دورة الحياة
|
||||
|
||||
#### 1. طلب إنشاء المجموعة
|
||||
|
||||
**تدفق الطلب:**
|
||||
```
|
||||
User/System → Librarian → Storage Management Topic → Vector Stores
|
||||
```
|
||||
|
||||
**السلوك:**
|
||||
يقوم أمين المكتبة ببث طلبات `create-collection` إلى جميع أنظمة التخزين الخلفية.
|
||||
تقوم معالجات مخازن المتجهات بالاعتراف بالطلب ولكن **لا تقوم بإنشاء مجموعات فعلية**.
|
||||
يتم إرجاع الاستجابة على الفور مع الإشارة إلى النجاح.
|
||||
يتم تأجيل إنشاء المجموعة الفعلي حتى أول عملية كتابة.
|
||||
|
||||
**السبب:**
|
||||
الأبعاد غير معروفة في وقت الإنشاء.
|
||||
يتجنب إنشاء مجموعات بأبعاد خاطئة.
|
||||
يبسط منطق إدارة المجموعات.
|
||||
|
||||
#### 2. عمليات الكتابة (الإنشاء المؤجل)
|
||||
|
||||
**تدفق الكتابة:**
|
||||
```
|
||||
Data → Storage Processor → Check Collection → Create if Needed → Insert
|
||||
```
|
||||
|
||||
**السلوك:**
|
||||
1. استخراج بُعد التضمين من المتجه: `dim = len(vector)`
|
||||
2. إنشاء اسم المجموعة مع لاحقة البُعد
|
||||
3. التحقق مما إذا كانت المجموعة موجودة بهذا البُعد المحدد
|
||||
4. إذا لم تكن موجودة:
|
||||
إنشاء مجموعة بالبُعد الصحيح
|
||||
تسجيل: `"Lazily creating collection {name} with dimension {dim}"`
|
||||
5. إدراج التضمين في المجموعة الخاصة بالبُعد
|
||||
|
||||
**سيناريو مثال:**
|
||||
```
|
||||
1. User creates collection "papers"
|
||||
→ No physical collections created yet
|
||||
|
||||
2. First document with 384-dim embedding arrives
|
||||
→ Creates d_user_papers_384
|
||||
→ Inserts data
|
||||
|
||||
3. Second document with 768-dim embedding arrives
|
||||
→ Creates d_user_papers_768
|
||||
→ Inserts data
|
||||
|
||||
Result: Two physical collections for one logical collection
|
||||
```
|
||||
|
||||
#### 3. عمليات الاستعلام
|
||||
|
||||
**تدفق الاستعلام:**
|
||||
```
|
||||
Query Vector → Determine Dimension → Check Collection → Search or Return Empty
|
||||
```
|
||||
|
||||
**السلوك:**
|
||||
1. استخراج البُعد من متجه الاستعلام: `dim = len(vector)`
|
||||
2. إنشاء اسم المجموعة مع لاحقة البُعد
|
||||
3. التحقق مما إذا كانت المجموعة موجودة
|
||||
4. إذا كانت موجودة:
|
||||
إجراء بحث عن التشابه
|
||||
إرجاع النتائج
|
||||
5. إذا لم تكن موجودة:
|
||||
تسجيل: `"Collection {name} does not exist, returning empty results"`
|
||||
إرجاع قائمة فارغة (دون إثارة أي خطأ)
|
||||
|
||||
**أبعاد متعددة في نفس الاستعلام:**
|
||||
إذا كان الاستعلام يحتوي على متجهات بأبعاد مختلفة
|
||||
تستعلم كل بُعد عن المجموعة المقابلة له
|
||||
يتم تجميع النتائج
|
||||
يتم تخطي المجموعات المفقودة (ولا يتم التعامل معها كأخطاء)
|
||||
|
||||
**السبب:**
|
||||
الاستعلام عن مجموعة فارغة هو حالة استخدام صالحة
|
||||
إرجاع نتائج فارغة هو أمر منطقي
|
||||
يتجنب الأخطاء أثناء بدء تشغيل النظام أو قبل استيعاب البيانات
|
||||
|
||||
#### 4. حذف المجموعة
|
||||
|
||||
**عملية الحذف:**
|
||||
```
|
||||
Delete Request → List All Collections → Filter by Prefix → Delete All Matches
|
||||
```
|
||||
|
||||
**السلوك:**
|
||||
1. إنشاء نمط البادئة: `d_{user}_{collection}_` (لاحظ الشرطة السفلية في النهاية)
|
||||
2. سرد جميع المجموعات في مخزن المتجهات.
|
||||
3. تصفية المجموعات التي تتطابق مع البادئة.
|
||||
4. حذف جميع المجموعات المتطابقة.
|
||||
5. تسجيل كل عملية حذف: `"Deleted collection {name}"`
|
||||
6. سجل ملخص: `"Deleted {count} collection(s) for {user}/{collection}"`
|
||||
|
||||
**مثال:**
|
||||
```
|
||||
Collections in store:
|
||||
- d_alice_papers_384
|
||||
- d_alice_papers_768
|
||||
- d_alice_reports_384
|
||||
- d_bob_papers_384
|
||||
|
||||
Delete "papers" for alice:
|
||||
→ Deletes: d_alice_papers_384, d_alice_papers_768
|
||||
→ Keeps: d_alice_reports_384, d_bob_papers_384
|
||||
```
|
||||
|
||||
**الأساس المنطقي:**
|
||||
يضمن التنظيف الكامل لجميع المتغيرات الأبعاد.
|
||||
يمنع مطابقة الأنماط الحذف العرضي للمجموعات غير المرتبطة.
|
||||
عملية ذرية من وجهة نظر المستخدم (يتم حذف جميع الأبعاد معًا).
|
||||
|
||||
## الخصائص السلوكية
|
||||
|
||||
### العمليات العادية
|
||||
|
||||
**إنشاء المجموعة:**
|
||||
✓ يُرجع النجاح على الفور.
|
||||
✓ لا يتم تخصيص مساحة تخزين فعلية.
|
||||
✓ عملية سريعة (لا يوجد إدخال/إخراج خلفي).
|
||||
|
||||
**الكتابة الأولى:**
|
||||
✓ ينشئ مجموعة بالبعد الصحيح.
|
||||
✓ أبطأ قليلاً بسبب تكلفة إنشاء المجموعة.
|
||||
✓ عمليات الكتابة اللاحقة لنفس البعد سريعة.
|
||||
|
||||
**الاستعلامات قبل أي عمليات كتابة:**
|
||||
✓ تُرجع نتائج فارغة.
|
||||
✓ لا توجد أخطاء أو استثناءات.
|
||||
✓ يظل النظام مستقرًا.
|
||||
|
||||
**عمليات كتابة الأبعاد المختلطة:**
|
||||
✓ ينشئ تلقائيًا مجموعات منفصلة لكل بُعد.
|
||||
✓ يتم عزل كل بُعد في مجموعته الخاصة.
|
||||
✓ لا توجد تعارضات في الأبعاد أو أخطاء في المخطط.
|
||||
|
||||
**حذف المجموعة:**
|
||||
✓ يزيل جميع متغيرات الأبعاد.
|
||||
✓ تنظيف كامل.
|
||||
✓ لا توجد مجموعات يتيمة.
|
||||
|
||||
### الحالات الخاصة
|
||||
|
||||
**نماذج تضمين متعددة:**
|
||||
```
|
||||
Scenario: User switches from model A (384-dim) to model B (768-dim)
|
||||
Behavior:
|
||||
- Both dimensions coexist in separate collections
|
||||
- Old data (384-dim) remains queryable with 384-dim vectors
|
||||
- New data (768-dim) queryable with 768-dim vectors
|
||||
- Cross-dimension queries return results only for matching dimension
|
||||
```
|
||||
|
||||
**الكتابات الأولية المتزامنة:**
|
||||
```
|
||||
Scenario: Multiple processes write to same collection simultaneously
|
||||
Behavior:
|
||||
- Each process checks for existence before creating
|
||||
- Most vector stores handle concurrent creation gracefully
|
||||
- If race condition occurs, second create is typically idempotent
|
||||
- Final state: Collection exists and both writes succeed
|
||||
```
|
||||
|
||||
**ترحيل الأبعاد:**
|
||||
```
|
||||
Scenario: User wants to migrate from 384-dim to 768-dim embeddings
|
||||
Behavior:
|
||||
- No automatic migration
|
||||
- Old collection (384-dim) persists
|
||||
- New collection (768-dim) created on first new write
|
||||
- Both dimensions remain accessible
|
||||
- Manual deletion of old dimension collections possible
|
||||
```
|
||||
|
||||
**استعلامات المجموعة الفارغة:**
|
||||
```
|
||||
Scenario: Query a collection that has never received data
|
||||
Behavior:
|
||||
- Collection doesn't exist (never created)
|
||||
- Query returns empty list
|
||||
- No error state
|
||||
- System logs: "Collection does not exist, returning empty results"
|
||||
```
|
||||
|
||||
## ملاحظات حول التنفيذ
|
||||
|
||||
### تفاصيل حول نظام التخزين الخاص
|
||||
|
||||
**Qdrant:**
|
||||
يستخدم `collection_exists()` للتحقق من الوجود
|
||||
يستخدم `get_collections()` لعرض القائمة أثناء الحذف
|
||||
يتطلب إنشاء المجموعة `VectorParams(size=dim, distance=Distance.COSINE)`
|
||||
|
||||
**Pinecone:**
|
||||
يستخدم `has_index()` للتحقق من الوجود
|
||||
يستخدم `list_indexes()` لعرض القائمة أثناء الحذف
|
||||
يتطلب إنشاء الفهرس الانتظار حتى حالة "جاهز"
|
||||
يتم تكوين المواصفات بدون خادم مع السحابة/المنطقة
|
||||
|
||||
**Milvus:**
|
||||
تدير الفئات المباشرة (`DocVectors`، `EntityVectors`) دورة الحياة
|
||||
ذاكرة تخزين مؤقت داخلية `self.collections[(dim, user, collection)]` للأداء
|
||||
يتم تنظيف أسماء المجموعات (أحرف وأرقام وشرطة سفلية فقط)
|
||||
يدعم مخططًا بمعرفات متزايدة تلقائيًا
|
||||
|
||||
### اعتبارات الأداء
|
||||
|
||||
**زمن الوصول للكتابة الأولية:**
|
||||
تكلفة إضافية بسبب إنشاء المجموعة
|
||||
Qdrant: ~100-500 مللي ثانية
|
||||
Pinecone: ~10-30 ثانية (توفير بدون خادم)
|
||||
Milvus: ~500-2000 مللي ثانية (يتضمن الفهرسة)
|
||||
|
||||
**أداء الاستعلام:**
|
||||
يضيف التحقق من الوجود تكلفة إضافية ضئيلة (~1-10 مللي ثانية)
|
||||
لا يوجد تأثير على الأداء بمجرد وجود المجموعة
|
||||
يتم تحسين كل مجموعة أبعاد بشكل مستقل
|
||||
|
||||
**تكلفة التخزين:**
|
||||
بيانات وصفية قليلة لكل مجموعة
|
||||
التكلفة الرئيسية هي التخزين لكل بُعد
|
||||
مقايضة: مساحة التخزين مقابل مرونة الأبعاد
|
||||
|
||||
## اعتبارات مستقبلية
|
||||
|
||||
**توحيد الأبعاد التلقائي:**
|
||||
يمكن إضافة عملية خلفية لتحديد ودمج متغيرات الأبعاد غير المستخدمة
|
||||
سيتطلب ذلك إعادة تضمين أو تقليل الأبعاد
|
||||
|
||||
**اكتشاف الأبعاد:**
|
||||
يمكن تعريض واجهة برمجة تطبيقات لسرد جميع الأبعاد المستخدمة لمجموعة
|
||||
مفيد للإدارة والمراقبة
|
||||
|
||||
**تفضيل الأبعاد الافتراضي:**
|
||||
يمكن تتبع "البُعد الأساسي" لكل مجموعة
|
||||
يستخدم للاستعلامات عندما يكون سياق البُعد غير متاح
|
||||
|
||||
**حصص التخزين:**
|
||||
قد تكون هناك حاجة إلى حدود الأبعاد لكل مجموعة
|
||||
يمنع الانتشار المفرط لمتغيرات الأبعاد
|
||||
|
||||
## ملاحظات حول الترحيل
|
||||
|
||||
**من نظام لاحقة الأبعاد القديم:**
|
||||
المجموعات القديمة: `d_{user}_{collection}` (بدون لاحقة البُعد)
|
||||
المجموعات الجديدة: `d_{user}_{collection}_{dim}` (مع لاحقة البُعد)
|
||||
لا يوجد ترحيل تلقائي - تظل المجموعات القديمة قابلة للوصول
|
||||
ضع في اعتبارك برنامج ترحيل يدوي إذا لزم الأمر
|
||||
يمكن تشغيل كلا نظامي التسمية في وقت واحد
|
||||
|
||||
## المراجع
|
||||
|
||||
إدارة المجموعات: `docs/tech-specs/collection-management.md`
|
||||
مخطط التخزين: `trustgraph-base/trustgraph/schema/services/storage.py`
|
||||
خدمة أمين المكتبة: `trustgraph-flow/trustgraph/librarian/service.py`
|
||||
Loading…
Add table
Add a link
Reference in a new issue