# vehix-agent
**Repository Path**: iotplanet/vehix-agent
## Basic Information
- **Project Name**: vehix-agent
- **Description**: 一个面向新能源汽车车队的云端智能运维 Agent——以 GB/T 32960 数据规范为底座,以 UDS 诊断协议为工具核心,以 MCP 为工具化标准,做出一个"能查询、能诊断、能派单、能下发车控(带审批)"的可运行全栈应用。
- **Primary Language**: Unknown
- **License**: MulanPSL-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-08-10
- **Last Updated**: 2026-08-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ⚡ Vehix Agent
新能源智能车队运维平台
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` 使用相对路径,可在任意机器执行):
```bash
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
```
## 部署
### Docker(独立运行)
```bash
# 推荐:设置 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。
### 宿主机 nginx 反向代理(HTTPS 子路径)
Docker 内部没有 nginx:前端和后端各自把端口发布到宿主机回环地址,由宿主机 nginx 按路径直连各服务:
| 端口(仅 127.0.0.1) | 服务 |
|---------------------|------|
| `8080` | frontend |
| `8081` | backend |
如果你的服务器已有 HTTPS nginx,将 `host-nginx.conf.example` 中的 location 块(`/vehix/api/` → 后端、`/vehix/` → 前端等)加入你的 `server {}` 配置:
```nginx
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`。)
然后启动容器:
```bash
VITE_BASE_URL=/vehix/ VEHIX_LLM_API_KEY=sk-xxx docker compose up -d
# 访问 https://your-domain.com/vehix/
```
TLS 由宿主机 nginx 处理,容器内部只运行 HTTP。
### CI 构建 + 服务器拉取部署(推荐)
镜像由 GitHub Actions 构建并推送阿里云 ACR(个人版),服务器只 `pull` 不打包。
**一次性配置(GitHub)**:
1. 在 ACR 控制台创建命名空间(如 `iotplanet`),并设置「访问凭证」密码
2. GitHub → Settings → Secrets and variables → Actions,新增 Secrets:
- `ACR_USERNAME`:阿里云账号名
- `ACR_PASSWORD`:ACR 访问凭证密码
- `VITE_AMAP_KEY`:高德 JS API Key
3. 若命名空间不是 `iotplanet`,修改 `.github/workflows/build-push-acr.yml` 顶部的 `ACR_NAMESPACE`
push 到 `main` 后自动构建并推送 `latest` + `sha-xxxxxxx` 两个 tag;打 `v*` tag 会额外生成版本 tag。
**服务器部署**(只需 Docker,无需构建链):
```bash
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 两步即可;需要回滚时固定版本拉取:
```bash
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
```
## 快速启动
```bash
# 后端
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
```
### 数据治理 Demo(M1 雏形 · Kafka → Iceberg → UI/Agent)
默认真数链路、分层图与对外 5 分钟脚本见 **[ext/docs/DEMO.md](./ext/docs/DEMO.md)**(`make demo-up` / `demo-pipeline` / `demo-verify`)。
方案与 WP 状态:**[docs/data-governance.md](./docs/data-governance.md)**。
当前 **冻结深化**:不展开 WP0 真车、Gold、DQC/OPA 深讲。
## 默认账户
首次启动(库中无用户时)自动创建以下账户。密码均可经环境变量覆盖:
| 用户名 | 环境变量 | 默认密码 | 角色 |
|--------|---------|---------|------|
| `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
### 角色权限 (RBAC)
| 操作 | viewer | operator | admin | superuser |
|------|--------|----------|-------|-----------|
| 查看车队/车辆/遥测/DTC | ✅ | ✅ | ✅ | ✅ |
| Agent 对话查询 | ✅ | ✅ | ✅ | ✅ |
| 低风险车控(解锁/空调/充电) | ❌ | ✅ | ✅ | ✅ |
| 中风险车控(限功率/清DTC) | ❌ | ❌ | ✅ | ✅ |
| 高危车控审批 | ❌ | ❌ | ✅ | ✅ |
| OTA 管理 | ❌ | ❌ | ✅ | ✅ |
| 车辆注册/删除 | ❌ | ❌ | ✅ | ✅ |
| 工单查看 | ✅ | ✅ | ✅ | ✅ |
| 工单状态流转 | ❌ | ✅ | ✅ | ✅ |
| 系统配置管理 | ❌ | ❌ | ✅ | ✅ |
### 车控审批流
```
operator 发起命令
├─ 低风险 → 直接执行
├─ 中风险 → 需 admin 审批 → 下发
└─ 高危 (remote_shutdown) → 需 admin 审批 → 下发
```
### LLM 配置
遵循 **12-Factor App** 方法论,LLM Key 通过环境变量注入,不做应用层加密存储。
```bash
# 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)
## 权限测试
```bash
# 登录获取 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 " \
-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 " \
-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)
- **数据治理(M1 雏形)**: Kafka · Flink · Iceberg · Trino · Spring data-svc(见 `ext/`)
- **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
├── ext/ # 数据治理扩展(M1 雏形:Flink/Iceberg/Trino/data-svc;OPA/DQC 骨架)
└── docs/ # 设计文档
├── ROADMAP.md
├── production.md
├── data-governance.md # 数据治理层(现状雏形 / WP / MCP / 选型)
├── configuration.md
├── xtream-codec-integration.md
└── Vehix Agent.md
```