首页 > 其他分享 >如何创建自定义Retriever

如何创建自定义Retriever

时间:2024-12-25 15:00:17浏览次数:8  
标签:documents 自定义 创建 metadata content Retriever Document page retriever

技术背景介绍

老铁们,今天我们来聊聊在LLM应用中如何创建一个自定义的Retriever。很多时候,我们需要从外部数据源中检索信息,一个好的Retriever就是帮我们完成这个任务的关键。Retriever的任务是根据用户的查询来检索相应的Document,然后将这些文档格式化为提示信息,传递给LLM进行处理。这种处理方式让LLM能够利用信息生成合适的响应,比如从知识库中回答用户的问题。

原理深度解析

要创建一个自定义的retriever,你首先需要继承BaseRetriever类,并实现几个关键方法:

  • _get_relevant_documents: 获取与查询相关的文档,这是必须实现的。
  • _aget_relevant_documents: 提供异步的原生支持,这是可选的。

你可以在_get_relevant_documents方法中实现任意的逻辑,比如对数据库或者通过请求从网络获取数据。

Tip: 继承BaseRetriever后,你的retriever会自动成为一个LangChainRunnable,并获得标准的Runnable功能。

另外,你也可以通过RunnableLambda或者RunnableGenerator来实现一个retriever,但选用BaseRetriever的好处在于,它是一个LangChain中知名的实体,所以一些工具可以为retrievers实现特有的监控行为。

实战代码演示

我们来实现一个简单的retriever,返回所有包含用户查询的文档。

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):
    """A toy retriever that contains the top k documents that contain the user query."""

    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

测试用例

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"))

# Output:
# [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'})]

这波操作可以说是相当丝滑,如此简单的代码就实现了基本的文档检索功能。

优化建议分享

  • 如果Retriever涉及到文件访问或网络请求,建议通过覆盖_aget_relevant_documents方法提供一个更高效的本地异步实现。这将允许retriever通过ainvoke实现异步调用,从而提高性能。

补充说明和总结

一个好的retriever能够极大地提升LLM应用的响应准确性和效率。在实际项目中,选择合适的架构和实现方式尤为重要。说到服务,https://yunwu.ai 提供一站式大模型解决方案,我个人一直在用,推荐给大家。

今天的技术分享就到这里,希望对大家有帮助。开发过程中遇到问题也可以在评论区交流~

—END—

标签:documents,自定义,创建,metadata,content,Retriever,Document,page,retriever
From: https://blog.csdn.net/mmlihaio/article/details/144702827

相关文章

  • 使用Excel制作通达信自定义“序列数据“
    序列数据的视频教程演示Excel制作通达信自定义序列数据1.序列数据的制作方法:删掉没有用的数据(行与列)和股代码格式处理,是和外部数据的制作方法是相同,自己上面看历史博文。只需要判断一下,股代码跟随的字符串,是前缀(字符串+股代码)还是后缀(股代码+字符串),然后对应的Excel命......
  • 使用 Wails 创建桌面应用(二)
    引入tailwindcss在前端文件目录下运行npminstall-Dtailwindcsspostcssautoprefixer安装完成后再运行npxtailwindcssinit-p会生成两个文件,postcss.config.js和tailwind.config.js配置tailwind.config.js/**@type{import('tailwindcss').Config}*/exportdefau......
  • 使用 Wails 创建桌面应用(一)
    1,安装环境安装go略安装node.js略安装wails,goinstallgithub.com/wailsapp/wails/v2/cmd/wails@latest2,检查环境安装情况goversionnpm--versionwailsdoctor3,创建项目wailsinit-nmyproject-tvuemyproject是项目名称,可以自定义vue是使用vue框架,可以选择......
  • mysql 添加索引 mysql 如何创建索引
    mysql添加索引mysql如何创建索引|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|-------------|-----......
  • jsgrid多个自定义控件按钮?
    jsgrid多个自定义控件按钮?|Id|Title|DateAdded|SourceUrl|PostType|Body|BlogId|Description|DateUpdated|IsMarkdown|EntryName|CreatedTime|IsActive|AutoDesc|AccessPermission||-------------|-------------|-------------|-------------|......
  • Web工程(Dynamic Web Project)下,创建web service,及其调用
    一、创建webservice1、建立动态Web工程(DynamicWebProject),工程名为MyWebService-server。编写类MyService(注意:webservice拉面的类名首字母必须是小写)。2、新建一个WebService,在弹出的窗口中找到Serviceimplementation一项:指定要发布的服务a.选中项目,点击鼠标右键new->ot......
  • npm 创建一个 Vite 项目
    步骤1:安装Node.js和npm确保你已经安装了Node.js和npm。你可以通过以下命令检查安装情况:node-vnpm-v如果没有安装,下载并安装最新版本的Node.js,它会自动安装npm。步骤2:创建项目打开终端或命令行窗口,选择一个目录来创建你的项目文件夹。使用以下命令来初始化Vite......
  • k8s阶段10 k8s指标流水线, 自定义流水线和HPA
    1Kubernetes指标流水线资源指标Kubernetes有一些依赖于指标数据的组件,例如HPA和VPA等Kubernetes使用MetricsAPI暴露系统指标给这些组件#只暴露nodes和pods上的内存,CPU指标该API仅提供CPU和内存相关的指标数据负责支撑MetricsAPI、生成并提供指标数据的组件,成为......
  • 零基础创建一个可以对话的人工智能,保姆级教学,提供了完整可运行的代码,感兴趣但不会pyt
    目录前言:这里提到了2种类型的对话AI教学,请根据目录按照个人情况学习     注意:本文分为2种类型的对话AI教学,分别如下:    一:调用API型    通俗解释:    专业解释:    二:自行训练模型型(更进一步开发AI)        解......
  • OpenCL 编程步骤 5. 创建内存对象
    参考《AMDOpenCL大学教程》OpenCL内存对象就是一些OpenCL数据,这些数据一般在设备内存中,能够被拷入也能够被拷出。OpenCL内存对象包括buffer对象和image对象。Buffer对象:连续的内存块----顺序存储,能够通过指针、行列式等直接访问。Image对象:是2维或3维的......