
一、为什么要自己搭建 AI 知识库服务?
目前市面上关于“本地 AI 知识库”的教程非常多,但大多数方案只解决了单机使用的问题。
一旦你的需求变成:
- 在公司内网共享
- 在家庭局域网多设备访问
- 通过接口给前端或其他系统调用
就会发现,很多“本地教程”其实并不完整。
本文基于 Ubuntu Linux,从零搭建一个:
- 基于 Ollama 的大模型服务
- 支持 RAG(检索增强生成)知识库
- 对外提供 REST + SSE 流式接口
- 可接简单 Web 前端交互
整体目标不是追求复杂,而是跑通一条可落地、可扩展的 AI 知识库服务链路。
二、整体流程概览
整个搭建过程可以拆解为 6 个关键步骤:
- 在 Linux 上安装并运行 Ollama
- 下载并配置合适的 AI 模型
- 构建本地知识库(RAG)
- 使用 Python 进行向量化与检索
- 封装一个支持 SSE 的后端接口
- 前端通过 EventSource 实现实时交互
三、在 Linux 上安装 Ollama
在 Ubuntu 环境下,Ollama 的安装非常简单:
curl -fsSL https://ollama.com/install.sh | sh
安装完成后,确认是否成功:
ollama -v
能正常输出版本号,说明安装没有问题。
启动与自启配置
# 启动 ollama 服务
sudo systemctl start ollama
# 设置开机自启
sudo systemctl enable ollama
默认情况下,Ollama 会监听在本机 11434 端口。
四、下载并选择 AI 模型
为什么推荐 Qwen3?
在个人或中小型服务器环境下,模型选择非常关键。
这里推荐 Qwen3 系列,原因很简单:
- 支持对话 + 推理
- 模型体积覆盖面广
- 性能与资源消耗比较平衡
- 非常适合本地或私有化部署
例如下载 8B 模型:
ollama pull qwen3:8b
如果你的机器配置较低,也可以选择更小的版本。
对比说明:
DeepSeek-R1 是推理模型,DeepSeek-V3 偏对话,但最小 671B,对个人设备并不现实。
五、构建本地知识库(RAG)
1. 安装依赖库
我们使用 Python + LangChain 来实现最基础的 RAG 能力:
pip install -i https://mirrors.aliyun.com/pypi/simple/ \
langchain chromadb sentence-transformers
建议直接使用国内镜像,避免安装卡死。
2. RAG 核心示例代码
下面是一个最小可运行示例,用于说明完整流程:
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_ollama import OllamaLLM
from langchain_core.prompts import PromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
# 1. 加载本地文档
loader = TextLoader("example.txt")
documents = loader.load()
# 2. 文本切分
splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = splitter.split_documents(documents)
# 3. 向量模型
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-mpnet-base-v2"
)
# 4. 构建向量数据库
db = Chroma.from_documents(docs, embeddings)
# 5. 创建 Ollama LLM
llm = OllamaLLM(model="qwen3:0.6b")
# 6. Prompt 模板
prompt = PromptTemplate(
template="根据以下内容回答问题,如果无法判断,请直接回答不知道。\n\n{context}",
input_variables=["context", "input"]
)
# 7. 文档链 + 检索链
doc_chain = create_stuff_documents_chain(llm, prompt)
retriever = db.as_retriever()
rag_chain = create_retrieval_chain(retriever, doc_chain)
# 8. 测试查询
result = rag_chain.invoke({"input": "你是谁?"})
print(result["answer"])
关于 HuggingFace 访问问题
国内访问 HuggingFace 模型时,建议提前设置镜像:
export HF_ENDPOINT=https://hf-mirror.com
否则向量模型下载基本跑不通。
六、封装 SSE 流式接口(Node.js)
为什么使用 SSE?
相比 WebSocket,SSE 更轻量:
- 基于 HTTP
- 单向推送,足够用
- 浏览器原生支持(除 IE)
非常适合 AI 文本逐字返回的场景。
SSE 必须的响应头
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
数据格式规范
res.write(`data: ${data}\n\n`);
Ollama + SSE 服务完整示例
const axios = require('axios');
const split2 = require('split2');
const AI_HOST = 'http://localhost:11434';
const getAnswer = async (req, res) => {
const { prompt } = req.query;
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const payload = {
model: 'qwen3:0.6b',
messages: [{ role: 'user', content: `${prompt}/no_think` }],
};
axios.post(`${AI_HOST}/api/chat`, payload, {
responseType: 'stream',
}).then(response => {
const stream = response.data.pipe(split2('\n'));
stream.on('data', line => {
if (line.trim()) {
res.write(`data: ${line}\n\n`);
}
});
stream.on('end', () => res.end());
stream.on('error', () => res.end());
}).catch(() => {
res.end();
});
};
module.exports = { getAnswer };
/no_think 用于提示模型直接对话输出,减少推理过程文本。
七、前端使用 EventSource 接收数据
浏览器端调用非常简单:
const source = new EventSource(`/api/ai?prompt=${question}`);
source.addEventListener('message', event => {
console.log(event.data);
});
source.addEventListener('error', () => {
source.close();
});
服务端 res.end() 后,如果客户端不手动关闭连接,浏览器会自动重试,因此在 error 中及时 close() 非常重要。
实现的是一个最小可用的 AI 知识库服务原型:
- 本地模型
- 私有知识库
- 流式输出
- 可前后端分离
虽然仍处于 Demo 阶段,但已经完整跑通了从模型 → 知识 → 接口 → 前端的整条链路。
后续可以继续深入的方向包括:
- 多文档、多目录知识库
- 权限与鉴权
- 多模型切换
- 企业内网部署优化
踩坑很多,但好在现在有 AI,很多坑也能靠 AI 自己填平。
持续更新中。
Comments NOTHING