💡 本地部署 DeepSeek AI 助手:从零开始的完整指南
本教程带你从零搭建一个本地 AI 助手系统,实现让 DeepSeek 模型“读取文档 + 回答问题”的智能问答功能。 适合:没有编程基础的初学者 / 想在本地运行大模型的人。
🧩 步骤 1:安装 Ollama(如已安装可跳过)
1.1 下载并安装
curl -fsSL https://ollama.com/install.sh | sh
命令解释:
curl:命令行下载工具(就像浏览器下载文件)-fsSL:下载参数,保证下载过程稳定| sh:下载完成后直接执行安装脚本
👉 Windows 用户可前往 Ollama 官网 下载安装程序。
1.2 验证安装
ollama --version
看到类似 ollama version 0.1.29 的输出,就说明安装成功。
🤖 步骤 2:下载 DeepSeek 模型
2.1 模型选择对照表
| 模型名称 | 大小 | 内存需求 | 速度 | 智能程度 | 推荐 |
|---|---|---|---|---|---|
| deepseek-r1:1.5b | 1GB | 4GB | 很快 | 一般 | ❌ 太弱 |
| deepseek-r1:7b | 4GB | 8GB | 较快 | 不错 | ✅ 推荐(需16GB内存) |
| deepseek-r1:14b | 8GB | 12GB | 较慢 | 很好 | ⚠️ 16GB勉强可用 |
| deepseek-r1:32b | 18GB | 20GB+ | 慢 | 最强 | ❌ 普通电脑跑不动 |
2.2 下载模型
ollama pull deepseek-r1:7b
解释:
ollama pull:下载模型deepseek-r1:7b:模型名称 + 参数量(7B = 70亿参数)
💬 步骤 3:测试模型是否能正常运行
ollama run deepseek-r1:7b
输入:
你好,请介绍一下你自己
模型能回复说明运行成功。
退出方式:输入 /bye 或按下 Ctrl + C。
📄 步骤 4:准备资料
4.1 安装文档处理库
pip3 install pypdf2 python-docx
说明:
pip3 install:安装 Python 工具包pypdf2:读取和解析 PDF 文件python-docx:读取 Word 文件(.docx)
4.2 创建项目文件夹
cd ~/Desktop
mkdir my-ai-assistant
cd my-ai-assistant
mkdir documents # 原始PDF和Word文件
mkdir processed # 转换后的纯文本
mkdir scripts # Python脚本
结构示意:
my-ai-assistant/
├── documents/ ← 存放原始资料
├── processed/ ← 转换后的文本
└── scripts/ ← 程序脚本
4.3 创建文档转换脚本
创建一个名为 convert_docs.py 的文件,代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文档转换脚本 - 把PDF和Word文档转成纯文本
"""
import os
from pathlib import Path
# 导入文档处理库
try:
from PyPDF2 import PdfReader # 处理PDF
from docx import Document # 处理Word
except ImportError:
print("❌ 缺少必要的库,请运行:")
print("pip3 install pypdf2 python-docx --break-system-packages")
exit(1)
def convert_pdf_to_text(pdf_path):
"""
把PDF文件转换成文本
参数:pdf_path - PDF文件的路径
返回:提取的文本内容
"""
try:
# 打开PDF文件
reader = PdfReader(pdf_path)
text = ""
# 逐页提取文字
for page_num, page in enumerate(reader.pages, 1):
print(f" 正在处理第 {page_num}/{len(reader.pages)} 页...")
text += page.extract_text() + "\n\n"
return text
except Exception as e:
print(f"❌ 处理PDF失败:{e}")
return ""
def convert_docx_to_text(docx_path):
"""
把Word文档转换成文本
参数:docx_path - Word文件的路径
返回:提取的文本内容
"""
try:
# 打开Word文档
doc = Document(docx_path)
text = ""
# 逐段提取文字
for para_num, paragraph in enumerate(doc.paragraphs, 1):
if para_num % 10 == 0: # 每处理10段显示一次进度
print(f" 正在处理第 {para_num} 段...")
text += paragraph.text + "\n"
return text
except Exception as e:
print(f"❌ 处理Word失败:{e}")
return ""
def main():
"""
主程序:扫描documents文件夹,转换所有PDF和Word文档
"""
print("=" * 50)
print("📄 文档转换工具")
print("=" * 50)
# 设置文件夹路径
documents_dir = Path("documents")
processed_dir = Path("processed")
# 检查文件夹是否存在
if not documents_dir.exists():
print(f"❌ 找不到 {documents_dir} 文件夹")
print("请先创建这个文件夹,并把PDF和Word文档放进去")
return
# 创建输出文件夹
processed_dir.mkdir(exist_ok=True)
# 获取所有文档文件
pdf_files = list(documents_dir.glob("*.pdf"))
docx_files = list(documents_dir.glob("*.docx"))
total_files = len(pdf_files) + len(docx_files)
if total_files == 0:
print(f"❌ {documents_dir} 文件夹里没有找到PDF或Word文档")
print("支持的格式:.pdf, .docx")
return
print(f"\n找到 {len(pdf_files)} 个PDF文件,{len(docx_files)} 个Word文档")
print(f"总共需要处理 {total_files} 个文件\n")
processed_count = 0
failed_count = 0
# 处理PDF文件
for i, pdf_file in enumerate(pdf_files, 1):
print(f"[{i}/{len(pdf_files)}] 正在转换PDF:{pdf_file.name}")
text = convert_pdf_to_text(pdf_file)
if text.strip(): # 如果提取到了内容
# 保存为文本文件
output_file = processed_dir / f"{pdf_file.stem}.txt"
output_file.write_text(text, encoding='utf-8')
print(f" ✅ 已保存到:{output_file}")
processed_count += 1
else:
print(f" ⚠️ 没有提取到内容,可能是扫描版PDF")
failed_count += 1
print()
# 处理Word文档
for i, docx_file in enumerate(docx_files, 1):
print(f"[{i}/{len(docx_files)}] 正在转换Word:{docx_file.name}")
text = convert_docx_to_text(docx_file)
if text.strip():
output_file = processed_dir / f"{docx_file.stem}.txt"
output_file.write_text(text, encoding='utf-8')
print(f" ✅ 已保存到:{output_file}")
processed_count += 1
else:
print(f" ⚠️ 没有提取到内容")
failed_count += 1
print()
# 显示统计结果
print("=" * 50)
print(f"✅ 转换完成!")
print(f"成功:{processed_count} 个")
print(f"失败:{failed_count} 个")
print(f"所有文本文件已保存到:{processed_dir}/")
print("=" * 50)
if __name__ == "__main__":
main()
4.4 运行转换脚本
cd ~/Desktop/my-ai-assistant
python3 scripts/convert_docs.py
结果:
- 看到每个文件的转换日志
- 转换后的
.txt文件会出现在processed文件夹
🧠 步骤 5:构建知识库(RAG 系统)
让 AI 能“阅读”你的资料并基于内容回答问题。
5.1 安装 RAG 相关库
pip3 install chromadb sentence-transformers langchain
关键组件说明:
| 名称 | 作用 |
|---|---|
| RAG(Retrieval-Augmented Generation) | 让 AI 先“查资料”再生成答案,减少“胡编乱造” |
| ChromaDB | 轻量级的向量数据库,用于存储文本的数字表示 |
| sentence-transformers | 将文字转为“向量”(机器能理解的数字形式) |
| langchain | AI 应用开发框架,用于连接模型、工具、数据库等组件 |
📘 简单理解:
sentece-transformers 是“翻译文字成数字”的工具,
langchain 是“把模型和知识库粘在一起”的胶水。
5.2 创建知识库脚本
在 scripts 文件夹中创建build_knowledge_base.py,代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
知识库构建脚本 - 把你的文档导入向量数据库
这样AI就能快速找到相关资料来回答问题
"""
import os
from pathlib import Path
try:
import chromadb
from chromadb.utils import embedding_functions
from sentence_transformers import SentenceTransformer
except ImportError:
print("❌ 缺少必要的库,请运行:")
print("pip3 install chromadb sentence-transformers --break-system-packages")
exit(1)
def split_text_into_chunks(text, chunk_size=500, overlap=50):
"""
把长文本切成小块(因为AI一次处理有限制)
参数:
text: 要切分的文本
chunk_size: 每块的字数(默认500字)
overlap: 块之间重叠的字数(避免切断重要信息)
返回:文本块的列表
"""
chunks = []
start = 0
text_length = len(text)
while start < text_length:
# 切出一块文本
end = start + chunk_size
chunk = text[start:end]
# 如果不是最后一块,尝试在标点符号处切断
if end < text_length:
# 往回找最近的句号、问号或换行
for i in range(len(chunk) - 1, max(0, len(chunk) - 100), -1):
if chunk[i] in ['。', '!', '?', '\n', '.', '!', '?']:
chunk = chunk[:i + 1]
end = start + i + 1
break
if chunk.strip(): # 如果这块不是空的
chunks.append(chunk.strip())
# 下一块从重叠位置开始
start = end - overlap
return chunks
def build_knowledge_base():
"""
主程序:读取所有文本文件,构建知识库
"""
print("=" * 60)
print("🔨 正在构建知识库...")
print("=" * 60)
# 设置路径
processed_dir = Path("processed")
db_dir = Path("knowledge_db")
# 检查文件夹
if not processed_dir.exists() or not list(processed_dir.glob("*.txt")):
print(f"❌ {processed_dir} 文件夹里没有找到文本文件")
print("请先运行 convert_docs.py 转换文档")
return
# 获取所有文本文件
text_files = list(processed_dir.glob("*.txt"))
print(f"\n找到 {len(text_files)} 个文本文件\n")
# 初始化向量数据库
print("📦 正在初始化数据库...")
client = chromadb.PersistentClient(path=str(db_dir))
# 删除旧的集合(如果存在)
try:
client.delete_collection("company_docs")
except:
pass
# 创建新集合
# 使用中文向量模型
print("📥 正在加载中文向量模型(第一次会下载,需要几分钟)...")
collection = client.create_collection(
name="company_docs",
metadata={"description": "公司文档知识库"}
)
# 处理每个文件
all_chunks = []
all_metadatas = []
all_ids = []
chunk_id = 0
for file_num, text_file in enumerate(text_files, 1):
print(f"\n[{file_num}/{len(text_files)}] 正在处理:{text_file.name}")
# 读取文件内容
text = text_file.read_text(encoding='utf-8')
print(f" 文件大小:{len(text)} 字")
# 切分成小块
chunks = split_text_into_chunks(text)
print(f" 切分为:{len(chunks)} 块")
# 为每块准备元数据(记录来源)
for chunk in chunks:
all_chunks.append(chunk)
all_metadatas.append({
"source": text_file.name,
"chunk_id": chunk_id
})
all_ids.append(f"doc_{chunk_id}")
chunk_id += 1
print(f" ✅ 完成")
# 批量导入数据库
print(f"\n💾 正在将 {len(all_chunks)} 个文本块导入数据库...")
print(" (这一步会比较慢,请耐心等待)")
# 分批处理(避免内存溢出)
batch_size = 100
for i in range(0, len(all_chunks), batch_size):
batch_end = min(i + batch_size, len(all_chunks))
print(f" 进度:{batch_end}/{len(all_chunks)} ({batch_end*100//len(all_chunks)}%)")
collection.add(
documents=all_chunks[i:batch_end],
metadatas=all_metadatas[i:batch_end],
ids=all_ids[i:batch_end]
)
print("\n" + "=" * 60)
print("✅ 知识库构建完成!")
print(f"总共导入:{len(all_chunks)} 个文本块")
print(f"数据库位置:{db_dir}/")
print("=" * 60)
print("\n💡 下一步:运行 ai_assistant.py 开始使用AI助手")
if __name__ == "__main__":
build_knowledge_base()
该脚本会:
- 读取
processed文件夹的文本 - 分块处理(每500字一块)
- 向量化后存入 ChromaDB
5.3 构建知识库
cd ~/Desktop/my-ai-assistant
python3 scripts/build_knowledge_base.py
完成后,你的本地知识库就准备好了 🎉
🧩 步骤 6:创建 AI 助手程序
在 scripts 文件夹中创建 ai_assistant.py,代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI助手主程序 - 你的专属领域智能助手
基于DeepSeek模型和公司文档知识库
"""
import chromadb
import requests
import json
from pathlib import Path
class AIAssistant:
"""AI助手类"""
def __init__(self):
"""初始化AI助手"""
print("🤖 正在启动AI助手...")
# 连接知识库
db_dir = Path("knowledge_db")
if not db_dir.exists():
print("❌ 找不到知识库!")
print("请先运行 build_knowledge_base.py 构建知识库")
exit(1)
self.client = chromadb.PersistentClient(path=str(db_dir))
self.collection = self.client.get_collection("company_docs")
# Ollama API设置
self.ollama_url = "http://localhost:11434/api/generate"
self.model_name = "deepseek-r1:7b"
print("✅ AI助手已就绪!\n")
def search_knowledge(self, question, top_k=3):
"""
在知识库中搜索相关内容
参数:
question: 用户的问题
top_k: 返回最相关的几条结果(默认3条)
返回:相关文档的列表
"""
results = self.collection.query(
query_texts=[question],
n_results=top_k
)
return results['documents'][0] if results['documents'] else []
def ask(self, question):
"""
回答用户问题
流程:
1. 在知识库中搜索相关资料
2. 把资料和问题一起发给AI
3. AI基于资料生成答案
"""
print(f"\n💭 问题:{question}")
print("\n🔍 正在搜索相关资料...")
# 搜索相关文档
relevant_docs = self.search_knowledge(question, top_k=3)
if not relevant_docs:
print("⚠️ 没有找到相关资料,AI将基于通用知识回答\n")
context = ""
else:
print(f"✅ 找到 {len(relevant_docs)} 条相关资料\n")
context = "\n\n".join(relevant_docs)
# 构建提示词(告诉AI如何回答)
prompt = f"""你是一个专业的AI助手,请基于以下公司内部资料回答用户的问题。
【相关资料】
{context}
【用户问题】
{question}
【回答要求】
1. 如果资料中有相关信息,请基于资料详细回答
2. 如果资料中没有相关信息,请明确告知,不要编造
3. 回答要专业、准确、易懂
4. 适当引用资料中的关键信息
请开始回答:"""
# 调用DeepSeek模型
print("🤖 AI正在思考...\n")
print("-" * 60)
try:
response = requests.post(
self.ollama_url,
json={
"model": self.model_name,
"prompt": prompt,
"stream": True # 流式输出(像打字一样逐字显示)
},
stream=True
)
full_response = ""
for line in response.iter_lines():
if line:
try:
data = json.loads(line)
if 'response' in data:
text = data['response']
print(text, end='', flush=True)
full_response += text
except:
pass
print("\n" + "-" * 60)
return full_response
except Exception as e:
print(f"\n❌ 调用AI失败:{e}")
print("请确保Ollama正在运行:ollama serve")
return None
def interactive_mode(self):
"""
交互模式:持续对话
"""
print("=" * 60)
print("🎉 欢迎使用专属AI助手!")
print("=" * 60)
print("\n💡 使用说明:")
print(" - 直接输入问题,按回车提交")
print(" - 输入 'quit' 或 'exit' 退出")
print(" - 输入 'clear' 清屏")
print("\n" + "=" * 60 + "\n")
while True:
try:
# 获取用户输入
question = input("👤 你:").strip()
if not question:
continue
# 处理特殊命令
if question.lower() in ['quit', 'exit', '退出']:
print("\n👋 再见!")
break
if question.lower() in ['clear', '清屏']:
import os
os.system('clear')
continue
# 回答问题
self.ask(question)
print("\n" + "=" * 60 + "\n")
except KeyboardInterrupt:
print("\n\n👋 再见!")
break
except Exception as e:
print(f"\n❌ 出错了:{e}\n")
def main():
"""主程序入口"""
# 创建AI助手实例
assistant = AIAssistant()
# 启动交互模式
assistant.interactive_mode()
if __name__ == "__main__":
main()
该程序实现问答功能:
- 用户输入问题
- 系统在知识库中检索相关内容
- 把结果交给 DeepSeek 模型生成回答
🚀 步骤 7:启动与测试
7.1 启动 Ollama 服务
ollama serve
保持该窗口运行。
7.2 启动 AI 助手
cd ~/Desktop/my-ai-assistant
python3 scripts/ai_assistant.py
7.3 测试提问
我们公司有哪些产品?
模型将基于你资料中的内容生成回答。
🔧 常见问题 FAQ
Q1. 如何更新知识库?
# 放入新文档
python3 scripts/convert_docs.py
python3 scripts/build_knowledge_base.py
Q2. 回答不准确?
- 确认资料清晰、无错别字
- 增加相关内容
- 尝试更大模型(14B)
Q3. 太慢?
- 换小模型(如 7B)
- 优化检索参数(
top_k=2) - 使用 GPU 加速
📚 参考资料
✅ 总结
| 组件 | 作用 | 说明 |
|---|---|---|
| Ollama | 本地运行大模型 | 类似“离线版 ChatGPT” |
| DeepSeek | AI 模型 | 理解和生成自然语言 |
| RAG | 检索增强生成 | 让 AI “先查资料再回答” |
| ChromaDB | 向量数据库 | 存储文本向量 |
| Sentence-transformers | 文本转向量 | 让机器理解语义 |
| LangChain | 框架 | 让模型、数据库协同工作 |