Structural Diff API
واجهة REST API تقارن النص المُنشأ بالذكاء الاصطناعي بالنسخة المُحرَّرة من قِبل المُعلِّم — تكشف التغييرات الهيكلية على مستوى الصفوف (تقسيم، دمج، تعديل، إضافة، حذف)، مع تفاصيل الفروق لكل عمود، ودرجات CER/WER/SegER/SER/SACR، ودرجة جودة مركّبة لكل دُفعة.
البدء السريع
لا حاجة إلى 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 | وسم اللكنة. |
file_name | 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": { "overallCER": 0.12, "overallWER": 0.18, "SegER": 0.33, "transcriptCER": 0.12, "transcriptWER": 0.18, "SER": 0.05, "transcriptSER": 0.04, "SACR": null },
"composite": { "grade": 3.8, "label": "Good", "percent": "12.3" },
"meta": { "originalRows": 2, "reworkedRows": 3, "headers": [...] }
}
}حالات الـ diff
| الحالة | المعنى |
|---|---|
| UNCHANGED | الصف متطابق في كلا النسختين. |
| MODIFIED | الصف موجود في كلا النسختين لكن المحتوى تغيّر. |
| ADDED | الصف موجود فقط في النسخة المُعادة صياغتها. |
| DELETED | الصف موجود فقط في النسخة الأصلية. |
| SPLIT | صف أصلي واحد قُسِّم إلى صفين أو أكثر في النسخة المُعادة. |
| MERGED | صفّان أصليان أو أكثر اندمجا في صف واحد في النسخة المُعادة. |
الدرجات
| Name | Type | Description |
|---|---|---|
overallCER | number | معدل خطأ الأحرف في جميع الأعمدة (0–1، الأقل كلما كان أفضل). |
overallWER | number | معدل خطأ الكلمات في جميع الأعمدة (0–1). |
SegER | number | معدل خطأ التجزئة — أحداث حدود (تقسيمات ودمجات وصفوف مضافة ومحذوفة) / المقاطع المتوقعة (0–1، الأقل كلما كان أفضل). |
transcriptCER | number | CER محسوب فقط على عمود النص المكتوب. |
transcriptWER | number | WER محسوب فقط على عمود النص المكتوب. |
SER | number | معدل خطأ الجمل — صفوف MODIFIED / (UNCHANGED + MODIFIED). نسبة الصفوف القابلة للمقارنة التي تحتوي على أي تعديل (0–1). |
transcriptSER | number | SER محسوب على الجمل داخل نص عمود النص المكتوب. |
SACR | number | معدل تغيير تنسيب المتحدث — الصفوف التي تغيّر فيها المتحدث / صفوف MODIFIED. قيمة null إذا لم يُكتشف عمود متحدث. |
الدرجة المركّبة
| Name | Type | Description |
|---|---|---|
grade | number | درجة رقمية (1.0–5.0، الأعلى كلما كان أفضل) تُحسب بمعدل المقاييس الممكّنة. |
label | string | وسم قابل للقراءة — أحد: "Excellent"، "Good"، "Acceptable"، "Below Average"، "Poor"، "Unacceptable". |
percent | string | متوسط نسبة الخطأ عبر مقاييس التقييم الممكّنة. |
enabledMetrics | string[] | مصفوفة أسماء المقاييس التي ساهمت في هذا المركّب (مثال: ["CER"، "Transcript CER"، "WER"، "Transcript WER"، "SegER"، "SER"، "Transcript SER"]). فارغة عند تعطيل جميع المقاييس. |
بيانات الاستجابة
| Name | Type | Description |
|---|---|---|
originalRows | number | عدد الصفوف في المصفوفة الأصلية. |
reworkedRows | number | عدد الصفوف في المصفوفة المُعادة. |
headers | string[] | أسماء أعمدة الرؤوس المستخدمة في هذا الـ diff. |
خيارات الإعداد
مرّر كائن config في جسم الطلب لتجاوز القيم الافتراضية للخوارزمية. جميع الحقول اختيارية.
| Name | Type | Default | Description |
|---|---|---|---|
simpleMode | boolean | false | تعطيل كشف التقسيم والدمج. مقارنة صف بصف فقط. |
enableSplits | boolean | true | تفعيل كشف الصفوف المقسّمة. |
enableMerges | boolean | true | تفعيل كشف الصفوف المدمجة. |
enableCER | boolean | true | حساب معدل خطأ الأحرف. |
enableWER | boolean | true | حساب معدل خطأ الكلمات. |
enableSegER | boolean | true | حساب معدل خطأ التجزئة (تقسيم، دمج، أحداث الحدود الهيكلية). |
enableSER | boolean | true | حساب معدل خطأ الجمل. |
stripDiacritics | boolean | true | توحيد الأحرف العربية/المعلَّمة قبل المقارنة. |
positionalMode | boolean | false | مقارنة الصفوف بالترتيب الحرفي مع تخطي المحاذاة. |
ignoreColNames | string[] | [] | أسماء الأعمدة المستبعدة من كشف MODIFIED. |
enableInlineDiff | boolean | true | تضمين transcriptDiff في صفوف MODIFIED. ضبطه false لتخطي حساب الفروق حرفاً بحرف وتقليل حجم الاستجابة. |
structuralTransforms | TransformRule[] | [] | قواعد find/replace تُطبَّق على الجانبين قبل حساب التشابه (حد أقصى 20 قاعدة). |
enableTranscriptCER | boolean | true | حساب CER مقيّد بعمود transcript فقط. مستقل عن enableCER. |
enableTranscriptWER | boolean | true | حساب WER مقيّد بعمود transcript فقط. مستقل عن enableWER. |
enableTranscriptSER | boolean | true | SER على مستوى الجمل في عمود transcript — يحسب الجمل المتغيّرة في صفوف MODIFIED وSPLIT وMERGED. |
enableSACR | boolean | true | حساب معدل تغيير تنسيب المتحدث (صفوف MODIFIED التي تغيّر فيها المتحدث / إجمالي MODIFIED). يكشف عمود المتحدث تلقائياً؛ يُعيد null إذا لم يُعثر عليه. |
speakerColName | string | auto-detect | تجاوز الكشف التلقائي لعمود المتحدث. مطابقة غير حساسة للحالة (مثال: "spk_id"). |
enableComposite | boolean | true | حساب الدرجة المركّبة للجودة (متوسط 1–5 عبر المقاييس الممكّنة). |
cerInComposite | boolean | true | تضمين overallCER في الدرجة المركّبة. يُحسَب CER ويُعاد حتى عند false. |
werInComposite | boolean | true | تضمين overallWER في الدرجة المركّبة. يُحسَب WER ويُعاد حتى عند false. |
segerInComposite | boolean | true | تضمين SegER في الدرجة المركّبة. يُحسَب SegER ويُعاد حتى عند false. |
serInComposite | boolean | true | تضمين SER في الدرجة المركّبة. يُحسَب SER ويُعاد حتى عند false. |
تعيين الأعمدة
عندما تكون 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_SERVER_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 متاحة للوكالات والفرق في مرحلة الاختبار. تُخصَّص المفاتيح بشكل فردي. تواصل معنا لتلقي مفتاحك والبدء في التكامل.