模型交付

为 Android AI 模型下载设计安全重试策略

根据失败证据决定退避、等待约束、停止或要求用户操作,并保护已下载的部分文件。

审核状态: 内容已校验;中文稿供用户审核 · 2026-10-04 · Fact IDs: COVE-DOWNLOAD-01, COVE-MODEL-02

直接回答

安全的重试策略要先分类失败,而不是先数重试次数。只有当故障可能是暂时性的,而且下一次仍能使用相同且固定的制品身份时,才考虑重试。完整性不匹配、正文格式错误、制品修订不兼容、用户取消或配置错误,都不应自动无限重试,除非原因或输入已经发生变化。系统约束和取消状态需要被尊重;只有身份和响应历史明确的部分字节才能保留;当应用无法安全判定时,应提供明确的人工恢复选项。重复发起 HTTP 请求并不自动安全:若正文来自另一修订,即使请求成功,追加后也可能得到损坏文件。 当前仓库的 ModelDownloader 会先尝试配置的主 URL;遇到超时或 DNS 解析失败时,可能继续尝试配置的镜像。其他异常会返回错误,不会一概静默切换来源。它会根据临时文件长度发起 Range 请求,接受 HTTP 200 或 206,并且仅在配置了 SHA-256 时才对完整临时文件进行摘要检查。这些是现有实现的描述,不意味着每条重试路径都天然安全。当前 E2B 摘要为空,因此不能声称这种配置能够检测摘要不匹配。任何重试策略都必须先说明:应用对制品身份、来源和已有字节的来历究竟掌握了什么。 失败类别应根据可观察证据划分。暂时 DNS 错误或套接字超时可能允许稍后重试,但要与鉴权失败、制品不存在、意外内容类型或服务器错误区分开。用户主动取消应终止该次操作,不能在后台违背用户意愿再次发起。WorkManager 因约束变化而停止任务,与传输出错不是同一回事:持久任务 API 支持约束和取消,Worker 必须合作响应停止信号。存储不足不会靠等待网络重试解决。摘要不匹配时应隔离或删除候选模型文件并要求可信替代制品;对相同字节无限重试无法修复根因。 退避应该避免大量客户端同时重试,并节省电量与网络资源,但不能隐藏状态。记录尝试次数、失败类别、延迟类别、制品修订、部分文件情况和用户控制。没有系统测试与明确产品策略时,不要编造一个“最佳”固定间隔。适用时让调度器执行网络等约束,并在任务真正运行时再次检查,因为入队之后状态可能变化。平台发出取消或停止信号时,要及时关闭流和连接。界面可以显示等待不计费网络、已安排重试、需要用户操作、已取消或最终失败。通知不应成为唯一状态来源。 安全续传不仅是保留一个临时部分文件。持久化的传输记录应绑定模型 ID、不可变修订或 URL 身份、预期长度来源、存在时的摘要、部分文件路径、上一次响应状态和范围信息,以及真正写入的字节数。下一次响应到达后,要验证其状态、Content-Range、请求偏移和确切表示形式。如果服务器忽略 Range 并返回完整正文,应从全新的临时文件开始,而不是追加。如果表示形式已改变或元数据缺失,应丢弃或隔离旧部分数据,并且只有策略允许时才能重新下载。不能因为上次写入的字节数看起来达到预期值,就直接提升文件。 重试测试矩阵应使用确定性假服务或受控测试服务器,覆盖超时、DNS 失败、临时服务器错误、404、鉴权失败、范围无效、服务器忽略 Range、正文截断、版本变化、空间不足、摘要不匹配、用户取消和调度器停止。既要检查再次尝试的策略,也要检查数据安全:不重复传输、不跨版本追加、不删除用户数据、不在取消后重试、不让不完整文件进入就绪状态。还应在入队与执行之间插入进程重建,确认状态对产品承诺而言持久可靠。即使瞬时错误重试成功,仍需通过完整性和运行时加载验收,应用才能报告功能已就绪。 ### 操作步骤 1. 建立失败分类及动作表。把每种可观察故障标为暂时性、等待约束、用户操作、完整性或安全终止、制品不存在或配置错误,并写明是否允许重试、界面状态和下一步安全动作。 2. 将重试绑定到制品来源。持久化模型 ID、固定修订、URL 或来源身份、预期元数据、部分文件路径、字节偏移和最近一次范围响应状态。身份缺失或冲突时,不得因为文件名相同便复用旧字节。 3. 实现尊重调度和取消的任务。如果工作需要跨进程保留,使用持久任务并显式设置约束、观察停止信号、关闭活动资源;用户明确取消后不应再次自动排队。 4. 注入确定性故障并测试恢复。模拟不同响应、部分文件、网络变化、进程死亡和存储压力;逐次核对每次重试后的磁盘数据和用户可见状态,而不只检查最后成功。 5. 审核重试的隐私与资源成本。日志记录故障类别而非私密提示或凭据;网络、电量与无限重试必须受清晰产品规则控制。 ### 验收标准 - 每一类故障都有重试资格和用户下一步的明确策略。 - 只有模型修订及响应范围来源相符时才能复用部分字节;表示形式不明时不能复用。 - 用户取消或平台停止后,任务会关闭资源且不会违背用户选择自动重试。 - 完整性、鉴权、制品缺失及永久配置错误不会在输入未变或用户未介入时循环。 ### 重试策略对照 | 结果 | 正确策略 | 不安全捷径 | |---|---|---| | 暂时连接故障 | 退避并在条件仍成立时重试固定制品 | 立即进入紧密重试循环 | | 约束变化或任务停止 | 保存可验证状态并等待调度策略 | 把每次停止都当作损坏或成功 | | 摘要或表示身份不匹配 | 拒绝候选文件 | 无限下载相同字节或标记就绪 | ### 常见问题 **所有失败请求都应自动重试吗?**不应。超时可能是暂时故障;制品不存在、鉴权失败、摘要不匹配和用户取消需要不同处理,通常应停止自动任务。先分类再判断是否安全重试。 **WorkManager 重试等于从上次字节续传吗?**不等于。调度下一次 Worker 与追加有效部分表示是两个独立问题。传输层仍须校验制品身份、服务器范围响应和持久化偏移,确认后才写入。 **摘要校验失败时应怎样恢复?**不要提升候选文件。只拒绝或隔离该模型制品,保护其他用户数据,明确显示可修复的完整性失败,并仅在策略允许时获取可信替代文件。 **用户取消后还能继续重试吗?**同一操作不可以。取消应对该工作身份保持终止状态。新尝试需来自用户有意操作,或来自产品明确记录的其他事件,不能偷偷在后台恢复。

网络策略变化时后台模型传输失败

用户在受限网络下开始下载模型,之后在网络间切换。当前任务可能停止,临时文件也可能留下部分字节;Worker 还可能因不再满足约束而被系统停止。应用必须分清“等待条件”与“制品损坏”。

决策

分类事件,保存制品身份与部分响应来源,只允许符合条件的失败安排下一次尝试。Worker 停止本身既不能证明损坏,也不能证明已成功。

预期结果

下一次尝试会安全续传可证明匹配的表示、从头开始、等待约束或请求用户操作,不会混合字节或无限循环。

需要收集的证据

只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:

  • 失败类别与处理决策表
  • 模型修订及部分响应状态
  • 取消、系统停止和恢复测试结果

收到完整字节流还不够;最终落盘、完整性、运行时加载和恢复路径也必须验证。

实施流程

  1. 定义明确的重试类别. 将超时、DNS、服务器状态、鉴权、制品缺失、正文格式错误、范围不匹配、存储压力、摘要不符、用户取消及调度停止分别分类,并为每类定义可否重试、何时停止以及如何提示用户。
  2. 在调度前保存传输身份. 保存模型 ID、不可变修订、来源身份、预期元数据、部分路径、偏移量和上次范围状态。身份缺失或不一致时,应将部分数据视为不安全,不能因为文件名相同就绑定到新版本。
  3. 遵守约束与取消. 如果任务需要跨进程存活,使用持久任务并记录必要约束,同时观察停止信号。及时关闭流和连接,只保留已验证的传输信息;明确的用户取消不能触发新的自动尝试。
  4. 写入前验证续传响应. 打开追加模式前,先检查状态、请求范围、返回范围、表示身份和正文类型。若服务器返回完整文件或不同修订,应按策略安全重启或拒绝,而不是接在已有字节后。
  5. 通过故障注入验证恢复. 使用受控服务器和存储夹具覆盖临时及永久失败、进程重建、约束变化、部分写入与摘要不匹配。每次尝试后检查落盘字节和界面状态,不只看最终是否成功。

让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。

验收标准

  • 每种故障都有明确的重试、等待、终止或要求用户操作策略。
  • 除非模型修订和范围响应来源一致,否则不会复用部分字节。
  • 取消及 Worker 停止会关闭资源,且不能在用户选择之后偷偷触发重试。
  • 只有完整性通过且运行时接受的候选制品,才会成为已选就绪模型。

决策对照表

维度选择或证据解读方式
暂时连接错误退避重试只有故障证据支持其暂时性时,才重试同一固定表示。
约束丢失或调度停止等待并核对不能自动等同于网络错误、文件损坏或成功。
完整性或身份不匹配拒绝候选制品重新获取可信替代;重复相同请求无法修复来源身份变化。

需要避免的失败模式

  • 对所有失败无限重试
  • 把 Worker 停止当作模型文件损坏
  • 将不同版本的部分字节续接

还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。

最小复现记录

层级记录内容
设备厂商、型号、芯片、内存档位、操作系统版本
软件应用版本和 Git 提交号
模型系列、变体、版本、格式、文件长度、摘要、量化方式
运行时名称、版本、请求后端及实际后端证据
工作负载样例版本、输入摘要、提示词摘要、输出策略
结果完成、失败、取消、回退及保护隐私的诊断信息

发布检查表

  • ☐ 主要搜索问题已回答,且没有未经支持的数字。
  • ☐ 所有模型文件和运行时版本均已固定。
  • ☐ 代表性任务和失败处理策略均有说明。
  • ☐ 生命周期、取消、清理和回退均已测试。
  • ☐ 用户内容与网络边界均有说明。
  • ☐ 结论只适用于被记录的配置。
  • ☐ 新增测试结果时链接到原始方法或证据。

来源与相关证据

中文部署与排错专题见。奇连 AI 端侧专题。

常见问题

每个失败请求都应自动重试吗?

不应如此。超时可能只是暂时故障;制品缺失、鉴权失败、完整性不符和用户取消需要不同操作。先判断事件类型,再决定下一次请求是否安全。

WorkManager 重试会自动续传文件字节吗?

不会自动保证。任务调度和字节续传是两层逻辑;传输实现仍需验证制品身份、服务器范围响应和持久化偏移,确认安全后才能追加。

摘要校验失败后的安全处理是什么?

不要把候选文件提升为活动模型。拒绝或隔离该制品、保留无关用户数据、显示可修复错误,并且仅按应用明确策略获取可信替代文件。

用户取消以后还能自动重试吗?

对同一任务身份不能。取消应成为该次操作的终止结果。只有用户再次主动发起,或产品中明确记录的其他事件,才能创建新尝试。