اتصال هوش مصنوعی به Laravel؛ آموزش امن API و مدیریت خطا
آموزش اتصال هوش مصنوعی به Laravel با HTTP Client، نگهداری امن API Key، اعتبارسنجی، Timeout، Retry، صف و تست Http::fake؛ همراه با روش بررسی اتصال به Avaztek AI.
کاربر فرم پشتیبانی را ثبت میکند و قرار است پاسخ پیشنهادی هوش مصنوعی در پنل اپراتور نمایش داده شود. اگر درخواست مدل مستقیماً از مرورگر ارسال شود، کلید API لو میرود؛ اگر همان درخواست داخل Controller بیپایان منتظر بماند، کاربر با خطای Timeout روبهرو میشود. اتصال هوش مصنوعی به Laravel فقط نوشتن یک دستور HTTP نیست؛ باید مسیر امن کلید، اعتبارسنجی داده، زمانسنجی، مدیریت خطا، صف و ثبت مصرف از ابتدا مشخص باشد.
در این راهنما، یک مسیر پیادهسازی مرحلهبهمرحله با HTTP Client خود Laravel میسازیم. قطعهکدها برای نمایش الگوی اتصال از Backend هستند؛ آدرس API و قرارداد پاسخ باید با Provider واقعی و نسخه API شما تطبیق داده شود. تمرکز این صفحه بر پیادهسازی درخواست امن در Laravel است؛ برای تصمیم معماری چندمدلی راهنمای AI Gateway و برای انتخاب سرویس مقایسه APIهای هوش مصنوعی را جداگانه نوشتهایم.
پیشنیازهای اتصال API هوش مصنوعی به Laravel
یک برنامه Laravel با PHP سازگار با نسخه پروژه، کلید معتبر یک Provider که استفاده از آن برای حساب و محل فعالیت شما مجاز است، یک Endpoint مستند و محیط آزمون نیاز دارید. ابزار داخلی Http در Laravel بر پایه HTTP Client است و برای بیشتر اتصالهای JSON به نصب SDK اضافی نیاز ندارد. قبل از ارسال داده واقعی مشتری، محل پردازش و سیاست محرمانگی Provider را بررسی کنید.
| جزء | مسئولیت | خطر بیتوجهی |
|---|---|---|
| Controller یا FormRequest | اعتبارسنجی و احراز مجوز کاربر | داده نامعتبر و مصرف ناخواسته مدل |
| Config / Secret Manager | نگهداری آدرس مجاز و کلید سرور | نشت API Key در مرورگر یا Git |
| Service برای HTTP | Timeout، خطا و تبدیل پاسخ Provider | منطق تکراری در چند Controller |
| Queue و پایگاهداده | اجرای کار طولانی و پیگیری وضعیت | Timeout کاربر و گمشدن عملیات |
| Usage و Logging | اندازهگیری مصرف و تأخیر بدون متن حساس | هزینه نامشخص و عیبیابی دشوار |
گام اول: کلید API را در مرورگر و Repository قرار ندهید
کلید را فقط در متغیر محیطی یا سامانه مدیریت Secret سمت سرور نگه دارید. افزودن کلید به JavaScript یا Blade حتی در صفحه مدیریت، آن را برای مرورگر قابل مشاهده میکند. برای نمونه، این دو متغیر را در محیط امن تعریف کنید؛ مقادیر نمونه واقعی نیستند:
AI_PROVIDER_URL=https://api.example.com/v1/text
AI_PROVIDER_KEY=replace-with-secret-server-key
آدرس نمونه api.example.com عمداً مستنداتنمایی نمیکند و Endpoint عملیاتی نیست. URL واقعی باید فقط از مستند رسمی Provider گرفته شود. در config/services.php تنظیمها را اضافه کنید:
'ai_text' => [
'url' => env('AI_PROVIDER_URL'),
'key' => env('AI_PROVIDER_KEY'),
],
در کد برنامه از config('services.ai_text.key') استفاده کنید، نه فراخوانی پراکنده env()؛ این کار با config:cache سازگار است. اگر یک کلید در Log، خطای عمومی یا مخزن Git افشا شد، صرف حذفکردن فایل کافی نیست؛ کلید باید از سمت ارائهدهنده لغو و جایگزین شود.
گام دوم: ورودی را قبل از صرف هزینه اعتبارسنجی کنید
در مثال تولید پاسخ پیشنهادی پشتیبانی، متن خالی یا بیش از حد بزرگ نباید مستقیم به مدل ارسال شود. به جای اعتماد به محدودیت HTML فرم، اعتبارسنجی را در Laravel اجرا کنید و قبل از فراخوانی خارجی مجوز دسترسی کاربر به همان درخواست را بسنجید.
// Inside a controller method, after authenticating the user:
$data = $request->validate([
'message' => ['required', 'string', 'min:10', 'max:3000'],
]);
$prompt = trim($data['message']);
// Remove or mask personal information before sending it to a provider.
این کد حد طول ورودی را بر اساس تعداد نویسه کنترل میکند، نه تعداد Token. سقف توکن و هزینه باید در مرحله مستقل تخمین و پس از پاسخ با Usage واقعی تطبیق داده شوند. برای فیلدهایی مانند شماره سفارش یا ایمیل، ارسال حداقل داده ضروری را انتخاب کنید.
گام سوم: با HTTP Client لاراول درخواست کنترلشده بفرستید
برای یک Provider با قرارداد ساده Bearer Token و JSON، میتوان اتصال را در Service متمرکز کرد. کد زیر ساختار عمومی Transport را نشان میدهد؛ model، input و شکل پاسخ باید با Endpoint واقعی بررسی شوند. هیچگاه اجازه ندهید کاربر URL دلخواه برای درخواست سرور تعیین کند؛ این کار میتواند به SSRF منجر شود.
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\ConnectionException;
$url = (string) config('services.ai_text.url');
$key = (string) config('services.ai_text.key');
if (! str_starts_with($url, 'https://') || $key === '') {
throw new \RuntimeException('AI provider configuration is incomplete');
}
try {
$response = Http::acceptJson()
->withToken($key)
->connectTimeout(5)
->timeout(25)
->post($url, [
'model' => $selectedModel,
'input' => $prompt,
]);
} catch (ConnectionException $e) {
// Report a temporary connection problem without exposing credentials.
throw new \RuntimeException('AI connection timed out', 0, $e);
}
if ($response->failed()) {
// Classify the HTTP status; do not return the raw provider body to users.
throw new \RuntimeException('AI provider returned HTTP '.$response->status());
}
$result = $response->json();
if (! is_array($result)) {
throw new \UnexpectedValueException('Invalid AI response format');
}
در نمونه بالا input و model یک قرارداد فرضیاند و برای همه APIها معتبر نیستند؛ مثال عملی بدون انطباق با قرارداد Provider کامل نمیشود. در معماری واقعی، پاسخ باید با Schema اختصاصی همان مدل بررسی شود و فقط داده موردنیاز برنامه به کاربر بازگردد. مستندات HTTP Client لاراول مرجع رفتار timeout، خطا و پاسخ است.
گام چهارم: خطاهای HTTP را به چهار گروه تقسیم کنید
| خطا | معنای معمول | رفتار مناسب برنامه |
|---|---|---|
| 401 یا 403 | کلید، مجوز یا محدودیت حساب/منطقه | توقف درخواست و بررسی دسترسی؛ بدون Retry کور |
| 400 یا 422 | درخواست نامعتبر یا ناسازگار با قرارداد API | بررسی Schema و مدل؛ اصلاح داده |
| 429 | محدودیت نرخ یا سهمیه | بررسی Retry-After و سیاست بودجه، نه تکرار فوری |
| 5xx یا Timeout | اختلال احتمالی سرویس یا مسیر ارتباطی | Retry محدود برای عملیات مجاز و ایمن |
در درخواستهایی که هزینه دارند، Timeout الزاماً به معنی «مدل هیچ کاری نکرده» نیست. ممکن است Provider پاسخ را ساخته اما ارتباط قطع شده باشد. اگر بدون ثبت شناسه درخواست دوباره اجرا کنید، احتمال هزینه تکراری وجود دارد. همچنین خطای اتصال TLS با خطای HTTP 403 یک مسئله نیست؛ برای زیرساخت ایران این تفکیک ضروری است و در راهنمای مشکلات اتصال AI از سرور ایران کاملتر آمده است.
گام پنجم: Retry را محدود و وابسته به نوع خطا کنید
در Laravel میتوان برای تلاش دوباره از retry() استفاده کرد، اما اعمال آن روی همه خطاها، بهخصوص پاسخ ۴۰۱ یا درخواست نامعتبر، فقط هزینه و فشار را بیشتر میکند. اگر از retry() در HTTP Client استفاده میکنید، شرط باید میان خطای اتصال و خطاهای قابل تلاش مجدد تفاوت بگذارد. کد زیر تنها برای عملیات قابل تکرار و بیاثر جانبی مناسب است:
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
$response = Http::withToken($key)
->acceptJson()
->connectTimeout(5)
->timeout(25)
->retry(3, 500, function ($exception) {
if ($exception instanceof ConnectionException) {
return true;
}
return $exception instanceof RequestException
&& in_array($exception->response->status(), [502, 503, 504], true);
}, throw: false)
->post($url, $payload);
مقدار ۵۰۰ میلیثانیه و سه تلاش، عدد آموزشی هستند؛ برای بار واقعی باید Backoff مناسب، محدودیت مجموع زمان و سیاست Provider را تنظیم کنید. بسته به نوع خطا، حتی با throw: false خطای اتصال ممکن است همچنان Exception بدهد و باید try/catch داشته باشید. اگر فراخوانی قابل تکرار ایمن نیست یا مدل هزینه تکراری ایجاد میکند، Retry خودکار را حذف کنید یا از قابلیت Idempotency رسمی Provider کمک بگیرید.
گام ششم: درخواست طولانی را به Job تبدیل کنید
درخواست HTTP وبسایت نباید تا پایان تحلیل سند طولانی باز بماند. برای کارهای چندثانیهای یا حجیم، ابتدا رکوردی با شناسه تصادفی و وضعیت pending در پایگاهداده ذخیره کنید و Job را بعد از ثبت موفق به صف بفرستید. کاربر شناسه درخواست میگیرد و وضعیت را از Endpoint مجاز پیگیری میکند؛ Job میتواند نتیجه را ذخیره کند و شکستها را قابل مشاهده نگه دارد.
// Schematic controller pattern; create the model and job separately.
$task = AiTask::create([
'user_id' => auth()->id(),
'status' => 'pending',
'request_key' => (string) Str::uuid(),
]);
ProcessAiTask::dispatch($task->id)->afterCommit();
return response()->json([
'task_id' => $task->id,
'status' => $task->status,
], 202);
این قطعه برای نشاندادن الگوست و کلاسهای AiTask و ProcessAiTask باید در پروژه پیادهسازی شوند. صرف ساخت Job بدون Worker فعال، ذخیره وضعیت و بازیابی کارهای معطل کافی نیست. برای رفتار afterCommit() و Workerها، مستندات رسمی Queue لاراول را متناسب با نسخه پروژه بررسی کنید.
گام هفتم: امنیت، هزینه و لاگ را در یک Service کنترل کنید
هر درخواست باید با شناسه کاربر یا پروژه، مدل انتخابشده، زمان شروع، مدت اجرا و کد خطای پاکسازیشده قابل ردیابی باشد. متن خام Prompt و Tokenهای API را بدون ضرورت ثبت نکنید. پاسخ مدل برای عملیات حساس باید ابتدا اعتبارسنجی شود؛ هیچ خروجی تولیدی را بدون بررسی به دستور SQL، مسیر فایل، ایمیل خودکار یا درخواست پرداخت تبدیل نکنید.
همچنین سقف طول ورودی با سقف مالی یکسان نیست. ممکن است چند درخواست کوتاه به مدلی با هزینه بالاتر فرستاده شوند. برای کنترل عملیاتی، سهمیه هر پروژه، سقف درخواست همزمان و برآورد Token را اضافه کنید؛ سپس Usage واقعی را پس از دریافت نتیجه ثبت کنید. روش اجرای Budget و Cache در آموزش کاهش هزینه API هوش مصنوعی توضیح داده شده است.
تست بدون مصرف API واقعی؛ از Http::fake استفاده کنید
پیش از اتصال به Provider واقعی، مسیر موفق، خطای ۴۲۹، فرمت پاسخ نادرست و Timeout را در تست شبیهسازی کنید. Http::fake() درخواست خروجی را جایگزین میکند تا تست به اینترنت یا کلید واقعی وابسته نباشد. مثال زیر صحت ارسال Header و رفتار یک پاسخ موفق را میسنجد:
use Illuminate\Support\Facades\Http;
Http::fake([
'api.example.com/*' => Http::response([
'output' => 'متن آزمایشی',
'usage' => ['input_tokens' => 12, 'output_tokens' => 8],
], 200),
]);
$response = Http::withToken('test-secret')
->acceptJson()
->timeout(10)
->post('https://api.example.com/v1/text', [
'model' => 'test-model', 'input' => 'سلام',
]);
assert($response->successful());
assert($response->json('output') === 'متن آزمایشی');
Http::assertSent(fn ($request) =>
$request->hasHeader('Authorization', 'Bearer test-secret')
);
این تست، رفتار HTTP Client و قرارداد نمونه را میسنجد؛ اثبات نمیکند Endpoint بیرونی واقعی در دسترس است یا پاسخ همه مدلها همین ساختار را دارد. برای اجرای تستها به محیط Laravel با پیکربندی معتبر نیاز دارید. در کنار تست مثبت، وضعیت بازگشت خطای ۴۰۱، داده غیر JSON و ثبت نشدن Secret در Log را نیز در مجموعه آزمون پروژه پوشش دهید.
آیا SDK بهتر است یا HTTP Client لاراول؟
| روش | مزیت | محدودیت | پیشنهاد |
|---|---|---|---|
| HTTP Client مستقیم | کنترل کامل Header، Timeout و پاسخ | نگهداری Schema و تغییر نسخه API با تیم شماست | یک API مشخص با قرارداد ساده |
| SDK رسمی Provider | مدلسازی درخواست و قابلیتهای رسمی | وابستگی به نسخه SDK و امکانات پشتیبانیشده | وقتی چند قابلیت اختصاصی دارید |
| AI Gateway با SDK پروژه | قرارداد مرکزی، سهمیه و صف بین چند محصول | هزینه عملیاتی و تنظیمات دسترسی مستقل | چند برنامه یا چند Provider مجاز |
برای سرویسهای مختلف، فقط برچسب «سازگار با OpenAI» را ملاک نگذارید. بعضی Endpointها شبیهاند، ولی همه فیلدها، خروجی ساختارمند، Stream و مصرف توکن یکسان نیست. پیش از مهاجرت، تست قرارداد برای تمام قابلیتهای موردنیاز بنویسید.
مسائل اتصال API از سرورهای ایران را چگونه تشخیص دهیم؟
اگر درخواست از لپتاپ موفق است اما از دیتاسنتر پاسخ نمیگیرد، ابتدا DNS، اتصال TLS و Timeout خروجی همان سرور را بررسی کنید. پاسخ HTTP ۴۰۳ با خطای TCP یا اعتبارسنجی گواهی فرق دارد. با وجود مسیر شبکه سالم نیز ممکن است Provider برای منطقه حساب شما دسترسی مجاز ارائه نکند؛ تغییر IP یا استفاده از واسط، بهخودیخود مجوز قراردادی ایجاد نمیکند.
برای پروژه دارای داده حساس، محل پردازش و سیاست نگهداری را از قبل مستند کنید. هنگام استفاده از Proxy مدیریتشده هم از مسیر پنهانی جایگزین استفاده نکنید: اگر مسیر انتخابشده خراب شد، باید خطای قابل مشاهده برگردد، نه اینکه داده بدون اطلاع به مقصد دیگر برود.
Avaztek AI برای اتصال چند محصول Laravel چه کمکی میکند؟
Avaztek AI طبق مستندات محصول، درگاه نسخهبندیشده /api/v1، مدیریت Provider و مدل، API Key پروژه، گزارش Usage، سهمیه و پردازش صفمحور دارد. برای تیمی که چند برنامه PHP یا Laravel به چند قابلیت هوش مصنوعی وصل میکند، این معماری میتواند سیاست دسترسی و گزارش مصرف را از کد Controllerها جدا کند.
در مستندات فنی سامانه SDK رسمی PHP/Laravel نیز معرفی شده است. این راهنما از عمد هیچ URL اختصاصی یا نام متد تأییدنشدهای از SDK را بهعنوان کد قابل اجرا عرضه نمیکند؛ برای جزئیات اتصال باید از نسخه مستند فعلی استفاده شود. سرویس نمیتواند کیفیت همه مدلها، دسترسی همه Providerها یا رفع محدودیت قراردادی را تضمین کند.
اگر پروژه نیازمند Gateway، سهمیه و صف مرکزی است، مشخصات فنی، نسخه Laravel، کاربرد مدل و حجم تقریبی درخواست را در فرم تماس و درخواست بررسی اتصال Avaztek AI ثبت کنید. کلید API یا داده محرمانه مشتری را در فرم نفرستید.
پرسشهای متداول اتصال AI به Laravel
آیا برای اتصال هوش مصنوعی به Laravel باید SDK نصب کنم؟
خیر. اگر Provider یک HTTP API مستند دارد، Http خود Laravel برای درخواست JSON و Header کافی است. SDK برای قراردادهای پیچیدهتر یا امکانات ویژه مفید است، اما همچنان باید کلید، خطا و مصرف را مدیریت کنید.
چرا کلید AI API در فایل JavaScript نباید باشد؟
چون فایل و درخواستهای مرورگر برای کاربر قابل مشاهدهاند و کلید میتواند کپی شود. کلید را در محیط Backend نگه دارید و فقط یک Endpoint احراز هویتشده برای درخواستهای مجاز برنامه بسازید.
بهترین مقدار Timeout برای API هوش مصنوعی چیست؟
عدد ثابتی وجود ندارد. Timeout اتصال را از زمان پردازش جدا کنید و مقدارها را از p95 واقعی سرویس و تجربه مطلوب کاربر تعیین کنید. برای وظایف طولانی، اجرای Job و پیگیری وضعیت از انتظار باز در Controller مناسبتر است.
آیا درخواست Timeout شده را همیشه دوباره بفرستیم؟
خیر. Provider ممکن است پردازش و هزینه را انجام داده باشد. برای Retry، نوع عملیات، شناسه درخواست و سیاست Idempotency را بررسی کنید؛ تکرار فوری همه خطاها راهکار امنی نیست.
آیا Http::fake ثابت میکند API واقعی کار میکند؟
نه. این ابزار رفتار کلاینت و قرارداد مورد انتظار برنامه را بدون اینترنت میسنجد. صحت Endpoint، دسترسی منطقهای و Schema واقعی نیاز به تست یکپارچهسازی با مجوز و کلید معتبر دارد.
چه زمانی از Avaztek AI برای Laravel استفاده کنیم؟
وقتی چند برنامه یا مدل دارید و مدیریت مرکزی کلید، سهمیه، صف و گزارش مصرف برایتان مهم شده است، ارزیابی آن منطقی است. برای بررسی معماری و دسترسی از فرم درخواست فنی استفاده کنید.
جمعبندی: کد اتصال کوتاه است، مسئولیت عملیات بلندمدت
برای اتصال امن هوش مصنوعی به Laravel، کلید را در Backend نگه دارید، ورودی را اعتبارسنجی کنید، HTTP Client را با Timeout و خطای کنترلشده اجرا کنید و کار طولانی را به صف بسپارید. بعد با تست Http::fake و گزارش Usage، رفتار برنامه را پیش از اتصال واقعی بسنجید. برای مدیریت مشترک چند پروژه هم Avaztek AI گزینهای برای بررسی است؛ راهنمای اتصال و فرم درخواست در وبسایت رسمی آن قرار دارد.
نظرات و گفتوگو
نظرها پس از تایید مدیر منتشر میشوند. پاسخهای رسمی مدیر با نشان مشخص نمایش داده میشوند.