调用FAISS.from_documents时触发IndexError索引越界问题
问题:调用FAISS.from_documents时触发IndexError: list index out of range
问题描述
使用LangChain的FAISS模块从文档列表构建向量索引时,调用FAISS.from_documents(docs, embeddings)触发IndexError: list index out of range,错误指向FAISS源码中index = faiss.IndexFlatL2(len(embeddings[0]))这一行,说明生成的嵌入向量列表为空,无法获取第一个元素的长度。
我的代码
import os import streamlit as st import pickle import time from langchain_openai import OpenAI from langchain_openai import OpenAIEmbeddings from langchain.chains import RetrievalQAWithSourcesChain from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.document_loaders import UnstructuredURLLoader from dotenv import load_dotenv load_dotenv() # 从.env加载环境变量(主要是OpenAI API Key) st.title("链接研究工具") st.sidebar.title("新闻文章URL") urls = [] for i in range(1): url = st.sidebar.text_input(f"URL {i+1}") urls.append(url) process_url_clicked = st.sidebar.button("处理URL") file_path = "faiss_store_openai.pkl" llm = OpenAI(temperature=0.9, max_tokens=500) if process_url_clicked: loader = UnstructuredURLLoader(urls=urls) st.text("数据加载中...") data = loader.load() text_splitter = RecursiveCharacterTextSplitter( separators=['\n\n', '\n', '.', ','], chunk_size=1000 ) st.text("文本分割中...") docs = text_splitter.split_documents(data) embeddings = OpenAIEmbeddings() db = FAISS.from_documents(docs, embeddings) st.text("嵌入向量构建中...") time.sleep(2) query = st.text_input("问题: ") if query: if os.path.exists(file_path): with open(file_path, "rb") as f: vectorstore = pickle.load(f) chain = RetrievalQAWithSourcesChain.from_llm(llm=llm, retriever=vectorstore.as_retriever()) result = chain({"question": query}, return_only_outputs=True) # result格式为 {"answer": "", "sources": [] } st.header("答案") st.write(result["answer"]) # 显示来源(如果有) sources = result.get("sources", "") if sources: st.subheader("来源:") sources_list = sources.split("\n") for source in sources_list: st.write(source)
报错信息
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 535, in _run_script exec(code, module.__dict__) File "/Users/rahulsharma/Desktop/2_news_research_tool_project/main.py", line 41, in <module> db = FAISS.from_documents(docs, embeddings) File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/langchain_core/vectorstores.py", line 528, in from_documents return cls.from_texts(texts, embedding, metadatas=metadatas, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/langchain_community/vectorstores/faiss.py", line 966, in from_texts return cls.__from( File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/langchain_community/vectorstores/faiss.py", line 923, in __from index = faiss.IndexFlatL2(len(embeddings[0]))
环境信息
langchain: 0.1.3 python-dotenv: 1.0.0 streamlit: 1.31.1 unstructured: 0.12.5 tiktoken: 0.5.2 faiss-cpu: 1.7.4 libmagic: 1.0 python-magic: 0.4.27 python-magic-bin: None OpenAI: 1.13.3
原因分析
错误核心是embeddings为空列表,导致代码尝试访问embeddings[0]时触发索引越界。而embeddings为空的根源是输入的docs为空,可能的触发场景:
- 未输入有效的URL,或输入的URL无法加载到内容
UnstructuredURLLoader加载失败(比如URL无效、网络问题、页面内容无法解析)- 文本分割后未生成任何有效文档块(比如源内容全是分隔符)
解决方案
1. 添加输入有效性检查
在处理URL前过滤空URL,加载数据和分割文本后检查结果是否为空,避免后续无效操作:
修改process_url_clicked分支的代码:
if process_url_clicked: # 过滤空URL valid_urls = [url.strip() for url in urls if url.strip()] if not valid_urls: st.error("请输入有效的URL地址") st.stop() loader = UnstructuredURLLoader(urls=valid_urls) st.text("数据加载中...") data = loader.load() # 检查是否加载到内容 if not data: st.error("未能从URL加载到内容,请检查URL有效性或网络连接") st.stop() text_splitter = RecursiveCharacterTextSplitter( separators=['\n\n', '\n', '.', ','], chunk_size=1000, chunk_overlap=200 # 添加重叠部分,避免分割丢失上下文 ) st.text("文本分割中...") docs = text_splitter.split_documents(data) # 检查分割后是否有文档块 if not docs: st.error("文本分割后未生成有效文档块,请检查源页面内容") st.stop() embeddings = OpenAIEmbeddings() db = FAISS.from_documents(docs, embeddings) st.text("嵌入向量构建中...") # 保存向量索引到文件(原代码缺失此步骤,导致查询时读取不到新构建的索引) with open(file_path, "wb") as f: pickle.dump(db, f) st.success("向量索引构建完成并已保存")
2. 修复其他潜在问题
- 移除重复的
OpenAIEmbeddings导入(原代码中同时从langchain_openai和langchain_community导入,保留一个即可) - 给
RecursiveCharacterTextSplitter添加chunk_overlap参数,避免分割后上下文丢失 - 确保
.env文件中正确配置了OpenAI API Key,避免嵌入生成失败
预期结果
添加检查后,只有当输入有效URL、加载到内容并生成有效文档块时,才会执行FAISS向量索引构建,避免触发索引越界错误,同时构建完成的索引会保存到文件,供后续查询使用。
内容的提问来源于stack exchange,提问作者Dismay
相关产品推荐
相关产品推荐

