一. 环境准备
1. 安装Ollama
Linux终端运行:
curl -fsSL https://ollama.com/install.sh | sh # Linux/MacOS
winget install ollama # Windows
2. 下载模型
Ollama支持多种模型:
7B基础模型:
ollama pull llama2
轻量级高效模型:
ollama pull mistral
作者选择了后者,读者可根据本机配置自由选择。
3. 验证Ollama运行
测试文本生成:
ollama run mistral "Hello world"
二. Python环境配置
1. 创建虚拟环境
python -m venv ollama-env
source ollama-env/bin/activate # Linux/Mac
ollama-env\Scripts\activate # Windows
2. 安装依赖库
在Ollama虚拟环境下安装Langchain依赖库:
pip install langchain langchain-community langchain-core langchain-ollama langchain-text-splitters python-dotenv
安装后可以通过如下指令查看已经安装的包:
pip list | grep "需要查找的包"
三. 基础代码(在线模型)
1. 文本生成脚本
from langchain_community.llms import Ollamallm = Ollama(model="mistral", temperature=0.9)response = llm.invoke("解释量子计算的基本原理")
print("模型回复:", response)
2. 对话式AI
# from langchain_community.chat_models import ChatOllama 已过时
from langchain_core.messages import HumanMessage
from langchain_ollama import ChatOllamachat = ChatOllama(model="mistral", temperature=0.9)messages = [HumanMessage(content="请写一颗线段树")]
response = chat.invoke(messages)print("AI回复:", response.content)
3. 文档问答系统
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_ollama import OllamaEmbeddings, OllamaLLM
# from langchain_community.llms import Ollama 已过时
from langchain.chains import RetrievalQA# 加载文档
loader = TextLoader("/media/ab/软件/所有课程/H3-2/07项目实训/cherry_for_sdu/RAG_TEST/report.txt")
docs = loader.load()# 分割文本
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)# 创建向量数据库
embeddings = OllamaEmbeddings(model="mistral")
vectorstore = FAISS.from_documents(splits, embeddings)# 构建问答链
qa_chain = RetrievalQA.from_chain_type(llm=OllamaLLM(model="mistral"),retriever=vectorstore.as_retriever(),return_source_documents=True
)# 提问
query = "莱特兄弟的“飞行者一号”成功升空是什么时候"
result = qa_chain.invoke({"query": query})print("答案:", result["result"])
print("来源文档:", result["source_documents"][0].page_content[:200])
四. 基础功能测试
1. 文本生成脚本
将待分析的文档保存为report.txt
2. 启动服务
ollama serve & # 后台启动Ollama服务
python document_qa.py所在路径
3. 交互测试
根据提示输入问题进行测试
五. 基础RAG代码及测试
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_ollama import OllamaEmbeddings, OllamaLLM
from langchain.chains import RetrievalQA
import osclass SimpleRAG:def __init__(self, model_name="mistral"):self.model_name = model_nameself.embeddings = OllamaEmbeddings(model=model_name)self.llm = OllamaLLM(model=model_name)self.vectorstore = Noneself.qa_chain = Nonedef load_documents(self, file_path):"""加载并预处理文档"""if not os.path.exists(file_path):raise FileNotFoundError(f"文件 {file_path} 不存在")loader = TextLoader(file_path)docs = loader.load()text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200,separators=["\n\n", "\n", "。", "!", "?", ";"])return text_splitter.split_documents(docs)def build_vectorstore(self, splits, persist_dir=None):"""构建/加载向量存储"""if persist_dir and os.path.exists(persist_dir):print(f"加载已有向量存储: {persist_dir}")self.vectorstore = FAISS.load_local(persist_dir, self.embeddings)else:print("创建新向量存储...")self.vectorstore = FAISS.from_documents(splits, self.embeddings)if persist_dir:self.vectorstore.save_local(persist_dir)print(f"向量存储已保存到: {persist_dir}")def initialize_qa(self):"""初始化问答链"""if not self.vectorstore:raise ValueError("请先构建向量存储")self.qa_chain = RetrievalQA.from_chain_type(llm=self.llm,retriever=self.vectorstore.as_retriever(search_kwargs={"k": 3}),return_source_documents=True)def query(self, question):"""执行查询"""if not self.qa_chain:raise ValueError("请先初始化QA链")result = self.qa_chain.invoke({"query": question})print(f"\n问题: {question}")print(f"\n答案: {result['result']}")self._show_sources(result['source_documents'])def _show_sources(self, documents):"""显示来源文档"""print("\n相关文档片段:")for i, doc in enumerate(documents[:3], 1):content = doc.page_content.replace("\n", " ").strip()print(f"{i}. {content[:250]}...")print("-" * 50)if __name__ == "__main__":# 配置参数DOC_PATH = "/media/ab/软件/所有课程/H3-2/07项目实训/cherry_for_sdu/RAG_TEST/report.txt"VECTORSTORE_DIR = "./vectorstore"# 初始化系统rag = SimpleRAG()try:# 文档处理splits = rag.load_documents(DOC_PATH)# 构建向量存储(自动复用已有存储)rag.build_vectorstore(splits, persist_dir=VECTORSTORE_DIR)# 初始化QA链rag.initialize_qa()# 交互式问答print("输入问题开始查询(输入'exit'退出)")while True:question = input("\n你的问题: ")if question.lower() in ['exit', 'quit']:breakif len(question.strip()) < 3:print("问题太短,请重新输入")continuerag.query(question)except Exception as e:print(f"系统错误: {str(e)}")