Files
bigwo/test2/ARCHITECTURE.md

16 KiB
Raw Blame History

BigWo 智能语音对话系统 — 系统架构文档

版本2.0 | 更新日期2026-03-13


1. 系统概述

BigWo 是一个企业级智能客服对话系统,支持语音通话文字对话两种交互模式,可无缝切换且保持上下文连续。

核心能力

能力 说明
实时语音对话 Native WebSocket + S2S 端到端语音大模型,混合编排模式
知识库问答 Function Calling → 方舟私域知识库 → 本地知识库
文字对话 Coze v3 Chat API支持 SSE 流式输出
语音↔文字切换 同一 sessionId 贯穿MySQL 持久化完整历史
工具调用 知识库检索、天气、订单、时间、计算

技术栈

  • 前端React 18 + Vite 5 + TailwindCSS 4 + Lucide Icons
  • 后端Node.js + Express 4 (port 3012)
  • 语音Native WebSocket (wss://openspeech.bytedance.com/api/v3/realtime/dialogue) + S2S 端到端 + 方舟 LLM
  • 文字Coze v3 Chat API流式 SSE
  • 知识库:方舟 Chat Completions API + knowledge_base metadata
  • 数据库MySQL 8 (mysql2/promise)
  • 部署PM2 (cluster) + Nginx 反向代理 + 宝塔面板

2. 系统架构图

┌───────────────────────────────────────────────────────────┐
│                      浏览器客户端                           │
│  ┌────────────┐  ┌───────────┐  ┌────────────────────┐   │
│  │ VoicePanel │  │ ChatPanel │  │SessionHistoryPanel │   │
│  └─────┬──────┘  └─────┬─────┘  └────────────────────┘   │
│        │               │                                  │
│  ┌─────▼──────────┐ ┌──▼───────┐  ┌────────────────┐    │
│  │useNativeVoice  │ │ chatApi  │  │   voiceApi     │    │
│  │  Chat (Hook)   │ │(HTTP/SSE)│  │ (HTTP 封装)    │    │
│  └─────┬──────────┘ └──┬───────┘  └────────────────┘    │
│        │                │                                 │
│  ┌─────▼──────────────┐ │                                 │
│  │nativeVoiceService  │ │                                 │
│  │  (WebSocket+Audio) │ │                                 │
│  └─────┬──────────────┘ │                                 │
└────────┼────────────────┼─────────────────────────────────┘
         │ WebSocket       │ HTTPS
         │ PCM 音频流      │ REST/SSE
         ▼                 ▼
┌──────────────────────────────────────────────────┐
│         Express 后端 (port 3001)                  │
│                                                   │
│  /ws/realtime-dialog — Native 语音网关 (核心)     │
│  routes/voice.js     — 语音配置、直连会话         │
│  routes/chat.js      — 文字对话 (Coze SSE)        │
│  routes/session.js   — 会话列表、历史、删除       │
│                                                   │
│  services/nativeVoiceGateway.js — WebSocket 网关  │
│  services/realtimeDialogProtocol.js — 二进制协议  │
│  services/realtimeDialogRouting.js — 意图路由     │
│  services/toolExecutor.js — 工具执行器            │
│  services/arkChatService.js — 方舟 LLM            │
│  services/cozeChatService.js — Coze Chat          │
│  db/index.js — MySQL CRUD                         │
│                                                   │
└──────┬───────────────┬────────────────────────────┘
       │               │
       │ WebSocket     │
       ▼               ▼
┌───────────────┐  ┌─────────────────┐  ┌──────────────┐
│ 火山 Realtime │  │   MySQL 8       │  │ 方舟知识库   │
│ Dialog 服务   │  │ sessions 表     │  │ (远程 API)   │
│ (S2S + LLM)  │  │ messages 表     │  └──────────────┘
└───────────────┘  └─────────────────┘

3. 目录结构

test2/
├── client/                        # 前端React + Vite
│   ├── src/
│   │   ├── App.jsx                # 主应用,模式切换 + 会话管理
│   │   ├── components/
│   │   │   ├── VoicePanel.jsx     # 语音通话界面
│   │   │   ├── ChatPanel.jsx      # 文字对话界面SSE 流式)
│   │   │   ├── SessionHistoryPanel.jsx # 会话历史侧边栏
│   │   │   ├── SettingsPanel.jsx  # 语音参数设置面板
│   │   │   └── SubtitleDisplay.jsx# 实时字幕展示
│   │   ├── hooks/
│   │   │   └── useNativeVoiceChat.js # Native WebSocket 语音 Hook
│   │   └── services/
│   │       ├── nativeVoiceService.js # WebSocket 语音服务(音频采集/播放)
│   │       ├── voiceApi.js        # 语音/会话 HTTP 请求
│   │       └── chatApi.js         # 文字 HTTP/SSE 请求
│   └── vite.config.js
├── server/                        # 后端Express
│   ├── app.js                     # 入口,启动 HTTP + WebSocket 服务
│   ├── routes/
│   │   ├── voice.js               # 语音配置、直连会话、知识库查询
│   │   ├── chat.js                # 文字对话Coze SSE 流式)
│   │   └── session.js             # 会话列表、历史、删除、模式切换
│   ├── services/
│   │   ├── nativeVoiceGateway.js  # WebSocket 语音网关(核心)
│   │   ├── realtimeDialogProtocol.js # 二进制协议编解码
│   │   ├── realtimeDialogRouting.js  # 意图路由 + 工具调度
│   │   ├── toolExecutor.js        # 工具执行器
│   │   ├── arkChatService.js      # 方舟 LLM
│   │   └── cozeChatService.js     # Coze Chat API文字主服务
│   ├── db/index.js                # MySQL CRUD
│   └── .env                       # 环境变量
└── ecosystem.config.js            # PM2 部署配置

4. 语音通话模块Native WebSocket 方案)

4.1 混合编排模式

S2S 端到端模型处理普通闲聊(低延迟),方舟 LLM 同时决策是否需要调用工具。两者并行运行。

4.2 会话生命周期

客户端 WebSocket 连接  →  /ws/realtime-dialog
      ↓
nativeVoiceGateway 创建会话  →  连接上游 Realtime Dialog 服务
      ↓
客户端采集麦克风 PCM  →  发送音频帧  →  上游 ASR + S2S
      ↓
上游返回字幕/音频  →  realtimeDialogRouting 意图路由
      ↓
工具调用或闲聊回复  →  ChatTTSText 注入语音流  →  客户端播放
      ↓
客户端断开 WebSocket  →  会话结束  →  可切换文字模式

4.3 语音相关端点

端点 类型 说明
/ws/realtime-dialog WebSocket 核心Native 语音网关
/api/voice/config GET 获取模型、音色列表
/api/voice/direct/session POST 创建直连会话
/api/voice/direct/message POST 添加消息
/api/voice/direct/query POST 知识库直接查询
/api/voice/stop POST 停止会话

4.4 核心服务文件

文件 职责
nativeVoiceGateway.js WebSocket 网关,管理客户端↔上游连接、音频流转发、消息持久化
realtimeDialogProtocol.js 二进制协议编解码(消息类型、标志位、序列化/反序列化)
realtimeDialogRouting.js 意图路由(规则+LLM 双层决策)、工具调度、语音播报

5. 语音意图路由与工具调用

5.1 数据流

用户语音 ASR 识别文本
    │ 上游 Realtime Dialog 服务返回
    ▼
nativeVoiceGateway 接收字幕 → 持久化用户语音到 DB
    ▼
realtimeDialogRouting.resolveReply()
    │
    ├─ 规则路由:时间/天气/订单/计算 → 直接工具调用
    ├─ search_knowledge → 方舟知识库 API
    └─ chat → 方舟 LLM 闲聊回复
    │
    ▼
工具结果/LLM回复 → ChatTTSText 注入上游语音流
    ▼
AI 语音播报 + 持久化到 DB

5.2 关键设计

问题 解决方案
意图识别 规则路由 + LLM 路由双层决策
S2S 与工具冲突 ChatTTSText 注入工具结果覆盖 S2S 直连回复
音频编解码 realtimeDialogProtocol 自定义二进制协议
语音文本分段 按标点切分,估算播报时长,分段 TTS

6. 文字对话模块

6.1 架构

通过 Coze v3 Chat API 实现Coze Bot 内置知识库插件。

用户输入 → POST /api/chat/send-stream
    ↓
cozeChatService.chatStream()
    │ 首次对话注入语音历史作为上下文
    │ Coze 自动管理 conversation_id
    ↓
SSE 流式返回 → 前端逐字展示

6.2 文字 API 端点chat.js

端点 方法 说明
/api/chat/start POST 创建会话,注入语音历史上下文
/api/chat/send POST 非流式发送
/api/chat/send-stream POST SSE 流式发送
/api/chat/history/:id GET 获取会话状态
/api/chat/:id DELETE 删除会话

7. 会话管理与模式切换

7.1 统一 sessionId

同一个 sessionId 贯穿语音和文字模式,所有消息持久化到 MySQL messages 表。

7.2 消息来源标记

source 值 说明
voice_asr 语音 ASR 识别的用户文本
voice_bot AI 语音回复字幕
voice_tool 语音场景工具调用结果
chat_user 文字对话用户输入
chat_bot 文字对话 AI 回复

7.3 会话管理 APIsession.js

端点 方法 说明
/api/session/list GET 获取会话列表(带最后消息预览)
/api/session/:id/history GET 获取完整历史(支持 llm/full 格式)
/api/session/:id/switch POST 切换模式,返回上下文历史
/api/session/:id DELETE 删除会话及其消息

7.4 数据库表

sessionsid(PK), user_id, mode(voice/chat), created_at, updated_at

messagesid(AI PK), session_id, role(user/assistant/tool/system), content, source, tool_name, created_at


8. 客户端组件

8.1 组件树

App.jsx                    # 模式切换 + 全局设置 + 会话管理
├── VoicePanel.jsx         # 语音通话 UI开始/结束/静音/时长)
│   └── SubtitleDisplay    # 实时字幕definite/interim 区分)
├── ChatPanel.jsx          # 文字对话 UI消息列表 + SSE 流式显示)
├── SessionHistoryPanel.jsx # 会话历史侧边栏(新建/切换/删除会话)
└── SettingsPanel.jsx      # 设置面板(模型/音色/系统角色/VAD

8.2 useNativeVoiceChat Hook

管理 Native WebSocket 语音通话完整生命周期:

  • start(options):连接 WebSocket → 采集麦克风 PCM → 发送音频帧
  • stop():断开 WebSocket → 返回字幕和 sessionId
  • toggleMute():静音/取消静音
  • 状态isActive, isMuted, isConnecting, subtitles, duration, error

8.3 nativeVoiceService.js

封装 Native WebSocket 语音连接:

  • connect(options):建立 WebSocket 连接初始化音频采集getUserMedia + Web Audio API 降采样)
  • disconnect():关闭连接、停止音频
  • setMuted(muted):控制麦克风
  • 事件回调onSubtitle字幕、onConnectionStateChange连接状态、onError错误
  • 音频播放:接收 PCM 音频帧,通过 Web Audio API 播放

9. 环境变量

必需

变量 说明
VOLC_S2S_APP_ID S2S 端到端语音 AppID
VOLC_S2S_TOKEN S2S Token
VOLC_ARK_ENDPOINT_ID 方舟 LLM 推理接入点 ID

可选

变量 说明
COZE_API_TOKEN Coze 智能体 Token文字对话
COZE_BOT_ID Coze Bot ID
VOLC_ARK_KNOWLEDGE_BASE_IDS 方舟私域知识库数据集 ID逗号分隔
VOLC_ARK_API_KEY 方舟 API Key
VOLC_WEBSEARCH_API_KEY 联网搜索 Key
VOLC_S2S_SPEAKER_ID 自定义音色 ID
ENABLE_NATIVE_VOICE_GATEWAY 语音网关开关(默认开启,设 false 关闭)
MYSQL_HOST/PORT/USER/PASSWORD/DATABASE MySQL 配置

10. 部署架构

互联网用户
    │
    ▼ HTTPS (443) + WSS
┌──────────────┐
│   Nginx      │  ← 宝塔面板管理
│  (反向代理)   │
│  SSL 终止    │
└──────┬───────┘
       │ http://localhost:3001
       ▼
┌──────────────┐
│   PM2        │  ← ecosystem.config.js
│  bigwo-server│
│  (Node.js)   │
└──────┬───────┘
       │
       ├── MySQL 8 (localhost:3306)
       ├── 火山 Realtime Dialog (wss://openspeech.bytedance.com)
       ├── 方舟 LLM API (ark.cn-beijing.volces.com)
       └── Coze API (api.coze.cn)

PM2 配置

  • 进程名:bigwo-server
  • 工作目录:/www/wwwroot/demo.tensorgrove.com.cn/server
  • 日志路径:/var/log/bigwo/server-out.logserver-error.log
  • 内存限制512M 自动重启

11. 工具定义tools.js

系统定义了 5 个 Function Calling 工具:

工具 参数 说明
search_knowledge query: string 核心工具,强制优先调用
query_weather city: string 天气查询Mock
query_order order_id: string 订单查询Mock
get_current_time 当前时间
calculate expression: string 数学计算

search_knowledge 查询链

方舟私域知识库 (30s 超时)
  │ POST https://ark.cn-beijing.volces.com/api/v3/chat/completions
  │ metadata.knowledge_base: { dataset_ids, top_k: 3, threshold: 0.5 }
  │
  │ 失败 ↓
  ▼
本地知识库 (即时,关键词匹配)
  │ 覆盖:退货、退款、配送、保修、会员

12. 安全与限制

  • API 签名:所有火山引擎 API 调用使用 AK/SK HMAC 签名
  • FC 回调签名ServerSignature 校验(当前信任模式)
  • 计算工具防注入:仅允许 0-9 + - * / ( ) . % 字符
  • CORS:已开启(cors() 中间件)
  • Body 限制1MB
  • 会话过期:文字对话 30 分钟自动清理
  • 环境变量:敏感信息存于 .env,启动时校验

13. 已知问题与优化方向

  1. 天气和订单工具为 MockqueryWeather 和 queryOrder 使用硬编码数据,可接入真实 API
  2. 本地知识库简陋searchLocalKnowledge 仅 5 条硬编码记录,需接入真实知识库
  3. 方舟 LLM Mock 模式:未配置 VOLC_ARK_ENDPOINT_ID 时返回硬编码回复
  4. 文字对话依赖 CozeCoze 未配置时文字对话模式不可用,可考虑 fallback 到 arkChatService
  5. 知识库冷启动:方舟 KB 首次查询较慢(~10s后续查询 ~3-5s