一、为什么要自己搭建 AI 知识库服务?

目前市面上关于“本地 AI 知识库”的教程非常多,但大多数方案只解决了单机使用的问题。
一旦你的需求变成:

  • 在公司内网共享
  • 在家庭局域网多设备访问
  • 通过接口给前端或其他系统调用

就会发现,很多“本地教程”其实并不完整。

本文基于 Ubuntu Linux,从零搭建一个:

  • 基于 Ollama 的大模型服务
  • 支持 RAG(检索增强生成)知识库
  • 对外提供 REST + SSE 流式接口
  • 可接简单 Web 前端交互

整体目标不是追求复杂,而是跑通一条可落地、可扩展的 AI 知识库服务链路。


二、整体流程概览

整个搭建过程可以拆解为 6 个关键步骤:

  1. 在 Linux 上安装并运行 Ollama
  2. 下载并配置合适的 AI 模型
  3. 构建本地知识库(RAG)
  4. 使用 Python 进行向量化与检索
  5. 封装一个支持 SSE 的后端接口
  6. 前端通过 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 自己填平。

持续更新中。

此作者没有提供个人介绍。
最后更新于 2025-12-15