آموزش ساخت AI Agent در n8n روی سرور شخصی (VPS)
در این راهنما یاد میگیرید چگونه با استفاده از نود AI Agent، مدل Claude، ابزار HTTP Request و تنظیمات مدیریت حافظه، یک ایجنت هوشمند در n8n روی VPS خود راهاندازی کنید.
ماهیت یک AI agent در n8n و تفاوت آن با chain
یک AI agent در n8n، یک نود واحد به نام AI Agent است که نودهای فرعی به آن متصل شدهاند: یک مدل چت، یک یا چند ابزار، و یک حافظه اختیاری. شما هدف خود را به زبان ساده بیان میکنید و مدل تصمیم میگیرد که کدام ابزارها را و به چه ترتیبی فراخوانی کند تا بتواند پاسخ دهد. تمام موارد زیر، پیکربندیهای پیرامون همین ایده واحد هستند.
یک chain دقیقاً برعکس عمل میکند. در یک Basic LLM Chain، شما مراحل را تعیین میکنید و مدل فقط متن را تکمیل میکند. در یک agent، مدل مراحل را تعیین میکند؛ بنابراین ممکن است یک سوال مشابه، امروز هزینه یک فراخوانی مدل را داشته باشد و فردا هزینه نه فراخوانی را. همین تفاوت واحد، تمام تنظیمات این راهنما را هدایت میکند. اگر این حلقه (loop) برای شما به عنوان یک مفهوم—و نه فقط یک ویژگی در n8n—جدید است، ارزش دارد که پیش از سرهمبندی آن با نودها، یک بار آن را دستی بنویسید، زیرا نود دقیقاً همان بخشی را پنهان میکند که قرار است در ادامه این راهنما درباره منطق آن بحث کنیم.
این راهنما فرض میکند که n8n هماکنون پشت HTTPS روی ماشینی که کنترل آن را در دست دارید، در حال اجراست. اگر اینطور نیست، با میزبانی n8n روی Docker با گواهی معتبر شروع کنید، زیرا API key که قصد ذخیره آن را دارید، به پشتیبانگیری از کلید رمزنگاری (encryption-key) که در آن راهنما بر آن تأکید شده، نیاز دارد. برای الگوهای غیر-agent، مانند خلاصهسازهای webhook و دستهبندیکنندههای زمانبندیشده، به الگوهای گردشکار Claude و n8n مراجعه کنید.
پیش از اعتماد به هر نام فیلد در اینجا، نسخه n8n خود را بررسی کنید، زیرا n8n نودهای AI را مکرراً تغییر میدهد.
docker compose exec n8n n8n --versionنسخه 1.82.0 تنظیمات agent-type را منسوخ کرد و Tools Agent را جایگزین آن نمود. نودهای قدیمی نسخه 1 همچنان این تنظیم را دارند؛ مستندات n8n حذف آن نسخه از نود را برای n8n 3.0 برنامهریزی کرده است.
گام 1: انتخاب ماشه (Trigger)
برای یک عامل گفتگو (Conversational Agent)، یک گره Chat Trigger اضافه کنید. گزینه Make Chat Publicly Available را در حین ساخت غیرفعال نگه دارید تا فقط پنل چت ویرایشگر به آن دسترسی داشته باشد. پس از تکمیل عامل و تصمیمگیری در مورد احراز هویت، آن را فعال کنید.
گره Chat Trigger فیلدی با نام chatInput را به عامل تحویل میدهد. این نام در گام 3 اهمیت دارد و اشتباه در آن، رایجترین خطای اولیه است.
برای یک عامل بدون نظارت (Unattended Agent)، از یک گره Schedule Trigger یا Webhook استفاده کنید. هیچکدام از اینها chatInput تولید نمیکنند، بنابراین باید prompt را خودتان بنویسید.
گام 2: اعتبارنامه مدل
یک نود AI Agent را روی بوم (canvas) قرار دهید. n8n بلافاصله یک کانکتور خالی Chat Model را در زیر آن نمایش میدهد. یک زیر-نود Anthropic Chat Model را به آن متصل کنید.
اعتبارنامه را از کنسول Claude در آدرس platform.claude.com، در بخش Settings و سپس API keys ایجاد کنید. کلید فقط یک بار نمایش داده میشود. کنسول هنگام ایجاد کلید از شما میخواهد که یک تاریخ انقضا انتخاب کنید؛ یک ایجنت بدون نظارت (unattended) در روز انقضای کلیدش از کار میافتد، بنابراین آن تاریخ را در جایی یادداشت کنید که در دسترستان باشد. برای یک ایجنت بدون نظارت، از کلید service account با محدوده (scope) یک workspace استفاده کنید تا درخواستها نیازی به هدر جداگانه workspace نداشته باشند.
هزینه استفاده از API بر اساس توکن محاسبه میشود و نحوه پرداخت آن، مطابق وضعیت تا تاریخ 31 October 2026، به طرح Claude شما بستگی دارد. طرحهای Max، Ultra و Team شامل اعتبار ماهانه API هستند: 100 دلار برای Max، 200 دلار برای Ultra و تا 500 دلار به صورت اشتراکی برای Team. شما میتوانید این اعتبار را با متصل کردن یک سازمان در کنسول به طرح مربوطه از مسیر Settings > Billing در طرحهای Max یا Ultra، یا Organization settings > Billing در طرح Team دریافت کنید و نیازی به افزودن روش پرداخت در کنسول نیست. مشترکین جدید میتوانند پس از 7 روز حضور در طرح، اعتبار خود را دریافت کنند و اعتبار استفادهنشده در پایان هر دوره صورتحساب، یا به صورت ماهانه در طرحهای سالانه، منقضی میشود. هنگامی که اعتبار موجود تمام شود، درخواستها از محل اعتبار خریداریشده کسر میشوند، قابلیت auto-reload میتواند اعتبار بیشتری تهیه کند و سازمانهایی که صورتحساب دریافت میکنند، برای استفاده مازاد شارژ میشوند. درخواستها زمانی متوقف میشوند که یک سازمان پیشپرداختشده هیچ اعتباری نداشته باشد؛ هزینه استفاده از API هرگز از طرح Claude شما کسر نمیشود. طرحهای Free، Pro و Enterprise هیچ اعتبار ماهانه API ندارند، بنابراین در این طرحها هزینه API جدا از اشتراک محاسبه میشود.
مدل را بر اساس هر ایجنت انتخاب کنید، نه بر اساس شرکت. یک ایجنت تکابزاری که جستجویی انجام میدهد و نتیجه را گزارش میکند، به خوبی روی Haiku اجرا میشود. نسخه فعلی، یعنی Haiku 5.5، مطابق وضعیت تا تاریخ 12 October 2026 با قیمت 0.10 دلار به ازای هر میلیون توکن ورودی و 0.50 دلار به ازای هر میلیون توکن خروجی لیست شده است، که این قیمت برای هر درخواستی که طول پرامپت آن از 100,000 توکن فراتر رود، به 0.50 دلار و 2.50 دلار افزایش مییابد؛ وضعیتی که یک پنجره حافظه طولانی و نتایج بزرگ ابزارها میتواند شما را به آن سمت سوق دهد. هنگامی که ایجنت چندین ابزار دارد و باید برای استفاده از آنها برنامهریزی کند، به سراغ Sonnet بروید. شکستی که باید از آن اجتناب کنید، استفاده از یک مدل ارزان است که چهار بار ابزار اشتباه را فراخوانی میکند، چرا که هزینه آن از مدل گرانقیمتی که یک بار ابزار درست را فراخوانی میکند، بیشتر خواهد بود.
گزینه Maximum Number of Tokens را در تنظیمات زیر-نود تعیین کنید. این گزینه طول هر پاسخی که مدل تولید میکند را محدود میکند. اگر آن را روی مقدار پیشفرض بزرگ رها کنید، یک اجرای اشتباه میتواند پاسخی بسیار طولانی تولید کند و هزینه آن برای شما محاسبه شود.
یک نکته مهم از مستندات n8n که همه با آن مواجه میشوند: عبارتها (expressions) در داخل یک زیر-نود همیشه بر اساس اولین آیتم ورودی ارزیابی میشوند، نه به ازای هر آیتم. عبارتهای مربوط به هر آیتم را در فیلدهای پرامپت نود اصلی (root node) قرار دهید.
گام 3: پرامپتی که ایجنت دریافت میکند
گره AI Agent را باز کنید. پارامتر Source for Prompt (User Message) دارای دو تنظیم است.
- گزینه Connected Chat Trigger Node انتظار یک فیلد ورودی به نام
chatInputرا دارد. این گزینه مناسبترین انتخاب برای استفاده پشت یک Chat Trigger است. - گزینه Define below فیلد Prompt (User Message) را نمایش میدهد که در آن میتوانید متن ثابت یا یک expression بنویسید. این گزینه برای استفاده پشت یک Schedule Trigger یا گره Webhook مناسب است.
هنگامی که یک گره Webhook در ابتدای مسیر قرار دارد، بدنه POST در $json.body قرار میگیرد، بنابراین فیلد پرامپت به شکل زیر خواهد بود.
Check the current status of {{ $json.body.service }} and tell me
whether it is up. If it is down, say for how long. No preamble.گام 4: اختصاص یک ابزار به عامل (Agent)
مستندات n8n بیان میکنند که باید حداقل یک زیر-گره (sub-node) ابزار را به گره AI Agent متصل کنید، اگرچه کد فعلی گره (نسخه 3.1) تنها در صورت نبود مدل چت از اجرا امتناع میکند. در هر صورت، با یک ابزار شروع کنید؛ چرا که یک ابزارِ کارآمد، آموزندهتر از چهار ابزارِ ناقص است و عاملی که هیچ ابزاری ندارد، صرفاً یک زنجیره (chain) پرهزینهتر است.
یک گره HTTP Request را به اتصال Tool در عامل متصل کنید. آن را دقیقاً مشابه یک گره HTTP Request معمولی پیکربندی کنید و سپس ابتدا آن endpoint را از طریق یک shell تست کنید.
curl -s -H 'Accept: application/json' \
https://status.example.com/api/status/database | head -c 400اگر دستور curl خطایی برگرداند یا یک صفحه ورود HTML نمایش دهد، عامل نیز با شکست مواجه خواهد شد و این خطا به گونهای نمایش داده میشود که گویی مشکل از مدل است، در حالی که در واقع مشکل از URL یا احراز هویت است. این مورد را در shell اصلاح کنید، نه در گره.
فیلد Description در ابزار، مستنداتی برای همکاران شما نیست. مدل این فیلد را به همراه نام ابزار و طرحواره پارامترها میخواند تا تصمیم بگیرد که آیا این ابزار مرتبط است یا خیر. آن را به صورت یک جمله ساده درباره خروجی بنویسید: "Returns the current up or down state and the downtime duration for one monitored service, as JSON."
برای اینکه به مدل اجازه دهید بخشی از درخواست را تکمیل کند، از عبارت $fromAI() استفاده کنید. این قابلیت فقط در ابزارهای متصل به گره AI Agent کار میکند و در ابزار Code در دسترس نیست.
{{ $fromAI('service', 'The name of the service to look up', 'string') }}آرگومانها شامل key و سپس مقادیر اختیاری description، type و defaultValue هستند. کلید باید بین 1 تا 64 کاراکتر باشد و از حروف، ارقام، زیرخط و خط تیره استفاده کند. نوع (type) باید یکی از موارد string، number، boolean یا json باشد و مقدار پیشفرض آن string است. یک فراخوانی کاملتر به شکل زیر است.
{{ $fromAI('limit', 'How many records to return', 'number', 20) }}کلید یک راهنما است، نه ارجاع به دادههای موجود. $fromAI('service') فیلدی به نام service را از جایی نمیخواند. این دستور به مدل میگوید "یک مقدار تولید کن و نام آن را service بگذار"، و مدل برای یافتن آن، گفتگو، دادههای ورودی و نتایج سایر ابزارها را جستجو میکند. در یک گردش کار چت، ممکن است مدل به سادگی از کاربر سوال کند.
جستجوی وب معمولاً دومین ابزار رایج است و از آنجایی که این ابزار نیز صرفاً یک endpoint دیگر از نوع HTTP است، میتوانید همین گره را به نمونه SearXNG خودتان به جای یک API جستجوی پولی متصل کنید، مشروط بر اینکه با هر صفحهای که برمیگرداند به عنوان متن غیرقابلاعتمادی که اکنون درون prompt شما قرار گرفته است، برخورد کنید.
گام 5: حافظه و دلیل فراموشی عامل (agent)
بدون یک زیر-گره (sub-node) حافظه، هر پیام از صفر شروع میشود. یک زیر-گره Simple Memory را متصل کنید تا مکالمههای اخیر را نگه دارد.
این گره دو پارامتر دارد. Session Key تعیین میکند که این کدام مکالمه است، بنابراین دو کاربر با کلیدهای متفاوت، تاریخچههای جداگانهای خواهند داشت. Context Window Length مشخص میکند که چه تعداد از تعاملات قبلی در prompt بازپخش شوند.
پارامتر Context Window Length هم یک تنظیمکننده هزینه است و هم یک تنظیمکننده کیفیت، زیرا هر نوبتِ بهخاطر سپردهشده، در هر فراخوانی بعدی بهعنوان توکنهای ورودی دوباره ارسال میشود. یک پنجره با اندازه 20 برای یک عامل پرحرف به این معنی است که شما هزینه پیامهای اولیه را بیست بار پرداخت میکنید.
قابلیت Simple Memory در یک گردشکار عملیاتی (production workflow) فعال، زمانی که n8n در حالت queue mode اجرا میشود، کار نمیکند؛ زیرا تاریخچه را در یک Map تکنمونه (singleton) محلیِ پردازش ذخیره میکند که با IDهای گردشکار و نشست کلیدگذاری شده است و workerها این حافظه را به اشتراک نمیگذارند. در یک نمونه با حالت queue mode، بهجای آن از زیر-گره Postgres Chat Memory استفاده کنید و آن را به پایگاه دادهای متصل کنید که هم پردازش اصلی و هم workerها به آن دسترسی داشته باشند.
گام 6: پیام سیستم (System Message)
گزینههای (Options) ایجنت را باز کرده و یک System Message اضافه کنید. این بخش محل قرارگیری شرح وظایف است و تأثیرگذارترین متن در کل گردش کار محسوب میشود.
You are an infrastructure status assistant. Always call the status
tool before answering a question about whether something is running.
Never guess. If the tool returns an error, say so and stop.دستور "همیشه پیش از پاسخدهی، ابزار وضعیت (status tool) را فراخوانی کن" در اینجا نقش کلیدی ایفا میکند. بدون این دستور، مدلی که تصور میکند پاسخ را میداند، از ابزار صرفنظر کرده و بر اساس حافظه خود پاسخ میدهد؛ پاسخی که به محض تغییر زیرساخت شما، با اطمینان کامل اشتباه خواهد بود.
چرا عامل (agent) در حلقه میافتد و چه چیزی آن را متوقف میکند
همچنین در بخش Options، گزینهای به نام Max Iterations وجود دارد که مقدار پیشفرض آن 10 است. هر تکرار (iteration) شامل یک فراخوانی مدل است که یا درخواست استفاده از ابزارها را میدهد یا پاسخ نهایی را بازمیگرداند؛ نتایج ابزارها به فراخوانی بعدی تزریق میشوند. بنابراین، یک اجرای واحد عامل، تنها یک فراخوانی API نیست، بلکه میتواند تا 10 فراخوانی باشد و هر کدام کل تاریخچهٔ مکالمهٔ در حال رشد را به عنوان ورودی حمل میکنند.
این مقدار را کاهش دهید. اکثر عاملهای تکابزاری در 2 تکرار به پایان میرسند و محدودیت 3 یا 4 تکرار، باعث میشود یک حلقهٔ بیپایان به یک خطای تمیز تبدیل شود که در لیست اجرا قابل مشاهده است.
هنگام دیباگ کردن، گزینهٔ Return Intermediate Steps را فعال کنید. در این صورت خروجی نهایی شامل فراخوانیهای ابزاری است که عامل در طول مسیر انجام داده است؛ این تنها راهی است که میتوانید تفاوت بین «مدل هرگز ابزار را فراخوانی نکرد» و «ابزار هیچ نتیجهٔ مفیدی برنگرداند» را تشخیص دهید. پیش از عملیاتی کردن سیستم، این گزینه را غیرفعال کنید، زیرا این مراحل برای کاربر نهایی نویز محسوب میشوند.
اجرای یک عملیات را از طریق shell مشاهده کنید.
docker compose logs -f n8nجلوگیری از مصرف بیرویه توسط عاملهای خودکار
عاملی که پشت یک Chat Trigger قرار دارد، توسط یک انسان نظارت میشود و در صورت مشاهده پاسخ نادرست، آن انسان عامل را متوقف میکند. اما عاملی که پشت یک Schedule Trigger قرار دارد، هیچ ناظری ندارد. آنچه در اینجا باید کنترل کنید، هزینه مصرف مدل است، نه هزینه لایسنس؛ زیرا گرههای عامل، ابزار و حافظه همگی در نسخه رایگان و self-hosted کار میکنند و ویژگیهایی که نیاز به کلید پولی دارند، عمدتاً مربوط به تیم و حاکمیت هستند. شرح کامل این موضوع در کنترل هزینه عاملهای هوش مصنوعی روی یک VPS همیشه روشن آمده است. چهار تنظیم زیر بیشترین نقش را در این زمینه ایفا میکنند:
- مقدار Maximum Number of Tokens را در زیر-گره مدل محدود کنید تا هیچ پاسخ واحدی نتواند بیش از حد طولانی شود.
- مقدار Max Iterations را روی کوچکترین عددی تنظیم کنید که همچنان وظیفه را به پایان میرساند.
- پاسخهای ابزارها را کوچک نگه دارید. ابزاری که یک فایل JSON با 4000 خط برمیگرداند، تمام آن را در فراخوانی بعدی مدل و سپس در تمام فراخوانیهای بعدی همان اجرا قرار میدهد.
- بررسی کنید که آیا عامل واقعاً به زمانبندی (Schedule) نیاز دارد یا خیر. کاری که هر پنج دقیقه اجرا میشود، 288 بار در روز فعال میگردد. هزینه هر اجرا، عددی است که باید در این تعداد ضرب کنید.
هنگام اعمال تغییرات، انتشار (Publish) گردش کار را لغو کنید یا حداقل به یاد داشته باشید که کدام نسخه فعال است. یک گردش کار منتشرشده با Schedule Trigger، نسخهای را اجرا میکند که آخرین بار منتشر کردهاید، نه پیشنویسی که روی صفحه میبینید؛ زیرا n8n ویرایشهای شما را تا زمانی که دوباره دکمه انتشار را نزنید، در حالت پیشنویس نگه میدارد.
FAQ
چرا نود AI Agent من اجرا نمیشود؟
ابتدا کانکتورها را بررسی کنید. نود AI Agent به یک زیر-نود مدل چت نیاز دارد و بدون آن، پیش از برقراری هرگونه تماس API، با خطای "Please connect a model to the Chat Model input" متوقف میشود. مستندات n8n همچنین وجود حداقل یک زیر-نود ابزار (tool) را الزامی میدانند؛ بنابراین اگر مدل متصل است و نود همچنان کار نمیکند، یک ابزار، حتی یک ابزار ساده، به آن متصل کرده و دوباره اجرا کنید.
ایجنت پاسخ میدهد، اما هرگز ابزار من را فراخوانی نمیکند. مشکل چیست؟
تقریباً همیشه مشکل از فیلد Description ابزار است. مدل، ابزارها را با خواندن این توضیحات انتخاب میکند؛ بنابراین توضیحی مانند "HTTP Request" هیچ اطلاعاتی درباره زمان استفاده از ابزار به مدل نمیدهد. آن را بازنویسی کنید تا مشخص شود چه دادهای بازگردانده میشود و در چه شرایطی مفید است، سپس یک خط به System Message اضافه کنید و به ایجنت دستور دهید پیش از پاسخدهی، آن ابزار را فراخوانی کند.
چرا هزینه یک سوال مشابه در هر بار اجرا متفاوت است؟
زیرا مدل تعداد گامها را انتخاب میکند. هر تکرار، کل مکالمه تا آن لحظه، شامل خروجی ابزارهای قبلی را دوباره ارسال میکند؛ بنابراین اجرایی که چهار تکرار انجام میدهد، هزینه توکنهای ورودی و خروجی را برای هر چهار فراخوانی محاسبه میکند. Max Iterations سقف این تکرارها است و Return Intermediate Steps به شما نشان میدهد که یک اجرای خاص واقعاً از چند گام استفاده کرده است.
حافظه (Memory) من در ویرایشگر کار میکند اما در محیط تولید (production) نه. چه چیزی تغییر کرده است؟
بررسی کنید که آیا این instance در حالت queue mode اجرا میشود یا خیر. Simple Memory تاریخچه را در یک Map محلیِ فرآیند (process-local singleton) ذخیره میکند که با IDهای ورکفلو و نشست (session) کلیدگذاری شده است، و فرآیندهای worker مجزا به آن دسترسی مشترک ندارند. از زیر-نود Postgres Chat Memory استفاده کنید که تاریخچه را در پایگاهدادهای ذخیره میکند که تمام workerها به آن دسترسی دارند.