> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel AI SDK 的 Amazon Bedrock 驅動

> Laravel AI SDK 的 Amazon Bedrock 驅動。支援文字生成、串流、工具使用、結構化輸出、檔案附件、對話歷史、嵌入、圖像生成、語音（TTS）、重新排序。

## 概觀

[revolution/laravel-amazon-bedrock](https://github.com/invokable/laravel-amazon-bedrock) 是可讓 [Laravel AI SDK](https://laravel.com/docs/ai-sdk) 使用 Amazon Bedrock 的驅動。可透過 Laravel AI SDK 的統一 API 使用 Bedrock 上的多種模型。

| 功能                     | 僅使用 Bedrock API 金鑰即可用 | 支援的模型 / 服務                                                                                |
| ---------------------- | --------------------- | ----------------------------------------------------------------------------------------- |
| 文字生成 / 串流              | ✅                     | Anthropic Claude、Amazon Nova，以及大多數 Bedrock 模型（皆透過 Converse API）                           |
| 工具使用（Function Calling） | ✅                     |                                                                                           |
| 結構化輸出                  | ✅                     |                                                                                           |
| 檔案附件                   | ✅                     | 透過 Converse API 附加圖像、文件、音訊、影片（各模型支援的格式不同）                                                 |
| 圖像生成                   | ✅                     | Stability AI（預設）、Amazon Nova Canvas（不建議）                                                  |
| 語音（TTS）                | ⚠️                    | Amazon Polly（generative / neural / long-form / standard 引擎）                               |
| 語音轉文字（STT）             | ❌                     | 尚未支援                                                                                      |
| 嵌入                     | ✅                     | Amazon Titan Embeddings V2（預設）、Cohere Embed English/Multilingual V3、Cohere Embed V4（支援批次） |
| 重新排序                   | ⚠️                    | Cohere Rerank 3.5、Amazon Rerank 1.0                                                       |
| 檔案                     | ✅                     | 文字生成支援本機檔案附加。伺服器端上傳與 `fromId()` 尚未支援                                                      |

<Info>
  表中的 `⚠️` 表示的不是「功能本身不支援」，而是「僅使用 Bedrock API 金鑰無法使用」。
</Info>

<Info>
  Laravel AI SDK v0.6.3 新增了使用 Bedrock API 金鑰的 Text、Image、Embeddings 的官方支援。由於本套件也支援官方整合尚未涵蓋的功能（如透過 Amazon Polly 的語音（TTS）與重新排序），因此仍持續公開。
</Info>

主要特色如下。

* **認證**：可從 Bedrock API 金鑰、AWS IAM 認證（SigV4）、預設 AWS 認證鏈（IAM 角色、instance profile 等）中選擇。
* **Failover**：支援 AI SDK 的多提供者 failover。速率限制（429）、過載（503、529）、額度相關錯誤會對應為可 failover 的例外。
* **快取控制**：對 [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html) 的系統提示常態啟用 ephemeral 快取。
* **統一 API**：Anthropic Claude、Amazon Nova、Meta Llama、Mistral 等所有模型皆可透過 Bedrock Converse API 以統一介面使用。

## 需求

* PHP >= 8.3
* Laravel >= 12.x

## 安裝

<Steps>
  <Step title="安裝套件">
    ```bash theme={null}
    composer require revolution/laravel-amazon-bedrock
    ```
  </Step>

  <Step title="發布 AI SDK 設定">
    ```bash theme={null}
    php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
    ```
  </Step>
</Steps>

## 設定

在 `config/ai.php` 中新增 `amazon-bedrock` 提供者，並依需要將預設提供者切換為 Bedrock。

```php theme={null}
'default' => 'amazon-bedrock',
'default_for_images' => 'amazon-bedrock',
'default_for_audio' => 'amazon-bedrock',
'default_for_embeddings' => 'amazon-bedrock',
'default_for_reranking' => 'amazon-bedrock',
```

### 選項 1：Bedrock API 金鑰

```php theme={null}
'providers' => [
    'amazon-bedrock' => [
        'driver' => 'amazon-bedrock',
        'key'    => env('AWS_BEDROCK_API_KEY', ''),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
],
```

```dotenv theme={null}
AWS_BEDROCK_API_KEY=your_api_key
AWS_DEFAULT_REGION=us-east-1
```

Bedrock API 金鑰可從 AWS 管理主控台取得。

<Warning>
  Bedrock API 金鑰僅適用於 Bedrock Runtime API。使用 `bedrock-agent-runtime` 的重新排序，或 Amazon Polly（TTS）皆無法使用。請改用 SigV4 或預設 AWS 認證鏈。
</Warning>

### 選項 2：AWS IAM 認證（SigV4）

使用以 [Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) 簽章的 AWS access key 與 secret key。

```php theme={null}
'providers' => [
    'amazon-bedrock' => [
        'driver' => 'amazon-bedrock',
        'key'    => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'token'  => env('AWS_SESSION_TOKEN'),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
],
```

```dotenv theme={null}
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=wJalr...
AWS_SESSION_TOKEN= # 選填（用於 STS 臨時認證）
AWS_DEFAULT_REGION=us-east-1
```

<Info>
  `AWS_SESSION_TOKEN` 僅在使用臨時認證（STS）時設定。
</Info>

### 選項 3：預設 AWS 認證鏈（IAM 角色）

在 EC2、ECS、Lambda 等具備 IAM 角色的環境中，可省略 `key` 與 `secret`，使用 [預設的 AWS 認證提供者鏈](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html)。

```php theme={null}
'providers' => [
    'amazon-bedrock' => [
        'driver' => 'amazon-bedrock',
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
],
```

```dotenv theme={null}
AWS_DEFAULT_REGION=us-east-1
```

預設認證鏈會從環境變數、共用認證檔（`~/.aws/credentials`）、ECS task role、EC2 instance profile 等自動解析。

### 選用的設定鍵

| 鍵                              | 說明                           | 預設值                                |
| ------------------------------ | ---------------------------- | ---------------------------------- |
| `secret`                       | AWS secret access key（SigV4） | —                                  |
| `token`                        | AWS session token（SigV4）     | —                                  |
| `timeout`                      | HTTP 請求逾時（秒）                 | 30                                 |
| `max_tokens`                   | 每次請求的預設 max tokens           | 8096                               |
| `models.text.default`          | 預設文字模型                       | Claude Sonnet                      |
| `models.text.cheapest`         | 最便宜的文字模型                     | Claude Haiku                       |
| `models.text.smartest`         | 效能最強的文字模型                    | Claude Opus / Fable                |
| `models.embeddings.default`    | 預設嵌入模型                       | `amazon.titan-embed-text-v2:0`     |
| `models.embeddings.dimensions` | 預設嵌入維度數                      | `1024`                             |
| `models.image.default`         | 預設圖像模型                       | `stability.stable-image-core-v1:1` |
| `models.audio.default`         | 預設語音（TTS）引擎                  | `generative`                       |
| `models.reranking.default`     | 預設重新排序模型                     | `cohere.rerank-v3-5:0`             |

## 文字生成

### Agent 類別

以 Artisan 指令建立 Agent 類別。

```bash theme={null}
php artisan make:agent BedrockAgent
```

```php theme={null}
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;

class BedrockAgent implements Agent
{
    use Promptable;

    public function instructions(): string
    {
        return '你是一位軟體開發專家。';
    }
}
```

```php theme={null}
use App\Ai\Agents\BedrockAgent;

$response = (new BedrockAgent)->prompt('請介紹一下 Laravel。');

echo $response->text;
```

### Anonymous Agent

不建立類別、需要快速使用時，可利用 `agent()` 輔助函式。

```php theme={null}
use function Laravel\Ai\agent;

$response = agent(
    instructions: '你是一位軟體開發專家。',
)->prompt('請介紹一下 Laravel。');

echo $response->text;
```

### 串流

```php theme={null}
use App\Ai\Agents\BedrockAgent;
use Illuminate\Support\Facades\Route;

Route::get('/stream', function () {
    return (new BedrockAgent)->stream('請介紹一下 Laravel。');
});
```

也可以手動處理事件。

```php theme={null}
use Laravel\Ai\Streaming\Events\TextDelta;

use function Laravel\Ai\agent;

$stream = agent(
    instructions: '你是一位軟體開發專家。',
)->stream('請介紹一下 Laravel。');

foreach ($stream as $event) {
    if ($event instanceof TextDelta) {
        echo $event->delta;
    }
}
```

### 工具使用（Function Calling）

定義在生成過程中會被呼叫的工具。

```php theme={null}
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;

class GetWeather implements Tool
{
    public function description(): string
    {
        return '回傳指定城市的目前天氣。';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'city' => $schema->string()->required()->description('城市名稱'),
        ];
    }

    public function handle(Request $request): string
    {
        // 在此呼叫天氣 API
        return json_encode(['temperature' => 22, 'condition' => 'sunny']);
    }
}
```

從 Agent 中使用。

```php theme={null}
use App\Ai\Tools\GetWeather;
use Laravel\Ai\Attributes\MaxSteps;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;

#[MaxSteps(5)]
class WeatherAgent implements Agent, HasTools
{
    use Promptable;

    public function tools(): array
    {
        return [new GetWeather];
    }

    public function instructions(): string
    {
        return '你是一位天氣助理。';
    }
}

$response = (new WeatherAgent)->prompt('東京的天氣如何？');
echo $response->text;
```

Anonymous Agent 也可以使用。

```php theme={null}
use function Laravel\Ai\agent;

$response = agent(
    instructions: '你是一位天氣助理。',
    tools: [new GetWeather],
    maxSteps: 5,
)->prompt('東京的天氣如何？');
```

串流中呼叫工具也能運作。SDK 會自動執行工具，並持續對話直到取得最終的文字回應。

### 檔案附件

透過 `attachments` 參數可將圖像、文件、音訊、影片附加至提示中。Bedrock Converse API 會處理附件區塊，但實際上可用的格式取決於模型（例：Anthropic Claude 僅支援圖像與文件）。

```php theme={null}
use Laravel\Ai\Files\Document;
use Laravel\Ai\Files\Image;

use function Laravel\Ai\agent;

// 附加本機路徑的圖像
$response = agent(
    instructions: '你是一位有用的助理。',
)->prompt('請說明這張圖片。', attachments: [
    Image::fromPath('/path/to/photo.jpg'),
]);

// 附加 URL 上的文件
$response = agent(
    instructions: '你是一位有用的助理。',
)->prompt('請總結這份文件。', attachments: [
    Document::fromUrl('https://example.com/report.pdf'),
]);

// 從字串附加（明確指定格式）
$response = agent(
    instructions: '你是一位有用的助理。',
)->prompt('請分析這段文字。', attachments: [
    Document::fromString($csvContent, 'text/csv')->as('data.csv'),
]);
```

支援的附件型別為 `Laravel\Ai\Files\*` 底下的 `Image`、`Document`、`Audio`。影片可透過 `Illuminate\Http\UploadedFile` 附加。

<Info>
  伺服器端的檔案上傳（`Document::fromPath()->put()`）以及透過 ID 重用（`Document::fromId()`）在 Bedrock 中尚未支援。
</Info>

### 對話歷史

若要維持多輪對話，可在 Agent 類別中實作 `Conversational` 介面。在 `messages()` 中回傳過去的對話訊息，SDK 會自動包含在每次提示中。

```php theme={null}
<?php

namespace App\Ai\Agents;

use App\Models\ChatHistory;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\Conversational;
use Laravel\Ai\Messages\Message;
use Laravel\Ai\Promptable;

class ChatAgent implements Agent, Conversational
{
    use Promptable;

    public function __construct(public int $userId) {}

    public function instructions(): string
    {
        return '你是一位有用的助理。';
    }

    public function messages(): iterable
    {
        return ChatHistory::where('user_id', $this->userId)
            ->latest()
            ->limit(20)
            ->get()
            ->reverse()
            ->map(fn ($m) => new Message($m->role, $m->content))
            ->all();
    }
}
```

```php theme={null}
$response = (new ChatAgent(auth()->id()))->prompt('上次我們聊了什麼？');
```

#### 使用 `RemembersConversations` 自動儲存

若不想自行實作 `messages()`，可利用 `RemembersConversations` trait 進行完全自動的對話儲存。需要 AI SDK 的資料庫資料表，請先執行 `php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider" && php artisan migrate`。

```php theme={null}
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Concerns\RemembersConversations;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\Conversational;
use Laravel\Ai\Promptable;

class ChatAgent implements Agent, Conversational
{
    use Promptable, RemembersConversations;

    public function instructions(): string
    {
        return '你是一位有用的助理。';
    }
}
```

開始新對話。

```php theme={null}
$response = (new ChatAgent)->forUser($user)->prompt('你好！');

$conversationId = $response->conversationId;
```

繼續既有對話。

```php theme={null}
$response = (new ChatAgent)
    ->continue($conversationId, as: $user)
    ->prompt('請告訴我更多細節。');
```

Bedrock 驅動會自動將對話歷史加入 Bedrock Converse API 請求中，因此所有支援的模型都能運用多輪對話的上下文。

### 結構化輸出

實作 `HasStructuredOutput` 介面便可取得有型別的回應。

```php theme={null}
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;

class ExtractPerson implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): string
    {
        return '請從給定的文字中萃取人物資訊。';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'name' => $schema->string()->description('人物的全名'),
            'age' => $schema->integer()->description('年齡'),
            'occupation' => $schema->string()->description('職業'),
        ];
    }
}

$response = (new ExtractPerson)->prompt('John 是一位 30 歲的軟體工程師。');

echo $response['name'];       // "John"
echo $response['age'];        // 30
echo $response['occupation']; // "software engineer"
```

Anonymous Agent 也可使用結構化輸出。

```php theme={null}
use function Laravel\Ai\agent;

$response = agent(
    instructions: '請從給定的文字中萃取人物資訊。',
    schema: fn (JsonSchema $schema) => [
        'name' => $schema->string()->description('人物的全名'),
        'age' => $schema->integer()->description('年齡'),
    ],
)->prompt('Alice is 25 years old.');

echo $response['name']; // "Alice"
echo $response['age'];  // 25
```

在內部會建立一個依 schema 回傳值的合成工具（`output_structured_data`）。這種方式透過 Converse API 與 Bedrock 上的所有模型相容。

### Converse API（所有模型）

所有文字生成與串流都透過 [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html) 執行。包含 Anthropic Claude 在內都已統一，可用相同介面使用 Amazon Nova、Meta Llama、Mistral、Cohere、DeepSeek 等 Bedrock 上的各種模型。

```php theme={null}
use function Laravel\Ai\agent;

// Anthropic Claude（透過 Converse API）
$response = agent(
    instructions: '你是一位軟體開發專家。',
    model: 'global.anthropic.claude-sonnet-4-6',
)->prompt('請介紹一下 Laravel。');

// Amazon Nova
$response = agent(
    instructions: '你是一位有用的助理。',
    model: 'amazon.nova-pro-v1:0',
)->prompt('請介紹一下 AWS。');

// Meta Llama
$response = agent(
    instructions: '你是一位有用的助理。',
    model: 'meta.llama3-1-70b-instruct-v1:0',
)->prompt('請說明量子運算。');

// Mistral
$response = agent(
    instructions: '你是一位有用的助理。',
    model: 'mistral.mistral-large-2402-v1:0',
)->prompt('請寫一首關於寫程式的俳句。');

// Cohere Command R+
$response = agent(
    instructions: '你是一位有用的助理。',
    model: 'cohere.command-r-plus-v1:0',
)->prompt('請總結這段文字。');

// DeepSeek R1
$response = agent(
    instructions: '你是一位有用的助理。',
    model: 'deepseek.r1-v1:0',
)->prompt('請解答這道數學問題。');
```

串流、工具使用、結構化輸出、檔案附件會在支援這些功能的模型上運作。詳情請參考 [Bedrock 支援模型清單](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-supported-models-features.html)。

### Provider Options

若要傳遞如 `anthropic_version` 等 Bedrock 專屬選項，可實作 `HasProviderOptions`。

```php theme={null}
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasProviderOptions;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;

class BedrockAgent implements Agent, HasProviderOptions
{
    use Promptable;

    public function instructions(): string
    {
        return '你是一位軟體開發專家。';
    }

    public function providerOptions(Lab|string $provider): array
    {
        return [
            'top_p' => 0.9,
        ];
    }
}
```

支援的 Provider Options：

| 選項                             | 說明                     | 預設值 |
| ------------------------------ | ---------------------- | --- |
| `top_k`                        | Top-K 取樣參數             | —   |
| `top_p`                        | Top-P（nucleus）取樣參數     | —   |
| `additionalModelRequestFields` | Converse API 的模型專屬額外參數 | —   |

### Agent 的設定屬性

可透過 PHP 屬性設定文字生成的選項。

```php theme={null}
use Laravel\Ai\Attributes\MaxTokens;
use Laravel\Ai\Attributes\Temperature;
use Laravel\Ai\Attributes\Timeout;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;

#[MaxTokens(4096)]
#[Temperature(0.7)]
#[Timeout(120)]
class BedrockAgent implements Agent
{
    use Promptable;

    // ...
}
```

## 圖像生成

使用 Stability AI 模型（預設）或 Amazon Nova Canvas 生成圖像。

```php theme={null}
use Laravel\Ai\Image;
use Revolution\Amazon\Bedrock\Bedrock;

// 預設使用 Stability AI Stable Image Core
$response = Image::of('可愛的蒸汽龐克機器人')->generate(provider: Bedrock::KEY);

// 取得第一張圖像
$image = $response->firstImage();

// 儲存至磁碟
$response->store('images', 's3');

// 輸出為 HTML 的 <img> 標籤
echo $response->toHtml('蒸汽龐克機器人');
```

可用的 Stability AI 模型（皆需 `us-west-2` 區域）：

```php theme={null}
// Stable Image Core — 快速、低成本（預設）
$response = Image::of('風景')
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-core-v1:1');

// Stable Diffusion 3.5 Large — 高品質、大量生成
$response = Image::of('人像')
    ->generate(provider: Bedrock::KEY, model: 'stability.sd3-5-large-v1:0');

// Stable Image Ultra — 超逼真、最高品質
$response = Image::of('質感精緻的產品')
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-ultra-v1:1');
```

<Info>
  Stability AI 圖像模型僅可於 `us-west-2` 使用。使用這些模型時請設定 `AWS_DEFAULT_REGION=us-west-2`。
</Info>

### Stability AI 的圖像編輯

Stability AI Image Services 的編輯類模型也可透過 `attachments()` 方法使用。傳入輸入圖像，並以編輯模型進行轉換。

```php theme={null}
use Laravel\Ai\Files\Image as ImageFile;
use Laravel\Ai\Image;
use Revolution\Amazon\Bedrock\Bedrock;

$inputImage = ImageFile::fromPath('/path/to/photo.jpg');

// Inpaint — 用遮罩或 alpha channel 重繪區域
$response = Image::of('請把背景換成森林')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-inpaint-v1:0');

// Erase — 移除不需要的元素
$response = Image::of('')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-erase-object-v1:0');

// 移除背景以擷取主體
$response = Image::of('')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-remove-background-v1:0');

// Search and Replace — 以提示指定的物件進行替換
$response = Image::of('貓')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-search-replace-v1:0');

// Style Transfer — 套用提示風格
$response = Image::of('油畫風格')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-style-transfer-v1:0');
```

可用的 Stability AI 編輯模型（皆可於 `us-east-1`、`us-east-2`、`us-west-2` 使用）：

| Model ID                                        | 說明                          |
| ----------------------------------------------- | --------------------------- |
| `stability.stable-image-inpaint-v1:0`           | Inpaint — 重繪選取區域            |
| `stability.stable-outpaint-v1:0`                | Outpaint — 將圖像向邊界外擴展        |
| `stability.stable-image-erase-object-v1:0`      | Erase — 移除物件                |
| `stability.stable-image-remove-background-v1:0` | 移除背景                        |
| `stability.stable-image-search-replace-v1:0`    | Search and Replace — 替換物件   |
| `stability.stable-image-search-recolor-v1:0`    | Search and Recolor — 變更物件顏色 |
| `stability.stable-image-style-guide-v1:0`       | Style Guide — 以參考圖像套用風格     |
| `stability.stable-style-transfer-v1:0`          | Style Transfer — 轉移畫風       |
| `stability.stable-image-control-sketch-v1:0`    | Control Sketch — 從草圖生成      |
| `stability.stable-image-control-structure-v1:0` | Control Structure — 依結構生成   |
| `stability.stable-creative-upscale-v1:0`        | Creative Upscale — 一邊補全一邊放大 |
| `stability.stable-conservative-upscale-v1:0`    | Conservative Upscale — 保留細節 |
| `stability.stable-fast-upscale-v1:0`            | Fast Upscale — 輕量的 4 倍放大    |

亦支援 Amazon Nova Canvas，但 AWS 正逐步將其標示為不建議使用。

```php theme={null}
// Nova Canvas（不建議。可於 us-east-1、ap-northeast-1、eu-west-1 使用）
$response = Image::of('夕陽')
    ->size('3:2')           // '1:1', '3:2', '2:3'
    ->quality('high')       // 'low', 'medium', 'high'（僅 Nova Canvas）
    ->generate(provider: Bedrock::KEY, model: 'amazon.nova-canvas-v1:0');
```

## 語音（TTS）

使用 [Amazon Polly](https://docs.aws.amazon.com/polly/latest/dg/what-is.html) 從文字生成語音。

```php theme={null}
use Laravel\Ai\Audio;
use Revolution\Amazon\Bedrock\Bedrock;

$response = Audio::of('我很喜歡用 Laravel 寫程式。')->generate(provider: Bedrock::KEY);

$rawContent = (string) $response;
```

可指定男聲 / 女聲。

```php theme={null}
$response = Audio::of('我很喜歡用 Laravel 寫程式。')
    ->female()
    ->generate(provider: 'bedrock');

$response = Audio::of('我很喜歡用 Laravel 寫程式。')
    ->male()
    ->generate(provider: Bedrock::KEY);
```

指定特定的 [Polly 聲音](https://docs.aws.amazon.com/polly/latest/dg/voicelist.html)。

```php theme={null}
$response = Audio::of('我很喜歡用 Laravel 寫程式。')
    ->voice('Joanna')
    ->generate(provider: Bedrock::KEY);
```

儲存生成的語音。

```php theme={null}
$response = Audio::of('我很喜歡用 Laravel 寫程式。')->generate(provider: Bedrock::KEY);

$path = $response->store();
$path = $response->storeAs('audio.mp3');
```

也可以指定引擎（模型）。

```php theme={null}
// generative（預設）、neural、long-form、standard
$response = Audio::of('我很喜歡用 Laravel 寫程式。')
    ->generate(provider: Bedrock::KEY, model: 'neural');
```

**預設聲音：**`default-female` → Ruth、`default-male` → Matthew（兩者皆支援 generative 引擎）。

<Warning>
  Amazon Polly 是與 Bedrock 不同的 AWS 服務。Bedrock API 金鑰（bearer token）無法用於 Polly，請改用 AWS IAM 認證（SigV4）或預設 AWS 認證鏈。
</Warning>

## 嵌入

使用 Amazon Titan Embeddings V2 產生向量嵌入。

```php theme={null}
use Laravel\Ai\Embeddings;
use Revolution\Amazon\Bedrock\Bedrock;

$response = Embeddings::for(['Hello world', 'Foo bar'])->generate(provider: Bedrock::KEY);

// 第一個嵌入向量
$vector = $response->first();

// 迭代所有嵌入
foreach ($response as $embedding) {
    // $embedding 為 float 陣列
}

echo $response->tokens; // 總 token 數
```

可指定維度數（Titan Embeddings V2 支援 256、512、1024）。

```php theme={null}
$response = Embeddings::for(['Hello world'])->dimensions(512)->generate(provider: Bedrock::KEY);
```

指定自訂模型的範例。

```php theme={null}
$response = Embeddings::for(['Hello world'])
    ->dimensions(1024)
    ->generate(provider: Bedrock::KEY, model: 'amazon.titan-embed-text-v2:0');
```

### Cohere Embed 模型

Cohere Embed 模型會自動被偵測並使用批次 API。Titan 每筆輸入都需一次 HTTP 請求，而 Cohere 會將所有輸入整合為一次請求，因此在處理多段文字時效率更好。

```php theme={null}
// Cohere Embed English V3
$response = Embeddings::for(['Hello world', 'Foo bar'])
    ->dimensions(1024)
    ->generate(provider: Bedrock::KEY, model: 'cohere.embed-english-v3');

// Cohere Embed Multilingual V3
$response = Embeddings::for(['Hello', '你好'])
    ->dimensions(1024)
    ->generate(provider: Bedrock::KEY, model: 'cohere.embed-multilingual-v3');

// Cohere Embed V4（輸出維度可設為 256〜1536）
$response = Embeddings::for(['Hello world'])
    ->dimensions(512)
    ->generate(provider: Bedrock::KEY, model: 'cohere.embed-v4');
```

<Info>
  Cohere Embed 模型不會回傳 token 數，因此 `$response->tokens` 一律為 `0`。
</Info>

## 重新排序

使用 Cohere Rerank 3.5 或 Amazon Rerank 1.0，依與查詢的相關度重新排序文件。

```php theme={null}
use Laravel\Ai\Reranking;
use Revolution\Amazon\Bedrock\Bedrock;

$response = Reranking::of([
    'Laravel 是一款 PHP 的 Web 框架。',
    'Python 是一種程式語言。',
    'Laravel 提供了適合 Web 開發的優雅語法。',
])->rerank(query: 'Laravel 是什麼？', provider: Bedrock::KEY);

// 相關度最高的文件
echo $response->first()->document;
echo $response->first()->score;

// 依排序取得所有結果
foreach ($response as $result) {
    echo "{$result->index}: {$result->document} ({$result->score})\n";
}

// 限制件數
$response = Reranking::of([...])
    ->limit(2)
    ->rerank(query: 'Laravel 是什麼？', provider: Bedrock::KEY);
```

指定自訂模型的範例。

```php theme={null}
$response = Reranking::of([...])
    ->rerank(query: '搜尋查詢', provider: Bedrock::KEY, model: 'amazon.rerank-v1:0');
```

<Info>
  重新排序 API 使用的是 `bedrock-agent-runtime` 端點（非 `bedrock-runtime`）。Amazon Rerank 1.0 無法在 `us-east-1` 使用，該區域請改用 Cohere Rerank 3.5。
</Info>

## 測試

可直接使用 AI SDK 的標準測試機能。

雖然官方文件未提及，但透過 `agent()` 輔助函式建立的 Anonymous Agent 可以用 `AnonymousAgent::fake()` 進行 mock，結構化輸出版本則可用 `StructuredAnonymousAgent::fake()`。

```php theme={null}
use Laravel\Ai\AnonymousAgent;
use Laravel\Ai\Prompts\AgentPrompt;

use function Laravel\Ai\agent;

it('can generate text', function () {
    AnonymousAgent::fake();

    $response = agent(
        instructions: '你是一位軟體開發專家。',
    )->prompt('請介紹一下 Laravel。');

    AnonymousAgent::assertPrompted(function (AgentPrompt $prompt) {
        return $prompt->contains('Laravel');
    });
});
```

<Info>
  最新資訊請參考 [GitHub 儲存庫](https://github.com/invokable/laravel-amazon-bedrock)。
</Info>


## Related topics

- [Bot 教學 - Laravel Bluesky](/zh-TW/packages/laravel-bluesky/bot-tutorial.md)
- [我的包](/zh-CN/packages/index.md)
- [建立 AI SDK 的自定義 Provider](/zh-TW/advanced/ai-sdk-custom-provider.md)
- [Laravel AI SDK](/zh-TW/ai-sdk.md)
- [郵件寄送](/zh-TW/mail.md)
