> 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/gai-lan/upgrade.md).

# 升级

## 从 v2 升级到 v3

在这个新的重大版本中，Neuron 组件的公开 API 并没有发生剧烈变化（我们尽可能将影响降到最低），但 Agent、RAG 和消息系统的底层架构已经基于 Workflow 组件完全重建，而现在整个框架都由它驱动。

现在 Agent 和 RAG 不再是简单对象，而是工作流。它们继承了在之前独立实现中无法集成的功能，例如：

* 统一的 [消息系统](/neuron-v3-zh/agent/messages.md#the-unified-messaging-layer) 用于多模态智能体
* 原生支持 [工具审批](/neuron-v3-zh/agent/middleware.md#human-in-the-loop) 以及完全可自定义的人在回路流程
* 多智能体 [流式](https://docs.neuron-ai.dev/workflow/streaming) 与协作。

我们还借此版本修复了 v2 中出现的其他关键设计问题，例如 **对所有提供方的推理模型提供完整支持**，以及其他设计改进，使我们能够以更少的破坏性变更在未来更自由地演进框架。

我们将继续努力提供尽可能好的开发者体验，帮助你用 PHP 创建成功的 AI 产品。

## 更新依赖

你应该更新应用程序中的以下依赖项 `composer.json` 文件：

* **neuron-core/neuron-ai** 为 **^3.0**

## 高影响变更

### 新的 Agent 命名空间

Agent 类及相关类和 trait 已从根目录移至专用命名空间 `NeuronAI\Agent`.

你需要在使用 Agent 类的文件中更新命名空间，从：

```php
use NeuronAI\Agent;
```

到：

```php
use NeuronAI\Agent\Agent;
```

SystemPrompt 类也一样。新的命名空间是 `NeuronAI\Agent\SystemPrompt`.

### 移除 chatAsync()

该 `chatAsync()` 方法已从 `AgentInterface`中完全移除。如果你在应用程序中使用了此方法，你必须切换到新的异步模式。

<a href="/pages/2f39a37d3f7f10b55944122f5a793b8f10533a03" class="button primary" data-icon="arrow-right-long">了解异步</a>

### Agent 返回类型

由于 Agent 现在是一个工作流，你需要使用略有不同的 API 来真正运行 agent 并获取 LLM 响应。

以前你会直接从 `chat()` 方法中获得一个 Message 实例。现在 chat 方法返回一个工作流状态，你可以用它来获取最终的 agent 响应。

返回的 agent 状态让你可以轻松访问 LLM 响应，同时也可以检查 agent 内部执行的其他方面。下面是运行 agent 并输出 LLM 生成内容的新语法示例。

```php
// 旧版本的 chat() 返回 LLM 响应
$message = MyAgent::make()->chat(new UserMessage("Hi, who are you?"));

// V3 - 你需要调用 "getMessage()"
$message = MyAgent::make()
    ->chat(new UserMessage("Hi, who are you?"))
    ->getMessage();

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

### 消息内容块

内容块现在取代了基于“附件”的旧方案。旧的附件系统已被移除。迁移方式：

**旧方案** （不再可用）：

```php
$message = new UserMessage('Analyze this');
$message->addAttachment(new Image($url, AttachmentContentType::URL));
```

**新方案**:

```php
// 简单文本消息（向后兼容）
$message = new UserMessage("Hi");

// 传递图片、文件等的新格式
$message = new UserMessage([
    new TextBlock('分析这个'),
    new ImageBlock($url, SourceType::URL)
]);

// 添加更多块
$message->addContent(
    new TextBlock('记得以专业礼宾的身份回答。')
);

// 打印所有文本内容块
echo $message->getContent();
```

该方法 `getContent()` 没有变化，但现在会返回所有文本块拼接后的结果，并跳过媒体类型。

块的组合解锁了多模态支持，如果你需要在执行过程中动态注入额外提示或指令，这会非常有帮助。

<a href="/pages/c43edf835d021aaf4a99b145fbe60714e93cbfaa" class="button primary" data-icon="arrow-right-long">了解消息</a>

### 流式分块

在之前的版本中，流式接口会为 LLM 响应分块返回简单字符串，以及 `ToolCallMessage`，或者 `ToolCallResultMessage` 实例直接用于工具相关操作。这会让消息实例与你的应用读取流之间耦合得过于紧密。

我们实现了专用的分块类 `TextChunk`, `ReasoningChunk`, `ToolCallChunk`, `ToolResultChunk`等，以便为每种流增量提供专门的容器。这样更清晰的职责分离，为 [适配器系统](#streaming-adapters)的实现打开了大门，并让我们在未来以更少的破坏性变更改进这一层，同时保持统一消息系统的稳定。

#### ToolCallChunk

在上一版本中，Neuron 直接流式输出 `ToolCallMessage` 包含本次迭代中涉及工具列表的实例。现在你会得到一个专用的 `ToolCallChunk` 用于模型请求执行的每个工具。

<a href="/pages/926cdf3ff5b29c99f85d867517837b91641afff5" class="button primary" data-icon="arrow-right-long">阅读更多关于流式传输的信息</a>

### 结构化输出

我们扩展了 `SchemaProperty` 属性的角色，使其成为类属性 JSON schema 定义的真实来源。它现在支持 `最小值`, `最大值`, `最小长度`, `最大长度`, `anyOf`.

```php
use NeuronAI\StructuredOutput\SchemaProperty;

class Person 
{
    #[SchemaProperty(
        description: '用户名称。',
        required: true,
        minLength: 3,
        maxLength: 255,
    )]
    public string $name;
    
    #[SchemaProperty(
        description: '用户喜欢吃什么。', 
        required: false,
        min: 18,
        max: 64,
    )]
    public ?int $age = null;
}
```

#### 对象数组

如果某个属性是结构化对象数组，你不再需要指定该属性类型的 doc-block，只需在 `anyOf` 参数：

```php
class Report
{
    #[SchemaProperty(
        description: '报告内容。', 
        required: true,
        anyOf: [TextBlock::class, TableBlock::class, ImageBlock::class]
    )]
    public array $content;
}
```

<a href="/pages/05afe29ed635c4c3611b88d603ebd11492cbd5b2" class="button primary" data-icon="arrow-right-long">结构化输出</a>

### 工作流中断请求（人在回路）

在上一版本中，当你在 Node 内请求中断时，可以传递一个数据数组，向客户端说明中断的原因和背后的操作。

{% code title="旧语法" %}

```php
$feedback = $this->interrupt(['message' => 'do you want to approve?']);
```

{% endcode %}

这种懒类型方法导致了不一致和错误。我们引入了 `InterruptRequest` 原语，帮助你使用带类型结构创建中断流程，以便安全地集成到 UI 中。

{% code title="新语法" %}

```php
$feedback = $this->interrupt(new ApprovalRequest(
    reason: 'Do you want to approve?',
    actions: [
        new Action(...)
    ]
));
```

{% endcode %}

在文档的专门章节中了解更多。

<a href="/pages/de954a56ea9df43e4aac850226dc0531dadd7a19" class="button primary" data-icon="arrow-right-long">工作流中断</a>

### 工作流数据库持久化变更

工作流持久化数据库表的列名已更改：

* data -> interrupt

<a href="/pages/55dcebde930b487a68c1e48c569da3ea403ed662" class="button primary" data-icon="arrow-right-long">工作流持久化</a>

## 中等影响

### 重命名 ToolCallResultMessage

该类已重命名为 `ToolResultMessage`.

### 监控与观察者

Agent、RAG 和 Workflow 实体不再实现 PHP `\SplSubject` 接口，而观察者类也不再实现 `\SplObserver` 接口。我们引入了新的 `ObserverInterface` ，它只需由诸如 `LogObserver`这样的事件监听器实现。这个更轻量的结构帮助我们使 Workflow、node 和 middleware 等工作流构建块具备可观察性。这意味着你可以从自定义节点发出事件，只需创建并注册自定义观察者来监听这些事件即可。

阅读 [监控部分](/neuron-v3-zh/agent/observability.md).

### 移除 HttpClientOptions

该类已被移除，转而采用框架内对 HttpClient 的完整抽象。我们采用了适配器模式，让你可以将自定义 http 客户端注入框架组件，并自定义其配置。Guzzle 客户端适配器还支持 handler stack、自定义头等。

你可以在 [异步](/neuron-v3-zh/agent/async.md) 部分。

### Qdrant 1.10.x

Qdrant 向量存储组件已更新，以支持从 1.10.x 版本开始包含的新的 [查询 API](https://api.qdrant.tech/api-reference/search/query-points) 。如果你使用的是旧版本的 Qdrant 数据库，则需要升级你的实例。

### AbstractChatHistory 方法签名

如果你实现了自定义聊天历史组件，你需要调整这些钩子方法的签名。它们的可见性级别已从 public 改为 protected，并且不再有返回类型：

```php
class MyChatHistory extends AbstractChatHistory
{
    protected function setMessages(array $messages): void
    {
        // 一次性处理保存整个历史记录。
    }

    protected function onNewMessage(Message $message): void
    {
        // 处理单条消息的添加。
    }

    protected function onTrimHistory(int $index): void
    {
        // 当触发裁剪时，位置从 0 到 $index 的消息必须被移除。
    }

    protected function clear(): void
    {
        // 移除所有消息。
    }
}
```

## 新功能

### 工具审批与条件审批

得益于底层工作流架构支持的人在回路模式，我们创建了一个内置中间件，使你可以像即插即用的功能一样在智能体中启用工具审批：

```php
new ToolApproval(
    tools: [
        BuyTicketTool::class => function (array $args): bool {
            return $args['amount'] > 100;
        }
    ]
)
```

<a href="/pages/9ea2066a9f786ede6683c1553ff65e839e3105e5#tool-approval-human-in-the-loop" class="button primary" data-icon="arrow-right-long">工具审批</a>

### Mistral 专用提供方

Mistral 提供方不再是纯粹的 OpenAI 实现，而是演进为拥有自己的 API 格式实现，以支持多模态输入和推理模型。

<a href="/pages/c3b733b97e20989b495a4cd7afab5a205a44773a#mistral" class="button primary" data-icon="arrow-right-long">Mistral AI 提供方</a>

### Cohere AI 提供方

此版本附带一个全新的提供方，用于支持 Cohere 推理平台的云端和私有部署。

<a href="/pages/c3b733b97e20989b495a4cd7afab5a205a44773a#cohere" class="button primary" data-icon="arrow-right-long">Cohere AI 提供方</a>

### 文本转语音提供方

得益于消息的新块组合方式，现在可以轻松处理输入和输出多模态。在此版本中，我们加入了几个可用于处理音频内容的提供方。

<a href="/pages/7e52f0ef77106be30cc1606fa521fa6e46b09030" class="button primary" data-icon="arrow-right-long">文本转语音提供方</a>

### 流式适配器

适配器充当 Neuron 内部流式事件（文本分块、工具调用、推理步骤）与特定前端协议之间的转换器，例如 Vercel AI SDK、AG-UI，或你的自定义前端需求。

这种架构使你无需修改核心智能体逻辑，就能将 Neuron 智能体无缝集成到各种前端框架（React、Vue 等）中。

<figure><img src="/files/47675371437628d2207448d69c2aab3c41b6ba25" alt=""><figcaption></figcaption></figure>

<a href="/pages/926cdf3ff5b29c99f85d867517837b91641afff5#stream-adapters" class="button primary" data-icon="arrow-right-long">了解更多关于适配器的信息</a>

### 文件 ID 内容块

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

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

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

基于你的提供方规格，你对 Image、Video 等也可以采用相同方式。

### 中间件

中间件提供了一种严格控制工作流内部发生内容的方法，因此也适用于你的 Agent 和 RAG，因为它们现在也都是工作流。

核心的工作流执行涉及根据其他节点返回的事件来调用节点。中间件暴露出钩子，以便在执行过程中介入 `之前` 和 `之后` 节点的执行：

<figure><img src="/files/f1432da4b4f85598ea3ab494fa5d3bb0aa908ef7" alt=""><figcaption></figcaption></figure>

此架构已被用于创建 [内置中间件](/neuron-v3-zh/agent/middleware.md) ，适用于 Agent 类，例如上下文摘要或工具审批。

<a href="/pages/7dc437e92dfa92ac5d18fa325dd246325de65cde" class="button primary" data-icon="arrow-right-long">了解更多关于中间件的信息</a>
