新能源智能车队运维平台
MCP 工具化 · LangGraph 多智能体编排 · 跨协议统一车队管理
内置 AI 助手 维克斯(Vehix) — 你的 24×7 智能车队运维伙伴
维克斯 是一个基于 LLM 的智能车队运维助手,具备多步诊断推理、车控安全审批、OTA 升级管理和多协议(GB/T 32960 / JT/T 808 / UDS)混合车队统一管理能力。通过 MCP(Model Context Protocol)标准化工具接口,维克斯可以无缝接入各类车辆数据源和控制系统。
核心验证:MCP 工具标准化、LLM 多步诊断推理、车控安全审批门禁、多协议混合车队管理。
应用启动时用 SQLAlchemy create_all 保证表存在(适合 demo)。
结构化演进请用 Alembic(alembic.ini 使用相对路径,可在任意机器执行):
cd backend
source venv/bin/activate
# 生成迁移(模型变更后)
alembic -c alembic.ini revision --autogenerate -m "描述"
# 执行迁移
alembic -c alembic.ini upgrade head
# 回滚一步
alembic -c alembic.ini downgrade -1# 推荐:设置 JWT secret;SQLite 数据落在 named volume `backend-data`
VEHIX_JWT_SECRET=$(openssl rand -hex 32) VEHIX_LLM_API_KEY=sk-xxx VITE_AMAP_KEY=4b3b... docker compose up -d
# 子路径(默认 VITE_BASE_URL=/vehix/)经宿主机 nginx 访问 https://domain/vehix/
# 裸端口本地访问(无 /vehix/ 前缀):
# VITE_BASE_URL=/ VEHIX_JWT_SECRET=... VEHIX_LLM_API_KEY=... docker compose up -d --build
# 访问 http://localhost:8080 (前端) / http://localhost:8081 (后端,仅本机)/api/health 只检查数据库与模拟器(不调用 LLM),供 Docker healthcheck 使用。
MCP HTTP(/mcp/*)默认关闭;需要时设 VEHIX_MCP_HTTP_ENABLED=true 且需 admin Token。
Docker 内部没有 nginx:前端和后端各自把端口发布到宿主机回环地址,由宿主机 nginx 按路径直连各服务:
| 端口(仅 127.0.0.1) | 服务 |
|---|---|
8080 |
frontend |
8081 |
backend |
如果你的服务器已有 HTTPS nginx,将 host-nginx.conf.example 中的 location 块(/vehix/api/ → 后端、/vehix/ → 前端等)加入你的 server {} 配置:
location /vehix/api/ { proxy_pass http://127.0.0.1:8081/api/; }
location /vehix/ { proxy_pass http://127.0.0.1:8080/; }(完整配置含 /vehix/mcp/、/vehix/docs、/vehix/openapi.json 路由及 SSE 所需超时设置,见 host-nginx.conf.example。)
然后启动容器:
VITE_BASE_URL=/vehix/ VEHIX_LLM_API_KEY=sk-xxx docker compose up -d
# 访问 https://your-domain.com/vehix/TLS 由宿主机 nginx 处理,容器内部只运行 HTTP。
镜像由 GitHub Actions 构建并推送阿里云 ACR(个人版),服务器只 pull 不打包。
一次性配置(GitHub):
- 在 ACR 控制台创建命名空间(如
iotplanet),并设置「访问凭证」密码 - GitHub → Settings → Secrets and variables → Actions,新增 Secrets:
ACR_USERNAME:阿里云账号名ACR_PASSWORD:ACR 访问凭证密码VITE_AMAP_KEY:高德 JS API Key
- 若命名空间不是
iotplanet,修改.github/workflows/build-push-acr.yml顶部的ACR_NAMESPACE
push 到 main 后自动构建并推送 latest + sha-xxxxxxx 两个 tag;打 v* tag 会额外生成版本 tag。
服务器部署(只需 Docker,无需构建链):
echo "ACR_NAMESPACE=iotplanet" >> .env
docker compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d日常更新:服务器上重复上面 pull + up 两步即可;需要回滚时固定版本拉取:
IMAGE_TAG=sha-abc1234 docker compose -f docker-compose.yml -f docker-compose.prod.yml pull && docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d# 后端
cd backend
cp .env.example .env # 编辑 .env 填入 LLM Key 和 JWT Secret
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
python -m app.main # http://localhost:8000
# 前端
cd frontend
cp .env.example .env # 编辑 .env 填入高德地图 Key
pnpm install && pnpm dev # http://localhost:5173首次启动(库中无用户时)自动创建以下账户。密码均可经环境变量覆盖:
| 用户名 | 环境变量 | 默认密码 | 角色 |
|---|---|---|---|
superuser |
VEHIX_INITIAL_SUPERUSER_PASSWORD |
admin123 |
超级管理员 |
admin |
VEHIX_INITIAL_ADMIN_PASSWORD |
admin123 |
管理员 |
operator |
VEHIX_INITIAL_OPERATOR_PASSWORD |
operator123 |
操作员 |
viewer |
VEHIX_INITIAL_VIEWER_PASSWORD |
viewer123 |
查看者 |
生产部署务必更换 VEHIX_JWT_SECRET 与上述密码。登录页仅在本地开发(或 VITE_SHOW_DEMO_CREDENTIALS=true)显示演示账号提示。
- JWT Bearer Token:
POST /api/auth/login获取 access token(15 分钟)和 refresh token(7 天) - 密码哈希:bcrypt (cost factor 12)
- Token 刷新:
POST /api/auth/refresh使用 refresh token 换取新 token
| 操作 | viewer | operator | admin | superuser |
|---|---|---|---|---|
| 查看车队/车辆/遥测/DTC | ✅ | ✅ | ✅ | ✅ |
| Agent 对话查询 | ✅ | ✅ | ✅ | ✅ |
| 低风险车控(解锁/空调/充电) | ❌ | ✅ | ✅ | ✅ |
| 中风险车控(限功率/清DTC) | ❌ | ❌ | ✅ | ✅ |
| 高危车控审批 | ❌ | ❌ | ✅ | ✅ |
| OTA 管理 | ❌ | ❌ | ✅ | ✅ |
| 车辆注册/删除 | ❌ | ❌ | ✅ | ✅ |
| 工单查看 | ✅ | ✅ | ✅ | ✅ |
| 工单状态流转 | ❌ | ✅ | ✅ | ✅ |
| 系统配置管理 | ❌ | ❌ | ✅ | ✅ |
operator 发起命令
├─ 低风险 → 直接执行
├─ 中风险 → 需 admin 审批 → 下发
└─ 高危 (remote_shutdown) → 需 admin 审批 → 下发
遵循 12-Factor App 方法论,LLM Key 通过环境变量注入,不做应用层加密存储。
# 1. 查看当前配置状态(不泄露完整 Key)
curl http://localhost:8000/api/llm/status
# → {"configured":true, "model":"deepseek-chat", "key_preview":"sk-7752****8ad"}
# 2. 测试新 Key 是否有效(不保存,仅验证)
curl -X POST http://localhost:8000/api/llm/test \
-H "Content-Type: application/json" \
-d '{"api_key":"sk-your-new-key","base_url":"https://api.deepseek.com","model":"deepseek-chat"}'
# → {"ok":true, "model":"deepseek-chat", "latency_ms":82.5}
# 3. 测试通过后,修改 .env 或 docker-compose.yml,重启生效为什么这样设计:密钥管理应交给专业的 Secret Manager(K8s Secret / Vault / AWS Secrets Manager),不应该在应用层重造轮子。当前简单场景用 .env 环境变量,生产环境升级为零代码改动。
- 生产环境使用
openssl rand -hex 32生成VEHIX_JWT_SECRET - 更换所有默认账户密码
- 启用 HTTPS(JWT 明文传输风险)
- 配置 CORS 白名单(当前默认允许 localhost 开发端口)
- 登录接口添加速率限制(5 次/分钟/IP)
# 登录获取 token
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# 使用 token 下发命令
curl -X POST http://localhost:8000/api/vehicles/LSVAU2A0000000/commands \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"command":"unlock_door"}'
# viewer 尝试下发命令 → 403 Forbidden
curl -X POST http://localhost:8000/api/vehicles/LSVAU2A0000000/commands \
-H "Authorization: Bearer <viewer_token>" \
-H "Content-Type: application/json" \
-d '{"command":"unlock_door"}'- 后端: Python / FastAPI / LangGraph / SQLAlchemy / SQLite (可切换 PostgreSQL)
- 前端: React 19 / HeroUI v3 / Tailwind CSS v4 / ECharts / AMap
- 协议: GB/T 32960 (新能源) / JT/T 808 (商用车) / UDS ISO 14229 (诊断)
- 工具标准: MCP (Model Context Protocol)
- Rust 扩展: Command Gateway / UDS Parser / OTA Verifier
vehix-agent/
├── backend/
│ ├── app/
│ │ ├── agent/ # LangGraph 多智能体编排
│ │ ├── api/ # REST API + SSE streaming
│ │ ├── auth/ # JWT 认证 + RBAC 权限
│ │ ├── mcp/ # MCP 工具层 (含 OTA 暂停/继续等)
│ │ ├── models/ # ORM 模型 (8 个表)
│ │ └── simulator/ # 车辆模拟器 (GB/T 32960 + JT/T 808)
│ └── rust-services/ # Rust 安全模块 (WIP)
├── frontend/ # React SPA
└── docs/ # 设计文档
├── xtream-codec-integration.md
└── auth-and-config-design.md