
LlamaIndex UpstashChatStore API 深度解析基于 Upstash Redis 的对话历史存储【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index本篇围绕 LlamaIndex 的llama_index.storage.chat_store.upstash模块API 参考页 upstash.md 所指向的UpstashChatStore类展开讲解如何在 LlamaIndex 应用中用 Upstash Redis 作为对话记忆的远端持久化后端覆盖安装、构造参数、全部同步/异步 API 的实际调用方式以及源码层面基于 Redis List 的存取、按索引删除与 TTL 过期实现细节帮助你在构建多用户、多实例的对话应用时正确选型和排错。模块定位API 参考页指向什么关联文档 docs/api_reference/api_reference/storage/chat_store/upstash.md 的内容非常简短::: llama_index.storage.chat_store.upstash options: members: - UpstashChatStore这是 mkdocs 的自动 API 文档指令它声明本页面的文档对象是llama_index.storage.chat_store.upstash模块且只列出其中的UpstashChatStore一个成员。也就是说该 API 参考页的实质就是UpstashChatStore这个类的公开接口。这个类定义在集成包 base.py 中由init.py 通过__all__ [UpstashChatStore]对外导出。UpstashChatStore继承自核心包中的 BaseChatStorellama_index.core.storage.chat_store.base.BaseChatStore因此它遵循 LlamaIndex 统一的按 key 存储对话消息抽象每个 key通常是用户 ID 或会话 ID对应一个ChatMessage列表。BaseChatStore定义了 7 个同步抽象方法set_messages、get_messages、add_message、delete_messages、delete_message、delete_last_message、get_keys其默认异步实现只是把同步方法丢进线程池执行见 base.py#L52-L78。而UpstashChatStore额外实现了原生异步方法async_set_messages、async_get_messages等直接使用 Upstash Redis 官方 SDK 的 asyncio 客户端这是它相对基础实现的关键差异点。安装与依赖版本按照集成包 README.md 与框架文档 chat_stores.md 中的说明安装命令为pip install llama-index-storage-chat-store-upstash结合 pyproject.toml 可以看到当前仓库中该包的版本约束项目约束说明包版本0.4.0当前仓库内的发布版本Python3.10,4.0需要 Python 3.10 及以上upstash_redis1.1.0,2Upstash 官方 Redis 客户端含 REST URL Token 的 serverless 接入方式llama-index-core0.13.0,0.15与核心包的兼容区间使用前提你需要一个 Upstash Redis 实例并拿到它的 REST URL 与 Token通常形如https://database-id.upstash.io。构造参数详解UpstashChatStore的构造函数签名与参数语义见 base.py#L46-L73from llama_index.storage.chat_store.upstash import UpstashChatStore chat_store UpstashChatStore( redis_urlYOUR_UPSTASH_REDIS_URL, # Upstash Redis 实例的 URL必填 redis_tokenYOUR_UPSTASH_REDIS_TOKEN, # 实例的认证 Token必填 ttl300, # 可选单位秒为 key 设置过期时间 )源码层面有三个值得注意的实现细节参数校验redis_url或redis_token为空字符串时直接抛出ValueError(Please provide a valid URL and token)即两者都缺省值的情况下无法构造成功双客户端实例化构造函数会同时创建同步客户端SyncRedisupstash_redis.Redis和异步客户端AsyncRedisupstash_redis.asyncio.Redis分别存于私有属性_sync_redis_client与_async_redis_client所以同步与异步 API 可以混用初始化失败只记日志不抛异常如果客户端初始化过程中发生异常代码只调用logger.error(...)记录错误而不会中断构造后续调用会在使用客户端时才暴露问题——排错时建议留意日志输出。ttl同时是 pydantic 的公开字段ttl: Optional[int] Field(defaultNone, descriptionTime to live in seconds.)默认为None表示不设过期也可以在构造后直接赋值例如chat_store.ttl 300源码中的 TTL 测试正是这样做的见 test_chat_store_upstash_chat_store.py#L108-L117。完整 API同步与异步方法一览UpstashChatStore公开的方法成对出现同步版 async_前缀异步版与BaseChatStore接口一一对应同步方法异步方法Redis 操作行为set_messages(key, messages)async_set_messages(key, messages)DEL 逐条RPUSHEXPIRE整体替换某 key 下的消息列表get_messages(key)async_get_messages(key)LRANGE key 0 -1取回完整消息列表空时返回[]add_message(key, message, idxNone)async_add_message(key, message, idxNone)RPUSH或读改写EXPIRE追加或按索引插入单条消息delete_messages(key)async_delete_messages(key)DEL删除整个 key固定返回Nonedelete_message(key, idx)async_delete_message(key, idx)LINDEXLSETLREM删除指定索引的消息并返回它delete_last_message(key)async_delete_last_message(key)RPOP弹出并返回最后一条消息get_keys()async_get_keys()KEYS *返回 store 中全部 key此外还有一个类方法class_name()固定返回字符串UpstashChatStore用于 LlamaIndex 的组件序列化/反序列化标识。源码级实现解析消息的序列化JSON 字符串存入 Redis List每个 key 在 Redis 中就是一个 List每条消息是一个 JSON 字符串。写入路径是 _message_to_dict对ChatMessage调用.dict()再经json.dumps序列化后rpush到列表尾部读取路径则是lrange(key, 0, -1)取全量后逐条ChatMessage.parse_raw(item)反序列化见 base.py#L118-L133。这意味着消息的 role、content、additional_kwargs 等字段都会原样保留在远端。set_messages的先删后写语义同步版实现base.py#L86-L100先delete(key)清掉旧列表再逐条add_message追加。由于每条add_message在设置ttl时都会刷新一次EXPIRE最后set_messages末尾还会再显式expire(key, self.ttl)保证整个列表从写入完成时刻开始计 TTL。按索引删除占位符 LSET/LREM 两步法Redis 没有原子的按索引删除列表元素命令源码用了一个巧妙的两步方案base.py#L222-L250lindex(key, idx)先取出要删除的消息lset(key, idx, placeholder)把该位置替换为占位符字符串f{key}:{idx}:deletedlrem(key, 1, placeholder)按值匹配删除这一个占位符。异常例如 idx 越界导致lindex失败会被捕获并记录日志后返回None与BaseChatStore接口中Optional[ChatMessage]的返回类型一致。按索引插入读—改—写add_message(key, message, idx...)指定索引时会走_insert_element_at_indexbase.py#L334-L356先get_messages拉取当前全部消息在 Python 列表中insert(idx, message)然后delete(key)清库并set_messages整体重写。从源码结构看这是一种简单直白的实现代价是每次索引插入产生一次全量读加一次全量写对超长会话列表有一定开销但对常规对话长度完全够用。TTL 的触发点只要构造时或运行中设置了ttl以下写操作后都会调用expire(key, self.ttl)刷新过期时间set_messages、add_message、delete_message。也就是说 TTL 是每次活动后重置的滑动过期模式适合做不活跃会话自动清理。与 ChatMemoryBuffer 集成框架文档 chat_stores.md 将UpstashChatStore描述为借助 Upstash 提供的 serverless Redis 服务将聊天历史存储到远端适合需要可扩展、高效聊天存储的应用场景。典型用法是把 chat store 挂到ChatMemoryBuffer上from llama_index.storage.chat_store.upstash import UpstashChatStore from llama_index.core.memory import ChatMemoryBuffer chat_store UpstashChatStore( redis_urlYOUR_UPSTASH_REDIS_URL, redis_tokenYOUR_UPSTASH_REDIS_TOKEN, ttl300, # 可选过期时间秒 ) chat_memory ChatMemoryBuffer.from_defaults( token_limit3000, chat_storechat_store, chat_store_keyuser1, # 用 key 区分不同用户/会话 )其中chat_store_key决定对话落在 Redis 的哪个 List key 下多租户场景下通常传用户 IDtoken_limit控制内存中保留最近多少 token 的上下文超出的部分仍保存在远端 store 中。在异步上下文中也可以直接操作 store来自集成包 README 的示例import asyncio from llama_index.core.llms import ChatMessage async def main(): messages [ ChatMessage(contentHello, roleuser), ChatMessage(contentHi there!, roleassistant), ] await chat_store.async_set_messages(conversation1, messages) retrieved_messages await chat_store.async_get_messages(conversation1) print(retrieved_messages) deleted_message await chat_store.async_delete_last_message(conversation1) print(fDeleted message: {deleted_message}) asyncio.run(main())测试用例与验证现状集成包附带了完整的测试套件 test_chat_store_upstash_chat_store.py覆盖非法参数初始化期望ValueError、追加/读取/删除单条与全部消息、按索引插入后的顺序断言、TTL 过期后列表为空ttl3后等待 4 秒、get_keys返回已写入的 key以及对应的全套 async 版本测试。测试通过环境变量UPSTASH_REDIS_REST_URL与UPSTASH_REDIS_REST_TOKEN连接真实 Upstash 实例。需要说明的是从源码看该测试文件中所有用例当前都标注了pytest.mark.skip(reasonSkipping all tests)即仓库内这些集成测试处于跳过状态不会在 CI 中实际运行。如果你要在本地验证该 store 的行为需要在设置好上述两个环境变量的前提下手动解除跳过。测试文件中的断言例如删除索引 1 后剩余 1 条且内容是 First message、TTL3 秒等待 4 秒后取回空列表也恰好印证了上文对delete_message与 TTL 行为的源码分析。使用建议与注意事项URL 与 Token 缺一不可两者任一为空会直接ValueError建议从环境变量读取避免硬编码到代码库。初始化失败是静默的客户端创建异常只记日志程序要继续靠redis_url/redis_token的有效性自行保证上线前建议先用get_keys()做一次连通性检查。get_keys使用KEYS *base.py#L312-L321 直接执行keys(*)并做了一次若非 list 则包一层 list的防御性处理。生产环境中如果该 Redis 实例上有大量其他 key从源码结构看这一步的扫描代价值得留意必要时可以在业务侧自行维护 key 前缀约定。TTL 语义是滑动过期每次写操作刷新过期时间适合会话级别的自动清理而不适合做严格的绝对过期时间。版本兼容区间当前仓库中该包锁定llama-index-core0.13.0,0.15与 Python 3.10升级核心包或客户端大版本时建议先跑一遍本地集成验证。相关文档与源码入口资源路径API 参考页本文对应文档docs/api_reference/api_reference/storage/chat_store/upstash.mdUpstashChatStore实现base.py集成包 README安装与示例README.md集成包测试test_chat_store_upstash_chat_store.py依赖声明pyproject.tomlChat Store 框架指南含 Upstash 章节chat_stores.md抽象基类BaseChatStorellama-index-core/llama_index/core/storage/chat_store/base.py【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考