Skip to content

Repository files navigation

车载智能助手云端 Agent 平台

这是一个车载智能助手云端 Agent 平台演示项目,当前已跑通文字、流式、事件和多模态交互闭环:

前端交互面板 -> Java Spring Boot 后端 -> Python FastAPI Agent -> 模拟车辆工具/视觉模型 -> 返回回答

模块

car-agent-platform/
├── backend-java/      Java Spring Boot 后端,负责 HTTP、WebSocket 和调用 Agent
├── agent-python/      Python FastAPI Agent 服务,负责意图识别和车辆工具调用
├── vehicle-event-simulator/ Kafka 车辆事件模拟器
├── frontend/          Vite + React 前端聊天页面
├── docker-compose.yml 后续一键启动多服务
└── README.md

第一版端口

服务 地址
前端 http://localhost:5173
Java 后端 http://localhost:8080
Python Agent http://localhost:8000
MySQL localhost:3306
Redis localhost:6379
Kafka localhost:9092
Ollama http://localhost:11434

本地启动

项目 Dockerfile 默认使用 docker.m.daocloud.io/library/... 作为基础镜像来源,原因是部分网络环境下 Docker Hub 直连可能失败。

本地模型配置(无需 API Key)

项目默认使用 Docker Compose 内的 Ollama,不需要任何云端 API Key:文本问答使用 qwen2.5:3b,图片理解使用 qwen2.5vl:3b。仓库只提交 .env.example,真实的 .env 和本地密码记录不会提交。

克隆仓库后,先在项目根目录创建本地配置:

Copy-Item .env.example .env
$passwordChars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789'.ToCharArray()
$rootPassword = -join (1..32 | ForEach-Object { $passwordChars | Get-Random })
$appPassword = -join (1..32 | ForEach-Object { $passwordChars | Get-Random })
while ($appPassword -eq $rootPassword) { $appPassword = -join (1..32 | ForEach-Object { $passwordChars | Get-Random }) }
(Get-Content .env) -replace '^MYSQL_ROOT_PASSWORD=.*$', "MYSQL_ROOT_PASSWORD=$rootPassword" -replace '^MYSQL_PASSWORD=.*$', "MYSQL_PASSWORD=$appPassword" | Set-Content .env

也可以手动编辑 .env,为 MYSQL_ROOT_PASSWORDMYSQL_PASSWORD 填入两组不同的随机密码。不要把 .envLOCAL_PASSWORDS.txt 上传到 GitHub。

上传仓库时建议在项目根目录初始化 Git,再执行 git add ..gitignore 会自动排除本地密码和构建缓存。GitHub 网页的“上传文件”不会替你执行 .gitignore,手动上传时必须确认没有选中 .envLOCAL_PASSWORDS.txt

首次启动 Ollama 后,需要一次性拉取两个模型:

docker compose up -d ollama
docker compose exec ollama ollama pull qwen2.5:3b
docker compose exec ollama ollama pull qwen2.5vl:3b

模型文件保存在 ollama-data volume 中,后续重启无需重复下载。完成后启动整套服务:

docker compose up --build -d

Agent 健康检查会显示 llmConfiguredllmProviderllmModelvisionConfiguredvisionModel

curl http://localhost:8000/health

Docker Compose 启动

docker compose up --build -d

查看容器:

docker compose ps

停止服务:

docker compose down

MySQL 数据库名和用户名默认为 car_agent,密码由本机 .env 提供。首次启动会创建数据卷;已有数据卷不会因为修改 .env 自动改密码,需要按数据库迁移方式更新账号密码。

1. 启动 Python Agent

cd agent-python
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
python -m uvicorn app.main:app --reload --port 8000

健康检查:

curl http://localhost:8000/health

2. 启动 Java 后端

cd backend-java
mvn spring-boot:run

健康检查:

curl http://localhost:8080/api/health

3. 启动前端

cd frontend
npm install
npm run dev

打开:

http://localhost:5173

测试聊天接口

curl -X POST http://localhost:8080/api/chat ^
  -H "Content-Type: application/json" ^
  -d "{\"sessionId\":\"session-001\",\"vehicleId\":\"car-001\",\"content\":\"我的车还有多少电?\"}"

PowerShell 推荐用下面这种写法:

$body = @{ sessionId = 'session-001'; vehicleId = 'car-001'; content = '我的车还有多少电?' } | ConvertTo-Json -Compress
Invoke-RestMethod -Uri 'http://localhost:8080/api/chat' -Method Post -ContentType 'application/json; charset=utf-8' -Body $body

会话和历史消息接口

创建或获取会话:

$body = @{ sessionId = 'session-001'; vehicleId = 'car-001'; title = '默认车载助手会话' } | ConvertTo-Json -Compress
Invoke-RestMethod -Uri 'http://localhost:8080/api/sessions' -Method Post -ContentType 'application/json; charset=utf-8' -Body $body

查询历史消息:

Invoke-RestMethod -Uri 'http://localhost:8080/api/sessions/session-001/messages' -Method Get

车辆状态和 Redis 缓存

查询车辆状态:

Invoke-RestMethod -Uri 'http://localhost:8080/api/vehicles/car-001/state' -Method Get

Redis key 设计:

vehicle:car-001:state
session:session-001:context

V5 Kafka 车辆事件推送

Compose 会启动 Kafka 和 vehicle-event-simulator。模拟器每 15 秒向 vehicle-events topic 写入一条事件,包括低电量、胎压异常、充电完成、车门未锁。Java 后端通过 Kafka consumer 消费事件,合并更新 Redis 中的 vehicle:{vehicleId}:state;需要提醒用户的事件会通过 /ws/chat 主动推送到前端事件提醒列表。

查看 Kafka 事件模拟器日志:

docker compose logs -f vehicle-event-simulator

查看 Java 后端消费日志:

docker compose logs -f backend-java

查看车辆状态是否被事件更新:

Invoke-RestMethod -Uri 'http://localhost:8080/api/vehicles/car-001/state' -Method Get

查看 Redis 缓存:

docker compose exec redis redis-cli keys '*'
docker compose exec redis redis-cli get vehicle:car-001:state
docker compose exec redis redis-cli lrange session:session-001:context 0 -1

第一轮 Agent 能力

  • 结构化工具路由:车辆状态查询、车辆控制、最近事件查询、说明书检索
  • 本地车辆说明知识库检索,返回匹配的说明书章节来源
  • Kafka 事件写入 Redis 最近事件列表,Agent 可以回答“最近有什么异常/提醒”
  • 本地 Ollama 文本模型同步和流式调用,支持超时、重试及不可用时规则降级
  • Java Agent Client 通过 SSE 接收增量内容,再经 WebSocket 推送到前端
  • Redis 上下文保留最近会话消息,车辆事件作为额外上下文注入 Agent

当前已实现

  • Java 后端健康检查
  • Java 后端 HTTP 聊天接口
  • Java 后端 WebSocket 聊天入口
  • MySQL 保存会话和聊天消息
  • 查询指定会话的历史消息
  • Redis 缓存车辆状态和最近上下文
  • Kafka 车辆事件消费和 Redis 状态更新
  • WebSocket 主动车辆事件提醒
  • 查询车辆最近事件:GET /api/vehicles/{vehicleId}/events
  • Python Agent 健康检查
  • Python Agent 简单规则意图识别
  • Ollama 本地模型接入,无需 API Key,调用失败时自动降级
  • OpenAI 兼容文本模型流式回复、超时和重试
  • 车辆说明书检索和事件上下文问答
  • 模拟车辆状态查询和控制
  • React 前端聊天界面和历史消息加载
  • 图片上传链路:前端 -> Java multipart 校验/转发 -> Python /agent/vision
  • Ollama qwen2.5vl:3b 视觉模型可执行图片理解;模型未下载或调用失败时返回明确降级原因
  • 浏览器 Web Speech API 语音识别,识别结果复用现有聊天链路
  • 浏览器 SpeechSynthesis 语音播报,支持手动播报和自动播报开关
  • 轻量 WebRTC 音频演示:浏览器内双 PeerConnection、SDP/ICE 协商和麦克风音轨状态
  • 前端展示当前 Agent 工具、知识来源、模型状态和降级状态

第一轮演示

启动后可以依次发送:

我的车还有多少电?
胎压异常时应该怎么处理?
最近有什么车辆提醒?
打开空调

其中说明书问题会走 manual_search,事件问题会走 recent_event_query,车辆控制会走 vehicle_control。如果本地语言模型不可用,Agent 仍会返回规则工具结果。

第二轮配置

视觉接口默认连接 Compose 中的本地 Ollama。首次拉取 qwen2.5vl:3b 后即可执行图片理解,不需要 API Key:

VISION_PROVIDER=ollama
VISION_API_KEY=
VISION_BASE_URL=http://ollama:11434/v1
VISION_MODEL=qwen2.5vl:3b
VISION_MAX_ATTEMPTS=2
VISION_TIMEOUT_SECONDS=120

当前视觉链路按 JPG、PNG、WebP 校验,单张图片最大 8 MB。若 Ollama 未启动或视觉模型尚未拉取,接口会返回明确降级状态,不会伪造识别结果。浏览器语音识别和麦克风演示需要用户授权,并取决于浏览器能力;未支持时界面会显示明确状态。

本地模型首次加载通常比热请求慢。Java 到 Agent 的同步聊天、流式聊天和视觉请求超时可分别通过 AGENT_CHAT_TIMEOUT_SECONDSAGENT_STREAM_TIMEOUT_SECONDSAGENT_VISION_TIMEOUT_SECONDS 调整,Compose 默认值为 90、150、150 秒。

项目目录包含 frontendbackend-javaagent-pythonvehicle-event-simulator 四个模块,可从仓库根目录按本文档启动。

第三轮工程能力

  • Kafka 消费以 eventId 做 Redis 原子幂等,重复事件不会重复改状态、写历史或推送。
  • Kafka 无效消息和消费异常使用固定间隔重试,超过次数投递到 vehicle-events.DLT,并保留消费日志。
  • 车辆事件同时写入 MySQL vehicle_event 表,eventId 唯一;Redis 仍保留 24 小时最近事件缓存。
  • 事件持久化查询:GET /api/vehicles/{vehicleId}/events/history?eventType=LOW_BATTERY&from=...&to=...&limit=20
  • Agent 服务增加 IP 窗口限流、并发上限和文本/视觉模型调用短路熔断;健康检查返回治理阈值和熔断状态。
  • WebSocket 增加应用层心跳 ping/pong;前端断线指数退避重连,最多 5 次,并展示连接状态。
  • Actuator 指标:/actuator/health/actuator/metrics,包含 Agent 调用耗时/结果/降级、Kafka 消费结果和 WebSocket 在线数。

架构与链路

浏览器 React 面板
  ├─ HTTP /api/chat、/api/vision/analyze
  ├─ WebSocket /ws/chat(assistant_start/delta/done、vehicle_event、ping/pong)
  ├─ Web Speech API / SpeechSynthesis
  └─ 本地双 PeerConnection WebRTC 音频演示
          │
          ▼
Java Spring Boot
  ├─ MySQL:会话、消息、车辆事件历史
  ├─ Redis:车辆状态、上下文、近期事件、eventId 幂等键
  ├─ Kafka:车辆事件消费、重试、DLT
  └─ HTTP multipart / SSE client
          │
          ▼
Python FastAPI Agent
  ├─ 规则工具:车辆状态、控制、近期事件、说明书检索
  ├─ Ollama qwen2.5:3b:同步/流式问答,超时/重试/熔断/降级
  └─ Ollama qwen2.5vl:3b:图片理解,模型不可用时明确降级

校招演示脚本

  1. 打开前端,展示车辆状态、事件提醒和 Agent 运行状态面板。
  2. 发送“我的车还有多少电?”,说明 vehicle_state_query 和规则降级链路。
  3. 发送“胎压异常时应该怎么处理?”,展示 manual_search 和知识来源。
  4. 发送“最近有什么车辆提醒?”,展示 Redis 事件上下文和事件去重。
  5. 点击“语音”,说“打开空调”,确认语音转文字后沿用 WebSocket 流式回复。
  6. 上传仪表盘或故障灯图片:展示 qwen2.5vl:3b 的实际识别结果;若模型未拉取则展示视觉调用失败的降级状态。
  7. 打开“回复自动播报”,点击任意回复的“播放”,展示浏览器 TTS。
  8. 点击 WebRTC“启动链路”,授权麦克风后展示 音频链路已建立;说明这是本地信令演示,不是生产级音视频平台。
  9. 查看 /actuator/metrics 和 Kafka 日志,说明限流、熔断、重试、DLT、幂等和指标设计。

后续计划

  1. 支持大模型流式响应
  2. 增加车辆说明书 RAG 问答
  3. 增加更完整的前端演示面板

车载智能助手 Vehicle Agent 智能汽车 车载 Agent 多模态交互 视觉理解 语音交互 Spring Boot FastAPI React Kafka Redis MySQL WebSocket

About

车载智能助手云端 Agent 平台,支持多模态交互、车辆事件处理和本地视觉理解

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages