summarize CLI 缓存设计全解析:SQLite 存储、键构造、配置与驱逐策略

发布时间:2026/9/17 18:44:49
summarize CLI 缓存设计全解析:SQLite 存储、键构造、配置与驱逐策略 summarize CLI 缓存设计全解析SQLite 存储、键构造、配置与驱逐策略【免费下载链接】summarizePoint at any URL/YouTube/Podcast or file. Get the gist. CLI and Chrome Extension.项目地址: https://gitcode.com/GitHub_Trending/summarize/summarizesummarize 项目是一款面向 URL / YouTube / 播客 / 本地文件的抓重点工具同时提供 CLI 与 Chrome 扩展。本文聚焦其 CLI 侧的缓存子系统design 文档见 docs/cache.md系统讲解缓存的设计目标、SQLite 存储结构、各类缓存键的 SHA-256 构造方式、配置文件参数、CLI 开关以及 TTL 与容量双重驱逐策略并结合仓库源码逐一印证实现细节。读完本文你将能准确判断一次运行是否会命中缓存、如何排查缓存失效、如何调优cache配置以及如何安全地清理缓存。一、缓存设计目标与整体架构summarize 的缓存是仅存在于 CLI 侧的轻量级 SQLite 缓存整个缓存就是一个单文件数据库另有 WAL/SHM 侧车文件。它的设计目标在 docs/cache.md 中明确为四点避免重复的转录 / 提取 / 摘要同一 URL 多次运行不必重复抓取与调用 LLM无文件蔓延、磁盘占用有界通过容量上限maxMb与 TTL 双重约束安全的默认值、易于关闭默认开启但可通过 CLI 标志一键绕过仅使用原生 SQLiteNode 24node:sqlite与 Bunbun:sqlite运行时自带能力不引入任何第三方 SQLite 依赖。代码职责划分非常清晰见 src/cache.tssrc/cache.ts对外暴露缓存配置类型、路径解析、统计读取与清理工具src/cache-store.ts真正持有 SQLite 行数据负责读写、驱逐eviction、幻灯片文件清理以及转录缓存适配器src/cache-database.ts把 Node / Bun 两种 SQLite 绑定隔离在同一个接口后面src/cache-keys.ts集中实现全部版本化versioned缓存键构造逻辑。此外还有一个独立于 SQLite 的媒体下载缓存见下文第五节两者并不共享存储。二、存储单文件 SQLite 与 pragma 设置默认路径与覆盖方式默认数据库路径~/.summarize/cache.sqlite覆盖方式配置项cache.path。路径解析的完整逻辑位于 src/cache.ts 的resolveCachePath支持~与~/前缀展开借助环境变量HOME或USERPROFILE绝对路径直接使用相对路径则基于 home 目录拼接当配置未提供且无法解析 home 时返回null即不启用数据库缓存。// resolveCachePath 关键行为src/cache.ts if (raw ~ || raw.startsWith(~/)) { const expanded raw ~ ? home : join(home, raw.slice(2)); return resolvePath(expanded); } return isAbsolute(raw) ? raw : home ? resolvePath(join(home, raw)) : null;SQLite pragma 与表结构打开数据库时会执行以下 pragma见 src/cache-store.tspragma值作用busy_timeout5000写锁竞争时最多等待 5 秒避免并发 CLI 进程直接报错journal_modeWAL允许读写并发配合-wal/-shm侧车文件synchronousNORMAL平衡持久性与写入性能WAL 下常规选择auto_vacuumINCREMENTAL删除数据后通过PRAGMA incremental_vacuum逐步回收空间缓存表cache_entries的结构src/cache-store.tsCREATE TABLE IF NOT EXISTS cache_entries ( kind TEXT NOT NULL, -- 缓存类别extract / summary / transcript / chat / slides key TEXT NOT NULL, -- SHA-256 缓存键 value TEXT NOT NULL, -- 序列化后的缓存负载文本或 JSON size_bytes INTEGER NOT NULL, -- 条目大小用于容量驱逐 created_at INTEGER NOT NULL, last_accessed_at INTEGER NOT NULL, -- LRU 排序依据 expires_at INTEGER, -- TTL 过期时间戳NULL 表示永不过期 PRIMARY KEY (kind, key) ); CREATE INDEX idx_cache_accessed ON cache_entries(last_accessed_at); CREATE INDEX idx_cache_expires ON cache_entries(expires_at);kind的合法取值由 core 包定义packages/core/src/runtime/cache-store.tsextract | summary | transcript | chat | slides。同一个 key 可以分属不同 kind互不冲突联合主键。写入采用 UPSERTON CONFLICT(kind, key) DO UPDATE重复生成同键内容会覆盖旧条目并刷新last_accessed_at。值得注意的细节close()时会先执行PRAGMA wal_checkpoint(TRUNCATE)把 WAL 合并回主库并截断侧车文件src/cache-store.ts这解释了为何--clear-cache需要同时删除-wal与-shm。Node / Bun 双运行时绑定src/cache-database.ts 通过检测全局Bun对象来决定加载哪个绑定if (isBun) { const mod await import(bun:sqlite); return new mod.Database(path); } const mod await import(node:sqlite); // Node 24 内置 DatabaseSync return new mod.DatabaseSync(path);另外在 Node 上运行时它会过滤掉ExperimentalWarning中与 sqlite 相关的警告installSqliteWarningFilter避免噪声刷屏。这是原生 SQLite only目标的直接实现证据。三、缓存键版本化 SHA-256 构造所有缓存键都是 SHA-256 十六进制摘要由 Nodecrypto/ Buncrypto提供src/cache-keys.ts。键的构造逻辑集中在src/cache-keys.ts核心思想是把决定缓存有效性的所有因素打包进 JSON 后整体哈希。各类缓存键定义docs/cache.md 原文缓存类别键说明Transcriptssha256({url, namespace, fileMtime?, formatVersion})本地文件路径会带上fileMtime以便在文件变更后自动失效Extracted contentURL → text/markdownsha256({url, extractSettings, formatVersion})提取设置变化如抓取选项会使键改变Summariessha256({contentHash, promptHash, model, length, language, formatVersion})即使 URL 不同只要内容哈希相同也能命中内容哈希优先Slides清单 输出目录中的磁盘图片sha256({url, slideSettings, formatVersion})幻灯片设置变化会使键改变源码级键构造对照 src/cache-keys.ts 可以还原每个键的具体字段Transcript 键buildTranscriptCacheKeyValueL155-L172hashJson({ url, namespace, fileMtime: fileMtime ?? null, formatVersion });namespace是转录来源命名空间目前包含 YouTube 模式例如yt:auto、yt:web并由createCacheStore的transcriptNamespace参数注入见 src/cache-store.ts。本地媒体文件的fileMtime参与键计算因此文件被重新生成后旧缓存自动失效。Summary 键buildSummaryCacheKeyValueL100-L123hashJson({ contentHash, promptHash, model, lengthKey, languageKey, formatVersion });其中的contentHash与promptHash有专门构造规则promptHashbuildPromptHashL35-L48从 prompt 中抽取instructions与context两个标签块拼合后哈希若 prompt 中不存在任何标签则回退为对整个 prompt 做哈希contentHashbuildPromptContentHashL50-L60取自实际发送给模型的content块因此幻灯片时间轴、转录补充信息等会影响该键若 prompt 内容为空则回退为附件的二进制字节哈希buildAttachmentContentHashL62-L76其中记录附件的 kind、mediaType、byteLength 与字节哈希。长度buildLengthKeyL78-L82区分预设模式与字符数模式preset:short或chars:1200这类形式语言buildLanguageKeyL84-L86在自动模式下记为auto否则用语言 tag。Slides 键buildSlidesCacheKeyValueL125-L153包含url与一组幻灯片设置ocr、outputDir、sceneThreshold、autoTuneThreshold、maxSlides、minDurationSeconds。formatVersion格式级失效开关formatVersion是 core 包中的硬编码常量packages/core/src/runtime/cache-store.ts 中CACHE_FORMAT_VERSION 2。当提示词格式或缓存负载结构发生不兼容变更时维护者会提升该常量使所有旧缓存一次性全部失效——这是比逐个改键更省事的全局失效手段。摘要缓存内容哈希优先语义摘要键不包含 URL只包含contentHash。这意味着同一篇文章以不同 URL 形式出现例如带?utm_source参数、或镜像站只要提取出的content块一致摘要缓存就能命中避免了重复调用 LLM。这是原文档强调的cache hit even if URL differs (content hash wins)。四、配置cache 与 cache.media完整配置示例docs/cache.md 原文{ cache: { enabled: true, maxMb: 512, ttlDays: 30, path: ~/.summarize/cache.sqlite, media: { enabled: true, maxMb: 2048, ttlDays: 7, path: ~/.summarize/cache/media, verify: size } } }默认值与源码 packages/core/src/runtime/cache-store.ts 一致cache.enabled truecache.maxMb 512cache.ttlDays 30cache.path未设置回退~/.summarize/cache.sqlitecache.media.maxMb 2048、cache.media.ttlDays 7、cache.media.verify sizesrc/media-cache.ts配置解析位于 src/config/sections.tsparseCacheConfigL150-L175读取cache对象enabled必须是布尔值maxMb/ttlDays必须是大于 0 的数字path必须是非空字符串任一字段非法都会抛出带路径与字段名的明确错误parseMediaCacheConfigL110-L148cache.media必须是对象verify只接受none、size、hash三者之一否则报错。类型定义见 src/config/types.ts。所有字段均可省略省略即采用默认值。五、媒体缓存下载文件独立于 SQLite 的文件缓存需要特别区分媒体缓存是用于已下载媒体文件yt-dlp 或直接媒体 URL的独立文件缓存不是 SQLite 数据库docs/cache.md 原文明确标注 This isnotthe SQLite DB。默认路径~/.summarize/cache/mediaTTL7 天容量上限2048 MBCLI--no-media-cache仅禁用媒体缓存注意--no-cache不会禁用媒体缓存——二者互相独立。实现位于 src/media-cache.ts其机制与 SQLite 缓存有显著差异目录内一个index.json充当索引version: 1按 URL 的 SHA-256 映射到文件名、大小、可选 sha256、媒体类型、时间戳与过期时间通过.lock文件实现跨进程索引锁带 PID 心跳每 30 秒刷新 mtime锁文件超过 5 分钟判定为陈旧并接管L134-L173文件命名{sha256(url)}{ext}扩展名根据原始文件名或 mediaType 推断如.mp3、.m4a、.mp4、.m3u8推断规则见 L81-L100verify完整性校验三档size默认比对记录大小与磁盘大小、hash重算文件 SHA-256、none不校验写入先落到.incoming-*暂存文件再原子 rename 进缓存目录避免半成品污染缓存put时若单文件大小超过maxBytes则直接不缓存。媒体缓存与 SQLite 缓存的对照维度SQLite 缓存媒体缓存存储形态单文件cache.sqlite WAL/SHM目录 index.json默认上限512 MB2048 MB默认 TTL30 天7 天索引cache_entries表index.json并发控制SQLitebusy_timeout WAL.lock文件 心跳六、CLI 标志与运维命令三个缓存相关 CLI 标志定义见 src/run/help.ts标志作用--no-cache绕过摘要缓存的读写LLM 输出。提取/转录缓存仍然生效--cache-stats打印缓存统计信息后退出--clear-cache删除缓存数据库连同 WAL/SHM必须单独使用校验逻辑位于 src/run/runner-setup.ts--clear-cache与--cache-stats都要求must be used alone一旦与其他参数混用会直接抛错错误文案见 src/locale.ts支持多语言本地化。--no-cache只影响摘要缓存而幻灯片模式还有独立的--no-cache语义Bypass slide cache (force re-extract)见 src/run/help.ts说明缓存开关是按缓存类别精确作用的。统计与清理的实现readCacheStatssrc/cache.ts以只读模式打开数据库PRAGMA query_only ON按kind分组统计条目数并汇总size_bytes磁盘占用统计getSqliteFileSizeBytesL121-L130会把主库、-wal、-shm三个文件大小相加且容忍侧车文件在 checkpoint 期间短暂消失。clearCacheFilessrc/cache.ts使用rmSync(force: true)依次删除主库、-wal、-shm即使文件不存在也不会报错。七、驱逐策略TTL LRU 双保险SQLite 缓存的驱逐src/cache-store.tsTTL 清理读/写时触发sweepExpired用expires_at now一次性查出全部过期条目并删除读取时也会惰性检查单条是否过期readEntry过期即删并返回 miss容量清理写时触发enforceSize先求SUM(size_bytes)若超过maxBytes则按last_accessed_at升序每次批量取 50 条最久未访问的条目删除LRU 语义直到总大小回落到上限以内最后执行PRAGMA incremental_vacuum回收空间。此外幻灯片缓存比较特殊deleteEntry对kind slides的条目会调用cleanupSlidesPayload同时通过buildReferencedSlideArtifacts收集仍被其他 slides 条目引用的磁盘图片路径并予以保留src/cache-store.ts避免误删共享资源clear()全量清理时也会先对 slides 条目做负载清理再清表。相关实现见 src/cache-slides-cleanup.ts。媒体缓存的驱逐src/media-cache.tsTTLpruneExpired删除expiresAtMs已到期的条目含磁盘文件与索引项容量enforceMaxBytes先补齐缺失的sizeBytes若总量超限则按lastAccessAtMs升序LRU逐条删除直到达标。两套缓存都是读时惰性校验 写时主动清扫的组合整体设计保证磁盘占用始终有界。八、与其他组件的边界扩展面板缓存、转录来源与共享格式浏览器扩展使用独立面板缓存CLI 的 SQLite 缓存与 Chrome 扩展的面板缓存完全隔离扩展使用chrome.storage.localURL 维度键控条目采用30 天 TTL 与 8 MB 容量上限它与 core 共享可移植的行格式化buildPortableCacheRow/parseCacheJson见 packages/core/src/runtime/cache-store.ts而 daemon 的提取与摘要缓存仍然使用 SQLite。转录来源库存与命中诊断core 持有转录来源库存TRANSCRIPT_SOURCES同时服务提取与 SQLite 读取两条路径涵盖内嵌字幕与 YouTube 原生媒体缓存命中时会保留条目的原始来源诊断信息source、service、resourceKey、namespace、formatVersion一并写入负载见 src/cache-store.ts方便排查某条转录究竟来自哪个通道。无第三方依赖整个缓存体系只依赖 Node 24 / Bun 原生 SQLite 与 Node 内置crypto/fs模块没有引入任何第三方 SQLite 或哈希库——这在 src/cache.ts 与 src/cache-database.ts 的 import 清单中可以完整验证。九、实践建议与排查速查基于上述设计与实现给出以下可直接落地的操作建议判断是否命中摘要缓存摘要键 sha256({contentHash, promptHash, model, lengthKey, languageKey, formatVersion})。若你修改了自定义 prompt、切换了模型、改动了输出长度或语言键必然变化属正常失效若只是 URL 不同而正文相同仍可命中。本地文件转录不失效请确认文件mtime是否变化——转录键包含fileMtime编辑文件后会自然产生新键。限制磁盘占用调小cache.maxMb/cache.ttlDays或把cache.path指向专用磁盘。精确绕过缓存只想强制重新总结用--no-cache提取/转录缓存仍生效想完全关掉媒体下载缓存用--no-media-cache两者互不影响。查看与清理--cache-stats查看各 kind 条目数与总大小--clear-cache一次性删除整个数据库需单独使用并会自动连带 WAL/SHM。怀疑缓存负载不兼容关注CACHE_FORMAT_VERSION当前为 2升级后旧缓存整体作废属预期行为。媒体文件损坏把cache.media.verify从默认的size提升为hash可在每次读取时重算 SHA-256 校验追求极致性能可设为none。延伸阅读CLI 配置整体说明见 docs/config.md命令行用法见 docs/commands/index.md 与 docs/cli.md缓存相关测试覆盖可参考 tests/cache.store.test.ts、tests/cache.keys.test.ts、tests/cache-stats.test.ts、tests/cache.path.test.ts、tests/cache-state.refresh.test.ts 与 tests/media-cache.test.ts。【免费下载链接】summarizePoint at any URL/YouTube/Podcast or file. Get the gist. CLI and Chrome Extension.项目地址: https://gitcode.com/GitHub_Trending/summarize/summarize创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询