Langchain中改进RAG能力的3种常用的扩展查询方法

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时计算 Flink 版,1000CU*H 3个月
简介: 有多种方法可以提高检索增强生成(RAG)的能力,其中一种方法称为查询扩展。我们这里主要介绍在Langchain中常用的3种方法

查询扩展技术涉及对用户的原始查询进行细化,以生成更全面和信息丰富的搜索。使用扩展后的查询将从向量数据库中获取更多相关文档。

1、Step Back Prompting

Take A Step Back: Evoking Reasoning Via Abstraction In Large Language Models

https://arxiv.org/pdf/2310.06117.pdf

这是google deep mind开发的一种方法,它使用LLM来创建用户查询的抽象。该方法将从用户查询中退后一步,以便更好地从问题中获得概述。LLM将根据用户查询生成更通用的问题。

下面是原始查询和后退查询的示例。

 {
     "Original_Query": "Could the members of The Police perform lawful arrests?",
     "Step_Back_Query": "what can the members of The Police do?",
 },
 {
     "Original_Query": "Jan Sindel’s was born in what country?",
     "Step_Back_Query": "what is Jan Sindel’s personal history?",
 }

下面代码演示了如何使用Langchain进行Step Back Prompting

 #---------------------Prepare VectorDB-----------------------------------
 # Build a sample vectorDB
 from langchain.text_splitter import RecursiveCharacterTextSplitter
 from langchain_community.document_loaders import WebBaseLoader
 from langchain_community.vectorstores import Chroma
 from langchain.embeddings import OpenAIEmbeddings
 import os

 os.environ["OPENAI_API_KEY"] = "Your OpenAI KEY"

 # Load blog post
 loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
 data = loader.load()

 # Split
 text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=0)
 splits = text_splitter.split_documents(data)

 # VectorDB
 embedding = OpenAIEmbeddings()
 vectordb = Chroma.from_documents(documents=splits, embedding=embedding)

 #-------------------Prepare Step Back Prompt Pipeline------------------------
 from langchain_core.output_parsers import StrOutputParser
 from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
 from langchain_core.runnables import RunnableLambda
 from langchain.chat_models import ChatOpenAI

 retriever = vectordb.as_retriever()
 llm = ChatOpenAI()

 # Few Shot Examples
 examples = [
     {
         "input": "Could the members of The Police perform lawful arrests?",
         "output": "what can the members of The Police do?",
     },
     {
         "input": "Jan Sindel’s was born in what country?",
         "output": "what is Jan Sindel’s personal history?",
     },
 ]

 # We now transform these to example messages
 example_prompt = ChatPromptTemplate.from_messages(
     [
         ("human", "{input}"),
         ("ai", "{output}"),
     ]
 )

 few_shot_prompt = FewShotChatMessagePromptTemplate(
     example_prompt=example_prompt,
     examples=examples,
 )

 prompt = ChatPromptTemplate.from_messages(
     [
         (
             "system",
             """You are an expert at world knowledge. Your task is to step back and paraphrase a question to a more generic step-back question, which is easier to answer. Here are a few examples:""",
         ),
         # Few shot examples
         few_shot_prompt,
         # New question
         ("user", "{question}"),
     ]
 )

 question_gen = prompt | llm | StrOutputParser()

 #--------------------------QnA using Back Prompt Technique-----------------
 from langchain import hub

 def format_docs(docs):
     doc_strings = [doc.page_content for doc in docs]
     return "\n\n".join(doc_strings)

 response_prompt = hub.pull("langchain-ai/stepback-answer")

 chain = (
     {
         # Retrieve context using the normal question
         "normal_context": RunnableLambda(lambda x: x["question"]) | retriever | format_docs,
         # Retrieve context using the step-back question
         "step_back_context": question_gen | retriever | format_docs,
         # Pass on the question
         "question": lambda x: x["question"],
     }
     | response_prompt
     | llm
     | StrOutputParser()
 )

 result = chain.invoke({"question": "What Task Decomposition that work in 2022?"})

在那个脚本中,我们的问题是

 Original Query: What Task Decomposition that work in 2022?

Step Back Prompting为

 Step Back Query: What are some examples of task decomposition in the current year?

这两个查询将用于提取相关文档,将这些文档组合在一起作为一个上下文,提供给LLM生成最终的答案。

 {
     # Retrieve context using the normal question
     "normal_context": RunnableLambda(lambda x: x["question"]) | retriever | format_docs,
     # Retrieve context using the step-back question
     "step_back_context": question_gen | retriever | format_docs,
     # Pass on the question
     "question": lambda x: x["question"],
 }

2、 Multi Query

Langchain Multi Query Retriever

https://python.langchain.com/docs/modules/data_connection/retrievers/MultiQueryRetriever

多步查询是一种使用LLM从第一个查询生成更多查询的技术。这种技术试图解决用户提示不是那么具体的情况。这些生成的查询将用于在矢量数据库中查找文档。

多步查询的目标是改进查询,使其与主题更加相关,从而从数据库中检索更多相关的文档。

因为Langchain 有详细的文档,我们就不贴代码了

3、Cross Encoding Re-Ranking

这个方法是多查询和交叉编码器重新排序的结合,当用户使用LLM生成更多的问题时,每个生成的查询都从向量数据库中提取一对文档。

这些提取的文档通过交叉编码器传递,获得与初始查询的相似度分数。然后对相关文档进行排序,并选择前5名作为LLM返回结果。

为什么需要挑选前5个文档?因为需要尽量避免从矢量数据库检索的不相关文档。这种选择确保交叉编码器专注于最相似和最有意义的文档,从而生成更准确和简洁的摘要。

 #------------------------Prepare Vector Database--------------------------
 # Build a sample vectorDB
 from langchain.text_splitter import RecursiveCharacterTextSplitter
 from langchain_community.document_loaders import WebBaseLoader
 from langchain_community.vectorstores import Chroma
 from langchain.embeddings import OpenAIEmbeddings
 from langchain.chat_models import ChatOpenAI
 import os

 os.environ["OPENAI_API_KEY"] = "Your API KEY"

 # Load blog post
 loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
 data = loader.load()

 llm = ChatOpenAI()

 # Split
 text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=0)
 splits = text_splitter.split_documents(data)

 # VectorDB
 embedding = OpenAIEmbeddings()
 vectordb = Chroma.from_documents(documents=splits, embedding=embedding)

 #--------------------Generate More Question----------------------------------
 #This function use to generate queries using LLM
 def create_original_query(original_query):
     query = original_query["question"]
     qa_system_prompt = """
             You are an AI language model assistant. Your task is to generate five 
         different versions of the given user question to retrieve relevant documents from a vector 
         database. By generating multiple perspectives on the user question, your goal is to help
         the user overcome some of the limitations of the distance-based similarity search. 
         Provide these alternative questions separated by newlines."""

     qa_prompt = ChatPromptTemplate.from_messages(
         [
             ("system", qa_system_prompt),
             ("human", "{question}"),
         ]
     )

     rag_chain = (
         qa_prompt
         | llm
         | StrOutputParser()
     )

     question_string = rag_chain.invoke(
         {"question": query}
     )

     lines_list = question_string.splitlines()
     queries = []
     queries = [query] + lines_list

     return queries

 #-------------------Retrieve Document and Cross Encoding--------------------
 from sentence_transformers import CrossEncoder
 from langchain_core.prompts import ChatPromptTemplate
 from langchain_core.runnables import RunnableLambda, RunnablePassthrough
 from langchain_core.output_parsers import StrOutputParser
 import numpy as np

 cross_encoder = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')

 #Cross Encoding happens in here
 def create_documents(queries):
     retrieved_documents = []
     for i in queries:
         results = vectordb.as_retriever().get_relevant_documents(i)
         docString = format_docs(results)
         retrieved_documents.extend(docString)


     unique_a = []
     #If there is duplication documents for each query, make it unique
     for item in retrieved_documents:
         if item not in unique_a:
             unique_a.append(item)

     unique_documents = list(unique_a)

     pairs = []
     for doc in unique_documents:
         pairs.append([queries[0], doc])

     #Cross Encoder Scoring
     scores = cross_encoder.predict(pairs)

     final_queries = []
     for x in range(len(scores)):
         final_queries.append({"score":scores[x],"document":unique_documents[x]})

     #Rerank the documents, return top 5
     sorted_list = sorted(final_queries, key=lambda x: x["score"], reverse=True)
     first_five_elements = sorted_list[:6]
     return first_five_elements

 #-----------------QnA Document-----------------------------------------------
 qa_system_prompt = """
         Assistant is a large language model trained by OpenAI. \
         Use the following pieces of retrieved context to answer the question. \
         If you don't know the answer, just say that you don't know. \

         {context}"""

 qa_prompt = ChatPromptTemplate.from_messages(
     [
         ("system", qa_system_prompt),
         ("human", "{question}"),
     ]
 )

 def format(docs):
     doc_strings = [doc["document"] for doc in docs]
     return "\n\n".join(doc_strings)


 chain = (
     # Prepare the context using below pipeline
     # Generate Queries -> Cross Encoding -> Rerank ->return context
     {"context": RunnableLambda(create_original_query)| RunnableLambda(create_documents) | RunnableLambda(format), "question": RunnablePassthrough()}
     | qa_prompt
     | llm
     | StrOutputParser()
 )

 result = chain.invoke({"question":"What Task Decomposition that work in 2022?"})

从上面代码主要是创建了两个用于生成查询和交叉编码的自定义函数。

create_original_query用于生成查询,它将返回5个生成的问题加上原始查询。

create_documents则根据6个问题(上面的5个生成问题和1个原始查询)检索24个相关文档。这24个相关文档可能重复,所以需要进行去重。

之后我们使用

 scores = cross_encoder.predict(pairs)

给出文档和原始查询之间的交叉编码分数。然后就是对文档重新排序,保留前5个文档。

总结

以上就是最常用的3种改进RAG能力扩展查询方法。当你在使用RAG时,并且没有得到正确或详细的答案,可以使用上述查询扩展方法来解决这些问题。希望所有这些技术可以用于你的下一个项目。

https://avoid.overfit.cn/post/39c514dafe0a4cabaa747c83ec1d4e3f

作者:Wayan Wardana

相关实践学习
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
目录
相关文章
|
4月前
|
数据采集 存储 人工智能
智能体(AI Agent)开发实战之【LangChain】(二)结合大模型基于RAG实现本地知识库问答
智能体(AI Agent)开发实战之【LangChain】(二)结合大模型基于RAG实现本地知识库问答
|
6月前
|
存储 人工智能 自然语言处理
LangChain RAG入门教程:构建基于私有文档的智能问答助手
本文介绍如何利用检索增强生成(RAG)技术与LangChain框架构建基于特定文档集合的AI问答系统。通过结合检索系统和生成机制,RAG能有效降低传统语言模型的知识局限与幻觉问题,提升回答准确性。文章详细展示了从环境配置、知识库构建到系统集成的全流程,并提供优化策略以改进检索与响应质量。此技术适用于专业领域信息检索与生成,为定制化AI应用奠定了基础。
1409 5
LangChain RAG入门教程:构建基于私有文档的智能问答助手
|
12月前
|
存储 人工智能 搜索推荐
解锁AI新境界:LangChain+RAG实战秘籍,让你的企业决策更智能,引领商业未来新潮流!
【10月更文挑战第4天】本文通过详细的实战演练,指导读者如何在LangChain框架中集成检索增强生成(RAG)技术,以提升大型语言模型的准确性与可靠性。RAG通过整合外部知识源,已在生成式AI领域展现出巨大潜力。文中提供了从数据加载到创建检索器的完整步骤,并探讨了RAG在企业问答系统、决策支持及客户服务中的应用。通过构建知识库、选择合适的嵌入模型及持续优化系统,企业可以充分利用现有数据,实现高效的商业落地。
418 6
|
12月前
|
SQL 数据库
LangChain-09 Query SQL DB With RUN GPT 查询数据库 并 执行SQL 返回结果
LangChain-09 Query SQL DB With RUN GPT 查询数据库 并 执行SQL 返回结果
117 2
|
7月前
|
Python 存储 自然语言处理
Langchain 和 RAG 最佳实践
这是一篇关于LangChain和RAG的快速入门文章,主要参考了由Harrison Chase和Andrew Ng讲授的​​Langchain chat with your data​​​课程。你可以在​​rag101仓库​​​中查看完整代码。本文翻译自我的英文博客,最新修订内容可随时参考:​​LangChain 与 RAG 最佳实践​​。
264 4
Langchain 和 RAG 最佳实践
|
8月前
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
195 2
|
机器学习/深度学习 SQL 数据挖掘
ADB优化器背后的秘密:如何用成本估算和规则引擎编织高效的查询网络?
【8月更文挑战第27天】AnalyticDB (ADB) 是一款专为大规模数据集设计的高性能分析型数据库。本文深入探讨ADB的优化器如何通过成本估算、规则引擎及机器学习等策略生成高效执行计划。成本估算是选择最优路径的关键;规则引擎通过谓词下推等手段优化查询;机器学习则使优化器能基于历史数据预测执行效率。结合示例代码与执行计划分析,展现了ADB在提升查询性能方面的强大功能。未来,ADB将继续进化以满足日益增长的大数据分析需求。
196 0
|
监控 数据处理 索引
整合LlamaIndex与LangChain构建高级的查询处理系统
该文阐述了如何结合LlamaIndex和LangChain构建一个扩展性和定制性强的代理RAG应用。LlamaIndex擅长智能搜索,LangChain提供跨平台兼容性。代理RAG允许大型语言模型访问多个查询引擎,增强决策能力和多样化回答。文章通过示例代码展示了如何设置LLM、嵌入模型、LlamaIndex索引及查询引擎,并将它们转换为LangChain兼容的工具,实现高效、精准的问题解答。通过多代理协作,系统能处理复杂查询,提高答案质量和相关性。
860 0
|
12月前
|
机器学习/深度学习 人工智能 开发框架
解锁AI新纪元:LangChain保姆级RAG实战,助你抢占大模型发展趋势红利,共赴智能未来之旅!
【10月更文挑战第4天】本文详细介绍检索增强生成(RAG)技术的发展趋势及其在大型语言模型(LLM)中的应用优势,如知识丰富性、上下文理解和可解释性。通过LangChain框架进行实战演练,演示从知识库加载、文档分割、向量化到构建检索器的全过程,并提供示例代码。掌握RAG技术有助于企业在问答系统、文本生成等领域把握大模型的红利期,应对检索效率和模型融合等挑战。
571 14
|
12月前
|
存储 人工智能 搜索推荐
揭秘LangChain+RAG如何重塑行业未来?保姆级实战演练,解锁大模型在各领域应用场景的神秘面纱!
【10月更文挑战第4天】随着AI技术的发展,大型语言模型在各行各业的应用愈发广泛,检索增强生成(RAG)技术成为推动企业智能化转型的关键。本文通过实战演练,展示了如何在LangChain框架内实施RAG技术,涵盖金融(智能风控与投资决策)、医疗(辅助诊断与病历分析)及教育(个性化学习推荐与智能答疑)三大领域。通过具体示例和部署方案,如整合金融数据、医疗信息以及学生学习资料,并利用RAG技术生成精准报告、诊断建议及个性化学习计划,为企业提供了切实可行的智能化解决方案。
463 5

热门文章

最新文章