张子阳的博客

首页 读书 技术 店铺 关于
张子阳的博客 首页 读书 技术 关于

LlamaIndex 查询csv文件 - Part.1

2025-04-30 张子阳 分类: 大语言模型

默认情况下,我们使用 SimpleDirectoryReader 加载文件时,是以纯文本的方式读取的。很多时候,我们面对的文本格式是多种多样的,例如常见的:PDF、CSV、HTML、Word、Json。这些文件类型,要么在存储时压缩了信息,例如CSV(将公共属性压缩在了首行);要么加入了额外的标记,例如: HTML(添加了诸如h1、p、div等标签)。如果按照默认方式加载,这些文件都将会被作为纯文本处理,这可能会在查询时产生错误的结果。本节将介绍,如何正确地加载csv格式的文件。

数据准备

之前我们介绍过player.txt文件,我们模拟了一份玩家信息的列表,然后针对这个文件进行提问。它的格式类似下面这样:

昵称​​:剑影随风 ​​区服​​:青云峰 ​​出生日期​​:2002-08-15 ​​年龄​​:22 ​​注册日期​​:2023-05-20 ​​注册时长​​:708天 ​​注册方式​​:微信 ​ 昵称​​:ShadowBlade_007 ​​区服​​:赤霄谷 ​​出生日期​​:1989-11-03 ​​年龄​​:35 ​​注册日期​​:2021-09-12 ​​注册时长​​:1324天 ​​注册方式​​:手机号 ... 省略若干行

我们将它转为csv格式,转换后,就变成了这样:

昵称,区服,出生日期,年龄,注册日期,注册时长,注册方式 剑影随风,青云峰,2002-08-15,22,2023-05-20,708天,微信 ShadowBlade_007,赤霄谷,1989-11-03,35,2021-09-12,1324天,手机号 玄霜飞雪,玄霜崖,2001-11-08,23,2024-02-14,440天,游客 追风逐月,青云峰,1990-05-19,34,2021-06-30,1429天,微信 血战八方,赤霄谷,1983-09-22,41,2020-05-18,1807天,手机号 ... 省略若干行

我们将这个csv文件保存为player.csv,然后将它放在工作目录下。

方式1:文本转换

既然大模型对纯文本的理解更天然,那么第一种方式,就是可以将csv文件再转换为纯文本文件,然后再进行进一步的处理。创建文件 csv_query1.py,代码类似这样:

import pandas as pd from llama_index.core import Document # 1. 加载 df = pd.read_csv("./player.csv") documents = [ Document( text=f"昵称:{row['昵称']}, 区服:{row['区服']}, 出生日期:{row['出生日期']}, 年龄:{row['年龄']}, 注册日期:{row['注册日期']}, 注册时长:{row['注册时长']}, 注册方式:{row['注册方式']}" ) for _, row in df.iterrows() ] # 后续代码保持一致

通过这种方式,我们等于是将csv又转换回了纯文本,并给每个数值添加了说明。虽然对于csv文件,我们有其他的替代方式,但是对于 数据库建表脚本(sql格式),如果想要让大模型正确的理解,就可以采用这种方式,将Sql脚本,转换成文本。

方式2:使用Data loader

除了上面的方式以外,更好的办法,是针对不同类型的文件,使用特定的数据加载器(Data Loader),来加载对应格式的文件。

因为数据格式非常多,官方也不可能覆盖所有格式,提供全部类型的加载器。所以推出了LlamaHub,这是一个插件集市,可以由广大开发者自行开发、共享加载器。除了加载器,还可以找到其他各种开发中可能用到的工具。它的地址是:llamahub.ai,标签卡选择 Data Loaders,可以检索已有的加载器。从中我们可以找到两个CSV加载器:CSVReader和PagedCSVReader。这两者的区别就是 CSVReader 会一次读取全部csv内容,适合小文件;PagedCSVReader 则会分页进行读取。

创建文件 csv_query2.py,使用 CSVReader 来加载文件:player.csv,下面是完整代码:

# 构建向量库 from dotenv import load_dotenv load_dotenv() # 配置模型 from llama_index.core import Settings, SimpleDirectoryReader from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.llms.openai import OpenAI Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-large") Settings.llm = OpenAI(model="gpt-4o") # 1. 加载 from llama_index.readers.file import CSVReader parser = CSVReader() file_extractor = {".csv": parser} documents = SimpleDirectoryReader( input_files=["player.csv"], file_extractor=file_extractor, encoding="utf-8").load_data() # utf-8 失效,默认会选择'gbk' # 2. 索引 import chromadb chroma_client = chromadb.PersistentClient(path="./chroma_db") chroma_collection = chroma_client.get_or_create_collection("player") from llama_index.vector_stores.chroma import ChromaVectorStore from llama_index.core import StorageContext vector_store = ChromaVectorStore(chroma_collection=chroma_collection) storage_context = StorageContext.from_defaults(vector_store=vector_store) from llama_index.core import VectorStoreIndex vector_index = VectorStoreIndex.from_documents( documents=documents, storage_context=storage_context ) vector_index.storage_context.persist(persist_dir="./chroma_db") # 3. 转换为查询引擎 query_engine = vector_index.as_query_engine() # 4. 查询 response = query_engine.query("寒冰法师 是什么时候注册的?") # 5. 打印结果 print(response)

执行这段代码,可以得到结果:寒冰法师是 2023 年 4 月 10 日注册的。 这和player.csv中的数据一致的。

在 SimpleDirectoryReader 中,我们配置了 encoding="utf-8" ,并且csv的格式也同样是 utf-8,但是在执行的过程中,却遇到了报错:Failed to load file player.csv with error: 'gbk' codec can't decode byte 0xa3 in position 84: illegal multibyte sequence. Skipping...
从错误信息来看,配置并没有生效,为了解决这个问题,我这里是将 csv 的编码格式调为了 gbk,就正常了。在windows系统上,对于中文的处理,编码规则可能默认为了gbk,且不能修改。

感谢阅读,希望这篇文章能给你带来帮助!