Skip to content

使用 Laravel 创建 DALL-E 图像生成 API:分步指南

在本指南中,我们将逐步介绍如何创建一个 Laravel API 端点,用于生成DALL-E图像并将其存储在本地文件系统中。这个功能对于需要按需生成 AI 图像的应用程序(如内容创作工具或聊天机器人)非常有用。

简介

DALL-E是由 OpenAI 开发的一个 AI 模型,可以根据文本描述创建独特的图像。将这种能力集成到Laravel应用程序中,为动态的、AI 驱动的视觉内容开辟了可能性。

问题

许多开发者发现将 AI 图像生成功能集成到他们的 Laravel 应用程序中具有挑战性。这个过程不仅涉及生成图像,还包括高效存储、提供访问以及处理潜在的错误。本文旨在通过提供全面的指南来简化这个过程。

解决方案

让我们将解决方案分解为以下步骤:

步骤 1:设置 OpenAI API

在开始之前,您需要从OpenAI API获取 API 密钥。访问 OpenAI 网站,创建一个账户,并生成 API 密钥。

获得 API 密钥后,将其添加到您的 Laravel环境配置中:

OPENAI_API_KEY=your_api_key_here

步骤 2:创建 OpenAIProvider 辅助类

创建一个新文件app/AI/Providers/OpenAIProvider.php并添加以下代码:

php
<?php

namespace App\AI\Providers;

use App\Exceptions\Errors;
use OpenAI;
use Exception;

class OpenAIProvider
{
    const array MODEL_RETRY_TIMES = [3000, 7000, 10000];

    private static function getApiKey(): string
    {
        return config('openai.api_key');
    }

    private static function getClient(): OpenAI\Client
    {
        return OpenAI::client(self::getApiKey());
    }

    public static function images(
        string $prompt,
        int $n = 1,
        string $model = 'dall-e-3',
        string $quality = 'hd',
        string $size = '1792x1024',
        string $style = 'natural',
        string $response_format = 'url',
        ?string $user = null
    ): ?array {
        $urls = [];
        $parameters = [
            'prompt' => $prompt,
            'model' => $model,
            'n' => $n,
            'quality' => $quality,
            'size' => $size,
            'style' => $style,
            'response_format' => $response_format,
        ];

        if ($user !== null) {
            $parameters['user'] = $user;
        }

        try {
            $response = retry(
                times: self::MODEL_RETRY_TIMES,
                callback: function () use ($parameters) {
                    return self::getClient()->images()->create($parameters);
                },
            );

            foreach ($response->data as $data) {
                $urls[] = $data->url;
            }
        } catch (Exception $e) {
            Errors::captureException($e);
        }

        return $urls;
    }
}

这个类处理与 OpenAI API 的交互,包括在必要时重试请求并捕获发生的任何异常。

步骤 3:实现错误处理

创建一个新文件app/Exceptions/Errors.php并添加以下代码:

php
<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Support\Facades\Log;

use function Sentry\captureException;

class Errors
{
    public static function captureException(Exception $e): void
    {
        captureException($e);

        if (config('app.env') === 'local') {
            Log::error($e);
        }
    }
}

这个类捕获异常并使用Sentry 错误跟踪记录它们,对于开发环境还会进行额外的本地日志记录。

步骤 4:设置控制器

创建一个新的控制器app/Http/Controllers/ChatbotController.php并添加以下代码:

php
<?php

namespace App\Http\Controllers;

use App\AI\Providers\OpenAIProvider;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

class ChatbotController extends Controller
{
    public function v1Dalle(Request $request): JsonResponse
    {
        $v = $request->validate([
            'prompt' => 'required|string',
        ]);

        $chatbot_api_key = config('integrations.chatbot_api_key');
        $incoming_api_key = $request->headers->get('X-Api-Key');

        if ($chatbot_api_key !== $incoming_api_key) {
            return response()->json([
                'error' => 'Unauthorized',
            ], 401);
        }

        $prompt = $v['prompt'];
        $app_url = config('app.url');
        $public_url = null;

        $images = OpenAIProvider::images(
            prompt: $prompt,
        );

        foreach ($images as $image) {
            $image_contents = Http::get($image)->body();

            $filename = 'dalle3/'.uniqid().'.png';
            $public_filename = 'public/'.$filename;

            Storage::put($public_filename, $image_contents);

            $public_url = $app_url.Storage::url($public_filename);
        }

        return response()->json([
            'url' => $public_url,
        ]);
    }
}

这个控制器处理传入的请求,验证 API 密钥,使用 OpenAIProvider 生成图像,使用Laravel Storage将其保存到本地文件系统,并返回保存图像的公共 URL。

步骤 5:设置路由

routes/api.php文件中添加以下路由:

php
Route::post('/v1/dalle', [ChatbotController::class, 'v1Dalle']);

步骤 6:配置 API 密钥

在您的.env文件中添加以下内容:

CHATBOT_API_KEY=your_chatbot_api_key_here

然后,在config/integrations.php中(如果该文件不存在,请创建它)添加:

php
<?php

return [
    'chatbot_api_key' => env('CHATBOT_API_KEY'),
];

步骤 7:刷新本地配置

为确保新的环境变量被加载到应用程序中,运行php artisan optimize:clear命令。这将执行几个操作,其中之一是确保新的环境变量被缓存。

步骤 8:测试端点

您可以使用 Postman 或 curl 等工具测试端点。向/api/v1/dalle发送 POST 请求,包含以下头部和主体:

头部:

X-Api-Key: your_chatbot_api_key_here
Content-Type: application/json

主体:

json
{
  "prompt": "A futuristic cityscape with flying cars"
}

响应应包含生成图像的 URL。

安全考虑

在实现此 API 时,遵循API 安全最佳实践至关重要:

  1. 始终使用 HTTPS 进行 API 请求,以保护 API 密钥和其他敏感数据。
  2. 将 API 密钥安全地存储在环境变量中,绝不要存储在版本控制中
  3. 在您的端点上实现Laravel 中的速率限制,以防止滥用。

性能考虑

为确保 DALL-E 图像生成 API 的最佳性能:

  1. 考虑对频繁请求的图像实施缓存,以减少 API 调用和存储操作。
  2. 如果您预期高流量,请使用Laravel 队列进行图像生成任务,以防止阻塞主线程。

这种方法的局限性

虽然本指南中提出的解决方案提供了一个功能性的 DALL-E 图像生成 API,但重要的是要意识到其局限性:

  1. 单一固定 API 密钥:示例使用单一固定的环境变量(CHATBOT_API_KEY)来验证请求。这种方法缺乏灵活性,可能不适合多用户系统或需要不同访问级别的应用程序。

  2. 本地文件存储:图像存储在本地文件系统中,这可能不具有可扩展性或不适合分布式系统。在生产环境中,您可能需要考虑使用 AWS S3 或 Google Cloud Storage 等云存储解决方案。

  3. 错误处理:虽然实现了基本的错误处理,但它并未涵盖所有可能的边缘情况或向客户端提供详细的错误消息。

  4. 固定图像参数:在这个示例中,DALL-E 参数(如大小和质量)是硬编码的,您可以根据需要在请求中添加额外的参数。

  5. 有限的提示验证:示例仅检查提示是否为非空字符串,没有任何内容审核或长度限制。

  6. 无使用跟踪:示例不跟踪 API 使用情况,这对于计费或监控目的可能很重要。

结论

通过遵循这些步骤,我们已成功创建了一个使用 Laravel 生成 DALL-E 图像并将其存储在本地文件系统中的 API 端点。

这个端点可以轻松集成到现有的 Laravel 应用程序中,允许按需生成和存储 AI 图像。

请记住优雅地处理错误,实施适当的安全措施,并在应用程序扩展时考虑性能优化。