> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veadk.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 TOS ContextBucket 存储

`tos_context` 是 VeADK 的长期记忆后端，使用火山引擎 [TOS](https://www.volcengine.com/product/TOS) ContextBucket 保存和检索记忆。记忆推理与检索由托管服务完成，无需部署向量数据库或配置 embedding 模型。

一个 `index` 对应一个 ContextBucket；同一 ContextBucket 内，每个运行时 `user_id` 对应独立的 ContextSet。需要在多个会话中召回同一用户的记忆时，应始终使用相同的 `user_id`。

## 何时使用

* 希望使用托管的长期记忆服务，避免自行维护向量数据库；
* 需要按 `user_id` 隔离不同用户的记忆；
* 已有火山引擎账号、ContextBucket 服务端点及访问服务所需的权限。

## 前提条件

* 安装 VeADK 1.0.9 或更高版本；
* 获取火山引擎账号 ID、ContextBucket 控制面端点，以及目标区域的数据面端点；
* 准备可访问、创建 ContextBucket 和 ContextSet，并可写入、检索记忆的 AK/SK，或为 AgentKit、VeFaaS 运行环境配置具有相同权限的 IAM Role；
* 确保运行环境能够访问配置的控制面和数据面端点。

<Note>
  ContextBucket 的开通范围、控制面端点和 IAM 权限由 TOS 服务侧提供，并不等同于普通 TOS Bucket 权限。如果当前账号未获得 ContextBucket 的开通信息，请先通过火山引擎服务支持渠道确认可用地域、控制面端点和最小权限策略，再配置本页参数。
</Note>

## 安装依赖

ContextBucket 要求 TOS SDK `tos>=2.9.4b1`。VeADK 的基础依赖允许安装更早的 TOS SDK，因此需要在 VeADK 所在环境中单独升级：

```bash lines theme={null}
python -m pip install --upgrade "tos>=2.9.4b1"
```

版本约束已经明确包含预发布版本 `2.9.4b1`，pip 无需额外使用 `--pre`。如果项目的包管理或锁文件策略禁止预发布依赖，请按对应工具的方式允许该依赖并重新生成锁文件。

可以通过以下命令确认已安装的版本：

```bash lines theme={null}
python -c "from importlib.metadata import version; print(version('tos'))"
```

## 配置凭证与服务端点

以下示例使用环境变量提供凭证，避免把 AK/SK 写入代码或配置文件：

```bash lines theme={null}
export VOLCENGINE_ACCESS_KEY="your-access-key"
export VOLCENGINE_SECRET_KEY="your-secret-key"
export DATABASE_TOS_CONTEXT_ACCOUNT_ID="your-account-id"
export DATABASE_TOS_CONTEXT_CONTROL_ENDPOINT="your-control-endpoint"
export DATABASE_TOS_CONTEXT_ENDPOINT="tos-cn-beijing.volces.com"
export DATABASE_TOS_CONTEXT_REGION="cn-beijing"
```

使用 STS 临时凭证时，还需设置 `VOLCENGINE_SESSION_TOKEN`。如果没有同时提供 AK 和 SK，后端会改用 AgentKit 或 VeFaaS 运行环境的 IAM Role 凭证；只提供 AK 或只提供 SK 不会组成有效凭证。

<Warning>
  首次初始化会查询并可能创建 ContextBucket；每个 `user_id` 首次保存或检索记忆时，还会查询并可能创建 ContextSet。这些操作会创建或访问云资源，并把会话内容发送到 TOS。请在执行示例前确认账号权限、费用、数据处理和保留策略符合业务要求。
</Warning>

## 使用示例

下面的示例先保存一个会话，再从新会话中检索同一用户的长期记忆。运行前还需按[模型配置](/productions/veadk/preview/zh/components/agent/model)准备模型凭证。

```python lines theme={null}
import asyncio

from veadk import Agent, Runner
from veadk.memory.long_term_memory import LongTermMemory

APP_NAME = "support-memory"
USER_ID = "user-42"


async def main() -> None:
    memory = LongTermMemory(
        backend="tos_context",
        index=APP_NAME,
        app_name=APP_NAME,
        top_k=5,
    )
    agent = Agent(
        name="support_agent",
        instruction="回答前先使用 `load_memory` 检索与当前用户有关的长期记忆。",
        long_term_memory=memory,
    )
    runner = Runner(agent=agent, app_name=APP_NAME, user_id=USER_ID)

    await runner.run(
        messages="请记住：我对花生过敏。",
        session_id="session-1",
    )
    completed_session = await runner.session_service.get_session(
        app_name=APP_NAME,
        user_id=USER_ID,
        session_id="session-1",
    )
    assert completed_session is not None
    await memory.add_session_to_memory(completed_session)

    response = await runner.run(
        messages="我对什么食物过敏？",
        session_id="session-2",
    )
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

运行成功后，第二个会话可以检索到同一 `user_id` 在第一个会话中保存的花生过敏信息。初始化时如果 `support-memory` 对应的 ContextBucket 不存在，服务会自动创建；首次保存时还会为 `user-42` 创建启用记忆场景的 ContextSet。

### 显式传入后端配置

除环境变量外，也可以通过 `backend_config` 提供非敏感连接配置。后端最终必须获得有效的 `index`；推荐在 `LongTermMemory` 外层设置，VeADK 会自动补入后端配置。

```python lines theme={null}
from veadk.configs.database_configs import TOSContextBucketConfig
from veadk.memory.long_term_memory import LongTermMemory

memory = LongTermMemory(
    backend="tos_context",
    index="support-memory",
    backend_config={
        "account_id": "your-account-id",
        "tos_context_config": TOSContextBucketConfig(
            control_endpoint="your-control-endpoint",
            endpoint="tos-cn-beijing.volces.com",
            region="cn-beijing",
        ),
    },
)
```

## 参数

### `LongTermMemory` 参数

| 参数 | 类型 | 默认值 | 说明 |
| :- | :- | :- | :- |
| `backend` | `str` | `"opensearch"` | 使用此后端时设为 `"tos_context"` |
| `index` | `str` | `""` | ContextBucket 的默认名称。此后端要求提供有效的 `index` 或 `app_name`，建议显式设置 `index` |
| `app_name` | `str` | `""` | 应用名称；未设置 `index` 时作为回退值 |
| `top_k` | `int` | `5` | 每次检索最多返回的记忆数量 |
| `backend_config` | `dict` | `{}` | 传给所选后端的配置。字典中没有 `index` 时，VeADK 使用外层的 `index` 或 `app_name` 补齐 |
| `user_id` | `str` | `""` | 已废弃，使用 Session 或检索参数中的 user\_id |

### 后端配置项

| 参数 | 类型 | 默认值 | 说明 |
| :- | :- | :- | :- |
| `index` | `str` | 外层的 `index` 或 `app_name` | 必填。长期记忆的隔离标识；未设置 `context_bucket_name` 时也作为 ContextBucket 名称。通常在 `LongTermMemory` 外层设置 |
| `context_bucket_name` | `str \| None` | 读取 `DATABASE_TOS_CONTEXT_BUCKET_NAME`，否则使用 `index` | ContextBucket 名称 |
| `account_id` | `str \| None` | 读取 `DATABASE_TOS_CONTEXT_ACCOUNT_ID` | 必填。ContextBucket 所属的火山引擎账号 ID |
| `volcengine_access_key` | `str \| None` | 读取 `VOLCENGINE_ACCESS_KEY` | 火山引擎 Access Key。必须与 Secret Key 同时提供；否则使用运行环境的 IAM Role |
| `volcengine_secret_key` | `str \| None` | 读取 `VOLCENGINE_SECRET_KEY` | 火山引擎 Secret Key。必须与 Access Key 同时提供；否则使用运行环境的 IAM Role |
| `session_token` | `str` | 读取 `VOLCENGINE_SESSION_TOKEN`，未设置时为 `""` | 使用 STS 临时 AK/SK 时所需的会话令牌 |
| `tos_context_config` | `TOSContextBucketConfig` | 使用该配置类的默认值 | 控制面端点、数据面端点和区域配置 |

### `TOSContextBucketConfig` 参数

| 参数 | 类型 | 默认值 | 说明 |
| :- | :- | :- | :- |
| `control_endpoint` | `str \| None` | `None` | 必填。ContextBucket 控制面端点 |
| `endpoint` | `str` | `"tos-cn-beijing.volces.com"` | TOS 数据面端点 |
| `region` | `str` | `"cn-beijing"` | TOS 服务区域。未显式设置时回退到 `REGION` 环境变量，仍为空时默认 `cn-beijing` |

### 保存选项

调用 `await memory.add_session_to_memory(session, infer=False)` 可以控制保存时是否由 ContextBucket 执行记忆推理

| 参数 | 类型 | 默认值 | 说明 |
| :- | :- | :- | :- |
| `infer` | `bool` | `True` | 是否在写入内容时执行记忆推理。智能体自动保存会话时使用默认值 |

### 环境变量

| 环境变量 | 默认值 | 说明 |
| :- | :- | :- |
| `DATABASE_TOS_CONTEXT_ACCOUNT_ID` | 无 | 必填。ContextBucket 所属的火山引擎账号 ID |
| `DATABASE_TOS_CONTEXT_CONTROL_ENDPOINT` | 无 | 必填。ContextBucket 控制面端点 |
| `DATABASE_TOS_CONTEXT_BUCKET_NAME` | 使用 `index` | ContextBucket 名称 |
| `DATABASE_TOS_CONTEXT_ENDPOINT` | `tos-cn-beijing.volces.com` | TOS 数据面端点 |
| `DATABASE_TOS_CONTEXT_REGION` | `cn-beijing` | TOS 服务区域。未设置时回退到 `REGION` 环境变量 |
| `VOLCENGINE_ACCESS_KEY` | 无 | 火山引擎 Access Key |
| `VOLCENGINE_SECRET_KEY` | 无 | 火山引擎 Secret Key |
| `VOLCENGINE_SESSION_TOKEN` | `""` | STS 临时凭证的会话令牌；长期 AK/SK 无需设置 |

## 失败行为

| 阶段 | 行为 | 处理建议 |
| :- | :- | :- |
| 初始化 | TOS SDK 不支持 ContextBucket、账号 ID 或控制面端点缺失、ContextBucket 名称不合法、凭证不可用，或 ContextBucket 查询与创建失败时，初始化会报错 | 在启动阶段验证配置、网络和权限，不要在服务运行后才首次初始化 |
| 保存 | ContextSet 不可用或 TOS 写入失败时，后端记录错误并返回 `False`。通过 `add_session_to_memory` 或自动保存调用时，该布尔值不会作为方法结果返回 | 监控错误日志，并通过业务验证确认关键记忆已经写入 |
| 检索 | ContextSet 不可用或 TOS 检索失败时，后端记录错误并返回空结果。空结果也可能表示没有匹配记忆 | 结合错误日志区分服务失败和无匹配结果；不要把空结果直接视为服务正常 |

## 限制

* ContextBucket 名称长度必须为 3–63 个字符，只能包含小写字母、数字和连字符，且不能以连字符开头或结尾。
* 最低兼容基线 `2.9.4b1` 是 TOS SDK 的预发布版本；升级 TOS SDK 或 VeADK 时应重新执行兼容性验证。
* 已存在的 ContextSet 必须已启用记忆场景，否则保存和检索会失败。
* 记忆严格按 `user_id` 隔离。更改同一用户的 `user_id` 后，新的会话无法检索旧 ContextSet 中的记忆。
* 此后端不支持 `get_user_profile(user_id)`；调用该方法会返回空字符串。

此后端使用 `VOLCENGINE_*` 凭证字段。全局 BytePlus 配置可映射 AK/SK，但不会据此自动切换 ContextBucket 服务地址；服务地址、区域与临时令牌仍需匹配目标服务。不要把普通 TOS 在 BytePlus 的支持范围视为 ContextBucket 的可用范围
