> 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/gong-zuo-liu/persistence.md).

# 持久化

当我们谈论 Neuron 中的持久化时，我们指的是系统在任何时刻捕获并保留正在运行的工作流完整状态的能力。这包括：

* **所有变量及其当前值**
* **精确的执行位置** – 哪个节点处于活动状态，哪些已完成，哪些在等待
* **上下文和元数据** – 时间戳、用户信息、决策历史
* **错误状态和重试计数器** – 以便能够优雅地处理失败

可以把它想象成一个高级的“游戏存档”功能，只不过是用于业务流程。在任何时刻，当某个节点请求中断时，Neuron 会创建你工作流状态的快照，并将其存储到持久化层中。稍后——无论是几秒、几小时还是几周后——工作流都可以被恢复到那个准确的时刻，并继续执行，仿佛什么都没有发生。

与 Neuron 中的一贯做法一样，Workflow 持久化层建立在一个通用接口之上，因此它具有可扩展性和可互换性。下面是受支持的持久化层。

### 何时使用持久化

当你打算使用中断时，持久化就会派上用场（例如 [工具审批](/neuron-v3-zh/agent/middleware.md#tool-approval-human-in-the-loop)).

### InMemoryPersistence

它只会在当前执行周期内将数据保存在内存中。

```php
use NeuronAI\Workflow\Persistence\InMemoryPersistence;

$workflow = new WorkflowAgent(
    new InMemoryPersistence()
);
```

### FilePersistence

它会将工作流数据和状态存储到本地文件中。

```php
use NeuronAI\Workflow\Persistence\FilePersistence;

$workflow = new WorkflowAgent(
    new FilePersistence(__DIR__), 
);
```

### 数据库

要将工作流中断持久化到数据库中，你需要传入一个 `PDO` 实例。如果你在某个框架之上开发，你可以像 [SQLChatHistory](/neuron-v3-zh/agent/chat-history-and-memory.md#sqlchathistory).

```php
use NeuronAI\Workflow\Persistence\DatabasePersistence;

$workflow = new WorkflowAgent(
    new DatabasePersistence(
        pdo: new \PDO(...),
        table: 'workflow_interrupts'
    ), 
);
```

以下是创建该表的 SQL 脚本：

{% tabs %}
{% tab title="MySQL/MariaDB" %}

```sql
CREATE TABLE IF NOT EXISTS workflow_interrupts (
    workflow_id VARCHAR(255) PRIMARY KEY,
    interrupt LONGBLOB NOT NULL,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL,
    
    INDEX idx_workflow_id (workflow_id),
    INDEX idx_updated_at (updated_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

{% endtab %}

{% tab title="PostgreSQL" %}

```sql
CREATE TABLE workflow_interrupts (
    workflow_id VARCHAR(255) PRIMARY KEY,
    interrupt BYTEA NOT NULL,
    created_at TIMESTAMP NOT NULL,
    updated_at TIMESTAMP NOT NULL
);

CREATE INDEX idx_workflow_id ON workflow_interrupts(workflow_id);
CREATE INDEX idx_updated_at ON workflow_interrupts(updated_at);
```

{% endtab %}

{% tab title="SQLite" %}

```sql
CREATE TABLE workflow_interrupts (
    workflow_id TEXT PRIMARY KEY,
    interrupt BLOB NOT NULL,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL
);

CREATE INDEX idx_workflow_id ON workflow_interrupts(workflow_id);
CREATE INDEX idx_updated_at ON workflow_interrupts(updated_at);
```

{% endtab %}
{% endtabs %}

### Eloquent

你应该创建自己的 Eloquent 模型，并将类名字符串作为构造参数传入。该模型可以具有自定义关联、作用域、属性等，但基本结构必须基于以下迁移脚本：

```bash
php artisan make:migration create_workflow_interrupts_table --create=workflow_interrupts
```

```php
Schema::create('workflow_interrupts', function (Blueprint $table) {
    $table->id();
    $table->string('workflow_id')->unique();
    $table->longText('interrupt')->charset('binary');
    $table->timestamps();
});
```

#### WorkflowInterrupt 模型

这是所需的最小结构：

```php
class WorkflowInterrupt extends Model
{    
    protected $fillable = ['workflow_id', 'interrupt'];
}
```

与 Workflow 一起使用：

```php
use App\Models\WorkflowInterrupt;
use NeuronAI\Workflow\Persistence\EloquentPersistence;

// 创建一个工作流
$workflow = WorkflowAgent(
    persistence: new EloquentPersistence(WorkflowInterrupt::class)
);
```
