Hermes Web Chat MVP 实战:从0搭建自己的AI网页聊天系统(完整版)


目录

第一章 为什么要做 Hermes Web Chat

第二章 整体架构设计

第三章 项目目录

第四章 前端页面开发

第五章 FastAPI Backend

第六章 DeepSeek调用

第七章 API设计

第八章 OpenResty代理配置

第九章 HTTPS部署

第十章 Systemd部署

第十一章 常见问题排查

第十二章 性能优化

第十三章 下一步升级方向

附录A 全部源码

附录B 完整nginx配置

附录C 完整systemd配置

第一章 为什么要做 Hermes Web Chat

之前我们的Hermes Agent已经可以:

✅ 企业微信

✅ Redis Queue

✅ Worker

✅ DeepSeek

但是存在一个问题。

所有入口都是企业微信。

调试十分麻烦。

于是我们决定先做一个:

浏览器 → Hermes → DeepSeek

这是整个Hermes最轻量的一层。

整体结构如下:

Browser

     │

     ▼

index.html

     │

fetch()

     │

     ▼

FastAPI

     │

DeepSeek SDK

     │

     ▼

DeepSeek API

     │

返回答案

     │

     ▼

Browser

整个链路非常简单。

没有Redis。

没有Worker。

没有企业微信。

先把AI能力打通。


第二章 创建项目

首先建立项目。

mkdir hermes-web-chat-mvp

cd hermes-web-chat-mvp

建立目录

hermes-web-chat-mvp/

├── frontend/

│   └── index.html

│

├── backend/

│   ├── app/

│   │

│   ├── main.py

│   │

│   ├── chat.py

│   │

│   └── requirements.txt

│

└── README.md

这是最终目录。


第三章 Python环境

创建虚拟环境。

cd backend

python3 -m venv venv

激活

source venv/bin/activate

安装依赖。

requirements.txt

fastapi

uvicorn

requests

python-dotenv

安装

pip install -r requirements.txt

查看

pip list

应该看到

fastapi

uvicorn

requests

第四章 编写 Backend

main.py

from fastapi import FastAPI
from pydantic import BaseModel
import requests

app = FastAPI()

API_KEY="你的DeepSeek Key"

class ChatRequest(BaseModel):
    message:str

@app.post("/chat")
def chat(req:ChatRequest):

    headers={
        "Authorization":f"Bearer {API_KEY}"
    }

    data={
        "model":"deepseek-chat",
        "messages":[
            {
                "role":"user",
                "content":req.message
            }
        ]
    }

    r=requests.post(
        "https://api.deepseek.com/chat/completions",
        headers=headers,
        json=data
    )

    result=r.json()

    reply=result["choices"][0]["message"]["content"]

    return {"reply":reply}

启动

uvicorn main:app --host 0.0.0.0 --port 8001

浏览器打开

http://服务器IP:8001/docs

应该看到Swagger。


第五章 编写前端

frontend/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hermes Chat</title>
</head>

<body>

<h2>Hermes Chat</h2>

<input id="msg">

<button onclick="send()">
Send
</button>

<div id="reply"></div>

<script>

async function send(){

const message=document.getElementById("msg").value;

const res=await fetch("/api/chat",{

method:"POST",

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

body:JSON.stringify({

message:message

})

});

const data=await res.json();

document.getElementById("reply").innerHTML=data.reply;

}

</script>

</body>

</html>

启动

python3 -m http.server 8080

浏览器访问

http://服务器IP:8080

第六章 OpenResty

由于浏览器不能直接访问8001。

因此我们配置Nginx。

server {

    listen 443 ssl;

    server_name hermes.xxx.com;

    location / {

        root /opt/hermes/frontend;

        index index.html;

    }

    location /api/ {

        proxy_pass http://127.0.0.1:8001/;

    }

}

这里要注意:

location /api/

对应

proxy_pass http://127.0.0.1:8001/

最后面的

/

千万不能漏。


第七章 前端Fetch

这里也是最容易踩坑的位置。

很多人写成

fetch("/chat")

结果404。

因为真正代理的是

/api/chat

所以必须:

fetch("/api/chat")

第八章 我们踩过的坑

这是整个项目最重要的一章。

1 Backend没有启动

我们当时执行

ps aux | grep uvicorn

发现

没有8001

所以

curl

127.0.0.1:8001/chat

直接失败。


2 OpenResty代理错误

一开始配置的是

proxy_pass http://127.0.0.1:8001;

导致

/api/chat

↓

8001/api/chat

Backend没有

/api/chat

于是404。

后来改成

proxy_pass http://127.0.0.1:8001/;

恢复正常。


3 返回 No response

这是当时最大的坑。

{"reply":"No response"}

原因并不是前端。

而是:

DeepSeek接口没有返回choices。

所以

result["choices"]

为空。

最终增加:

print(r.text)

定位到了真实错误。


4 CORS问题

如果前端不是同域。

例如

8080

↓

8001

浏览器会报:

CORS blocked

需要:

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(

CORSMiddleware,

allow_origins=["*"],

allow_methods=["*"],

allow_headers=["*"]

)

5 HTTPS

如果网页:

https://

Backend:

http://

浏览器会:

Mixed Content

所以最终统一:

Browser

↓

HTTPS

↓

OpenResty

↓

HTTP

↓

FastAPI

浏览器始终HTTPS。


第九章 Systemd部署

创建

/etc/systemd/system/hermes-web.service

内容:

[Unit]
Description=Hermes Web Chat

After=network.target

[Service]

WorkingDirectory=/opt/ai/hermes-web-chat-mvp/backend

ExecStart=/opt/ai/hermes-web-chat-mvp/backend/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8001

Restart=always

User=root

[Install]

WantedBy=multi-user.target

启动:

systemctl daemon-reload

systemctl enable hermes-web

systemctl start hermes-web

查看日志:

journalctl -u hermes-web -f

第十章 后续升级方向

目前这个 MVP 已经完成了基础验证,后续可以逐步演进为真正的企业级 AI 平台:

  • 接入流式输出(Streaming),实现类似 ChatGPT 的逐字显示效果。
  • 引入多轮会话与上下文管理,支持连续对话。
  • 增加 Markdown 渲染、代码高亮和数学公式展示。
  • 集成用户登录、权限控制与会话历史。
  • 接入 Redis 队列,提高高并发场景下的处理能力。
  • 增加文件上传、知识库检索(RAG)与工具调用能力。
  • 与企业微信助手复用同一套 AI 服务,实现网页端与企业微信端统一后端。

结语

这套《Hermes Web Chat MVP》实践,不仅实现了一个可运行的 AI 网页聊天系统,更重要的是验证了从浏览器到 FastAPI,再到 DeepSeek 的完整调用链,为后续与企业微信、Redis、Worker、知识库以及多 Agent 架构融合打下了基础。

相比直接在复杂架构中调试,一个轻量级 Web Chat MVP 能够快速验证模型调用、接口设计、反向代理和部署流程,是整个 Hermes 企业 AI 平台建设中的第一块基石。后续所有高级能力,都可以在这一 MVP 的基础上逐步演进,而无需推倒重来。