
如何快速實(shí)現(xiàn)REST API集成以優(yōu)化業(yè)務(wù)流程
? ? ? ?有了對(duì)Advanced RAG概念的理解,現(xiàn)在讓我們將使用LlamaIndex作為實(shí)施的框架,BM25作為我們的排序函數(shù)。BM25算法是信息檢索系統(tǒng)中廣泛使用的排序函數(shù),特別是在文檔檢索中。它是概率信息檢索家族的一部分,是對(duì)經(jīng)典TF-IDF(術(shù)語(yǔ)頻率逆文檔頻率)方法的改進(jìn)。因此,我們將使用它作為我們的重新排序函數(shù)。
? ? ? ?在這篇文章中,我們將研究?jī)煞N不同的實(shí)現(xiàn)高級(jí)RAG的方法,一種是使用OpenAI LLM,另一種是在完全局部LLM(Mistral)。
首先在項(xiàng)目文件夾的根目錄中創(chuàng)建一個(gè)項(xiàng)目文件夾和包括如下內(nèi)容的.env文件。
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"LLM_URI="http://localhost:11434"
導(dǎo)入相關(guān)庫(kù)
import nest_asyncioimport osimport sysimport logging
from dotenv import load_dotenv, find_dotenv
from llama_index import ( SimpleDirectoryReader, ServiceContext, StorageContext, VectorStoreIndex,)from llama_index.query_engine import RetrieverQueryEnginefrom llama_index.retrievers import BM25Retrieverfrom llama_index.llms import OpenAI, Ollamafrom llama_index.embeddings import OllamaEmbeddingfrom llama_index.postprocessor import SentenceTransformerRerankfrom llama_index import QueryBundle
配置asyncio和logger
logging.basicConfig(stream=sys.stdout, level=logging.INFO)logging.getLogger().handlers = []logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
nest_asyncio.apply()
? ? ? ? 讓我們?cè)O(shè)計(jì)一個(gè)名為AdvancedRAG的類,該類具有以下3個(gè)函數(shù):
class AdvancedRAG: def __init__(self): _ = load_dotenv(find_dotenv()) # load documents self.documents = SimpleDirectoryReader("./data/", required_exts=['.pdf']).load_data()
# global variables used later in code after initialization self.retriever = None self.reranker = None self.query_engine = None
self.bootstrap()
def bootstrap(self): # initialize LLMs llm = OpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"), temperature=0, system_prompt="You are an expert on the Inflamatory Bowel Diseases and your job is to answer questions. Assume that all questions are related to the Inflammatory Bowel Diseases (IBD). Keep your answers technical and based on facts – do not hallucinate features.")
# initialize service context (set chunk size) service_context = ServiceContext.from_defaults(chunk_size=1024, llm=llm) nodes = service_context.node_parser.get_nodes_from_documents(self.documents)
# initialize storage context (by default it's in-memory) storage_context = StorageContext.from_defaults() storage_context.docstore.add_documents(nodes)
index = VectorStoreIndex( nodes=nodes, storage_context=storage_context, service_context=service_context, )
# We can pass in the index, doctore, or list of nodes to create the retriever self.retriever = BM25Retriever.from_defaults(similarity_top_k=2, index=index)
# reranker setup & initialization self.reranker = SentenceTransformerRerank(top_n=1, model="BAAI/bge-reranker-base")
self.query_engine = RetrieverQueryEngine.from_args( retriever=self.retriever, node_postprocessors=[self.reranker], service_context=service_context, )
def query(self, query): # will retrieve context from specific companies nodes = self.retriever.retrieve(query) reranked_nodes = self.reranker.postprocess_nodes( nodes, query_bundle=QueryBundle(query_str=query) )
print("Initial retrieval: ", len(nodes), " nodes") print("Re-ranked retrieval: ", len(reranked_nodes), " nodes")
for node in nodes: print(node)
for node in reranked_nodes: print(node)
response = self.query_engine.query(str_or_query_bundle=query) return response
Initialization方法(__init__):
環(huán)境設(shè)置:使用load_dotenv(find_dotenv())加載環(huán)境變量。這可能用于配置設(shè)置,如API密鑰或URL。
文檔加載:使用SimpleDirectoryReader從指定目錄加載文檔。這些文檔可能被用作檢索任務(wù)的語(yǔ)料庫(kù)。
全局變量:為檢索器、重排序器和query_engine設(shè)置占位符,它們可能是檢索和排序過(guò)程中的關(guān)鍵組件。
Bootstrap方法調(diào)用:調(diào)用Bootstrap方法來(lái)初始化各種組件。
Bootstrap方法:
初始化大型語(yǔ)言模型(llm):使用Ollama或OpenAI GPT-4設(shè)置語(yǔ)言模型實(shí)例(llm)。
初始化嵌入模型:使用OllamaEmbedding設(shè)置嵌入模型(embed_mode),該模型用于創(chuàng)建文本的矢量表示。
服務(wù)上下文:使用塊大小和模型(llm和embed_mode)配置服務(wù)上下文。
節(jié)點(diǎn)解析和存儲(chǔ):將文檔解析為節(jié)點(diǎn),并將其存儲(chǔ)在內(nèi)存數(shù)據(jù)庫(kù)中,以便快速訪問(wèn)。
索引創(chuàng)建:使用VectorStoreIndex創(chuàng)建索引,以高效檢索文檔。
Retriever初始化:初始化BM25Retriever,這是一個(gè)基于BM25算法的檢索模型。
重新排序初始化:使用SentenceTransformerRerank設(shè)置重新排序,重新排序檢索到的結(jié)果的相關(guān)性。
查詢引擎初始化:初始化一個(gè)查詢引擎,該引擎將檢索器和重排序器組合在一起以處理查詢。
Query方式:
檢索:檢索與給定查詢相關(guān)的節(jié)點(diǎn)(文檔)。
重排序:對(duì)檢索到的節(jié)點(diǎn)應(yīng)用重新排序。
響應(yīng)生成:使用查詢引擎根據(jù)查詢生成響應(yīng)。
if __name__ == "__main__": adv_rag = AdvancedRAG() resp = adv_rag.query("What is the impact of IBD in women ?") print(resp)
? ? ? ? ?當(dāng)您使用OpenAI GPT-4配置運(yùn)行上述代碼時(shí),以下應(yīng)該是輸出。
使用本地LLM和本地嵌入模型(Mistral)修改代碼,在上面的代碼中,只需注釋現(xiàn)有的OpenAI GPT-4 LLM并使用下面的代碼。
# initialize LLMsllm = Ollama(base_url=os.getenv("LLM_URI"), model="mistral")
初始化Mistral嵌入,如下所示
# initialize mistral embed modelembed_model = OllamaEmbedding(base_url=os.getenv("LLM_URI"), model_name="mistral")
現(xiàn)在,通過(guò)傳遞embed_mode來(lái)修改現(xiàn)有的服務(wù)上下文,如下所示:
# initialize service context (set chunk size)service_context = ServiceContext.from_defaults(chunk_size=1024, llm=llm, embed_model=embed_model)
? ? ? 現(xiàn)在,如果將代碼指向下面的本地LLM和本地嵌入來(lái)編寫代碼,那么輸出如下:
您可以清楚地看到,GPT-4和Mistral等2種方法生成的響應(yīng)發(fā)生了一些顯著變化,但具有置信度|重新排序分?jǐn)?shù)的檢索節(jié)點(diǎn)保持不變。
? ? 總之,高級(jí)檢索增強(qiáng)生成(Advanced Retrieval Augmented Generation,簡(jiǎn)稱RAG)是信息檢索和自然語(yǔ)言處理領(lǐng)域的一次重大飛躍。通過(guò)將BM25等最先進(jìn)的排名算法與先進(jìn)的重新排序技術(shù)和GPT-4或Mistral等尖端語(yǔ)言模型相集成,advanced RAG為處理復(fù)雜的查詢?nèi)蝿?wù)提供了一個(gè)強(qiáng)大而靈活的解決方案。正如我們?cè)谟懻撝信e例說(shuō)明的那樣,這種實(shí)際實(shí)現(xiàn)不僅展示了Advanced RAG的理論潛力,還展示了其在現(xiàn)實(shí)世界中的適用性。無(wú)論是在提高搜索引擎的準(zhǔn)確性、提高聊天機(jī)器人中響應(yīng)的相關(guān)性,還是在推進(jìn)知識(shí)系統(tǒng)的前沿領(lǐng)域,高級(jí)RAG證明了人工智能驅(qū)動(dòng)的語(yǔ)言理解和信息處理的不斷發(fā)展和成熟。Advanced RAG中檢索準(zhǔn)確性和上下文生成的融合為各種應(yīng)用中更智能、更靈敏、更知識(shí)淵博的系統(tǒng)鋪平了道路,預(yù)示著人工智能能力的新時(shí)代。
[1]?https://blog.stackademic.com/advanced-retrieval-augmented-generation-how-reranking-can-change-the-game-d06e12b77074
文章轉(zhuǎn)自微信公眾號(hào)@ArronAI
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)