构建个人智能助手

一、搭建本地RAG系统 (Langchain版)

1、安装必要的库

pip install langchain ollama nomic sentence-transformers faiss-cpu

ollama pull nomic-embed-text

建议安装 langchain 版本为0.3.7,高版本的不兼容

复制代码
pip install langchain==0.3.7

说明:langchain: RAG 框架•ollama: 用于运行本地大模型•nomic: nomic-embed-text 模型的 Python 接口•sentence-transformers: sentence-transformers 库,nomic 模型基于此•faiss-cpu: 用于构建本地向量数据库

2、下载 Deepseek R1 模型 (Ollama)

ollama pull deepseek-r1:latest

3、编写 Python 代码,搭建 RAG 系统

第一个python脚本,基于本地已安装的大模型

python 复制代码
import os
from langchain_community.llms import Ollama
from langchain.chains import LLMChain
from langchain_core.prompts import PromptTemplate

print("正在连接Ollama模型...")

# 1. 初始化本地大语言模型 (使用确切的模型名称,根据 ollama list 输出)
try:
    # 根据之前 ollama list 的输出,使用确切的模型名称
    llm = Ollama(model="deepSeek-R1:7b")
    print("成功连接到 deepSeek-R1:7b 模型")
except Exception as e:
    print(f"连接模型失败: {e}")

# 2. 创建一个简单的提示模板
template = """
基于以下上下文信息回答问题:
上下文:
- RAG (Retrieval-Augmented Generation) 是一种结合检索和生成的技术,可以提升大模型的知识覆盖范围和回答准确性
- Langchain 是一个强大的框架,用于构建基于大型语言模型的应用
- Deepseek R1 是一个优秀的开源大语言模型,性能媲美 OpenAI-o1
- Ollama 可以让你在本地电脑上轻松运行各种大语言模型

问题:{question}

请根据上述信息回答问题。
"""

prompt = PromptTemplate(template=template, input_variables=["question"])

# 3. 创建链
try:
    simple_chain = LLMChain(prompt=prompt, llm=llm)
    print("链创建成功")
except Exception as e:
    print(f"创建链失败: {e}")
    exit(1)

print("开始提问...")

# 4. 提问!
questions = [
    "RAG 是什么?",
    "Deepseek R1 模型怎么样?", 
    "Langchain 框架有什么用?"
]

for query in questions:
    try:
        result = simple_chain.run(question=query)
        print(f"问题:{query}")
        print(f"回答:{result.strip()}")
        print("-" * 50)
    except Exception as e:
        print(f"查询 '{query}' 失败: {e}")

print("程序执行完成")

4、补充创建自定义嵌入模型

  1. ✅ 创建了自定义嵌入模型(绕过了 Hugging Face 网络依赖)
  2. ✅ 创建了向量数据库
  3. ✅ 连接到了正确的 Ollama 模型 (deepSeek-R1:7b)
  4. ✅ 创建了 RAG 检索问答链
  5. ✅ 开始处理查询
python 复制代码
import os
import sys
import numpy as np
from typing import List
from langchain_core.embeddings import Embeddings

# 设置环境变量以完全禁用网络访问
os.environ['HF_HUB_OFFLINE'] = '1'
os.environ['TRANSFORMERS_OFFLINE'] = '1'

print("正在创建自定义嵌入模型以绕过网络依赖...")

# 创建一个自定义嵌入类,继承自 LangChain 的 Embeddings 类
class CustomEmbeddings(Embeddings):
    def __init__(self):
        # 设置固定的随机种子以确保结果一致性
        np.random.seed(42)
    
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        """
        为文档列表创建嵌入向量
        使用文本内容的哈希值作为随机种子,确保相同文本始终产生相同嵌入
        """
        embeddings = []
        for text in texts:
            # 使用文本的哈希值作为种子,确保相同文本总是有相同嵌入
            seed = abs(hash(text)) % (2**32)
            rng = np.random.RandomState(seed)
            # 创建384维的嵌入向量(模拟常见的嵌入维度)
            embedding = rng.normal(size=384).tolist()
            embeddings.append(embedding)
        return embeddings
    
    def embed_query(self, text: str) -> List[float]:
        """为单个查询创建嵌入向量"""
        return self.embed_documents([text])[0]

# 使用自定义嵌入模型
embeddings = CustomEmbeddings()
print("自定义嵌入模型创建成功")

# 继续执行 RAG 流程
from langchain_community.vectorstores import FAISS
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA

# 2. 准备你的知识库文档
documents = [
"Langchain 是一个强大的框架,用于构建基于大型语言模型的应用。",
"RAG (Retrieval-Augmented Generation) 可以提升大模型的知识覆盖范围和回答准确性。",
"Deepseek R1 是一个优秀的开源大语言模型,性能媲美 OpenAI-o1。",
"Ollama 可以让你在本地电脑上轻松运行各种大语言模型。"
]
print("文档准备完成")

# 3. 将文档嵌入向量数据库 (FAISS)
print("正在创建向量数据库...")
try:
    vectorstore = FAISS.from_texts(documents, embeddings)
    print("向量数据库创建成功")
except Exception as e:
    print(f"创建向量数据库失败: {e}")
    sys.exit(1)

# 4. 初始化本地大语言模型 (deepSeek-R1:latest, 通过 Ollama)
print("正在连接Ollama模型...")
try:
    llm = Ollama(model="deepSeek-R1:latest")
    print("Ollama模型连接成功")
except Exception as e:
    print(f"连接Ollama模型失败: {e}")
    print("尝试备用模型名称...")
    try:
        llm = Ollama(model="deepSeek-R1:7b")
        print("成功连接到备用模型")
    except Exception as e2:
        print(f"备用模型也无法连接: {e2}")
        print("请确保Ollama服务正在运行且模型已下载")
        sys.exit(1)

# 5. 创建 RAG 检索问答链
print("正在创建 RAG 检索问答链...")
try:
    qa_chain = RetrievalQA.from_chain_type(
        llm=llm,
        retriever=vectorstore.as_retriever()
    )
    print("RAG检索问答链创建成功")
except Exception as e:
    print(f"创建RAG链失败: {e}")
    sys.exit(1)

print("开始提问...")

# 6. 提问!
questions = [
    "RAG 是什么?",
    "Deepseek R1 模型怎么样?", 
    "Langchain 框架有什么用?"
]

for query in questions:
    try:
        result = qa_chain({"query": query})
        print(f"问题:{query}")
        print(f"回答:{result['result']}")
        print("-" * 50)
    except Exception as e:
        print(f"查询 '{query}' 失败: {e}")

print("程序执行完成")

二、加载 Word 和 PDF 文档作为知识库

知识库 documents 变量只是一个简单的字符串列表。在实际应用中,我们通常需要处理 Word (.docx) 和 PDF 等更常见的文件格式。Langchain 框架提供了强大的 文档加载器 (Document Loaders),可以轻松搞定各种文件类型的加载。

  1. 加载 Word 文档 (.docx)

想要加载本地Word文档作为知识库。专门处理Word文档加载,并包含必要的依赖安装:

python 复制代码
pip install python-docx
python 复制代码
# 从本地Word文档加载内容作为知识库
try:
    from docx import Document
    # 检查是否存在Word文档
    word_doc_path = "my_knowledge.docx"
    if os.path.exists(word_doc_path):
        print(f"正在加载Word文档: {word_doc_path}")
        doc = Document(word_doc_path)
        paragraphs = [p.text for p in doc.paragraphs if p.text.strip()]
        # 将段落合并成文档列表
        documents = paragraphs if paragraphs else ["知识库文档为空"]
        print(f"从Word文档加载了 {len(documents)} 个段落")
    else:
        print(f"未找到Word文档: {word_doc_path}")
        
except ImportError:
    print("未安装python-docx库,使用默认知识库文档...")
    
print("文档准备完成")
  1. 加载 PDF 文档 (.pdf)

支持PDF格式文档作为知识库。首先需要安装必要的依赖,然后扩展文档加载功能:

python 复制代码
pip install PyPDF2
python 复制代码
# 然后尝试加载PDF文档
    import PyPDF2
    pdf_doc_path = "local_test.pdf"
    if os.path.exists(pdf_doc_path):
        print(f"正在加载PDF文档: {pdf_doc_path}")
        with open(pdf_doc_path, 'rb') as pdf_file:
            pdf_reader = PyPDF2.PdfReader(pdf_file)
            pdf_paragraphs = []
            for page_num in range(len(pdf_reader.pages)):
                page = pdf_reader.pages[page_num]
                text = page.extract_text()
                if text.strip():
                    # 将长文本按段落分割
                    paragraphs = text.split('\n')
                    pdf_paragraphs.extend([p for p in paragraphs if p.strip()])
            documents.extend(pdf_paragraphs)  # 添加到文档列表
        print(f"从PDF文档加载了 {len(pdf_paragraphs)} 个段落")
    else:
        print("未找到PDF文档 (local_test.pdf)")

3、加载当前目录下所有 .docx.pdf 文件:

python 复制代码
 # 获取当前目录下所有的Word和PDF文件
    current_dir = os.getcwd()
    docx_files = [f for f in os.listdir(current_dir) if f.endswith('.docx')]
    pdf_files = [f for f in os.listdir(current_dir) if f.endswith('.pdf')]
    
    print(f"在当前目录找到 {len(docx_files)} 个Word文档和 {len(pdf_files)} 个PDF文档")
    
    # 加载所有Word文档
    from docx import Document
    for docx_file in docx_files:
        try:
            print(f"正在加载Word文档: {docx_file}")
            doc = Document(docx_file)
            paragraphs = [p.text for p in doc.paragraphs if p.text.strip()]
            documents.extend(paragraphs)  # 添加到文档列表
            print(f"从 {docx_file} 加载了 {len(paragraphs)} 个段落")
        except Exception as e:
            print(f"加载Word文档 {docx_file} 时出错: {e}")
    
    # 加载所有PDF文档
    import PyPDF2
    for pdf_file in pdf_files:
        try:
            print(f"正在加载PDF文档: {pdf_file}")
            with open(pdf_file, 'rb') as pdf_file_handle:
                pdf_reader = PyPDF2.PdfReader(pdf_file_handle)
                pdf_paragraphs = []
                for page_num in range(len(pdf_reader.pages)):
                    page = pdf_reader.pages[page_num]
                    text = page.extract_text()
                    if text.strip():
                        # 将长文本按段落分割
                        paragraphs = text.split('\n')
                        pdf_paragraphs.extend([p for p in paragraphs if p.strip()])
                documents.extend(pdf_paragraphs)  # 添加到文档列表
                print(f"从 {pdf_file} 加载了 {len(pdf_paragraphs)} 个段落")
        except Exception as e:
            print(f"加载PDF文档 {pdf_file} 时出错: {e}")
    
    # 如果没有找到任何文档,则使用默认文档
    if not documents:
        print("未找到任何Word或PDF文档,使用默认知识库文档...")

三、 总结:本地RAG,触手可及的AI力量!

通过本文的教程,相信你已经成功搭建了自己的本地 RAG 系统!

相关推荐
kokunka2 小时前
【源码+注释】纯C++小游戏开发之射击小球游戏
开发语言·c++·游戏
测试秃头怪2 小时前
面试大厂就靠这份软件测试八股文了【含答案】
自动化测试·软件测试·python·功能测试·面试·职场和发展·单元测试
测试杂货铺2 小时前
软件测试面试题大全,你要的都在这。。
自动化测试·软件测试·python·功能测试·面试·职场和发展·测试用例
测试大圣2 小时前
软件测试基础知识总结(超全的)
软件测试·python·功能测试·测试工具·职场和发展·单元测试·测试用例
sww_10262 小时前
RAG检索增强 ETL最佳实战
人工智能·python·spring
云栖梦泽2 小时前
易语言开发从入门到精通:补充篇·网络编程进阶+实用爬虫开发·API集成·代理IP配置·异步请求·防封禁优化
开发语言
java1234_小锋3 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
铅笔侠_小龙虾3 小时前
Flutter Demo
开发语言·javascript·flutter
2501_944525543 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter