docs: 更新 tool-engine 移除后的文档引用
- tool-engine.md: 迁移至 AI-Core (8081),更新为内存环形缓冲区字段 - devtools.md: 移除 tool-engine 服务引用,更新启动顺序和代理路由 - architecture-analysis.md: Section 3.4 重写为 pkg/plugins 工具系统 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
# Tool-Engine API
|
||||
# 工具调用 API (已迁移至 AI-Core)
|
||||
|
||||
**Base URL:** `http://<host>:8092` | **Auth:** 无
|
||||
> **Base URL:** `http://<host>:8081` | **Auth:** 无
|
||||
> **迁移说明:** tool-engine 服务 (8092) 已移除。工具注册与调用功能已整合到 `pkg/plugins` 共享模块,由 AI-Core (8081) 直接管理。API 路径保持不变。
|
||||
> **源码:** [pkg/plugins/manager/registry.go](../../backend/pkg/plugins/manager/registry.go)
|
||||
|
||||
工具引擎注册了 13 个内置工具,支持单次和批量执行,可选数据库持久化的调用日志。
|
||||
工具注册中心管理 15+ 个内置工具,通过内存环形缓冲区 (500 条) 记录调用日志。
|
||||
|
||||
---
|
||||
|
||||
@@ -33,17 +35,14 @@
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `id` | int | 数据库自增 ID |
|
||||
| `call_id` | string | UUID v4 |
|
||||
| `call_id` | string | 调用唯一标识 (纳秒时间戳) |
|
||||
| `tool_name` | string | 工具名 |
|
||||
| `arguments` | json.RawMessage | 调用参数 |
|
||||
| `arguments` | string | 调用参数 (JSON 字符串) |
|
||||
| `output` | string | 输出文本 |
|
||||
| `error` | string | 错误信息 |
|
||||
| `success` | bool | 是否成功 |
|
||||
| `duration_ms` | int | 执行耗时 |
|
||||
| `user_id` | string | 调用用户 |
|
||||
| `session_id` | string | 调用会话 |
|
||||
| `created_at` | string | 时间戳 |
|
||||
| `timestamp` | int64 | Unix 毫秒时间戳 |
|
||||
|
||||
### ToolCallCount
|
||||
|
||||
@@ -60,7 +59,7 @@
|
||||
## 1. GET /api/v1/health
|
||||
|
||||
```json
|
||||
{ "status": "ok", "service": "tool-engine" }
|
||||
{ "status": "ok", "service": "ai-core" }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -147,7 +146,7 @@
|
||||
|
||||
## 6. GET /api/v1/tools/calls — 调用日志
|
||||
|
||||
需要 `DB_URL` 环境变量。未配置数据库时返回空结果。
|
||||
内存环形缓冲区 (500 条),无需数据库。
|
||||
|
||||
### Query 参数
|
||||
|
||||
@@ -155,7 +154,7 @@
|
||||
|------|------|------|
|
||||
| `tool_name` | 全部 | 按工具名过滤 |
|
||||
| `page` | 1 | 页码 |
|
||||
| `limit` | 20 (max 100) | 每页条数 |
|
||||
| `limit` | 50 (max 500) | 每页条数 |
|
||||
|
||||
### 响应 200
|
||||
|
||||
@@ -186,7 +185,7 @@
|
||||
}
|
||||
```
|
||||
|
||||
未配置数据库时全返回 0。
|
||||
内存缓冲区,重启后数据清零。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ DevTools 是 Cyrene 项目的开发管理控制台,提供 Web UI + CLI 两种
|
||||
|
||||
### 可用服务 ID
|
||||
|
||||
`gateway`, `ai-core`, `memory-service`, `tool-engine`, `voice-service`, `iot-debug-service`, `plugin-manager`, `platform-bridge`, `frontend`
|
||||
`gateway`, `ai-core`, `memory-service`, `voice-service`, `iot-debug-service`, `plugin-manager`, `platform-bridge`, `frontend`
|
||||
|
||||
### 示例
|
||||
|
||||
@@ -77,12 +77,12 @@ DevTools 是 Cyrene 项目的开发管理控制台,提供 Web UI + CLI 两种
|
||||
|
||||
| 操作 | 说明 |
|
||||
|------|------|
|
||||
| 一键启动 | 按依赖顺序启动全部 9 个服务 |
|
||||
| 一键启动 | 按依赖顺序启动全部 8 个服务 |
|
||||
| 强制重启 | 先停止全部再重新启动 |
|
||||
| 单个启动/停止/重启 | 针对每个服务的独立操作 |
|
||||
| 编译 | 重新编译 Go 服务并启动 |
|
||||
|
||||
启动顺序:memory-service → tool-engine → plugin-manager → iot-debug-service → voice-service → ai-core → platform-bridge → gateway → frontend。每步等待健康检查通过。
|
||||
启动顺序:memory-service → plugin-manager → iot-debug-service → voice-service → ai-core → platform-bridge → gateway → frontend。每步等待健康检查通过。
|
||||
|
||||
### 2.5 性能监控 (Performance)
|
||||
|
||||
@@ -99,7 +99,7 @@ DevTools 是 Cyrene 项目的开发管理控制台,提供 Web UI + CLI 两种
|
||||
|
||||
### 2.7 工具调用 (Tool Calls)
|
||||
|
||||
代理到 `tool-engine`,查询工具调用记录和统计数据,按工具名筛选。
|
||||
代理到 `ai-core`,查询工具调用记录和统计数据,按工具名筛选、分页。
|
||||
|
||||
### 2.8 语音识别 (STT)
|
||||
|
||||
@@ -198,7 +198,7 @@ GET /api/dashboard
|
||||
| `/api/clients*` | Gateway | `/api/v1/admin/clients*` |
|
||||
| `/api/model-config/*` | Gateway | `/api/v1/admin/models/*` |
|
||||
| `/api/iot/devices*` | IoT Debug | `/api/v1/devices*` |
|
||||
| `/api/tool-calls*` | Tool-Engine | `/api/v1/tools/calls*` |
|
||||
| `/api/tool-calls*` | AI-Core | `/api/v1/tools/calls*` |
|
||||
| `/api/voice/status` | Voice-Service | `/api/v1/status` |
|
||||
| `/api/voice/transcribe` | Voice-Service | `/api/v1/transcribe` |
|
||||
| `/api/voice/logs` | DevTools 内部 | 内存环形缓冲区 |
|
||||
@@ -235,7 +235,6 @@ ws://localhost:9090/ws
|
||||
| `ai-core` | AI-Core | 8081 | Go |
|
||||
| `iot-debug-service` | IoT Debug | 8083 | Go |
|
||||
| `memory-service` | 记忆服务 | 8091 | Go |
|
||||
| `tool-engine` | 工具引擎 | 8092 | Go |
|
||||
| `voice-service` | 语音识别服务 | 8093 | Go |
|
||||
| `plugin-manager` | 插件管理器 | 8094 | Go |
|
||||
| `platform-bridge` | 多平台桥接 | 8095 | Go |
|
||||
|
||||
@@ -0,0 +1,856 @@
|
||||
# Cyrene AI 项目架构与功能分析文档
|
||||
|
||||
> **日期**:2026-05-23
|
||||
> **分支**:`dev`
|
||||
> **项目根目录**:`d:\Project\Code\Uni\Cyrene`
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [项目概览](#一项目概览)
|
||||
2. [总体架构](#二总体架构)
|
||||
3. [后端服务详解](#三后端服务详解)
|
||||
- [AI-Core (8081) — 对话引擎](#31-ai-core-8081--对话引擎)
|
||||
- [Gateway (8080) — API 网关](#32-gateway-8080--api-网关)
|
||||
- [Memory-Service (8091) — 记忆系统](#33-memory-service-8091--记忆系统)
|
||||
- [工具系统 (pkg/plugins + AI-Core)](#34-工具系统-pkgplugins--ai-core-集成)
|
||||
- [IoT-Debug-Service (8083) — 模拟设备](#35-iot-debug-service-8083--模拟设备)
|
||||
- [Voice-Service (8093) — 语音服务](#36-voice-service-8093--语音服务)
|
||||
- [Proto (占位)](#37-proto-占位)
|
||||
4. [前端详解](#四前端详解)
|
||||
- [技术栈](#41-技术栈)
|
||||
- [状态管理](#42-状态管理)
|
||||
- [组件树](#43-组件树)
|
||||
- [自定义 Hooks](#44-自定义-hooks)
|
||||
- [API 模块](#45-api-模块)
|
||||
- [WebSocket 消息流](#46-websocket-消息流)
|
||||
5. [DevTools (9090) — 调试工具](#五devtools-9090--调试工具)
|
||||
6. [对话管线详解](#六对话管线详解)
|
||||
7. [数据库设计](#七数据库设计)
|
||||
8. [安全性](#八安全性)
|
||||
9. [已知限制与改进方向](#九已知限制与改进方向)
|
||||
|
||||
---
|
||||
|
||||
## 一、项目概览
|
||||
|
||||
Cyrene(昔涟)是一个 AI 数字伴侣系统,以 React SPA 为前端,Go 微服务集群为后端,通过 PostgreSQL 持久化数据和 pgvector 向量搜索实现长期记忆。系统以虚拟角色"昔涟"的固定人格与用户对话,支持 IoT 智能家居操控、定时提醒、知识库管理、自动化规则引擎、语音识别/合成、图片分析、互联网搜索 (SearXNG) 等功能。
|
||||
|
||||
| 维度 | 数据 |
|
||||
|------|------|
|
||||
| 后端语言 | Go 1.24 |
|
||||
| 前端框架 | React 18.3 + TypeScript 5.6 + Vite 6.0 |
|
||||
| 数据库 | PostgreSQL (pgvector 向量扩展) |
|
||||
| LLM 模型 | 多模型配置系统 (models.json),支持多 Provider/多用途路由回退链 |
|
||||
| WebSocket 库 | gorilla/websocket (Go), 原生 WebSocket (浏览器) |
|
||||
| HTTP 框架 | Gin (Gateway), net/http (其他服务) |
|
||||
| 状态管理 | Zustand 4.5 |
|
||||
| CSS 框架 | Tailwind CSS 3.4 |
|
||||
| 包管理器 | pnpm |
|
||||
| Go 代理 | GOPROXY=https://goproxy.cn,direct |
|
||||
|
||||
---
|
||||
|
||||
## 二、总体架构
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Browser (React SPA) │
|
||||
│ localhost:5173 (dev) / 生产由 Gateway 托管静态文件 │
|
||||
└───────────┬──────────────────────────────────┬───────────────┘
|
||||
│ WebSocket (ws://gateway:8080/ws/chat)
|
||||
│ + REST API (gateway:8080/api/v1/*)
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Gateway (:8080) │
|
||||
│ Gin Router → JWT Auth → Rate Limiter → Handlers │
|
||||
│ WebSocket Hub: 会话状态/消息缓存/IoT广播 │
|
||||
│ 规则引擎: 定时/事件触发自动化 │
|
||||
└───┬──────────┬──────────┬──────────┬──────────┬─────────────┘
|
||||
│ SSE │ HTTP │ HTTP │ HTTP │ HTTP
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────────┐
|
||||
│AI-Core │ │Memory │ │Tool │ │Voice │ │IoT Debug │
|
||||
│ :8081 │ │:8091 │ │:8092 │ │:8093 │ │ :8083 │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│编排器 │ │PGVector│ │13工具 │ │whisper │ │8个模拟设备 │
|
||||
│意图分析 │ │语义搜索│ │调用日志│ │edge-tts│ │toggle/set/ │
|
||||
│子会话 │ │去重衰减│ │IoT客户端│ │TTS回退│ │history API │
|
||||
│人格系统 │ │ │ │ │ │ │ │传感器波动 │
|
||||
│思考引擎 │ │ │ │ │ │ │ │ │
|
||||
└────┬───┘ └────┬───┘ └────┬───┘ └────┬───┘ └──────────────┘
|
||||
│ │ │ │
|
||||
└──────────┴──────────┴──────────┘
|
||||
│
|
||||
┌───────▼───────┐
|
||||
│ PostgreSQL │
|
||||
│ + pgvector │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
**核心数据流**:用户消息 → Gateway WebSocket → AI-Core SSE → 编排器并行处理(意图分析 → 子会话分派 → LLM 合成 → 审查拆分) → Gateway 解析 → WebSocket 逐条返回前端。
|
||||
|
||||
---
|
||||
|
||||
## 三、后端服务详解
|
||||
|
||||
### 3.1 AI-Core (:8081) — 对话引擎
|
||||
|
||||
**目录**:`backend/ai-core/`
|
||||
**入口**:[cmd/main.go](backend/ai-core/cmd/main.go)
|
||||
**包数量**:11 个内部包,约 40 个 `.go` 文件
|
||||
|
||||
#### 3.1.1 启动流程
|
||||
|
||||
1. 加载 `backend/.env` 环境变量
|
||||
2. 初始化人格加载器(`persona.NewLoader`)——从 `internal/persona/` 目录读取 YAML 配置
|
||||
3. 初始化 LLM 适配器:优先加载 `models.json` → `ModelSelector`;无配置文件时回退到 `.env`
|
||||
4. 初始化记忆系统(`memory.NewStore` + `NewRetriever` + `NewExtractor`)——PostgreSQL 持久化
|
||||
5. 初始化会话历史存储(`context.NewConversationStore`)——内存缓存,上限 50 条
|
||||
6. 初始化 IoT 客户端(`tools.NewIoTClient`)——连接 IoT Debug Service
|
||||
7. 注册 13 个 LLM 可调用工具(`tools.NewRegistry`)
|
||||
8. 启动后台思考引擎(`background.NewThinker`)
|
||||
9. 构建编排器 v2.0(`orchestrator.NewOrchestrator`)
|
||||
10. 注册 HTTP 端点:`/api/v1/chat`(SSE)、`/api/v1/memory/search`、`/api/v1/memory`(CRUD)、`/api/v1/health`
|
||||
|
||||
#### 3.1.2 包结构
|
||||
|
||||
| 包 | 文件 | 职责 |
|
||||
|----|------|------|
|
||||
| `orchestrator/` | `orchestrator.go`, `intent_analyzer.go`, `synthesizer.go` | 对话编排 v2.0:意图分析→子会话分派→综合生成 |
|
||||
| `subsession/` | `manager.go`, `registry.go`, `general_provider.go`, `memory_provider.go`, `iot_provider.go`, `review_provider.go` | 子会话框架:4 个提供者并行执行 |
|
||||
| `llm/` | `adapter.go`, `openai.go`, `stream.go`, `selector.go` | LLM 抽象层:OpenAI 兼容协议、流式输出、断句器、多模型路由选择器 |
|
||||
| `config/` | `loader.go` | 模型配置加载器:只读加载 models.json |
|
||||
| `memory/` | `store.go`, `retriever.go`, `extractor.go`, `client.go` | 记忆系统:存储/检索/提取/HTTP 客户端 |
|
||||
| `persona/` | `loader.go`, `injector.go` | 人格管理:YAML 加载、系统提示构建、风格注入 |
|
||||
| `tools/` | `registry.go`, `calculator_tool.go`, `datetime_tool.go`, `crypto_tool.go`, `file_tool.go`, `http_tool.go`, `iot_client.go`, `iot_control_tool.go`, `iot_tools.go`, `json_tool.go`, `markdown_tool.go`, `random_tool.go`, `text_tool.go`, `web_fetch.go`, `web_search.go` | 工具系统:13 个 LLM 可调用工具 + IoT 客户端 |
|
||||
| `context/` | `builder.go` | 上下文构建器:会话历史/人格/子会话结果组合为 LLM 提示 |
|
||||
| `background/` | `thinker.go` | 后台思考引擎:事件驱动(chat 后/沉默)自主思考 |
|
||||
| `model/` | `message.go`, `session.go`, `sub_session.go`, `memory.go` | 共享数据模型:消息、会话、子会话、记忆 |
|
||||
|
||||
#### 3.1.3 Orchestrator v2.0 管线
|
||||
|
||||
```
|
||||
用户输入 → ProcessInput()
|
||||
├─ 1. 意图分析 (intentAnalyzer.Analyze)
|
||||
│ ├─ isStrongIoTCommand() 快速通道 (0s)
|
||||
│ ├─ isGreeting() 快速通道 (0s)
|
||||
│ └─ LLM 意图分析 (fallback)
|
||||
├─ 2. 加载人格配置 → BuildSystemPrompt
|
||||
├─ 3. 子会话分派 (subManager.Dispatch)
|
||||
│ ├─ general_provider (通用对话意图)
|
||||
│ ├─ memory_provider (记忆检索)
|
||||
│ ├─ iot_provider (IoT 设备查询/操控)
|
||||
│ └─ review_provider (审查拆分)
|
||||
│ 快速通道: greeting/纯聊天 → 跳过所有子会话
|
||||
├─ 4. 200ms 超时等待子会话结果
|
||||
├─ 5. Synthesizer 流式生成 (ChatWithTools + 最多5轮工具调用循环)
|
||||
├─ 6. 流式输出 delta → SSE
|
||||
├─ 7. parseReviewMessages() 审查拆分 → StreamReview SSE
|
||||
├─ 8. 断句信息 → StreamSegments SSE
|
||||
├─ 9. StreamDone → [DONE]
|
||||
└─ 10. 后处理: 缓存回复 + 异步记忆提取
|
||||
```
|
||||
|
||||
**快速通道条件**:
|
||||
- IoT 命令:`controlWords ∩ msg AND deviceWords ∩ msg` → 跳过 LLM 意图分析(节省 2-3s)
|
||||
- 纯问候/聊天无 IoT 无 Memory:跳过所有子会话分派
|
||||
|
||||
**`parseReviewMessages()`** — 括号匹配状态机:
|
||||
- 输入:`"(歪着头看你) 叶酱,客厅灯早就开着啦♪..."`
|
||||
- 输出:`[{type: "action", content: "歪着头看你"}, {type: "chat", content: "叶酱,客厅灯早就开着啦♪..."}]`
|
||||
- 支持 `()` 和 `()` 两种括号
|
||||
- `splitReviewLongMessage()`:80 字符智能断句(句号/感叹号/问号/逗号边界)
|
||||
|
||||
#### 3.1.4 Intent Analyzer
|
||||
|
||||
**文件**:[intent_analyzer.go](backend/ai-core/internal/orchestrator/intent_analyzer.go)
|
||||
|
||||
**快速通道关键词**:
|
||||
```go
|
||||
controlWords = ["打开", "关闭", "关掉", "关上", "调到", "设置", "开关", "调节", "调高", "调低", "开一下", "关一下"]
|
||||
deviceWords = ["灯", "空调", "窗帘", "电视", "风扇", "加湿器", "插座", "门锁", "传感器"]
|
||||
```
|
||||
|
||||
**意图类型**:`iot_control`, `iot_query`, `greeting`, `chat`, `story`, `memory_trigger`, `knowledge`, `task`
|
||||
|
||||
#### 3.1.5 IoT Provider (子会话)
|
||||
|
||||
**文件**:[iot_provider.go](backend/ai-core/internal/subsession/iot_provider.go)
|
||||
|
||||
- `Execute()`:收集所有 device-action 对 → 批量执行
|
||||
- 上下文窗口:±30 字节 + 全文回退逻辑
|
||||
- 操作检测:`hasOpen`/`hasClose` 布尔值判断
|
||||
- 通过 `personaDir` 字段加载 IoT 回复人格配置
|
||||
|
||||
#### 3.1.6 后台思考引擎
|
||||
|
||||
- 事件驱动:`TriggerPostChatThink()` 在每次对话后触发
|
||||
- 沉默触发:用户长时间不活动
|
||||
- 思考内容可持久化到 memory-service
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Gateway (:8080) — API 网关
|
||||
|
||||
**目录**:`backend/gateway/`
|
||||
**入口**:[cmd/main.go](backend/gateway/cmd/main.go)
|
||||
**包数量**:8 个内部包,约 30 个 `.go` 文件
|
||||
|
||||
#### 3.2.1 启动流程
|
||||
|
||||
1. 加载配置 (`config.Load`)
|
||||
2. 确保上传目录 `./uploads/` 存在
|
||||
3. 初始化 7 个持久化 Store(降级:连接失败不影响启动)
|
||||
4. 种子数据:自动创建 admin 用户 + 清理旧 admin 用户
|
||||
5. 初始化 WebSocket Hub + 闲置会话清理 + IoT 广播
|
||||
6. 初始化规则引擎
|
||||
7. 配置 Gin 路由 → 启动 HTTP 服务
|
||||
8. 启动提醒/简报调度器
|
||||
|
||||
#### 3.2.2 路由表
|
||||
|
||||
**公开路由**:
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/v1/health` | 健康检查 |
|
||||
| POST | `/api/v1/auth/register` | 注册(限流) |
|
||||
| POST | `/api/v1/auth/login` | 登录(限流) |
|
||||
|
||||
**需认证路由** (JWT + Rate Limit):
|
||||
| 方法 | 路径 | Handler |
|
||||
|------|------|---------|
|
||||
| POST | `/api/v1/auth/refresh` | authHandler |
|
||||
| POST | `/api/v1/sessions` | sessionHandler.Create |
|
||||
| GET | `/api/v1/sessions` | sessionHandler.List |
|
||||
| DELETE | `/api/v1/sessions` | sessionHandler.DeleteAll |
|
||||
| GET | `/api/v1/sessions/:id` | sessionHandler.Get |
|
||||
| DELETE | `/api/v1/sessions/:id` | sessionHandler.Delete |
|
||||
| GET | `/api/v1/sessions/:id/messages` | sessionHandler.GetMessages |
|
||||
| DELETE | `/api/v1/sessions/:id/messages` | sessionHandler.ClearMessages |
|
||||
| GET | `/api/v1/sessions/:id/export` | sessionHandler.ExportSession |
|
||||
| GET | `/api/v1/messages/search` | sessionHandler.SearchMessages |
|
||||
| GET | `/api/v1/memory/search` | memoryHandler.Query |
|
||||
| GET | `/api/v1/memory` | memoryHandler.List |
|
||||
| POST | `/api/v1/memory` | memoryHandler.Add |
|
||||
| DELETE | `/api/v1/memory` | memoryHandler.Delete |
|
||||
| POST | `/api/v1/notifications/push` | notificationHandler.Push |
|
||||
| GET/POST/PUT/DELETE | `/api/v1/reminders*` | reminderHandler |
|
||||
| GET/POST | `/api/v1/briefings*` | briefingHandler |
|
||||
| POST/GET | `/api/v1/voice/*` | voiceHandler |
|
||||
| POST/GET/DELETE | `/api/v1/files/*` | fileHandler |
|
||||
| GET/POST/PUT/DELETE | `/api/v1/automation/rules*` | automationHandler |
|
||||
| GET/POST/PUT/DELETE | `/api/v1/automation/scenes*` | automationHandler |
|
||||
| POST/GET/PUT/DELETE | `/api/v1/knowledge/*` | knowledgeHandler |
|
||||
| POST/GET | `/api/v1/images/*` | imageHandler |
|
||||
|
||||
**WebSocket**:
|
||||
| 路径 | 说明 |
|
||||
|------|------|
|
||||
| `GET /ws/chat?token=xxx&session_id=xxx` | WebSocket 升级(仅限 admin 用户) |
|
||||
|
||||
**内部服务** (Internal Service Token):
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| POST | `/api/v1/internal/notify` | 内部通知推送 |
|
||||
|
||||
**Webhook** (Webhook Auth):
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| POST | `/api/v1/webhook/generic` | 通用 Webhook |
|
||||
| POST | `/api/v1/webhook/discord` | Discord Webhook |
|
||||
|
||||
#### 3.2.3 WebSocket Hub
|
||||
|
||||
**文件**:[hub.go](backend/gateway/internal/ws/hub.go)
|
||||
|
||||
核心数据结构:
|
||||
- `clients map[*Client]bool` — 所有活跃连接
|
||||
- `userClients map[string]map[*Client]bool` — 按用户索引
|
||||
- `sessions map[string]*SessionState` — 会话状态追踪
|
||||
- `conversationCache sync.Map` — 对话缓存(最多 50 条/session)
|
||||
|
||||
功能:
|
||||
- 客户端注册/注销(优雅清理,两阶段广播)
|
||||
- 按用户/会话精准推送
|
||||
- 闲置会话自动标记(超过 idleTimeout 无活动 → state="idle")
|
||||
- IoT 设备状态广播:每 10 秒轮询 IoT Debug Service 并推送给所有客户端
|
||||
- 对话缓存:`CacheMessage()` / `GetConversation()` / `GetSessionHistory()`
|
||||
|
||||
#### 3.2.4 消息持久化
|
||||
|
||||
**WebSocket handler** ([chat_handler.go](backend/gateway/internal/handler/chat_handler.go)) 的 `streamResponse()`:
|
||||
|
||||
1. 用户消息**立即**持久化到 DB(在 WebSocket 发送前)
|
||||
2. AI 回复**流式**接收 SSE,逐 delta 转发 WebSocket
|
||||
3. `review_messages` 解析后每条独立持久化(role="action"/"assistant")
|
||||
4. 最终完整文本也持久化一次
|
||||
|
||||
#### 3.2.5 Store 层
|
||||
|
||||
| Store | 文件 | 功能 |
|
||||
|-------|------|------|
|
||||
| `SessionStore` | `session_store.go` | 会话 CRUD、消息持久化、搜索 |
|
||||
| `UserStore` | `user_store.go` | 用户注册/查询/列表/删除 |
|
||||
| `ReminderStore` | `reminder_store.go` | 提醒 CRUD |
|
||||
| `BriefingStore` | `briefing_store.go` | 每日简报 CRUD |
|
||||
| `AutomationStore` | `automation_store.go` | 自动化规则/场景 CRUD |
|
||||
| `FileStore` | `file_store.go` | 文件上传/管理 |
|
||||
| `KnowledgeStore` | `knowledge_store.go` | 知识库/文档管理 |
|
||||
|
||||
#### 3.2.6 规则引擎
|
||||
|
||||
**文件**:[rule_engine.go](backend/gateway/internal/engine/rule_engine.go)
|
||||
|
||||
- 事件驱动自动化:定时触发 / Webhook 触发
|
||||
- 场景执行:一组规则的批量触发
|
||||
- 通过 WebSocket 向用户推送通知
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Memory-Service (:8091) — 记忆系统
|
||||
|
||||
**目录**:`backend/memory-service/`
|
||||
**入口**:[cmd/main.go](backend/memory-service/cmd/main.go)
|
||||
**文件数**:6 个 Go 文件
|
||||
|
||||
#### 3.3.1 包结构
|
||||
|
||||
| 包 | 文件 | 职责 |
|
||||
|----|------|------|
|
||||
| `cmd/` | `main.go` | HTTP 服务入口 |
|
||||
| `internal/config/` | `config.go` | 配置加载 |
|
||||
| `internal/model/` | `memory.go` | 记忆数据模型 |
|
||||
| `internal/store/` | `store.go` | PostgreSQL + pgvector 存储层 |
|
||||
| `internal/service/` | `memory_service.go` | 业务逻辑层 |
|
||||
| `internal/handler/` | `memory_handler.go` | HTTP 处理器 |
|
||||
|
||||
#### 3.3.2 记忆数据模型
|
||||
|
||||
```
|
||||
MemoryEntry {
|
||||
ID, UserID, Content, Category, Priority,
|
||||
Embedding (pgvector 1536维),
|
||||
CreatedAt, UpdatedAt, DecayFactor, AccessCount, LastAccessedAt
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3.3 核心功能
|
||||
|
||||
- **语义搜索**:pgvector 余弦相似度检索 top-N 相关记忆
|
||||
- **去重**:Jaccard 相似度检测,合并高相似度记忆
|
||||
- **衰减机制**:`DecayFactor` 随时间衰减,低权重记忆被清理
|
||||
- **记忆巩固**:高访问频率记忆自动提升优先级
|
||||
- **CRUD API**:创建/查询/列表/删除
|
||||
|
||||
#### 3.3.4 HTTP API
|
||||
|
||||
| 端点 | 方法 | 说明 |
|
||||
|------|------|------|
|
||||
| `/api/v1/memories` | POST | 创建记忆 |
|
||||
| `/api/v1/memories?user_id=xxx` | GET | 列表 |
|
||||
| `/api/v1/memories/:id` | GET | 获取 |
|
||||
| `/api/v1/memories/:id` | DELETE | 删除 |
|
||||
| `/api/v1/memories/search?user_id=xxx&q=xxx&limit=10` | GET | 语义搜索 |
|
||||
| `/api/v1/thinking/logs` | POST | 记录思考日志 |
|
||||
| `/api/v1/health` | GET | 健康检查 |
|
||||
|
||||
---
|
||||
|
||||
### 3.4 工具系统 (pkg/plugins + AI-Core 集成)
|
||||
|
||||
> **迁移说明:** tool-engine (8092) 已移除。工具注册与调用整合到 `pkg/plugins` 共享模块,由 AI-Core 直接管理。
|
||||
|
||||
**目录**:`backend/pkg/plugins/`
|
||||
**核心**:[pkg/plugins/manager/registry.go](backend/pkg/plugins/manager/registry.go)
|
||||
**插件数**:11 个共享插件 + 5 个 AI-Core 专属工具
|
||||
|
||||
#### 3.4.1 16 个 LLM 可调用工具
|
||||
|
||||
**共享插件** (`pkg/plugins/`):
|
||||
|
||||
| 工具 | 目录 | 功能 |
|
||||
|------|------|------|
|
||||
| calculator | `calculator/` | 数学表达式求值 |
|
||||
| datetime | `datetime/` | 日期时间计算/格式化 |
|
||||
| text | `text/` | 文本处理(统计/转换/截断) |
|
||||
| crypto | `crypto/` | 哈希/加解密 |
|
||||
| random | `random/` | 随机数/字符串生成 |
|
||||
| markdown | `markdown/` | Markdown 渲染 |
|
||||
| json | `json/` | JSON 解析/查询/格式化 |
|
||||
| file | `file/` | 文件读写/列表 |
|
||||
| http | `http/` | HTTP 请求(GET/POST 等) |
|
||||
| web_search | `web_search/` | SearXNG 网络搜索 (DuckDuckGo 兜底) |
|
||||
| web_fetch | `web_fetch/` | 网页内容提取 |
|
||||
|
||||
**AI-Core 专属工具** (`ai-core/internal/tools/`):
|
||||
|
||||
| 工具 | 功能 |
|
||||
|------|------|
|
||||
| iot_query | IoT 设备状态查询 |
|
||||
| iot_control | IoT 设备操控 |
|
||||
| host_exec | 主机命令执行 (沙箱) |
|
||||
| host_file | 主机文件操作 (沙箱) |
|
||||
| host_system | 主机系统信息 |
|
||||
| vision_analyze | 图片视觉分析/OCR |
|
||||
| knowledge_search | 知识库 RAG 检索 |
|
||||
| knowledge_ingest | 知识库文档导入 |
|
||||
|
||||
#### 3.4.2 ToolRegistry 调用审计
|
||||
|
||||
[registry.go](backend/pkg/plugins/manager/registry.go) — 内存环形缓冲区 (500 条) 记录工具调用的参数/结果/耗时/成功率。API 端点:
|
||||
- `GET /api/v1/tools/calls` — 分页查询,支持按工具名过滤
|
||||
- `GET /api/v1/tools/calls/stats` — 按工具聚合的成功率/平均耗时
|
||||
|
||||
#### 3.4.3 主聊天流程工具调用
|
||||
|
||||
`Synthesizer` 通过 `ChatWithTools` 向 LLM 传递工具定义,支持最多 5 轮工具调用循环。后台思考器使用相同机制。
|
||||
|
||||
---
|
||||
|
||||
### 3.5 IoT-Debug-Service (:8083) — 模拟设备
|
||||
|
||||
**目录**:`backend/iot-debug-service/`
|
||||
**单文件服务**:[cmd/main.go](backend/iot-debug-service/cmd/main.go)(626 行)
|
||||
|
||||
#### 3.5.1 模拟设备列表
|
||||
|
||||
| ID | 名称 | 类型 | 可操作性 |
|
||||
|----|------|------|---------|
|
||||
| `light-livingroom` | 客厅灯 | light | toggle, brightness, color |
|
||||
| `light-bedroom` | 卧室灯 | light | toggle, brightness, color |
|
||||
| `ac-livingroom` | 客厅空调 | ac | toggle, temperature, mode |
|
||||
| `ac-bedroom` | 卧室空调 | ac | toggle, temperature, mode |
|
||||
| `curtain-livingroom` | 客厅窗帘 | curtain | toggle, position |
|
||||
| `sensor-temperature` | 温度传感器 | sensor | 只读 |
|
||||
| `sensor-humidity` | 湿度传感器 | sensor | 只读 |
|
||||
| `lock-door` | 智能门锁 | lock | toggle, battery |
|
||||
|
||||
#### 3.5.2 API
|
||||
|
||||
| 端点 | 方法 | 说明 |
|
||||
|------|------|------|
|
||||
| `/api/v1/devices` | GET | 列出所有设备(不含历史) |
|
||||
| `/api/v1/devices/{id}` | GET | 获取单个设备(含最近 10 条历史) |
|
||||
| `/api/v1/devices/{id}/toggle` | POST | 切换开关状态 |
|
||||
| `/api/v1/devices/{id}/set` | POST | 设置属性 `{field, value}` |
|
||||
| `/api/v1/devices/{id}/history` | GET | 获取操作历史 |
|
||||
|
||||
#### 3.5.3 特性
|
||||
|
||||
- **线程安全**:`sync.RWMutex` 保护所有设备操作
|
||||
- **传感器波动**:每 30 秒自动模拟温度 ±0.2°C / 湿度 ±1% 随机波动
|
||||
- **属性设置**:声明式控制,支持中文值("开"/"关")和布尔值
|
||||
- **操作历史**:记录每次变更的字段、旧值、新值、时间戳
|
||||
|
||||
---
|
||||
|
||||
### 3.6 Voice-Service (:8093) — 语音服务
|
||||
|
||||
**目录**:`backend/voice-service/`
|
||||
**入口**:[cmd/main.go](backend/voice-service/cmd/main.go)
|
||||
**文件数**:6 个 Go 文件
|
||||
|
||||
#### 3.6.1 STT (语音识别)
|
||||
|
||||
- **引擎**:whisper.cpp(本地运行)
|
||||
- **前处理**:ffmpeg 音频格式转换
|
||||
- **支持语言**:中文(`zh`)
|
||||
|
||||
#### 3.6.2 TTS (语音合成)
|
||||
|
||||
三级回退策略:
|
||||
1. **edge-tts**(首选)— Microsoft Edge TTS API,音质最好
|
||||
2. **espeak-ng**(回退)— 离线 TTS,无需网络
|
||||
3. **静默 WAV 生成器**(最终回退)— 生成等长静音音频,保证用户体验不中断
|
||||
|
||||
---
|
||||
|
||||
### 3.7 Proto (占位)
|
||||
|
||||
`backend/proto/` — 目前仅包含 `.gitkeep`,为未来的 Protobuf/gRPC 通信预留。
|
||||
|
||||
---
|
||||
|
||||
## 四、前端详解
|
||||
|
||||
**目录**:`frontend/web/`
|
||||
**入口**:[main.tsx](frontend/web/src/main.tsx) → [App.tsx](frontend/web/src/App.tsx)
|
||||
|
||||
### 4.1 技术栈
|
||||
|
||||
| 技术 | 版本 | 用途 |
|
||||
|------|------|------|
|
||||
| React | 18.3 | UI 框架 |
|
||||
| TypeScript | 5.6 | 类型系统 |
|
||||
| Vite | 6.0 | 构建工具 |
|
||||
| Zustand | 4.5 | 状态管理 |
|
||||
| Tailwind CSS | 3.4 | 样式 |
|
||||
| 原生 WebSocket | — | 实时通信 |
|
||||
| SpeechSynthesis API | — | TTS 朗读 |
|
||||
| SpeechRecognition API | — | STT 语音输入 |
|
||||
|
||||
### 4.2 状态管理 (Zustand)
|
||||
|
||||
| Store | 文件 | 职责 |
|
||||
|-------|------|------|
|
||||
| `authStore` | `authStore.ts` | 用户认证状态、token 管理 |
|
||||
| `chatStore` | `chatStore.ts` | 消息列表、流式状态、IoT 设备状态、后台思考状态、历史分页 |
|
||||
| `sessionStore` | `sessionStore.ts` | 会话列表、当前会话、消息加载、导出 |
|
||||
| `notificationStore` | `notificationStore.ts` | 站内通知列表、已读管理 |
|
||||
| `personaStore` | `personaStore.ts` | 昔涟人格配置、心情状态 |
|
||||
|
||||
### 4.3 组件树
|
||||
|
||||
```
|
||||
App
|
||||
├── ErrorBoundary
|
||||
└── AppLayout
|
||||
├── Header (Logo, 连接状态, 搜索按钮)
|
||||
├── Sidebar (会话列表, 新建对话)
|
||||
├── ChatContainer
|
||||
│ ├── MessageList
|
||||
│ │ ├── MessageBubble (用户/助手消息)
|
||||
│ │ │ ├── CyreneAvatar (昔涟头像)
|
||||
│ │ │ ├── ImageLightbox (图片灯箱)
|
||||
│ │ │ ├── AIMessageActions (朗读按钮)
|
||||
│ │ │ └── ActionMessageBubble (动作消息: 居中/斜体/灰色)
|
||||
│ │ └── TypingIndicator (输入中动画)
|
||||
│ ├── IoTStatusBar (设备状态条)
|
||||
│ └── ChatInput (输入框/附件/发送)
|
||||
├── AutomationPanel (自动化规则管理)
|
||||
├── BriefingPanel (每日简报)
|
||||
├── FilePanel (文件管理)
|
||||
├── KnowledgePanel (知识库管理)
|
||||
├── ReminderPanel (提醒管理)
|
||||
└── SearchModal (全局搜索)
|
||||
```
|
||||
|
||||
### 4.4 自定义 Hooks
|
||||
|
||||
| Hook | 文件 | 功能 |
|
||||
|------|------|------|
|
||||
| `useWebSocket` | `useWebSocket.ts` | WebSocket 连接生命周期、指数退避自动重连、消息路由 |
|
||||
| `useChat` | `useChat.ts` | 消息发送逻辑 |
|
||||
| `useAuth` | `useAuth.ts` | 认证状态管理 |
|
||||
| `useSession` | `useSession.ts` | 会话切换、历史加载 |
|
||||
| `useSpeechRecognition` | `useSpeechRecognition.ts` | 浏览器语音识别封装 |
|
||||
| `useSpeechSynthesis` | `useSpeechSynthesis.ts` | 浏览器 TTS 封装 |
|
||||
| `usePWA` | `usePWA.ts` | PWA 安装/更新 |
|
||||
|
||||
#### 4.4.1 WebSocket 重连策略
|
||||
|
||||
- **指数退避**:初始 1s,每次翻倍,最大 30s
|
||||
- **jitter**:在 `[delay/2, delay]` 范围内随机,避免惊群
|
||||
- **最大重试**:10 次后放弃并提示用户刷新
|
||||
- **会话恢复**:重连后自动发送 `history` 消息恢复后端上下文
|
||||
|
||||
### 4.5 API 模块
|
||||
|
||||
| 模块 | 文件 | 对应后端 |
|
||||
|------|------|---------|
|
||||
| `client` | `client.ts` | Axios 实例、JWT 拦截器 |
|
||||
| `auth` | `auth.ts` | `/api/v1/auth/*` |
|
||||
| `sessions` | `sessions.ts` | `/api/v1/sessions/*` |
|
||||
| `memory` | `memory.ts` | `/api/v1/memory/*` |
|
||||
| `reminders` | `reminders.ts` | `/api/v1/reminders/*` |
|
||||
| `briefings` | `briefings.ts` | `/api/v1/briefings/*` |
|
||||
| `voice` | `voice.ts` | `/api/v1/voice/*` |
|
||||
| `files` | `files.ts` | `/api/v1/files/*` |
|
||||
| `automation` | `automation.ts` | `/api/v1/automation/*` |
|
||||
| `knowledge` | `knowledge.ts` | `/api/v1/knowledge/*` |
|
||||
|
||||
### 4.6 WebSocket 消息流
|
||||
|
||||
**客户端 → 服务端**:
|
||||
```typescript
|
||||
{ type: "message", content: "你好", mode: "text", session_id: "xxx", timestamp: 123 }
|
||||
{ type: "history", session_id: "xxx" }
|
||||
{ type: "voice_input", audio_data: "base64..." }
|
||||
```
|
||||
|
||||
**服务端 → 客户端**:
|
||||
| type | 触发时机 | 前端处理 |
|
||||
|------|---------|---------|
|
||||
| `stream_chunk` | AI 流式逐字输出 | `appendToLastMessage` 累积 |
|
||||
| `stream_end` | 流式输出结束 | `finishStreaming` 标记完成 |
|
||||
| `response` | 审查后的独立消息 (action/chat) | `addMessage` 添加独立气泡 |
|
||||
| `history_response` | 会话恢复/历史请求 | 仅在无消息时加载 |
|
||||
| `review` | 旧版审查消息 | 逐条 `addMessage` |
|
||||
| `multi_message` | 多段消息 | 逐段 `addMessage` |
|
||||
| `stream_segments` | 断句信息 | 逐段 `addMessage` |
|
||||
| `device_update` | IoT 设备状态广播 (10s) | `setIoTDevices` 更新状态栏 |
|
||||
| `background_thinking` | 后台思考状态变化 | `setBackgroundThinkingStatus` |
|
||||
| `notification` | 系统通知/提醒 | `addNotification` + 浏览器桌面通知 |
|
||||
| `error` | 服务端错误 | 系统消息气泡 |
|
||||
|
||||
---
|
||||
|
||||
## 五、DevTools (:9090) — 调试工具
|
||||
|
||||
**目录**:`devtools/`
|
||||
**类型**:Node.js Express 应用
|
||||
|
||||
### 5.1 服务管理
|
||||
|
||||
| 端点 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| `/api/services` | GET | 列出所有服务状态 |
|
||||
| `/api/services/:id/build` | POST | 编译服务 (go build -o main.exe) |
|
||||
| `/api/services/:id/start` | POST | 启动服务 |
|
||||
| `/api/services/:id/stop` | POST | 停止服务 |
|
||||
| `/api/services/:id/restart` | POST | 重启服务 |
|
||||
| `/api/services/:id/logs` | GET | 获取服务日志 |
|
||||
| `/api/services/:id/memory` | GET | 获取进程内存 |
|
||||
|
||||
### 5.2 其他功能
|
||||
|
||||
- **IoT 管理**:设备列表/状态切换
|
||||
- **记忆管理**:记忆搜索/CRUD
|
||||
- **性能监控**:CPU/内存使用率
|
||||
- **数据库管理**:表结构检查、迁移执行
|
||||
- **WebSocket 状态**:连接数/会话列表
|
||||
- **健康检查轮询**:每秒检测所有服务可达性
|
||||
|
||||
### 5.3 关键配置
|
||||
|
||||
**构建命令**([config.js](devtools/src/config.js)):
|
||||
```javascript
|
||||
buildCommand: 'go',
|
||||
buildArgs: ['build', '-o', isWin ? 'main.exe' : 'main', './cmd/main.go'],
|
||||
goBin: GO_BIN
|
||||
```
|
||||
|
||||
所有 Go 服务统一编译为 `main.exe`(Windows),DevTools 通过 `./main` 启动。**自定义二进制名称不会被 DevTools 识别。**
|
||||
|
||||
---
|
||||
|
||||
## 六、对话管线详解
|
||||
|
||||
### 6.1 完整请求时序
|
||||
|
||||
```
|
||||
Browser (React) Gateway AI-Core
|
||||
│ │ │
|
||||
├─ WebSocket: {type:"message"} ──┤ │
|
||||
│ ├─ POST /api/v1/chat ──────►│
|
||||
│ │ (SSE streaming) │
|
||||
│ │ ├─ 意图分析 (0-1.4s)
|
||||
│ │ ├─ 并行子会话
|
||||
│ │ │ ├─ memory (检索)
|
||||
│ │ │ ├─ iot (查询/操控)
|
||||
│ │ │ └─ general (意图)
|
||||
│ │ ├─ LLM 合成 (3-4s)
|
||||
│ │ ├─ parseReviewMessages
|
||||
│ │ │
|
||||
│ │◄── SSE: delta ────────────┤
|
||||
│◄── WS: stream_chunk ──────────┤ │
|
||||
│◄── WS: stream_chunk ... ──────┤ │
|
||||
│ │◄── SSE: review_messages ──┤
|
||||
│◄── WS: response (action) ─────┤ (200ms delay) │
|
||||
│◄── WS: response (chat) ───────┤ │
|
||||
│ │◄── SSE: [DONE] ──────────┤
|
||||
│◄── WS: stream_end ────────────┤ │
|
||||
```
|
||||
|
||||
### 6.2 性能数据
|
||||
|
||||
| 场景 | 总响应 | 意图分析 | 子会话 | LLM 合成 |
|
||||
|------|--------|---------|--------|---------|
|
||||
| "你好呀" | ~3.9s | 0s | 跳过 | 3.9s |
|
||||
| "打开客厅灯" | ~2.6s | 0s | IoT+Memory | ~2.6s |
|
||||
| "关掉客厅灯" | ~2.6s | 0s | IoT+Memory | ~2.6s |
|
||||
| "打开卧室灯和卧室空调" | ~3.0s | 0s | IoT+Memory | ~3.0s |
|
||||
| "看看设备状态" | ~5.3s | 1.4s | IoT+Memory | ~3.9s |
|
||||
| "你还记得我喜欢什么吗?" | ~4-5s | LLM | Memory+General | ~3-4s |
|
||||
|
||||
LLM 合成(deepseek-v4-flash)是主要延迟来源,约占 60-80% 的总响应时间。
|
||||
|
||||
### 6.3 E2E 消息流示例
|
||||
|
||||
```
|
||||
用户: "帮我把客厅灯打开"
|
||||
→ Gateway WS → AI-Core SSE
|
||||
→ Intent: iot_control (快速通道, 0s)
|
||||
→ Dispatch: memory + general + iot + review (并行)
|
||||
→ IoT: 查询 8 个设备 → 匹配客厅灯 → 已开状态
|
||||
→ Synthesize: 综合上下文 → LLM 生成回复
|
||||
→ parseReviewMessages:
|
||||
action: "歪着头看你"
|
||||
chat: "叶酱,客厅灯早就开着啦♪ 你是不是工作太累看花了眼呀?"
|
||||
→ Gateway: 200ms 间隔逐条推送 WebSocket response
|
||||
→ Frontend: ActionMessageBubble + MessageBubble 分别渲染
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、数据库设计
|
||||
|
||||
### 7.1 PostgreSQL 连接
|
||||
|
||||
所有服务共用 PostgreSQL 数据库 `cyrene_ai`,通过 `DB_URL` 环境变量配置:
|
||||
```
|
||||
postgres://cyrene:cyrene_pass@localhost:5432/cyrene_ai?sslmode=disable
|
||||
```
|
||||
|
||||
### 7.2 主要表结构
|
||||
|
||||
| 表 | 管理方 | 用途 |
|
||||
|----|--------|------|
|
||||
| `users` | Gateway | 用户认证 |
|
||||
| `sessions` | Gateway | 会话记录 |
|
||||
| `messages` | Gateway | 对话消息(role, content, timestamp) |
|
||||
| `memories` | Memory-Service | 记忆存储(含 pgvector embedding) |
|
||||
| `reminders` | Gateway | 定时提醒 |
|
||||
| `briefings` | Gateway | 每日简报 |
|
||||
| `automation_rules` | Gateway | 自动化规则 |
|
||||
| `automation_scenes` | Gateway | 自动化场景 |
|
||||
| `files` | Gateway | 文件元数据 |
|
||||
| `knowledge_bases` | Gateway | 知识库 |
|
||||
| `knowledge_documents` | Gateway | 知识文档 |
|
||||
| — (工具调用日志) | AI-Core (内存) | 环形缓冲区 500 条,无 DB 持久化 |
|
||||
|
||||
### 7.3 已知缺项
|
||||
|
||||
- `messages` 表缺少 `msg_type` 列——目前通过 `role` 字段区分 action/chat(`role="action"` 表示动作消息)
|
||||
|
||||
---
|
||||
|
||||
## 八、安全性
|
||||
|
||||
| 层面 | 实现 |
|
||||
|------|------|
|
||||
| 认证 | JWT (HS256),默认永不过期 |
|
||||
| 密码存储 | bcrypt 哈希 |
|
||||
| 会话隔离 | 按 userID + sessionID 双重隔离 |
|
||||
| 限流 | 认证端点:5次/分钟/IP;API 端点:10 req/s + 突发 20 |
|
||||
| CORS | 可配置的来源白名单 |
|
||||
| HTTP 框架 | Gin 的生产模式(ReleaseMode)+ Recovery 中间件 |
|
||||
| WebSocket 安全 | JWT token 验证 + admin-only 主对话 |
|
||||
| 内部服务 | Internal Service Token 认证 |
|
||||
|
||||
---
|
||||
|
||||
## 九、已知限制与改进方向
|
||||
|
||||
### 当前限制
|
||||
|
||||
1. **LLM 合成延迟**(3-4s):deepseek-v4-flash 调用是主要瓶颈,合成阶段无法被快速通道绕过
|
||||
2. **"开" 字歧义**:无法将单独的 "开" 加入快速通道("开心"/"开始" 产生误判),"开灯" 等短命令仍走 LLM
|
||||
3. **msg_type 数据库列缺失**:messages 表使用 `role` 字段区分 action/chat,不是专用的 `msg_type` 列
|
||||
4. **Node.js v24 Windows 原生 WebSocket bug**:频繁建立连接可能触发 libuv `UV_HANDLE_CLOSING` 断言
|
||||
5. **流式审查**:`parseReviewMessages()` 需要等 LLM 合成完成后才能执行,无法实时拆分
|
||||
6. **`frontend/packages/shared/`** 和 **`backend/proto/`** 为空占位
|
||||
|
||||
### 建议改进方向
|
||||
|
||||
1. **LLM 响应缓存**:对相似问候/常见 IoT 命令引入语义缓存
|
||||
2. **数据库迁移**:为 messages 表添加 `msg_type` 列
|
||||
3. **流式审查**:在 LLM 合成过程中实时识别并分段发送 action/chat
|
||||
4. **Protobuf 通信**:填充 `backend/proto/` 目录,服务间改用 gRPC
|
||||
5. **WebSocket 兼容**:生产环境使用 `ws` npm 包替代原生 WebSocket
|
||||
6. **前端集成测试**:Playwright/CDP 端到端测试
|
||||
|
||||
---
|
||||
|
||||
## 附:快速参考
|
||||
|
||||
### 服务端口一览
|
||||
|
||||
| 服务 | 端口 | 技术 |
|
||||
|------|------|------|
|
||||
| Gateway | 8080 | Gin + WebSocket |
|
||||
| AI-Core | 8081 | net/http + SSE |
|
||||
| IoT Debug | 8083 | net/http |
|
||||
| Memory | 8091 | net/http + pgvector |
|
||||
| Tool Engine | 8092 | net/http |
|
||||
| Voice | 8093 | net/http + whisper.cpp |
|
||||
| Frontend (dev) | 5173 | Vite |
|
||||
| DevTools | 9090 | Express |
|
||||
|
||||
### 常用命令
|
||||
|
||||
```bash
|
||||
# 构建所有 Go 服务
|
||||
cd backend/ai-core && GOWORK=off go build -o main.exe ./cmd/main.go
|
||||
cd backend/gateway && GOWORK=off go build -o main.exe ./cmd/main.go
|
||||
# ... 其他服务同理
|
||||
|
||||
# 或通过 DevTools API
|
||||
curl -X POST http://localhost:9090/api/services/ai-core/build
|
||||
curl -X POST http://localhost:9090/api/services/gateway/build
|
||||
|
||||
# 启动前端开发服务器
|
||||
cd frontend/web && pnpm dev
|
||||
|
||||
# E2E 测试
|
||||
node test/test_final_e2e.mjs
|
||||
```
|
||||
|
||||
### 环境变量 (.env)
|
||||
|
||||
位于 `backend/.env`,基础设施与 LLM 回退配置:
|
||||
```
|
||||
POSTGRES_HOST=localhost
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_USER=cyrene
|
||||
POSTGRES_PASSWORD=cyrene_pass
|
||||
POSTGRES_DB=cyrene_ai
|
||||
JWT_SECRET=xxx
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=xxx
|
||||
|
||||
# Phase 6: 以下 LLM 变量作为 models.json 不存在时的回退
|
||||
LLM_API_URL=https://api.deepseek.com/v1
|
||||
LLM_API_KEY=sk-xxx
|
||||
LLM_MODEL=deepseek-v4-flash
|
||||
LLM_FALLBACK_MODEL=deepseek-v4-flash
|
||||
```
|
||||
|
||||
### 模型配置 (models.json)
|
||||
|
||||
Phase 6 新增,位于 `backend/models.json`(`.gitignore` 已排除)。格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"providers": {
|
||||
"deepseek": {
|
||||
"name": "deepseek",
|
||||
"base_url": "https://api.deepseek.com",
|
||||
"api_key": "sk-xxx",
|
||||
"timeout_sec": 120,
|
||||
"max_retries": 3
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"primary_chat": {
|
||||
"id": "primary_chat",
|
||||
"name": "deepseek-v4-flash",
|
||||
"provider": "deepseek",
|
||||
"description": "主对话模型",
|
||||
"tags": ["chat", "fast"],
|
||||
"params": { "temperature": 0.8, "max_tokens": 2048 },
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"chat": {
|
||||
"purpose": "chat",
|
||||
"fallback_chain": ["primary_chat", "fallback_chat"],
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**配置管理 API**(Gateway admin,DevTools 代理提供 UI):
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET/POST/DELETE | `/api/v1/admin/models/providers/:name` | Provider CRUD |
|
||||
| GET/POST/DELETE | `/api/v1/admin/models/models/:id` | Model CRUD |
|
||||
| GET/POST/DELETE | `/api/v1/admin/models/routing/:purpose` | Routing CRUD |
|
||||
|
||||
**向后兼容**:如果 `models.json` 不存在,`ModelSelector` 自动回退到 `.env` 的 4 个 LLM 变量,行为与 Phase 5 及之前完全一致。
|
||||
Reference in New Issue
Block a user