sanjarani/openai-laravel

A comprehensive PHP package for seamless integration with the OpenAI API, featuring support for the latest models (GPT-4o, o1), Assistants API v2, Tools, streaming, prompt caching, and full compatibility with Laravel 12+.

v1.0.0 2025-05-14 07:51 UTC

This package is auto-updated.

Last update: 2025-05-14 07:55:03 UTC


README

یک پکیج قدرتمند و مدرن PHP برای تعامل با API قدرتمند OpenAI، با تمرکز ویژه بر سازگاری کامل با لاراول ۱۲ به بالا و پیاده‌سازی آخرین استانداردها و ویژگی‌های پیشرفته OpenAI.

ویژگی‌های کلیدی

  • پشتیبانی جامع از Endpointهای OpenAI: شامل Chat (gpt-4o, gpt-3.5-turbo)، Completions، Embeddings (text-embedding-3-small, text-embedding-3-large)، Images (DALL·E 3, DALL·E 2)، Assistants API (با قابلیت استفاده از ابزارها مانند Code Interpreter و File Search)، Files، Fine-tuning، Models و Moderations.
  • سازگاری با لاراول ۱۲ به بالا: طراحی شده با در نظر گرفتن آخرین ویژگی‌ها و بهترین شیوه‌های لاراول.
  • سرویس پروایدر و Facade: برای یکپارچه‌سازی آسان با پروژه‌های لاراول.
  • پیکربندی انعطاف‌پذیر: از طریق فایل پیکربندی config/openai.php و متغیرهای محیطی (.env).
  • کش پرامپت (Prompt Caching): قابلیت کش کردن پاسخ‌های API برای کاهش هزینه‌ها و افزایش سرعت (قابل فعال‌سازی و تنظیم).
  • پشتیبانی از Streaming: برای Endpointهای Chat و Completions و Fine-tuning Events، امکان دریافت پاسخ‌ها به صورت جریانی.
  • مدیریت خطای پیشرفته: استفاده از Exceptionهای اختصاصی برای مدیریت بهتر خطاهای API.
  • ساختار ماژولار و قابل توسعه: طراحی شده با Endpointهای مجزا و یک کلاس AbstractEndpoint برای سهولت در نگهداری و افزودن قابلیت‌های جدید.
  • به‌روز با آخرین مدل‌ها: شامل پشتیبانی از مدل‌های جدید مانند gpt-4o و text-embedding-3-small.
  • مستندات کامل: راهنمای جامع برای نصب، پیکربندی و استفاده از تمامی ویژگی‌ها.

نیازمندی‌ها

  • PHP ۸.۱ به بالا
  • Laravel Framework ۱۲.۰ به بالا
  • Composer

نصب

۱. برای نصب پکیج از طریق Composer دستور زیر را اجرا کنید:

composer require sanjarani/openai-php

(توجه: نام sanjarani/openai-php یک مثال است. پس از انتشار واقعی پکیج، نام صحیح جایگزین خواهد شد.)

۲. (مخصوص لاراول) فایل پیکربندی و سرویس پروایدر به صورت خودکار توسط لاراول شناسایی می‌شوند. در صورت نیاز به انتشار دستی فایل پیکربندی، دستور زیر را اجرا کنید:

php artisan vendor:publish --provider="Sanjarani\OpenAI\OpenAIServiceProvider" --tag="config"

این دستور فایل openai.php را در پوشه config پروژه شما ایجاد می‌کند.

پیکربندی

پس از نصب، متغیرهای محیطی زیر را در فایل .env پروژه خود تنظیم کنید:

OPENAI_API_KEY="sk-your-openai-api-key"
OPENAI_ORGANIZATION_ID="org-your-organization-id" # اختیاری

# مدل‌های پیش‌فرض (اختیاری، مقادیر زیر پیش‌فرض‌های پکیج هستند)
OPENAI_CHAT_MODEL=gpt-4o
OPENAI_COMPLETION_MODEL=gpt-3.5-turbo-instruct
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_IMAGE_MODEL=dall-e-3
OPENAI_MODERATION_MODEL=text-moderation-latest

# تنظیمات کش (اختیاری)
OPENAI_CACHE_ENABLED=false
OPENAI_CACHE_STORE=null # استفاده از استور پیش‌فرض کش لاراول
OPENAI_CACHE_TTL=3600 # مدت زمان اعتبار کش به ثانیه (پیش‌فرض: ۱ ساعت)

# سایر تنظیمات (اختیاری)
OPENAI_BASE_URL=https://api.openai.com
OPENAI_API_VERSION=v1
OPENAI_TIMEOUT=30
OPENAI_VERIFY_SSL=true
  • OPENAI_API_KEY: کلید API شما از OpenAI.
  • OPENAI_ORGANIZATION_ID: شناسه سازمان شما در OpenAI (در صورت استفاده).
  • OPENAI_CHAT_MODEL و سایر OPENAI_*_MODEL: مدل‌های پیش‌فرض برای هر قابلیت. می‌توانید این مقادیر را در فایل config/openai.php نیز مشاهده و تغییر دهید.
  • OPENAI_CACHE_ENABLED: برای فعال یا غیرفعال کردن کش پاسخ‌های API.
  • OPENAI_CACHE_STORE: نام استور کش لاراول که می‌خواهید استفاده کنید (مثلاً redis, memcached). اگر null باشد از استور پیش‌فرض استفاده می‌شود.
  • OPENAI_CACHE_TTL: مدت زمان نگهداری آیتم‌ها در کش به ثانیه.

استفاده

می‌توانید از Facade OpenAI برای دسترسی به Endpointهای مختلف استفاده کنید.

use Sanjarani\OpenAI\Facades\OpenAI;

// مثال برای Chat API
$messages = [
    ["role" => "system", "content" => "You are a helpful assistant."],
    ["role" => "user", "content" => "Hello! Who are you?"],
];

$response = OpenAI::chat()->create($messages);
echo $response["choices"][0]["message"]["content"];

مدیریت خطا

در صورت بروز خطا در ارتباط با API، پکیج یک Sanjarani\OpenAI\Exceptions\OpenAIException پرتاب می‌کند. می‌توانید جزئیات خطا را از این Exception دریافت کنید:

use Sanjarani\OpenAI\Facades\OpenAI;
use Sanjarani\OpenAI\Exceptions\OpenAIException;

try {
    $response = OpenAI::chat()->create([["role" => "user", "content" => "Hello"]]);
} catch (OpenAIException $e) {
    // $e->getMessage() پیام اصلی خطا
    // $e->getCode() کد وضعیت HTTP یا کد خطای داخلی
    // $e->getErrorDetails() آرایه‌ای از جزئیات خطا از API (در صورت وجود)
    logger()->error("OpenAI API Error: " . $e->getMessage(), ["details" => $e->getErrorDetails()]);
}

کش کردن پاسخ‌ها (Prompt Caching)

اگر کش را در فایل پیکربندی (openai.cache.enabled = true) فعال کرده باشید، پکیج به طور خودکار پاسخ‌های موفق از Endpointهایی که از کش پشتیبانی می‌کنند (مانند Chat, Completions, Embeddings, Models list/retrieve, Assistants retrieve/list) را کش می‌کند. درخواست‌های بعدی با پارامترهای یکسان، پاسخ را از کش دریافت خواهند کرد.

پاسخ‌هایی که از کش بازگردانده می‌شوند، یک کلید _from_cache با مقدار true خواهند داشت.

$response = OpenAI::chat()->create($messages);

if (isset($response["_from_cache"]) && $response["_from_cache"] === true) {
    echo "Response was retrieved from cache!";
}

Endpointها

۱. Chat

برای تعامل با مدل‌های مکالمه مانند gpt-4o و gpt-3.5-turbo.

ایجاد یک پاسخ Chat:

$messages = [
    ["role" => "user", "content" => "Translate 'Hello, world!' to French."],
];
$options = [
    "model" => "gpt-4o", // اختیاری، از مقدار پیش‌فرض در کانفیگ استفاده می‌کند
    "temperature" => 0.7,
    "max_tokens" => 50,
];
$response = OpenAI::chat()->create($messages, $options);
// $response["choices"][0]["message"]["content"]

ایجاد یک پاسخ Chat به صورت جریانی (Streaming):

$messages = [
    ["role" => "user", "content" => "Tell me a short story."],
];
$stream = OpenAI::chat()->createStream($messages);

foreach ($stream as $responseChunk) {
    // پردازش هر قطعه از پاسخ
    // $responseChunk["choices"][0]["delta"]["content"]
    if (isset($responseChunk["choices"][0]["delta"]["content"])) {
        echo $responseChunk["choices"][0]["delta"]["content"];
    }
    if (($responseChunk["choices"][0]["finish_reason"] ?? null) === "stop") {
        // پایان جریان
        break;
    }
}

۲. Completions (Legacy)

برای کار با مدل‌های تکمیل متن قدیمی‌تر (مانند gpt-3.5-turbo-instruct).

ایجاد یک Completion:

$prompt = "Write a tagline for an ice cream shop.";
$options = [
    "model" => "gpt-3.5-turbo-instruct",
    "max_tokens" => 30,
];
$response = OpenAI::completions()->create($prompt, $options);
// $response["choices"][0]["text"]

ایجاد یک Completion به صورت جریانی (Streaming):

$prompt = "Once upon a time...";
$stream = OpenAI::completions()->createStream($prompt);

foreach ($stream as $responseChunk) {
    // $responseChunk["choices"][0]["text"]
    if (isset($responseChunk["choices"][0]["text"])) {
        echo $responseChunk["choices"][0]["text"];
    }
     if (($responseChunk["choices"][0]["finish_reason"] ?? null) === "stop") {
        break;
    }
}

۳. Embeddings

برای ایجاد بردارهای جاسازی (embedding vectors) از متن.

$input = "The quick brown fox jumps over the lazy dog";
$options = [
    "model" => "text-embedding-3-small", // یا text-embedding-3-large
];
$response = OpenAI::embeddings()->create($input, $options);
// $response["data"][0]["embedding"] (آرایه‌ای از اعداد float)

۴. Images

برای تولید و ویرایش تصاویر با استفاده از مدل‌های DALL·E.

تولید تصویر (Generations):

$prompt = "A futuristic cityscape with flying cars, digital art";
$options = [
    "model" => "dall-e-3", // یا dall-e-2
    "n" => 1,
    "size" => "1024x1024", // برای dall-e-3: 1024x1024, 1792x1024, 1024x1792
    "response_format" => "url", // یا b64_json
    "quality" => "standard", // برای dall-e-3: standard, hd
    "style" => "vivid" // برای dall-e-3: vivid, natural
];
$response = OpenAI::images()->create($prompt, $options);
// $response["data"][0]["url"] یا $response["data"][0]["b64_json"]

ویرایش تصویر (Edits - DALL·E 2 only):

$imagePath = "/path/to/your/image.png"; // تصویر مربعی PNG کمتر از ۴ مگابایت
$prompt = "Add a sun wearing sunglasses to the sky";
$options = [
    "mask" => "/path/to/your/mask.png", // اختیاری، تصویر PNG با همان ابعاد تصویر اصلی
    "n" => 1,
    "size" => "1024x1024",
];
$response = OpenAI::images()->edit($imagePath, $prompt, $options);
// $response["data"][0]["url"]

ایجاد واریاسیون از تصویر (Variations - DALL·E 2 only):

$imagePath = "/path/to/your/image.png"; // تصویر مربعی PNG کمتر از ۴ مگابایت
$options = [
    "n" => 1,
    "size" => "1024x1024",
];
$response = OpenAI::images()->createVariation($imagePath, $options);
// $response["data"][0]["url"]

۵. Moderations

برای بررسی اینکه آیا متن با سیاست‌های محتوای OpenAI مغایرت دارد یا خیر.

$input = "Some potentially problematic text.";
$options = [
    "model" => "text-moderation-latest", // یا text-moderation-stable
];
$response = OpenAI::moderations()->create($input, $options);
// $response["results"][0]["flagged"]
// $response["results"][0]["categories"] (آرایه‌ای از دسته‌بندی‌های نقض شده)
// $response["results"][0]["category_scores"] (امتیازات برای هر دسته‌بندی)

۶. Files

برای آپلود، مدیریت و بازیابی فایل‌ها جهت استفاده در سایر Endpointها مانند Fine-tuning و Assistants.

آپلود فایل:

$filePath = "/path/to/your/data.jsonl";
$purpose = "fine-tune"; // یا "assistants"
$response = OpenAI::files()->upload($filePath, $purpose);
// $response["id"] (شناسه فایل آپلود شده)

لیست فایل‌ها:

$response = OpenAI::files()->list();
// $response["data"] (آرایه‌ای از آبجکت‌های فایل)

بازیابی اطلاعات یک فایل:

$fileId = "file-xxxxxxxxxxxx";
$response = OpenAI::files()->retrieve($fileId);
// $response (آبجکت فایل)

حذف یک فایل:

$fileId = "file-xxxxxxxxxxxx";
$response = OpenAI::files()->delete($fileId);
// $response["deleted"]

بازیابی محتوای یک فایل:

$fileId = "file-xxxxxxxxxxxx";
$content = OpenAI::files()->retrieveContent($fileId);
// $content (محتوای خام فایل)

۷. Fine-tuning (Fine-tuning Jobs API v1)

برای ایجاد و مدیریت جاب‌های fine-tuning.

ایجاد یک Fine-tuning Job:

$trainingFileId = "file-xxxxxxxxxxxx";
$model = "gpt-3.5-turbo"; // مدلی که می‌خواهید fine-tune کنید
$options = [
    "suffix" => "my_custom_model_v1", // اختیاری
    "validation_file" => "file-yyyyyyyyyyyy", // اختیاری
    "hyperparameters" => ["n_epochs" => 3]
];
$response = OpenAI::fineTuning()->createJob($trainingFileId, $model, $options);
// $response (آبجکت Fine-tuning Job)

لیست Fine-tuning Jobs:

$response = OpenAI::fineTuning()->listJobs(["limit" => 10]);
// $response["data"]

بازیابی یک Fine-tuning Job:

$jobId = "ft_job-xxxxxxxxxxxx";
$response = OpenAI::fineTuning()->retrieveJob($jobId);
// $response (آبجکت Fine-tuning Job)

لغو یک Fine-tuning Job:

$jobId = "ft_job-xxxxxxxxxxxx";
$response = OpenAI::fineTuning()->cancelJob($jobId);
// $response (آبجکت Fine-tuning Job با وضعیت cancelled)

لیست رویدادهای یک Fine-tuning Job (با قابلیت Streaming):

$jobId = "ft_job-xxxxxxxxxxxx";
// برای دریافت لیست معمولی:
// $events = OpenAI::fineTuning()->listJobEvents($jobId, ["limit" => 20]);

// برای دریافت به صورت جریانی:
$stream = OpenAI::fineTuning()->listJobEvents($jobId, ["stream" => true]);
foreach ($stream as $event) {
    // $event (آبجکت رویداد)
    echo $event["message"] . "\n";
    if ($event["type"] === "job.status" && $event["data"]["status"] === "succeeded") break;
}

حذف یک مدل Fine-tuned (از طریق Models API):

$modelId = "ft:gpt-3.5-turbo:your-org:my_custom_model_v1:xxxxxx";
$response = OpenAI::fineTuning()->deleteModel($modelId); // یا OpenAI::models()->delete($modelId)
// $response["deleted"]

۸. Models

برای لیست کردن و بازیابی اطلاعات مدل‌های موجود.

لیست مدل‌ها:

$response = OpenAI::models()->list();
// $response["data"] (آرایه‌ای از آبجکت‌های مدل)

بازیابی اطلاعات یک مدل:

$modelId = "gpt-4o";
$response = OpenAI::models()->retrieve($modelId);
// $response (آبجکت مدل)

حذف یک مدل Fine-tuned (این متد در ModelsEndpoint نیز موجود است):

$modelId = "ft:gpt-3.5-turbo:your-org:my_custom_model_v1:xxxxxx";
$response = OpenAI::models()->delete($modelId);
// $response["deleted"]

۹. Assistants API (v2)

برای ساخت اپلیکیشن‌های هوش مصنوعی با دستیارهای پیشرفته.

تعریف ابزارها (Tools):

use Sanjarani\OpenAI\Support\Tool;

$codeInterpreterTool = Tool::codeInterpreter();
$fileSearchTool = Tool::fileSearch();
$functionTool = Tool::function(
    "getCurrentWeather",
    "Get the current weather in a given location",
    [
        "type" => "object",
        "properties" => [
            "location" => ["type" => "string", "description" => "The city and state, e.g. San Francisco, CA"],
            "unit" => ["type" => "string", "enum" => ["celsius", "fahrenheit"]]
        ],
        "required" => ["location"]
    ]
);

ایجاد یک Assistant:

$assistant = OpenAI::assistants()->create(
    "gpt-4o",
    [
        "name" => "Personal Math Tutor",
        "instructions" => "You are a personal math tutor. Write and run code to answer math questions.",
        "tools" => [$codeInterpreterTool, $fileSearchTool] // یا آرایه‌ای از تعریف ابزارها
        // "tool_resources" => [ "file_search" => [ "vector_store_ids" => ["vs_xxxx"] ] ] // در صورت نیاز
    ]
);
$assistantId = $assistant["id"];

بازیابی یک Assistant:

$retrievedAssistant = OpenAI::assistants()->retrieve($assistantId);

به‌روزرسانی یک Assistant:

$updatedAssistant = OpenAI::assistants()->update($assistantId, [
    "description" => "An even better math tutor.",
    "tools" => [Tool::codeInterpreter()] // بازنویسی ابزارها
]);

لیست Assistantها:

$assistantsList = OpenAI::assistants()->list(["limit" => 5, "order" => "desc"]);

حذف یک Assistant:

$deletionStatus = OpenAI::assistants()->delete($assistantId);

مدیریت فایل‌های Assistant:

// آپلود یک فایل برای استفاده با Assistant (ابتدا از Files API استفاده کنید)
$fileUploadResponse = OpenAI::files()->upload("/path/to/document.pdf", "assistants");
$fileIdForAssistant = $fileUploadResponse["id"];

// پیوست کردن فایل به Assistant (v1 روش قدیمی‌تر، v2 از tool_resources استفاده می‌کند)
// برای v2، فایل‌ها معمولاً به Vector Stores اضافه می‌شوند و سپس Vector Store به Assistant متصل می‌شود.
// یا فایل‌ها هنگام ایجاد Message یا Run به Thread اضافه می‌شوند.

// مثال برای v1 (اگر API هنوز پشتیبانی کند):
// $assistantFile = OpenAI::assistants()->createFile($assistantId, $fileIdForAssistant);
// $retrievedAssistantFile = OpenAI::assistants()->retrieveFile($assistantId, $fileIdForAssistant);
// $assistantFilesList = OpenAI::assistants()->listFiles($assistantId);
// $deletedAssistantFile = OpenAI::assistants()->deleteFile($assistantId, $fileIdForAssistant);

کار با Threads, Messages, Runs (برای تکمیل تعامل با Assistant):

این پکیج در حال حاضر Endpointهای مستقیم برای Threads, Messages, Runs را به صورت مجزا پیاده‌سازی نکرده است، اما شما می‌توانید با استفاده از متد request در کلاس اصلی OpenAI یا AbstractEndpoint به این Endpointها دسترسی پیدا کنید یا آن‌ها را به پکیج اضافه نمایید. ساختار پکیج برای چنین توسعه‌ای آماده است.

مثال (نیاز به پیاده‌سازی یا استفاده از متد request عمومی):

// // ایجاد یک Thread (مثال مفهومی، نیاز به پیاده‌سازی دارد)
// $thread = OpenAI::threads()->create(); 
// $threadId = $thread["id"];

// // افزودن پیام به Thread (مثال مفهومی)
// $message = OpenAI::threads()->messages($threadId)->create([
//     "role" => "user",
//     "content" => "I need to solve the equation 3x + 11 = 14. Can you help me?"
// ]);

// // اجرای Assistant روی Thread (مثال مفهومی)
// $run = OpenAI::threads()->runs($threadId)->create([
//     "assistant_id" => $assistantId,
//     "instructions" => "Please address the user as Jane Doe. The user has a premium account."
// ]);
// $runId = $run["id"];

// // بررسی وضعیت Run و دریافت پاسخ‌ها (مثال مفهومی، نیاز به polling و مدیریت status دارد)
// do {
//     sleep(1);
//     $runStatus = OpenAI::threads()->runs($threadId)->retrieve($runId);
// } while (in_array($runStatus["status"], ["queued", "in_progress", "requires_action"]));

// if ($runStatus["status"] === "completed") {
//     $messagesList = OpenAI::threads()->messages($threadId)->list();
//     // نمایش پیام‌های Assistant
// }

توسعه و مشارکت

از مشارکت شما در توسعه این پکیج استقبال می‌شود. لطفاً برای گزارش باگ‌ها یا ارائه پیشنهادات از بخش Issues در GitHub استفاده کنید. برای ارسال Pull Request، لطفاً از استانداردهای کدنویسی پروژه پیروی کنید.

لایسنس

این پکیج تحت لایسنس MIT منتشر شده است. برای جزئیات بیشتر فایل LICENSE را مطالعه کنید.