توليد الصور في Gemini باستخدام الموجه

صِف المشكلة/الخطأ/السؤال

مرحباً بالجميع،
أواجه مشكلة في سلوك التنفيذ المتداخل داخل عقدة Loop Over Images.

إعدادي:

  1. Loop Over Images: معالجة قائمة الصور المجلوبة من Google Drive واحدة تلو الأخرى (Batch Size = 1).
  2. داخل الحلقة: لكل صورة، يتم إنشاء مجلد (Create Concept Folder) وتحميل ملف الصورة.
  3. توسع العناصر: ثم تقوم عقدة Code (Build Prompts) بأخذ بيانات الصورة الفردية وتوليد 6 متغيرات مطالبة مختلفة (توسيع عنصر دخول واحد بنجاح إلى 6 عناصر خروج).
  4. المعالجة: تنفذ العقد اللاحقة (Gemini data وHTTP Request وUpload Concept Image) 6 مرات بشكل مثالي للصورة الأولى.
  5. عودة الحلقة: في نهاية سلسلة التنفيذ، أستخدم عقدة Limit بـ Max Items = 1 لتقليل 6 عناصر إلى عنصر واحد بالضبط قبل إعادته إلى منفذ دخل Loop Over Images.

المشكلة:

  • التكرار الأول يعمل بدون أخطاء (ينشئ المجلد، وينشئ ويحمل جميع 6 صور المفهوم).
  • في التكرار الثاني (للصورة الثانية)، تنشّط الحلقة بشكل صحيح، وتنفذ عقدة Create Concept Folder بنجاح.
  • ومع ذلك، مباشرة بعد إنشاء المجلد، يتوقف سير العمل تماماً. العقد اللاحقة (Download Image وBuild Prompts وغيرها) لا تُنفذ على الإطلاق للعنصر الثاني.
    يبدو أن n8n يفقد تتبع تسلسل التنفيذ أو فهرس العنصر أثناء التكرار الثاني من الحلقة لأن عدد العناصر تم توسيعه من 1 إلى 6 داخل جسم الحلقة، على الرغم من أنني استخدمت عقدة Limit لإرجاع عنصر واحد بالضبط إلى عداد الحلقة.
    كيف يمكنني إعادة تعيين سياق/فهرس العنصر بشكل صحيح داخل الحلقة بحيث يعمل التكرار الثاني بالكامل؟
    (ملاحظة: أرفق لقطة شاشة لتخطيط سير العمل أدناه)

ما رسالة الخطأ (إن وجدت)؟

يرجى مشاركة سير العمل الخاص بك


(حدّد العقد على لوحتك واستخدم اختصارات لوحة المفاتيح CMD+C/CTRL+C و CMD+V/CTRL+V لنسخ ولصق سير العمل.)

شارك الإخراج الذي أرجعته العقدة الأخيرة

معلومات عن إعداد n8n الخاص بك

  • إصدار n8n:
  • قاعدة البيانات (الافتراضي: SQLite):
  • إعداد n8n EXECUTIONS_PROCESS (الافتراضي: own, main):
  • تشغيل n8n عبر (Docker, npm, n8n cloud, تطبيق سطح المكتب):
  • نظام التشغيل:

مرحباً، يبدو أن هذه مشكلة في بنية الحلقة بدلاً من شيء يمكنك إصلاحه بـ “إعادة تعيين” فهرس العنصر. عقدة Limit تقلل فقط من عدد العناصر التي يتم تمريرها للأمام؛ وهي لا تستعيد سياق العنصر الخارجي الأصلي. في n8n، يُهم ربط العناصر عندما تقوم عقدة بتوسيع أو تحويل العناصر، خاصة عندما تعتمد التعبيرات لاحقاً على .item أو بيانات العقدة السابقة.

سأعيد هيكلتها كحلقة متداخلة مناسبة:

الحلقة الخارجية: Loop Over Images
Create Concept Folder
Download Image
Build Prompts

ثم الحلقة الداخلية: Loop Over Prompts
Gemini data
Generate Concept Image
Prepare Binary
Upload Concept Image
→ العودة إلى Loop Over Prompts

بعد انتهاء Loop Over Prompts الداخلية، قم بربط مخرج Done الخاص بها مرة أخرى إلى عقدة Loop Over Images الخارجية حتى تبدأ الصورة التالية. لا تقم بإدخال أحد العناصر الستة المُنتجة من الفوري/الصورة مرة أخرى في حلقة الصورة الخارجية. عقدة Loop Over Items في n8n مخصصة لمعالجة الدفعات والمتابعة من مسارات الحلقة/المنتهية، والعقد غالباً ما تعالج القوائم تلقائياً، لذا يجب التحكم في عدد العناصر من خلال بنية الحلقة بدلاً من إصلاحها باستخدام Limit.

أيضاً، في عقدة Code الخاصة بـ Build Prompts، انسخ حقول الصورة والمجلد الأصلية إلى كل من العناصر الستة المُنتجة من الفوري، على سبيل المثال imageId وimageName وfolderId ومسار الملف المُنزل. بهذه الطريقة، لن تحتاج خطوة التحميل إلى الاعتماد على مراجع العناصر الخارجية الضعيفة. إذا كنت تستخدم تعبيرات .item لاحقاً، فتأكد من أن عقدة Code تحافظ على ربط العناصر/pairedItem، لأن n8n تحتاج إلى هذا الربط عندما يصبح عنصر إدخال واحد عناصر إخراج متعددة.

مرحبا @Gokhan_ARSLANTAS أهلا وسهلا!
يمكنك حذف الحلقة بالكامل. Create Concept Folder يعمل بالفعل مرة واحدة لكل صورة واردة، لذلك قم بتغذية قائمة ملفات Drive مباشرة فيها، ثم دع عقدة Code واحدة تصدر كل مزيج من الصور والمحفزات كعناصر مسطحة (صورتان، 6 محفزات = 12 عنصر)، يحمل كل منها folderId و fileId و prompt خاصة به:

const scenarios = ['scenario 1', 'scenario 2', 'scenario 3', 'scenario 4', 'scenario 5', 'scenario 6'];
const images = $('List Images').all();

return $input.all().flatMap((folder, i) => scenarios.map((s, n) => ({
  json: {
    folderId: folder.json.id,
    fileId: images[i].json.id,
    filename: `${images[i].json.name}-v${n + 1}.png`,
    prompt: `${images[i].json.name}, ${s}`
  }
})));

استبدل List Images باسم عقدة قائمة Drive الخاصة بك. ثم تعمل Download Image و Gemini data و HTTP Request و Upload Concept Image كل واحدة مرة واحدة لكل عنصر، لذلك الشيء بأكمله هو خط واحد مستقيم بدون عقدة حلقة وبدون حافة تغذي مرة أخرى في أي شيء.
إذا كانت صورة API تفرض حدود معدل عليك، قم بتقليل سرعة عقدة HTTP Request باستخدام Add Option > Batching (Items per Batch = 1, Batch Interval = 1000) بدلا من وضع حلقة مرة أخرى.

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

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

مرحباً @Gokhan_ARSLANTAS
نعم. صورة واحدة فقط تعني أن عقدة Code تُصدر 6 عناصر بدلاً من 12، وكل من Download Image و Gemini data و HTTP Request و Upload Concept Image يعمل 6 مرات. لا شيء آخر يتغير.
إذا كانت هناك دائماً صورة واحدة بالضبط، يمكنك حذف إقران الفهرس والحفاظ على البنية المسطحة:

const scenarios = ['scenario 1', 'scenario 2', 'scenario 3', 'scenario 4', 'scenario 5', 'scenario 6'];
const image = $('List Images').first().json;
const folderId = $input.first().json.id;

return scenarios.map((s, n) => ({
  json: {
    folderId,
    fileId: image.id,
    filename: `${image.name}-v${n + 1}.png`,
    prompt: `${image.name}, ${s}`
  }
}));

اترك عقدة Code على Mode: Run Once for All Items، وهو الإعداد الافتراضي، لأن الكود يُرجع مصفوفة العناصر الكاملة بـ 6 عناصر بنفسه.

أؤكد تشخيص جيمس، وهو بالضبط المشكلة الكلاسيكية لخلط مستويات الحلقات في n8n.

عقدة Limit لا تقوم بـ “إعادة تعيين” أي شيء من سياق الحلقة الخارجية — فهي تقتصر على تصفية عدد العناصر التي تمر. تبقى Loop Over Images تتوقع أن يكون للتدفق الذي يعود إلى مدخلاتها نفس “الشكل” (نسب العناصر) الذي خرج منها، وعندما تضع عقدة Code توسع 1→6 في المنتصف، تكسر هذا النسب حتى لو اختزلتها إلى 1 لاحقاً باستخدام Limit.

حل الحلقة المتداخلة الذي يقترحه جيمس هو الصحيح. هناك بعض الأشياء التي يجب الانتباه لها عند تطبيقك له:

  • في عقدة Code Build Prompts، تأكد من إرجاع pairedItem بشكل صريح في كل واحد من العناصر الستة المُنتجة، مشيراً إلى فهرس العنصر الأصلي. وإلا، فإن أي تعبير لاحق يعتمد على بيانات من العنصر الأب (imageId، folderId، وما إلى ذلك) قد يفشل بصمت بدلاً من إظهار خطأ.
  • الحلقة الداخلية (Loop Over Prompts) تحتاج إلى Batch Size خاص بها مُعد بشكل صحيح — إذا تركته بنفس حجم الخارجية بالخطأ من نسخ لصق، فستعود إلى نفس الأعراض.
  • تحقق من أن مخرجات “Done” من الحلقة الداخلية (وليس “Loop”) هي ما يعود للخارج — من الأخطاء الشائعة توصيل المنفذ الخاطئ والبقاء عالقاً في حلقة لا نهائية أو قصيرة.

يجب أن يحل هذا المشكلة من التكرار الثاني فما بعده.