Guides
Persistence
为 we0agent 接入内存、SQLite 或自定义持久化,让会话、消息、工具状态和 resume 能跨请求保存。
持久化决定 session、message、part、tool state、summary 和 revert 状态保存在哪里。没有显式传入 persistence 时,We0Agent 使用 MemoryPersistence,只适合测试和短生命周期进程。
数据流
什么时候必须接持久化
| 需求 | 是否必须 |
|---|---|
| 本地跑一次 demo | 否,内存即可 |
| 同一进程内临时对话 | 不一定 |
| 页面刷新后还能看到历史 | 是 |
mode="resume" 跨请求恢复 | 是 |
| snapshot / revert / summary | 是 |
| 多进程或服务重启后保留会话 | 是 |
SQLite 最小接入
from pathlib import Path
from we0agent.persistence.sql import SqlPersistence
persistence = SqlPersistence.sqlite(Path("workspace/session.sqlite"))
await persistence.initialize_schema()
agent = We0Agent(
name="demo",
model=model,
system_prompt=prompt,
tools=tools,
persistence=persistence,
)首次使用 SQL 持久化前必须调用 initialize_schema()。重复调用是幂等的。
SQLite 示例运行命令见 Examples: persistence_feature。
持久化后的续聊案例
同一个 session_id 加同一个 persistence 后端会形成连续会话。第一轮写入历史,第二轮模型会看到前面的用户消息和 assistant 输出。
import asyncio
from pathlib import Path
from we0agent.persistence.sql import SqlPersistence
persistence = SqlPersistence.sqlite(Path("workspace/session.sqlite"))
await persistence.initialize_schema()
agent = We0Agent(
name="demo",
model=model,
system_prompt=prompt,
tools=tools,
persistence=persistence,
)
session_id = "ses_recall_demo"
await agent.invoke(
abort=asyncio.Event(),
session_id=session_id,
messages=[user_message("记住:项目代号是 Aurora,负责人是 Lin。")],
)
async for event in agent.stream(
abort=asyncio.Event(),
session_id=session_id,
messages=[user_message("刚才说过项目代号和负责人是什么?")],
):
if event["type"] == "text-delta":
print(event["text"], end="", flush=True)服务重启后,只要重新创建指向同一个数据库的 SqlPersistence,并继续使用同一个 session_id,历史仍会参与下一轮模型输入。这个模式适合客服会话、IDE agent 面板、长任务审计和跨页面刷新恢复。
持久化模型
Persistence 端口保存三类主要数据:
| 数据 | 说明 |
|---|---|
| Session | We0SessionInfo,包含 id、时间、标题、summary、revert 等会话级信息。 |
| Message | MessageWithParts.info,包含 user / assistant 等消息头。 |
| Part | MessageWithParts.parts,包含文本、工具、step、patch、compaction 等结构化片段。 |
内存持久化
from we0agent.persistence.memory import MemoryPersistence
persistence = MemoryPersistence()内存实现不需要建表,进程退出即丢失。适合:
- 单元测试
- 文档示例
- 不需要 resume 的短任务
不适合生产会话。
SQL 后端
SQLite:
from pathlib import Path
from we0agent.persistence.sql import SqlPersistence
persistence = SqlPersistence.sqlite(Path("session.sqlite"))
await persistence.initialize_schema()自定义 SQLAlchemy async URL:
persistence = SqlPersistence("postgresql+psycopg://user:pass@host/db")
await persistence.initialize_schema()如果 URL 是 postgresql://...,实现会归一化为 postgresql+psycopg://...。
注入位置
构造 agent 时注入,作为默认持久化:
agent = We0Agent(
name="demo",
model=model,
system_prompt=prompt,
persistence=persistence,
)单次请求也可以覆盖:
async for event in agent.stream(
abort=abort,
session_id="demo-session",
messages=[message],
persistence=another_persistence,
):
...通常不建议频繁覆盖,除非你明确在做迁移、测试隔离或多租户路由。
读取会话
session = await persistence.get_session("demo-session")
messages = await persistence.messages("demo-session")
part = await persistence.get_part(
session_id="demo-session",
message_id="msg_...",
part_id="part_...",
)messages(session_id) 返回完整 MessageWithParts 列表,按消息时间升序排列。
自定义 Persistence
继承 we0agent.persistence.base.Persistence 抽象基类即可接入自己的存储。最小需要覆盖这些能力:
| 方法 | 用途 |
|---|---|
ensure_session / get_session / touch_session | 创建、读取、更新时间。 |
messages | 读取完整历史。 |
save_message_with_parts | 保存消息和 parts。 |
update_message / update_part | 更新 assistant、tool、summary 等运行中状态。 |
remove_message / remove_part | 支持 cleanup、revert 等操作。 |
set_revert / clear_revert | 保存和清理回滚状态。 |
生产实现要特别注意事务边界:message 和 parts 应尽量在同一事务里保存,避免 resume 看到半条历史。
易错点
- SQL 持久化忘记
initialize_schema()会导致表不存在。 - prompt 和 resume 必须使用同一个
session_id和同一个持久化后端。 MemoryPersistence不跨进程,不适合需要恢复的服务。- 仓库示例工作区会清理自己的目录;业务数据应放在业务系统管理的目录中。
- 自定义存储要保持消息排序稳定,否则模型历史会乱序。
下一步
- 恢复会话:看 Resume。
- 文件快照:看 Snapshots。
- 回滚服务:看 Revert。
- 排查持久化:看 Troubleshooting。