在如今信息爆炸的时代,如何迅速从海量数据中获取所需信息是一个关键问题。对此,查询分析技术提供了有效的解决方案。本指南将展示如何构建一个查询分析系统,通过实际代码演示,让我们从用户问题到结果的检索过程中,体验查询分析的强大功能。
技术背景介绍
查询分析是一种优化数据检索的方法,通过解析用户查询,生成结构化检索请求,以提高检索结果的相关性和准确性。在本例中,我们以LangChain的YouTube视频为检索对象,构建一个简单的搜索引擎,并展示如何通过查询分析改善搜索结果。
核心原理解析
查询分析的关键在于定义查询模式(query schema),以实现对数据属性的过滤和优化。在我们的例子中,我们构建了一个包含日期过滤器的查询模式,并使用OpenAI的函数调用模型将用户问题转换为结构化查询。
代码实现演示
首先,我们需要安装必要的依赖项:
# 安装所需的Python库
%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()
加载文档
我们使用YoutubeLoader
来加载LangChain的YouTube视频转录文档:
from langchain_community.document_loaders import YoutubeLoader
import datetime
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())
# 添加视频发布日期年份到文档元数据
for doc in docs:
doc.metadata["publish_year"] = int(
datetime.datetime.strptime(
doc.metadata["publish_date"], "%Y-%m-%d %H:%M:%S"
).strftime("%Y")
)
构建索引
我们采用向量库索引文档,并进行文本分块,以提高检索精度:
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,
)
查询分析与检索
定义查询模式并进行生成和分析:
from typing import Optional
from langchain_core.pydantic_v1 import BaseModel, Field
class Search(BaseModel):
query: str = Field(..., description="相似性搜索查询")
publish_year: Optional[int] = Field(None, description="视频发布日期年份")
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
system = """您是将用户问题转换为数据库查询的专家。"""
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
query_analyzer.invoke("videos on RAG published in 2023")
通过分析进行检索
使用生成的结构化查询进行检索:
from typing import List
from langchain_core.documents import Document
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]
应用场景分析
查询分析系统适合用于需要高效数据检索的场景,例如在线知识库、数据密集型科研项目以及复杂客户查询管理系统等。
实践建议
- 根据数据特性选择合适的向量库和嵌入模型。
- 在定义查询模式时,考虑数据的各个维度,以提高检索结果的准确性。
- 定期更新嵌入模型和向量库,以适应数据变化。
如果遇到问题欢迎在评论区交流。
—END—