كيف يمكنني الوصول إلى بيانات وصف استخدام الرمز المميز الذي يتم إرجاعه بواسطة نموذج LLM لطلب معين وتمريره إلى العقد اللاحقة في n8n لمعالجة إضافية، مثل تتبع استهلاك الرموز المميزة وحساب التكاليف والاحتفاظ بسجلات الاستخدام؟
ما رسالة الخطأ (إن وجدت)؟
يرجى مشاركة سير العمل الخاص بك
(حدّد العقد على لوحتك واستخدم اختصارات لوحة المفاتيح CMD+C/CTRL+C و CMD+V/CTRL+V لنسخ ولصق سير العمل.)
شارك المخرجات التي أرجعتها العقدة الأخيرة
معلومات حول إعداد n8n الخاص بك
إصدار n8n: 2.43.5
قاعدة البيانات (الافتراضي: SQLite): افتراضي
إعداد n8n EXECUTIONS_PROCESS (الافتراضي: own, main): main
تشغيل n8n عبر (Docker, npm, n8n cloud, desktop app): Docker
مخرجات عقدة Agent الخاصة بها هي فقط output (بالإضافة إلى intermediateSteps إذا قمت بتفعيل “Return intermediate steps”) - تعداد الرموز يقع على عقدة نموذج الدردشة الفرعية، لأنها العقدة الوحيدة التي ترى الاستجابة الخام للمزود.
طريقتان تعمل:
ضع استدعاء النموذج في سير عمل فرعي خاص به: Basic LLM Chain + Chat Model، يتم استدعاؤه عبر Execute Workflow. يحمل العنصر الخاص بالسلسلة tokenUsage ({ promptTokens, completionTokens, totalTokens } على موفري OpenAI)، لذا يحصل الأب على الإجابة والعدادات معاً ويمكنه جمعها في مجموع تراكمي أو صيغة تكلفة.
دع المزود يتولى المحاسبة - تعيد نقطة نهاية الجيل في OpenRouter تعداد الرموز والتكلفة بالدولار الأمريكي لاستدعاء معين، لذا لا توجد مخرجات عقدة يمكن الوثوق بها على الإطلاق.
فخ تستحق معرفته قبل بناء هذا: عامل الأدوات يجري استدعاء نموذج واحد لكل جولة أداة ذهاباً وإياباً، وليس واحداً لكل تشغيل سير عمل. جمع كل تنفيذ سير عمل يقلل العد بعدد التكرارات، لذا عد لكل تنفيذ نموذج. وقم بتشغيل سير العمل مرة واحدة وافتح بيانات تشغيل عقدة نموذج الدردشة الفرعية أولاً - فهي توضح بالضبط ما يعيده مزودك في إصدار n8n الخاص بك.
تُخزّن الأعداد لكل استدعاء بالفعل، لكنها ليست على مخرجات الوكيل. في كل مرة يرد فيها عقدة نموذج الدردشة، يسجّل n8n عملية تشغيل لتلك العقدة مع استخدام المزوّد المرفق. يحصل وكيل الأدوات على عملية تشغيل واحدة لكل استدعاء نموذج، وهذا هو المستوى الذي تريده لتتبع التكاليف.
في بيانات التنفيذ، تبدو كل عملية من هذه العمليات هكذا:
runData['<Chat Model node>'][i].data.ai_languageModel[0][0].json.tokenUsage
// { promptTokens, completionTokens, totalTokens }
عندما لا يعيد المزوّد أي استخدام، يخزّن n8n عداده الخاص باسم tokenUsageEstimate في نفس المكان، لذا سجّل أيهما حصلت عليه.
لا يمكنك قراءة ذلك من داخل التنفيذ الجاري، لذا سأفعله في سير عمل منفصل صغير للتسجيل:
حدّد المشغّل كل 15 دقيقة.
طلب HTTP إلى نسختك الخاصة بمفتاح واجهة برمجة التطبيقات n8n: GET /api/v1/executions?workflowId=<id>&status=success&includeData=true&startedAfter=<last checkpoint>
قسّم على data، بحيث يصبح كل تنفيذ عنصراً واحداً.
عقدة Code (تشغيل مرة واحدة لجميع العناصر) التي تجمع كل تشغيل نموذج في كل تنفيذ:
const out = [];
for (const item of $input.all()) {
const ex = item.json;
const runData = ex.data?.resultData?.runData ?? {};
let prompt = 0, completion = 0, calls = 0, estimated = false;
for (const runs of Object.values(runData)) {
for (const run of runs) {
const res = run.data?.ai_languageModel?.[0]?.[0]?.json;
const usage = res?.tokenUsage ?? res?.tokenUsageEstimate;
if (!usage) continue;
if (!res.tokenUsage) estimated = true;
prompt += usage.promptTokens ?? 0;
completion += usage.completionTokens ?? 0;
calls++;
}
}
out.push({ json: { executionId: ex.id, workflowId: ex.workflowId, startedAt: ex.startedAt, calls, prompt, completion, estimated } });
}
return out;
أدخل في جدول بيانات مفتوح حسب executionId، بحيث لا يؤدي تشغيل المسجل مرتين على نفس النافذة إلى عدّ مزدوج. احتفظ بالأسعار لكل نموذج في جدول ثانٍ واضرب هناك، لأن الأسعار تتغير أكثر من سير العمل.
يمشي عبر جميع العقد، لذا يستخرج أيضاً نموذجاً ثانياً، مثل نموذج احتياطي أو نموذج داخل وكيل فرعي. يجب فحص إعدادين: يجب حفظ عمليات التنفيذ الناجحة في الإنتاج (إعدادات سير العمل أو EXECUTIONS_DATA_SAVE_ON_SUCCESS)، وأن يعمل المسجل قبل أن يحذف التقليص. إذا كنت تريد تكلفة العمليات الفاشلة أيضاً، قم بمرتين ثانية مع status=error. الوكلاء الذين يحلقون على أداة قبل الفشل غالباً ما يكونون الأغلى.
بالنسبة لطلب واحد، سأستخدم HTTP Request لاستدعاء المزود، والحفاظ على JSON الخام، ثم استخدام Edit Fields أو Code لتمرير الاستخدام جنباً إلى جنب مع الإجابة إلى عقدة التسجيل الخاصة بك.
مع عقدة OpenAI العادية، قم بتعطيل Simplify Output أولاً. بالنسبة إلى Chat Completions، افحص usage.prompt_tokens و usage.completion_tokens و usage.total_tokens. يستخدم Responses input_tokens و output_tokens بدلاً من ذلك.
حالة AI Agent تحتاج إلى معاملة منفصلة: الاستخدام المرئي في عقدة Chat Model الفرعية لا يتم بالضرورة تمريره إلى الإخراج الرئيسي. نقله إلى سير عمل فرعي لن يعرض تلقائياً بيانات التعريف المفقودة، و Return Intermediate Steps ليس محاسبة استخدام كاملة.
سجل كل استدعاء نموذج، بما في ذلك المحاولات الجديدة، مع معرّف الاستجابة والنموذج الخاص به. احتفظ بالاستخدام المفقود كمجهول، احسب تكاليف الإدخال والإخراج بشكل منفصل، وحساب التخزين المؤقت. يتتبع مثال HTTP Request استدعاء واحد؛ سير عمل الوكيل يحتاج إلى محاسبة عبر حلقة أداتهم.
مرحباً @AstralVyom، بالنسبة لحالة AI Agent، فعّل Save execution progress → Save في إعدادات سير العمل. يتيح ذلك لعقدة بعد Agent استرجاع عمليات النموذج المكتملة بينما التنفيذ الكلي لا يزال جارياً.
أضف عقدة n8n بعد Agent: Resource: Execution، Operation: Get، Execution ID:={{ $execution.id }}، وInclude Execution Details مفعّلة. وصّل مخرجاتها إلى كود الجمع الخاص بـ @retailbox_michael، والذي يقرأ data.resultData.runData ويتعامل مع استدعاءات نماذج متعددة.
قد يؤدي حفظ التقدم إلى زيادة الكمون لأنه يحفظ بعد كل عقدة.
هناك مسار آخر يعمل مع وكيل الذكاء الاصطناعي العادي، دون إعادة تنظيم أي شيء إلى سلاسل: قراءة عدد الرموز مرة أخرى من التنفيذ بعد انتهائه.
في كل مرة يعمل عقدة النموذج الدردشة الفرعية، يحفظ n8n مخرجاتها في بيانات التنفيذ، وفي موفري النمط OpenAI، يحتوي هذا المخرجات على tokenUsage مع promptTokens و completionTokens و totalTokens. الوكيل ببساطة لا يمرره. لذلك في نهاية سير العمل الخاص بك (أو في سير عمل منفصل يتم تشغيله بواسطته)، أضف عقدة n8n، واختر Execution > Get، وأدخل {{ $execution.id }} وقم بتفعيل Include Execution Details. لاحظ أنه يجب إنهاء التنفيذ الحالي لهذا ليكون لديه كل شيء، لذا الإعداد الأنظف هو أن يستدعي سير العمل الرئيسي سير عمل تسجيل صغير مع Execute Workflow و “Wait for sub-workflow completion” معطّل، مع تمرير معرّف التنفيذ، ثم إضافة Wait لبضع ثوان قبل Get.
في النتيجة، ابحث تحت data.resultData.runData وابحث عن المفتاح باسم عقدة نموذج الدردشة الخاصة بك، على سبيل المثال “OpenAI Chat Model”. هذا مصفوفة تحتوي على إدخال واحد لكل استدعاء نموذج، وهذا مهم لأن وكيل الأدوات يستدعي النموذج مرة واحدة لكل جولة أداة. يمكن لعقدة Code أن تحلقة على تلك المصفوفة وتجمع قيم tokenUsage، ثم اضرب في أسعار الرمز الخاصة بك واكتب صفًا في جدول البيانات أو Google Sheets مع اسم سير العمل ومعرّف التنفيذ وعدد الرموز المطلوبة وعدد رموز الإكمال والتكلفة.
شغّله مرة واحدة وانقر على بيانات تشغيل عقدة نموذج الدردشة أولاً حتى تتمكن من رؤية المسار الدقيق الذي يعيده موفرك، لأن بعض الموفرين يسمون الحقول بشكل مختلف قليلاً. ستحتاج أيضًا إلى مفتاح API n8n معد كبيانات اعتماد لعقدة n8n.