> 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

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

Memory Management API 允许你直接读取和写入记忆记录——无需等待对话生成它们。可用它来审计某个角色了解了用户什么、在首次会话前预置事实，或移除不再准确的特定记忆。

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

所有记忆操作都可在 `ConvaiRestClient.Memory`。 `ConvaiRestClient` 中使用——它是一个独立于实时会话的 REST 客户端——你可以在任何时候调用它，包括在编辑器脚本中、Play Mode 之外。

***

### 初始化客户端

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

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

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

* **`characterId`** ——来自 `ConvaiCharacter` Inspector
* **`endUserId`** ——由你的 `IEndUserIdentityProvider` （或者来自 `PlayerPrefs` ，如果使用默认的 `DeviceEndUserIdProvider`)

***

### `MemoryRecord` 数据模型

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

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

示例 `记忆` 值： `“用户的名字是 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`                | 存储记录总数   |
| `页码`         | `int`                | 当前页码     |
| `PageSize`   | `int`                | 每页记录数    |
| `HasMore`    | `bool`               | 是否存在更多页面 |

***

#### 获取单条记忆

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

```csharp
var record = await client.Memory.GetAsync(characterId, endUserId, memoryId);
Debug.Log($"Memory: {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”` 用于去重后的更新 |
| `记忆` | `string` | Convai 存储的规范化事实文本                  |

***

#### 删除单条记忆

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

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

***

#### 删除所有记忆

{% hint style="danger" %}
`DeleteAllAsync` 会永久移除 **所有** 记忆记录，适用于指定的用户-角色对。此操作无法撤销。在任何面向用户的流程中调用此操作前，务必实现确认步骤。
{% endhint %}

```csharp
var result = await client.Memory.DeleteAllAsync(characterId, endUserId);
Debug.Log($"All memories deleted for user {result.EndUserId} on character {result.CharacterId}.");
```

***

### 处理 API 错误

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

```csharp
try
{
    var response = await client.Memory.ListAsync(characterId, endUserId);
    // 处理响应
}
catch (ConvaiRestException ex)
{
    Debug.LogError($"Memory API error {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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
