跳到主要内容

第十五节 — 数据存储划分

这一节回答:FinBayes 的不同数据类别分别放在哪里?为什么这样分?

5 类持久化数据

FinBayes 把持久化数据分为 5 类,每类有专属存储位置:

类别存储位置物理形式
State Store数据目录SQLite 数据库文件
Cache缓存目录Redis(本地实例)或进程内 LRU
Config Store配置目录YAML 配置文件
Credential StoreOS KeychainOS 系统凭证管理
Audit Trail数据目录SQLite(与 State Store 同库不同表)或独立 JSONL 文件

分类原则:按数据敏感度 + 访问频率 + 生命周期划分。最敏感的(凭证)走 OS 级保护;最频繁的(缓存)走内存;持久状态走 SQLite。


存储分类图

这张图表达什么:5 类数据各自的物理形式与典型内容。SQLite State Store 包含 8 张业务表(Session / Watchlist / Judgment Record / Dynamic Profile / StateCandidate / Fin Object / Audit Trail / Context Snapshots),其中 Audit Trail 是审计层独立表,Context Snapshots 是长会话压缩资产;mermaid 图为简洁起见仅画 6 类核心业务对象表。完整 8 张表的 schema 见下方"关键表"。

这张图特意不表达什么:表的字段定义(在附录数据对象 schema 索引);数据迁移流程(在升级流程中描述)。


State Store(SQLite)

为什么 SQLite

  • 本地优先部署的天然选择(无需独立服务进程)
  • 单文件易备份 / 易迁移
  • Python 生态完备(sqlite3 标准库 + aiosqlite 异步绑定)
  • 个人用户量级数据规模(每用户几千到几万条记录)远未到 SQLite 性能上限
  • 支持事务保证状态写入原子性

关键表

内容增长趋势
sessionsSession 实例用户活跃度相关
watchlist_objectsWatchlist 内的 Fin Object用户关注集大小
judgment_records历史判断长期累积
dynamic_profiles用户画像一用户一行
state_candidates待确认状态短期(过期清理)
fin_objects用户关注的金融对象用户关注的对象总数
audit_trail任务执行 / 状态变更 / 降级 等审计记录持续累积,按日归档
context_snapshots长会话压缩后的 Snapshot与 Session 关联

事务策略

  • 用户主动动作(confirm 候选 / 修改画像 / 删除 Session)走单事务
  • 主动信号触发的多 Judgment 更新走批量事务
  • 审计 trail 写入异步化(不阻塞主流程,允许丢少量审计记录的边界 case)

备份与恢复

  • runtime 启动时自动备份当前 SQLite 文件到 *.bak
  • schema migration 前强制备份
  • 用户可手动 finbayes backup 触发备份

Cache

用途:L3 缓存(精确 + 语义)+ Task 执行过程的中间数据 + Provider Readiness 状态缓存

实现选择

部署环境选用
用户本机已装 RedisRedis(推荐,支持 Redis Vector for L3b 语义缓存)
用户本机无 Redis进程内 LRU(如 cachetools 库),L3b 语义缓存改用简单的 in-memory FAISS 或临时禁用

关键设计

  • 缓存不存储敏感内容(凭证 / 用户画像中的隐私字段不进缓存)
  • 缓存键含 user_id,防 user-scoped poisoning(一个用户的缓存不能命中到另一个用户)
  • 行情类查询的缓存 TTL 必须短(≤30s),分析类可几小时
  • 进程重启缓存清空(不持久化)

降级:Cache 不可用时 runtime 退化为不缓存模式(每次都走全链路,成本上升但功能完整)。


Config Store

位置:配置目录下的 YAML 文件

文件内容
config.yaml全局配置(runtime 参数、超时、并发限制 等)
providers.yaml用户配置的 Provider 列表 + 偏好顺序(key 不在这里,在 Credential Store)
task_routing.yaml任务类型 → Provider 映射(可选用户自定义)
ui.yaml用户界面偏好(表达密度初始值、术语深度 等)

关键设计

  • 配置文件可被用户直接编辑(YAML 格式 + 详细注释)
  • runtime 启动时检查格式 + 验证字段,错误时退回默认配置 + 明示错误
  • 修改配置后无需重启 runtime(hot reload 支持)—— 但某些核心配置(如端口)仍需重启

Credential Store

位置:OS 系统凭证管理

平台实现
macOSKeychain Access(通过 keyring Python 库或 security CLI)
WindowsWindows Credential Manager
LinuxSecret Service(如 GNOME Keyring / KDE Wallet)
Linux 无桌面环境加密本地文件(用 cryptography 库 + 用户提供的密码)

存储内容

  • 云端 LLM Provider API key(OpenAI / Anthropic / DeepSeek / 等)
  • 数据 Provider API key / token
  • 用户自定义 Provider 的 secret

关键约束(凭证不变量在工程层的承接):

  • 金融执行凭证不进入 Credential Store(私钥 / 助记词 / 交易所 API key / 银行账户 / 信用卡)—— Credential Store 仅存"本机配置秘密"(LLM / 数据 Provider key 等),与"金融执行凭证"严格区分
  • 用户卸载 FinBayes 时自动清除该程序在 Keychain 中的所有凭证
  • Credential 不通过日志 / 审计 trail / 任何序列化输出泄露

Audit Trail

位置:与 State Store 同 SQLite 文件的独立表,或独立 JSONL 文件(用户可选)

内容

记录类型示例字段
任务执行task_id / type / 输入摘要 / 输出摘要 / Provider 调用链 / 成本 / 时长
状态变更object_type / object_id / before / after / 触发事件 / 时间戳
Provider 调用provider_id / model / token 数 / 成本 / 是否走 fallback
降级事件触发层级 / 原因 / 时间戳 / 关联 task
用户主动动作确认候选 / 修改画像 / 清空 / 删除 等
边界拒收事件输入特征摘要(不含具体凭证内容)/ 时间戳

关键约束

  • 审计 trail 不包含任何凭证类内容(边界拒收事件记录中只标"识别为凭证类,已拒收",不记录具体凭证字符串)
  • 审计 trail 可被用户查阅("为什么这次降级了" / "这条 Judgment 是怎么形成的")
  • 审计 trail 按日 / 月归档,避免单一文件无限增长

数据完整性保护

完整性问题保护机制
部分写入(runtime 崩溃时)SQLite WAL 模式 + 事务原子性
引用完整性(如 Session 引用不存在的 Judgment)数据库外键约束 + runtime 启动时完整性检查
Schema 版本不匹配(升级后)runtime 启动时检查 schema 版本 + 自动 migration
文件损坏runtime 启动时校验和检查 + 自动从 *.bak 恢复
用户误操作清空删除前二次确认 + 操作后保留 7 天可恢复窗口

用户视角的数据动作

用户可对自己的数据做下列动作:

动作影响范围
finbayes session delete <id>删除指定 Session(不删除引用的 Judgment / Watchlist)
finbayes judgment delete <id>删除指定 Judgment Record(需二次确认)
finbayes watchlist remove <fin_object_id>移除关注对象(不删除 Judgment)
finbayes profile view / modify / clear画像查看 / 修改 / 清空(清空时显式提示"协作上下文已重置")
finbayes export导出所有用户数据到 JSON / CSV
finbayes uninstall --clean卸载 + 完全删除所有数据(不可恢复)

战略不变量"用户画像主权"在数据操作层的完整承接。