如何将Llama Index VectorStoreIndex与LangChain集成构建RAG应用
整合LangChain与Llama Index句子窗口检索的可行方案
核心思路
将Llama Index的句子窗口检索引擎封装为LangChain可调用的工具(Tool),让LangChain聊天机器人在处理用户查询时,自动调用该工具获取相关上下文片段,再结合LangChain的提示模板生成回复。这种方式既保留了Llama Index的高级检索能力,又能利用LangChain的对话管理与提示模板优势,且不会将完整文档直接塞入prompt。
步骤1:完善Llama Index句子窗口检索引擎
假设你已有基础代码,这里补充完整的索引构建与引擎初始化逻辑:
from llama_index import SimpleDirectoryReader, SentenceWindowNodeParser, VectorStoreIndex from llama_index.indices.postprocessor import MetadataReplacementPostProcessor # 加载文档 documents = SimpleDirectoryReader("data/").load_data() # 初始化句子窗口节点解析器(窗口大小设为3,可根据需求调整) node_parser = SentenceWindowNodeParser.from_defaults( window_size=3, window_metadata_key="window", original_text_metadata_key="original_text" ) # 创建VectorStoreIndex index = VectorStoreIndex.from_documents( documents, node_parser=node_parser ) # 构建句子窗口检索引擎(添加元数据替换后处理器,返回完整窗口上下文) sentence_window_engine = index.as_query_engine( similarity_top_k=3, node_postprocessors=[ MetadataReplacementPostProcessor(target_metadata_key="window") ] )
步骤2:将Llama Index引擎封装为LangChain Tool
通过LangChain的Tool类,把句子窗口检索功能包装成可被聊天机器人调用的工具:
from langchain.tools import Tool def retrieve_context_with_llamaindex(query: str) -> str: """使用Llama Index句子窗口检索获取相关上下文""" response = sentence_window_engine.query(query) return str(response) # 封装为LangChain Tool llamaindex_retrieval_tool = Tool( name="llamaindex_sentence_window_retrieval", func=retrieve_context_with_llamaindex, description="当需要获取文档中的相关信息来回答用户问题时调用此工具,输入为用户的查询内容" )
步骤3:整合到LangChain聊天机器人
使用LangChain的对话链结合工具调用,实现带检索能力的聊天机器人。这里以ChatOpenAI为例,结合自定义提示模板:
from langchain.chat_models import ChatOpenAI from langchain.chains import ConversationChain from langchain.memory import ConversationBufferMemory from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder # 初始化LLM llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.7) # 自定义提示模板(结合聊天历史、检索上下文与用户查询) prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个专业的聊天机器人,回答问题时请结合检索到的上下文、聊天历史和用户当前问题生成自然流畅的回复。如果检索到的上下文无法回答问题,直接告知用户即可。"), MessagesPlaceholder(variable_name="history"), ("user", "用户问题: {input}\n检索到的上下文: {retrieved_context}") ]) # 构建对话链,添加记忆与工具调用逻辑 memory = ConversationBufferMemory(return_messages=True) def chat_with_retrieval(input_text: str) -> str: # 先调用检索工具获取上下文 retrieved_context = llamaindex_retrieval_tool.run(input_text) # 生成回复 chain = ConversationChain(llm=llm, memory=memory, prompt=prompt) response = chain.predict(input=input_text, retrieved_context=retrieved_context) return response # 测试调用 print(chat_with_retrieval("请解释文档中的X概念?"))
如果需要让LLM自主判断是否调用检索工具,可使用LangChain的Agent框架:
from langchain.agents import initialize_agent, AgentType agent = initialize_agent( tools=[llamaindex_retrieval_tool], llm=llm, agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION, memory=memory, verbose=True ) # 测试Agent agent.run("请解释文档中的X概念?")
性能评估方案
针对你提到的评估指标,可通过以下方式实现:
- 响应速度:在每次查询前后记录时间戳,计算差值:
import time start_time = time.time() response = chat_with_retrieval("测试问题") elapsed_time = time.time() - start_time print(f"响应时间: {elapsed_time:.2f} 秒") - 回复人性化程度:可通过人工评估(设置流畅度、相关性、自然度等评分项),或借助LLM自动评分:
def evaluate_human_likeness(response: str, query: str) -> float: eval_prompt = f"请从流畅度、相关性、自然度三个维度给以下回复打分,总分10分:\n用户问题: {query}\n回复: {response}\n仅输出分数即可" score = llm.predict(eval_prompt) return float(score) - Token用量:使用
tiktoken库统计每次请求的prompt和completion的token数:import tiktoken def count_tokens(text: str, model: str = "gpt-3.5-turbo") -> int: encoding = tiktoken.encoding_for_model(model) return len(encoding.encode(text)) # 统计prompt和回复的token数 prompt_text = f"用户问题: {input_text}\n检索到的上下文: {retrieved_context}" prompt_tokens = count_tokens(prompt_text) response_tokens = count_tokens(response) total_tokens = prompt_tokens + response_tokens
内容的提问来源于stack exchange,提问作者JP1990
相关产品推荐
相关产品推荐

