> ## 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 驱动。支持文本生成、流式输出、tool 使用、结构化输出、文件附件、会话历史、embedding、图像生成、语音 (TTS)、reranking。

## 概览

[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 key 即可使用 | 支持的模型 / 服务                                                                                 |
| -------------------------- | ------------------------ | ------------------------------------------------------------------------------------------ |
| 文本生成 / 流式输出                | ✅                        | Anthropic Claude、Amazon Nova，以及大部分 Bedrock 模型（全部通过 Converse API）                           |
| Tool 使用 (Function Calling) | ✅                        |                                                                                            |
| 结构化输出                      | ✅                        |                                                                                            |
| 文件附件                       | ✅                        | 通过 Converse API 附加图像、文档、音频、视频（不同模型支持的格式不同）                                                 |
| 图像生成                       | ✅                        | Stability AI（默认）、Amazon Nova Canvas（已弃用）                                                   |
| 语音 (TTS)                   | ⚠️                       | Amazon Polly（generative / neural / long-form / standard 引擎）                                |
| 语音识别 (STT)                 | ❌                        | 不支持                                                                                        |
| Embedding                  | ✅                        | Amazon Titan Embeddings V2（默认）、Cohere Embed English/Multilingual V3、Cohere Embed V4（支持批处理） |
| Reranking                  | ⚠️                       | Cohere Rerank 3.5、Amazon Rerank 1.0                                                        |
| 文件                         | ✅                        | 文本生成中支持本地文件附件。不支持服务端上传以及 `fromId()`                                                        |

<Info>
  表格中的 `⚠️` 表示的不是 “功能本身不支持”，而是 “仅通过 Bedrock API key 无法使用”。
</Info>

<Info>
  Laravel AI SDK v0.6.3 已官方支持使用 Bedrock API key 的 Text、Image 与 Embeddings。本包同时还支持基于 Amazon Polly 的语音 (TTS)、reranking 等官方集成尚未提供的功能，因此仍会继续维护公开。
</Info>

主要特性如下：

* **认证**：可以从 Bedrock API key、AWS IAM 凭据 (SigV4)、默认 AWS 凭据链（IAM role、实例配置文件等）中选择。
* **故障转移**：支持 AI SDK 的多 provider 故障转移。速率限制 (429)、过载 (503、529)、credit 相关错误会被映射为可故障转移的异常。
* **缓存控制**：始终为 [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html) 的 system prompt 启用 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` provider。根据需要，也可以将默认 provider 切换为 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 key

```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 key 可以在 AWS 管理控制台中获取。

<Warning>
  Bedrock API key 仅适用于 Bedrock Runtime API。使用 `bedrock-agent-runtime` 的 reranking 和 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>
  只有在使用临时凭据 (STS) 时，才需要设置 `AWS_SESSION_TOKEN`。
</Info>

### 方式 3：默认 AWS 凭据链 (IAM role)

在 EC2 / ECS / Lambda 等具备 IAM role 的环境中，可以省略 `key` 和 `secret`，使用[默认的 AWS 凭据 provider 链](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 任务 role、EC2 实例配置文件等来源中解析凭据。

### 可选配置项

| 键                              | 说明                            | 默认值                                               |
| ------------------------------ | ----------------------------- | ------------------------------------------------- |
| `secret`                       | AWS secret access key (SigV4) | —                                                 |
| `token`                        | AWS session token (SigV4)     | —                                                 |
| `timeout`                      | HTTP 请求超时（秒）                  | 30                                                |
| `max_tokens`                   | 单次请求的默认 max tokens            | 8096                                              |
| `models.text.default`          | 默认文本模型                        | `global.anthropic.claude-sonnet-4-6`              |
| `models.text.cheapest`         | 最便宜的文本模型                      | `global.anthropic.claude-haiku-4-5-20251001-v1:0` |
| `models.text.smartest`         | 性能最强的文本模型                     | `global.anthropic.claude-opus-4-7`                |
| `models.embeddings.default`    | 默认 embedding 模型               | `amazon.titan-embed-text-v2:0`                    |
| `models.embeddings.dimensions` | 默认 embedding 维度               | `1024`                                            |
| `models.image.default`         | 默认图像模型                        | `stability.stable-image-core-v1:1`                |
| `models.audio.default`         | 默认语音 (TTS) 引擎                 | `generative`                                      |
| `models.reranking.default`     | 默认 reranking 模型               | `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;
    }
}
```

### Tool 使用 (Function Calling)

定义会在生成过程中被调用的 tool。

```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('东京的天气如何？');
```

Tool 调用在流式输出中同样有效。SDK 会自动执行 tool，并持续对话，直到得到最终的文本响应。

### 文件附件

通过 `attachments` 参数可以向 prompt 中附加图像、文档、音频和视频文件。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>
  Bedrock 不支持服务端文件上传 (`Document::fromPath()->put()`) 和通过 ID 复用 (`Document::fromId()`)。
</Info>

### 会话历史

要保持多轮会话，请在 Agent 类中实现 `Conversational` 接口。在 `messages()` 中返回过去的会话消息，它们会自动包含在每次 prompt 中。

```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
```

在内部，它会创建一个合成 tool（`output_structured_data`）来强制返回符合 schema 的值。这种方式通过 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('请解答这道数学题。');
```

流式输出、tool 使用、结构化输出、文件附件都会在支持这些能力的模型上生效。详情请参考 [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 attribute 配置文本生成的选项。

```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 —— 通过 mask 或 alpha 通道重绘区域
$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 —— 替换 prompt 中指定的对象
$response = Image::of('猫')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-search-replace-v1:0');

// Style Transfer —— 应用 prompt 指定的风格
$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 voice](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 key（bearer token）不能用于 Polly。请使用 AWS IAM 凭据 (SigV4) 或默认 AWS 凭据链。
</Warning>

## Embedding

使用 Amazon Titan Embeddings V2 生成向量 embedding。

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

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

// 第一个 embedding 向量
$vector = $response->first();

// 遍历全部 embedding
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>

## Reranking

使用 Cohere Rerank 3.5 或 Amazon Rerank 1.0，按与 query 的相关度对文档重新排序。

```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: '搜索 query', provider: Bedrock::KEY, model: 'amazon.rerank-v1:0');
```

<Info>
  Reranking 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()` 来 mock。

```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/packages/laravel-bluesky/bot-tutorial.md)
- [创建 AI SDK 的自定义 Provider](/zh/advanced/ai-sdk-custom-provider.md)
- [SessionEvent](/zh/packages/laravel-copilot-sdk/session-event.md)
- [Laravel AI SDK](/zh/ai-sdk.md)
- [Laravel Nostr](/zh/packages/laravel-nostr.md)
