请你用LangChain实现一个完整的RAG问答系统,包括文档加载、分割、向量化、检索和生成。
📋 面试问题
请你用LangChain实现一个完整的RAG问答系统,包括文档加载、分割、向量化、检索和生成。
✅ 期望回答
from langchain.document_loaders import TextLoader, PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
# 1. 加载文档
loader = PyPDFLoader('knowledge.pdf')
documents = loader.load()
# 2. 文档分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, chunk_overlap=50,
separators=['\n\n', '\n', '。', '!', '?', ';']
)
docs = text_splitter.split_documents(documents)
# 3. 向量化 + 存储
embeddings = HuggingFaceEmbeddings(
model_name='BAAI/bge-large-zh-v1.5',
model_kwargs={'device': 'cuda'}
)
vectorstore = Chroma.from_documents(
docs, embeddings,
persist_directory='./chroma_db'
)
# 4. 自定义Prompt
prompt_template = '''基于以下上下文回答问题。如果无法回答,直接说不知道。
{context}
问题:{question}
回答:'''
PROMPT = PromptTemplate(
template=prompt_template,
input_variables=['context', 'question']
)
# 5. 构建QA Chain
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model='gpt-4', temperature=0),
chain_type='stuff',
retriever=vectorstore.as_retriever(search_kwargs={'k': 4}),
chain_type_kwargs={'prompt': PROMPT},
return_source_documents=True
)
# 6. 查询
result = qa_chain({'query': '什么是RAG?'})
print(result['result']) # 回答
print(result['source_documents']) # 引用来源
关键设计决策:
- 选择适合中文的Embedding模型(BGE)
- 合理的chunk_size(500)和overlap(50)
- 自定义Prompt控制行为
- 返回来源文档实现可溯源