作者来自 Elastic Mike PellegriniSemantic 字段会在摄取阶段将图像、音频、视频、PDF 和文本转换为多模态 embedding。你可以通过描述一个场景来找到对应的图片也可以使用视频中的一帧来检索相关的视频片段而这一切都只需依赖 Elasticsearch 中的一个字段即可完成。Elasticsearch 中的多模态搜索如今与文本搜索拥有相同的使用方式定义一个字段、索引内容然后执行查询即可。semantic字段会在摄取阶段自动为图像、音频、视频和 PDF 生成 embedding。所有模态都会映射到同一个共享的向量空间因此你可以使用文本描述检索图片使用一句话匹配相关音频使用视频中的一帧查找相关视频而这一切都只需依赖同一个字段即可完成。该功能作为技术预览版Tech Preview在 Elasticsearch 9.5 和 Serverless 中提供。技术预览功能可能会发生变化并且不受正式发布GA功能支持 SLA 的覆盖。调色板逐渐成形Elasticsearch 中的多模态搜索如何从semantic_text演进而来semantic字段融合了过去几年我们推出的多项互补功能将它们整合为一致的多模态搜索体验。这些功能各自解决了语义搜索中的一个重要问题而结合在一起之后便实现了原生的多模态搜索。第一笔来自semantic_text。在它出现之前实现语义搜索通常需要手动配置 mapping配置带有 ML 模型的 ingest pipeline手动对内容进行 chunk自行生成查询时的 embedding。semantic_text字段将这些复杂工作全部封装起来在摄取阶段自动执行 inference自动对长文档进行 chunk简化针对该字段编写的查询。semantic_text于 Elasticsearch 8.15 首次推出并于 Elasticsearch 8.18 正式发布如今已经成为平台语义搜索的基础。随后我们推出了支撑多模态搜索的模型。jina-embeddings-v5-omni是一系列多模态 embedding 模型能够将文本图像视频音频PDF统一编码到同一个向量空间中。由于不同模态生成的 embedding 在语义空间中彼此兼容因此可以将各种媒体存储在同一个索引中并跨所有内容进行统一检索。例如使用文本描述检索图片使用书面短语匹配音频而无需为每一种内容类型分别维护一套独立的处理 pipeline。有关这些 embedding 如何生成的更多信息请参阅模型文档。随后我们在 Elasticsearch 9.4 中引入了embedding query vector builder用于在查询阶段处理多模态输入。Query vector builder 是一种通用工具可在请求执行过程中将输入转换为向量。例如text_embeddingquery vector builder 用于仅支持文本的模型和文本输入lookupquery vector builder 用于从已有文档中获取向量。而新的embeddingquery vector builder 则专门面向多模态模型设计可接受多模态输入包括文本Base64 编码的二进制内容。因此你可以使用最适合当前场景的输入模态发起查询而 Elasticsearch 会在查询时自动生成对应的向量。最后补齐的一块拼图是多模态摄取。semantic_text将自动生成 embedding 的能力带到了文本而semantic字段则将这种自动化体验扩展到了图像音频视频PDF。从内容摄取到查询整个过程都可以自动完成。绘制第一幅图使用semantic字段创建索引下面创建一个包含semantic字段的索引。操作非常简单只需将字段类型设置为semantic并指定希望使用的 inference endpoint 即可。PUT example-index { mappings: { properties: { my_semantic_field: { type: semantic, inference_id: .jina-embeddings-v5-omni-small } } } }在本示例中我们使用.jina-embeddings-v5-omni-smallinference endpoint。这是我们内置的jina-embeddings-v5-omniinference service在所有能够访问Elastic Inference ServiceEIS的环境中均可使用包括ServerlessElastic Cloud HostedECH启用了Cloud Connected ModeCCM的 self-managed 部署semantic字段需要使用一个采用embeddingtask type 的inference endpoint因为embeddingtask type 专门用于多模态模型。semantic字段并不是用来替代semantic_text。在以下场景中仍应继续使用semantic_text字段值仅包含文本。使用text_embedding或sparse_embeddingtask type。关于何时应使用semantic而不是semantic_text请参阅相关文档。索引图像、音频、视频和 PDF要索引图像只需提供一个对象其中type设置为imagevalue包含采用Base64 编码的 Data URL格式的图像内容。PUT example-index/_doc/example_doc_1 { my_semantic_field: { type: image, value: data:image/jpeg;base64,base64-encoded-image-bytes } }也支持对象数组因此可以在同一个字段值中索引多张图片。PUT example-index/_doc/example_doc_2 { my_semantic_field: [ { type: image, value: data:image/jpeg;base64,base64-encoded-image-bytes }, { type: image, value: data:image/jpeg;base64,base64-encoded-image-bytes } ] }semantic字段也支持文本值与semantic_text一样。你既可以单独提供文本值也可以将文本值与图片值混合存储在同一个字段中PUT example-index/_doc/example_doc_3 { my_semantic_field: a cat on a windowsill } PUT example-index/_doc/example_doc_4 { my_semantic_field: [ a cat on a windowsill, { type: image, value: data:image/jpeg;base64,base64-encoded-image-bytes }, a dog running in a park ] }文本值的处理方式与semantic_text完全一致较长的文本会根据 inference service 或字段 mapping 中配置的 chunking 设置 自动进行 chunk。而图像等多模态内容则不会进行 chunk。每个多模态内容都会作为一个独立的 chunk 进行表示。semantic字段还支持其他模态只需将type的值设置为对应的内容类型即可。目前支持的类型包括imageaudiovideopdf例如要索引一个视频请求如下PUT example-index/_doc/example_doc_5 { my_semantic_field: { type: video, value: data:video/mp4;base64,base64-encoded-video-bytes } }不同模型支持的模态类型有所不同。jina-embeddings-v5-omni模型支持上述列出的所有模态。请查阅你所使用模型的文档以确定该模型支持哪些模态。使用文本查询进行图像搜索和跨模态检索要通过文本描述查找多模态内容可以在semantic字段上执行match查询GET example-index/_search { query: { match: { my_semantic_field: a cat on a windowsill } } }与semantic_text一样Elasticsearch 会自动使用该字段关联的 inference endpoint 为查询文本生成 embedding。随后Elasticsearch 会使用该查询 embedding 返回语义上相似的匹配结果。这种查询方式让文本到图像text-to-image搜索变得非常简单只需索引一张图片然后使用match查询就可以通过文本描述检索该图片它同样适用于其他模态索引多模态输入使用描述性文本进行搜索检索相关内容。使用图像、视频和其他多模态输入进行查询我们也可以使用多模态输入进行搜索方法是在knn查询中使用embeddingquery vector builder。例如我们可以使用一张图片进行搜索GET example-index/_search { query: { knn: { field: my_semantic_field, query_vector_builder: { embedding: { input: { type: image, value: data:image/jpeg;base64,base64-encoded-image-bytes } } } } } }input对象的格式与索引图像时提供的格式相同将type设置为image将value设置为 Base64 编码的 data URL。与使用文本描述进行查询类似Elasticsearch 会自动使用该字段关联的 inference endpoint 为查询图像生成 embedding。随后Elasticsearch 会使用该查询 embedding 返回语义上相似的匹配结果。与索引时一样其他模态也受到支持但仅限于你的 inference endpoint 所支持的模态类型。例如使用视频片段进行搜索时请求如下GET example-index/_search { query: { knn: { field: my_semantic_field, query_vector_builder: { embedding: { input: { type: video, value: data:video/mp4;base64,base64-encoded-video-bytes } } } } } }扩展组合能力高亮、retrievers 以及其他 semantic 字段功能semantic字段并不是从零开始构建的。它建立在与semantic_text相同的基础之上继承了semantic_text的行为方式和易用性并将这些能力扩展到了多模态内容。实际上这意味着你之前使用semantic_text时掌握的大部分内容都可以直接迁移过来。如果你之前已经使用过semantic_text那么semantic字段会让你感到非常熟悉。下面列出了一些可以直接使用的功能。完整列表请参阅相关文档。高亮最佳匹配的 chunk如果你在semantic字段中索引了多个值可能希望知道哪个值与查询的匹配程度最高semantichighlighter 可以用于返回最相关的 chunk 作为高亮片段GET example-index/_search { query: { match: { my_semantic_field: a cat on a windowsill } }, highlight: { fields: { my_semantic_field: { number_of_fragments: 2, order: score } } } }将order设置为score会按照相关性对返回的 fragments 进行排序而number_of_fragments用于限制返回的 chunk 数量。响应如下{ hits: { hits: [ { _index: example-index, _id: example_doc_4, _source: {...}, highlight: { my_semantic_field: [ a cat on a windowsill, data:image/jpeg;base64,base64-encoded-image-bytes ] } } ] } }注意经过高亮的多模态值会使用其 data URL 形式进行表示。使用 index options 控制向量量化semantic字段会将其 embedding 存储在底层的 vector 字段中而index_options可以用于控制该向量字段的索引方式。例如可以选择非默认的量化策略PUT example-index { mappings: { properties: { my_semantic_field: { type: semantic, inference_id: .jina-embeddings-v5-omni-small, index_options: { dense_vector: { type: int8_hnsw } } } } } }Multi-field retrieverssemantic字段支持linear和rrfretrievers 所支持的multi-field query format。你无需为每个字段手动编写一个 inner retriever只需提供一个统一的query以及一个fields列表即可同时可以自由混合 lexical 字段和 semantic 字段GET example-index/_search { retriever: { linear: { query: a cat on a windowsill, fields: [title, my_semantic_field], normalizer: minmax } } }该 retriever 会自动区分 lexical 字段和 semantic 字段分别对每一组字段执行查询并对结果进行归一化处理使每一组字段对最终排序产生相同的贡献从而避免 lexical 匹配结果压制 semantic 匹配结果。Cross-cluster searchsemantic字段支持cross-cluster searchCCS因此可以在大型多集群部署中使用该字段。只需使用标准的cluster:index格式列出要查询的索引即可GET example-index,remote-cluster:remote-index/_search { query: { match: { my_semantic_field: a cat on a windowsill } } }跨索引和跨集群查询的字段可以混合使用不同的 inference endpoint而这些 endpoint 可能会生成不同的 query embedding。搜索请求会自动为每个被查询的字段应用正确的 query embedding。从画布走向生产优化用于生产环境的多模态 embedding当你将多模态搜索从实验阶段投入生产时多模态输入的大小会成为一个实际问题。多模态数据通过 Base64 编码的 data URL 提供并且这些数据会存储在索引中。这些字符串的大小可能会快速增长一个高分辨率文件可能膨胀到数 MB 的编码文本从而带来以下影响磁盘上的索引大小会显著增加包含多模态数据的请求和响应会变大增加传输时间以及 ingress/egress 成本更大的多模态输入会导致 inference 速度变慢。好消息是你并不需要保留这么高的保真度。多模态 embedding 模型本身会在生成向量之前将每个输入压缩为紧凑的表示。因此一个更小、保真度更低的多模态输入例如缩小尺寸后的图片或更低码率的音频片段通常可以生成与原始完整输入非常相似的 embedding并保持相近的搜索质量。这同样适用于 PDF 输入。PDF 通常会被多模态模型以视觉方式处理因此只需要达到足够支持以下操作的质量即可图像 embeddingOCR。较长的 PDF 应该拆分为更小的输入 chunk这样生成的 embedding 才能更准确地表示每个 chunk。向模型提供较小的输入可以保持文档更加精简减少索引大小和响应大小加快 ingest 速度同时不会明显影响相关性。Elasticsearch 通过一个保护机制进一步强化了这种最佳实践indices.inference.max_binary_input_size集群设置限制每个 binary input 的大小默认值为1 MB。任何超过该限制的单个值都会被拒绝并返回明确错误。因此过大的输入会在索引阶段直接暴露为可处理的问题而不是悄悄导致索引膨胀。在 self-hosted 和 ECH 环境中可以通过cluster settings API调整该设置。在 Serverless 环境中该设置不可调整1 MB 是 binary size 的固定上限。在可能的情况下也建议使用source filtering将semantic字段从响应中排除。例如GET example-index/_search { _source: { excludes: [my_semantic_field] }, query: { match: { my_semantic_field: a cat on a windowsill } } }这样可以让响应更加小巧、性能更高并且更容易解析因为多模态数据不会随着每次响应一起返回。试用semantic字段semantic字段已在 Elasticsearch 9.5 和 Serverless 中提供。开始免费试用并立即体验。原文Semantic field: one field for multimodal search in Elasticsearch | Elasticsearch Labs