為什麼要在 Laravel 中使用 AI 內容生成?

在現代網頁應用中,AI 內容生成已成為提升用戶體驗的重要工具。透過 Laravel 整合 OpenAI,開發者可以自動化產生部落格文章、產品描述、客服回覆等內容,大幅提升內容產出效率。 傳統的同步 API 呼叫會造成用戶等待時間過長,影響使用者體驗。本教學將採用 Laravel Queue 機制,將 AI 生成的運算密集任務移至背景處理,讓前端頁面能夠立即回應,同時透過非同步 job 執行長時間的 AI 運算。 這種架構特別適合以下場景:自動產生 SEO 優化的文章草稿、批次生成產品說明、智慧客服系統的回覆建議等。

環境準備與基本設定

在開始之前,請確保您的開發環境滿足以下條件:
  • PHP 8.1 以上版本
  • Laravel 10 或更新版本
  • OpenAI API Key(需至 OpenAI 官網申請)
  • 資料庫(MySQL 或 PostgreSQL)
首先,建立新的 Laravel 專案並安裝必要的套件:
composer create-project laravel/laravel ai-content-generator
cd ai-content-generator
composer require openai-php/laravel
php artisan vendor:publish --provider="OpenAI\Laravel\OpenAIServiceProvider"
接下來,在 `.env` 檔案中設定 OpenAI API Key:
OPENAI_API_KEY=your-api-key-here
確認 `.env` 設定正確後,您可以透過以下指令驗證連線是否正常。

建立 OpenAI 服務類別

為了讓程式碼更具結構性,我們建立一個專門處理 AI 生成的服務類別。在 `app/Services` 目錄下建立 `ContentGeneratorService.php`:
<?php

namespace App\Services;

use OpenAI\Laravel\Facades\OpenAI;

class ContentGeneratorService
{
    public function generate(string $prompt, string $model = 'gpt-3.5-turbo'): string
    {
        $result = OpenAI::chat()->create([
            'model' => $model,
            'messages' => [
                ['role' => 'user', 'content' => $prompt]
            ],
            'max_tokens' => 1000,
            'temperature' => 0.7,
        ]);

        return $result->choices[0]->message->content;
    }

    public function generateBlogPost(string $title, string $keywords): string
    {
        $prompt = "請根據以下標題和關鍵詞,撰寫一篇 SEO 優化的部落格文章:\n標題:{$title}\n關鍵詞:{$keywords}";
        
        return $this->generate($prompt);
    }
}
這個服務類別封裝了 OpenAI API 的呼叫邏輯,並提供 `generateBlogPost` 方法方便產生部落格文章。您可以根據需求擴充其他生成方法,如產品描述、社交媒體貼文等。

使用 Queue 處理非同步生成

為了避免用戶長時間等待 AI 回應,我們使用 Laravel Queue 將生成任務移至背景執行。首先,建立一個專門的 Job 類別:
php artisan make:job GenerateContentJob
編輯 `app/Jobs/GenerateContentJob.php`:
<?php

namespace App\Jobs;

use App\Services\ContentGeneratorService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class GenerateContentJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $timeout = 120;

    public function __construct(
        public int $postId,
        public string $title,
        public string $keywords
    ) {}

    public function handle(ContentGeneratorService $generator): void
    {
        $content = $generator->generateBlogPost($this->title, $this->keywords);
        
        // 儲存生成的內容到資料庫
        \App\Models\Post::where('id', $this->postId)->update([
            'content' => $content,
            'ai_generated' => true,
            'generated_at' => now(),
        ]);
    }

    public function failed(\Throwable $exception): void
    {
        \App\Models\Post::where('id', $this->postId)->update([
            'generation_error' => $exception->getMessage(),
        ]);
    }
}
在控制器中調用這個 Job:
use App\Jobs\GenerateContentJob;
use App\Models\Post;

public function generateContent(Request $request)
{
    $post = Post::create([
        'title' => $request->title,
        'keywords' => $request->keywords,
        'status' => 'pending',
    ]);

    GenerateContentJob::dispatch($post->id, $post->title, $post->keywords);

    return response()->json([
        'message' => '內容生成任務已提交',
        'post_id' => $post->id,
    ]);
}
這樣用戶提交請求後會立即收到回應,而 AI 內容生成則在背景處理。

前端整合與實際應用

最後,讓我們建立前端表單來觸發 AI 內容生成。建立 Blade 視圖 `resources/views/admin/posts/create.blade.php`:
<form action="{{ route('posts.generate') }}" method="POST">
    @csrf
    <div>
        <label>文章標題</label>
        <input type="text" name="title" required>
    </div>
    <div>
        <label>關鍵詞(用逗號分隔)</label>
        <input type="text" name="keywords" required>
    </div>
    <button type="submit">AI 生成內容</button>
</form>

<div id="status"></div>

<script>
function checkStatus(postId) {
    fetch(`/posts/${postId}/status`)
        .then(res => res.json())
        .then(data => {
            if (data.status === 'completed') {
                document.getElementById('status').innerHTML = '內容已生成完成!';
            } else {
                setTimeout(() => checkStatus(postId), 3000);
            }
        });
}
</script>
您可以透過 Laravel Echo 或 AJAX 輪詢即時更新生成狀態,讓管理員能夠追蹤內容產出的進度。

總結與建議

本教學介紹了如何在 Laravel 中整合 OpenAI API 並使用 Queue 機制實現非同步 AI 內容生成。這種架構不僅提升用戶體驗,還能有效控制 API 呼叫成本。 實際應用時,建議您注意以下幾點:設定合理的 Queue 處理時間限制、實作錯誤重試機制、監控 API 使用量與費用、以及考慮加入內容審核功能確保生成品質。 透過本方案建立的基礎架構,您可以進一步擴充至其他 AI 應用場景,如智慧搜尋、自動化客服、語言翻譯等功能。