从头开始构建 RAG 的 LLM 代理:综合指南

在这里插入图片描述
GPT-3、GPT-4 等 LLM 及其开源版本经常难以检索最新信息,有时会产生幻觉或不正确的信息。

检索增强生成 (RAG)是一种将 LLM 的强大功能与外部知识检索相结合的技术。RAG 使我们能够将 LLM 响应建立在事实、最新的信息之上,从而显著提高 AI 生成内容的准确性和可靠性。

在这篇博文中,我们将探索如何从头开始为 RAG 构建 LLM 代理,深入研究架构、实现细节和高级技术。我们将涵盖从 RAG 基础知识到创建能够进行复杂推理和执行任务的复杂代理的所有内容。

在深入构建 LLM 代理之前,让我们先了解什么是 RAG 以及它为什么重要。

RAG(检索增强生成)是一种将信息检索与文本生成相结合的混合方法。在 RAG 系统中:

  • 查询用于从知识库中检索相关文档。
  • 然后将这些文档与原始查询一起输入到语言模型中。
  • 该模型根据查询和检索到的信息生成响应。
    在这里插入图片描述
    这种方法有几个优点:
  • 提高准确性:通过根据检索到的信息做出反应,RAG 可以减少幻觉并提高事实准确性。
  • 最新信息:知识库可以定期更新,使系统能够访问最新信息。
  • 用户评论透明:该系统可以提供信息来源,增加信任并允许核实事实。

了解 LLM 代理

LLM 支持的代理
当您面对一个没有简单答案的问题时,您通常需要遵循几个步骤,仔细思考,并记住您已经尝试过的方法。语言模型应用程序中的 LLM 代理正是为此类情况而设计的。它们结合了全面的数据分析、战略规划、数据检索以及从过去行动中学习的能力来解决复杂问题。

什么是 LLM 代理?

LLM 代理是先进的人工智能系统,专为创建需要顺序推理的复杂文本而设计。他们可以提前思考,记住过去的对话,并使用不同的工具根据情况和所需风格调整他们的反应。

考虑法律领域的一个问题,例如:“在加利福尼亚州,特定类型的合同违约可能产生什么法律后果?”具有检索增强生成 (RAG) 系统的基本法学硕士可以从法律数据库中获取必要的信息。

更详细的场景是:“鉴于新的数据隐私法,公司面临的常见法律挑战是什么,法院如何处理这些问题?”这个问题比仅仅查找事实更深入。它涉及了解新规则、它们对不同公司的影响以及法院的回应。法学硕士代理会将此任务分解为子任务,例如检索最新法律、分析历史案例、总结法律文件以及根据模式预测趋势。

LLM 代理的组件

LLM代理一般由四个部分组成:

  • Agent/Brain:处理和理解语言的核心语言模型。
  • 规划:推理、分解任务和制定具体计划的能力。
  • 内存:保存过去交互的记录并从中学习。
  • 工具使用: 集成各种资源来执行任务。

代理/大脑

LLM 代理的核心是语言模型,该模型基于经过大量训练的数据来处理和理解语言。首先,您需要给它一个特定的提示,指导代理如何响应、使用哪些工具以及要实现的目标。您可以使用适合特定任务或交互的角色来定制代理,从而提高其性能。

内存

记忆组件通过保存过去操作的记录来帮助 LLM 代理处理复杂任务。记忆主要有两种类型:

  • 短期记忆: 就像一个记事本,记录正在进行的讨论。
  • 长期记忆:像日记一样的功能,存储过去互动的信息以学习模式并做出更好的决策。

通过融合这些类型的记忆,代理可以提供更加定制化的响应并记住用户的长期偏好,从而创建更加紧密和相关的交互。

规划

规划使 LLM 代理能够推理、将任务分解为可管理的部分,并随着任务的发展调整计划。规划涉及两个主要阶段:

  • 计划制定:将任务分解为更小的子任务。
  • 计划反思:审查和评估计划的有效性,结合反馈意见完善策略。

思路链(CoT)和思路树(ToT)等方法有助于这一分解过程,让代理探索解决问题的不同路径。

设置环境

要构建我们的 RAG 代理,我们需要设置开发环境。我们将使用 Python 和几个关键库:

  1. 浪链:用于协调我们的 LLM 和检索组件
  2. 浓度:作为文档嵌入的向量存储
  3. OpenAI 的 GPT 模型:作为我们的基础 LLM(如果愿意,你可以用开源模型替代它)
  4. FastAPI:用于创建一个简单的 API 来与我们的代理进行交互

让我们开始设置我们的环境:

# Create a new virtual environment
python -m venv rag_agent_env
source rag_agent_env/bin/activate # On Windows, use `rag_agent_env\Scripts\activate`
# Install required packages
pip install langchain chromadb openai fastapi uvicorn
Now, let's create a new Python file called rag_agent.py and import the necessary libraries:
[code language="PYTHON"]
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.llms import OpenAI
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
import os
# Set your OpenAI API key
os.environ["OPENAI_API_KEY"] = "your-api-key-here"

构建简单的RAG系统

现在我们已经设置好了环境,让我们构建一个基本的 RAG 系统。我们将首先从一组文档中创建一个知识库,然后使用它来回答查询。

步骤 1:准备文件

首先,我们需要加载并准备文档。在本例中,我们假设有一个名为 knowledge_base.txt 的文本文件,其中包含一些有关 AI 和机器学习的信息。

# Load the document
# Load the document
loader = TextLoader("knowledge_base.txt")
documents = loader.load()
# Split the documents into chunks
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# Create embeddings
embeddings = OpenAIEmbeddings()
# Create a vector store
vectorstore = Chroma.from_documents(texts, embeddings)

步骤 2:创建基于检索的 QA 链

现在我们有了向量存储,我们可以创建一个基于检索的 QA 链:

# Create a retrieval-based QA chain
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=vectorstore.as_retriever())

步骤 3:查询系统

我们现在可以查询我们的 RAG 系统:

query = "What are the main applications of machine learning?"
result = qa.run(query)
print(result)

步骤4:创建LLM代理

虽然我们简单的RAG系统很有用,但它非常有限。让我们通过创建一个LLM代理来增强它,该代理可以执行更复杂的任务并对它检索到的信息进行推理。

LLM代理是一种人工智能系统,它可以使用工具并决定采取哪些行动。我们将创建一个代理,它不仅可以回答问题,还可以执行网络搜索和基本计算。

首先,让我们为代理定义一些工具:

from langchain.agents import Tool
from langchain.tools import DuckDuckGoSearchRun
from langchain.tools import BaseTool
from langchain.agents import initialize_agent
from langchain.agents import AgentType
# Define a calculator tool
class CalculatorTool(BaseTool):
name = "Calculator"
description = "Useful for when you need to answer questions about math"
def _run(self, query: str) try:return str(eval(query))except:return "I couldn't calculate that. Please make sure your input is a valid mathematical expression."
# Create tool instances
search = DuckDuckGoSearchRun()
calculator = CalculatorTool()
# Define the tools
tools = [Tool(name="Search",func=search.run,description="Useful for when you need to answer questions about current events"),
Tool(name="RAG-QA",func=qa.run,description="Useful for when you need to answer questions about AI and machine learning"),
Tool(name="Calculator",func=calculator._run,description="Useful for when you need to perform mathematical calculations")
]
# Initialize the agent
agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)

现在我们有了一个代理,它可以使用我们的RAG系统,执行web搜索和计算。让我们来测试一下:

result = agent.run("What's the difference between supervised and unsupervised learning? Also, what's 15% of 80?")
print(result)

这个代理展示了LLM代理的一个关键优势:它们可以组合多个工具和推理步骤来回答复杂的查询。

用先进的RAG技术增强Agent

虽然我们目前的RAG系统运行良好,但我们可以使用一些先进的技术来提高其性能:

a)基于密集通道检索(DPR)的语义搜索

与使用简单的基于嵌入的检索不同,我们可以实现DPR以实现更准确的语义搜索:

from transformers import DPRQuestionEncoder, DPRContextEncoder
question_encoder = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
context_encoder = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
# Function to encode passages
def encode_passages(passages):
return context_encoder(passages, max_length=512, return_tensors="pt").pooler_output
# Function to encode query
def encode_query(query):
return question_encoder(query, max_length=512, return_tensors="pt").pooler_output

b)查询扩展

我们可以使用查询扩展来提高检索性能:

from transformers import T5ForConditionalGeneration, T5Tokenizer
model = T5ForConditionalGeneration.from_pretrained("t5-small")
tokenizer = T5Tokenizer.from_pretrained("t5-small")
def expand_query(query):
input_text = f"expand query: {query}"
input_ids = tokenizer.encode(input_text, return_tensors="pt")
outputs = model.generate(input_ids, max_length=50, num_return_sequences=3)
expanded_queries = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
return expanded_queries

c)迭代细化

我们可以实现一个迭代的细化过程,其中代理可以提出后续问题来澄清或扩展其初始检索:

def iterative_retrieval(initial_query, max_iterations=3):
query = initial_query
for _ in range(max_iterations):
result = qa.run(query)
clarification = agent.run(f"Based on this result: '{result}', what follow-up question should I ask to get more specific information?")
if clarification.lower().strip() == "none":
break
query = clarification
return result
# Use this in your agent's process

实现多智能体系统

为了处理更复杂的任务,我们可以实现一个多智能体系统,其中不同的智能体专注于不同的领域。这里有一个简单的例子:

class SpecialistAgent:
def __init__(self, name, tools):
self.name = name
self.agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
def run(self, query):
return self.agent.run(query)
# Create specialist agents
research_agent = SpecialistAgent("Research", [Tool(name="RAG-QA", func=qa.run, description="For AI and ML questions")])
math_agent = SpecialistAgent("Math", [Tool(name="Calculator", func=calculator._run, description="For calculations")])
general_agent = SpecialistAgent("General", [Tool(name="Search", func=search.run, description="For general queries")])
class Coordinator:
def __init__(self, agents):
self.agents = agents
def run(self, query):
# Determine which agent to use
if "calculate" in query.lower() or any(op in query for op in ['+', '-', '*', '/']):
return self.agents['Math'].run(query)
elif any(term in query.lower() for term in ['ai', 'machine learning', 'deep learning']):
return self.agents['Research'].run(query)
else:
return self.agents['General'].run(query)
coordinator = Coordinator({'Research': research_agent, 'Math': math_agent, 'General': general_agent})
# Test the multi-agent system
result = coordinator.run("What's the difference between CNN and RNN? Also, calculate 25% of 120.")
print(result)

这种多代理系统允许专门化,可以更有效地处理更广泛的查询。

评估和优化RAG代理

为了确保我们的RAG代理运行良好,我们需要实施评估指标和优化技术:

a)相关性评价

我们可以使用BLEU、ROUGE或BERTScore等指标来评估检索文档的相关性:

from bert_score import score
def evaluate_relevance(query, retrieved_doc, generated_answer):
P, R, F1 = score([generated_answer], [retrieved_doc], lang="en")
return F1.mean().item()

b)答案质量评价

我们可以使用人工评估或自动化指标来评估答案的质量:

from nltk.translate.bleu_score import sentence_bleu
def evaluate_answer_quality(reference_answer, generated_answer):
return sentence_bleu([reference_answer.split()], generated_answer.split())
# Use this to evaluate your agent's responses

未来方向与挑战

当我们展望RAG代理的未来时,出现了几个令人兴奋的方向和挑战:

  1. 多模态RAG:扩展RAG以合并图像、音频和视频数据。
    2.联邦RAG:跨分布式、保护隐私的知识库实现RAG。
  2. 持续学习:为RAG代理开发方法,以随时更新其知识库和模型。
  3. 伦理考虑:解决RAG系统中的偏见、公平性和透明度问题。
  4. 可扩展性:为大规模、实时应用优化RAG。

结论

从头开始为RAG构建LLM代理是一个复杂但有益的过程。我们已经介绍了RAG的基础知识,实现了一个简单的系统,创建了一个LLM代理,用高级技术增强了它,探索了多代理系统,并讨论了评估和优化策略。

在此,我满怀期待地邀请您,即刻启程,一同踏入这片充满机遇与启迪的网络空间,让知识的力量照亮我们的前行之路。您的每一次访问,都是对我们工作的最大肯定与激励;您的每一份收获,都是我们不懈努力的最佳回馈。期待在网站上与您相遇,共赴知识探索之约!---------深度学习。

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

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

相关文章

还敢乱买智能猫砂盆?今天扒一扒糯雪、鸟语花香、CEWEY智能猫砂盆!

在这高科技迅速发展的时代,连猫咪用来拉屎的屎盆子也变成了全自动化,从普通的猫砂盆变成了智能猫砂盆,让铲屎官再也不用每天赶回家铲屎给猫整理烂摊子,实在是非常轻松。所以那个时候的我也果断扔掉了家里的猫砂盆,转而…

电子电路学习笔记(4)三极管

部分内容参考链接: 电子电路学习笔记(5)——三极管_三极管 箭头-CSDN博客 模拟电子技术基础笔记(4)——晶体三极管_集电结的单向导电性-CSDN博客 硬件基本功-36-三极管Ib电流如何控制Ic电流_哔哩哔哩_bilibili MOS…

使用DC/AC电源模块时需要注意的事项

BOSHIDA 使用DC/AC电源模块时需要注意的事项 1. 仔细阅读和理解产品说明书:在使用DC/AC电源模块之前,应该仔细阅读和理解产品说明书,了解其性能特点、技术要求和使用方法,以确保正确使用和避免潜在的安全风险。 2. 选择适当的电…

源代码编译安装LAMP

Apache简介 主要特点 开放源代码,跨平台应用 支持多种网页编程程序 模块化设计,运行稳定,良好得安全性 软件版本 1.X 目前最高版本是1.3,运行稳定 向下兼容性较好,但缺乏一些较新得功能 2.X 目前最高版本是2.4 …

PDF处理篇:如何调整 PDF 图像的大小

将视觉效果无缝集成到 PDF 中的能力使它们成为强大的通信工具。然而,笨拙的图像大小会迅速扰乱文档的流程,阻碍清晰度和专业性。幸运的是,GeekerPDF 和Adobe Acrobat等流行的应用程序提供了用户友好的解决方案来应对这一挑战。这个全面的指南…

Google 发布了最新的开源大模型 Gemma 2,本地快速部署和体验

Gemma 2 是 Google 最新发布的开源大语言模型。它有两种规模:90 亿(9B)参数和 270 亿(27B)参数,分别具有基础(预训练)和指令调优版本,拥有 8K Tokens 的上下文长度&#…

Vue3 特点以及优势-源码解剖

Vue3 特点以及优势-Vue3.4源码解剖 Vue3 特点以及优势 1.声明式框架 命令式和声明式区别 早在 JQ 的时代编写的代码都是命令式的,命令式框架重要特点就是关注过程声明式框架更加关注结果。命令式的代码封装到了 Vuejs 中,过程靠 vuejs 来实现 声明式代…

关于 VuePress 的插件

插件就好比第三方功能,例如增加一个阅读进度条、增加光标效果等。VuePress 官网对插件的介绍:插件通常会为 VuePress 添加全局功能。 这里简单介绍几个本站用的插件吧! ‍ ‍ 插件就好比第三方功能,例如增加一个阅读进度条、增…

如何实现在短信链接中直接打开微信小程序

你是否有过这样的体验,收到一条短信,里面有一个链接,点击后就直接打开了微信,并且进入了一个小程序。这种神奇的功能是如何实现的呢?本文将为你揭晓答案。 利用微信URL Link 接口生成链接 要实现短信中的链接直接打开…

VSG虚拟同步发电机simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 VSG虚拟同步发电机simulink建模与仿真,虚拟同步发电机(Virtual Synchronous Generator, VSG)技术是电力电子领域的一项重要创新&#xff0c…

Golang 依赖注入设计哲学|12.6K 的依赖注入库 wire

一、前言 线上项目往往依赖非常多的具备特定能力的资源,如:DB、MQ、各种中间件,以及随着项目业务的复杂化,单一项目内,业务模块也逐渐增多,如何高效、整洁管理各种资源十分重要。 本文从“术”层面&#…

爆火AI惨遭阉割,1600万美国年轻人集体「失恋」? Character AI被爆资金断裂,00后炸了

【新智元导读】最近,在美国00后中爆火的Character AI,竟然把聊天机器人对话模型给「阉割」了?愤怒的年轻人们冲进社区,抱怨的声浪快要掀翻天了!而这背后,似乎还有谷歌或Meta的授意。 美国当今最火爆的社交…

看个病都有大模型陪诊了!上海市第一人民医院主导,一手体验在此

现在看个病,都有大模型全程陪诊了。 这是上海市第一人民医院此时此时正在发生的事情—— AI就医助理,无需下载APP,打开支付宝就能用。 从诊前预约挂号、在线取号,到诊中院内导航、排队叫号、扫码支付,再到诊后的报告…

基于SpringBoot高校体育运动会管理系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…

KVB交易平台 :市场迎来新热潮!铜价会持续上涨吗?

近期,全球铜价出现明显上涨趋势。韩国光阳LME仓库的铜库存显著下降,市场对即时需求的增加作出了积极反应。供应端的紧张和需求端的复苏共同推动了铜价的上涨。 KVB外汇 分析师们对未来铜价保持谨慎乐观态度,认为长期内铜价有望保持稳定甚至进…

【面试系列】UI设计师高频面试题及详细解答

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…

守望先锋2延迟高、卡顿、丢包的解决方法一览

守望先锋2/ow2是一款在全球范围内拥有超高热度的特殊游戏,因为该作在一定程度上是FPS游戏融合了MOBA元素,守望先锋2中的每一位英雄之间都有克制因素,使其技能点形成闭环逻辑,提升了游戏的可重复游戏性和趣味性。不过很多玩家在游玩…

三菱A系列网络连接

寄存器名 读写 寄存器类型 变量类型 寄存器范围 说明 X##1 R/W BIT I/O离散 0-7FF Input Y##1 R/W BIT I/O离散 0-7FF Output M##1 R/W BIT I/O离散 0-9255 Internal relay B##1 R/W BIT I/O离散 0-3FF Link relay F##1 R/W BIT I…

电子邮件OTP验证身份认证接口API服务商比较

电子邮件OTP验证身份认证接口API服务商如何正确选择? 电子邮件OTP验证是一种广泛应用且安全的身份认证方式。AokSend将比较几家主要的电子邮件OTP验证身份认证接口API服务商,帮助企业选择合适的解决方案。 电子邮件OTP:验证优势 可以为用户…

【硬件模块】SGP30气体传感器

SGP30 这是SGP30官方文档里开头的介绍,简单来说就是SGP30是一个数字多像素气体传感器,然后具有长期稳定性和低漂移。 这些我们都不用管,我们只需要知道SGP30是通过I2C来通信的,并且可以采集的数据有CO2和TVOC的含量。TVOC是“To…