首页
/ LlamaIndex TablestoreChatStore:把聊天历史持久化到阿里云表格存储(Tablestore)的 Chat Store 集成

LlamaIndex TablestoreChatStore:把聊天历史持久化到阿里云表格存储(Tablestore)的 Chat Store 集成

2026-09-09 17:43:10作者:盛欣凯Ernestine

本篇技术指南围绕 LlamaIndex 的 TablestoreChatStore 展开——这是 llama-index-storage-chat-store-tablestore 集成包提供的聊天历史存储实现,将 LlamaIndex 对话记忆(ChatMemoryBuffer)的会话历史以 JSON 形式写入阿里云表格存储(Tablestore/OTS)。读完本篇,你将掌握该包的完整安装方式、构造函数参数、底层表结构与数据模型、全部 API 方法的源码级实现细节,以及如何将其接入聊天记忆流并用集成测试验证。

安装与包信息

该集成包位于 llama-index-integrations/storage/chat_store/llama-index-storage-chat-store-tablestore,其 pyproject.toml 声明了如下关键事实:

  • 包名:llama-index-storage-chat-store-tablestore,当前版本 0.3.0,MIT 协议;
  • Python 要求:>=3.10,<4.0
  • 依赖:llama-index-core>=0.13.0,<0.15tablestore>=6.1.0(阿里云表格存储官方 SDK)。

安装方式:

pip install llama-index-storage-chat-store-tablestore

快速上手:五步接入聊天记忆

集成包 README.md 给出的标准用法如下:

from llama_index.storage.chat_store.tablestore import TablestoreChatStore
from llama_index.core.memory import ChatMemoryBuffer

# 1. create tablestore vector store
chat_store = TablestoreChatStore(
    endpoint="<end_point>",
    instance_name="<instance_name>",
    access_key_id="<access_key_id>",
    access_key_secret="<access_key_secret>",
)
# You need to create a table for the first use
chat_store.create_table_if_not_exist()

chat_memory = ChatMemoryBuffer.from_defaults(
    token_limit=3000,
    chat_store=chat_store,
    chat_store_key="user1",
)

流程分三步:

  1. 构造 TablestoreChatStore:传入 Tablestore 实例的 endpoint、实例名与阿里云 AccessKey;
  2. 首次使用前建表:调用 create_table_if_not_exist() 幂等地创建存储表;
  3. 接入 ChatMemoryBuffer:通过 chat_store= 注入存储后端,chat_store_key="user1" 指定会话主键,token_limit=3000 限制送入 LLM 的历史 token 上限。此后 ChatMemoryBuffer 的每次追加、裁剪都会自动落盘,无需手动持久化或加载聊天历史。

API 参考页由 mkdocstrings 自动生成,见 docs/api_reference/api_reference/storage/chat_store/tablestore.md,其内容直接指向 llama_index.storage.chat_store.tablestore 模块中的 TablestoreChatStore 类。

TablestoreChatStore 构造函数参数

构造函数定义于 base.py 第 50-73 行。参数说明如下(取自类 docstring 与源码签名):

参数 类型 默认值 说明
tablestore_client tablestore.OTSClient None 外部已有的 OTS 客户端。若显式传入,则 endpoint/instance_name/access_key_id/access_key_secret 全部被忽略
endpoint str None Tablestore 实例 endpoint
instance_name str None Tablestore 实例名
access_key_id str None 阿里云 AccessKey ID
access_key_secret str None 阿里云 AccessKey Secret
table_name str "llama_index_chat_store_v1" 存储表名
**kwargs Any 透传给 tablestore.OTSClient 的额外参数

实现上,未传入现成客户端时,内部以 retry_policy=tablestore.WriteRetryPolicy() 构造 OTSClientbase.py 第 63-71 行),即写操作默认启用 Tablestore SDK 的写重试策略;若传入 tablestore_client,则直接复用该客户端(base.py 第 72-73 行),这为复用已有连接池或自定义认证(如 STS 临时凭证)留出了口子。

表结构与数据模型

从源码结构看,该存储采用"一行一会话"的极简模型(base.py 第 45-48 行):

  • 主键列 _primary_key = "session_id",类型为 STRING,即 chat_store_key(如 "user1");
  • 属性列 _history_column = "history",存放整段会话历史。

create_table_if_not_exist() 的建表逻辑(base.py 第 75-98 行):

table_meta = tablestore.TableMeta(
    self.table_name, [(self._primary_key, "STRING")]
)
reserved_throughput = tablestore.ReservedThroughput(
    tablestore.CapacityUnit(0, 0)
)
self._tablestore_client.create_table(
    table_meta, tablestore.TableOptions(), reserved_throughput
)

要点:

  • 先调用 list_table() 检查表名是否存在,存在则仅打日志返回,保证幂等;
  • 预留读写吞吐为 CapacityUnit(0, 0),即使用按量付费(CU 按量)模式建表。

消息序列化发生在读写边界(base.py 第 13-24 行):写入时将 List[ChatMessage] 逐条转为 dict 后 json.dumps(..., ensure_ascii=False) 整体序列化;读取时用 json.loads 反序列化并逐条 ChatMessage.model_validate(d) 还原为 Pydantic 模型。ensure_ascii=False 保证中文等多字节内容以原文落盘——集成测试中专门用 ChatMessage(content="Tablestore 第三 message", ...) 验证了这一点(test_chat_store_tablestore_chat_store.py 第 54-68 行)。

API 方法逐一解析

TablestoreChatStore 继承自核心包的 BaseChatStorellama-index-core/llama_index/core/storage/chat_store/base.py),实现了其全部 7 个抽象方法,并额外提供 create_table_if_not_exist()clear_store() 两个 Tablestore 专属操作。

set_messages:整行覆盖写入

base.py 第 110-131 行 使用 put_row 原子写入,同一 session_id 下已有的历史会被整体覆盖:

primary_key = [(self._primary_key, key)]
attribute_columns = [
    (
        self._history_column,
        json.dumps(_messages_to_dict(messages), ensure_ascii=False),
    ),
]
row = tablestore.Row(primary_key, attribute_columns)
self._tablestore_client.put_row(self.table_name, row)

get_messages:按主键单行读取

base.py 第 133-156 行 调用 get_row(table, primary_key, None, None, 1)max_version=1 只取最新版本),遍历 row.attribute_columns 找到 history 列并反序列化。行不存在时返回空列表,不抛异常。

add_message:读-改-写

base.py 第 158-173 行 的逻辑是 get_messages 取当前历史 → append(message)set_messages 回写。这里可以推断:由于底层是整行覆盖而非列追加,高并发下对同一 session_id 的并发追加存在读改写竞争,单会话串行对话场景不受影响。

delete 系列:整行删除、按索引删除、删除末条

  • delete_messages(key)base.py 第 175-190 行):先 get_messages 取回消息,再 delete_row 删除整行,并返回被删消息;
  • delete_message(key, idx)base.py 第 192-215 行):读改写,删除指定索引的消息;索引越界时记录 logger.error 并返回 None
  • delete_last_message(key)base.py 第 217-229 行):委托为 delete_message(key, -1),即删除最后一条——这是 ChatMemoryBuffer 在历史超出 token 上限时裁剪记忆所用的方法;
  • clear_store()base.py 第 100-104 行):遍历 get_keys() 逐行 delete_messages,清空全表。

get_keys:基于 get_range 的分页扫描

base.py 第 231-281 行 用 Tablestore 的范围读枚举全部会话键:

  • 起止主键为 [(session_id, INF_MIN)][(session_id, INF_MAX)],方向 Direction.FORWARD
  • 每批 limit=5000max_version=1,通过 next_start_primary_key 非空循环翻页直至扫完;
  • 只读取主键值(columns_to_get=[]),逐行取 row.primary_key[0][1] 收集为键列表。

与 ChatMemoryBuffer 的协同关系

ChatMemoryBuffer 定义于 llama-index-core/llama_index/core/memory/chat_memory_buffer.py,其 from_defaults(token_limit=..., chat_store=..., chat_store_key=...) 将本集成作为持久化后端。核心包 BaseChatStore 同时提供 aset_messagesaget_messages 等异步方法(base.py 第 52-78 行),通过 asyncio.to_thread 将同步实现包装为异步,因此 TablestoreChatStore 即使没有原生 async I/O,也能被异步记忆流程调用。

集成测试与本地验证

端到端测试位于 tests/test_chat_store_tablestore_chat_store.py。要点:

  • 测试依赖真实 Tablestore 实例,凭据来自环境变量 tablestore_end_pointtablestore_instance_nametablestore_access_key_idtablestore_access_key_secret;任一缺失时 pytest.skip 跳过(第 14-40 行);
  • 每个用例先 create_table_if_not_exist()clear_store() 保证干净状态;
  • 覆盖用例包括:test_add_messagetest_set_and_retrieve_messages(含中文内容断言)、test_delete_messagestest_delete_specific_messagetest_get_keystest_delete_last_messagetest_clear_store,与上文 API 方法一一对应,可直接作为回归基线。

相关存储组件

仓库中 Tablestore 的存储类集成不止 Chat Store,同一存储家族还包括:

这些集成在 mkdocs 配置中统一登记于 docs/api_reference/mkdocs.yml 第 511-570 行。若你的 RAG 系统希望将向量、文档、索引与聊天记忆统一落在 Tablestore 上,可按本文模式逐一接入,其中本文覆盖的 TablestoreChatStore 负责多轮对话状态的远程持久化。

小结

TablestoreChatStore 以"主键 session_id + JSON 列 history"的极简表模型,把 BaseChatStore 的 7 个抽象方法完整映射到 Tablestore 的 put_row/get_row/delete_row/get_range 原语上,并提供幂等建表能力。接入时只需四个连接参数加一次 create_table_if_not_exist(),即可让 ChatMemoryBuffer 的会话历史跨进程、跨重启持久化;实现细节、参数默认值与行为边界均可在上述源码与测试文件中逐行核对。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.89 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
602
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
396
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
526