任务架构

为 Android 本地 AI 明确 EML MIME 解码边界

仅定义导入 EML 的消息结构与正文规范化,不评测邮件摘要、不假设邮箱集成,也不自动读取或获取附件。

审核状态: 内容已校验;中文稿供用户审核 · 2026-10-08 · Fact IDs: ANDROID-PRIVACY-01, EMAIL-MIME-INGEST-2026-10

直接回答

EML 文件是序列化的 Internet 消息,不是 UTF-8 正文文本。在任何后续本地 AI 任务之前,导入器需要解析消息结构,生成定义清楚的正文视图。本文只规定输入规范化,不评测摘要质量、不解释邮件线程含义,也不表示 Cove 有邮箱客户端。应使用固定版本、成熟的 MIME parser,而不是用字符串切分编写万能 parser。保留用户选中的源字节,并将部件和解码选择记录到单独的派生表示。 分别解析消息头和 MIME 正文部件。RFC 5322 定义 Internet 消息头/正文结构,包括折叠头部行。RFC 2047 encoded-word 用于符合条件的头部文字,不是通用正文解码机制。保留原始头部供复核,按 parser 文档解析展示值,不要用解码后的发件人或主题充当身份认证。消息可能没有 MIME 头、使用少见但合法语法,或含损坏数据;应将不支持和格式错误分类,而不是猜成另一条消息。 根据 Content-Type 和 boundary 规则遍历 MIME 部件,不能从第一个空行开始一路拼接。`multipart/alternative` 中的部件是同一内容的不同表示,按 fidelity 递增排序;应按明确产品策略选择一种支持的表示,并保留所选 part 身份。`multipart/mixed` 可以包含独立正文部件和附件。`multipart/related` 可让根正文关联内嵌资源,但本地文字任务不应抓取外部图片或静默加入每个相关对象。嵌套 multipart、缺少结束 boundary、未知 subtype 和 `message/rfc822` 都需要明确的支持行为或可见的不支持结果。 按正确顺序解码每个选中的叶子部件:先将 Content-Transfer-Encoding 解码为 octet,再按该部件声明的 charset 转成文字。Base64 和 quoted-printable 是传输编码,不是字符集。先按 charset 解码再做传输解码会损坏非 ASCII 文本;把 RFC 2047 头部编码当正文 octet 处理也不正确。若 charset 缺失、无效、不支持或与字节不相符,应保留可恢复错误或明确标记的回退方式。不能悄悄替换无法解码的字节,再把结果说成准确源文本。 正文选择必须与附件处理分开。MIME 头中的文件名不证明附件已解析;HTML 替代正文也不授权抓取 URL 或执行标记。如果产品只支持 text/plain,应在明确策略允许时选择该部件,否则展示支持的备选并请用户选择。若另一个 parser 将 HTML 转为文字,应同时显示这项转换策略和来源 part。不能因为附件、内嵌图片、日历部件或嵌套消息存在于 MIME 树里,就把它们拼进邮件正文。 在多个阶段设置限制:原始消息字节、头部、MIME 嵌套、部件数、编码输入、解码后 octet 和最终文本。Base64 是传输编码而非压缩,其线上的编码表示通常比解码出的 octet 更大;解码文本、临时副本和深层 multipart 遍历仍需独立内存与工作量上限。缺失声明也有标准默认值:未给 Content-Type 时默认 text/plain 和 US-ASCII,未给 Content-Transfer-Encoding 时默认 7bit。记录何时使用标准默认值,不把它说成发件人显式声明;不支持的已声明字符集或不相容字节仍是独立错误。正文规范化不自动解包或 OCR 附件,区分损坏输入、不支持编码和合法空正文,并在操作安全结束后关闭自有流。 用具有独立预期结果的合成消息测试:纯文本、plain/HTML alternative、mixed 附件、related 内嵌引用、嵌套 multipart、折叠头部、RFC 2047 主题、quoted-printable、Base64 UTF-8、另一种支持的 charset、损坏编码、缺失 boundary、超大输入和空正文。断言正文的 MIME 路径、声明 media type、传输编码、字符集、输出状态和附件排除状态。保留原始源供用户比较,不记录私人邮件内容,并把结论限制到固定 parser 和已测夹具。

用户选择的 EML 同时含纯文本和 HTML 替代正文

Android 用户选择一封导出的消息,其中含 multipart/alternative、quoted-printable 纯文本、Base64 UTF-8 HTML 正文和一个内嵌图片引用。模型任务需要可读正文,但不能吞入附件树或抓取图片 URL。

决策

使用选定的 MIME library,按明确策略选择一种支持的正文表示,先解码传输字节再解码字符集,并保留 part 路径。

预期结果

派生文字视图可供复核且链接到确切源部件;内嵌资源与附件保持未处理,除非另有独立功能处理。

需要收集的证据

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

  • EMAIL-MIME-INGEST-2026-10:RFC 5322/MIME 部件、传输编码与字符集需要分层解析并保留来源。
  • ANDROID-PRIVACY-01:应用负责内容访问、存储和用户控制。
  • RFC 5322、2045、2046、2047 分别定义消息、MIME 正文编码、multipart 结构和头部 encoded-word。

任务质量需要有版本记录的语料和验收规则;流畅的单条样例不等于准确度结果。

实施流程

  1. 定义 EML 输入契约. 只接受用户选择的邮件文件,确定 parser/provider 与版本并保留原始字节。不暗示读取邮箱或自动解析附件。
  2. 解析头部与 MIME 结构. 使用懂标准的 library 处理折叠头部、encoded-word、boundary、嵌套部件和 `message/rfc822`。记录不支持语法,不要靠字符串拆分重建结构。
  3. 明确选定一种正文视图. 按文档化 `multipart/alternative` 策略选择,保留 selected part 身份;把 mixed 附件、related 资源和嵌套消息与正文分开。
  4. 先解码字节,再转换字符. 先应用每个叶子部件的传输编码,再用声明 charset。对缺失/不支持 charset 与损坏传输数据分别记录,不要混同为合法空正文。
  5. 限制资源并验证来源. 限制原始/解码大小、头部、嵌套和部件数量。测试合成夹具,保持源不变,记录 MIME 路径但不记录私人内容。

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

验收标准

  • 导入记录 parser/provider 版本、选中的 MIME part 路径、media type、传输编码、字符集和规范化结果。
  • multipart/alternative 按明确策略选一种表示;附件、related 资源及嵌套消息不会被盲目拼接或抓取。
  • 先做传输解码再做字符集解码,并区分合法空内容、不支持编码、格式错误和超限拒绝。
  • 原始 EML 保持不变,常规日志不含私人正文;不声称存在邮件摘要或邮箱集成功能。

决策对照表

维度选择或证据解读方式
RFC 5322 消息头解析头部语法与正文分隔符。头部展开和 RFC 2047 展示解码与正文部件解码是不同阶段。
multipart/alternative按产品策略选择一种受支持的等价正文表示。这些部件是替代版本,不是应拼接的独立段落。
multipart/mixed 或 related分别保留正文、附件和内嵌资源。部件引用不证明内容已解码,也不授权外部获取。
传输编码与字符集先将 Content-Transfer-Encoding 转成 octet,再应用声明 charset。两者是不同转换层,不能颠倒顺序或混为一谈。

需要避免的失败模式

  • 不要将全部 MIME text part 直接拼接,或把附件/内嵌资源当作正文。
  • 不要把 RFC 2047 头部 encoded-word 当作正文编码。
  • 传输解码后再按声明字符集解码;不要在解码失败时伪装成精确原文。
  • 不要自动抓取 HTML 图片链接,也不要声称 Cove 有邮箱客户端或 EML 导入功能。

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

最小复现记录

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

发布检查表

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

来源与相关证据

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

常见问题

导入器能否拼接每个 MIME text 部件?

不能。alternative 部件是同一内容的不同表示,mixed 部件则可能是附件。按声明策略选择一种受支持的正文,并保留其来源 part 身份。

应该先转成文字,再解码 quoted-printable 或 Base64 吗?

不应如此。先将 Content-Transfer-Encoding 解码为 octet,再应用部件 charset。若任一编码损坏或不支持,应记录不同的错误状态。

HTML 正文是否授权抓取图片 URL?

没有。MIME parser 会暴露引用和部件,但不授权网络获取。除非另有独立功能与同意策略明确处理,否则保持外部资源未请求状态。

空正文与解码失败是同一种状态吗?

不是。要将合法空部件与损坏传输数据、不支持字符集、缺 boundary、parser 失败和超限拒绝分别记录,避免后续处理掩盖差异。