RAG最佳实践:用 ElasticSearch 打造AI搜索系统与RAG 应用全流程详解!
今天来聊一个非常实际的话题:如何用 Elasticsearch 把 AI 搜索系统和 RAG 应用真正落地。
先拆解一下,在 Elasticsearch 里实现向量搜索,究竟需要哪几个核心组件。
首先是
嵌入模型
然后是
推理终端节点
接下来是
搜索
最后是
应用程序逻辑
把这些组件整合到一起,就构成了一个完整的 AI 搜索链路。
接下来,我们进入正题:如何从零手写一个 AI 对话式搜索应用。先简单定义一下,
AI 对话式搜索
架构图如下所示(图中展示了从用户输入到检索再到生成回答的完整流程)。
第一步:数据收集和预处理
确定数据来源——常见的有内部知识库、FAQ、文档资料。然后需要构建一个数据管道,把这些数据导入检索系统,准备好在 RAG 应用中直接使用。
第二步:设置数据管道
这里需要准备索引映射、建立索引、并存储数据。代码示例:
from elasticsearch_serverless import Elasticsearch
import json
import os
client = Elasticsearch(
os.getenv("ELASTICSEARCH_URL"),
api_key=os.getenv("ES_API_KEY"),
request_timeout=600
)
mappings={
"properties":{
"semantic":{"type":"semantic_text","inference_id":"e5-small"},
"content":{"type":"text","copy_to":"semantic"}
}
}
# Create index
client.indices.create(index="search-faq", mappings=mappings)
第三步:创建推理服务
要创建一个推理服务来操作 E5 多语言 ML 模型:
inference_config={
"service":"elasticsearch",
"service_settings":{
"num_allocations":1,
"num_threads":1,
"model_id":".multilingual-e5-small"
}
}
# Create inference
client.inference.put(
inference_id="e5-small",
task_type="text_embedding",
inference_config=inference_config
)
第四步:数据生成文档嵌入
with open("faq.json") as f:
documents = json.load(f)
def generate_docs():
index_name = "search-faq"
for row in documents:
yield { "index" : { "_index" : index_name } }
yield row
client.bulk(operations=generate_docs())
第五步:前端页面开发
负责与用户交互并展示搜索结果:
// Retrieve relevant content from the knowledge base
async function findRelevantContent(question: string) {
// Semantic search query
const body = await client.search({
size: 3,
index: 'search-faq',
body: {
query: {
semantic: {
field: "semantic",
query: question
}
}
}
});
return body.hits.hits.map((hit: any) => ({
content: hit._source.content
}));
}
页面效果图如下所示(展示了最终的搜索界面和结果呈现)。
——
接下来,我们看如何用 Elasticsearch 搭建
完整的 RAG 系统
ES 在 RAG 领域的解决方案如上图所示。一个典型的场景是:用户把问题直接抛给大模型,大模型只能依赖自己的内部知识回答。一旦涉及企业内部的私域信息,大模型就“抓瞎”了。这时 ES 就会启动 RAG 方案,把问题转交给知识库去检索。
知识库中不仅有文本,还有图片、视频等。我们提前把这些内容向量化,然后在检索阶段做文本和向量的混合召回,拿到 TopN 列表。之后将这份列表与用户原始问题拼成一个 prompt,再交给大模型。大模型根据这些上下文信息,就能给出更加精准的回答。
RAG 的核心思想就是“先检索、后生成”:先从外部知识库检索相关片段,再把这些片段和用户提问一起送入生成模型。用 Elasticsearch 作为向量数据库,解决大规模数据下的高效检索;而 LangChain 则负责构建和管理这种复杂应用的各层逻辑。
安装依赖:
pip install langchain-elasticsearch
配置连接:
from langchain_elasticsearch import ElasticsearchStore
es_store = ElasticsearchStore(
es_cloud_id="your-cloud-id",
es_api_key="your-api-key",
index_name="rag-example",
strategy=ElasticsearchStore.SparseVectorRetrievalStrategy(model_id=".elser_model_2"),
)
文档收集
texts = [
"LangChain is a framework for developing applications powered by large language models (LLMs).",
"Elasticsearch is a distributed, RESTful search and analytics engine capable of addressing a growing number of use cases.",
...
]
es_store.add_texts(texts)
向量化
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(api_key="sk-...")
构建检索链
from langchain import hub
from langchain_core.runnables import RunnablePassthrough
prompt = hub.pull("rlm/rag-prompt")
retriever = es_store.as_retriever()
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
用户查询向量化
生成回答
rag_chain.invoke("Which frameworks can help me build LLM apps?")
Elasticsearch Store 默认提供了多种开箱即用的检索策略,开发人员可以根据实际场景自由选择。但如果数据模型更复杂——比如索引里除了文本,还有标题、URL、标签等字段——该怎么办?Elasticsearch 的 Query DSL 给了你完全的控制权。
这里推荐一个更灵活的做法:在 LangChain 中使用 ElasticsearchRetriever,直接定义一个函数,把用户查询映射到 ES 请求上。
举个实际例子:假设我们想在检索环节加入语义重排序,用 Cohere 重排序模型提升顶部结果的相关性。可以用下面这种方式实现:
def text_similarity_reranking(search_query: str) -> Dict:
return {
"retriever": {
"text_similarity_reranker": {
"retriever": {
"standard": {
"query": {
"match": {
"text_field": search_query
}
}
}
},
"field": "text_field",
"inference_id": "cohere-rerank-service",
"inference_text": search_query,
"window_size": 10
}
}
}
retriever = ElasticsearchRetriever.from_es_params(
es_cloud_id="your-cloud-id",
es_api_key="your-api-key",
index_name="rag-example",
content_field=text_field,
body_func=text_similarity_reranking,
)
总的来说,Elasticsearch 在 RAG 方向上的优势非常明显:
低门槛
高性能
更精准
更智能
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名