基于 Linux 的本地 AI 智能问答平台搭建实践 —— Ollama + FastAPI + Nginx 实现本地大模型 Web 服务

摘要

这次实验主要是把本地大模型真正跑起来,并且不只是停留在服务器终端里面使用,而是进一步做成一个可以通过浏览器访问的简单 AI 聊天平台。

整个项目的核心思路其实比较简单:

用户打开浏览器,在网页里面输入问题,网页把问题发送给 Python 后台,Python 再去调用服务器上的 Ollama,Ollama 把问题交给本地大模型处理,最后再把模型生成的答案返回给网页。

整体的数据流可以理解成:

text 复制代码
用户浏览器
    ↓
Nginx
    ↓
前端 HTML
    ↓
FastAPI / Python
    ↓
Ollama API
    ↓
DeepSeek / Qwen 等本地大模型
    ↓
返回回答

原始项目采用了 Ollama 作为本地大模型运行平台,Python 负责后台接口,Nginx 提供 HTTP 服务,前端使用网页实现聊天界面。这种结构也比较适合作为学习 AI 应用开发的入门项目。

相比直接使用在线 ChatGPT 之类的服务,本地部署最大的一个特点就是数据可以留在自己的服务器环境中。课程资料中也提到了企业数据隐私问题,例如企业员工把公司内部资料直接提交给公共大模型,就可能产生数据泄露方面的风险,因此企业内部使用私有化大模型具有一定的实际意义。

所以这次项目最终可以理解成一个比较简单的"企业内部 AI 助手"。

例如:

text 复制代码
运维人员:
Linux 中如何查看某个端口是否被占用?

AI:
可以使用 ss 命令,例如:
ss -tunlp | grep 80

或者:

text 复制代码
运维人员:
Nginx 启动失败应该怎么排查?

AI:
可以依次检查:
1. systemctl status nginx
2. nginx -t
3. journalctl -u nginx
4. 检查 80 端口是否被占用

这样一来,原本只是学习 Ollama 命令的实验,就变成了一个真正能够用于日常工作的简单工具。

项目描述

项目到底要做什么

这个项目准备搭建一个简单的企业内部 AI 问答平台。

假设现在有一个企业内部服务器,里面运行着 Ollama 和大模型。

运维人员平时可能会遇到很多重复性问题,例如:

text 复制代码
Linux 怎么查看磁盘?
怎么查看内存?
怎么查看端口?
systemctl 怎么重启服务?
Nginx 为什么启动失败?
这个 Shell 命令是什么意思?
这个日志报错应该怎么排查?

以前遇到这些问题,可能需要自己搜索资料,或者问同事。

现在可以把这些问题直接交给内部 AI。

整个系统不需要用户直接接触 Ollama,而是通过网页访问。

最终效果就是:

text 复制代码
浏览器
   ↓
输入问题
   ↓
Python 后台
   ↓
Ollama
   ↓
本地大模型
   ↓
AI 返回答案
   ↓
浏览器显示

这就是整个项目最核心的功能。

为什么要采用本地大模型

项目资料中介绍了私有大模型产生的一个重要原因,就是企业在使用 AI 的时候越来越重视数据安全。特别是金融、医疗、政府以及企业内部系统,都可能存在大量不能直接上传到公共平台的数据。

比如运维人员可能会问:

text 复制代码
我们的服务器 192.168.x.x 为什么访问不了?

或者:

text 复制代码
/etc/nginx/nginx.conf 中这一段配置是什么意思?

如果以后进一步扩展,还可能让 AI 分析:

text 复制代码
业务服务器日志
系统日志
Nginx 日志
数据库错误日志
应用程序日志

这些内容里面可能包含服务器地址、用户名、接口地址、业务信息甚至一些敏感配置。

如果全部上传到公共 AI 平台,企业可能会比较担心。

而本地大模型的思路就是:

text 复制代码
数据
 ↓
企业内部服务器
 ↓
本地 AI
 ↓
返回结果

数据不需要为了完成一次问答而发送到外部平台。

当然,这并不代表"用了本地大模型就百分之百安全"。服务器本身的权限、网络、防火墙、账号、日志以及模型接口暴露情况仍然需要做好安全控制。

为什么选择 Ollama

本项目使用 Ollama 来运行大模型。

课程资料中把 Ollama 定位成一个开源的大型语言模型本地运行平台,它提供命令行和 API,可以比较方便地下载、运行和管理模型。

对于我们这种学习和实验项目来说,Ollama 最大的优势就是简单。

比如安装好之后,可以直接:

bash 复制代码
ollama pull deepseek-r1:1.5b

下载模型。

然后:

bash 复制代码
ollama run deepseek-r1:1.5b

直接开始聊天。

课程中的实验也是采用这种方式运行 DeepSeek 和 Qwen 模型的。

项目整体架构

这个项目主要分成四部分。

第一部分:Ollama

负责运行本地大模型。

例如:

text 复制代码
DeepSeek
Qwen

Ollama 本身可以通过 API 提供模型服务。

本实验中使用的 API 地址是:

text 复制代码
http://127.0.0.1:11434

例如获取模型:

text 复制代码
GET /api/tags

进行聊天:

text 复制代码
POST /api/chat

课程代码中已经实际演示了通过 Python 请求这两个接口。

第二部分:Python + FastAPI

Python 是整个项目的后台接口。

它主要负责两件事:

text 复制代码
接收网页发送的问题
        ↓
请求 Ollama
        ↓
把 AI 的答案返回给网页

FastAPI 则负责把 Python 程序变成 Web API。

例如:

text 复制代码
POST /chat

这个接口就是专门处理聊天请求的。

第三部分:前端网页

前端就是用户看到的聊天界面。

用户输入:

text 复制代码
Linux 如何查看端口?

点击"发送"。

JavaScript 使用:

javascript 复制代码
fetch()

把问题发送给:

text 复制代码
http://192.168.50.231:8000/chat

然后把 Python 返回的内容显示在页面上。

原始前端代码已经采用了这种方式实现浏览器和 FastAPI 的通信。

第四部分:Nginx

Nginx 主要负责提供网页访问。

前端 HTML 放在:

text 复制代码
/usr/share/nginx/html

然后启动 Nginx:

bash 复制代码
systemctl start nginx

用户访问服务器 IP,就可以打开网页。课程中的实验也是采用 /usr/share/nginx/html/index.html 作为前端页面。

项目步骤

准备服务器环境

根据原始实验资料,需要准备一台麒麟系统服务器,并准备 Python 和 Ollama 环境,同时服务器需要有足够的 CPU、内存和磁盘空间来运行大模型。资料中的基础要求包括至少 4 核 CPU、8G 内存和 50G 磁盘空间。

实际实验的时候,如果只是运行比较小的模型,配置压力会小一些。

例如:

text 复制代码
CPU:4 核以上
内存:8G 以上
磁盘:50G 以上

如果以后运行更大的模型,最好进一步增加内存或者配置 GPU。

安装 Ollama

如果使用课程中的安装包,可以先上传:

text 复制代码
ollama-linux-amd64.tgz

然后解压到:

text 复制代码
/usr/local/

例如:

bash 复制代码
mkdir /soft
cd /soft

ls

确认安装包存在以后:

bash 复制代码
tar -xf ollama-linux-amd64.tgz -C /usr/local/

然后检查:

bash 复制代码
ls /usr/local/bin/ollama

如果可以看到:

text 复制代码
ollama

说明文件已经解压出来。

课程中也是通过这种方式安装 Ollama 的。

检查 Ollama

执行:

bash 复制代码
/usr/local/bin/ollama -v

如果看到版本号,例如:

text 复制代码
ollama version is 0.3.9

说明 Ollama 程序已经安装好了。

需要注意的是,如果此时 Ollama 服务还没有启动,可能会看到:

text 复制代码
Warning: could not connect to a running Ollama instance

这个时候不要马上认为安装失败。

因为:

text 复制代码
安装 Ollama

和:

text 复制代码
启动 Ollama 服务

是两件事情。

只要版本号能够正常显示,一般说明客户端程序已经存在。课程资料也专门展示了这种情况。

配置 Ollama 服务

创建模型目录:

bash 复制代码
mkdir /ollama_models

然后创建:

text 复制代码
/etc/systemd/system/ollama.service

配置:

ini 复制代码
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=root
Group=root
Restart=always
RestartSec=3
Environment="OLLAMA_MODELS=/ollama_models"
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_ORIGINS=*"
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target

然后执行:

bash 复制代码
systemctl daemon-reload
systemctl restart ollama

最后检查:

bash 复制代码
ss -tunpl | grep 11434

如果看到:

text 复制代码
*:11434

说明 Ollama 正在监听 11434 端口。

课程中的服务配置也是通过 systemd 管理 Ollama,并设置 OLLAMA_MODELSOLLAMA_HOST

下载模型

例如下载:

bash 复制代码
ollama pull deepseek-r1:1.5b

下载完成以后可以查看:

bash 复制代码
ollama ls

例如:

text 复制代码
NAME
deepseek-r1:1.5b
qwen2:0.5b

课程资料中通过 ollama ls 查看本地模型,通过 ollama ps 查看正在运行的模型,也可以使用 ollama rm 删除不需要的模型。

测试模型

先不要急着写 Python。

建议先在服务器终端测试模型。

bash 复制代码
ollama run deepseek-r1:1.5b

然后输入:

text 复制代码
你好

如果模型能够正常回复:

text 复制代码
你好,有什么可以帮助你的?

说明:

text 复制代码
Ollama
模型
服务器

这几个部分基本没问题。

这个测试非常重要。

因为如果直接开始写 Python,最后网页不能聊天的时候,很难判断到底是:

text 复制代码
Ollama 出问题?
Python 出问题?
FastAPI 出问题?
Nginx 出问题?
前端出问题?

所以实际开发中最好一层一层测试。

安装 Python 3.11

本次模拟是在麒麟系统中额外安装 Python 3.11,同时特别强调不要直接删除系统原来的 Python,因为系统中的其他程序可能依赖旧版本。

安装依赖:

bash 复制代码
dnf install -y gcc openssl-devel bzip2-devel libffi-devel

下载 Python:

bash 复制代码
wget https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz

解压:

bash 复制代码
tar xf Python-3.11.9.tgz
cd Python-3.11.9

配置安装路径:

bash 复制代码
./configure --prefix=/usr/local/python3.11

然后编译:

bash 复制代码
make -j8

安装:

bash 复制代码
make install

最后通过软链接提供命令:

bash 复制代码
ln -s /usr/local/python3.11/bin/python3.11 /usr/bin/python3.11
ln -s /usr/local/python3.11/bin/pip3.11 /usr/bin/pip3.11

检查:

bash 复制代码
python3.11 -V
pip3.11 -V

安装 Python 依赖

安装 FastAPI:

bash 复制代码
pip3.11 install fastapi uvicorn

同时需要:

bash 复制代码
pip3.11 install requests

这里的作用很好理解:

text 复制代码
requests
    ↓
Python 请求 Ollama API

FastAPI
    ↓
给前端提供 HTTP API

uvicorn
    ↓
启动 FastAPI 程序

编写后台接口

创建:

text 复制代码
/data/main.py

一个适合本项目的后台代码如下:

python 复制代码
import requests
import uvicorn

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel


app = FastAPI()


# 允许前端访问后台接口
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


# 接收前端发送的数据
class ChatModel(BaseModel):
    text: str


# 聊天接口
@app.post("/chat")
def chat_page(item: ChatModel):

    url = "http://127.0.0.1:11434/api/chat"

    headers = {
        "Content-Type": "application/json"
    }

    payload = {
        "model": "deepseek-r1:1.5b",
        "messages": [
            {
                "role": "user",
                "content": item.text
            }
        ],
        "stream": False
    }

    response = requests.post(
        url,
        headers=headers,
        timeout=500,
        json=payload
    )

    data = response.json()

    return {
        "content": data.get("message", {}).get("content", "")
    }


if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=True
    )

这段代码基本就是整个项目最核心的部分。

启动 Python

运行:

bash 复制代码
python3.11 -u /data/main.py

如果启动成功,一般可以看到类似:

text 复制代码
Uvicorn running on http://0.0.0.0:8000

然后检查:

bash 复制代码
ss -tunlp | grep 8000

如果看到:

text 复制代码
*:8000

说明 Python 后台已经启动。

创建 Nginx 前端页面

安装 Nginx:

bash 复制代码
dnf install -y nginx

启动:

bash 复制代码
systemctl start nginx

查看状态:

bash 复制代码
systemctl status nginx --no-pager

然后把前端页面放到:

text 复制代码
/usr/share/nginx/html/index.html

课程中的 Nginx 部署也是采用这种方式。

步骤分析和代码解释

Python 为什么要调用 Ollama API

这里是整个项目最关键的地方。

我们并不是让 Python 自己运行大模型。

实际上 Python 做的是一个"中间人"。

比如用户在网页输入:

text 复制代码
Linux 怎么查看磁盘使用情况?

浏览器把数据发送给:

text 复制代码
FastAPI

FastAPI 收到以后,再执行:

python 复制代码
requests.post(
    "http://127.0.0.1:11434/api/chat"
)

把问题交给 Ollama。

所以:

text 复制代码
浏览器
 ↓
FastAPI
 ↓
requests
 ↓
Ollama API
 ↓
DeepSeek

这也是为什么 Python 代码里面需要 requests

课程中的 Ollama API 示例就是通过 requests.post() 请求 /api/chat,并将模型名称、用户问题以及 stream 参数放到 JSON 数据中。

ChatModel 是干什么的

代码:

python 复制代码
class ChatModel(BaseModel):
    text: str

看起来可能比较简单。

它其实是在规定:

text 复制代码
前端发送的数据必须长这样:
json 复制代码
{
    "text": "Linux怎么查看磁盘?"
}

那么 FastAPI 收到之后:

python 复制代码
item.text

就可以拿到:

text 复制代码
Linux怎么查看磁盘?

然后再交给 Ollama。

所以这里可以理解成一个数据格式检查。

/chat 接口

代码:

python 复制代码
@app.post("/chat")
def chat_page(item: ChatModel):

这里定义了一个:

text 复制代码
POST /chat

接口。

用户发送:

json 复制代码
{
    "text": "什么是Linux软链接?"
}

后台就可以处理。

这个接口可以理解成整个系统的"聊天入口"。

payload 是整个请求的核心

代码:

python 复制代码
payload = {
    "model": "deepseek-r1:1.5b",
    "messages": [
        {
            "role": "user",
            "content": item.text
        }
    ],
    "stream": False
}

这里实际上是在告诉 Ollama:

text 复制代码
我要使用哪个模型?
用户说了什么?
是否采用流式输出?

例如用户输入:

text 复制代码
什么是systemctl?

最终发送给 Ollama 的数据大概就是:

json 复制代码
{
    "model": "deepseek-r1:1.5b",
    "messages": [
        {
            "role": "user",
            "content": "什么是systemctl?"
        }
    ],
    "stream": false
}

这里的:

text 复制代码
model

决定使用哪个模型。

这里:

text 复制代码
content

就是用户真正的问题。

为什么 stream 设置成 false

代码:

python 复制代码
"stream": False

代表等待模型把完整答案生成出来之后,再一次性返回。

这样对于刚开始做实验来说比较容易理解。

流程就是:

text 复制代码
用户提问
 ↓
等待模型生成
 ↓
完整答案
 ↓
返回网页

如果以后想做成 ChatGPT 那种一个字一个字往外出现的效果,就可以研究流式输出。

那时候数据流会变成:

text 复制代码
用户提问
 ↓
模型开始生成
 ↓
返回第一部分
 ↓
返回第二部分
 ↓
返回第三部分
 ↓
......
 ↓
生成结束

这样用户体验会更好,但代码复杂度也会增加。

所以当前实验先采用:

python 复制代码
stream=False

是比较适合入门的方案。

前端代码是怎么和 Python 连接的

前端核心代码:

javascript 复制代码
ret = await fetch(
    'http://192.168.50.231:8000/chat',
    {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            text: text.value
        })
    }
)

这里最重要的是:

javascript 复制代码
fetch()

它就是浏览器向后台发送 HTTP 请求的方法。

例如:

text 复制代码
用户输入:
Linux怎么查看端口?

JavaScript 获取:

javascript 复制代码
text.value

然后转换成:

json 复制代码
{
    "text": "Linux怎么查看端口?"
}

发送给:

text 复制代码
192.168.50.231:8000/chat

也就是 Python FastAPI。

课程原始前端代码同样使用 fetch() 调用 FastAPI 的 /chat 接口。

前端为什么需要 CORS

FastAPI 中:

python 复制代码
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

这部分很多初学者第一次看到会比较懵。

简单理解就是:

text 复制代码
网页在一个地址
后台 API 在另一个地址

浏览器为了安全,默认会限制这种跨域请求。

例如:

text 复制代码
网页:
http://192.168.50.231

API:
http://192.168.50.231:8000

虽然服务器 IP 一样,但是端口不一样。

对于浏览器来说,它们并不是完全相同的来源。

所以实验阶段使用 CORS 允许访问。

不过真正部署到企业环境的时候,不建议长期使用:

python 复制代码
allow_origins=["*"]

而应该指定允许访问的网页来源。

Nginx 在这个项目中到底做什么

很多人刚开始可能会觉得:

text 复制代码
Python 已经可以启动网页了,为什么还要 Nginx?

其实 Python 的 FastAPI 主要负责:

text 复制代码
API

Nginx 更适合负责:

text 复制代码
网页
静态文件
HTTP访问
反向代理

所以可以这样分工:

text 复制代码
Nginx
负责:
index.html
CSS
JavaScript

FastAPI
负责:
/chat

这样的结构更清楚。

最终:

text 复制代码
浏览器
   ↓
Nginx
   ↓
index.html
   ↓
JavaScript
   ↓
FastAPI:8000
   ↓
Ollama:11434

这就是一个比较完整的 Web + AI 应用架构。

示例测试及结果

第一阶段:测试 Ollama

首先执行:

bash 复制代码
ollama ls

查看:

text 复制代码
deepseek-r1:1.5b

然后:

bash 复制代码
ollama run deepseek-r1:1.5b

输入:

text 复制代码
你好,请介绍一下Linux。

如果能够正常返回答案,就说明模型本身没有问题。

第二阶段:测试 Ollama API

使用 Python 测试:

python 复制代码
import requests

url = "http://127.0.0.1:11434/api/chat"

payload = {
    "model": "deepseek-r1:1.5b",
    "messages": [
        {
            "role": "user",
            "content": "什么是Linux?"
        }
    ],
    "stream": False
}

response = requests.post(
    url,
    json=payload,
    timeout=500
)

print(response.json())

如果返回 JSON:

json 复制代码
{
    "message": {
        "role": "assistant",
        "content": "Linux是一种开源操作系统..."
    }
}

说明:

text 复制代码
Python
 ↓
Ollama
 ↓
模型

已经连接成功。

第三阶段:测试 FastAPI

启动:

bash 复制代码
python3.11 -u main.py

然后通过浏览器或者其他 HTTP 工具请求:

text 复制代码
POST /chat

请求:

json 复制代码
{
    "text": "Linux怎么查看内存?"
}

后台返回:

json 复制代码
{
    "content": "可以使用 free -h 查看系统内存使用情况。"
}

这说明:

text 复制代码
FastAPI
 ↓
Ollama API

已经成功连接。

第四阶段:浏览器测试

打开:

text 复制代码
http://服务器IP

例如:

text 复制代码
http://192.168.88.135

进入网页之后:

text 复制代码
输入:
Linux如何查看端口?

点击:
发送

页面先显示:

text 复制代码
用户说:Linux如何查看端口?

然后后台处理。

最后显示:

text 复制代码
模型说:
可以使用 ss -tunlp 查看Linux系统中正在监听的端口。

至此,整个链路就跑通了。

测试 Linux 运维问题

这个时候我们就可以开始测试比较有实际意义的问题。

测试一:磁盘

输入:

text 复制代码
Linux怎么查看磁盘空间?

可能返回:

text 复制代码
可以使用 df -h 查看磁盘空间使用情况。

如果想查看某个目录占用了多少空间,可以使用:

du -sh /目录

测试二:端口

输入:

text 复制代码
Linux怎么查看8000端口有没有被占用?

可能返回:

text 复制代码
可以执行:

ss -tunlp | grep 8000

如果有程序监听8000端口,就会显示对应的进程信息。

这个问题就比较贴合运维日常。

测试三:服务

输入:

text 复制代码
Nginx启动失败应该怎么排查?

可以让 AI 给出:

text 复制代码
第一步:
systemctl status nginx

第二步:
nginx -t

第三步:
journalctl -u nginx

第四步:
检查80端口是否已经被其他程序占用。

这就比单纯测试:

text 复制代码
你好

更有意义。

总合应用:把它做成企业内部运维 AI 助手

如果只做到"网页聊天",其实只能算是一个 AI Demo。

真正有价值的地方,是把它和实际工作结合起来。

这里可以把项目定义成:

企业内部 Linux 运维智能助手

例如一个企业有几十台 Linux 服务器。

新员工刚进入公司,对 Linux 不熟。

平时遇到:

text 复制代码
磁盘满了怎么办?
服务启动不了怎么办?
端口被占用了怎么办?
Nginx 怎么配置?
日志怎么看?
Shell 脚本是什么意思?

可以先询问内部 AI。

场景一:新人学习 Linux

例如:

text 复制代码
用户:
systemctl restart nginx 是什么意思?

AI:

text 复制代码
systemctl 是Linux中管理systemd服务的命令。

restart 表示重启。

nginx 表示要操作的服务。

所以整个命令就是:
重启Nginx服务。

这样新员工可以边操作边学习。

场景二:运维故障排查

例如:

text 复制代码
用户:
我的Nginx启动失败了,应该怎么办?

AI 可以给出排查思路:

text 复制代码
1. 查看服务状态
systemctl status nginx

2. 检查配置文件
nginx -t

3. 查看日志
journalctl -u nginx

4. 查看端口
ss -tunlp | grep 80

这时候 AI 的作用不是简单告诉你一个命令,而是帮助你建立:

text 复制代码
故障
 ↓
查看状态
 ↓
查看日志
 ↓
检查配置
 ↓
检查端口
 ↓
解决问题

这种使用方式才比较接近真正的运维场景。

场景三:企业内部知识库

以后还可以继续升级。

比如企业有:

text 复制代码
Linux运维手册
Nginx配置文档
数据库操作手册
业务部署文档
故障处理流程
服务器规范

可以进一步让 AI 学习这些内部资料。

最终员工问:

text 复制代码
生产环境Nginx应该怎么重启?

AI 不只是根据通用知识回答,而是根据企业内部规范回答。

例如:

text 复制代码
按照公司运维规范:

1. 先检查Nginx配置
2. 确认配置无误
3. 执行reload
4. 检查服务状态
5. 检查业务访问

这就从:

text 复制代码
聊天机器人

慢慢变成:

text 复制代码
企业内部知识助手

场景四:Linux 日志分析

还可以继续扩展成:

text 复制代码
用户上传日志
       ↓
Python后台
       ↓
AI分析
       ↓
告诉用户可能的问题

例如日志:

text 复制代码
nginx: [error] connect() failed

用户问:

text 复制代码
这个错误可能是什么原因?

AI 可以从:

text 复制代码
网络
端口
后端服务
防火墙
配置

几个方向进行分析。

当然,如果以后让 AI 直接执行 Linux 命令,就必须增加权限控制,不能让模型随便执行:

bash 复制代码
rm -rf

这种高风险命令。

这也是项目进一步扩展时非常重要的一点。

总结项目中的坑和容易遇到的问题

Ollama 已经安装,但是运行模型失败了

比如:

bash 复制代码
ollama -v

有版本号。

但是:

bash 复制代码
ollama run deepseek-r1:1.5b

出现连接错误。

这种情况一般要先想到:

text 复制代码
Ollama客户端存在
≠
Ollama服务正在运行

检查:

bash 复制代码
systemctl status ollama

再检查:

bash 复制代码
ss -tunlp | grep 11434

11434端口没有监听

如果:

bash 复制代码
ss -tunlp | grep 11434

什么都没有。

说明 Ollama 服务没有正常监听。

可以查看:

bash 复制代码
systemctl status ollama

如果启动失败:

bash 复制代码
journalctl -u ollama

查看详细日志。

不要一看到端口不通就直接修改防火墙。

先确认服务到底有没有启动。

Python 连接不上 Ollama

例如 Python 报:

text 复制代码
Connection refused

首先检查:

bash 复制代码
curl http://127.0.0.1:11434/api/tags

如果访问不了:

text 复制代码
问题在 Ollama

如果 curl 正常,但是 Python 不行:

text 复制代码
再检查 Python 代码

这样排查会快很多。

Python版本问题

麒麟系统本身可能已经存在 Python。

这时候不要直接:

bash 复制代码
rm /usr/bin/python

然后安装新的 Python。

因为系统里面可能有程序依赖原来的 Python。

课程资料也特别强调了这一点,因此采用额外安装 Python 3.11 的方式,而不是直接替换系统 Python。

所以比较稳妥的方式是:

text 复制代码
系统Python
继续保留

Python3.11
单独安装

然后:

bash 复制代码
python3.11
pip3.11

单独使用。

前端网页可以打开,但是点击发送没有反应

这个问题非常常见。

首先按:

text 复制代码
F12

打开浏览器开发者工具。

查看:

text 复制代码
Console
Network

如果出现:

text 复制代码
CORS

可能是跨域配置问题。

如果出现:

text 复制代码
Failed to fetch

可以检查:

text 复制代码
8000端口
FastAPI服务
服务器IP

例如前端:

javascript 复制代码
fetch('http://192.168.50.231:8000/chat')

这里的 IP 如果写错了,就肯定访问不到。

Nginx能打开,但是AI不能聊天

这说明:

text 复制代码
Nginx正常

但是:

text 复制代码
FastAPI或者Ollama存在问题

可以按照下面的顺序检查:

text 复制代码
第一步:
curl 127.0.0.1:11434/api/tags

第二步:
检查Ollama

第三步:
检查8000端口

第四步:
检查FastAPI

第五步:
检查浏览器Network

不要一上来就重装所有软件。

模型太大,服务器运行很慢

这个问题也很现实。

模型并不是越大越好。

服务器配置比较低的时候,如果强行运行大型模型,很可能:

text 复制代码
响应很慢
内存不足
CPU长期100%
系统卡顿

课程中的实验使用:

text 复制代码
deepseek-r1:1.5b
qwen2:0.5b

这种相对较小的模型进行测试。

所以学习阶段可以先使用小模型。

等:

text 复制代码
架构
代码
接口
网页

全部跑通以后,再考虑更换更大的模型。

如何解决这些坑和问题

实际做项目的时候,我比较推荐采用"从底层往上测试"的方式。

不要一开始就测试整个网页。

应该这样:

text 复制代码
第一层:模型
    ↓
第二层:Ollama API
    ↓
第三层:Python
    ↓
第四层:FastAPI
    ↓
第五层:前端
    ↓
第六层:Nginx

第一层:确认模型

执行:

bash 复制代码
ollama ls

确认模型存在。

然后:

bash 复制代码
ollama run deepseek-r1:1.5b

输入:

text 复制代码
你好

确认模型能回答。

第二层:确认 Ollama API

执行:

bash 复制代码
curl http://127.0.0.1:11434/api/tags

如果能返回模型信息:

json 复制代码
{
    "models": [...]
}

说明 API 正常。

第三层:确认 Python

单独执行:

python 复制代码
requests.post(...)

确认 Python 能拿到 AI 返回结果。

这样可以把:

text 复制代码
Python问题

和:

text 复制代码
Ollama问题

分开。

第四层:确认 FastAPI

启动:

bash 复制代码
python3.11 -u main.py

然后确认:

bash 复制代码
ss -tunlp | grep 8000

如果端口存在,再测试:

text 复制代码
POST /chat

确认接口返回:

json 复制代码
{
    "content": "..."
}

第五层:确认网页

网页只负责:

text 复制代码
获取输入
 ↓
fetch
 ↓
显示结果

所以如果网页打不开:

text 复制代码
检查Nginx

如果网页能打开但是发送失败:

text 复制代码
检查FastAPI

如果 FastAPI 报错:

text 复制代码
检查Ollama

这种方式排查问题会比较清晰。

第六层:最后再做 systemd

当手动运行:

bash 复制代码
python3.11 -u /data/main.py

确认没有问题以后,再交给 systemd 管理。

例如:

ini 复制代码
[Unit]
Description=My Python Service
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/local/python3.11/bin/python3.11 -u /data/main.py
Restart=on-failure
RestartSec=5
StandardOutput=journal+console
StandardError=journal+console

[Install]
WantedBy=multi-user.target

然后:

bash 复制代码
systemctl daemon-reload
systemctl start myapp
systemctl enable myapp

这样服务器重启以后,Python 服务也可以自动启动。

课程资料中已经给出了通过 systemd 管理 Python 服务的方式。

总结

通过这次实验,可以把整个项目理解成四个核心部分:

text 复制代码
Ollama
负责运行AI模型

Python + FastAPI
负责后台接口

HTML + JavaScript
负责用户界面

Nginx
负责网页访问

它们组合起来以后:

text 复制代码
              用户
               ↓
          浏览器网页
               ↓
             Nginx
               ↓
        HTML + JavaScript
               ↓
        FastAPI / Python
               ↓
          requests
               ↓
        Ollama API
               ↓
       DeepSeek / Qwen
               ↓
          返回答案
               ↓
             用户

这个项目虽然代码量并不大,但是里面实际上已经包含了很多后面做项目会经常遇到的东西:

text 复制代码
Linux服务器
Python环境
HTTP请求
REST API
FastAPI
JSON
前后端通信
CORS
Nginx
systemd
Ollama
本地大模型

所以它不应该只被理解成一次"大模型安装实验"。

更准确地说,这是一个把:

text 复制代码
Linux
+
Python
+
Web
+
API
+
AI

结合起来的小型综合项目。

如果只是学习 Ollama,那么执行:

bash 复制代码
ollama run deepseek-r1:1.5b

就已经可以完成基本实验。

但是进一步加入 Python:

text 复制代码
Python → Ollama API

就开始进入 AI 应用开发。

再加入 FastAPI:

text 复制代码
浏览器 → FastAPI → Ollama

就形成了一个真正的后台服务。

最后再加入 Nginx:

text 复制代码
浏览器 → Nginx → 前端 → FastAPI → Ollama

就已经有了一个比较完整的 Web AI 应用雏形。

而这个项目后面还可以继续扩展,例如:

text 复制代码
聊天记录保存
用户登录
权限管理
企业知识库
文档上传
日志分析
流式输出
多模型切换
AI运维助手
RAG知识库

这样一步一步扩展下去,就可以从现在这个简单的"AI聊天网页",慢慢做成真正能够在企业内部使用的"私有化 AI 运维助手"。

对于目前这个阶段来说,最重要的并不是把功能一下子做得特别复杂,而是先把下面这条链路彻底理解:

text 复制代码
用户提出问题
    ↓
网页发送请求
    ↓
FastAPI接收请求
    ↓
Python调用Ollama
    ↓
Ollama调用本地模型
    ↓
模型生成答案
    ↓
Python返回结果
    ↓
网页显示答案

只要这条链路真正理解了,后面无论是增加数据库、知识库,还是做企业内部 AI 平台,基本都是在这套结构上继续往里面增加功能。

相关推荐
小小小小钰儿2 小时前
1.2-AI核心理论与术语
人工智能·计算机·网络安全·信息安全·程序员·编程
桃西西呀2 小时前
"循环深度"让小模型免费变大?GPT-6 Astra 背后的潜空间推理原理,8 个误读我替你拆了
人工智能·gpt·llm
数智工坊2 小时前
NTIRE2024×4图像超分竞赛综述|Mamba崛起、数据缩放、频域增强成为新趋势
网络·人工智能·深度学习·cnn·机器人
倔强的石头1062 小时前
【Linux指南】动静态库系列(七):符号表与重定位:链接器如何把函数调用接起来
linux·前端·javascript
山岚的运维笔记2 小时前
mysql 专业笔记 -- 第 8 章:使用变量
运维·数据库·笔记·后端·学习·mysql·dba
Raas1002 小时前
AI网关和大模型网关区别?MAI Gateway(魔芋企业级AI网关)如何实现AI流量统一治理
大数据·人工智能·gateway·ai网关·mai gateway·企业级产品
APSandafa2 小时前
安达发|灯具制造数字化:靠APS自动排程跑出交付优势
人工智能·制造·aps系统·aps自动排产·aps自动排单·aps智能排产排程排单软件
动物园猫2 小时前
道路设施目标检测数据集:4类别、5,000张图像 | 目标检测
人工智能·目标检测·计算机视觉
HIT_Weston2 小时前
203、【Agent】【OpenCode】JS 语法:作用域链与 var 循环陷阱
人工智能·agent·opencode