> 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/usage-examples.md).

# 长期记忆使用示例

Unity 中四个完整的长期记忆模式——零配置持久化、认证身份、记忆初始化和记忆重置。

这些示例涵盖了四种最常见的长期记忆集成模式。每个示例都是独立的，并展示完整设置、相关代码和预期的运行时结果。

### 模式 1 — 零配置持久化

使用 `DeviceEndUserIdProvider` （SDK 默认）当你不需要按账户划分的记忆时使用。无需任何代码。只需在控制面板中启用 LTM，SDK 会自动处理身份和存储。

**何时使用：** 没有用户账户的消费类应用、快速原型，或基于编辑器的测试。

**限制：** 记忆仅限于设备范围。清除 `PlayerPrefs` 或重新安装应用会生成新的身份——不会保留任何记忆。

**设置：**

1. 在 [convai.com](https://convai.com)登录，在角色中打开该角色，并切换 **长期记忆** 为 **开** ，位于 **记忆** 选项卡。
2. 添加 `ConvaiManager` 和 `ConvaiCharacter` 到已配置角色 ID 的场景中。
3. 进入播放模式并进行对话。停止播放模式以触发记忆提取。
4. 重新进入播放模式并验证角色是否记得刚才分享的内容。

没有 `IEndUserIdentityProvider` 需要注册。SDK 使用 `DeviceEndUserIdProvider` 加载 Draco 解码器。

**预期结果：** 角色会自动引用之前会话中的事实。相同的 GUID 在 `PlayerPrefs["convai.end_user_id"]` 会在同一台机器上的每个会话中使用。

***

### 模式 2 — 已认证身份

使用自定义 `IEndUserIdentityProvider` 当用户使用账户登录时。这可确保记忆在不同设备和重新安装后仍随用户保持。

**何时使用：** 具有用户身份验证的应用——企业培训平台、入职系统、带账户的消费应用。

```csharp
using Convai.Domain.Identity;

public class AccountIdentityProvider : IEndUserIdentityProvider
{
    private readonly string _accountId;

    public AccountIdentityProvider(string accountId)
    {
        _accountId = accountId;
    }

    public string GetEndUserId()
    {
        return _accountId;
    }
}
```

在 `Awake()` 之前 `ConvaiRoomManager.Start()` 中注册提供程序：

```csharp
using Convai.Runtime.Components;
using UnityEngine;

public class IdentityRegistrar : MonoBehaviour
{
    [SerializeField] private ConvaiManager _convaiManager;

    private void Awake()
    {
        string accountId = AuthService.CurrentUser.AccountId;
        _convaiManager.SetEndUserIdentityProvider(new AccountIdentityProvider(accountId));
    }
}
```

可选地附加一个显示名称，以便编辑器的长期记忆面板显示易读标签而不是原始 ID：

```csharp
using System.Collections.Generic;
using Convai.Domain.Identity;

public class AccountMetadataProvider : IEndUserMetadataProvider
{
    private readonly string _displayName;

    public AccountMetadataProvider(string displayName)
    {
        _displayName = displayName;
    }

    public IReadOnlyDictionary<string, object> GetEndUserMetadata()
    {
        return new Dictionary<string, object> { { "name", _displayName } };
    }
}
```

```csharp
_convaiManager.SetEndUserMetadataProvider(
    new AccountMetadataProvider(AuthService.CurrentUser.DisplayName));
```

**预期结果：** 每个用户的记忆都存储在其账户 ID 下。记忆会在不同设备和重新安装后保留。编辑器面板会显示用户的显示名称。

***

### 模式 3 — 首次会话前预置记忆

在用户第一次对话之前预先加载事实，这样角色从一开始就能引用已完成的模块、证书或入职状态。

{% hint style="danger" %}
**不要在面向玩家的构建版本中发布此模式。** `ConvaiRestClient` 需要你的 API 密钥。将 API 密钥嵌入分发的应用程序会使其面临被提取的风险。请仅从服务器端服务或编辑器工具运行记忆预置。
{% endhint %}

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

public class OnboardingMemorySeeder : MonoBehaviour
{
    // 仅限编辑器/服务器端使用——绝不要在带有嵌入式 API 密钥的情况下发布
    [ContextMenu("预置新员工记忆")]
    private async void SeedEmployeeMemory()
    {
        string characterId = "onboarding-assistant-id";
        string employeeAccountId = "emp-00421";

        var certifications = new List<string>
        {
            "该员工已于 2025-04-10 完成消防安全一级。",
            "该员工已于 2025-04-15 完成危险材料处理。",
            "该员工尚未完成受限空间进入认证。"
        };

        using var client = new ConvaiRestClient(ConvaiSettings.Instance.ApiKey);
        var response = await client.Memory.AddAsync(characterId, employeeAccountId, certifications);

        Debug.Log($"已预置 {response.Memories.Count} 条记忆记录。");
    }
}
```

**预期结果：** 在员工与入职助手的第一次对话中，角色已经了解他们的认证状态，并引导他们进入下一项所需模块。

***

### 模式 4 — 重置用户的记忆

清除某个用户—角色组合的所有已存事实，然后可选择禁用 LTM。当用户记录已过期，或需要在测试会话之间重置时使用。

```csharp
using Convai.RestAPI;
using UnityEngine;

public class MemoryReset : MonoBehaviour
{
    [ContextMenu("清除记忆并禁用 LTM")]
    private async void PurgeAndDisable()
    {
        string characterId = "your-character-id";
        string endUserId = "target-end-user-id";

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

        // 第 1 步：删除此用户—角色组合的所有记忆
        await client.Memory.DeleteAllAsync(characterId, endUserId);
        Debug.Log("记忆已清除。");

        // 第 2 步：在角色上禁用 LTM
        await client.Characters.SetMemoryEnabledAsync(characterId, false);
        Debug.Log("长期记忆已禁用。");
    }
}
```

若只想删除记忆但保持 LTM 启用，请调用 `DeleteAllAsync` 并跳过 `SetMemoryEnabledAsync` 这一步。若要删除某个用户在所有角色中的记录，而不是仅删除某一个角色的记录，请使用 `client.EndUsers.DeleteAsync(endUserId)` 代替。参见 [管理最终用户记录](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/end-user-management.md).

**预期结果：** 该用户—角色组合的下一次会话将不再包含任何存储上下文。角色会将该用户视为新联系人。

***

### 下一步

{% content-ref url="/pages/0b7e1084a14c3bcf13fec179ad83b458f07ecff4" %}
[记忆管理 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/memory-management-api.md)
{% endcontent-ref %}

{% content-ref url="/pages/9c55a31cd790424665e521972bff5affc2dbe7f9" %}
[长期记忆脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/long-term-memory/long-term-memory-scripting-reference.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/usage-examples.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.
