[خلل/قيد] Vertex AI يرجع 400 Bad Request بعد استقبال استجابة أداة سير العمل الفرعي — السبب الجذري: n8n يرجع دائماً مصفوفة بدلاً من كائن

الوصف

أستخدم عقدة AI Agent في n8n مع Vertex AI (Gemini) كنموذج الدردشة، مدمجة مع أداة سير عمل فرعي تسمى search_rag التي تبحث في قاعدة بيانات متجهة Qdrant.

في كل مرة يستدعي AI Agent الأداة ويستقبل الرد، يفشل العامل فوراً مع:

Bad request - please check your parameters Google request failed with status code 400

لا توجد تفاصيل خطأ إضافية — لا توجد تتبعات للمكدس، لا توجد أخطاء على مستوى الحقل من Google.


السبب الجذري المحدد

بعد تصحيح أخطاء مكثف، حددت السبب الجذري التالي:

1. يتطلب Vertex AI/Gemini أن يكون functionResponse كائن JSON {}، وليس مصفوفة JSON []

يمتلك Gemini API متطلبات أكثر صرامة من OpenAI فيما يتعلق بصيغة functionResponse. تحديداً، يتوقع Gemini أن تكون استجابة الأداة كائن، وليس مصفوفة. عندما يُرجع سير العمل الفرعي [{...}] (مصفوفة تحتوي على كائن)، يعرّف Gemini هذا كحمل عمل غير صحيح ويُرجع خطأ 400 في خطوة التحقق من الطلب — قبل أن تقوم النموذج حتى بمعالجة المحتوى. هذا هو السبب في أن خطأ 400 «صامت» بدون تفاصيل على مستوى الحقل.

2. سير العمل الفرعي في n8n يُرجع دائماً مصفوفة — لا يمكن تغيير هذا

هذا هو السلوك الافتراضي في n8n: تُغلف جميع مخرجات سير العمل في مصفوفة [{...}]. الطريقة الوحيدة للإرجاع كائن بدلاً من مصفوفة في n8n هي استخدام الرد على Webhook مع First Incoming Item — لكن هذا النهج لا يمكن تطبيقه على أدوات سير العمل الفرعي داخل AI Agent.

3. LangChain يقوم بتسلسل الصيغة الخاطئة لـ Vertex AI

تستخدم عقدة Agent في n8n مجموعة LangChain للتواصل مع Vertex AI. يقوم LangChain بتسلسل مخرجات الأداة في سلسلة JSON ويضعها في functionResponse، لكن إذا كانت البنية على المستوى الأعلى مصفوفة، فإن بعض إصدارات SDK من Vertex AI ترفضها في خطوة التحقق قبل أن تقوم النموذج بمعالجتها.


مثال ملموس

ما يُرجعه سير العمل الفرعي حالياً (مصفوفة — غير صحيح لـ Vertex AI):

[
{
"message": "Found 3 result(s) for collection_type: media.",
"searchResults": [...],
"count": 3
}
]

ما يتوقعه Vertex AI (كائن — صحيح):

{
"message": "Found 3 result(s) for collection_type: media.",
"searchResults": [...],
"count": 3
}


ما تم تأكيده

  • سير العمل الفرعي ينفذ بنجاح ويُرجع استجابة صحيحة
  • الخطأ يحدث بعد استقبال العامل لاستجابة الأداة، وليس قبله
  • الخطأ يحدث في كلا الحالتين: عند العثور على النتائج و عند عدم العثور على نتائج
  • لا توجد قيم فارغة أو غير محددة في الاستجابة
  • Vertex AI لا يتطلب اسم حقل معين — message و result و output كلها مقبولة
  • Vertex AI لا يحظر المصفوفات المتداخلة — searchResults: [...] داخل كائن بخير
  • القيد الوحيد هو: يجب أن تكون المستوى الأعلى كائن {}، وليس مصفوفة []

الأسئلة

  1. هل هناك أي طريقة لجعل أداة سير عمل فرعي في n8n تُرجع كائن JSON بدلاً من مصفوفة JSON لـ Vertex AI؟
  2. هل هذا تحديد معروف من تكامل n8n + Vertex AI؟
  3. هل لدى فريق n8n خطط لإصلاح مجموعة LangChain لفك تغليف المصفوفة تلقائياً في كائن عند استخدامها مع Vertex AI؟

مرحباً @nguyenthieutoan
المصفوفة لا تصل أبداً إلى Vertex. عقدة Vertex الفرعية تعمل على @langchain/google-common، والتي تحلل مخرجات الأداة وترسلها كـ functionResponse.response = { content: <output> }، لذلك المستوى الأعلى هو بالفعل كائن سواء أرجعت سير العمل الفرعي [{...}] أو {...}. رمز 400 في الدور التالي لاستدعاء أداة هو توقيع thought_signature في Gemini 3.x: يضع النموذج توقيعاً على جزء functionCall، n8n لا يعيده، و Vertex يرفض الطلب التالي. العقدة تعرض فقط رمز الحالة، وهذا هو السبب في أن الخطأ يبدو فارغاً. نماذج 2.5 لا تتطلب التوقيع، لذا اضبط Model Name على عقدة Google Vertex Chat Model الخاصة بك على gemini-2.5-flash واكتمل حلقة الأداة. للبقاء على نموذج 3.x، استخدم عقدة Google Gemini Chat Model مع مفتاح AI Studio، نقطة النهاية هذه لا تفرضها.
انظر إلى هذا:

ما رأيك؟

@nguyenthieutoan — إذا كنت تبحث عن طريقة نظيفة للحفاظ على إعداد سير العمل الحالي لديك دون الوقوع في مشكلة التحقق من التوقيع في Gemini 3.x، فإن استبدال عقدة Vertex بعقدة Google Gemini Chat Model عبر مفتاح API الخاص بـ AI Studio عادة ما يكون الحل الأسرع الذي يحافظ على القدرة الكاملة للنموذج.

بدلاً من ذلك، إذا كنت بحاجة إلى البقاء بدقة على Google Cloud / Vertex AI للامتثال للمتطلبات المؤسسية، يمكنك توجيه استجابة الأداة عبر عقدة غلاف HTTP Request خفيفة الوزن قبل إعادتها إلى حمولة Agent للحفاظ على نافذة السياق الكاملة.

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

شكراً لإعلامك بهذا، لقد أنشأنا CV-37 كتذكرة تطوير داخلية للبحث فيها.

شكراً لإعلامك بذلك، لقد أنشأنا AI-2668 كتذكرة تطوير داخلية للبحث في الأمر.

معلومات إضافية لك: بدأ ظهور هذا الخطأ فقط بعد أن قمت بالتحديث إلى الإصدار 2.31.x (قد يحدث أيضاً على 2.29.x أو 2.30.x، لكنني لست متأكداً، لأنني عندما كنت أستخدم الإصدار 2.28.7، لم يحدث هذا الخطأ).

ليس لديّ أي فكرة عن كيفية تتبع الإصدار المحدد الذي سيتضمن إصلاحاً لهذا النوع من المشاكل بدقة.