Structural Diff API
واجهة REST API تقارن النص المُنشأ بالذكاء الاصطناعي بالنسخة المُحرَّرة من قِبل المُعلِّم — تكشف التغييرات الهيكلية على مستوى الصفوف (تقسيم، دمج، تعديل، إضافة، حذف)، مع تفاصيل الفروق لكل عمود، ودرجات CER/WER/SER، ودرجة جودة مركّبة لكل دُفعة.
البدء السريع
لا حاجة إلى SDK. أرسل طلب POST مع مصفوفتين من صفوف النص المكتوب وستتلقى diff كاملاً بصيغة JSON. الـ API في مرحلة الاختبار — اطلب مفتاح API للبدء.
١. تحقق من أن الخدمة تعمل:
curl https://structural-diff-engine.onrender.com/v1/health٢. شغّل مقارنة:
curl -X POST https://structural-diff-engine.onrender.com/v1/diff \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"original": [
{ "speaker": "Alice", "start_time": 0, "end_time": 1, "transcript": "Hello world" },
{ "speaker": "Bob", "start_time": 1, "end_time": 3, "transcript": "Good morning everyone" }
],
"reworked": [
{ "speaker": "Alice", "start_time": 0, "end_time": 1, "transcript": "Hello there" },
{ "speaker": "Bob", "start_time": 1, "end_time": 2, "transcript": "Good morning" },
{ "speaker": "Bob", "start_time": 2, "end_time": 3, "transcript": "everyone" }
]
}'عنوان URL الأساسي
جميع نقاط الاتصال مسبوقة بـ /v1.
https://structural-diff-engine.onrender.comالمصادقة
أضف مفتاح API في رأس الطلب x-api-key عند كل استدعاء لـ /v1/diff.
curl -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
-X POST https://structural-diff-engine.onrender.com/v1/diff -d '{...}'حدود الاستخدام
يُطبَّق مستويان مستقلان لكل مفتاح API، مع الرجوع إلى IP عند غيابه. تجاوز أي مستوى يُعيد 429 Too Many Requests.
| المستوى | الحد | رأس الاستجابة |
|---|---|---|
| دفعي | 10 طلبات / دقيقة | RateLimit-Limit |
| نافذة | 60 طلباً / 15 دقيقة | RateLimit-Remaining |
نقاط الاتصال
GET /v1/health
فحص خفيف للتوفر. لا تتطلب مصادقة. تُعيد إصدار الخدمة ومدة التشغيل.
/v1/health· بدون مصادقة{ "status": "ok", "version": "1.0.0", "uptime": 42, "timestamp": "..." }POST /v1/diff
قارن مصفوفتين من صفوف النص المكتوب. تُعيد النتائج على مستوى الصفوف مع درجات الجودة. الحجم الأقصى: 5 ميجابايت · الصفوف القصوى: 30,000.
/v1/diff مصادقة مطلوبةجسم الطلب
| Name | Type | Description |
|---|---|---|
original* | array | كائنات الصفوف من النسخة الأصلية / الأساسية. |
reworked* | array | كائنات الصفوف للمقارنة. |
config | object | تجاوزات اختيارية للخوارزمية. انظر . |
headers | string[] | أسماء الأعمدة — مطلوبة عند استخدام إدخال مصفوفة ثنائية الأبعاد. |
columnMapping | object | خريطة فهارس الأعمدة لإدخال المصفوفة ثنائية الأبعاد. انظر . |
حقول كائن الصف
جميع الحقول اختيارية باستثناء transcript. تُمرَّر الحقول غير المعروفة دون تغيير.
| Name | Type | Description |
|---|---|---|
transcript* | string | المحتوى النصي للصف. |
speaker | string | اسم المتحدث أو معرّفه. |
start_time | number|string | وقت بدء المقطع بالثواني. |
end_time | number|string | وقت انتهاء المقطع بالثواني. |
non_speech_events | string | تعليقات توضيحية مثل [موسيقى]، [ضحك]. |
emotion | string | وسم العاطفة. |
language | string | رمز اللغة (مثال: "ar"، "en"). |
locale | string | رمز اللهجة الإقليمية (مثال: "ar-MA"). |
accent | string | وسم اللكنة. |
شكل الاستجابة
جميع الاستجابات الناجحة تستخدم هذا الغلاف:
{
"status": "success",
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-04-08T21:00:00.000Z",
"data": {
"results": [
{
"status": "MODIFIED",
"originalRow": { "transcript": "Hello world", ... },
"reworkedRow": { "transcript": "Hello there", ... },
"notes": "transcript changed"
},
{
"status": "SPLIT",
"originalRow": { "transcript": "Good morning everyone", ... },
"reworkedRows": [ { "transcript": "Good morning" }, { "transcript": "everyone" } ],
"notes": "split into 2 rows"
}
],
"scores": { "CER": 0.12, "WER": 0.18, "SER": 0.33, "cerT": 0.12, "werT": 0.18 },
"composite": { "score": 3.8, "grade": "B", "label": "Good" },
"meta": { "originalRows": 2, "reworkedRows": 3, "headers": [...] }
}
}حالات الـ diff
| الحالة | المعنى |
|---|---|
| UNCHANGED | الصف متطابق في كلا النسختين. |
| MODIFIED | الصف موجود في كلا النسختين لكن المحتوى تغيّر. |
| ADDED | الصف موجود فقط في النسخة المُعادة صياغتها. |
| DELETED | الصف موجود فقط في النسخة الأصلية. |
| SPLIT | صف أصلي واحد قُسِّم إلى صفين أو أكثر في النسخة المُعادة. |
| MERGED | صفّان أصليان أو أكثر اندمجا في صف واحد في النسخة المُعادة. |
الدرجات
| Name | Type | Description |
|---|---|---|
CER | number | معدل خطأ الأحرف في جميع الأعمدة (0–1، الأقل كلما كان أفضل). |
WER | number | معدل خطأ الكلمات في جميع الأعمدة (0–1). |
SER | number | معدل خطأ التجزئة — نسبة الصفوف المقسّمة أو المدمجة. |
cerT | number | CER محسوب فقط على عمود النص المكتوب. |
werT | number | WER محسوب فقط على عمود النص المكتوب. |
الدرجة المركّبة
| Name | Type | Description |
|---|---|---|
score | number | درجة الجودة الموزونة (1.0–5.0، الأعلى كلما كان أفضل). |
grade | string | الدرجة الحرفية: A، B، C، D، أو F. |
label | string | وسم قابل للقراءة — مثال: "ممتاز"، "جيد"، "يحتاج تحسين". |
خيارات الإعداد
مرّر كائن config في جسم الطلب لتجاوز القيم الافتراضية للخوارزمية. جميع الحقول اختيارية.
| Name | Type | Description |
|---|---|---|
simpleMode | boolean | تعطيل كشف التقسيم والدمج. مقارنة صف بصف فقط. الافتراضي: false. |
enableSplits | boolean | تفعيل كشف الصفوف المقسّمة. الافتراضي: true. |
enableMerges | boolean | تفعيل كشف الصفوف المدمجة. الافتراضي: true. |
enableCER | boolean | حساب معدل خطأ الأحرف. الافتراضي: true. |
enableWER | boolean | حساب معدل خطأ الكلمات. الافتراضي: true. |
enableSER | boolean | حساب معدل خطأ التجزئة. الافتراضي: true. |
stripDiacritics | boolean | توحيد الأحرف العربية/المعلَّمة قبل المقارنة. الافتراضي: true. |
positionalMode | boolean | مقارنة الصفوف بالترتيب الحرفي مع تخطي المحاذاة. الافتراضي: false. |
ignoreColNames | string[] | أسماء الأعمدة المستبعدة من كشف MODIFIED. الافتراضي: []. |
enableInlineDiff | boolean | تضمين transcriptDiff في صفوف MODIFIED. ضبطه false لتخطي حساب الفروق حرفاً بحرف وتقليل حجم الاستجابة. الافتراضي: true. |
structuralTransforms | TransformRule[] | قواعد find/replace تُطبَّق على الجانبين قبل حساب التشابه (حد أقصى 20 قاعدة). الافتراضي: []. |
تعيين الأعمدة
عندما تكون original / reworked مصفوفات ثنائية الأبعاد (مصفوفات من مصفوفات) بدلاً من كائنات، امدد headers و/أو columnMapping لإخبار المحرك بأي فهرس يحمل كل حقل.
{
"original": [[0, 1, "Alice", "Hello world"]],
"headers": ["start_time", "end_time", "speaker", "transcript"],
"columnMapping": { "transcript": 3, "speaker": 2, "start_time": 0, "end_time": 1 }
}| Name | Type | Description |
|---|---|---|
transcript* | integer | فهرس عمود base-0 لحقل النص المكتوب. |
speaker | integer | فهرس عمود base-0 لحقل المتحدث. |
start_time | integer | فهرس عمود base-0 لوقت البداية. |
end_time | integer | فهرس عمود base-0 لوقت النهاية. |
nse | integer | فهرس عمود base-0 للأحداث غير الكلامية. |
extraCols | integer[] | فهارس أعمدة إضافية للتضمين (بحد أقصى 20). |
مرجع الأخطاء
جميع الأخطاء تستخدم غلافاً موحداً:
{
"status": "error",
"requestId": "550e8400-...",
"timestamp": "2026-04-08T21:00:00.000Z",
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [{ "field": "original", "message": "\"original\" is required" }]
}
}| HTTP | الرمز | السبب |
|---|---|---|
| 400 | BAD_REQUEST | جسم JSON ذو تنسيق خاطئ |
| 401 | UNAUTHORIZED | رأس x-api-key مفقود أو غير صالح |
| 404 | NOT_FOUND | نقطة اتصال غير معروفة |
| 413 | PAYLOAD_TOO_LARGE | جسم الطلب يتجاوز 5 ميجابايت |
| 422 | VALIDATION_ERROR | فشل التحقق من صحة الجسم (انظر مصفوفة details) |
| 429 | RATE_LIMIT_EXCEEDED | تجاوز حد الدفعة أو حد النافذة |
| 500 | INTERNAL_ERROR | خطأ غير متوقع في الخادم أو المحرك |
تتبع الطلبات
قدّم رأس x-request-id لربط الطلبات عبر نظامك. أحرف أبجدية رقمية وشرطات وشرحطات سفلية فقط، بحد أقصى 64 حرفاً. تُعاد القيمة في رؤوس الاستجابة.
curl -H "x-request-id: job-2026-01-batch-3" \
-H "x-api-key: YOUR_KEY" \
-X POST https://structural-diff-engine.onrender.com/v1/diff -d '{...}'الحصول على وصول API
الـ API متاحة للوكالات والفرق في مرحلة الاختبار. تُخصَّص المفاتيح بشكل فردي. تواصل معنا لتلقي مفتاحك والبدء في التكامل.