التوثيق

ثلاثة استدعاءات، ولديك حكم

يأخذ ⁦Kirelta⁩ صفوفًا من الأرقام — متجهات الخصائص نفسها التي تغذِّي بها نموذجك — ويخبرك هل ما زالت تشبه البيانات التي دُرِّب عليها النموذج. وكل ما أدناه جاهز للنسخ واللصق.

في هذه الصفحة
  1. درِّب خط أساس
  2. قيِّم دفعة
  3. اقرأ الحكم
  4. اربطه بخدمتك
  5. كل ما تبقّى
  6. حين يفشل شيء

تفضِّل مرجعًا يقرؤه الحاسوب؟ ⁦openapi.yaml⁩ — كل حقل مُراجَع مقابل الخدمة العاملة، لا مكتوب من الذاكرة.

العنوان الأساسي ⁨https://api.kirelta.com⁩. وثِّق استدعاءات البيانات بالترويسة X-API-Key. واحصل على مفتاح من صفحة الحساب.

درِّب خط أساس

أرسِل دفعة صفوف تمثِّل سلوكًا سليمًا — بيانات من فترة كان النموذج يعمل فيها جيدًا. يتعلَّم ⁦Kirelta⁩ شكل تلك البيانات ويختار لها مراقبه بنفسه. وعلى كل صف أن يحمل العدد نفسه من الخصائص.

أرسِل outputs أيضًا. أضِف التنبؤات التي أنتجها نموذجك على تلك الصفوف نفسها، فيتعلَّم ⁦Kirelta⁩ السلوك الطبيعي لها كذلك — ليتمكَّن لاحقًا من التقاط نموذج انهار بينما البيانات الداخلة إليه ما زالت تبدو عادية تمامًا. وذلك عطل لا تراه أي أداة تراقب المدخلات وحدها.

POST /fit?model=NAME

curl

curl -X POST "https://api.kirelta.com/fit?model=credit-risk" \
  -H "X-API-Key: kir_your_key" \
  -H "Content-Type: application/json" \
  -d '{"rows": [[0.8, 1.2, 0.4], [1.1, 0.9, 0.6]]}'

Python

import requests

requests.post(
    "https://api.kirelta.com/fit",
    params={"model": "credit-risk"},
    headers={"X-API-Key": "kir_your_key"},
    json={"rows": healthy_rows},   # [[0.8, 1.2, 0.4], [1.1, 0.9, 0.6], ...300 healthy rows]
).json()

JavaScript

await fetch("https://api.kirelta.com/fit?model=credit-risk", {
  method: "POST",
  headers: {
    "X-API-Key": "kir_your_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ rows: healthyRows })
}).then(r => r.json());

المُخرَجات

{
  "status": "fitted",
  "model": "credit-risk",
  "n": 300,
  "features": 3,
  "baseline_fit": "clear"
}

قيِّم دفعة

الآن أرسِل صفوفًا حديثة — تلك التي تريد حكمًا عليها فعلًا. يقارنها ⁦Kirelta⁩ بخط الأساس ويجيب في كائن واحد.

POST /assess?model=NAME

curl

curl -X POST "https://api.kirelta.com/assess?model=credit-risk" \
  -H "X-API-Key: kir_your_key" \
  -H "Content-Type: application/json" \
  -d '{"rows": [[0.9, 1.0, 0.5], [1.3, 0.8, 0.7]]}'

Python

r = requests.post(
    "https://api.kirelta.com/assess",
    params={"model": "credit-risk"},
    headers={"X-API-Key": "kir_your_key"},
    json={"rows": recent_rows},   # [[0.9, 1.0, 0.5], [1.3, 0.8, 0.7], ...recent rows]
)
verdict = r.json()["verdict"]   # TRUSTED | DEGRADED | UNTRUSTED | INSUFFICIENT_EVIDENCE

JavaScript

const r = await fetch("https://api.kirelta.com/assess?model=credit-risk", {
  method: "POST",
  headers: {
    "X-API-Key": "kir_your_key",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ rows: recentRows })
});
const { verdict, action } = await r.json();

اقرأ الحكم

هذا هو المنتج كله. وكل ما تعرضه اللوحة مبنيٌّ من هذه الحقول — ولا يُحسب شيء آخر في أي مكان.

{
  "model": "t_e573d9984466::credit-risk",
  "verdict": "UNTRUSTED",
  "action": "BLOCK / escalate to a human",
  "flagged_rate": 1.0,
  "drift_alarmed": true,
  "n": 80,

  "martingale": 2203.05,
  "alarm_threshold": 20.0,
  "drift_started_at": 1,

  "feature_importance": [
    { "feature": 2, "importance": 0.3770 },
    { "feature": 1, "importance": 0.3561 },
    { "feature": 0, "importance": 0.2669 }
  ],
  "top_features": [2, 1, 0],

  "output_stability": {
    "active": true,
    "drift": true,
    "shifted": true,
    "n": 80
  },

  "notes": ["The data this model was trained on may itself contain anomalies..."],
  "note_codes": ["baseline_may_contain_anomalies"],

  "input_collapsed": false,
  "typicality_median": 0.4913,

  "temporal": { "elevated": false, "note": "..." }
}
⁦verdict⁩TRUSTED · DEGRADED · UNTRUSTED — الاستدعاء نفسه. تفرَّع على هذا.
⁦action⁩توصية المحرِّك بالكلمات، مثل ALLOW, REVIEW (elevated abstention), BLOCK / escalate to a human.
⁦flagged_rate⁩نسبة الصفوف في هذه الدفعة التي وقعت خارج النطاق المدرَّب. 0.0–1.0.
⁦drift_alarmed⁩true حين يُطلق إنذار الانحراف. ومعدَّل إنذاره الكاذب مقيَّد على التشغيل كله، لا لكل دفعة.
⁦n⁩كم صفًّا جرى تقييمه.
⁦top_features⁩مؤشِّرات الأعمدة التي أسهمت أكثر في الانحراف، الأشدُّ غرابةً أولًا.
⁦feature_names⁩ (send on /fit)اختياري، وقيمته أكبر من كلفته. مرِّر أسماء أعمدتك كقائمة، بالترتيب نفسه لصفوفك، فيعود كل جزء من الدليل مسمًّى: {"feature": 2, "name": "cpu_load", "importance": 0.529}. وبدونها لا يستطيع المحرِّك أن يقول إلا #2 — وهي حقيقة لا تفسير. والقائمة ذات الطول الخاطئ تُرفض بدل أن تُطبَّق، لأن خاصية مُسمَّاة خطأً أسوأ من خاصية بلا اسم. وعميل ⁦Python⁩ يقرؤها من إطار بيانات ⁦pandas⁩ تلقائيًا.
⁦persisted⁩ (on /fit)هل بلغ هذا النموذج القرص. true يعني أنه ينجو من إعادة التشغيل؛ و false يعني أنه في الذاكرة فقط، و persistence_note يوضِّح السبب (لا وحدة تخزين مهيَّأة، أو فشلت الكتابة). والنموذج الذي يقول fitted لكن persisted:false يبعد إعادة نشر واحدة عن الزوال. و /health تُبلِّغ عن الحقيقة نفسها على مستوى الخدمة باسم durable.
⁦output_stability⁩الطبقة الثانية — سلوك النموذج نفسه. أرسِل outputs (التنبؤات التي أنتجها نموذجك) إلى /fit و /assess ويختبر ⁦Kirelta⁩ أيضًا هل ما زال النموذج يتصرَّف كنفسه. حاضرة دائمًا، بما في ذلك حين تكون مُطفأة — فالطبقة المُظلمة تُبلِّغ active: false وتقول لماذا، لأن «لا انحراف» من طبقة لم تعمل قط لا يعني شيئًا. التركيبة التي تهمّ: verdict: TRUSTED مع output_stability.drift: true هو العطل الصامت — لم يتغيَّر شيء في الأعلى، والنموذج كفَّ بهدوء عن التصرُّف كنفسه. والأدوات التي تراقب المدخلات وحدها تُغفله في كل مرة.
⁦martingale alarm_threshold⁩كم اقتربت هذه الدفعة من الإنذار. القيمة دليل هذه الدفعة ضد «لا انحراف»؛ ويُطلق الإنذار لحظة بلوغها alarm_threshold. ودفعة عند 9 / 20 ليست مُنذَرة وليست بخير — بل هي على مشارف منتصف الطريق إلى الحجب. وكل أداة أخرى تعطيك الثنائية فقط. ويُحكم على كل استدعاء بصفوفه هو، فاقرأه لكل دفعة.
⁦input_collapsed typicality_median⁩العطل الذي لا يستطيع إنذار الانحراف رؤيته. typicality_median يقيس مدى اعتيادية نقاطك الحيّة، 0.0–1.0؛ وحول 0.50 سليم. وحين يتسلَّق نحو 1.00، يبدو كل صف تقريبًا طبيعيًا تمامًا — وهو ما لا تفعله بيانات حقيقية قط — و input_collapsed يصبح true. وله سببان: تغذية عالقة (حسَّاس متجمِّد، أو مهمة تُعيد قيمًا افتراضية أو متوسطات أعمدة، أو ربط يطابق صفًّا واحدًا)، أو تغيُّر في الشكل حافَظ على المتوسط والتغاير نفسيهما. ولا يبدو أي منهما شاذًّا، فيبقى الحكم ⁦TRUSTED⁩ — وهذا الحقل وحده ما يخبرك.
⁦drift_started_at⁩مؤشِّر الصف الذي أُعلن فيه الانحراف. ويغيب حين لا شيء يُنذر. ويقع ببضعة صفوف بعد البداية الحقيقية (مقيسًا: نحو 4 صفوف بعد إزاحة حادّة في منتصف الدفعة) — فاقرأه على أنه «ليس بعد هنا»، لا على أنه أول صف سيئ بالضبط.
⁦feature_importance⁩الحصة الحقيقية من الانحراف الذي تحمله كل خاصية، بمجموع 1.0 — لا مجرد ترتيب. top_features مُبقًى للتوافق.
⁦notes note_codes⁩تشخيصات عن هذا النموذج، بجُمل صريحة. notes هو ما تعرضه على شخص؛ و note_codes هو ما تتفرَّع عليه — معرِّف مستقر لكل تشخيص، فلا يعتمد معالِجك على صياغة قد يُعاد صوغها. وأجدرها بالربط أولًا هو baseline_may_contain_anomalies: فالبيانات التي درَّبت عليها قد تحتوي شذوذات، وهذا يغيِّر كيف ينبغي أن يُقرأ كل حكم من ذلك الأساس. وعامِل القائمة على أنها مفتوحة — تُضاف رموز جديدة مع الوقت، فتجاهل ما لا تعرفه بدل أن تفشل عليه.
⁦slow_drift_rate⁩يظهر فقط حين يشيخ خط الأساس نفسه. ويلتقط الانحراف البطيء الذي لا يُسقط أي دفعة منفردة.
⁦temporal⁩هل إنذار الانحراف موثوق تمامًا لهذه الدفعة. يفترض الإنذار أن الصفوف التي ترسلها مستقلة بعضها عن بعض. وحين لا تكون كذلك — قراءات من جلسة واحدة، أو تصدير مرتَّب — يصبح الإنذار أقل موثوقية لتلك الدفعة، و temporal.elevated يُبلِّغ true، مع temporal.note يشرح ذلك بالكلمات. ورايات الصفوف ومعدَّل التعليم لا تتأثَّر. تفرَّع على elevated. يخبرك ⁦Kirelta⁩ بدل أن يدعك تُفرط في الثقة بالإنذار.
⁦trend⁩يظهر فقط عند انطباقه: {"state":"recovering","window":8} يعني أن هذا النموذج أُنذر مؤخرًا وهو الآن يتحسَّن. وهو لا يحلُّ أبدًا محلَّ verdict — اقرأ كليهما.

اربطه بخدمتك

الشكل المعتاد: قيِّم الدفعة قبل أن تتصرَّف بناءً على التنبؤات، ثم تفرَّع على الحكم.

Python

import requests

KIRELTA = "https://api.kirelta.com"
KEY     = "kir_your_key_here"

def can_i_trust(model, rows):
    r = requests.post(f"{KIRELTA}/assess?model={model}",
                      headers={"X-API-Key": KEY},
                      json={"rows": rows}, timeout=10)
    r.raise_for_status()
    return r.json()

verdict = can_i_trust("credit-risk", recent_feature_rows)

if verdict["verdict"] == "UNTRUSTED":
    escalate_to_human(verdict)          # don't act on the model's output
elif verdict["verdict"] in ("DEGRADED", "INSUFFICIENT_EVIDENCE"):
    # degraded, or no conclusion either way: act, but flag it
    log_for_review(verdict)
    serve(predictions)
else:
    serve(predictions)                  # TRUSTED

الشكل نفسه بلغة ⁦JavaScript⁩:

JavaScript

const KIRELTA = "https://api.kirelta.com";
const KEY = "kir_your_key_here";

async function canITrust(model, rows) {
  const r = await fetch(`${KIRELTA}/assess?model=${model}`, {
    method: "POST",
    headers: { "X-API-Key": KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ rows })
  });
  if (!r.ok) throw new Error(`assess failed: ${r.status}`);
  return r.json();
}

const verdict = await canITrust("credit-risk", recentFeatureRows);

if (verdict.verdict === "UNTRUSTED") {
  escalateToHuman(verdict);             // don't act on the model's output
} else if (["DEGRADED", "INSUFFICIENT_EVIDENCE"].includes(verdict.verdict)) {
  // degraded, or no conclusion either way: act, but flag it
  logForReview(verdict);
  serve(predictions);
} else {
  serve(predictions);                   // TRUSTED
}

كل ما تبقّى

بقية السطح، في مكان واحد.

GET /models

كل نموذج في مستأجرك، وكم خاصية يتوقَّع كلٌّ منها.

GET /model/meta?model=NAME

أي مراقب اختاره ⁦Kirelta⁩ لهذا النموذج ولماذا — مفيد حين تريد تسويغ حكم.

GET /usage

خطتك، والتنبؤات المستخدَمة هذا الشهر، ونماذجك مقابل حدِّك.

POST /keys · POST /keys/revoke

إنشاء مفاتيح الواجهة البرمجية وإبطالها. توثيق بالجلسة (Authorization: Bearer)، لا بالمفتاح — أو استخدم ببساطة صفحة الحساب.

GET /account/export · DELETE /account

نزِّل كل ما هو محفوظ عن حسابك، أو امحُه تمامًا.

GET /events · GET /alerts · POST /alerts

أحداث الثقة — ما الذي تغيَّر. يُرسل ⁦Kirelta⁩ حدثًا إلى خطَّافك حين يتغيَّر حكم نموذج، لا عند كل قراءة: فنموذج قُيِّم ألف مرة وهو معطَّل يرسل حدثًا واحدًا لا ألفًا. والتصعيد من متدهور إلى غير موثوق يمرُّ دائمًا، بفترة تهدئة أو بدونها — فسماع «متدهور» ثم صمت هو أخطر ما يمكن لهذا النظام أن يفعله بك. يُنبِّه ⁦Kirelta⁩؛ ولا يتصرَّف في أنظمتك أبدًا. لا يرى إلا ما ترسله إليه. لا يوجد مجدوِل. فإن توقَّفت خدمتك عن استدعاء /assess، صمَت ⁦Kirelta⁩، ولن يخبرك أي حدث بأنك عميت — فأبقِ ذلك الفحص في مراقبة زمن التشغيل لديك أنت. GET /alerts يخبرك هل القناة تعمل، لا ما هو مهيَّأ فقط. وإلى جانب الرابط و format يُعيد delivery — كم من تنبيهاتك الأخيرة قبلتها نقطة نهايتك فعلًا، ومتى كانت آخر محاولة، ولماذا فشلت إن فشلت. وإن كان consecutive_failures غير صفري، حملت الاستجابة أيضًا delivery_warningصريحًا. استطلعه، أو راقبه في اللوحة: فخطَّاف ويب توقَّف بصمت عن قبول التسليمات هو أداة مراقبة لم تعد تملكها.

GET /health

بلا توثيق. يُعيد {"status":"ok"} حين يكون المحرِّك يعمل.

حين يفشل شيء

400لم يكن الجسم ما توقَّعته نقطة النهاية. والرسالة تقول ما الخطأ. ويحمل الخطأ المتعلِّق ببياناتك كذلك code ثابتًا، مثل baseline_too_small أو feature_mismatch، والأرقام التي تذكرها الرسالة، مثل min_rows: فابنِ منطقك على الرمز، لا على الصياغة.
401مفتاح واجهة برمجية مفقود أو مُبطَل.
404هذا النموذج أو السجل غير موجود في مساحة عملك — كقراءة تفاصيل نموذج لم يُدرَّب قط.
409لم يُدرَّب هذا النموذج بعد: يُجيب /assess بـ 409 حتى يُشغَّل /fit له.
429أحد حدَّين، يُميَّز بينهما من جسم الاستجابة. حدُّ التنبؤات الشهري: يقول detail «⁦⁨You have reached your monthly prediction limit. Upgrade your plan to continue processing predictions.⁩⁩» ولا يُعالَج شيء آخر حتى يبدأ الشهر الجديد أو ترقِّي خطتك. أو حدُّ المعدَّل: تراجَع ثم أعِد المحاولة.

لا يوجد النموذج إلا بعد /fit. فإن أجاب /assess بـ 409، فدرِّب خط الأساس أولًا.