管道显示"一切正常",智能体却在自信地答错:企业文档摄取中被静默丢弃的那一层含义

上周读到一篇 Amazon 的论文(arXiv:2610.30026),看完之后我后背有点发凉。

你有没有想过这样一个问题:你们公司部署的 AI 智能体,每天要读几百份 Word 政策文档——合规手册、SOP、采购条款。文档进系统之前,要先经过一道"摄取层",把 .docx 转成纯文本喂给模型。这一步所有监控都显示成功,文本看起来完完整整,智能体回答起来流畅自信。

但答案是错的。而且错得毫无痕迹。

这篇论文干的事,就是把这条裂缝撬开给你看:作者写在文档格式里的那层含义——红色字、黄色高亮——在摄取层被静默丢弃了,而下游没有任何一个环节会报警。

核心摘要:企业智能体读文档前必须由摄取层把 Word/PDF 转成 token,主流转换器(docling、纯文本提取)能忠实恢复文字和表格,却把作者用颜色和高亮编码的"请特别注意这一条"全部扔掉。结果是模型不是少说,而是多说——假阳性率涨 4 倍,自信地把没标记的条款也当成关键需求。在 76 份真实政策文档上,格式盲摄取把 micro F1 从 0.690 打到 0.150(docling)和 0.075(纯文本),这个差距在两家厂商的 6 个模型上全部复现。作者的修复方案是纯代码、零 LLM 调用的解析层,把格式线索序列化成混合 Markdown+自定义标签。这不是底层模型突破,但它戳中的是企业 RAG 落地里一个真实、普遍、且被严重低估的坑——值得每个做文档智能的人细读。

论文信息

  • 标题:What the Author Wrote, What the Agent Reads: Silent Cue Loss in Enterprise Document Ingestion
  • 作者:Yikai Zhao、Saurabh Pandey、Pradeep Kumar Misra(均为 Amazon)
  • 链接:https://arxiv.org/abs/2610.30026 (2026 年 10 月 21 日)

🎯 这个坑到底有多普遍

先说一个数字。作者扫了 6,462 份真实的公共政策文档,发现 32.8% 的文档里有作者刻意加的颜色或高亮标记,10.3% 的文档在"义务性句子"(shall/must 这类约束句)上带标记。还有 2.6% 的文档,标记只藏在正文遍历够不着的地方——页眉、页脚、脚注、批注。

这不是对抗性的边缘案例,是日常。

作者写文档的时候,红色字是"禁令",黄色高亮是"注意这里",删除线是"这条已经被新条款取代"。这些视觉线索对人来说是空气一样的存在,你不会意识到自己在依赖它,直到它消失。而摄取层恰恰就是让它消失的那个环节——主流转换器恢复文本、恢复表格、恢复标题层级,唯独不恢复颜色。docling 不保留,ParseBench 这类解析基准甚至不评分颜色这个维度。

问题就埋在这:格式丢了,文本还在,所以没有任何监控会觉得异常。智能体拿到的上下文看起来是完整的,它不会拒答,不会说"我不确定"——它会流畅地给出错误答案。

说实话,这个失败模式比"模型幻觉"更让我警惕。幻觉至少还有不确定性信号可循,而这里的模型是确定性地错。


🧪 实验设计:一个干净得少见的评测

在讲方法之前,先说说这个评测做得有多扎实,因为它直接决定了结论的可信度。

任务设计得很朴素:"列出本文档中作者单独标记为需要特别注意的每一条需求"。 Ground truth 不靠人标注,直接从文档自己的 OOXML run 属性里取——作者在 Word 里标的红字,XML 里写得明明白白。他们还做了交叉验证:用渲染后的页面图像独立核对,Cohen's κ 达到 0.72,说明机器取的标签和人眼看到的基本一致。

评分也是确定性的:答案里出现 gold 需求开头连续 4 个实词就算命中,没有 LLM judge。332 条 gold 里只有 1 条不足 4 个实词,召回上限 0.997。

作者还顺手测了"格式盲方法的上限"——训练一个监督文本分类器(TF-IDF + 逻辑回归),在完全看不到格式的情况下,模型能不能从措辞猜出哪些句子被标记了?ROC AUC 只有 0.664。紧迫关键词规则 0.508,句长特征 0.492——基本等于瞎猜。

这个数字很关键:作者标不标记一条需求,写在格式里,而不是写在措辞里。 格式丢了,这个信息就是真的丢了,再强的语言模型也猜不回来。


📊 主实验:0.690 对 0.075

主实验对比六个 arm,76 份文档,3 次重复,1,368 次调用,主模型是 Claude Opus 4.6(temperature 0)。结果是这张表:

摄取方法 micro F1 精度 假阳性率 与本文方法的 Δ macro F1 p 值
本文方法 0.690 0.824 0.011 — —
本文方法(仅显著性角色) 0.687 0.834 0.010 −0.005 1.00
本文方法(无类型化标记) 0.605 0.811 0.010 +0.092 0.025
docx2python(最强 baseline) 0.586 0.797 0.010 +0.110 0.022
docling 0.150 0.196 0.043 +0.578 <10⁻⁴
纯文本 0.075 0.437 0.005 +0.689 <10⁻⁴

几个值得停下来看的点。

纯文本 0.075,docling 0.150。本文方法 0.690。差距分别是 +0.689 和 +0.578,p 值小于万分之一,在 76 份文档里分别赢了 62 份和 57 份。这个不是边际改进,是可答与不可答的区别。

但真正该盯住的是失败的方向。docling 的假阳性率是 0.043,约为本文方法 0.011 的 4 倍。也就是说,丢了格式线索之后,模型不是变得更保守、答得更少——恰恰相反,它把没被作者标记的需求也一堆一堆地报成"关键条款"。

对智能体自主性来说,这是最危险的失败方向。漏报你还有机会兜底,过度断言会直接污染下游所有决策。

这里我得说一句公道话:docx2python 作为最强 baseline 拿到 0.586,其实不算差——它好歹保留了部分字符格式。但距离 0.690 仍有统计显著的差距(p=0.022),说明"保留一部分格式"和"把格式翻译成模型能用的语义信号"之间,还有一层关键工作要做。


🏗️ 方法:把格式当信号,不当装饰

作者的三阶段流水线里,真正的贡献在 Stage 1。

图3:三阶段流水线总览

图3:三阶段流水线。Stage 1(Parse & Annotate,本文核心)用纯代码恢复字符级格式——包括正文遍历够不着的页眉页脚、脚注、修订记录、公式——并序列化成混合 Markdown+标签格式;Stage 2 按文档大小自动分层(小于 25K token 单次调用,到 50K 加忠实性验证,更大则分块加二元层次合并,N≤16 段需 2N−1 次调用),虚线是处理嵌入图表的并行视觉通道;Stage 3 把类型化实体路由进五文件的渐进式披露包。

Stage 1 的一个硬约束让我很喜欢:纯代码,零 LLM 调用。 用 python-docx 读 OOXML,把每段格式相同的连续文本切成 FormattingSpan(不可变记录,12 个属性),然后用 11 条高置信度的"格式→语义"映射规则附加 SemanticRole。

序列化用的是混合协议:Markdown 能表达的(粗体、斜体、删除线)就用 Markdown,表达不了的(颜色、高亮)用自定义标签,文档级元数据(标题层级、表格结构)用结构标签:

**key term**          ← 粗体,Markdown 原生
[COLOR:red]text[/COLOR]        ← 红色文本
[HIGHLIGHT:yellow]text[/HIGHLIGHT]   ← 高亮
[PARAGRAPH roles="CRITICAL_WARNING"] ← 块级角色

混合方案比纯自定义标签省 15–20% 的 token——粗体用 ** 两个字节搞定,没必要包一层标签。

11 条映射规则里挑几条有意思的:

Word 属性 消歧规则 语义角色 抽取信号
部分 span 加粗 块内仅部分加粗 Key_Term 定义性术语
全粗独立短行 单行且不足 200 字符 Implicit_Heading 隐式小节边界
红色文本 模糊阈值判定 Critical_Warning 关键禁令,CRITICAL 严重度
非白色高亮 存在即触发,红色高亮升级 Warning 警示声明,MAJOR 严重度
删除线 精确属性 Deprecated 已被取代的政策值
等宽字体 字体名匹配已知集合 Code_or_Literal 逐字保留的标识符

有几处工程细节能看出作者是真踩过坑的。

红色的判定公式是 is_red(r,g,b) = (r>180) ∧ (g<80) ∧ (b<80) 再加一个已知红色 hex 集合——看起来很周全,但实测 99.7% 的红色 span 恰好就是纯红 #FF0000,那个精心设计的容差基本没派上用场。作者很坦诚地把这一点写进了论文。

影响最大的修正来自高亮。原规则只认黄色高亮,一量语料发现青色、浅灰高亮也很常见,改成"除白色/无以外任何高亮都算 warning"之后,作者标记段落获得显著性角色的比例从 79.1% 跳到 97.6%——这是全文对结果影响最大的单一修正。

还有一个克制的设计:中置信度规则(比如绿色→状态标记)被整体排除。理由很直白——错误的提示比没有提示更糟。这种"宁可少说"的态度在充斥着过度设计的论文里挺难得的。

修订记录的处理也值得一提。OOXML 里被删除的文本是 w:del 里嵌套 w:r 携带 w:delText,python-docx 的朴素遍历根本够不着。修正后:插入的内容是当前生效文本,删除的内容映射到 strikethrough 语义("作者已废弃")。纯文本摄取在 28 条修订里有 16 例完全丢值、3 例只浮现被取代的旧值——后者是赤裸裸的事实错误。


🔬 消融:整个效应只有两个字——颜色和高亮

这是全文我觉得最漂亮的一个实验。逐线索留一消融:每次从 span 级精确移除一类线索,看 macro F1 掉多少。

  • 高亮:掉 0.302(p < 10⁻⁵)
  • 颜色:掉 0.262(p = 2×10⁻⁵)
  • 粗体、斜体、等宽、删除线:各自在 ±0.003 以内,置信区间跨零

粗体没贡献不是因为稀少——单文档可以有上千个粗体标记——而是因为太常见以致没有信息量。真正承载含义的线索只有颜色和高亮这两个,而这两个恰恰是主流转换器最不关心的。

消融还是线索特异性的:移除颜色,带颜色标记的文档从 0.699 崩到 0.214,带高亮标记的文档纹丝不动(0.694);移除高亮则完全镜像(0.659 掉到 0.128,颜色文档不变)。这说明映射规则没有把不同线索的贡献搅在一起,归归因是干净的。


🤔 预注册的关键问题:只保留线索够不够?

作者还预注册了一个确认性测试,回答一个挺微妙的问题:把线索保留下来就够了,还是必须告诉模型这个线索的含义是什么?

对比一下两个 arm:untyped(只有 [COLOR:red] 这种原始标记)和 typed(额外附加 CRITICAL_WARNING 语义角色)。79 份文档,6 次重复,1,422 次调用:

Arm micro F1 假阳性率 Δ p_Holm
typed(仅显著性角色) 0.667 0.010 — —
untyped 0.597 0.009 +0.085 0.049

typed 胜出,13 胜 4 负 62 平,置信区间 [+0.035, +0.145]。

这和已有文献能对上:PASTA 那篇报告说强调标记能带来 22% 的平均提升,而 Dillitzer 等人的工作观察到"注意力—性能背离"——模型确实会多看被强调的文本几眼,但准确率未必跟着涨。这篇论文给出的解释是:原始标记只解决"看到",类型化角色才解决"看懂"。

不过 typed 层有两个诚实的注脚。一是作者修复了一个解析器 bug(表格渲染器给黑色文本误发 [COLOR:#000000]),修复前后效应量几乎不变(+0.084 → +0.085),但 p 值从 0.005 变差到 0.049——结论存活,但只是勉强。二是 typed 的提升只在 6 个模型中的 3 个上稳健复现。


🌐 跨模型复现:失败是表示层的属性,不是模型的属性

作者把实验铺到两家厂商的 6 个模型上(Claude Opus 4.6 / Sonnet 4.6 / Haiku 4.5 / Opus 5 / Sonnet 5 + OpenAI GPT-5.6-terra):

模型 本文方法 untyped docx2python 纯文本
Claude Opus 4.6 0.687 0.605 0.586 0.075
Claude Haiku 4.5 0.629 0.531 0.499 0.048
Claude Sonnet 4.6 0.615 0.577 0.544 0.007
GPT-5.6-terra 0.534 0.468 0.510 0.045
Claude Opus 5 0.358 0.346 0.263 0.068
Claude Sonnet 5 0.164 0.173 0.180 0.018

纯文本在所有模型上全部崩塌(0.007–0.075)。这证明失败是表示层的属性——换更强的模型救不回来,因为信息根本没进上下文。

有个细节挺有意思:没有 typing 收益的两个模型,恰好是几乎不尝试任务的模型。Claude Sonnet 5 召回只有 0.09、精度 0.96——极端弃答。同一个缺失的线索,在 Opus 4.6 上表现为过度标记(假阳性泛滥),在 Sonnet 5 上表现为极端保守。病理方向相反,病根是同一个。

外部验证方面,作者在 Microsoft OCB 基准(326 项、59 文档)上把总分推到 0.959,对比 docx2python 的 0.810、docling 的 0.720、纯文本的 0.634。Metadata、Comment、Footnote 这三个特征上,所有 baseline 都是 0 分,本文方法是满分——因为这些内容本来就住在正文遍历够不着的地方。唯一的败项是 Highlight 单项输给 docx2python(0.889 对 1.000),作者如实报告了。

PDF 侧在 ParseBench 的 126 条格式规则上,与最强 PDF baseline(pymupdf4llm)总恢复数打平(65/126),唯一显著差异在高亮:11/18 对 4/18(McNemar p=0.039)。纯文本定位了 107/126 的目标文本,但恢复的线索数是 0——这个对照实在太有说服力了。


🔧 下游流水线:差距不在内容丢失,在"标记"丢失

完整三阶段流水线(抽取 + 渲染成五文件渐进式披露包)的对照也很有信息量。68 份文档上:本文方法 micro F1 0.503,docx2python 0.258,docling 0.084。

关键在于三个 arm 的 gold 需求文本保留率几乎一样(0.665 / 0.634 / 0.607)。也就是说,内容大家都抽出来了——差距只在于:只有本文的包还记录着"哪几条需求是作者标过的"。被标记需求进入 quick-reference 文件的比率是 0.569,未标记的只有 0.245,2.3 倍的富集。

渐进式披露包里的忠实性验证环节也做得比较克制:

图5:忠实性验证流程

图5:忠实性验证流程。随机抽 20% 实体(上限 80 个),用 Opus 4.6 对照 source quote 逐字段打分(0–3 分):3 分保留、2 分标记、1 分和 0 分降级为低置信度——但 0 分不丢弃,避免截断导致的假阳性损失;引用被降级实体的关系也同步更新。

嵌入图表走单独的视觉通道,单次 vision 调用同时做分类和抽取:

图4:图表理解协议

图4:单趟图表理解协议。把上下文(caption、标题路径、相邻段落)和图片一起喂给一次 vision 调用,同时完成图表分类与实体抽取;装饰性图片提前跳过。流程图映射为 PROCEDURE,决策树映射为 DECISION_POINT,组织架构图和矩阵映射为 ENUMERATION,时间线映射为 TIMELINE,数据图表映射为 METRIC。


💡 我的判断

这篇论文不是那种让人惊呼" paradigm shift "的工作,它更像一记扎实的闷棍,打在企业 AI 落地的一个真实软肋上。

亮点有三个。 一是问题定义得好。"静默失败"这个切入点比"提升解析准确率"高级——它指出了一个被所有人忽视的监控盲区:管道每一环都健康,最终答案却是错的。二是评测方法论干净。OOXML 属性当 ground truth、确定性评分、预注册假设检验、跨模型复现、外部基准交叉验证,这套组合拳在 LLM 论文里属于少见的严谨。三是消融的归因干净——整个效应定位到颜色和高亮两个线索,不多不少。

局限也得说清楚。 typed 相对 untyped 的优势 p 值只有 0.049,而且只在 6 个模型中的 3 个上稳健复现——"语义类型化"这一步的价值我认为还没被完全坐实。表示成本是纯文本的两倍 token,这在长文档上是实打实的钱。ground truth 终究是机器从 OOXML 自动派生的,κ=0.72 的交叉验证不错但不是人工标注。另外任务召回上限被评分规则卡在 0.997、实际召回 0.60,任务没饱和,headroom 还有不少。

还有一个我自己没完全想明白的点:本文方法说到底就是把"格式→语义"的映射硬编码进了 11 条规则里。企业文档的格式约定千奇百怪——有的公司用紫色表示待审批,有的用高亮表示"已确认"而非"待注意"。这套规则在新组织里泛化时,需要多少定制成本?论文里"只保留高置信度映射"的策略是对的,但也意味着中低频的约定全部丢掉了。

对工程的启发很直接:如果你在搭企业 RAG 或文档智能体,去测一下你的摄取层保不保留颜色和高亮。大概率不保留。然后抽样看看你的文档库里有多大比例的文档在用这两个线索——如果接近这篇论文测到的三分之一,那你可能一直在裸奔。修复成本不高:Stage 1 是纯代码,零 LLM 调用,token 翻倍的代价换事实性,这笔账怎么算都值。

往大了说,这篇论文戳的是"上下文工程"的一个元问题:模型只能读到表示层允许它读到的东西。 我们花了那么多精力调 prompt、调解码参数,却很少审计"信息进上下文之前"发生了什么。这个审计环节,迟早会成为企业智能体系统的标配质检项。


觉得有启发的话,欢迎点赞、在看、转发。跟进最新AI前沿,关注我