
这类问题的关键不是再给文件名改一个“更 SEO”的名字而是给文档补上一层可检索的语义接口一句话摘要告诉系统“它总体讲什么”关键词提供稳定术语锚点可回答问题则把文档语言映射成用户更可能使用的问法。参考企业案例中团队为文档生成摘要、技术术语和若干可回答问题再把这些字段用于检索增强。案例中的规模和效果数字属于原作者这篇只讨论可以被验证的机制、Java 实现和质量控制不把案例数据当成我们的实测结果。一、物理元数据与语义元数据一份文件天然带有不少元数据filename 数据采集通讯模块使用说明.docx path /archive/manual/v3/ author 张三 updated 2025-11-03这些字段回答的是“文件是谁、放在哪里、何时更新”属于物理元数据。它们对权限、版本、过滤和审计非常重要但不一定能回答“文件能解决什么问题”。语义元数据面向检索summary 介绍 MQTT 采集通道、心跳、重连和认证参数的配置方法 keywords [MQTT, 心跳, 重连, TLS, 采集通道] questions [ MQTT 设备如何设置心跳间隔 连接断开后如何配置自动重连 MQTT 通道如何启用 TLS 认证 ]物理元数据与语义元数据不是替代关系。前者负责范围和约束后者负责发现和匹配。生产检索通常需要二者共同参与先用租户、权限、版本等物理字段过滤再用正文和语义字段计算相关性。二、三类语义字段分别解决什么问题摘要为长文档建立稳定入口摘要压缩整篇文档的主题适合解决标题过宽、正文过长的问题。它应该包含文档对象、核心任务和边界而不是生成一句空泛的“本文介绍了相关配置方法”。好的摘要说明 MQTT 采集通道的连接参数、心跳与自动重连策略以及 TLS 双向认证配置不包含 Broker 部署教程。这里最后一句边界也很重要。没有边界的摘要会让文档在更多无关问题中被召回。关键词为术语和精确检索提供锚点关键词适合保存产品名、协议名、错误码、配置项和领域术语。它们不应该只是摘要里出现频率最高的普通词。例如“配置”“系统”“使用”几乎没有区分度keepAliveSeconds、TLS、QoS、自动重连才是能帮助检索和过滤的术语。可回答问题缩短“用户问法”和“文档写法”的距离文档通常使用陈述句和章节标题用户则使用疑问句。预生成可回答问题相当于为每份文档建立几个面向用户语言的入口。它最适合以下场景标题使用内部术语用户使用业务口语一个文档覆盖多个具体任务关键答案只占长文档中的一小节用户问题经常以“怎么配”“为什么失败”“是否支持”出现。但问题列表不是越多越好。如果给每份文档生成几十个宽泛问题不同文档会共享大量相似问法反而造成召回污染。三、设计一个可版本化的 Metadata Schema语义元数据不是塞进一个MapString, Object就结束。至少要记录生成来源、模型、提示词版本和内容版本否则以后很难回答“这个关键词是谁生成的”“模型升级后哪些文档需要重跑”。publicrecordSemanticMetadata(StringdocumentId,StringsourceHash,Stringsummary,ListStringkeywords,ListStringanswerableQuestions,StringmodelId,StringpromptVersion,StringschemaVersion,InstantgeneratedAt,MetadataStatusstatus,ListStringwarnings){}推荐使用下面的幂等键idempotencyKey SHA-256( sourceHash modelId promptVersion schemaVersion )源文档没有变化、模型和提示词也没有变化时批任务可以直接复用结果任何一项变化都能明确触发重新生成而不是凭更新时间猜测。字段本身也要有约束字段建议约束主要风险summary1–3 句包含主题与边界空泛、过度推断keywords5–10 个去重并规范大小写普通词、同义词堆积answerableQuestions3–6 个必须能由原文回答生成原文不存在的问题warnings保存缺少上下文、内容过短等问题静默接受低质量结果四、用 Spring AI 构建增强流水线Spring AI 的 ETL 把文档处理拆为 Reader、Transformer 和 Writer。官方还提供KeywordMetadataEnricher与SummaryMetadataEnricher说明元数据增强本身就是一个转换步骤而不是检索时临时拼接的字符串。如果需要同时输出摘要、关键词和问题列表最好使用结构化输出让模型响应能够直接映射为 Java 类型publicrecordEnrichmentResult(Stringsummary,ListStringkeywords,ListStringanswerableQuestions,ListStringwarnings){}调用层的核心不是写一段特别长的 Prompt而是把输入、输出和证据边界写清楚Stringinstruction 你是企业文档检索元数据生成器。 只能依据给定文档生成结果不补充外部事实。 要求 1. summary 用 1-3 句话说明主题、任务和边界 2. keywords 输出 5-10 个有区分度的术语 3. answerableQuestions 输出 3-6 个原文能够直接回答的问题 4. 原文无法支持的内容不要生成并写入 warnings。 %s .formatted(converter.getFormat());EnrichmentResultresultchatClient.prompt().system(instruction).user(documentText).call().entity(EnrichmentResult.class);StructuredOutputConverter或BeanOutputConverter能提供结构化格式说明并完成映射但它不等于业务验证。JSON 能成功反序列化只说明格式合法不说明问题真的能由原文回答。因此增强后还要做一层确定性检查publicValidationResultvalidate(EnrichmentResultvalue,ParsedDocumentsource){varwarningsnewArrayListString();if(value.summary().length()20)warnings.add(summary_too_short);if(value.keywords().size()5)warnings.add(keywords_too_few);if(value.answerableQuestions().stream().distinct().count()!value.answerableQuestions().size()){warnings.add(duplicate_questions);}returnnewValidationResult(warnings.isEmpty(),warnings);}更严格的系统还可以增加“答案证据校验”让模型为每个问题返回原文证据片段再检查证据是否确实存在于源文档。这样能挡住“问题听起来合理但原文其实没有答案”的情况。五、批量生成必须解决的六个工程问题逐份调用模型看起来只是一个循环真正跑到成百上千份文档时会立刻遇到六个问题。1. 限流模型服务通常有请求频率和 Token 配额。并发线程数不等于可用吞吐量盲目开线程只会制造大量 429。Resilience4j RateLimiter 可以按周期发放许可把服务端限制显式写进客户端。2. 重试分类网络抖动、服务暂时不可用可以退避重试输入超长、鉴权失败、Schema 校验失败通常不应原样重试。Resilience4j Retry 支持按异常类型和结果决定是否重试也支持指数退避。RetryConfigconfigRetryConfig.custom().maxAttempts(3).intervalFunction(IntervalFunction.ofExponentialBackoff(500,2.0)).retryExceptions(IOException.class,TimeoutException.class).ignoreExceptions(InvalidDocumentException.class,AuthenticationException.class).build();3. 断点续传不要把“每处理 10 条写一次进度”当成固定答案。更稳的方式是每份文档都持久化状态PENDING/RUNNING/SUCCEEDED/FAILED/QUARANTINED批任务从未完成状态恢复。提交粒度可以批量但状态必须可追踪。4. 幂等任务重启可能让同一文档再次执行。以sourceHash 生成配置版本建唯一键写入时使用 upsert 或唯一约束避免重复记录和重复向量。5. 成本预算入库前先统计文档长度分布估算输入 Token、输出 Token 和调用次数。超长文档需要先按章节生成局部摘要再合成文档级摘要不能把所有内容直接塞给模型后祈祷不超窗。6. 可观测性至少记录模型 ID、提示词版本、输入长度、输出长度、耗时、重试次数、状态和错误类型。只保存最终摘要出了问题几乎无法排查。六、Question Metadata、HyDE 与 Query Rewrite 的边界这三个概念经常混在一起实际上发生时间和处理对象不同。Question Metadata入库时预计算它从文档生成“该文档能回答的问题”保存到索引中。查询时可以把用户问题与这些预计算问题做相似度匹配。优点是查询延迟低缺点是问题覆盖范围受入库时生成质量限制。HyDE查询时生成假设文档HyDE 原始论文的做法是根据用户查询生成一段假设文档再将这段假设文档编码用它在真实语料的向量空间中检索。论文明确指出假设文档可能含有虚构细节因此它的作用是提供检索表示不是作为最终答案证据。Query Rewrite查询时改写用户问题它把带指代、口语化或上下文不完整的问题改写成自包含问题。例如把“它的心跳怎么配”改写成“MQTT 采集通道如何配置心跳间隔”。它仍然是查询不会生成一篇假设答案文档。可以这样记Question Metadata文档 → 可能的问题离线 Query Rewrite用户问题 → 更清晰的问题在线 HyDE用户问题 → 假设文档 → 检索向量在线三者可以组合但不应该默认全部开启。Question Metadata 会增加入库成本Rewrite 和 HyDE 会增加查询延迟。是否启用必须由评测结果决定。七、如何证明增强真的有效语义元数据是否有效不能靠挑几个成功例子。先固定一组问题并标注每个问题应该命中哪些文档然后比较不同索引方案。下面只是一张评测设计示例不是本文实测数据实验组索引内容观察指标A正文Recall5、MRR、索引大小B正文 摘要Recall5、主题型问题变化C正文 关键词精确术语问题变化D正文 问题元数据用户问法差异大的问题变化E多字段加权组合总体 Recall、误召回与延迟建议把问题按类型分桶配置步骤、错误码、概念解释、版本差异、跨文档问题。总体 Recall 提升可能只来自某一类简单问题分桶后才能看出策略真正解决了什么。还要同时看副作用索引体积是否明显增加宽泛摘要是否让无关文档更容易入榜问题元数据是否出现同质化模型升级后重建成本是否可接受元数据与正文冲突时以谁为准。八、最容易踩的五个坑坑一把摘要直接拼到每个 Chunk 前面摘要语义过强可能在 Top-K 中反复霸榜把真正含答案的正文块挤出去。摘要适合作为独立字段或独立向量检索时分路召回和加权而不是无脑复制到所有块。坑二关键词只有热门普通词“系统、配置、使用、功能”看似正确实际区分度极低。应过滤停用词优先保留协议、产品、字段、错误码和动作短语。坑三生成的问题超出原文模型可能根据常识补出“这份文档应该能回答”的问题。必须要求证据或至少抽样检查问题能否在原文中定位答案。坑四混合字段却不记录来源正文、摘要、关键词和问题混成一段后检索命中时无法知道究竟是哪一部分起作用也无法单独调权重。不同字段应分别存储并在 Trace 中记录召回来源。坑五模型和 Prompt 升级没有版本没有modelId/promptVersion/schemaVersion就无法判断新旧元数据是否混用也无法安全回滚。元数据也要像代码和数据库 Schema 一样版本化。九、面试时怎么讲这个设计一个有工程含量的回答可以这样组织文件名、路径等物理元数据主要用于权限、版本和过滤不能覆盖用户问法。我在入库阶段增加摘要、领域关键词和可回答问题三个语义字段并记录模型、Prompt、Schema 与源文档 Hash。批任务通过限流、分类重试、断点状态和幂等键保证可恢复效果通过固定问题集比较正文索引与多字段索引的 RecallK同时监控误召回和索引成本。如果面试官继续追问就可以展开为什么摘要不能复制到所有 Chunk、Question Metadata 和 HyDE 有什么区别、模型输出如何验证、元数据升级如何重建。每个问题都有明确的数据结构和流程而不是停留在“调用大模型生成标签”。落地检查表物理字段与语义字段分开存储、分开追踪摘要包含主题和边界不写空泛套话关键词去重、规范化并过滤普通词每个可回答问题都有原文证据或抽检记录结构化输出还要经过业务规则验证模型、Prompt、Schema 和源文档均有版本标识批任务具有限流、分类重试、断点和隔离状态幂等键能够阻止重复生成与重复写入用固定评测集比较 RecallK、误召回、延迟和索引成本Trace 能区分命中正文、摘要、关键词还是问题字段。总结语义元数据的价值是在文档和用户之间增加一层稳定、可管理的检索接口。摘要负责主题入口关键词负责术语锚点可回答问题负责用户问法映射物理元数据则继续承担权限、版本和范围过滤。真正困难的部分不是生成三组字符串而是让它们结构化、可验证、可版本化、可批量恢复并通过评测证明收益大于成本。做到这些元数据增强才是检索系统的一部分而不是给文档贴几张看起来聪明的标签。参考资料Spring AI ETL PipelineSpring AI Structured Output ConverterResilience4j RateLimiterResilience4j RetrySpring Batch Item Processing and IdempotencyHyDE: Precise Zero-Shot Dense Retrieval without Relevance LabelsHyDE 官方代码仓库Spring AI Evaluation Testing