DEBUG.WIKI
丽萨主机;为跨境业务选好 IP;原生 / 住宅 IP · 按套餐选择;查看 IP →
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

LangGraph 用 astream 时,SqliteSaver 报不支持 async

同步 saver 不实现异步 checkpoint 方法。使用 AsyncSqliteSaver,并让连接寿命覆盖图执行。

同一张图用 invoke 能运行,换成 ainvoke 或 astream 后,在 checkpoint 的 aget_tuple、aput 等方法里报 NotImplementedError。如果异常说明 The SqliteSaver does not support async methods,应检查 saver 的类型,而不是调整模型流式参数。aget_state 也会通过异步 checkpoint 接口读取状态。

Open Notebook 的旧 v1-dev-single 开发镜像属于出现过这种同步 saver 被异步读取问题的环境。后续应用发行已处理这一问题,但该开发镜像的 checkpoint 包版本和首次应用修复版本未确定,不能给出一个适用于所有环境的修复包版本,也不能据应用修复推断同步 saver 已支持异步调用。

SqliteSaver 的同步/异步接口边界与镜像版本分开核对。SQLite checkpoint 属于独立的 langgraph-checkpoint-sqlite 包,异步调用应使用 AsyncSqliteSaver。部署时检查实际安装版本是否提供下列接口;示例写法不保证适用于所有历史发行版。

连接与图一起放在异步上下文内

在项目现有环境里安装与 langgraph 兼容的 langgraph-checkpoint-sqlite 和 aiosqlite,把具体版本写入锁文件,再用不调用模型的图验证:

import asyncio
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver

class State(TypedDict):
    count: int

def increment(state: State):
    return {"count": state["count"] + 1}

async def main():
    builder = StateGraph(State)
    builder.add_node("increment", increment)
    builder.add_edge(START, "increment")
    builder.add_edge("increment", END)
    async with AsyncSqliteSaver.from_conn_string(":memory:") as saver:
        graph = builder.compile(checkpointer=saver)
        config = {"configurable": {"thread_id": "sqlite-async-demo"}}
        result = await graph.ainvoke({"count": 0}, config)
        assert result["count"] == 1
        snapshot = await graph.aget_state(config)
        assert snapshot.values["count"] == 1

asyncio.run(main())

脚本用于普通 Python 进程;Notebook 已有事件循环时直接 await main(),不要再嵌套 asyncio.run。:memory: 只用于验证接口,连接关闭后数据消失。需要持久化时改为独立数据库文件,并单独检查重新打开后读取 checkpoint。

不要在 async with 结束后才执行返回的 graph:图仍引用已经退出上下文的 saver。长期服务应在应用启动生命周期建立连接,在关闭生命周期释放,执行请求期间保持可用。

同步调用也可以保留

若业务本来就同步,保留 SqliteSaver 并使用 invoke/同步状态接口即可。选择哪一种取决于调用链;把同步数据库对象塞进异步图,不会自动转换为异步实现。

异步接口解决的是当前 NotImplementedError,不会消除 SQLite 的写入串行限制。并发 Agent 要验证真实请求压力和恢复行为,不能仅凭这个内存示例推断生产吞吐。修正后检查图执行、checkpoint 读取、同一 thread_id 的恢复,以及服务退出时连接能正常关闭;异常若已经变成 database is locked,应另查事务和并发策略。