构建AI Agent可视化仪表盘:从WebSocket实时通信到会话管理实战
2026/5/7 9:50:30 网站建设 项目流程

1. 项目概述:为 Hermes AI 构建一个现代化的 Web 仪表盘

如果你正在使用 Hermes AI Agent,并且厌倦了在终端里敲命令、查看日志文件来管理对话,那么你很可能需要一个更直观、更强大的管理界面。这就是 Hermes Dashboard 诞生的初衷。它是一个开源的、现代化的 Web 仪表盘,专门为 Hermes AI Agent 生态系统设计,让你能够在一个漂亮的图形界面中,实时查看和管理所有的 AI 对话会话。

这个项目本质上是一个“桥梁”应用。它不替代 Hermes 的核心功能,而是作为一个可视化层,通过一个轻量级的后端服务(基于 FastAPI)连接到正在运行的 Hermes Gateway,然后通过一个现代化的前端界面(基于 React + TypeScript)将数据呈现给你。想象一下,你有一个强大的 AI 引擎(Hermes),它一直在后台默默处理任务,而 Hermes Dashboard 就是为这个引擎配上的一个全彩仪表盘和中央控制台,让你能一目了然地看到转速、油温,并能轻松地进行操控。

它的核心价值在于将 Hermes 的会话数据(那些存储在~/.hermes/sessions/下的.jsonl文件)从冰冷的文本格式,转化为具有实时聊天流、工具调用可视化、会话 token 用量统计的交互式体验。无论你是开发者想要更便捷地调试 AI 行为,还是普通用户希望有一个更友好的聊天界面,这个仪表盘都能显著提升使用 Hermes 的效率和愉悦感。项目在设计上深受 PinchChat(一个为 OpenClaw 设计的优秀 UI)的启发,但在实现上完全针对 Hermes 的 API 和数据格式进行了重构和优化。

2. 核心功能与架构设计解析

2.1 功能全景:不止于聊天窗口

初看 Hermes Dashboard,你可能认为它只是一个聊天界面。但实际上,它围绕“会话管理”和“交互可视化”两个核心,构建了一套相当完整的功能矩阵。

首先是实时交互层。这是最直观的部分,它通过 WebSocket 实现了与 Hermes Gateway 的实时双向通信。当你发送一条消息时,前端会通过 WebSocket 将请求发送到 Bridge Server,后者再转发给 Hermes API。Hermes 的流式响应会通过 Server-Sent Events (SSE) 或类似机制返回,Bridge Server 将其转换为 WebSocket 消息流,推送到前端。这意味着你可以看到 AI 一个字一个字“思考”并回复的过程,而不是等待整个响应完成,体验非常流畅。

其次是深度可视化层,这也是我认为最有价值的部分。Hermes 这类智能体框架的核心能力之一是调用工具(Tools)。在原始日志中,工具调用可能只是一段 JSON。但在 Dashboard 里,每个工具调用都被渲染成一个可折叠的卡片,上面有清晰的工具名称、状态徽章(如“成功”、“执行中”、“错误”),甚至可能包含输入参数和返回结果的预览。这对于调试复杂的多步工具调用链至关重要。另一个亮点是“思考块”(Thinking Blocks)的展示。许多 AI 模型在回复前会有内部的推理过程,Dashboard 将这些过程捕获并以可折叠区块的形式呈现出来,旁边还会显示该段思考所耗费的时间,让你能直观感知 AI 的“思考深度”和效率。

最后是全局管理层。仪表盘左侧是一个完整的会话列表,支持拖拽排序,每个会话条目都配有一个直观的 token 使用量进度条和平台图标(如 Discord、Telegram、API 等),让你快速识别会话来源。顶部提供了全局的可见性切换按钮,可以一键隐藏或显示所有会话中的“思考块”、“工具调用”和“结果”部分,这在会话内容很长、你只想关注最终对话时非常有用。再加上多主题(深色、浅色、OLED)和多强调色的支持,整个界面既功能强大又高度可定制。

2.2 架构拆解:为什么是三层结构?

项目的架构图清晰地展示了一个典型的三层分离架构:前端 React 应用、中间桥接服务器(Bridge Server)和后端 Hermes Gateway。这种设计并非偶然,而是基于清晰的责任边界和实际需求考量。

前端(React + TypeScript + Vite)独立运行在localhost:10007,它的职责纯粹是 UI 渲染和用户交互。使用 Vite 构建确保了极快的热更新和启动速度,这对开发体验至关重要。TypeScript 的引入则保障了在复杂状态(如会话列表、实时消息流)管理下的代码可靠性。将前端独立出来,意味着未来你可以完全替换前端技术栈(比如用 Vue 或 Svelte 重写),而不会影响后端逻辑。

桥接服务器(Python FastAPI)是整个系统的中枢神经,运行在8643端口。它承担了几个关键任务:第一,作为协议转换器,将前端 WebSocket 协议与 Hermes Gateway 的 HTTP/SSE 协议进行桥接;第二,作为数据聚合器,它需要读取~/.hermes/sessions/目录下的原始.jsonl文件,将其解析、转换为前端需要的结构化会话数据;第三,提供额外的 REST API,比如健康检查、模型列表查询等,这些功能可能不直接存在于 Hermes Gateway 的 API 中。选择 FastAPI 是因为它异步性能好,对 WebSocket 支持原生,并且能自动生成 API 文档,非常适合这类中间件角色。

Hermes Gateway是既有的服务,运行在8642端口。Dashboard 架构明智地选择了“只读”和“代理”模式。桥接服务器会读取会话文件,但对于发送新消息、创建会话等写操作,则是将请求转发给 Hermes Gateway。这样做的好处是避免了直接操作文件系统可能带来的数据不一致风险,完全遵循 Hermes 自身的业务逻辑。

实操心得:架构选择的必然性为什么不直接让 React 前端调用 Hermes Gateway 的 API?主要有两个原因:跨域(CORS)和会话文件读取。Hermes Gateway 可能未配置允许前端域名跨域,且前端 JavaScript 出于安全限制无法直接读取用户本地文件系统。因此,这个 Python 桥接服务器是必不可少的中间层,它运行在本地,既能无障碍读取本地会话文件,又能通过配置灵活的 CORS 规则来服务前端。

3. 从零开始的部署与配置实操

3.1 环境准备与一键启动

假设你已经在本地运行了 Hermes AI Agent,并且 Gateway 正在默认的 8642 端口运行。部署 Dashboard 的第一步是获取代码。

# 克隆仓库 git clone https://github.com/monaleesa77/hermes-dashboard.git cd hermes-dashboard

项目最贴心的地方在于提供了一个start.sh脚本。在深入手动步骤之前,强烈建议先尝试这个一键启动脚本。它通常会帮你完成以下工作:检查 Python 和 Node.js 环境、创建 Python 虚拟环境、安装后端依赖、安装前端依赖,并尝试顺序启动后端和前端服务。

# 尝试一键启动(确保你有执行权限) chmod +x start.sh ./start.sh

如果一切顺利,脚本会在终端输出服务启动的日志,并提示你访问http://localhost:10007。用浏览器打开这个链接,你应该就能看到 Dashboard 的界面了。这是最快验证项目是否能跑起来的方法。

3.2 手动启动流程与深度配置

如果一键脚本因为环境差异失败了,或者你想更清晰地了解每个环节,手动启动是更好的学习方式。这个过程分为后端、前端两部分。

后端桥接服务器启动:

# 1. 进入后端目录 cd backend # 2. 创建并激活Python虚拟环境(隔离依赖) python3 -m venv venv # 在 macOS/Linux 上: source venv/bin/activate # 在 Windows 上: # venv\Scripts\activate # 3. 安装依赖 pip install -r requirements.txt # 关键依赖通常包括:fastapi, uvicorn, pydantic, websockets, python-dotenv # 4. 启动服务器 python main.py # 或使用 uvicorn 以获得更好的性能(如果 main.py 中 app 对象名为 app): # uvicorn main:app --host 0.0.0.0 --port 8643 --reload

启动后,你应该看到类似Uvicorn running on http://0.0.0.0:8643的输出。此时可以另开一个终端,测试后端 API 是否正常:

curl http://localhost:8643/api/health

预期返回一个{"status": "ok"}的 JSON。

前端 React 应用启动:

# 1. (如果还在 backend 目录)返回项目根目录 cd .. # 2. 进入前端目录 cd frontend # 3. 安装 Node.js 依赖(这步可能耗时,取决于网络) npm install # 或者如果你使用 yarn: yarn install # 4. 启动开发服务器 npm run dev

Vite 开发服务器启动后,会告诉你应用运行在http://localhost:10007(或类似的端口)。现在,打开浏览器访问这个地址,前端界面应该能加载出来。但此时,前端可能还无法连接到后端,因为需要正确配置。

关键配置详解:backend/.env文件

后端服务的所有关键配置都通过backend/.env文件管理。首次运行前,你可能需要根据你的环境调整它。

# Bridge Server 自身的监听地址和端口 BRIDGE_HOST=0.0.0.0 # 监听所有网络接口,这对于后续移动设备访问很重要 BRIDGE_PORT=8643 # 要连接的 Hermes Gateway 地址 HERMES_API_URL=http://localhost:8642 # 默认值,确保你的 Hermes Gateway 运行在此地址 HERMES_API_KEY=any # 如果 Hermes Gateway 需要 API 密钥,在此配置。‘any’可能是默认占位符。 # Hermes 会话文件的存储根目录 HERMES_HOME=/Users/your_username/.hermes # 必须修改!替换为你的实际用户目录路径 # 在 Linux/macOS 上,通常是 ~/.hermes # 在 Windows 上,可能是 C:\Users\YourName\.hermes # CORS 跨域设置,允许哪些前端地址访问后端 CORS_ORIGINS=http://localhost:10007,https://localhost:10007,http://127.0.0.1:10007,https://127.0.0.1:10007,http://192.168.*:10007,http://10.*.*.*:10007

注意事项:HERMES_HOME 路径是最大的坑90% 的启动失败都与HERMES_HOME配置错误有关。脚本或后端服务需要读取$HERMES_HOME/sessions/下的.jsonl文件来加载会话列表。如果路径不对,前端看到的会话列表就是空的。务必使用绝对路径,并确认该目录下确实存在 Hermes 生成的会话文件。你可以通过ls ~/.hermes/sessions/命令来验证。

3.3 移动端访问配置实战

将 Dashboard 扩展到手机或平板电脑上访问,能极大提升使用便利性。项目文档提供了基本步骤,但实际操作中会遇到几个典型问题。

第一步:确保同网络与获取 IP你的电脑和手机必须连接到同一个 Wi-Fi 网络。然后,你需要找到电脑在当前局域网内的 IP 地址,而不是127.0.0.1

# 在 macOS 上,最可靠的方式: ipconfig getifaddr en0 # 如果 en0 没结果,试试 en1,或者用: ifconfig | grep "inet " | grep -v 127.0.0.1 | head -n 1 | awk '{print $2}' # 在 Linux 上: hostname -I | awk '{print $1}' # 在 Windows PowerShell 中: (Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias Wi-Fi).IPAddress # 或者通过命令提示符:ipconfig | findstr IPv4

假设你得到的 IP 是192.168.1.100

第二步:修改 CORS 配置以允许手机访问这是关键一步。前端的开发服务器(Vite)默认只允许本地访问。为了让手机能访问,你需要确保两件事:

  1. 后端 CORS 允许手机 IP:修改backend/.env中的CORS_ORIGINS,添加你手机的访问地址。例如,添加http://192.168.1.100:10007。注意,这里支持通配符,http://192.168.*:10007已经覆盖了192.168.1.100
  2. 前端 Vite 配置允许主机访问:修改frontend/vite.config.ts,确保开发服务器监听所有网络接口。
// frontend/vite.config.ts export default defineConfig({ server: { host: '0.0.0.0', // 允许所有网络接口访问 port: 10007, // ... 其他配置 }, // ... 其他配置 });

第三步:启动服务并访问确保后端 (BRIDGE_HOST=0.0.0.0) 和前端 (host: '0.0.0.0') 都配置为监听所有接口后,重启两个服务。然后在手机的浏览器中访问http://192.168.1.100:10007

实操心得:移动端访问的防火墙问题如果手机无法访问,十有八九是电脑的防火墙阻止了外部对100078643端口的连接。在 macOS 上,你需要进入“系统设置”->“网络”->“防火墙”->“防火墙选项”,为Python(运行后端) 和Node(运行前端) 添加允许传入连接的规则。在 Windows 上,需要在“Windows Defender 防火墙”中添加入站规则。这是一个非常常见的绊脚石。

4. 核心功能的使用技巧与避坑指南

4.1 会话管理与数据解析机制

Dashboard 左侧的会话列表是其数据管理的核心。它并非实时轮询 Hermes Gateway,而是通过桥接服务器定期扫描HERMES_HOME/sessions/目录下的.jsonl文件。每个.jsonl文件代表一个会话,文件中的每一行都是一个 JSON 对象,记录了一条消息或一个事件。

会话加载逻辑:后端启动时和定期(可能通过定时任务或前端轮询)会遍历会话目录,解析每个文件。它会提取会话的元数据(如 ID、创建时间、平台类型)并计算 token 使用量。这个 token 用量进度条非常实用,它能让你快速识别哪些会话消耗了大量资源。平台图标(Discord、Telegram 等)则是根据会话元数据中的platform字段渲染的。

拖拽排序的持久化:你可能会注意到,当你拖拽会话重新排序后,刷新页面顺序可能又恢复了。这是因为当前的排序状态很可能只保存在前端的内存中(比如浏览器的localStorage),并未写回原始的.jsonl文件。这是一个设计上的权衡,因为直接修改 Hermes 的原始数据文件存在风险。如果你需要固定的会话顺序,可能需要考虑在桥接服务器层实现一个轻量级的排序索引文件。

常见问题:会话列表为空

  • 原因1HERMES_HOME路径配置错误。这是最常见的原因。请用绝对路径,并确认路径下有文件。
  • 原因2:会话文件格式不兼容。Hermes 的会话文件格式可能随版本更新而变化。确保你使用的 Dashboard 版本与 Hermes 版本大致匹配。可以查看桥接服务器的日志,看是否有解析错误。
  • 原因3:文件权限问题。确保运行后端服务的用户有权限读取~/.hermes/sessions/目录。

4.2 实时聊天与 WebSocket 连接维护

聊天功能的核心是 WebSocket 连接。前端会尝试连接到ws://localhost:8643/ws/chat(或对应的主机地址)。这个连接一旦建立,就会用于收发所有实时消息。

连接稳定性处理:在实际使用中,网络抖动或服务重启会导致 WebSocket 断开。一个健壮的实现会在前端包含自动重连逻辑。通常,在检测到连接关闭后,会等待一个指数退避的时间(如 1秒,2秒,4秒...)后尝试重新连接。你可以打开浏览器的开发者工具(F12)的“网络”选项卡,筛选“WS”类型,观察 WebSocket 连接的状态和消息流量,这是调试聊天功能的首选方法。

消息流格式:从 Hermes Gateway 返回的流式响应,经过桥接服务器转换后,会通过 WebSocket 以分块(chunk)的形式发送到前端。前端需要将这些 chunk 拼接起来,并实时更新到 UI 上。消息中通常会包含类型字段,用以区分是“思考内容”、“工具调用”还是“最终回复”,从而决定渲染到哪个 UI 区块。

避坑指南:处理复杂的工具调用链当 AI 执行一个涉及多个步骤、且后续步骤依赖前序步骤结果的复杂工具调用时,前端的渲染逻辑需要特别注意状态管理。工具调用卡片应该清晰地展示执行顺序、依赖关系和每个步骤的结果。如果发现工具调用显示错乱或丢失,首先检查后端桥接服务器从 Hermes Gateway 接收到的原始事件流是否完整,然后检查前端解析这些事件并更新组件状态的逻辑是否正确,特别是异步更新时可能存在的竞态条件。

4.3 主题与视觉定制实践

Dashboard 提供了深色、浅色、OLED 三种主题和六种强调色。这些样式很可能通过 CSS 变量(Custom Properties)和 Tailwind CSS 的暗黑模式类来实现。

主题切换原理:前端通常会在根元素(如<html>)上设置一个数据属性(如>from fastapi import APIRouter, HTTPException import os import glob from datetime import datetime, timedelta router = APIRouter() @router.delete("/api/sessions/cleanup") async def cleanup_old_sessions(days_old: int = 7): """ 删除早于指定天数的会话文件。 """ sessions_path = os.path.expanduser(config.HERMES_HOME + "/sessions") cutoff_time = datetime.now() - timedelta(days=days_old) deleted_files = [] for file_path in glob.glob(os.path.join(sessions_path, "*.jsonl")): file_mtime = datetime.fromtimestamp(os.path.getmtime(file_path)) if file_mtime < cutoff_time: os.remove(file_path) deleted_files.append(os.path.basename(file_path)) return {"deleted": deleted_files, "count": len(deleted_files)}

然后记得在main.pyapp对象中引入这个路由。

前端扩展示例:在会话列表添加搜索框你可以在frontend/src/components/Sidebar/目录下的会话列表组件中,增加一个输入框,并过滤sessions数组。关键是在 React 状态中维护一个搜索关键词,并在渲染列表前进行过滤。

5.2 系统化故障排查指南

当 Dashboard 无法正常工作时,可以按照以下流程进行排查,这能帮你快速定位问题层。

第1步:检查基础服务首先,确认 Hermes Gateway 这个基石服务是否在运行。

curl http://localhost:8642/health

如果没有响应,你需要先启动 Hermes Gateway:hermes gateway run

第2步:检查桥接服务器(Backend)后端是连接前端和 Hermes 的桥梁,它的健康状态至关重要。

curl http://localhost:8643/api/health
  • 如果无响应:检查后端进程是否运行(ps aux | grep python main.py),检查端口8643是否被占用(lsof -i :8643),检查.env配置是否正确,特别是HERMES_HOME
  • 如果返回错误:查看后端服务的日志输出,通常会有详细的错误信息,比如导入模块失败、配置文件找不到、会话文件解析错误等。

第3步:检查前端(Frontend)前端服务本身是否可访问。

curl http://localhost:10007
  • 如果无响应:检查前端开发服务器是否运行(npm run dev),检查端口10007是否被占用。
  • 如果页面能加载但空白或报错:打开浏览器开发者工具(F12),查看“控制台”(Console)和“网络”(Network)选项卡。控制台会显示 JavaScript 错误,网络选项卡会显示资源加载失败或 API 请求失败(特别是对localhost:8643的请求)。最常见的错误是 CORS 错误,这需要你确认CORS_ORIGINS配置包含了前端地址http://localhost:10007

第4步:检查 WebSocket 连接在浏览器中打开 Dashboard,按 F12 打开开发者工具,进入“网络”->“WS”过滤。你应该能看到一个到ws://localhost:8643/ws/chat的连接。如果状态不是“101 Switching Protocols”,或者很快断开,说明 WebSocket 连接失败。检查后端 WebSocket 路由实现,以及前端连接代码。

第5步:检查数据流如果界面能打开,WebSocket 也连上了,但会话列表为空或无法发送消息。

  • 会话列表为空:回到第2步,检查后端日志中读取HERMES_HOME的路径和结果。
  • 无法发送消息:在开发者工具的“网络”选项卡中,查看发送消息时 WebSocket 是否有消息发出,后端是否有日志。可能是消息格式不符合 Hermes Gateway 的预期,需要检查hermes_client.py中的请求封装逻辑。

5.3 性能优化与生产部署考量

目前项目提供的start.shnpm run dev都是面向开发环境的。如果你希望将其用于更稳定的日常使用,甚至小范围团队共享,需要考虑一些优化。

后端生产部署:开发时用的python main.pyuvicorn main:app --reload不适合生产。生产环境建议使用:

# 使用 Gunicorn 作为进程管理器,配合 Uvicorn 工作进程(适用于 Linux/macOS) cd backend source venv/bin/activate gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8643

这里-w 4指定了4个工作进程,可以根据你的 CPU 核心数调整。此外,应该设置--reload为关闭,并考虑配置反向代理(如 Nginx)来处理 SSL、静态文件和负载均衡。

前端构建与部署:开发服务器 (npm run dev) 提供了热重载,但性能不是最优。对于生产,需要构建静态文件:

cd frontend npm run build # 根据 package.json 中的脚本,通常是 `vite build`

构建完成后,会生成一个dist目录,里面是优化过的静态文件(HTML, JS, CSS)。你可以将这个目录交给 Nginx 或 Apache 等 Web 服务器来托管。此时,前端不再需要 Node.js 服务,但需要确保后端 API 地址(localhost:8643)在构建时被正确配置为生产环境的地址(例如,通过环境变量VITE_API_URL)。这通常需要在vite.config.ts和前端代码中做相应配置。

安全性强化:当前配置为了方便,可能使用了 HTTP 和简单的 CORS 规则。在生产环境,尤其是允许局域网访问时,强烈建议:

  1. 通过反向代理(如 Nginx)配置 HTTPS,使用 Let‘s Encrypt 等免费证书。
  2. 收紧 CORS 配置,只允许确切的域名或 IP。
  3. 如果 Hermes Gateway 支持,使用真正的 API Key 而非any
  4. 考虑为桥接服务器添加简单的认证层(如 HTTP Basic Auth),防止同一网络内未经授权的访问。

这个 Dashboard 项目为 Hermes AI Agent 的用户打开了一扇全新的窗口,将命令行下的交互提升到了可视化、可管理的层面。从我实际部署和使用的体验来看,它的价值在于极大地降低了日常使用和调试 Hermes 的心智负担。无论是实时观察 AI 的思考过程,还是管理大量的历史会话,这个工具都显得游刃有余。当然,作为一个开源项目,它在会话持久化排序、移动端 HTTPS 支持等方面还有打磨空间,但这恰恰为开发者提供了参与贡献的机会。如果你也受困于终端日志的海洋,不妨试试把它跑起来,或许你也会和我一样,再也回不去那种纯命令行的交互方式了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询