fdbw commited on
Commit
79b9b51
·
verified ·
1 Parent(s): b9816ee

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -0
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ from dotenv import load_dotenv
4
+ from langchain_community.vectorstores import FAISS
5
+ from langchain_community.document_loaders import TextLoader
6
+ from langchain.text_splitter import CharacterTextSplitter
7
+ from langchain_community.embeddings import SentenceTransformerEmbeddings
8
+ from langchain.prompts import PromptTemplate
9
+ from langchain_openai import ChatOpenAI
10
+ # 若使用本地模型,替换为以下导入
11
+ # from langchain_community.llms import HuggingFacePipeline
12
+ # import transformers
13
+
14
+ # 加载环境变量(HF Spaces需在Secrets中配置OPENAI_API_KEY)
15
+ load_dotenv()
16
+ openai_api_key = os.getenv("OPENAI_API_KEY")
17
+
18
+ # 配置路径
19
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
20
+ KNOWLEDGE_BASE_DIR = os.path.join(BASE_DIR, "knowledge_base")
21
+ FAMILY_TREE_PATH = os.path.join(KNOWLEDGE_BASE_DIR, "family_tree.txt")
22
+ PROMPT_TEMPLATE_PATH = os.path.join(KNOWLEDGE_BASE_DIR, "prompt_template.txt")
23
+ GENERATION_VERSES_PATH = os.path.join(KNOWLEDGE_BASE_DIR, "generation_verses.txt")
24
+
25
+ # 加载并处理知识库
26
+ def load_knowledge_base():
27
+ # 加载家谱数据
28
+ loader = TextLoader(FAMILY_TREE_PATH, encoding="utf-8")
29
+ documents = loader.load()
30
+ # 文本分割
31
+ text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)
32
+ docs = text_splitter.split_documents(documents)
33
+ # 初始化嵌入模型
34
+ embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
35
+ # 创建向量库
36
+ db = FAISS.from_documents(docs, embeddings)
37
+ return db
38
+
39
+ # 加载提示词模板
40
+ def load_prompt_template():
41
+ with open(PROMPT_TEMPLATE_PATH, "r", encoding="utf-8") as f:
42
+ prompt_template = f.read()
43
+ return PromptTemplate.from_template(prompt_template)
44
+
45
+ # 初始化RAG组件
46
+ db = load_knowledge_base()
47
+ prompt_template = load_prompt_template()
48
+
49
+ # 初始化大语言模型
50
+ llm = ChatOpenAI(
51
+ model_name="gpt-3.5-turbo",
52
+ temperature=0, # 0为精准回答,不生成冗余内容
53
+ api_key=openai_api_key
54
+ )
55
+
56
+ # 若使用本地模型(示例:Llama-2-7B),替换以下代码
57
+ # def load_local_llm():
58
+ # model_name = "meta-llama/Llama-2-7b-chat-hf"
59
+ # pipeline = transformers.pipeline(
60
+ # "text-generation",
61
+ # model=model_name,
62
+ # device_map="auto",
63
+ # model_kwargs={"torch_dtype": "auto"},
64
+ # max_new_tokens=500,
65
+ # temperature=0,
66
+ # )
67
+ # llm = HuggingFacePipeline(pipeline=pipeline)
68
+ # return llm
69
+ # llm = load_local_llm()
70
+
71
+ # 核心问答逻辑
72
+ def answer_question(question):
73
+ # 检索相关文档
74
+ retriever = db.as_retriever(search_kwargs={"k": 3}) # 取top3相关结果
75
+ relevant_docs = retriever.get_relevant_documents(question)
76
+ # 拼接检索结果
77
+ context = "\n".join([doc.page_content for doc in relevant_docs])
78
+ # 加载字辈表(补充上下文)
79
+ with open(GENERATION_VERSES_PATH, "r", encoding="utf-8") as f:
80
+ generation_verses = f.read()
81
+ context += "\n" + generation_verses
82
+ # 构建提示词
83
+ prompt = prompt_template.format(context=context, question=question)
84
+ # 调用LLM生成回答
85
+ response = llm.invoke(prompt)
86
+ return response.content
87
+
88
+ # 创建Gradio界面
89
+ with gr.Blocks(title="冯氏家谱RAG机器人") as demo:
90
+ gr.Markdown("# 冯氏家谱RAG机器人")
91
+ gr.Markdown("### 请输入关于冯氏家谱的问题,支持亲属关系、生卒信息、字辈世代查询")
92
+ gr.Markdown("#### 示例问题:\n1. 冯乔福的子女有谁?\n2. 冯仁杰的出生地是什么?\n3. 宗字辈的上一辈是什么字辈?")
93
+
94
+ with gr.Row():
95
+ question = gr.Textbox(label="输入问题", placeholder="请输入你的问题...", lines=2)
96
+ answer = gr.Textbox(label="回答结果", lines=5, interactive=False)
97
+
98
+ submit_btn = gr.Button("提交查询")
99
+ submit_btn.click(fn=answer_question, inputs=question, outputs=answer)
100
+
101
+ # 运行应用
102
+ if __name__ == "__main__":
103
+ demo.launch()