尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于Elasticsearch与Jina Embeddings构建智能文档搜索系统

基于Elasticsearch与Jina Embeddings构建智能文档搜索系统 1. 项目概述十分钟构建你的智能文档大脑如果你手头有一堆技术文档、产品手册或者内部知识库每次想找点东西都得靠记忆或者全局搜索关键词那效率实在太低了。我自己就经常被这种问题困扰直到我开始把文档“向量化”——简单说就是把文字变成计算机能理解的数学向量然后让机器根据语义相似度来帮我找东西。这听起来很复杂但其实用现在的工具十分钟就能搭出一个可用的原型。今天要聊的就是用Elasticsearch作为向量数据库用Jina Embeddings v5模型来生成高质量的文本向量快速打造一个我称之为“OpenClaw”的智能文档搜索系统。这个名字有点中二灵感来源于它能像爪子一样精准抓取你需要的信息并且整个架构是开放、可扩展的。这个方案的核心价值在于“开箱即用”和“效果平衡”。Elasticsearch 本身就是一个强大的搜索引擎从 8.x 版本开始原生支持向量检索这意味着你不用再维护一个单独的向量数据库简化了架构。Jina Embeddings v5 模型特别是jina-embeddings-v2-base-en和jina-embeddings-v2-base-zh在 MTEB 等权威榜单上表现非常亮眼尤其在处理长文本和跨语言检索时效果比一些通用模型要好而且它完全开源免费。对于大多数中小型知识库或者个人项目来说这个组合在效果、成本和复杂度上取得了很好的平衡。接下来我会带你走一遍从零开始的过程包括环境准备、文档处理、向量化入库和查询演示。你会发现虽然背后是 embedding 模型和向量检索这些听起来高大上的技术但实际操作起来就像搭积木一样简单。2. 核心组件选型与原理浅析为什么是 Elasticsearch Jina Embeddings v5这个选择背后有几个很实际的考量。我们先拆开看看每个部分扮演的角色。2.1 为什么选择 Elasticsearch 作为向量数据库首先得明确Elasticsearch后面简称 ES在这里不光是存向量它扮演的是“向量数据库全文搜索引擎”的二合一角色。这是它最大的优势。1. 原生向量支持无需额外插件从 ES 8.0 开始官方就引入了dense_vector字段类型来专门存储向量。这意味着你可以像创建普通文本字段一样在 mapping索引映射里定义一个向量字段。后续的knn近似最近邻搜索也是原生功能。早几年你可能需要安装elastiknn这类第三方插件现在官方支持让整个部署和运维变得非常稳定和简单兼容性也更好。2. 混合搜索能力Hybrid Search这是 ES 的杀手锏。你的文档里除了向量肯定还有原始文本、标题、标签、创建时间等元数据。传统的全文搜索BM25算法在关键词匹配、短语搜索上依然非常高效和精准。智能语义搜索向量检索则擅长理解意图比如你搜“如何解决启动错误”它能找到关于“故障排查”、“初始化失败”的段落。在 ES 里你可以轻松地将这两种搜索方式的得分进行融合比如加权求和得到既有关键词匹配精度又有语义理解广度的最终结果。这是很多单一向量数据库不具备的能力。3. 成熟的生态系统和运维工具ES 有完善的集群管理、监控Kibana、数据备份恢复方案。这对于未来系统上线后的维护至关重要。你不用担心数据丢了怎么办或者性能瓶颈怎么查。注意对于超大规模比如十亿级以上的纯向量检索场景专业的向量数据库如 Milvus, Qdrant在检索速度和精度上可能有专门优化。但对于绝大多数文档搜索场景百万级文档以内ES 的原生向量功能完全够用且混合搜索的优势无可替代。2.2 Jina Embeddings v5 模型强在哪里Embedding 模型负责把一段文本转换成一个固定长度的浮点数向量比如 768 维。这个向量的质量直接决定了搜索的准确性。Jina Embeddings v5 系列模型有几个突出的特点1. 针对长文本优化8192 Tokens很多开源的 Embedding 模型如早期的text-embedding-ada-002或一些 BERT 变体有长度限制512或1024 tokens。这意味着处理长文档时你需要进行截断或者复杂的分段可能丢失信息。Jina v5 模型支持高达 8192 tokens 的上下文长度这意味着你可以将整页甚至几页的文档直接送进去生成一个整体向量更好地保留文档的全局语义。当然对于非常长的文档合理的分段策略仍然是必要的但它的处理能力上限大大提升了。2. 在检索任务上表现卓越Jina AI 在训练这些模型时特别注重在信息检索IR任务上的性能。在 MTEBMassive Text Embedding Benchmark排行榜上jina-embeddings-v2-base-en在检索类任务中排名非常靠前甚至超过了某些参数量更大的模型。这意味着用它生成的向量在做相似度比较时更能拉开相关文档和不相关文档的距离从而提高搜索的召回率和准确率。3. 支持双语和跨语言检索它有针对中文优化的版本jina-embeddings-v2-base-zh也有多语言版本。更厉害的是即使你用英文模型它对中文也有不错的理解能力反之亦然。这为构建跨语言知识库提供了便利。比如你的文档是中英文混合的用户用中文提问模型也能从英文文档中找到相关答案。4. 完全开源与免费商用模型权重在 Hugging Face 上公开你可以下载到本地部署没有任何调用次数或费用的限制。这对于需要控制成本、保障数据隐私或者网络隔离的环境是必须的。2.3 OpenClaw 系统架构设计所谓的“OpenClaw”系统在这里指的就是我们构建的这个智能搜索流水线。它的工作流程非常清晰分为两个主要阶段索引构建和查询处理。索引构建阶段离线一次处理文档加载与预处理从各种来源Markdown, PDF, Word, 网页加载文档进行清理去除无关字符、格式、分段将长文档切成语义完整的段落或章节。文本向量化将每一个文本分段通过 Jina Embeddings v5 模型生成对应的 768 维向量。数据入库将“原始文本”、“元数据”和对应的“向量”作为一个完整的文档写入 Elasticsearch 索引。其中向量存储在dense_vector类型的字段中。查询处理阶段在线实时响应用户提问用户输入一个自然语言问题例如“Elasticsearch 集群健康状态为 red 该如何处理”查询向量化使用同一个Jina Embeddings v5 模型将用户的问题也转换成一个 768 维的向量。向量检索在 Elasticsearch 中使用knn搜索选项查找与查询向量最相似的文档向量。ES 会计算余弦相似度等距离返回最相似的 N 个结果。结果排序与返回可以将向量检索的相似度分数与传统的全文检索如果同时开启的分数进行融合对结果进行重新排序最后将最相关的文本片段返回给用户。这个架构的“开放”性体现在你可以轻松替换其中的组件。比如未来如果有了更强大的 Embedding 模型你只需要更换向量化那一步的模型调用即可其他部分基本不变。3. 十分钟快速上手环境准备与数据灌入理论说再多不如动手做一遍。我们目标是十分钟内看到效果所以一切从简使用 Docker 来快速搭建环境。3.1 一分钟启动 Elasticsearch我们使用 Docker 来运行一个单节点的 Elasticsearch这是最快的方式。确保你的机器上已经安装了 Docker 和 Docker Compose。创建一个docker-compose.yml文件内容如下version: 3.8 services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.13.0 container_name: openclaw-es environment: - discovery.typesingle-node - xpack.security.enabledfalse - ES_JAVA_OPTS-Xms512m -Xmx512m ports: - 9200:9200 volumes: - es_data:/usr/share/elasticsearch/data networks: - openclaw-net volumes: es_data: networks: openclaw-net: driver: bridge这里有几个关键点discovery.typesingle-node设置为单节点模式适合开发和测试。xpack.security.enabledfalse为了快速演示我们禁用了安全认证。在生产环境中这是绝对不允许的必须配置用户名密码和 TLS 证书。ES_JAVA_OPTS限制 Elasticsearch 的堆内存为 512MB对于 demo 足够避免吃光你的电脑内存。数据卷es_data用于持久化存储索引数据即使容器重启数据也不会丢失。在终端中进入该文件所在目录运行docker-compose up -d等待几十秒访问http://localhost:9200如果看到返回一个包含cluster_name等信息的 JSON说明 Elasticsearch 启动成功。3.2 准备示例文档与 Embedding 模型接下来我们需要一些文档和模型。为了在十分钟内完成我们准备一个简单的 Python 脚本并使用一个轻量级的 Embedding 模型。实际上Jina 的模型稍大但我们可以用 Hugging Face 的transformers库来在线加载首次需要下载。首先安装必要的 Python 库pip install elasticsearch transformers sentencepiece torch然后创建一个名为index_documents.py的脚本。我们先准备一点示例数据模拟一个简单的产品 FAQ 知识库# 示例文档数据 documents [ { id: 1, title: 如何安装 Elasticsearch, content: Elasticsearch 可以通过多种方式安装包括使用 Docker、下载压缩包或通过包管理器。使用 Docker 是最简单快速的方式只需一条命令即可运行。, category: 安装部署 }, { id: 2, title: Elasticsearch 集群健康状态红色处理, content: 当集群健康状态为 red 时表示有主分片未能分配。通常需要检查磁盘空间、节点网络或索引配置。可以尝试使用 _cluster/health API 查看详细原因并重新分配分片。, category: 运维排查 }, { id: 3, title: 使用 Kibana 进行数据可视化, content: Kibana 是 Elastic Stack 的数据可视化工具。你可以通过创建索引模式、探索数据和构建仪表板来直观展示 Elasticsearch 中的数据。, category: 数据分析 }, { id: 4, title: 什么是向量搜索, content: 向量搜索是一种基于语义相似度的搜索技术。它将文本转换为高维向量通过计算向量间的距离如余弦相似度来找到最相关的内容而非依赖关键词匹配。, category: 概念解析 } ]3.3 生成向量并写入 Elasticsearch现在我们在脚本中添加连接 ES、加载模型、生成向量和创建索引的逻辑。from elasticsearch import Elasticsearch from transformers import AutoTokenizer, AutoModel import torch import numpy as np # 1. 连接 Elasticsearch (无认证版仅用于演示) es_client Elasticsearch(http://localhost:9200) # 2. 加载 Jina Embeddings v2 模型 (这里以 base-en 为例首次运行会自动下载) model_name jinaai/jina-embeddings-v2-base-en tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name, trust_remote_codeTrue) # 注意 trust_remote_code def get_embedding(text): 生成文本的向量表示 inputs tokenizer(text, paddingTrue, truncationTrue, return_tensorspt, max_length8192) with torch.no_grad(): outputs model(**inputs) # 采用 mean pooling 来获得句子向量 embeddings outputs.last_hidden_state.mean(dim1).squeeze() return embeddings.numpy() # 3. 创建索引定义包含向量字段的 mapping index_name openclaw_docs if es_client.indices.exists(indexindex_name): es_client.indices.delete(indexindex_name) # 删除旧的方便重复运行 mapping { mappings: { properties: { title: {type: text}, content: {type: text}, category: {type: keyword}, content_vector: { type: dense_vector, dims: 768, # Jina v2 base 模型输出 768 维向量 index: True, # 必须为 true 才能进行 knn 搜索 similarity: cosine # 指定相似度计算方式为余弦相似度 } } } } es_client.indices.create(indexindex_name, bodymapping) print(f索引 {index_name} 创建成功。) # 4. 处理文档并灌入索引 for doc in documents: text_to_embed f{doc[title]} {doc[content]} # 将标题和内容合并生成向量 vector get_embedding(text_to_embed).tolist() # 转换为列表 doc_body { title: doc[title], content: doc[content], category: doc[category], content_vector: vector } es_client.index(indexindex_name, iddoc[id], documentdoc_body) print(f已索引文档: {doc[title]}) # 强制刷新使文档立即可搜 es_client.indices.refresh(indexindex_name) print(所有文档已索引完成可以开始搜索了。)运行这个脚本python index_documents.py第一次运行会下载模型可能需要几分钟取决于你的网络。之后再次运行就很快了。看到成功提示后我们的“智能文档库”就准备好了。4. 实现智能搜索与混合查询索引建好了现在我们来实现搜索功能。我们将实现两种搜索纯向量语义搜索以及结合了关键词的混合搜索。4.1 纯向量语义搜索kNN搜索这是最核心的智能搜索。用户输入一个问题我们将其向量化然后在 ES 中寻找向量最相似的文档。创建一个search.py文件from elasticsearch import Elasticsearch from transformers import AutoTokenizer, AutoModel import torch # 复用之前的模型和函数 model_name jinaai/jina-embeddings-v2-base-en tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name, trust_remote_codeTrue) es_client Elasticsearch(http://localhost:9200) index_name openclaw_docs def get_embedding(text): inputs tokenizer(text, paddingTrue, truncationTrue, return_tensorspt, max_length8192) with torch.no_grad(): outputs model(**inputs) embeddings outputs.last_hidden_state.mean(dim1).squeeze() return embeddings.numpy() def semantic_search(query, top_k3): 基于语义的向量搜索 query_vector get_embedding(query).tolist() search_body { knn: { field: content_vector, query_vector: query_vector, k: top_k, num_candidates: 100 # 在候选集中寻找的节点数越大越准越慢 }, _source: [title, content, category], # 指定返回哪些字段 size: top_k } response es_client.search(indexindex_name, bodysearch_body) return response[hits][hits] # 测试一下 if __name__ __main__: user_query 怎么安装ES # 注意这里用了口语化和缩写 results semantic_search(user_query) print(f查询: {user_query}\n) print(语义搜索结果:) for i, hit in enumerate(results): score hit[_score] title hit[_source][title] content_preview hit[_source][content][:100] ... print(f{i1}. [{score:.4f}] {title}) print(f 内容: {content_preview}) print()运行python search.py你会看到即使用户提问“怎么安装ES”非标准表述系统也能准确找到“如何安装 Elasticsearch”这篇文档。这就是语义搜索的魅力——它理解意图。4.2 混合搜索Hybrid Search结合关键词与语义有时候用户的问题里包含非常具体的关键词比如“_cluster/healthAPI”。这时传统的 BM25 全文搜索可能更精准。混合搜索就是将两种搜索方式的得分结合起来。Elasticsearch 8.x 之后可以很方便地在一次查询中同时进行knn和query全文检索。我们需要将两个分数进行标准化并融合。这里演示一种简单的线性加权融合方式def hybrid_search(query, vector_weight0.7, text_weight0.3, top_k5): 混合搜索结合向量搜索和全文搜索。 vector_weight: 向量搜索得分权重 text_weight: 全文搜索得分权重 query_vector get_embedding(query).tolist() search_body { size: top_k, _source: [title, content, category], query: { bool: { should: [ { match: { content: { query: query, boost: text_weight # 全文检索的权重因子 } } } ] } }, knn: { field: content_vector, query_vector: query_vector, k: top_k, num_candidates: 100, boost: vector_weight # 向量检索的权重因子 }, # 使用 rank fusion 来合并结果 (RRF - Reciprocal Rank Fusion) rank: { rrf: { window_size: top_k, rank_constant: 60 } } } # 注意在较新版本的 ES ( 8.9) 中可以直接使用 knn 与 query 同级并使用 rank 进行融合。 # 如果你的版本稍旧可能需要使用 _search API 的 knn 参数并手动处理分数融合。 response es_client.search(indexindex_name, bodysearch_body) return response[hits][hits] # 测试混合搜索 if __name__ __main__: user_query 使用 _cluster/health 查看集群状态 results hybrid_search(user_query, vector_weight0.6, text_weight0.4) print(f混合查询: {user_query}\n) print(混合搜索结果:) for i, hit in enumerate(results): score hit[_score] title hit[_source][title] category hit[_source][category] print(f{i1}. [{score:.4f}] {title} (分类: {category}))在这个例子中查询既包含了具体的 API 名称“_cluster/health”关键词又包含了“查看集群状态”这样的语义描述。混合搜索能确保既精准命中包含该 API 的文档又能通过语义理解找到相关的故障排查内容。rank参数中的rrf倒数排名融合是 ES 提供的一种高效的融合策略无需手动归一化分数非常方便。实操心得权重调优vector_weight和text_weight的比值需要根据你的数据和查询特点进行调整。如果用户查询多为口语化、长句可以调高向量权重如0.8。如果文档中专业术语、代码、固定名称很多可以调高全文检索权重如0.6。最好的方式是用一批真实的查询-文档对通过 A/B 测试来找到最佳权重。5. 生产环境部署考量与优化技巧十分钟搭建的原型可以跑起来但要真正用于生产环境还需要考虑很多问题。这里分享几个关键的优化点和避坑经验。5.1 性能优化索引与查询1. 向量索引参数调优在创建dense_vector字段时我们只设置了index: true和similarity: cosine。对于大规模数据ES 底层使用 HNSWHierarchical Navigable Small World图算法来加速近似最近邻搜索。你可以通过index_options来调整 HNSW 的参数影响构建速度和检索精度/速度的平衡。content_vector: { type: dense_vector, dims: 768, index: true, similarity: cosine, index_options: { type: hnsw, m: 16, // 每个节点在图中保留的邻居数越大越准越慢默认16 ef_construction: 100 // 构建图时考察的候选节点数越大图质量越高越慢默认100 } }对于千万级以下的文档默认参数通常足够。如果数据量极大亿级可能需要增大m和ef_construction来保证召回率但这会显著增加索引时间和内存占用。2. 查询时num_candidates参数在knn查询中num_candidates参数指定从每个分片中选取多少候选向量进行精确计算。值越大结果越准确但耗时越长。通常设置为k你想要的结果数的 10-20 倍是一个好的起点。在我们的 demo 中设置为 100 对于小数据量是足够的。3. 模型推理优化在 Python 端调用 Transformers 模型进行实时向量化可能成为瓶颈。有几种优化方案模型量化使用torch.quantization或bitsandbytes库对模型进行量化如 int8可以大幅减少内存占用并提升推理速度精度损失很小。使用 ONNX Runtime将模型导出为 ONNX 格式并用 ONNX Runtime 推理通常比原生 PyTorch 更快。部署独立的 Embedding 服务使用 FastAPI 等框架将模型封装成 HTTP API 服务方便横向扩展和负载均衡。甚至可以部署多个实例用 Nginx 做负载均衡。5.2 数据处理管道化与增量更新真实场景的文档是不断增加的。我们需要一个自动化的管道来处理新增文档。1. 文档分段策略Chunking虽然 Jina 模型支持长文本但无脑将整篇文档塞进去效果不一定好。一个最佳实践是使用“重叠分段法”。例如每段 500-1000 个字符段与段之间重叠 100-200 个字符。这能保证检索到相关段落时有足够的上下文信息。可以使用langchain的RecursiveCharacterTextSplitter或tiktoken用于精确计算 token来实现。2. 增量索引为每个文档或分段添加一个时间戳字段如update_time。定期扫描源数据只处理update_time晚于上次处理时间的文档。将处理分段、向量化和灌入 ES 的步骤脚本化用 Cron Job 或 Airflow 等调度工具定期执行。3. 处理失败与重试网络波动、模型服务暂时不可用、ES 写入失败等情况都需要考虑。在你的处理脚本中必须加入重试机制和异常处理。对于失败的文档记录日志并放入一个死信队列Dead Letter Queue稍后重试。5.3 安全与权限控制Demo 中我们禁用了 ES 的安全功能这在生产环境是致命的。1. 启用 Elasticsearch 安全特性在生产环境的docker-compose.yml或配置文件中必须设置environment: - discovery.typesingle-node - xpack.security.enabledtrue - xpack.security.http.ssl.enabledtrue - ELASTIC_PASSWORDyour_strong_password_here - xpack.license.self_generated.typetrial首次启动后你需要使用https和密码来访问。客户端连接时需要配置 SSL 证书和认证信息。2. 索引级别的权限控制使用 Elasticsearch 的基于角色的访问控制RBAC。创建一个只能读写openclaw_docs索引的专用用户而不是使用超级管理员账号。在应用程序中使用这个专用用户的凭证来连接 ES。3. 输入验证与防注入确保前端传入的搜索查询字符串经过了适当的清理和验证防止潜在的注入攻击虽然 ES 的 JSON 查询相对安全但仍需谨慎。6. 常见问题排查与实战记录在实际操作中你肯定会遇到各种各样的问题。我把我踩过的坑和解决方法记录下来希望能帮你节省时间。6.1 Elasticsearch 相关问题问题1启动 ES 时日志报错bootstrap check failure关于内存锁定。现象在 Linux 系统上ES 启动失败错误信息包含memory locking requested for elasticsearch process but memory is not locked。原因Elasticsearch 出于性能考虑希望将进程内存锁定在 RAM 中防止被交换到磁盘上。这需要系统权限。解决临时解决不推荐生产在elasticsearch.yml或 docker 环境变量中设置bootstrap.memory_lock: false。正确解决修改宿主机的系统配置。对于 docker 运行方式在docker-compose.yml中为 ES 服务添加ulimits: memlock: soft: -1 hard: -1并且确保容器有足够的内存限制mem_limit。问题2执行knn搜索时报错[knn] requires doc_values to be enabled。现象搜索请求返回 400 错误。原因在创建dense_vector字段映射时没有设置index: true或者使用的 ES 版本低于 8.0不支持该语法。解决确保你的 ES 版本 8.0并且在 mapping 中明确设置了index: true。在 7.x 版本中需要使用elastiknn插件语法完全不同。问题3写入或搜索速度很慢。现象灌数据或查询时响应时间长。排查与解决检查资源使用docker stats或top命令查看 ES 容器的 CPU 和内存使用率。如果内存不足JVM 会频繁 GC。确保为 ES 分配了足够的内存如-Xms4g -Xmx4g。调整刷新间隔默认情况下ES 每秒刷新一次索引refresh_interval1s这保证了数据的近实时可搜索性但会消耗性能。在批量灌入大量数据时可以临时将其设置为-1禁用刷新灌入完成后再改回来。es_client.indices.put_settings(indexindex_name, body{index: {refresh_interval: -1}}) # ... 批量灌数据 ... es_client.indices.put_settings(indexindex_name, body{index: {refresh_interval: 1s}}) es_client.indices.refresh(indexindex_name)使用批量 API不要用es_client.index单条插入使用es_client.bulkAPI 进行批量操作能极大提升写入吞吐量。6.2 Embedding 模型与 Python 端问题问题1加载 Jina 模型时报警告或错误trust_remote_code。现象运行AutoModel.from_pretrained时提示需要trust_remote_codeTrue。原因Jina 的模型定义可能使用了自定义的 PyTorch 模块Hugging Face 出于安全考虑需要显式授权。解决按照提示在加载模型时添加trust_remote_codeTrue参数。确保你从官方仓库jinaai下载模型。问题2生成向量的速度太慢影响查询响应时间。现象用户查询后需要等待好几秒才出结果瓶颈在 Python 端的模型推理。解决启用 GPU如果服务器有 NVIDIA GPU确保安装了torch的 CUDA 版本并且模型被自动移到了 GPU 上model.to(cuda)。推理速度会有数量级的提升。批处理Batch Inference在索引构建时不要一次只向量化一段文本。将多段文本组成一个 batch 送入模型能充分利用 GPU 的并行计算能力。def get_embeddings_batch(text_list): inputs tokenizer(text_list, paddingTrue, truncationTrue, return_tensorspt, max_length512).to(device) with torch.no_grad(): outputs model(**inputs) embeddings outputs.last_hidden_state.mean(dim1).cpu().numpy() return embeddings使用更轻量的模型如果对精度要求不是极致可以考虑 Jina 的更小模型或者其他的轻量级 Embedding 模型如all-MiniLM-L6-v2速度会快很多。问题3如何处理中文和英文混合的文档现象文档中中英文混杂担心单一模型效果不好。解决Jina 提供了jina-embeddings-v2-base-zh中文优化模型对中文理解更好。但对于中英混合场景jina-embeddings-v2-base-en的跨语言能力已经相当不错。一个更稳妥的策略是同时使用中英文模型生成向量并存到不同的字段中。查询时根据用户输入的语言倾向可以简单用字符检测选择对应的向量字段进行搜索。这增加了存储和计算成本但能获得最佳效果。6.3 搜索效果调优问题搜出来的结果感觉不太相关。排查路径检查向量维度是否匹配确保创建索引时dims参数如768与模型实际输出的向量维度一致。不一致会导致距离计算错误。检查文本预处理生成向量用的文本和存入 ES 的原始文本是否一致确保没有因为清洗过度而丢失关键信息。例如代码片段、错误代码、型号数字等是否被不当移除。尝试不同的相似度度量在 mapping 中similarity可以尝试l2_norm欧氏距离或dot_product点积。对于 Jina 这类经过余弦相似度优化的模型通常cosine是最佳选择。调整混合搜索权重如果纯语义搜索效果不佳尝试提高全文检索text_weight的权重。观察哪些查询效果不好针对性地调整。人工评估与迭代构建一个小的测试集几十个查询-相关文档对计算搜索系统的 MRR平均倒数排名或 NDCG 等指标。通过调整分段策略、模型、搜索参数来持续优化这些指标。最后这套“OpenClaw”系统只是一个起点。你可以在此基础上增加更多功能比如给搜索结果添加引用来源、实现多轮对话将历史对话也向量化作为上下文、或者接入前端做成一个漂亮的搜索界面。核心的流水线已经打通剩下的就是根据你的具体需求去扩展和打磨了。
返回列表