Download app.py from fdbw/fzd8: direct link, hf CLI and curl.
- Browser
- Download file 5.22 kB
-
https://huggingface.co/spaces/fdbw/fzd8/resolve/main/app.py
- Command line
-
hf download hf://spaces/fdbw/fzd8/app.py
-
curl -L -o app.py https://huggingface.co/spaces/fdbw/fzd8/resolve/main/app.py
5.22 kB
| # 导入核心依赖(修复所有模块路径) | |
| import os | |
| # 环境变量管理(建议使用 python-dotenv) | |
| from dotenv import load_dotenv | |
| load_dotenv() # 加载 .env 文件中的环境变量 | |
| # -------------------------- | |
| # 1. 文本分割器:从 langchain_text_splitters 导入(v0.1.0+ 新版本路径) | |
| # -------------------------- | |
| from langchain_text_splitters import CharacterTextSplitter | |
| # -------------------------- | |
| # 2. 文档加载器:仍在 langchain_community 中 | |
| # -------------------------- | |
| from langchain_community.document_loaders import TextLoader | |
| # -------------------------- | |
| # 3. 嵌入模型:根据版本选择路径 | |
| # -------------------------- | |
| # 方式1:OpenAI 嵌入(需安装 langchain-openai) | |
| from langchain_openai import OpenAIEmbeddings | |
| # 方式2:本地 HuggingFace 嵌入(需安装 sentence-transformers) | |
| # from langchain_community.embeddings import HuggingFaceEmbeddings | |
| # -------------------------- | |
| # 4. 向量存储:仍在 langchain_community 中 | |
| # -------------------------- | |
| from langchain_community.vectorstores import Chroma | |
| # -------------------------- | |
| # 5. 大模型:根据版本选择路径 | |
| # -------------------------- | |
| # 方式1:OpenAI Chat 模型(需安装 langchain-openai) | |
| from langchain_openai import ChatOpenAI | |
| # 方式2:本地 Ollama 模型(需安装 langchain-community 和 ollama) | |
| # from langchain_community.llms import Ollama | |
| # -------------------------- | |
| # 6. RetrievalQA:仍在 langchain_community 中 | |
| # -------------------------- | |
| from langchain_community.chains import RetrievalQA | |
| # 配置环境变量(也可通过 .env 文件设置) | |
| os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "your-openai-api-key") # 替换为你的 API Key | |
| def load_and_split_documents(file_path="docs/knowledge.txt"): | |
| """加载文档并分割为小片段""" | |
| # 确保文档目录存在 | |
| os.makedirs(os.path.dirname(file_path), exist_ok=True) | |
| # 若文档不存在,创建临时测试文档 | |
| if not os.path.exists(file_path): | |
| with open(file_path, "w", encoding="utf-8") as f: | |
| f.write("LangChain 是一个用于构建 LLM 应用的框架,支持检索增强生成(RAG)等功能。\n") | |
| f.write("RetrievalQA 是 LangChain 中用于检索问答的核心链,在 v0.1.0 后迁移到了 langchain_community 模块。\n") | |
| f.write("CharacterTextSplitter 在 v0.1.0 后迁移到了 langchain_text_splitters 模块。\n") | |
| # 1. 加载文档 | |
| loader = TextLoader(file_path, encoding="utf-8") | |
| documents = loader.load() | |
| # 2. 分割文档(修复后的文本分割器) | |
| text_splitter = CharacterTextSplitter( | |
| chunk_size=1000, # 每个片段的字符数 | |
| chunk_overlap=200, # 片段间重叠字符数 | |
| separator="\n" | |
| ) | |
| split_docs = text_splitter.split_documents(documents) | |
| return split_docs | |
| def create_vector_store(docs): | |
| """创建向量存储(使用 Chroma 本地向量库)""" | |
| # 初始化嵌入模型 | |
| # 方式1:OpenAI 嵌入 | |
| embeddings = OpenAIEmbeddings(model="text-embedding-3-small") | |
| # 方式2:本地 HuggingFace 嵌入 | |
| # embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5") | |
| # 创建向量库并存储文档 | |
| vector_store = Chroma.from_documents( | |
| documents=docs, | |
| embedding=embeddings, | |
| persist_directory="./chroma_db" # 向量库持久化路径 | |
| ) | |
| # Chroma v0.4+ 不再需要手动 persist() | |
| return vector_store | |
| def create_retrieval_qa_chain(vector_store): | |
| """创建 RetrievalQA 检索问答链""" | |
| # 1. 初始化大模型 | |
| # 方式1:OpenAI GPT-3.5/4 | |
| llm = ChatOpenAI( | |
| model_name="gpt-3.5-turbo", | |
| temperature=0.1 # 温度越低,回答越稳定 | |
| ) | |
| # 方式2:本地 Ollama 模型(如 Llama3) | |
| # llm = Ollama(model="llama3:8b", temperature=0.1) | |
| # 2. 创建检索器(从向量库中检索相关文档) | |
| retriever = vector_store.as_retriever( | |
| search_kwargs={"k": 3} # 检索前 3 个最相关的文档 | |
| ) | |
| # 3. 创建 RetrievalQA 链 | |
| qa_chain = RetrievalQA.from_chain_type( | |
| llm=llm, | |
| chain_type="stuff", # 链类型:stuff/map_reduce/refine 等 | |
| retriever=retriever, | |
| return_source_documents=True # 是否返回检索到的源文档 | |
| ) | |
| return qa_chain | |
| if __name__ == "__main__": | |
| # 1. 加载并分割文档 | |
| docs = load_and_split_documents() | |
| # 2. 创建向量存储 | |
| vector_store = create_vector_store(docs) | |
| # 3. 创建 RetrievalQA 链 | |
| qa_chain = create_retrieval_qa_chain(vector_store) | |
| # 4. 测试问答 | |
| query = "CharacterTextSplitter 在 LangChain 新版本中被迁移到了哪里?" | |
| result = qa_chain.invoke({"query": query}) # v0.1.0+ 推荐使用 invoke() 替代 __call__ | |
| # 输出结果 | |
| print("===== 问题 =====") | |
| print(query) | |
| print("\n===== 回答 =====") | |
| print(result["result"]) | |
| print("\n===== 参考文档 =====") | |
| for i, doc in enumerate(result["source_documents"]): | |
| print(f"\n文档 {i+1}:") | |
| print(f"内容:{doc.page_content}") | |
| print(f"来源:{doc.metadata['source']}") |