كل المقالات
8 دقائق قراءة

كيف تُصلح خطأ toncenter 429 «Too Many Requests»

خطأ toncenter 429 «Too Many Requests» — لماذا يصيب وكلاء الذكاء الاصطناعي أكثر من غيرهم، إصلاح سريع بالتراجع الأسّي، والحل الحقيقي بمفتاحك الخاص وسعة مضمونة.

toncenterخطأ 429حدّ المعدل في TONTON MCPTONNodeوكلاء الذكاء الاصطناعي TON

يتعطّل وكيلك على TON في أسوأ لحظة ممكنة: يطلب المستخدم «أظهر لي رصيدي وآخر صفقاتي»، فيذهب الوكيل بصدق إلى toncenter — ولا يأتيه JSON فيه البيانات، بل ردٌّ جافّ: HTTP 429 Too Many Requests. حاول الوكيل في نبضة واحدة أن يجمع رصيد المحفظة وحالة الحساب وتاريخ المعاملات وأن يستدعي get-method أو اثنين — فأغلق toncenter العامّ الباب عند الطلب الثاني. المستخدم يرى «حدث خطأ ما»، وأنت ترى جدارًا من السجلات الحمراء بالحالة نفسها. هذا ليس خللًا في كودك، بل هو حدّ المعدل العامّ في toncenter، وهو الجدار الذي يصطدم به أي وكيل بمجرّد أن يبدأ العمل بأكثر من طلب واحد في الثانية.

لنفكّك من أين يأتي toncenter 429، ولماذا يقع وكلاء الذكاء الاصطناعي في Too Many Requests على TON أكثر من الجميع، وكيف تخفض تواتر الأخطاء سريعًا بالتراجع (backoff) — وكيف تزيل السقف من أساسه بالانتقال إلى مفتاحك الخاص بسعة تمريرية مضمونة.

ماذا يعني 429 «Too Many Requests» على toncenter

الرمز 429 ردٌّ HTTP قياسي معناه «طلبات كثيرة جدًّا». الخادم لم يتعطّل ولم يرفض بياناتك: هو فقط يقول إنك تجاوزت التواتر المسموح به وإنه يُبطئك (rate limiting). وفي toncenter (v2) يبدو جسم الردّ عندئذٍ هكذا تقريبًا:

{ "ok": false, "error": "Rate limit exceeded", "code": 429 }

والمفتاح هنا: "ok": false و"code": 429 — هذه حالة HTTP مكرَّرة داخل الجسم، لا رمزَ خطأ داخليًّا صادرًا عن عقد. ولاحظ أيضًا أن حقل result الذي يحمل بيانات الحساب غير موجود هنا إطلاقًا — فنصّ الحدّ يقع في الحقل error. لذلك إن كان كودك يتوقّع أن يسحب البيانات من result، فسيحصل على undefined، والأرجح أن ينهار في موضع أبعد في المكدّس بخطأ تحليل غامض — بينما السبب الحقيقي راقد في error. والقاعدة بسيطة: عند ok: false تحقّق أولًا من code واقرأ error، ولا تفكّك result غير الموجود.

وأمّا الفولكلور فحديث على حدة: يتداول مجتمع TON «الخطأ 228». وهذا ليس رمز API، بل ميم — لن يعيد لك أي خادم الرقم 228. أما رمز الحدّ الحقيقي فهو 429 بالضبط، وهو ما ينبغي أن تبحث عنه في التوثيق. و429 خطأ مؤقّت: الاستدعاء نفسه سيمرّ إن نفّذته أبطأ أو بمفتاح صالح.

لماذا لا يمنحك toncenter بلا مفتاح سوى طلب واحد في الثانية

يحدّك toncenter العامّ بلا مفتاح API عند طلب واحد في الثانية تقريبًا. وهذا ليس خللًا ولا جشعًا — بل حمايةٌ لمورد مجاني مشترك يستخدمه آلاف الناس في وقت واحد. وثمة تفصيلتان يتعثّر بهما حتى المطوّرون المخضرمون:

  • المجمّع المشترك يخصّ حركة المرور المجهولة. فبلا مفتاح تتقاسم حدًّا عامًّا واحدًا يقارب 1 rps مع كل الطلبات مجهولة الاسم في العالم. وفي ساعة الذروة قد يصير التواتر المتاح لك فعليًّا أقلّ من ذلك.
  • المفتاح المدفوع يرفع السقف — لكن بشرط أن يُمرَّر فعلًا في الطلب. والفخّ الكلاسيكي: المفتاح موجود، لكن الترويسة X-API-Key ضاعت أثناء إعادة هيكلة عميل HTTP، فتعود إلى الحدّ العامّ وتقضي ساعات وأنت لا تفهم لماذا «لا تعمل» الباقة المدفوعة.

طلبٌ واحد في الثانية أمرٌ طبيعي لتصحيح يدوي في المتصفح، أو لسكربت يتحقّق من الرصيد مرة كل دقيقة. أما لأي أتمتة، فضلًا عن وكيل ذكي، فهذا قليل إلى حدٍّ قاتل.

لماذا يقع وكلاء الذكاء الاصطناعي في 429 أكثر من الجميع — نمط الدفقات

هنا مكمن الداء. التطبيق العادي يرسل طلباته موزَّعة بانتظام تقريبًا. أما وكيل الذكاء الاصطناعي فيعمل بطريقة أخرى — بدفقات (burst، انفجار مفاجئ). إنه يعمل بنبضات: ففي خطوة استدلال واحدة يحتاج إلى جمع السياق، فيستدعي عشرات النداءات تباعًا، في وقت شبه متزامن.

تخيّل خطوة واحدة: «يطلب المستخدم التحقّق مما إذا كانت الدفعة قد وصلت». وللإجابة، يستدعي الوكيل في أجزاء من الثانية، تباعًا:

  1. get_masterchain_info — لمعرفة رأس البلوكتشين الحالي؛
  2. get_balance — رصيد المحفظة؛
  3. get_account_state — حالة الحساب وأعلامه؛
  4. get_transactions — آخر المعاملات؛
  5. run_get_method — قراءة get-method في العقد؛
  6. get_jetton_balance — ومعها رصيد USDT.

ستة استدعاءات في نبضة واحدة. والحدّ واحدٌ في الثانية. الأول سيمرّ، وأما البقية فستعيد 429، فيعلق الوكيل أو يبدأ بالهلوسة على بيانات ناقصة. والمسألة ليست «وكيلًا رديئًا» — بل هذه بنية طبيعية للاستدلال الذاتي: اجمع السياق ثم فكّر. والأسوأ أن الوكيل، إذ يلتقط الأخطاء، كثيرًا ما يحاول «إصلاحها» باستدعاءات متكرّرة — فيُجهز على حصّة مستنفَدة أصلًا. الحدّ العامّ ببساطة غير مصمَّم لملفّ حِمل كهذا.

واللايت-سيرفرات العامة في الإعداد العالمي لـ TON لها قصة مشابهة — فتحت الحِمل تردّ not ready أو تسقط بمهلة ADNL. وعن ذلك بالتفصيل: لماذا يردّ اللايت-سيرفر «not ready» وما العمل. ولدى tonapi.io المرض نفسه، 429 — التحليل هنا.

إصلاح سريع — إعادة محاولة بتراجع أسّي واحترام Retry-After

أول ما يستحقّ الفعل الآن هو التوقّف عن ضرب الجدار بأقصى سرعة. فإن جاءك 429 رغم ذلك، لا تقصف الخادم بإعادة الطلب فورًا: هذا لا يفعل شيئًا سوى إطالة الحظر. وهذا علاجٌ مسكّن — يخفض تواتر 429 لكنه لا يرفع السقف. والمسكّن الصحيح يتكوّن من أربعة أجزاء.

1. تراجع أسّي مع jitter. انتظر في كل محاولة تالية أطول من سابقتها، مع إضافة عشوائية كي لا تتزامن العمليات المتوازية فتضرب في الثانية نفسها.

async function fetchWithBackoff(url, opts = {}, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(url, opts);
    if (res.status !== 429) return res;

    // الأولوية لـ Retry-After من الخادم، وإلا فالتراجع الأسّي مع jitter
    const retryAfter = res.headers.get("Retry-After");
    const baseMs = retryAfter
      ? Number(retryAfter) * 1000
      : Math.min(1000 * 2 ** attempt, 16000);
    const jitter = Math.random() * 300;
    await new Promise((r) => setTimeout(r, baseMs + jitter));
  }
  throw new Error("toncenter: 429 لم يتراجع بعد إعادة المحاولات");
}

2. احترم الترويسة Retry-After إن وصلت. toncenter لا يرسلها عادةً مع 429، لذا اجعل رهانك الأساسي على صيغة التراجع عندك. لكن إن حدّد الخادم فعلًا كم تنتظر — فانتظر هذه المدة بالضبط ولا تخمّن (وهذا ما يفعله في الكود أعلاه فرعُ if (retryAfter)).

3. قيّد التزامن. ضع أمام toncenter طابورًا أو سيمافورًا لا يُطلق أكثر من طلب واحد في الثانية تقريبًا. عندئذٍ تنبسط دفقة الوكيل على الزمن: تلك القائمة نفسها ذات الاستدعاءات الستة ستُنفَّذ تباعًا خلال نحو 6 ثوانٍ، لكن دون 429 واحد.

4. خزّن القراءات المتكرّرة مؤقّتًا. get_masterchain_info يمكن طلبه مرة واحدة داخل الخطوة نفسها وإعادة استخدامه. والبيانات الوصفية للجيتون (decimals، الرمز) لا تتغيّر — اقرأها مرة واحدة. والرصيد الذي قرأته قبل 300 ملي ثانية يُستبعَد أن يكون قد تغيّر.

هذا ينفع ويجعل الوكيل أكثر تهذيبًا، لكن لنعترف بصدق: التراجع لا يرفع السقف. أنت ما زلت محبوسًا عند 1 rps، غاية ما في الأمر أنك الآن تقف في الطابور بأدب بدل أن تسقط. المستخدم ينتظر ثوانيَ حيث كان يمكن أن ينتظر ميلي ثوانٍ. وبالنسبة إلى وكيل يحتاج إلى استجابة سريعة، هذا علاجٌ للعَرَض لا للمرض. أما بقية الحلول الالتفافية لواجهات API العامة فتجدها في بدائل toncenter لعام 2026.

الحلّ الحقيقي — مفتاحك الخاص وTON عبر MCP

جذر المشكلة أنك تتقاسم قناة عامة ضيّقة مع آلاف الطلبات مجهولة الاسم. والسبيل الوحيد لإزالة 429 إزالةً حقيقية هو الحصول على سعة تمريرية مضمونة خاصة بك بدل حصّة مشتركة. عندئذٍ تمرّ دفقة الوكيل ذات الاستدعاءات الستة كاملةً، بدل أن تصطدم بالجدار عند الخامس، ويصير بوسع الوكيل أن يجمع السياق بالسرعة القصوى. وتبقى إعادة المحاولة بالتراجع تأمينًا ضدّ أعطال الشبكة، لكنها تكفّ عن أن تكون آلية النجاة الأساسية.

وثمة طريق يزيل فوق ذلك العبث بحالات HTTP من أساسه. فإن كانت بيانات TON مطلوبة لـوكيل ذكاء اصطناعي تحديدًا، فالأنسب ألا تسلّمها إليه ردًّا REST خامًا يحتاج إلى تحليل ومعالجة لحالات 429، بل أدواتٍ جاهزة عبر MCP.

MCP (Model Context Protocol) معيارٌ يستدعي عبره وكلاء الذكاء الاصطناعي (Claude وCursor وChatGPT/Codex وأي عميل MCP) أدوات خارجية. فبدل أن تعلّم الوكيل كيف يصوغ طلب HTTP صحيحًا إلى toncenter، ويلتقط 429، ويقرأ Retry-After، ويحلّل JSON — تعطيه أدوات مُحدَّدة الأنواع، ويتولّى الخادم عنك كلّ العمل الشاقّ مع الشبكة.

TONNode خادم MCP مُستضاف لشبكة TON، بـ 16 أداة بالضبط. وتلك القراءات الستّ التي يخترق بها الوكيل عادةً حدّ toncenter هي هنا استدعاءات جاهزة:

  • get_masterchain_info — رأس الماسترتشين؛
  • get_balance — رصيد GRAM؛
  • get_account_state — الحالة والأعلام وآخر معاملة؛
  • get_transactions — تاريخ المعاملات؛
  • run_get_method — أي get-method للقراءة فقط في العقد؛
  • get_jetton_balance — رصيد جيتون أو USDT (وعنوان محفظة الجيتون يُحسب على السلسلة).

(وبالمناسبة، GRAM هو Toncoin بعد إعادة تسميته في يونيو 2026. أما الشبكة فما زالت تُسمّى TON، ولم يتغيّر سوى اسم العملة.)

وتحت الغطاء تعمل حزمة @tonnode/mcp عبر بروتوكول TON الأصلي — ADNL، دون طبقات HTTP وسيطة. أي إنك لا تستعيض عن نقطة نهاية REST بأخرى مثلها فحسب: فالوكيل يتحدّث إلى الشبكة مباشرةً، وأنت تكفّ عن تفكيك دلالات الحدود في HTTP يدويًا. والحزمة مفتوحة المصدر (MIT)، وموجودة على npm وGitHub (tonnode/mcp).

والفرق عمليًّا: لم يعد الوكيل بحاجة إلى أن يعرف ما 429، ولا Retry-After، ولا مهلة ADNL. يقول «أعطني رصيد هذا العنوان وآخر معاملاته» — فيحصل على ردّ مُهيكل. والدفقة نفسها ذات الاستدعاءات الستة تذهب إلى خادم لديه سعة تمريرية تحت مفتاحك، لا إلى حدّ عامّ مشترك.

كيف تربطه ومن أين تبدأ مجانًا

أمامك طريقان، ويمكنك البدء دون تسجيل أصلًا.

مجانًا ومحليًّا

مجموعة أدوات القراءة الكاملة عبر الإعداد العام — أضف فقط إلى إعدادات عميل MCP لديك:

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

لا مفاتيح، وnpx سيجلب الحزمة بنفسه. وهذا يكفي لتجرّب وتتأكّد أن الوكيل يقرأ TON دون 429 واحد. والتفصيل في دليل MCP لشبكة TON مجانًا.

نقطة نهاية مُستضافة بمفتاحك الخاص

وحين تحتاج إلى سعة تمريرية مضمونة تحت حِمل حقيقي، تربط نقطة النهاية المُستضافة بمفتاحك:

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

ثم تتحدّث إلى الوكيل بلغة البشر — وهو سيختار الأداة اللازمة بنفسه:

«تحقّق من العنوان EQC…: خذ الرصيد عبر get_balance، وحالة الحساب عبر get_account_state، وآخر 10 معاملات عبر get_transactions. ثم انظر رصيد USDT عبر get_jetton_balance

سيستدعي الوكيل الأدوات اللازمة بالترتيب اللازم — بدل أن يرتطم بحدّ المعدل ارتطامًا أعمى.

الباقات

على كلّ الباقات تتوفّر الأدوات الـ16 كاملةً — وأنت لا تدفع إلا مقابل السعة التمريرية:

الباقة السعر السعة التمريرية
Hobby مجانية إلى الأبد 60 طلبًا/دقيقة
Pro $29/شهر 300 طلب/دقيقة
Scale $199/شهر 1200 طلب/دقيقة

حتى باقة Hobby المجانية بـ 60 طلبًا/دقيقة تضعك في وضع مختلف تمامًا عن toncenter العامّ بحدّه القريب من 1 rps: العدد نفسه تقريبًا — نحو 60 طلبًا في الدقيقة — لكنه هذه المرة مضمون لك أنت، لا مشترك مع حشد من المجهولين. ودفقة الوكيل ذات العشرة استدعاءات تمرّ كاملةً، دون 429 واحد. ويُصدَر مفتاح Hobby فور تسجيل الدخول، بلا بطاقة.

أما الباقات المدفوعة فيمكن سدادها بـ GRAM أو USDT على شبكة TON عبر TonConnect، أو بـ BTC/ETH/SOL وغيرها عبر حساب xRocket في Telegram.

وهنا تحفّظان صادقان كي لا تتضخّم التوقّعات: تغطّي TONNode اليوم مهامّ القراءة وبناء المعاملات، لكنها لا تقدّم كمنتجات جاهزة الدفعَ لكل طلب (pay-per-request)، ولا REST API v2، ولا الويب-هوكس، ولا بثّ SSE، ولا اتفاقية مستوى خدمة (SLA) مكتوبة بنسب جهوزية. والعقدة الأرشيفية ذات التاريخ العميق ما زالت تُزامَن — وهذا بندٌ في خارطة الطريق، لا ضمان اليوم. وكلّ ما وُصف أعلاه يعمل بالفعل الآن.

خطة انتقال عملية

  1. خذ مفتاح Hobby المجاني (60 طلبًا/دقيقة، بلا بطاقة): tonnode.io/dashboard?plan=hobby.
  2. أدرج الإعداد المُستضاف أعلاه في عميل MCP لديك.
  3. استعِض عن الاستدعاءات اليدوية إلى toncenter بالأدوات get_balance وget_account_state وget_transactions وrun_get_method وget_jetton_balance.
  4. وحالما يصطدم الوكيل بحدّ 60 طلبًا/دقيقة تحت الحِمل — انتقل إلى Pro بـ $29/شهر (300 طلب/دقيقة): tonnode.io/pricing.

الخلاصة

  • 429 «Too Many Requests» على toncenter ارتطامٌ بالحدّ العامّ القريب من 1 rps، لا عطبٌ في كودك. (وهو قطعًا ليس «228» — فهذا الرمز لا وجود له.)
  • وكلاء الذكاء الاصطناعي يقعون فيه أكثر من الجميع بسبب نمط الدفقات: عشرات الاستدعاءات في نبضة استدلال واحدة.
  • إعادة المحاولة بالتراجع الأسّي، وRetry-After، والسيمافور، والتخزين المؤقّت تخفض تواتر 429 لكنها لا تحرّك السقف — والثمن هو السرعة.
  • والمخرج الحقيقي مفتاحٌ خاص بسعة تمريرية مضمونة. وإن كانت البيانات مطلوبة للوكيل تحديدًا، فإن TONNode تسلّم قراءات TON نفسها بوصفها أدوات MCP، فيختفي سؤال «كيف أعالج 429» من كودك ببساطة.

ابدأ مجانًا: احصل على مفتاح Hobby — 60 طلبًا/دقيقة، بلا بطاقة. وإن كان لدى وكيلك حِمل حقيقي ودفقات كثيفة — فخذ مباشرةً Pro بـ $29/شهر، 300 طلب/دقيقة.

امنح وكيلك الوصول إلى TON

16 أداة MCP: قراءة ومبادلات غير وصائية وعبر السلاسل ومحافظ. الباقة المجانية — 60 طلب/دقيقة، بلا بطاقة.