File size: 5,216 Bytes
3f35ad6 78db3e3 3f35ad6 78db3e3 79b9b51 3f35ad6 79b9b51 78db3e3 3f35ad6 78db3e3 3f35ad6 78db3e3 3f35ad6 78db3e3 f01a8cd 78db3e3 fbc3b56 78db3e3 3f35ad6 78db3e3 3f35ad6 78db3e3 f01a8cd 3f35ad6 78db3e3 9502f7f 78db3e3 3f35ad6 78db3e3 f01a8cd 3f35ad6 78db3e3 f01a8cd 78db3e3 3f35ad6 f01a8cd 3f35ad6 78db3e3 3f35ad6 f01a8cd 79b9b51 3f35ad6 78db3e3 3f35ad6 78db3e3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | # 导入核心依赖(修复所有模块路径)
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']}") |