> For the complete documentation index, see [llms.txt](https://docs.neuron-ai.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.neuron-ai.dev/neuron-v3-zh/agent/messages.md).

# 消息

## 统一消息层

Neuron 架构的一大优势是用于与多个 AI 提供商交互的统一消息层。开发者不必费力处理 OpenAI、Anthropic、Gemini、Ollama 以及无数其他提供商各不相同的响应格式，而是使用一个单一、优雅的抽象，它会在幕后处理所有复杂性。你的代码将不再依赖于你所使用的特定 LLM 引擎。

当你在应用中集成 Neuron Agents 时，你不会被锁定在任何特定提供商的生态系统或定价模式中。你可以在不同提供商之间无缝切换，以管理成本、环境，或借助新模型发布立即利用这些改进，而无需进行大规模重构项目。

**消息层不仅限于简单的文本内容，还为多模态输入/输出提供统一接口** （文件、图像、视频、音频）适用于所有受支持的提供商，即使底层实现差异巨大。这一架构决策意味着你的 AI 代理保持可移植且面向未来——当新的提供商出现或现有提供商更新其 API 时，你的应用代码无需更改，而 Neuron 的消息层会吸收所有适配复杂性。

## 什么是消息

消息是上下文的基本单位。它们表示模型的输入和输出，携带在与 LLM 交互时表示对话状态所需的内容和元数据。

消息是包含以下内容的对象：

* **角色** - 标识消息类型（例如：user、assistant）
* **内容块** - 表示消息的实际内容（如文本、图像、音频、文件等）
* **元数据** - 可选字段，例如额外的 LLM 响应信息。

下面是一个示例，说明如何向代理发送用户消息，并接收助手消息作为响应。

```php
use NeuronAI\\Chat\\Messages\\UserMssage;

$response = MyAgent::make()
    ->chat(new UserMessage("Hi, who are you?"))
    ->getMessage();

echo $response->getContent();
```

## 内容块

你可以把消息的内容块看作发送给模型，或由模型生成用以回答你的提示的数据负载。消息可以拥有一个对象列表，这些对象扩展自 `ContentBlock` 接口。Neuron 为文本、图像、文件、音频和视频提供了专用内容类型。

消息可以包含任意数量的块，甚至可以包含每种类型的多个块。Neuron 会自动将块类型映射为每个提供商所需的适当格式。

你可以使用以下方法获取并处理消息中的块列表 `getContentBlocks()` 方法中传入你的偏好来定制获取搜索结果的默认选项：

```php
$response = MyAgent::make()->chat(...)->getMessage();

foreach ($response->getContentBlocks() as $block) {
    echo match($block::class) {
        ReasoningContent::class => "推理：".$block->content."\n\n",
        TextContent::class => $block->content,
        ...
        // 其他内容块 
    };
}
```

或者直接使用 `getContent()` 来获取所有拼接后的文本内容：

```php
$response = MyAgent::make()
    ->chat(new UserMessage("..."))
    ->getMessage();

// 将所有文本块拼接为一个字符串
echo $response->getContent();
```

{% hint style="info" %}

#### 验证模型能力

在使用特定内容块之前，你需要验证模型能力，以便正确处理你想发送的信息（图像、音频、视频）。
{% endhint %}

### 文本

此块表示消息的文本部分。你可以在构造函数参数中使用一个简单字符串初始化消息，或者显式添加一个 `TextContent` 块：

```php
use NeuronAI\Chat\Messages\UserMessage;
use NeuronAI\\Chat\\Messages\\ContentBlocks\\TextContent;

// 在构造函数中传入字符串会向消息添加第一个 TextContentBlock
$message = new UserMessage("Hi");

// 向消息添加其他文本部分
$message->addContent(
    new TextContent("My name is John.")
);

$message->addContent(
    new TextContent('请记得以专业礼宾员的身份作答。')
);

// 获取所有拼接后的文本块
echo $message->getContent();
// Hi my name is John. 请记得以专业礼宾员的身份作答。

// 或者获取文本内容块数组
$blocks = $message->getTextBlocks();
```

如你所见，最终消息将由多个块组成。

### 推理

此块将包含模型在最终文本回复之前进行的推理步骤。Neuron 会自动从模型响应中捕获它：

```php
// 与推理模型聊天
$response = MyAgent::make()->chat(...)->getMessage();

foreach ($response->getContentBlocks() as $block) {
    echo match($block::class) {
        ReasoningContent::class => "推理：".$block->content."\n\n",
        TextContent::class => $block->content,
        ...
        // 其他内容块 
    };
}
```

### 图像

对于支持多模态的模型，你可以附加图像以及其他类型的内容，例如文件、音频和视频。

```php
use NeuronAI\Chat\Messages\UserMessage;
use NeuronAI\\Chat\\Messages\\ContentBlocks\\ImageContent;

$message = new UserMessage("描述这张图片");

$message->addContent(
    new ImageContent(
        source: 'https://placehold.co/600x400/EEE/31343C',
        sourceType: SourceType::URL,
        mediaType: 'image/png'
    )
);

$response = MyAgent::make()->chat($message)->getMessage();
echo $response->getContent();
```

### 文件

```php
use NeuronAI\Chat\Messages\UserMessage;
use NeuronAI\\Chat\\Messages\\ContentBlocks\\FileContent;

$message = new UserMessage("总结这份文档");

$message->addContent(
    new FileContent(
        source: base64_encode(file_get_contents(__DIR__.'/invoice.pdf')),
        sourceType: SourceType::BASE64,
        mediaType: 'application/pdf'
    )
);

$response = MyAgent::make()->chat($message)->getMessage();
echo $response->getContent();
```

### 文件 ID

通常你可以通过 URL 或 base64 编码格式，将文件（图像或文档）附加到消息中。许多提供商允许你在其平台上一次性上传文件，然后在消息中通过一个简单的 ID 引用这些文件。这可以大幅节省 token 消耗，并提升模型响应时间。

在从提供商平台收到文件 ID 后，你可以使用以下方式向消息添加文件块 `SourceType::ID`.

```php
// 引用之前在提供商平台上上传的文件 ID
$message = new UserMessage([
    new TextBlock('分析这个'),
    new FileBlock("file_id_xxxx", SourceType::ID)
]);
```

根据你的提供商规范，你也可以对 Image、Video 等使用相同方式。

### 音频

```php
use NeuronAI\Chat\Messages\UserMessage;
use NeuronAI\\Chat\\Messages\\ContentBlocks\\AudioContent;

$message = new UserMessage("转写这段音频");

$message->addContent(
    new FileContent(
        source: base64_encode(file_get_contents(__DIR__.'/music.mp3')),
        sourceType: SourceType::BASE64,
        mediaType: 'audio/mpeg3'
    )
);

$response = MyAgent::make()->chat($message)->getMessage();
echo $response ->getContent();
```

### 视频

```php
use NeuronAI\Chat\Messages\UserMessage;
use NeuronAI\\Chat\\Messages\\ContentBlocks\\VideoContent;

$message = new UserMessage("总结这节课的内容。");

$message->addContent(
    new VideoContent(
        source: base64_encode(file_get_contents(__DIR__.'/lesson_1.mp4')),
        sourceType: SourceType::BASE64,
        mediaType: 'video/mp4'
    )
);

$response = MyAgent::make()->chat($message)->getMessage();
echo $response->getContent();
```
