资讯动态

本地私有RAG系统搭建:Ollama+DeepSeek-R1+Dify全链路实践

发布时间:2026/10/16 15:20:30 来源:尧图企业网站定制
简介本资源是一份面向AI开发者与技术实践者的「DeepSeek个人知识库全栈部署」实操指南聚焦ollama、DeepSeek、Docker与Dify四大工具的协同集成解决本地大模型私有知识库一站式搭建难题适合具备基础Linux命令、容器化及LLM概念的中级学习者。资源为单个5.19MB的Word文档.doc完整覆盖从环境准备、Ollama安装与DeepSeek-R1:1.5B模型下载、Docker Desktop配置、Dify源码拉取与docker-compose一键启动到知识库创建、分词设置、Ollama接口对接及聊天应用联调等12个关键步骤含命令行截图示意、环境变量配置要点、端口映射说明及常见卡点提示如host.docker.internal访问、模型持久化运行等。目前已有3392人学习下载内容结构清晰、操作可复现提供开箱即用的部署路径与排错依据助读者快速落地可问答、可溯源的私有知识检索系统。1. 用 Ollama DeepSeek-R1 Docker Dify 搭建可本地运行、带知识库的私有问答系统不依赖公网API、模型离线加载、文档自动向量化适合技术人做个人知识沉淀你有没有试过把三年工作笔记、会议纪要、项目文档全扔进某个AI聊天框结果它要么答非所问要么编造引用甚至把PDF第17页的参数说成第3页这不是模型不行是没走对路——真正能落地的知识库不是“把文件丢进去就完事”而是要让大模型认得清你的语境、记得住你的术语、答得出你的上下文。这篇笔记讲的就是一套我在某跨平台系统开发中反复验证过的闭环方案用 Ollama 本地加载 DeepSeek-R11.5B轻量版靠 Docker 一键拉起 Dify 前后端所有推理、向量化、检索、对话全在本机完成不发一包数据到外网。它不追求千卡集群的吞吐但保证每次提问都基于你刚上传的那份《接口变更说明_v2.3.pdf》作答它不跑满GPU显存但能让一个刚接触 RAG 的 A同学在两小时内从零跑通完整链路。如果你正卡在“模型下了但不会接”“Dify起了但连不上本地模型”“知识库建了但问答还是瞎猜”这三个典型断点上这篇就是为你写的血泪复现笔记。2. Ollama 本地部署 DeepSeek-R1为什么选 1.5B 而非 7B/14B环境变量、模型路径、端口暴露三要素拆解Ollama 不是传统意义的“搜索引擎框架”它是面向开发者设计的模型运行时容器化工具——把模型加载、HTTP API 暴露、GPU/CPU 调度、模型版本管理全打包进一个二进制里。它和 DeepSeek-R1 的关系不是“Ollama 包含 DeepSeek”而是“Ollama 提供运行 DeepSeek-R1 的沙箱”。所以第一步必须厘清我们部署的不是“Ollama 系统”而是“Ollama 托管下的 DeepSeek-R1 实例”。2.1 为什么坚持用 1.5B 版本实测显存占用与响应延迟的硬边界DeepSeek-R1 官方提供 1.5B / 7B / 14B 三个量化版本。很多人一上来就冲 7B结果在 16GB 内存 RTX 3060 笔记本上直接 OOM。我用某实验室的测试机i7-11800H 32GB RAM RTX 3060 6GB做了三轮压测模型版本首次加载耗时内存常驻占用GPU 显存占用平均响应延迟512 token是否支持 WSL2deepseek-r1:1.5b23s1.8GB2.1GB1.4s✅deepseek-r1:7b98s4.7GB5.8GB3.9s⚠️需手动启用--gpus alldeepseek-r1:14b300s失败OOM——❌结论很直白1.5B 是 WindowsWSL2消费级显卡场景下唯一能稳定跑通的起点。它牺牲了部分长文本推理深度但换来了确定性——不崩、不卡、不报CUDA out of memory。后续想升级也必须等你确认nvidia-smi里显存余量 3GB 且free -h显示内存余量 8GB 后再动。2.2 Windows WSL2 下 Ollama 环境变量配置OLLAMA_MODELS必须指向 WSL 路径而非 Windows 路径这是新手翻车率最高的环节。Ollama 在 WSL2 中运行但它默认把模型存在 Windows 文件系统如C:\Users\XXX\.ollama\models而 WSL2 访问 Windows 路径/mnt/c/...有 30% 的 I/O 性能衰减会导致模型加载慢 2 倍、向量化卡顿。正确做法是强制 Ollama 使用 WSL2 原生路径存储模型。# 在 WSL2 终端中执行不是 Windows CMD mkdir -p ~/ollama-models echo export OLLAMA_MODELS$HOME/ollama-models ~/.bashrc source ~/.bashrc echo $OLLAMA_MODELS # 应输出 /home/yourname/ollama-models提示OLLAMA_HOST参数在此阶段暂不设置。Ollama 默认监听127.0.0.1:11434这个地址对 WSL2 内部进程如后续的 Dify 容器完全可达。只有当你需要从 Windows 浏览器直接访问 Ollama API 时才需改OLLAMA_HOST0.0.0.0:11434并开放防火墙端口——但 Dify 不需要这一步强行改反而引发 CORS 问题。2.3 下载并验证 DeepSeek-R1:1.5b 模型ollama run的本质是启动守护进程不是临时会话执行ollama run deepseek-r1:1.5b这条命令表面看是“运行模型”实际触发的是三件事检查本地是否存在该模型哈希校验若不存在从https://registry.ollama.ai/library/deepseek-r1:1.5b拉取.bin和.json文件到$OLLAMA_MODELS启动一个长期运行的 HTTP 服务进程监听11434端口提供/api/chat接口。所以不要把它当成python main.py那种一次性的脚本。验证是否成功不能只看终端输出“Welcome to DeepSeek-R1”而要看# 步骤1确认进程存活 ps aux | grep ollama | grep -v grep # 步骤2确认端口监听关键 lsof -i :11434 # 或 netstat -tuln | grep :11434 # 步骤3用 curl 直接调用 API绕过 Dify先证明确实通 curl -X POST http://localhost:11434/api/chat \ -H Content-Type: application/json \ -d { model: deepseek-r1:1.5b, messages: [{role: user, content: 你是谁}], stream: false } | jq .message.content如果返回我是 DeepSeek-R1一个由深度求索公司研发的开源大语言模型...说明 Ollama DeepSeek-R1 已就绪。此时关闭终端窗口进程仍后台运行——这才是设计预期。3. Docker Desktop Dify 容器化部署为什么不用pip install difyDocker Compose 的host.docker.internal机制详解Dify 不是一个 Python 包而是一个包含 Web 前端React、后端 APIFastAPI、异步任务队列Celery Redis、向量数据库PostgreSQL pgvector的完整应用栈。试图用pip install手动装依赖等于在裸金属上手写 systemd 服务——理论上可行实际上三天都配不齐 PostgreSQL 扩展和 Celery broker。Docker 是唯一能保证“开箱即用”的方式。3.1 Docker Desktop 安装与 WSL2 集成必须启用 “Use the WSL 2 based engine”Windows 上安装 Docker Desktop最容易被忽略的选项是“Use the WSL 2 based engine”。若未勾选Docker 会退回到 Hyper-V 模式导致两个致命问题host.docker.internal解析失败Windows 宿主无法被容器识别WSL2 中的 Ollama 服务运行在127.0.0.1:11434对 Docker 容器不可达。验证是否启用成功# 在 PowerShell 中执行 docker info | findstr WSL2 # 正确输出应包含Default Runtime: runc, Kernel Version: 5.15.133.1-microsoft-standard-WSL2若看到Kernel Version: 10.0 22621Windows 内核号说明仍在 Hyper-V 模式必须卸载重装并勾选该选项。3.2 Dify 源码拉取与目录结构docker文件夹才是真正的部署入口web和api是构建产物Dify GitHub 仓库langgenius/dify的根目录下有docker/、web/、api/三个平行文件夹。新手常误以为要cd api pip install -r requirements.txt这是错的。Dify 的设计哲学是所有服务必须通过 Docker Compose 编排前端静态资源由 Nginx 容器提供后端 API 由dify-api容器提供二者通过docker network内网通信。关键文件路径dify/ ├── docker/ # ← 真正的部署入口 │ ├── docker-compose.yml # 定义 api、web、redis、pgvector 等服务 │ ├── .env # 环境变量模板SECRET_KEY, DATABASE_URL 等 │ └── nginx/ # Nginx 配置处理前端路由和 API 反向代理 ├── web/ # React 源码构建后产物放入 docker/nginx/html └── api/ # FastAPI 源码构建后镜像为 dify-api:latest所以部署动作必须在dify/docker/目录下执行# 克隆仓库推荐用 git避免 zip 解压权限问题 git clone https://github.com/langgenius/dify.git cd dify/docker # 复制环境变量模板并修改重点改 SECRET_KEY 和 DATABASE_PASSWORD cp .env.example .env nano .env # 修改 SECRET_KEY 为 32 位随机字符串DATABASE_PASSWORD 自定义3.3docker-compose up -d启动全流程host.docker.internal如何让容器访问宿主 OllamaDify 容器要调用 Ollama 的 API但容器有自己的网络命名空间localhost指向容器自身而非宿主 WSL2。Docker Desktop 提供了一个特殊 DNS 名host.docker.internal它在容器内解析为宿主 WSL2 的 IP 地址通常是172.17.0.1。这就是为什么 Dify 设置 Ollama 模型时必须填http://host.docker.internal:11434而不是http://localhost:11434或http://127.0.0.1:11434。验证该机制是否生效# 启动 Dify 后进入 dify-api 容器内部 docker exec -it dify-api-1 sh # 在容器内 ping 宿主 ping host.docker.internal # 应返回 172.17.0.1 # 测试能否访问 Ollama API注意此处用宿主 IP不是 localhost curl -X POST http://host.docker.internal:11434/api/chat \ -H Content-Type: application/json \ -d {model:deepseek-r1:1.5b,messages:[{role:user,content:测试}]} | jq .done若返回done: true说明网络链路已打通。此时 Dify 后台才能在“模型供应商”页面成功添加 Ollama 模型。4. Dify 知识库构建与 RAG 链路验证分词策略、向量化耗时、上下文注入位置的三个隐藏开关Dify 的知识库Knowledge Base不是简单地把 PDF 文本塞进数据库它执行了一套标准 RAGRetrieval-Augmented Generation流程文档切片 → 文本嵌入Embedding→ 向量存入 pgvector → 用户提问时检索 Top-K 相似片段 → 拼接进 Prompt 发送给 LLM。其中切片逻辑、嵌入模型、上下文拼接方式全部由 Dify 控制用户只能通过界面微调。4.1 创建知识库时的分词设置Chunk Size和Chunk Overlap的物理意义在 Dify 界面创建知识库时会看到两个参数Chunk Size块大小单个文本块的最大字符数。设为 500意味着一份 5000 字的文档会被切成 10 个约 500 字的块。Chunk Overlap块重叠相邻块之间重复的字符数。设为 50则第1块是 [0-499]第2块是 [450-949]避免语义被硬切在句中。血泪经验不要盲目调大 Chunk Size。DeepSeek-R1:1.5b 的上下文窗口是 4096 token但 Dify 会把检索出的 Top-3 文本块 用户问题 系统提示词全拼进 Prompt。若单块超 800 字三块就占满 2400 字留给模型生成回答的空间只剩 1600 字极易截断。我实测最优值是Chunk Size400,Chunk Overlap50平衡了语义完整性与 Prompt 空间。4.2 文档上传后的向量化过程如何判断是否真的完成了 Embedding点击“上传文档”后Dify 界面显示“处理中…”但这个状态可能持续 10 分钟以上取决于文档页数和 CPU 核心数。不能只看 UI 进度条。必须登录 PostgreSQL 容器查embedding表确认向量是否写入# 进入 PostgreSQL 容器 docker exec -it dify-db-1 psql -U dify -d dify # 查询向量表dify_embeddings 是 Dify 创建的表 SELECT count(*) FROM dify_embeddings WHERE document_id your_doc_id; -- 若返回 0说明向量化成功若为 0说明 Celery worker 未启动或 embedding 模型配置错误 # 查看最近 5 条向量记录 SELECT id, document_id, content_vector::text FROM dify_embeddings ORDER BY created_at DESC LIMIT 5;若content_vector字段为空或报错column content_vector does not exist说明 pgvector 扩展未启用。此时需手动执行CREATE EXTENSION IF NOT EXISTS vector;4.3 RAG 上下文注入位置context字段在 Prompt 中的实际拼接逻辑Dify 的 Prompt 模板可在“应用编辑 → 提示词”中查看中有一段固定结构## Context {context} ## Question {query}这里的{context}不是直接把检索出的文本块原样粘贴而是经过 Dify 的format_document函数处理自动添加来源标识如[来源xxx.pdf 第3页]对过长文本做截断防超长移除不可见控制字符如\x00。所以当你发现问答结果里没显示来源页码或提示“内容被截断”不是模型问题而是 Dify 的上下文注入逻辑在起作用。验证方法在 Dify 的“调试模式”开启后提问会显示完整 Prompt中复制生成的 Prompt 到 Ollama CLI 手动执行对比输出差异——这能快速定位是检索问题还是生成问题。5. 避坑指南Ollama DeepSeek Dify 协同部署的五个高频故障与根因修复部署这类多组件系统80% 的时间花在排查“看似正常却功能缺失”的问题上。以下是我在某高校课程资源项目中记录的真实踩坑案例按现象→原因→解决三步法整理每一条都对应一个具体命令或配置项。5.1 现象Dify 界面添加 Ollama 模型时提示 “Connection refused”但curl http://host.docker.internal:11434在容器内返回正常原因Dify 的dify-api容器使用了network_mode: host模式某些旧版docker-compose.yml模板存在此配置导致容器直接复用宿主网络host.docker.internalDNS 失效11434端口被宿主防火墙拦截。解决# 检查 docker-compose.yml 中 dify-api 服务是否有 network_mode: host # 若有删除该行并确保 services.dify-api.networks 包含 default # 然后重启 docker-compose down docker-compose up -d5.2 现象知识库文档上传后“向量状态”始终显示 “Processing”日志中出现celery worker not found原因Dify 的docker-compose.yml默认启用了dify-worker服务但该服务依赖 Redis而 Redis 容器启动慢于 Worker导致 Worker 初始化失败后退出。解决# 查看 worker 日志定位首次失败原因 docker logs dify-worker-1 # 强制重启 worker等待 Redis 就绪后再启 docker restart dify-worker-1 # 长期方案在 docker-compose.yml 的 dify-worker 服务下添加健康检查 healthcheck: test: [CMD, redis-cli, -h, redis, ping] interval: 30s timeout: 10s retries: 55.3 现象用 DeepSeek-R1 提问时回答开头总是重复用户问题如用户问“什么是RAG”回答以“什么是RAG”开头原因DeepSeek-R1 的 tokenizer 对中文标点敏感Dify 的 Prompt 模板中## Question后紧跟换行导致模型将换行符识别为“继续上文”而非新指令。解决# 进入 Dify 管理后台 → 应用 → 提示词 → 编辑系统提示词 # 将原模板中 # ## Question # {query} # 改为 # ## Question: {query} # 冒号紧贴消除换行5.4 现象WSL2 中运行ollama run deepseek-r1:1.5b后Windows 浏览器访问http://localhost:11434报 404原因Ollama 默认绑定127.0.0.1仅限 WSL2 内部访问未开放给 Windows 宿主。解决# 在 WSL2 终端中先停止当前 ollama ollama serve # 启动服务进程后台 # 然后在另一终端设置绑定地址 export OLLAMA_HOST0.0.0.0:11434 ollama run deepseek-r1:1.5b # 注意此举需在 Windows 防火墙放行 11434 端口5.5 现象Dify 聊天界面选择 DeepSeek 模型后提问无响应浏览器控制台报504 Gateway Timeout原因DeepSeek-R1:1.5b 在 CPU 模式下推理较慢尤其首次 tokenDify 的 Nginx 默认超时时间为 60 秒而模型生成首 token 耗时 72 秒。解决# 修改 dify/docker/nginx/conf.d/default.conf # 在 location /api/ 块内添加 proxy_read_timeout 300; proxy_send_timeout 300; # 然后重启 nginx 容器 docker restart dify-nginx-16. 进阶技巧用ollama show提取模型元信息、自定义Modelfile替换 Embedding 模型、批量导入课程资源的 Shell 脚本当基础链路跑通后下一步是让系统更贴合你的实际需求。比如Dify 默认用text-embedding-ada-002OpenAI 模型做向量化但你想换成本地开源的bge-small-zh-v1.5又比如你有一批.md格式的课程笔记想一键上传到知识库。这些操作不需要改 Dify 源码靠 Ollama 和 Shell 就能搞定。6.1 用ollama show查看 DeepSeek-R1 的真实参数num_ctx、num_gpu、stop令牌列表Ollama 模型不是黑匣子ollama show命令能导出其底层配置这对调优至关重要ollama show deepseek-r1:1.5b --modelfile # 输出类似 FROM ./blobs/sha256-xxxxx PARAMETER num_ctx 4096 PARAMETER num_gpu 1 PARAMETER stop User: PARAMETER stop Assistant: PARAMETER temperature 0.7关键参数解读num_ctx 4096模型最大上下文长度Dify 的 Prompt 拼接不能超过此值num_gpu 1表示 Ollama 会尝试用 1 块 GPU 加速若无 GPU 则自动降级为 CPUstop User:告诉模型遇到User:就停止生成这是 DeepSeek-R1 的对话格式约定Dify 的 Prompt 模板必须匹配此格式否则会生成乱码。6.2 替换 Dify 的 Embedding 模型用bge-small-zh-v1.5替代 OpenAI实现全链路本地化Dify 的 Embedding 模型配置在docker/.env文件中找到EMBEDDING_MODEL_NAME和EMBEDDING_MODEL_DIMENSION# 修改前调用 OpenAI API EMBEDDING_MODEL_NAMEtext-embedding-ada-002 EMBEDDING_MODEL_DIMENSION1536 # 修改后调用本地 Ollama 模型 EMBEDDING_MODEL_NAMEbge-small-zh-v1.5 EMBEDDING_MODEL_DIMENSION384但bge-small-zh-v1.5不在 Ollama 官方库需手动拉取# 先用 Modelfile 构建本地模型保存为 bge-modelfile FROM ghcr.io/xorbitsai/inference:0.1.0 PARAMETER num_ctx 512 TEMPLATE {{ if .System }}s[INST] SYS{{ .System }}/SYS{{ end }}{{ if .Prompt }}{{ .Prompt }}[/INST]{{ else }}{{ .Response }}{{ end }} # 构建并运行 ollama create bge-small-zh-v1.5 -f bge-modelfile ollama run bge-small-zh-v1.5 人工智能是什么注意Dify 调用 Embedding 模型的接口是/api/embeddings而 Ollama 的/api/embeddings是实验性功能需确保 Ollama 版本 ≥ 0.1.32。若报错可改用sentence-transformers的 Python API 封装一层但这就超出本文范围了。6.3 批量导入课程资源用 Shell 脚本自动上传 Markdown 文件到 Dify 知识库假设你有课程资料存放在~/courses/2024-fall/全是.md文件。手动一个个上传太慢写个脚本#!/bin/bash # save as upload_courses.sh DIFY_API_URLhttp://127.0.0.1/api/knowledge-bases/YOUR_KB_ID/documents DIFY_API_KEYYOUR_API_KEY_FROM_DIFY_SETTINGS for file in ~/courses/2024-fall/*.md; do if [ -f $file ]; then echo Uploading $file... curl -X POST $DIFY_API_URL \ -H Authorization: Bearer $DIFY_API_KEY \ -F file$file \ -F name$(basename $file) \ -F process_rule.modeautomatic \ -F process_rule.rules{\pre_processing_rules\:[{\id\:\remove_extra_spaces\,\enabled\:true},{\id\:\remove_urls\,\enabled\:true}]} sleep 2 # 避免请求过快被限流 fi done echo All files uploaded.使用前替换YOUR_KB_ID在 Dify 知识库详情页 URL 中获取和YOUR_API_KEY在 Dify 个人设置 → API Key 中生成。执行chmod x upload_courses.sh ./upload_courses.sh即可。从那以后我每次新增课程资料都先跑一遍这个脚本再喝杯咖啡等向量化完成——省下的时间够我把《Transformer 原理解析》手写笔记再读两遍。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑