> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/memory-management-api.md).

# 记忆管理 API

为单个玩家列出、添加、检索和删除角色的记忆记录，包含设置、每个方法、响应类型和错误处理。

记忆管理 API 允许你直接读取和写入记忆记录——无需等待对话生成它们。可用它来审计角色对用户已知的信息，在首次会话前预置事实，或移除不再准确的特定记忆。

{% hint style="warning" %}
**Beta API。** 方法签名是稳定的，但未来的 SDK 更新中可能会发生变化。在生产环境中请锁定你的 SDK 版本，并在升级前查看更新日志。
{% endhint %}

所有记忆操作都可在 `ConvaiRestClient.Memory`。 `ConvaiRestClient` 上使用；它是与实时会话分开的 REST 客户端——你可以随时调用它，包括从编辑器脚本中在 Play Mode 之外调用。

***

### 初始化客户端

初始化 `ConvaiRestClient` 并使用你的 API 密钥。该客户端是 `IDisposable` ——始终使用 `using` 语句或调用 `Dispose()` 在完成后。

```csharp
using var client = new ConvaiRestClient(ConvaiSettings.Instance.ApiKey);
```

每个记忆操作都需要两个标识符：

* **`characterId`** ——角色 ID 来自 `ConvaiCharacter` 检视器
* **`endUserId`** ——由你的 `IEndUserIdentityProvider` 返回的标识符（或者来自 `PlayerPrefs` 如果使用默认的 `DeviceEndUserIdProvider`)

***

### `MemoryRecord` 数据模型

每条存储的事实都是一个 `MemoryRecord`:

| 属性          | 类型                           | 描述                     |
| ----------- | ---------------------------- | ---------------------- |
| `Id`        | `string`                     | 此记忆记录的唯一标识符            |
| `Memory`    | `string`                     | 以自然语言句子形式存储的事实         |
| `CreatedAt` | `string`                     | 该事实首次存储时的 ISO 8601 时间戳 |
| `UpdatedAt` | `string`                     | 最后更新的 ISO 8601 时间戳     |
| `Metadata`  | `Dictionary<string, object>` | 附加到此记录的可选键值数据          |

示例 `Memory` 值： `"用户的名字是 Alex。"`, `"Alex 于 2025-03-12 完成了密闭空间安全模块。"`, `"Alex 更喜欢逐步解释，而不是摘要。"`

有关包括响应模型在内的完整类型参考，请参见 [长期记忆脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/long-term-memory-scripting-reference.md).

***

### 记忆 CRUD 操作

#### 列出记忆

检索某个用户-角色对的所有已存储记忆记录。结果是分页的——使用 `page` 和 `pageSize` 来遍历大量数据。

```csharp
using Convai.RestAPI;
using Convai.RestAPI.Internal;
using System.Collections.Generic;
using UnityEngine;

public class MemoryInspector : MonoBehaviour
{
    [ContextMenu("列出所有记忆")]
    private async void ListAllMemories()
    {
        string characterId = "your-character-id";
        string endUserId = "target-end-user-id";

        using var client = new ConvaiRestClient(ConvaiSettings.Instance.ApiKey);

        int page = 1;
        bool hasMore = true;
        var allMemories = new List<MemoryRecord>();

        while (hasMore)
        {
            var response = await client.Memory.ListAsync(characterId, endUserId, page, pageSize: 50);
            allMemories.AddRange(response.Memories);
            hasMore = response.HasMore;
            page++;
        }

        foreach (var record in allMemories)
        {
            Debug.Log($"[{record.Id}] {record.Memory}");
        }
    }
}
```

**`MemoryListResponse` 字段：**

| 属性           | 类型                   | 描述       |
| ------------ | -------------------- | -------- |
| `Memories`   | `List<MemoryRecord>` | 本页记录     |
| `TotalCount` | `int`                | 已存储记录总数  |
| `Page`       | `int`                | 当前页码     |
| `PageSize`   | `int`                | 每页记录数    |
| `HasMore`    | `bool`               | 是否存在更多页面 |

***

#### 获取单条记忆

通过其 ID 检索一条特定记录。

```csharp
var record = await client.Memory.GetAsync(characterId, endUserId, memoryId);
Debug.Log($"记忆：{record.Memory}");
```

***

#### 添加记忆

将一个或多个事实作为自然语言字符串注入。Convai 会对重叠事实进行去重——添加一个在语义上等同于现有事实的事实时，会更新现有记录，而不会创建重复项。

```csharp
var facts = new List<string>
{
    "Jordan 是 Northfield 设施的夜班安全官。",
    "Jordan 已完成密闭空间进入认证。",
    "Jordan 比起理论性很强的解释，更喜欢实际示例。"
};

var response = await client.Memory.AddAsync(characterId, endUserId, facts);

foreach (var result in response.Memories)
{
    Debug.Log($"[{result.Event}] {result.Memory}（id: {result.Id}）");
}
```

**`AddMemoriesResponse` 和 `MemoryAddResult` 字段：**

`AddAsync` 返回 `AddMemoriesResponse`，其中包含一个 `List<MemoryAddResult>`。每个结果对应一条提交的事实：

| 属性       | 类型       | 描述                               |
| -------- | -------- | -------------------------------- |
| `Id`     | `string` | 已创建或更新记录的 ID                     |
| `事件`     | `string` | `"add"` 用于新记录， `"update"` 用于去重更新 |
| `Memory` | `string` | Convai 存储的规范化事实文本                |

***

#### 删除单条记忆

通过其 ID 移除一条特定记录。

```csharp
var result = await client.Memory.DeleteAsync(characterId, endUserId, memoryId);
Debug.Log($"已删除：{result.Deleted}");
```

***

#### 删除所有记忆

{% hint style="danger" %}
`DeleteAllAsync` 会永久移除 **所有** 指定用户-角色对的记忆记录。这无法撤销。在任何面向用户的流程中调用此方法前，请始终加入确认步骤。
{% endhint %}

```csharp
var result = await client.Memory.DeleteAllAsync(characterId, endUserId);
Debug.Log($"已为角色 {result.CharacterId} 上的用户 {result.EndUserId} 删除所有记忆。");
```

***

### 处理 API 错误

将所有异步记忆调用包装在 `try/catch`中。失败的操作会抛出 `ConvaiRestException` ，并带有 HTTP 状态码。

```csharp
try
{
    var response = await client.Memory.ListAsync(characterId, endUserId);
    // 处理响应
}
catch (ConvaiRestException ex)
{
    Debug.LogError($"记忆 API 错误 {ex.StatusCode}：{ex.Message}");
}
```

参见 [排查长期记忆](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/troubleshooting-and-diagnostics.md) 以获取完整的 HTTP 状态码参考。

***

### 下一步

{% content-ref url="/pages/d41fbdd4f21a090aa6d7e39be7a7eb215d0435c2" %}
[长期记忆使用示例](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/usage-examples.md)
{% endcontent-ref %}

{% content-ref url="/pages/49cef55d22f33c0ffdf4893701cd5a6686bd7590" %}
[管理终端用户记录](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/end-user-management.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/memory-management-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
