decula commited on
Commit
ce31327
·
1 Parent(s): 8ecf1c8

added langchain

Browse files
README_gemini_excel_rag.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gemini Flash 2.0 Excel RAG 系统
2
+
3
+ 这个项目利用 LangChain 调用 Google 的 Gemini Flash 2.0 模型,并使用 markitdown 库作为 Excel 导入工具,将数据存储到本地的向量数据库中。系统能够通过向量数据库中的 Excel 表格内容,以 RAG (检索增强生成) 的方式增强模型回答的准确性。
4
+
5
+ ## 功能特点
6
+
7
+ - 使用 Google 的 Gemini Flash 2.0 大语言模型
8
+ - 支持导入 Excel 文件到向量数据库
9
+ - 基于导入的 Excel 数据进行问答
10
+ - 使用 RAG 技术增强回答的准确性和相关性
11
+ - 提供友好的 Gradio Web 界面
12
+
13
+ ## 安装步骤
14
+
15
+ 1. 克隆或下载本项目代码
16
+
17
+ 2. 安装所需依赖包:
18
+
19
+ ```bash
20
+ pip install -r gemini_excel_requirements.txt
21
+ ```
22
+
23
+ 3. 获取 Google API 密钥:
24
+ - 访问 [Google AI Studio](https://makersuite.google.com/app/apikey)
25
+ - 创建一个 API 密钥
26
+ - 在 `gemini_excel_rag.py` 文件中替换 `YOUR_GOOGLE_API_KEY` 为您的实际 API 密钥
27
+
28
+ ## 使用方法
29
+
30
+ 1. 运行应用程序:
31
+
32
+ ```bash
33
+ python gemini_excel_rag.py
34
+ ```
35
+
36
+ 2. 在浏览器中访问显示的本地地址(通常是 http://127.0.0.1:7860)
37
+
38
+ 3. 使用界面:
39
+ - **导入 Excel 数据**:上传 Excel 文件并处理导入到向量数据库
40
+ - **查询问答**:输入问题,系统会基于导入的 Excel 数据回答
41
+ - **查看向量库内容**:搜索向量库中的内容,查看已导入的数据
42
+
43
+ ## 工作原理
44
+
45
+ 1. **数据导入流程**:
46
+ - 上传 Excel 文件
47
+ - 使用 pandas 读取 Excel 内容
48
+ - 将每行数据转换为文本格式
49
+ - 存储到 Chroma 向量数据库
50
+
51
+ 2. **查询回答流程**:
52
+ - 用户输入问题
53
+ - 系统在向量数据库中检索相关内容
54
+ - Gemini Flash 2.0 模型结合检索内容生成回答
55
+ - 返回增强后的回答给用户
56
+
57
+ ## 自定义配置
58
+
59
+ - 修改嵌入模型:可以在代码中更改 `embedding_model` 的初始化参数
60
+ - 调整文本分割参数:修改 `text_splitter` 的参数以适应不同的数据格式
61
+ - 更改 RAG 检索数量:在 `retriever` 的 `search_kwargs` 中调整 `k` 值
62
+
63
+ ## 注意事项
64
+
65
+ - 确保您有足够的网络连接以访问 Google API
66
+ - 大型 Excel 文件处理可能需要较长时间
67
+ - 向量数据库存储在本地 `./vector_store` 目录中
68
+
69
+ ## 依赖库
70
+
71
+ - langchain:用于构建 RAG 流程
72
+ - langchain-google-genai:连接 Gemini 模型
73
+ - gradio:提供 Web 界面
74
+ - pandas:处理 Excel 文件
75
+ - chromadb:向量数据库
76
+ - sentence-transformers:文本嵌入模型
77
+ - markitdown:Excel 内容提取工具
78
+
79
+ ## 许可证
80
+
81
+ 本项目使用 MIT 许可证。
gemini_excel_rag.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import torch
4
+ from langchain_google_genai import ChatGoogleGenerativeAI
5
+ from langchain.prompts import ChatPromptTemplate
6
+ from langchain.schema.runnable import RunnablePassthrough
7
+ from langchain.schema.output_parser import StrOutputParser
8
+ from langchain_community.vectorstores import Chroma
9
+ from langchain_community.embeddings import HuggingFaceEmbeddings
10
+ from langchain_core.documents import Document
11
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
12
+ from markitdown import ExcelExtractor
13
+ import pandas as pd
14
+ import numpy as np
15
+ import re
16
+
17
+ # 设置Google API密钥
18
+ os.environ["GOOGLE_API_KEY"] = "YOUR_GOOGLE_API_KEY" # 请替换为您的API密钥
19
+
20
+ # 设置向量数据库存储路径
21
+ VECTOR_STORE_PATH = "./vector_store"
22
+
23
+ # 初始化嵌入模型
24
+ embedding_model = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5")
25
+
26
+ # 初始化文本分割器
27
+ text_splitter = RecursiveCharacterTextSplitter(
28
+ chunk_size=500,
29
+ chunk_overlap=50,
30
+ separators=["\n\n", "\n", "。", "!", "?", ".", "!", "?", " ", ""]
31
+ )
32
+
33
+ # 初始化向量数据库
34
+ def get_vectorstore():
35
+ """获取向量数据库,如果不存在则创建一个空的"""
36
+ if os.path.exists(VECTOR_STORE_PATH):
37
+ return Chroma(persist_directory=VECTOR_STORE_PATH, embedding_function=embedding_model)
38
+ else:
39
+ vectorstore = Chroma.from_documents(
40
+ documents=[Document(page_content="初始化文档", metadata={"source": "初始化"})],
41
+ embedding=embedding_model,
42
+ persist_directory=VECTOR_STORE_PATH
43
+ )
44
+ vectorstore.persist()
45
+ return vectorstore
46
+
47
+ # 初始化LLM模型
48
+ def get_llm():
49
+ """初始化Gemini Flash 2.0模型"""
50
+ return ChatGoogleGenerativeAI(
51
+ model="gemini-flash-2.0",
52
+ temperature=0.7,
53
+ convert_system_message_to_human=True,
54
+ max_output_tokens=2048
55
+ )
56
+
57
+ # 创建RAG链
58
+ def create_rag_chain():
59
+ """创建RAG检索链"""
60
+ vectorstore = get_vectorstore()
61
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
62
+
63
+ # 创建提示模板
64
+ template = """
65
+ 你是一个专业的数据分析助手。请基于以下检索到的Excel表格数据回答用户的问题。
66
+ 如果检索内容中没有相关信息,请诚实地告知用户你不知道,不要编造答案。
67
+
68
+ 检索到的Excel表格数据:
69
+ {context}
70
+
71
+ 用户问题: {question}
72
+
73
+ 请提供详细、准确的回答,并在适当的情况下引用数据来源。
74
+ """
75
+
76
+ prompt = ChatPromptTemplate.from_template(template)
77
+
78
+ # 创建RAG链
79
+ llm = get_llm()
80
+ rag_chain = (
81
+ {"context": retriever, "question": RunnablePassthrough()}
82
+ | prompt
83
+ | llm
84
+ | StrOutputParser()
85
+ )
86
+
87
+ return rag_chain
88
+
89
+ # 处理Excel文件并添加到向量数据库
90
+ def process_excel_file(file_path):
91
+ """处理Excel文件并添加到向量数据库"""
92
+ try:
93
+ # 使用markitdown提取Excel内容
94
+ extractor = ExcelExtractor()
95
+ excel_content = extractor.extract(file_path)
96
+
97
+ # 将Excel内容分割成块
98
+ docs = text_splitter.split_text(excel_content)
99
+ documents = [Document(page_content=doc, metadata={"source": file_path}) for doc in docs]
100
+
101
+ # 添加到向量数据库
102
+ vectorstore = get_vectorstore()
103
+ vectorstore.add_documents(documents)
104
+ vectorstore.persist()
105
+
106
+ return f"成功处理Excel文件: {file_path},添加了{len(documents)}个文档块到向量数据库"
107
+ except Exception as e:
108
+ return f"处理Excel文件时出错: {str(e)}"
109
+
110
+ # 使用pandas直接处理Excel文件并添加到向量数据库
111
+ def process_excel_with_pandas(file_path):
112
+ """使用pandas处理Excel文件并添加到向量数据库"""
113
+ try:
114
+ # 读取Excel文件
115
+ df = pd.read_excel(file_path)
116
+
117
+ # 将每个表格行转换为文本
118
+ documents = []
119
+ for idx, row in df.iterrows():
120
+ # 将行转换为字符串格式
121
+ row_text = "\n".join([f"{col}: {val}" for col, val in row.items() if not pd.isna(val)])
122
+ # 创建文档
123
+ doc = Document(
124
+ page_content=row_text,
125
+ metadata={
126
+ "source": file_path,
127
+ "row": idx,
128
+ "sheet": "Sheet1" # 如果需要处理多个sheet,可以在这里修改
129
+ }
130
+ )
131
+ documents.append(doc)
132
+
133
+ # 添加到向量数据库
134
+ vectorstore = get_vectorstore()
135
+ vectorstore.add_documents(documents)
136
+ vectorstore.persist()
137
+
138
+ return f"成功处理Excel文件: {file_path},添加了{len(documents)}个行记录到向量数据库"
139
+ except Exception as e:
140
+ return f"处理Excel文件时出错: {str(e)}"
141
+
142
+ # 查询向量数据库
143
+ def query_vectorstore(query, k=5):
144
+ """直接查询向量数据库"""
145
+ vectorstore = get_vectorstore()
146
+ results = vectorstore.similarity_search(query, k=k)
147
+ return results
148
+
149
+ # 使用RAG链回答问题
150
+ def answer_question(question):
151
+ """使用RAG链回答问题"""
152
+ rag_chain = create_rag_chain()
153
+ response = rag_chain.invoke(question)
154
+ return response
155
+
156
+ # 创建Gradio界面
157
+ def create_interface():
158
+ with gr.Blocks(title="Gemini Flash 2.0 Excel RAG") as demo:
159
+ gr.HTML("<h1 style='text-align: center'>Gemini Flash 2.0 Excel RAG 系统</h1>")
160
+
161
+ with gr.Tab("导入Excel数据"):
162
+ with gr.Row():
163
+ excel_file = gr.File(label="上传Excel文件")
164
+ process_btn = gr.Button("处理并导入到向量数据库")
165
+ output_msg = gr.Textbox(label="处理结果")
166
+
167
+ process_btn.click(
168
+ process_excel_with_pandas,
169
+ inputs=[excel_file],
170
+ outputs=[output_msg]
171
+ )
172
+
173
+ with gr.Tab("查询问答"):
174
+ with gr.Row():
175
+ question_input = gr.Textbox(label="输入问题", placeholder="请输入您的问题...")
176
+ submit_btn = gr.Button("提交")
177
+ answer_output = gr.Textbox(label="回答", lines=10)
178
+
179
+ submit_btn.click(
180
+ answer_question,
181
+ inputs=[question_input],
182
+ outputs=[answer_output]
183
+ )
184
+
185
+ with gr.Tab("查看向量库内容"):
186
+ with gr.Row():
187
+ search_input = gr.Textbox(label="搜索关键词")
188
+ search_btn = gr.Button("搜索")
189
+ k_slider = gr.Slider(minimum=1, maximum=20, value=5, step=1, label="返回结果数量")
190
+ search_output = gr.JSON(label="搜索结果")
191
+
192
+ def format_search_results(query, k):
193
+ results = query_vectorstore(query, k=int(k))
194
+ formatted_results = []
195
+ for doc in results:
196
+ formatted_results.append({
197
+ "content": doc.page_content,
198
+ "metadata": doc.metadata,
199
+ "score": doc.metadata.get("score", "N/A")
200
+ })
201
+ return formatted_results
202
+
203
+ search_btn.click(
204
+ format_search_results,
205
+ inputs=[search_input, k_slider],
206
+ outputs=[search_output]
207
+ )
208
+
209
+ return demo
210
+
211
+ # 主函数
212
+ def main():
213
+ demo = create_interface()
214
+ demo.launch(share=False)
215
+
216
+ if __name__ == "__main__":
217
+ main()
gemini_excel_requirements.txt ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 基础依赖
2
+ gradio>=4.0.0
3
+ torch>=2.0.0
4
+ pandas>=2.0.0
5
+ numpy>=1.24.0
6
+
7
+ # LangChain相关依赖
8
+ langchain>=0.1.0
9
+ langchain-google-genai>=0.0.5
10
+ langchain-community>=0.0.13
11
+ langchain-core>=0.1.10
12
+
13
+ # 向量数据库相关
14
+ chromadb>=0.4.18
15
+ sentence-transformers>=2.2.2
16
+
17
+ # Excel处理相关
18
+ markitdown>=0.1.0
19
+ openpyxl>=3.1.2
20
+
21
+ # 嵌入模型
22
+ huggingface-hub>=0.19.0