Gemini CLI 会话管理实战:会话自动保存、恢复、检查点与保留策略深度解析
2026/9/5 18:10:08 网站建设 项目流程

Gemini CLI 会话管理实战:会话自动保存、恢复、检查点与保留策略深度解析

【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli

Gemini CLI 的会话管理(Session Management)负责把你与模型的完整对话历史持久化到本地,让你可以随时从上次中断的地方继续工作。本文基于官方文档 session-management.md 并结合当前仓库源码,系统讲解会话的自动保存机制、通过命令行与交互式浏览器恢复会话的完整操作、Git worktree 并行会话方案,以及sessionRetentionmaxSessionTurns的保留策略配置——读完之后,你可以独立完成会话的查看、恢复、删除与清理策略定制。

会话自动保存:保存什么、存在哪里

你与模型交互时,会话历史会被自动记录,无需任何手动操作。这一后台持久化过程即使在你中断会话(如 Ctrl+C、终端意外关闭)的情况下也能保证工作现场得以保留。

保存的内容包括完整的对话上下文:

  • 你的提示词(prompts)和模型的回复;
  • 所有工具执行记录(输入与输出);
  • Token 用量统计(输入、输出、缓存等维度);
  • 助理的思考与推理摘要(thoughts / reasoning summaries,在模型支持时可用)。

存储位置~/.gemini/tmp/<project_hash>/chats/,其中<project_hash>是基于项目根目录生成的唯一标识。这带来一个关键特性:会话是按项目隔离的。切换到另一个目录(另一个项目)再启动 CLI,加载的就是那个项目自己的会话历史,互不干扰。

从源码结构看,这一隔离逻辑由核心包的Storage类统一管理:sessions.ts 中listSessions通过config.storage拿到项目级临时目录,再拼接chats子目录扫描会话文件。会话文件名遵循session-<时间戳>-<ID前8位>.jsonl格式——在 sessionUtils.ts 的注释中明确写道:

The filename format issession-<TIMESTAMP>-<ID_SLICE(0,8)>.jsonl

文件名中只保留 UUID 的前 8 位作为短标识,完整 UUID 记录在文件内容的sessionId字段中。恢复或按短 ID 查找时,SessionSelector.sessionExists会先按前 8 位过滤候选文件,再逐个解析确认完整 ID 是否匹配(见 sessionUtils.ts#L415-L440)。

另外,扫描时会主动过滤三类文件,它们不会出现在会话列表中:

  • 子代理(subagent)会话:属于工具调用的内部实现细节,不对主代理历史开放;
  • 无可恢复内容的会话:仅含启动信息、系统消息或内部上下文的会话被跳过(hasResumableContent校验);
  • 损坏文件:解析失败的文件标记为 corrupted,列表接口自动剔除。

恢复会话:命令行三种方式

启动 Gemini CLI 时,使用--resume(简写-r)标志加载已有会话,支持三种寻址方式:

1. 恢复最近一次会话

gemini --resume

不带参数时立即加载最新会话。对应源码中RESUME_LATEST常量(sessionUtils.ts#L26):--resume无值时被解析为latestSessionSelector.resolveSession会按startTime升序排序后取最后一个。值得注意的是,当项目根本没有任何会话时,latest不会报错退出,而是发出警告并回退创建一个新会话(见 gemini.tsx#L315-L319)。

2. 按索引恢复

先列出可用会话(见下文 列出会话),再用序号恢复:

gemini --resume 1

索引是 1 基的,按会话开始时间从旧到新编号——越新的会话编号越大。

3. 按 UUID 恢复

直接提供完整会话 ID:

gemini --resume a1b2c3d4-e5f6-7890-abcd-ef1234567890

从 SessionSelector.findSession 的实现可以确认解析优先级:先按完整 UUID 精确匹配,匹配失败才尝试解析为纯数字索引(且要求索引严格为数字字符串、大于 0 且不超过会话总数)。找不到时抛出带INVALID_SESSION_IDENTIFIER错误码的SessionError,提示信息会引导你使用--list-sessions查看可用会话。

恢复会话:交互式 Session Browser

在 CLI 运行中,输入/resume斜杠命令即可打开Session Browser

/resume

从源码看,resumeCommand.ts 将其定义为CommandKind.BUILT_IN的内建命令,autoExecute: true——即无需带参数直接执行,其动作是返回dialog: 'sessionBrowser'交给 DialogManager 渲染。

在斜杠命令补全界面中,/resume(或/chat)等命令会按标题分隔符分组展示:

  • -- auto --(会话浏览器组):其中的list可被选中,直接打开会话浏览器;
  • -- checkpoints --(手动检查点命令组)。

唯一前缀如/resum/cha也会解析到同一个分组菜单。

Session Browser 支持的交互操作如下(这些按键处理逻辑可在 SessionBrowser.tsx 的键盘事件分支中找到对应实现):

操作按键说明
浏览上下方向键 / PageUp / PageDown滚动浏览历史会话列表
预览选中项显示会话日期、消息数、首条用户提示词等详情
搜索/进入搜索模式,按 ID 或会话内容过滤
恢复Enter恢复选中的会话
退出Esc关闭 Session Browser
删除xX删除选中的会话(源码中key.sequence === 'x' \|\| key.sequence === 'X'分支触发删除流程)

预览信息来自SessionInfo结构(sessionUtils.ts#L90-L121):包含startTimemessageCountlastUpdateddisplayName(通常为 AI 摘要或首条用户消息)等字段。搜索模式下会按需加载会话全文(includeFullContent选项)进行内容级匹配并展示带上下文的片段。

手动会话检查点

对于会话内部需要命名分支点(branch point)的场景,使用 chat checkpoints 保存和回跳:

/resume save decision-point /resume list /resume resume decision-point

兼容性别名:

  • /chat ...可以执行同样的命令;
  • /resume checkpoints ...在迁移期内也保持可用。

使用 Git worktrees 并行多个会话

同时处理多个任务时,可以用 Git worktrees 为每个 Gemini 会话提供独立的代码库副本,避免一个会话的改动与另一个会话冲突。由于会话按项目根目录(<project_hash>)隔离,每个 worktree 目录天然对应独立的会话存储空间,这与 worktree 的隔离诉求正好契合。

管理会话:列出与删除

列出会话

gemini --list-sessions

输出当前项目所有可用会话的示例:

Available sessions for this project (3): 1. Fix bug in auth (2 days ago) [a1b2c3d4] 2. Refactor database schema (5 hours ago) [e5f67890] 3. Update documentation (Just now) [abcd1234]

实现位于 listSessions:会话按开始时间升序编号,每行显示序号、标题(超过 100 字符截断为 97 字符加省略号)、相对时间与 8 位短 ID;当前活动会话会额外标注, current。此外,列表生成前会先调用generateSummary为最近一次会话生成 AI 摘要(未配置认证时优雅跳过),因此列表中的标题可能是摘要而非原始首条消息。

删除会话

命令行方式--delete-session后跟索引或 ID:

gemini --delete-session 2

deleteSession 的解析策略与--resume一致——先 UUID 后索引;同时有一条硬性保护:不允许删除当前活动会话isCurrentSession为真时直接提示Cannot delete the current active session.并返回)。

Session Browser 方式

  1. /resume打开浏览器;
  2. 导航到要删除的会话;
  3. x

配置保留策略:sessionRetention

你可以在settings.json中控制会话历史的保留方式。默认情况下,Gemini CLI 会自动清理过期的会话数据,防止历史无限膨胀;某个会话被删除时,其所有关联数据(实现计划、任务跟踪器、工具输出、活动日志)会一并清除。默认策略是保留会话 30 天

通过/settings命令或直接编辑settings.json自定义:

{ "general": { "sessionRetention": { "enabled": true, "maxAge": "30d", "maxCount": 50 } } }
  • enabled(boolean):会话清理总开关,默认true
  • maxAge(string):会话保留时长,例如"24h""7d""4w",超过该时长的会话将被删除,默认"30d"
  • maxCount(number):保留的会话数量上限,超出部分从最旧的开始删除。默认为未定义(不限制)。
  • minRetention(string):最短保留期(安全下限),默认"1d",比该期限更新的会话永远不会被自动清理。

底层实现细节(见 sessionCleanup.ts):

  • 时长字符串由parseRetentionPeriod解析,支持的单位是h(小时)、d(天)、w(周)、m(月,按 30 天计),且数值必须大于 0——注意文档示例中的"4w"之外的单位(如sy)不在支持范围;
  • 启动时执行的validateRetentionConfig会做三项校验:maxAge不得小于minRetentionmaxCount至少为 1;maxAgemaxCount必须至少指定其一。任何一项不满足,清理会被整体禁用并写警告日志(Session cleanup disabled: ...),而不是误删数据;
  • 清理入口cleanupExpiredSessions在 CLI 启动时运行,删除判定基于lastUpdated时间戳,且当前活动会话永远被排除在删除范围之外
  • 除了会话文件本身,还会级联调用deleteSessionArtifactsAsyncdeleteSubagentSessionDirAndArtifactsAsync清除该会话的工具输出目录、子代理会话等关联产物;
  • 同一份保留策略同样作用于tool-outputs目录的清理(cleanupToolOutputFiles),即工具输出的年龄与数量上限与maxAge/maxCount联动;
  • 全局兜底原则是“清理失败不阻断启动”:任何异常都会被捕获并计入failed统计,不会导致 CLI 无法启动。

配置单会话长度上限:maxSessionTurns

为防止单个会话的上下文窗口过大、成本过高,可以限制会话轮次:

{ "model": { "maxSessionTurns": 100 } }
  • maxSessionTurns(number):单次会话允许的最大轮数(用户与模型的交互往返数)。设为-1表示无限制(默认值)。

达到上限后的行为

  • 交互模式:CLI 显示一条提示信息并停止向模型发送请求,需要手动开启新会话;
  • 非交互模式:CLI 直接以错误退出。

延伸阅读

  • Memory 工具:把信息持久化并跨会话保留;
  • Checkpoint:会话状态的检查点机制;
  • CLI 参考:全部命令行标志;
  • Git worktrees 指南:并行会话的目录隔离方案;
  • 实现与测试:sessions.ts、sessionUtils.ts、sessionCleanup.ts、sessionCleanup.integration.test.ts、SessionBrowser 组件。

【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询