增强大模型高效检索:基于LlamaIndex ,构建一个轻量级带有记忆的 ColBERT 检索 Agent

在自然语言处理领域,高效检索相关信息的能力至关重要。将对话式记忆集成到文档检索系统中已经成为增强信息检索代理效果的强大技术。

在文中,我们专为 LlamaIndex 量身定制,将深入探讨构建一个轻量级的带有记忆的 ColBERT 检索代理,为高级检索任务提供简单而有效的解决方案。

我们还将探讨这种集成如何补充 ReAct 的功能,为 LlamaIndex 生态系统提供无缝的交互。

技术交流

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。

针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。

总结链接如下:

  • 《大模型面试宝典》(2024版) 正式发布!
  • 《大模型实战宝典》(2024版) 正式发布!

前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~

我们建了大模型算法岗技术与面试交流群, 想要进交流群、需要源码&资料、提升技术的同学,可以直接加微信号:mlc2060。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、微信搜索公众号:机器学习社区,后台回复:技术交流
方式②、添加微信号:mlc2060,备注:技术交流

定义

在我们踏上旅程之前,让我们澄清一些关键概念:

ColBERT:ColBERT,即基于 BERT 的上下文交互,是一种利用预训练语言模型如 BERT 来优化文档检索的技术。

HyDE:混合文档嵌入(HyDE)将稀疏和密集嵌入的优势结合起来,以获得更准确的文档表示。

对话式记忆:这指的是代理能够保留过去交互中的信息,从而实现更具上下文相关性的响应。

集成的好处

将对话式记忆集成到基于ColBERT的检索代理中带来了几个引人注目的优势:

  • 上下文相关性:通过保留对话历史,代理可以根据正在进行的对话定制检索结果,提高相关性。
    连续性:对话式记忆促进了交互的连续性,使对话流程更加自然和连贯。
  • 个性化:记忆集成使代理能够适应个人用户偏好和先前的交互,提升用户体验。

代码实现

让我们深入了解我们轻量级 ColBERT 检索代理与记忆的实现细节:

步骤 I:安装库

%pip install llama-index-core
%pip install llama-index-llms-openai
%pip install llama-index-embeddings-openai
%pip install llama-index-postprocessor-colbert-rerank
%pip install llama-index-readers-web

步骤 II:导入库,初始化 OpenAI,索引和加载数据

import os
from llama_index.readers.web import BeautifulSoupWebReaderfrom llama_index.core import VectorStoreIndex
from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.core.query_pipeline import (QueryPipeline,InputComponent,ArgPackComponent,
)
from llama_index.core.prompts import PromptTemplate
from llama_index.llms.openai import OpenAI
from llama_index.postprocessor.colbert_rerank import ColbertRerankfrom typing import Any, Dict, List, Optional
from llama_index.core.bridge.pydantic import Field
from llama_index.core.llms import ChatMessage
from llama_index.core.query_pipeline import CustomQueryComponent
from llama_index.core.schema import NodeWithScoreos.environ["OPENAI_API_KEY"] = "sk-..."# 加载数据
reader = BeautifulSoupWebReader()documents = reader.load_data(["https://docs.anthropic.com/claude/docs/tool-use"]
)# 索引
index = VectorStoreIndex.from_documents(documents,embed_model=OpenAIEmbedding(model="text-embedding-3-large", embed_batch_size=256),
)

步骤 III:查询管道构建

# 首先,我们创建一个输入组件来捕获用户查询
input_component = InputComponent()# 接下来,我们使用 LLM 重写用户查询
rewrite = ("请使用当前对话写一个查询给语义搜索引擎。\n""\n""\n""{chat_history_str}""\n""\n""最新消息:{query_str}\n"'查询:"""\n'
)
rewrite_template = PromptTemplate(rewrite)
llm = OpenAI(model="gpt-4-turbo-preview",temperature=0.2,
)# 我们将检索两次,因此需要将检索到的节点打包到一个列表中
argpack_component = ArgPackComponent()# 使用它,我们将检索...
retriever = index.as_retriever(similarity_top_k=6)# 然后使用 Colbert 进行后处理/重新排序
reranker = ColbertRerank(top_n=3)

步骤 VI:带有聊天历史的响应

DEFAULT_CONTEXT_PROMPT = ("以下是一些可能相关的上下文:\n""-----\n""{node_context}\n""-----\n""请使用上述上下文回答以下问题:\n""{query_str}\n"
)class ResponseWithChatHistory(CustomQueryComponent):llm: OpenAI = Field(..., description="OpenAI LLM")system_prompt: Optional[str] = Field(default=None, description="用于 LLM 的系统提示")context_prompt: str = Field(default=DEFAULT_CONTEXT_PROMPT,description="用于 LLM 的上下文提示",)def _validate_component_inputs(self, input: Dict[str, Any]) -> Dict[str, Any]:"""在 run_component 期间验证组件输入。"""# 注意:这是可选的,但我们展示了在哪里进行验证作为示例return input@propertydef _input_keys(self) -> set:"""输入键字典。"""# 注意:这些是必需的输入。如果有可选输入,请覆盖 `optional_input_keys_dict`return {"chat_history", "nodes", "query_str"}@propertydef _output_keys(self) -> set:return {"response"}def _prepare_context(self,chat_history: List[ChatMessage],nodes: List[NodeWithScore],query_str: str,) -> List[ChatMessage]:node_context = ""for idx, node in enumerate(nodes):node_text = node.get_content(metadata_mode="llm")node_context += f"上下文块 {idx}:\n{node_text}\n\n"formatted_context = self.context_prompt.format(node_context=node_context, query_str=query_str)user_message = ChatMessage(role="user", content=formatted_context)chat_history.append(user_message)if self.system_prompt is not None:chat_history = [ChatMessage(role="system", content=self.system_prompt)] + chat_historyreturn chat_historydef _run_component(self, **kwargs) -> Dict[str, Any]:"""运行组件。"""chat_history = kwargs["chat_history"]nodes = kwargs["nodes"]query_str = kwargs["query_str"]prepared_context = self._prepare_context(chat_history, nodes, query_str)response = llm.chat(prepared_context)return {"response": response}async def _arun_component(self, **kwargs: Any) -> Dict[str, Any]:"""异步运行组件。"""# 注意:可选的,但是异步 LLM 调用很容易实现chat_history = kwargs["chat_history"]nodes = kwargs["nodes"]query_str = kwargs["query_str"]prepared_context = self._prepare_context(chat_history, nodes, query_str)response = await llm.achat(prepared_context)return {"response": response}response_component = ResponseWithChatHistory(llm=llm,system_prompt=("你是一个问答系统。你将得到先前的聊天历史,""以及可能相关的上下文,来协助回答用户消息。"),
)
pipeline = QueryPipeline(modules={"input": input_component,"rewrite_template": rewrite_template,"llm": llm,"rewrite_retriever": retriever,"query_retriever": retriever,"join": argpack_component,"reranker": reranker,"response_component": response_component,},verbose=False,
)# 运行两次检索器 -- 一次使用虚构的查询,一次使用实际的查询
pipeline.add_link("input", "rewrite_template", src_key="query_str", dest_key="query_str"
)
pipeline.add_link("input","rewrite_template",src_key="chat_history_str",dest_key="chat_history_str",
)
pipeline.add_link("rewrite_template", "llm")
pipeline.add_link("llm", "rewrite_retriever")
pipeline.add_link("input", "query_retriever", src_key="query_str")# 每个输入到 argpack 组件都需要一个目标键 -- 它可以是任何东西
# 然后,argpack 组件将所有输入打包到一个列表中
pipeline.add_link("rewrite_retriever", "join", dest_key="rewrite_nodes")
pipeline.add_link("query_retriever", "join", dest_key="query_nodes")# reranker 需要打包后的节点和查询字符串
pipeline.add_link("join", "reranker", dest_key="nodes")
pipeline.add_link("input", "reranker", src_key="query_str", dest_key="query_str"
)# synthesizer 需要重新排序后的节点和查询字符串
pipeline.add_link("reranker", "response_component", dest_key="nodes")
pipeline.add_link("input", "response_component", src_key="query_str", dest_key="query_str"
)
pipeline.add_link("input","response_component",src_key="chat_history",dest_key="chat_history",
)

步骤 V:使用内存运行管道

from llama_index.core.memory import ChatMemoryBufferpipeline_memory = ChatMemoryBuffer.from_defaults(token_limit=8000)user_inputs = ["你好!","Claude-3 的工具使用是如何工作的?","有哪些模型支持它?","谢谢,这正是我需要知道的!",
]for msg in user_inputs:# 获取记忆chat_history = pipeline_memory.get()# 准备输入chat_history_str = "\n".join([str(x) for x in chat_history])# 运行管道response = pipeline.run(query_str=msg,chat_history=chat_history,chat_history_str=chat_history_str,)# 更新记忆user_msg = ChatMessage(role="user", content=msg)pipeline_memory.put(user_msg)print(str(user_msg))pipeline_memory.put(response.message)print(str(response.message))print()

结论

将对话记忆集成到轻量级的 ColBERT 检索代理中,赋予其上下文意识和个性化交互能力。

通过按照为 LlamaIndex 定制的本文,你可以构建一个复杂而简化的检索系统,既提供相关信息,又保持对话连贯性。

拥抱增强记忆的检索能力,提升您在 LlamaIndex 生态系统中的自然语言处理应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

后端方案设计文档结构模板可参考

文章目录 1 方案设计文档整体结构2 方案详细设计2.1 概要设计2.2 详细设计方案2.2.1 需求分析2.2.2 业务流程设计2.2.3 抽象类:实体对象建模2.2.4 接口设计2.2.5 存储设计 1 方案设计文档整体结构 一,现状:把项目的基本情况和背景都说清楚&a…

iA Writer for Mac:简洁强大的写作软件

在追求高效写作的今天,iA Writer for Mac凭借其简洁而强大的功能,成为了许多作家、记者和学生的首选工具。这款专为Mac用户打造的写作软件,以其独特的设计理念和实用功能,助你轻松打造高质量的文章。 iA Writer for Mac v7.1.2中文…

第2节:UIOTOS前端零代码应用 蓝图连线 信号值变化小示例02

目标 通过连线,实现信号值随机变化。 最终效果 实现过程 步骤1:接11节,选中底板设置其背景颜色 步骤2:拖入普通按钮V2组件,设置“text”值为“1”,并做form绑定 步骤3:选中按钮对输入框进行交…

Java 写一个死锁的例子

public class DeadLock {public static void main(String[] args) {Object lock1 new Object();Object lock2 new Object();new Thread(new A(lock1,lock2),"线程A").start();new Thread(new B(lock1,lock2),"线程B").start();} }class A implements Run…

Microsoft Universal Print 与 SAP 集成教程

引言 从 SAP 环境打印是许多客户的要求。例如数据列表打印、批量打印或标签打印。此类生产和批量打印方案通常使用专用硬件、驱动程序和打印解决方案来解决。 Microsoft Universal Print 是一种基于云的打印解决方案,它允许组织以集中化的方式管理打印机和打印机驱…

2023年蓝桥杯C++A组第三题:更小的数(双指针解法)

题目描述 小蓝有一个长度均为 n 且仅由数字字符 0 ∼ 9 组成的字符串,下标从 0 到 n − 1,你可以将其视作是一个具有 n 位的十进制数字 num,小蓝可以从 num 中选出一段连续的子串并将子串进行反转,最多反转一次。小蓝想要将选出的…

神经网络参数初始化

一、引入 在深度学习和机器学习的世界中,神经网络是构建智能系统的重要基石,参数初始化是神经网络训练过程中的一个重要步骤。在构建神经网络时,我们需要为权重和偏置等参数赋予初始值。对于偏置,通常可以将其初始化为0或者较小的…

【基础算法总结】滑动窗口一

滑动窗口 1.长度最小的字数组2.无重复字符的最长子串3.最大连续1的个数 III4.将 x 减到 0 的最小操作数 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃&…

工作任务管理平台B端实战项目作品集+WebApp项目源文件 figma格式

首先,作品集是什么?通常应该包含什么内容?为什么大家都在做自己的作品集呢? 作品集是个人或公司展示其过往工作成果的集合,通常包括各种专案、作品或成就的范例,用以展示创建者的技能、经验和专业水平。 …

Mysql--创建数据库

一、创建一个数据库 “db_classes” mysql> create database db_classes; mysql> show databases; -------------------- | Database | -------------------- | db_classes | | information_schema | | mysql | | performance_schema | |…

LabVIEW航空发动机主轴承试验器数据采集与监测

LabVIEW航空发动机主轴承试验器数据采集与监测 随着航空技术的迅速发展,对航空发动机性能的测试与监测提出了更高的要求。传统的数据采集与监测方法已难以满足当前高精度和高可靠性的需求,特别是在主轴承试验方面。基于LabVIEW的航空发动机主轴承试验器…

【LocalAI】(10):在autodl上编译embeddings.cpp项目,转换bge-base-zh-v1.5模型成ggml格式,本地运行main成功

1,关于 localai LocalAI 是一个用于本地推理的,与 OpenAI API 规范兼容的 REST API。 它允许您在本地使用消费级硬件运行 LLM(不仅如此),支持与 ggml 格式兼容的多个模型系列。支持CPU硬件/GPU硬件。 【LocalAI】&…

2024年武汉东湖高新水测成绩出来了

本次水测通过人员有1016名,通过的人数还是蛮多的,水测其实没有大家想象的那么难,现在职称评审都是水测线下评审的模式进行的。 水平测试分机考,笔试和面试答辩,各区随机安排选其一,机考就相当于考驾照刷题&…

Flutter笔记:Widgets Easier组件库(1)使用各式边框

Flutter笔记 Widgets Easier组件库(1):使用边框 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

如何在Linux上安装Python?2024Python安装教程

在Linux上安装Python并不难,对于Ubuntu或Debian系统,使用命令sudo apt install python3;对于CentOS、Red Hat或Fedora系统,使用命令sudo yum install python3。 如何在Linux上安装Python? 确切的安装步骤有所不同&am…

[1671]jsp教材管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 教材管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…

RAGFlow:安装与体验

服务器需要有docker,或者直接访问官方提供的demo: https://demo.ragflow.io/ docker-compose安装 需要确保 vm.max_map_count 不小于 262144 【更多】:sysctl -w vm.max_map_count=262144 克隆仓库:$ git clone https://github.com/infiniflow/ragflow.git 进入 doc…

【介绍下Unity编辑器扩展】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

【17】JAVASE-集合专题【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture:波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。…

【Java】java实现文件上传和下载(上传到指定路径/数据库/minio)

目录 上传到指定路径 一、代码层级结构 二、文件上传接口 三、使用postman进行测试; MultipartFile接收前端传递的文件:127.0.0.1:8082/path/uploadFile part接收前端传递的文件:127.0.0.1:8082/path/uploadFileByRequest 接收前端传递…