ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

DeepSeek-Reasonix 持久化工具恢复机制解析:崩溃后的副作用确认、安全重试与转录兼容设计

DeepSeek-Reasonix 持久化工具恢复机制解析:崩溃后的副作用确认、安全重试与转录兼容设计 DeepSeek-Reasonix 持久化工具恢复机制解析崩溃后的副作用确认、安全重试与转录兼容设计【免费下载链接】DeepSeek-ReasonixDeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Reasonix导读DeepSeek-Reasonix 是一款围绕前缀缓存稳定性设计、可长期驻留终端的 DeepSeek 原生 AI 编码 Agent。当工具执行已开始但结果未知时进程崩溃、网络中断、超时恢复机制必须在不误判、不重复副作用的前提下让会话继续。本文基于仓库文档 docs/TOOL_RECOVERY.md 并结合 Go 运行时、Electron 前端与测试代码系统讲解工具执行证据的持久化、快照与解析契约、安全重试边界、转录兼容性及验证发布流程读完即可掌握该机制的设计约束、配置开关与实操接入方式。设计前提执行证据归属 Go 运行时DeepSeek-Reasonix 桌面端采用 Go 运行时 Electron 前端的架构。工具执行证据tool execution evidence是运行时状态的一部分归属于 Go 运行时持有Electron 与 Remote远程Tab 共享同一套控制器 API不存在 Wails 绑定也没有独立的二次恢复数据库secondary recovery database来单独存储恢复状态。这意味着恢复数据与会话本身走同一条持久化路径会话 checkpoint天然享受既有的一致性保障本地 Tab 与远程 Tab 通过统一的控制器接口对外暴露能力前端无需感知恢复数据的存储位置不存在两套恢复逻辑、两套事实来源避免了运行时说 A、恢复库说 B的分裂。对应实现可见 desktop/tool_recovery.go桌面宿主定义了toolRecoveryController接口ToolRecoverySnapshot()与ResolveToolRecovery(...)本地与远程两条路径都收敛到这一接口上。执行与持久化六步生命周期恢复机制的根基是把工具调用从一次性的模型回合提升为带持久化证据的生命周期。文档给出六步流程结合源码internal/agent/tool_recovery_records.go可还原为提案保留原始参数工具提案tool proposal在会话中保留其原始参数而非只保留模型视角的摘要。启动前置校验参数校验、目标解析、权限检查都发生在启动之前。任何未通过校验的调用都不会进入恢复生命周期。分配身份并持久化收据运行时为调用分配 attempt ID、规范参数摘要canonical argument digest与稳定的幂等键idempotency key。在tool_started被确认并 fsync 之前动作收据action receipt先通过既有会话 checkpoint 路径保存。源码中身份由provider.ActionIdentity承载CallID、CanonicalTool、ArgumentDigest对规范化参数做 SHA-256、AttemptID16 字节随机数 hex、SessionID、TurnID、ResourceScope幂等键IdempotencyKey是对去掉 AttemptID 后的身份再做一次摘要——即同一工具 规范参数 会话作用域在重试时保持幂等键不变见 internal/agent/tool_recovery_records.go落盘顺序严谨先event.EmitChecked(... RecoveryCheckpoint: true)写入会话事件流再emitToolStarted对外确认已开始若 checkpoint 写入失败状态回退为ToolRunNotStartedL126-L136保证收据在、才开始。实际执行工具在携带幂等键的上下文context中执行工具方可借助tool.RecoveryIdempotencyKey(ctx)读取该键在自己的下游做去重。结果回写同一 attempt收到的结果在结果 checkpoint 之前更新同一个 attempt 记录。显式失败explicit failure与启动后取消/超时是明确区分开的——finishToolRecovery中只有确实执行过且带错误信息才会标记为ToolRunFailed超时未返回则保持started/running/unknowninternal/agent/tool_recovery_records.go。重启后的判定规则重启后已开始但无确认结果的调用保持 unresolved未决状态新格式的 dispatched 调用若缺少启动屏障start barrier则被取消旧格式legacy缺少启动证据的记录保持unknown——unknown 绝不等于未执行这是整套机制最核心的语义红线。首写者绑定与文件后置条件第一个写入者first writer还会把自己的动作身份与转录摘要transcript digest绑定到既有的文件 checkpoint 上。文件后置条件postcondition确立的是当前状态现在文件内容是什么而不是一次外部操作的历史结果历史上是否发生过这次写入——两者在恢复语义上不可混为一谈。未决效应阻塞后续写入未决的变更类调用会阻塞后续的变更类调用即使后续模型调用使用了全新的 call ID 也无法绕过beginToolRecovery在准入阶段检查PendingToolRecovery()只要存在未决的非只读记录就直接返回recovery_required: inspect and resolve the previous uncertain tool effect before another writeinternal/agent/tool_recovery_records.go。同时只读诊断仍然可用只读调用不阻塞用户仍可查看状态重写/压缩会话保留未决收据retainUnresolvedToolRecords把未决记录的调用以LocalOnly消息重新挂回重写后的消息列表模型历史重写无法抹掉外部副作用未确认的事实internal/agent/tool_recovery_records.go用户确认过确切工具/参数对不会自动重放确认被记录为user_confirmed且永远不会被伪装成一次成功的工具输出——确认状态与真实执行结果是两类互不混淆的事实。通用传输契约快照、动作与准入桌面宿主 API桌面宿主对外暴露两个入口desktop/tool_recovery.goGetToolRecoveryForTab(tabID)拉取恢复快照ResolveToolRecoveryForTab(tabID, request)提交解析动作inspect / confirm / reject / retry。两者都同时分发本地与远程操作。本地走toolRecoveryController接口远程则通过remoteToolRecovery转发到 Serve 端desktop/tool_recovery.go。远程 HTTP 路由Serve 端注册两条路由internal/serve/tool_recovery.goGET /tool-recovery读取快照受既有 expected-session 头校验保护validateExpectedSessionLocked防止跨会话读取POST /tool-recovery解析动作使用foregroundMutation包装——与模型回合共用前台所有权守卫foreground ownership guard并同样校验 expected-session 头。请求体有 16 KiB 上限且DisallowUnknownFields身份不匹配返回409 Conflict。远端客户端测试覆盖了未知结果绝不自动重放 POST与拒绝其他会话的快照两个关键场景desktop/tool_recovery_test.go。快照结构与内容派生版本号快照control.ToolRecoverySnapshot见 internal/control/tool_recovery.go包含字段含义sessionPath会话路径锁定目标会话runtimeEpoch运行时纪元标识当前运行时实例revision对快照内容做 SHA-256 派生的版本号任何变化都会导致 revision 变化calls未决的调用记录列表retryEnabled重试开关来自REASONIX_TOOL_RECOVERY_RETRYrevision是内容派生的ToolRecoverySnapshot()在返回前对整个视图做 JSON 序列化并计算 SHA-256 摘要作为revisioninternal/control/tool_recovery.go。这保证前端拿到的快照与后端解析时看到的快照严格一致任何并发变化都会让 revision 失配。动作请求与准入排斥动作请求control.ToolRecoveryRequestL25-L32携带精确的快照身份sessionPath、runtimeEpoch、revisionattemptId、inspectionId动作inspect、confirm、reject、retry四选一。控制器准入逻辑L54-L69排斥 running / finishing / rotating / closed 四类运行时状态命中即返回ErrTurnRunningrotating标志在解析期间置位保证解析与模型回合互斥快照身份任一字段不匹配即拒绝recovery snapshot changed; refresh before resolving不会带着过期快照执行动作attempt 失配、inspection 失配同样拒绝。检查Inspection语义普通快照省略原始参数ToolRecoverySnapshot()会主动清空Calls[i].ArgumentsL43-L45前端默认拿不到可执行的载荷显式 inspect 才返回存储参数inspect动作在返回结果时仅对目标 attempt 回填存储的参数用于展示L88-L98。这些参数永远不会进入模型恢复提示recovery prompt检查状态四值present效应存在、postcondition_satisfied文件后置条件已满足、absent_fenced不存在且已被围栏、unknown无法证明。来源见 internal/agent/tool_recovery_actions.go确认必须基于同一次检查ResolveToolRecovery要求inspectionId非空且与记录完全匹配否则报inspect this exact attempt before resolving itL81-L83reject 的语义边界拒绝一次重试只记录拒绝不证明外部效应不存在也不会授予后续更多写入权限源码注释明确Rejecting a retry does not prove the external effect absentL87解析后的继续恢复解析完成后Continue 走普通回合提交ordinary turn submission及其既有的围栏不复用任何特权路径。安全重试边界默认关闭围栏优先开关与能力协商重试默认禁用。只有在拥有方 Go 宿主owning Go host上设置环境变量REASONIX_TOOL_RECOVERY_RETRY1UI 的重试动作才会启用internal/control/tool_recovery.go远程宿主自行决定自身能力retryEnabled随快照下发远程是否启用由其实现决定前端面板中未启用时重试按钮直接不渲染desktop/frontend/src/components/ToolRecoveryPanel.tsx。重试的身份规则显式重试获得全新的 call ID 与 attempt ID但保留原始幂等键r.IdempotencyKey prior.IdempotencyKey见 internal/agent/tool_recovery_records.go同时原始收据记录SupersededBy指向新 attemptL137-L147。因此重试走普通工具调用的完整管线校验、策略、权限、hook、租约lease——没有豁免通道存储参数是权威UI 无法在重试时替换参数重试从会话中的存储记录取参数执行旧动作请求失效复用旧的 action request 无法再次触发执行旧 attempt 已被SupersededBy标记。围栏语义absent fenced 缺一不可重试的准入是最严格的环节internal/agent/tool_recovery_actions.go等待残留执行者退出只读重试会等待前序 stragglers 归零a.stragglers.live.Load() ! 0时拒绝变更类工具必须实现tool.EffectVerifier非只读工具在重试前必须重新建立absent 且 fenced状态RecoveryScope必须与记录的 scope 精确匹配sink/account/resource 绑定scope 变化即拒绝tool recovery sink identity changedfenced意味着前一次尝试已无法再提交commit。仅仅观察到效应不存在mere absence是不够的——必须由工具的下游权威给出 fenced 证明见 internal/tool/recovery.go 中EffectInspection{State, Fenced, Summary}的定义注释Absent is retry-safe only when Fenced proves an older attempt can no longer commit工具可通过tool.RecoveryIdempotencyKey(ctx)读取稳定幂等键在自己的 sink 处做去重internal/tool/recovery.go。文件工具与未知边界文件工具复用既有WriteVerifier只读后置条件检查走internal/tool/write_recovery.go中的FileWriteIntent与WriteSatisfied / WriteUnchanged / WriteConflict / WriteUnknown四态验证internal/tool/write_recovery.go能给出postcondition_satisfied通用 shell 命令与任意 MCP 服务无法证明外部不存在它们始终停留在unknown不可重试明确的承诺边界本实现不为缺少权威收据或去重能力的外部服务承诺 exactly-once——文档原话即does not promise exactly-once effects for external services lacking authoritative receipts or deduplication。转录与兼容性增量元数据绝不自动重写恢复机制对既有会话数据的侵入被严格限制ValidateTranscript只校验不改写它检查一个已经归一化的视图而不修改它采样门sampling gate在 provider 请求拦截器之后、流式传输之前运行使用与适配器相同的配对归一化pairing normalization出站修复视图被宿主明确拒绝的调用在出站修复视图中可以使用合法的空参数valid empty arguments但原始本地参数与校验错误被完整保留健康请求的字节流保持不变恢复收据是附加的本地元数据additive local metadata既有 JSON 仍然可读旧事件编号保持稳定不会因插入收据而重编号旧版远程客户端仍然能穿过新版服务器的执行围栏execution fence——服务器不因客户端旧而降低安全要求降级风险提示旧版可执行文件没有实现这些新的恢复保证因此在降级拥有方运行时之前必须先完成恢复finish recovery before downgrading不执行自动存储格式降级或迁移重写。快照暴露的统计信息unknown / confirmed / retried / rejected / blocked 各动作计数来自保留在会话中的证据是当前未决状态的视图而非终身遥测lifetime telemetry——统计随解析动作实时更新不代表历史总量。验证与发布策略多层验证矩阵核心测试Go覆盖参数/权限拒绝、持久化失败failed durability、显式结果分类、快照不可变性arguments 被剥离且 revision 稳定、过期 attempt 拒绝。代表性用例见 internal/control/tool_recovery_test.goTestToolRecoverySnapshotStripsArgumentsAndIsStable、TestToolRecoveryRejectsStaleSnapshot崩溃持久化测试子进程在 fsynced 外部效应之后、返回结果之前退出随后 reload 加上两次并发确认证明持久化与 at-most-one 解析——效应文件中恰好只有一次写入伪造权威 sink 测试用伪造的权威 sink 演练 unknown、非围栏 absence、围栏 absence、稳定幂等键、以及重复重试请求被拒等场景Chromium 验收进入desktop/frontend目录执行node bench/tool-recovery.mjs脚本位于 desktop/frontend/bench/tool-recovery.mjs。它校验检查、确认、继续continuation、不安全重试被禁用、以及延迟到达的检查不能覆盖切换后的新会话对应前端面板中的generation机制与late inspection cannot overwrite a new session断言见 desktop/frontend/src/components/ToolRecoveryPanel.tsx。分阶段上线建议Go 运行时与生成的 Electron 契约contract必须一起部署二者通过生成式契约文件保持字段一致初始状态重试保持禁用先检查未知结果、查看确认收据验证既有链路仅在工具级 sink 契约已验证的范围内启用重试禁用重试开关不会销毁日志journal与手动恢复路径——随时可以安全回退发布与生产环境 rollout 是独立于本地实现与测试的另一阶段按发布节奏推进。总结DeepSeek-Reasonix 的持久化工具恢复是一套把不确定性显式建模到会话生命周期里的机制执行证据通过 checkpoint 与 fsync 先落盘再确认快照/动作契约通过内容派生 revision 与严格准入排除并发与跨会话风险重试以默认关闭 EffectVerifier 围栏证明 稳定幂等键守住 at-most-once 边界对无法证明的外部服务诚实地保持unknown而不是猜测。对于希望长期驻留、依赖前缀缓存稳定性的 Agent 而言这套机制保证了崩溃之后事实仍在安全继续。【免费下载链接】DeepSeek-ReasonixDeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Reasonix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表