Checklist
🐞 问题详细描述
现象(实跑日志)
test_dyn_ext_003(内容「用户的B类签证将在2025年12月31日到期」,内联 prompt 抽取)实跑失败,异常链:
common.errors.BackendError: elasticsearch insert failed:
{'type': 'illegal_argument_exception',
'reason': 'mapper [metadata.tags] cannot be changed from type [keyword] to [date]'}
File ".../elasticsearch_fulltext.py:295, in insert
raise BackendError(f"elasticsearch insert failed: {res.get('error')}")
抽取本身成功(LLM 产出派生),落 KV 也成功,但**建全文索引(ES insert)**时:该 index 内 metadata.tags 字段先被某 document 推断为 keyword,后某 document(tags 含日期格式值)试图写成 date → ES 拒绝 → BackendError → write 失败。
根因(代码 + ES 行为)
- SUT 把 metadata 原样投影到 ES:
FulltextIndexBuilder 建 Document(id, text, metadata={tier,tags,source,...}),metadata.tags 是 LLM 抽取的主题词数组(见 S05 §IndexBuilder build 路径 / index_builder_impl/fulltext_index_builder.py)。
- ES dynamic mapping 自动推断:ES index 未显式声明
metadata.tags 的 mapping,靠 dynamic mapping 按首条 document 的值推断类型。tags 设计是 keyword(字符串数组),但当 LLM 把日期格式字符串("2025-12-31"、"12月31日"等)放进 tags 时,ES 可能把它推断为 date;同 index 内类型一旦确定(或在不同 document 间冲突),后续不一致类型被拒绝。
- LLM 抽取非确定:内容含显式日期("2025年12月31日到期")时,LLM 倾向把日期/有效期放进 tags 或 metadata → 触发 ES date 推断。
→ 内容含日期格式时,fulltext index 建索引失败(BackendError),write 整体失败。这是数据敏感(内容含日期)+ ES dynamic mapping 不稳定 + SUT 未显式锁 mapping 的组合。
截图:

影响
- 严重程度:Medium。仅当 LLM 抽取的 tags 含日期格式值时触发——内容含显式日期(截止日期、有效期、生日等)时易发。默认五接口套件用例内容多含日期(write_003 occurred_at、write_024 observation_date 等),理论上同样可能触发(取决于 LLM 是否把日期放进 tags)。
- 静默性:
BackendError 在 ES insert 时抛(elasticsearch_fulltext.py:295),KV 已落盘但索引失败 → 索引↔真源分歧(派生在 KV 但 fulltext 召不到)。与 index-degradation-silent-swallow.md 记录的"索引写失败静默吞"不同——此处是显式抛 BackendError(不吞),阻断 write。
- 可复现性:内容含显式日期 + LLM 把日期放进 tags 时稳定复现。
用例处置
- 用例处置:
ext_003(E2E,flaky):保留原内容(含显式日期)按契约断言、不改内容规避——但实测 flaky(取决于 LLM 是否把日期格式值放进 tags:第一次 fail、重跑 LLM 只放主题词时 passed)。作为 ES issue 的偶发 E2E 复现。
test_dyn_ext_009(确定性暴露型单测):用 KeywordClassifier 绕过 LlmClassifier 主题词追加 + write tags 入参纯控(首条 ["2025-12-31"] → ES date_detection 把 metadata.tags 推断为 date,第二条 ["normal_tag"] → date 字段 parse 失败)→ 按契约断言"两条 write 都应成功",实测第二条抛 BackendError → 用例 fail(暴露)。不依赖 LLM(~6s,确定性)。是 ES issue 的稳定暴露证据(红);ext_003 是其 flaky E2E 旁证。
详细的环境信息描述
windows
其他辅助信息
感谢您的贡献 🎉!
版本信息
感谢您的贡献 🎉!
感谢您的贡献 🎉!
Checklist
🐞 问题详细描述
现象(实跑日志)
test_dyn_ext_003(内容「用户的B类签证将在2025年12月31日到期」,内联 prompt 抽取)实跑失败,异常链:抽取本身成功(LLM 产出派生),落 KV 也成功,但**建全文索引(ES insert)**时:该 index 内
metadata.tags字段先被某 document 推断为keyword,后某 document(tags 含日期格式值)试图写成date→ ES 拒绝 →BackendError→write失败。根因(代码 + ES 行为)
FulltextIndexBuilder建Document(id, text, metadata={tier,tags,source,...}),metadata.tags是 LLM 抽取的主题词数组(见 S05 §IndexBuilder build 路径 /index_builder_impl/fulltext_index_builder.py)。metadata.tags的 mapping,靠 dynamic mapping 按首条 document 的值推断类型。tags设计是keyword(字符串数组),但当 LLM 把日期格式字符串("2025-12-31"、"12月31日"等)放进 tags 时,ES 可能把它推断为date;同 index 内类型一旦确定(或在不同 document 间冲突),后续不一致类型被拒绝。→ 内容含日期格式时,fulltext index 建索引失败(
BackendError),write整体失败。这是数据敏感(内容含日期)+ ES dynamic mapping 不稳定 + SUT 未显式锁 mapping 的组合。截图:
影响
BackendError在 ES insert 时抛(elasticsearch_fulltext.py:295),KV 已落盘但索引失败 → 索引↔真源分歧(派生在 KV 但 fulltext 召不到)。与index-degradation-silent-swallow.md记录的"索引写失败静默吞"不同——此处是显式抛 BackendError(不吞),阻断 write。用例处置
ext_003(E2E,flaky):保留原内容(含显式日期)按契约断言、不改内容规避——但实测 flaky(取决于 LLM 是否把日期格式值放进 tags:第一次 fail、重跑 LLM 只放主题词时 passed)。作为 ES issue 的偶发 E2E 复现。test_dyn_ext_009(确定性暴露型单测):用KeywordClassifier绕过LlmClassifier主题词追加 + write tags 入参纯控(首条["2025-12-31"]→ ESdate_detection把metadata.tags推断为 date,第二条["normal_tag"]→ date 字段 parse 失败)→ 按契约断言"两条 write 都应成功",实测第二条抛BackendError→ 用例 fail(暴露)。不依赖 LLM(~6s,确定性)。是 ES issue 的稳定暴露证据(红);ext_003 是其 flaky E2E 旁证。详细的环境信息描述
windows
其他辅助信息
感谢您的贡献 🎉!
版本信息
感谢您的贡献 🎉!
感谢您的贡献 🎉!