后端修复: - main.go: 恢复 /api/v1/chat 路由中丢失的 handleChat 调用 (空响应回归) - orchestrator.go: splitChatByLines 改为双换行分割, 避免单换行误拆 - chat_handler.go: multi_message 增加 !hasReview 守卫, 消息延迟 200→800ms - thinker.go: RecordUserMessage 追踪活跃会话ID, 推送主动消息到正确会话 - thinker.go: 增强思考提示词 — 禁止在用户休息/离开时发送主动消息 前端修复: - useWebSocket.ts: stream_segments 不再创建消息气泡, 消除重复回复 - MessageBubble.tsx: 动作消息居左对齐无头像, 时间戳移至气泡外侧 hover 显示 - ChatInput.tsx: 昔涟输入提示移至输入框上方, 波点动画效果 - MessageList/TypingIndicator/ChatContainer: 清理冗余 isTyping 传递 - MemoryPanel.tsx: 新增记忆面板组件 文档重整: - docs/debug/ → docs/debug_log/ 重命名统一 - 新增 debug_log/README.md 索引 - .gitignore: 新增 android/ 排除规则 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
20 KiB
第9轮持续调试:配置与环境完整性审计 + 综合汇总报告
日期: 2026-05-20 15:33 CST
审计范围: 全项目配置一致性、文件完整性、服务间通信、9轮综合汇总
项目: Cyrene AI 助手平台 (6 微服务 + 前端 + DevTools)
1. 当前状态速览
| 项目 | 状态 |
|---|---|
| 当前时间 | 2026-05-20 15:33:01 CST |
| 运行中服务 | 6/6 (gateway, ai-core, iot-debug-service, memory-service, tool-engine, voice-service) |
| 健康检查 | ✅ 全部通过 (6/6 HTTP 200) |
| 数据库连接 | PostgreSQL 通过 SSH 隧道 |
| LLM 模型 | deepseek-v4-flash (ai-core) |
2. 环境变量与配置一致性审计
2.1 .env.example 覆盖范围分析
backend/.env.example 定义了 33 个环境变量,分为 9 个类别。各服务实际读取的环境变量与 .env.example 的对比如下:
2.1.1 Gateway (config.go)
| 环境变量 | .env.example | Gateway 默认值 | 一致性 |
|---|---|---|---|
ENV |
✅ development |
"development" |
✅ |
GATEWAY_PORT |
❌ 缺失 | "8080" |
⚠️ 缺失 |
POSTGRES_HOST |
✅ | "localhost" |
✅ |
POSTGRES_PORT |
✅ | "5432" |
✅ |
POSTGRES_USER |
✅ | "cyrene" |
✅ |
POSTGRES_PASSWORD |
✅ | "change_me" |
✅ |
POSTGRES_DB |
✅ | "cyrene_ai" |
✅ |
REDIS_HOST |
✅ | "localhost" |
✅ |
REDIS_PORT |
✅ | "6379" |
✅ |
REDIS_PASSWORD |
✅ | "" |
✅ |
JWT_SECRET |
✅ your-secret-key-change-in-production |
"change-me-in-production" |
🔴 默认值不一致 |
JWT_EXPIRY_HOURS |
✅ 720 |
720 |
✅ |
ADMIN_USERNAME |
✅ admin |
"admin" |
✅ |
ADMIN_PASSWORD |
✅ your-admin-password |
"cyrene-dev-admin" |
🔴 默认值不一致 |
ADMIN_NICKNAME |
✅ 管理员 |
"管理员" |
✅ |
REGISTRATION_ENABLED |
✅ true |
false |
🔴 默认值不一致 |
AI_CORE_URL |
❌ 缺失 | "http://localhost:8081" |
⚠️ 缺失 |
MEMORY_SERVICE_URL |
❌ 缺失 | "http://localhost:8091" |
⚠️ 缺失 |
TOOL_ENGINE_URL |
❌ 缺失 | "http://localhost:8092" |
⚠️ 缺失 |
VOICE_SERVICE_URL |
❌ 缺失 | "http://localhost:8093" |
⚠️ 缺失 |
IOT_DEBUG_SERVICE_URL |
✅ | "http://localhost:8083" |
✅ |
LLM_API_URL |
✅ | "https://api.openai.com/v1" |
✅ |
LLM_API_KEY |
✅ | "" |
✅ |
LLM_MODEL |
✅ | "gpt-4o" |
✅ |
WS_MAX_CONNECTIONS |
❌ 缺失 | 1000 |
⚠️ 缺失 |
SESSION_IDLE_TIMEOUT_MIN |
❌ 缺失 | 30 |
⚠️ 缺失 |
WEBHOOK_API_KEY |
✅ | "" |
✅ |
INTERNAL_SERVICE_TOKEN |
❌ 缺失 | "cyrene-internal-token-change-me" |
⚠️ 缺失 |
BRIEFING_TIME |
❌ 缺失 | "08:00" |
⚠️ 缺失 |
Gateway 缺失覆盖率: 10/29 变量未在 .env.example 中定义 (34%)
2.1.2 AI-Core (main.go)
| 环境变量 | .env.example | AI-Core 默认值 | 一致性 |
|---|---|---|---|
AI_CORE_PORT |
❌ 缺失 | "8081" |
⚠️ 缺失 |
PERSONA_DIR |
❌ 缺失 | "./internal/persona" |
⚠️ 缺失 |
LLM_API_URL |
✅ | "https://api.openai.com/v1" |
✅ |
LLM_API_KEY |
✅ | "" |
✅ |
LLM_MODEL |
✅ | "gpt-4o" |
✅ |
LLM_FALLBACK_MODEL |
✅ | "gpt-4o-mini" |
✅ |
POSTGRES_HOST/PORT/USER/PASSWORD/DB |
✅ | 标准默认值 | ✅ |
POSTGRES_SSLMODE |
❌ 缺失 | "disable" |
⚠️ 缺失 |
IOT_DEBUG_SERVICE_URL |
✅ | "" |
✅ (但默认值为空 vs .env.example 有值) |
ADMIN_NICKNAME |
✅ | "管理员" |
✅ |
ENABLE_BACKGROUND_THINKING |
✅ | — | ✅ |
MEMORY_SERVICE_URL |
❌ 缺失 | "http://localhost:8091" |
⚠️ 缺失 |
DATA_DIR |
❌ 缺失 | "/tmp/cyrene_data" |
⚠️ 缺失 |
ENABLE_TOOLS |
❌ 缺失 | true |
⚠️ 缺失 |
AI-Core 缺失覆盖率: 6/13 变量未定义 (46%)
2.1.3 Memory-Service (config.go)
| 环境变量 | .env.example | 默认值 | 一致性 |
|---|---|---|---|
PORT |
❌ 缺失 | "8091" |
🔴 通用 PORT 命名冲突风险 |
DB_URL |
❌ 缺失 | "" |
⚠️ 缺失 |
POSTGRES_HOST/PORT/USER/PASSWORD/DB |
✅ | 标准默认值 | ✅ |
POSTGRES_SSLMODE |
❌ 缺失 | "disable" |
⚠️ 缺失 |
Memory-Service 缺失覆盖率: 3/6 变量未定义 (50%)
2.1.4 Tool-Engine (config.go)
| 环境变量 | .env.example | 默认值 | 一致性 |
|---|---|---|---|
PORT |
❌ 缺失 | "8092" |
🔴 通用 PORT 命名冲突风险 |
IOT_SERVICE_URL |
❌ (存在 IOT_DEBUG_SERVICE_URL) |
"http://localhost:8083" |
🔴 变量名不一致 |
DATA_DIR |
❌ 缺失 | "/tmp/cyrene_data" |
⚠️ 缺失 |
DB_URL |
❌ 缺失 | "" |
⚠️ 缺失 |
Tool-Engine 缺失覆盖率: 4/4 变量未定义 (100%)
2.1.5 Voice-Service (config.go)
| 环境变量 | .env.example | 默认值 | 一致性 |
|---|---|---|---|
PORT |
❌ 缺失 | "8093" |
🔴 通用 PORT 命名冲突风险 |
WHISPER_BINARY |
❌ 缺失 | "./whisper.cpp/main" |
⚠️ 缺失 |
WHISPER_MODEL |
❌ 缺失 | "./whisper.cpp/models/ggml-small.bin" |
⚠️ 缺失 |
WHISPER_LANGUAGE |
❌ 缺失 | "zh" |
⚠️ 缺失 |
TTS_PROVIDER |
✅ edge-tts |
— | ⚠️ 定义但 Voice-Service 未直接从 env 读取 (硬编码逻辑) |
TTS_VOICE |
✅ zh-CN-XiaoxiaoNeural |
— | ⚠️ 同上 |
ASR_PROVIDER |
✅ faster-whisper |
— | ✅ |
ASR_MODEL |
✅ medium |
— | ✅ |
Voice-Service 缺失覆盖率: 4/8 变量未定义 (50%)
2.1.6 IoT-Debug-Service (main.go)
| 环境变量 | .env.example | 默认值 | 一致性 |
|---|---|---|---|
IOT_DEBUG_PORT |
❌ 缺失 | "8083" |
⚠️ 缺失 |
IoT-Debug-Service 缺失覆盖率: 1/1 变量未定义 (100%)
2.2 🔴 严重发现:PORT 命名空间冲突
memory-service、tool-engine、voice-service 三个服务均使用通用环境变量名 PORT 来配置监听端口。在独立进程中运行时无问题,但存在以下风险:
- 如果未来合并到同一进程,将产生端口冲突
- 在 Docker Compose 中显式设置
PORT可规避,但缺乏自文档化 - 建议: 分别改为
MEMORY_SERVICE_PORT、TOOL_ENGINE_PORT、VOICE_SERVICE_PORT
2.3 🔴 严重发现:Tool-Engine 使用不一致的变量名
tool-engine/internal/config/config.go 读取 IOT_SERVICE_URL,而 .env.example 和 Gateway/AI-Core 均使用 IOT_DEBUG_SERVICE_URL。虽然 Docker Compose 中显式设置了 IOT_SERVICE_URL,但本地开发时如果只配置 .env.example 中的 IOT_DEBUG_SERVICE_URL,Tool-Engine 将使用默认值 http://localhost:8083(恰好一致),但链路不透明。
2.4 🟡 默认值不一致汇总
| 变量 | .env.example 默认值 | 代码默认值 | 服务 |
|---|---|---|---|
JWT_SECRET |
your-secret-key-change-in-production |
change-me-in-production |
Gateway |
ADMIN_PASSWORD |
your-admin-password |
cyrene-dev-admin |
Gateway |
REGISTRATION_ENABLED |
true |
false |
Gateway |
影响: 如果开发者复制 .env.example 为 .env 后未修改这些值,实际运行时的行为将与文档描述不一致。特别是 REGISTRATION_ENABLED:.env.example 说 true,但代码默认 false,如果用户不设置此变量,注册功能将静默关闭。
2.5 ✅ .env.example 覆盖良好的变量
以下变量在所有服务中一致且正确:
POSTGRES_HOST/PORT/USER/PASSWORD/DB— 所有服务统一LLM_API_URL/KEY/MODEL/FALLBACK_MODEL— Gateway + AI-Core 统一REDIS_HOST/PORT/PASSWORD— Gateway 统一IOT_DEBUG_SERVICE_URL— .env.example + Gateway + AI-Core 统一 (仅 Tool-Engine 用不同名称)ADMIN_NICKNAME— .env.example + Gateway + AI-Core 统一ENABLE_BACKGROUND_THINKING— .env.example + AI-Core 统一
3. 项目文件完整性审计
3.1 go.work ✅
backend/go.work 包含全部 6 个服务模块:
./ai-core
./gateway
./iot-debug-service
./memory-service
./tool-engine
./voice-service
3.2 Docker Compose 文件
docker-compose.yml (生产环境) ✅
包含全部 6 个后端服务 + Caddy + PostgreSQL + Redis + Qdrant + MinIO = 11 个服务。所有服务间依赖通过 depends_on 正确定义。
docker-compose.dev.yml (开发环境) ✅
包含全部 6 个后端服务 + 全部基础设施 (PostgreSQL, Redis, Qdrant, MinIO, NATS) = 11 个服务。Gateway 依赖所有其他后端服务启动后再启动。
docker-compose.dev.db.yml (仅基础设施) ✅
包含 5 个基础设施服务 (PostgreSQL, Redis, Qdrant, MinIO, NATS),设计意图为本地开发时仅启动数据库,后端服务在宿主机直接运行。容器名使用 cyrene_ 前缀避免冲突。
3.3 devtools.sh ✅
devtools.sh 功能正常:
- 自动加载
backend/.env环境变量 - 端口冲突检测与释放 (
fuser -k) - 自动安装 npm 依赖
- 健康检查等待 (最多30秒)
- 彩色日志输出
3.4 Deploy.md 🟡 多处过时
Deploy.md 存在以下与当前代码不一致的问题:
| 问题 | Deploy.md 描述 | 实际情况 |
|---|---|---|
| Go 版本要求 | Go 1.21+ |
go.work 使用 go 1.26.2 |
| 端口表缺失 | 仅列出 8080, 8081, 3001 | 缺少 8083, 8091, 8092, 8093 |
| DevTools 端口 | 3001 |
devtools.sh 使用 9090 |
| 服务状态描述 | memory-service/tool-engine/voice-service 标记为"规划中" | 三个服务已全部实现并正常运行 |
| 后端启动步骤 | 仅提及 ai-core 和 gateway | 缺少其他 4 个服务的启动说明 |
| Docker Compose 描述 | "启动 AI-Core 和 Gateway 后端服务" | docker-compose.dev.yml 实际启动全部 6 个服务 |
4. 服务间通信配置审计
4.1 Gateway → 子服务 URL 映射
| 目标服务 | Gateway 配置变量 | 默认 URL | 实际端口 | 状态 |
|---|---|---|---|---|
| AI-Core | AI_CORE_URL |
http://localhost:8081 |
8081 | ✅ |
| Memory-Service | MEMORY_SERVICE_URL |
http://localhost:8091 |
8091 | ✅ |
| IoT-Debug | IOT_DEBUG_SERVICE_URL |
http://localhost:8083 |
8083 | ✅ |
| Voice-Service | VOICE_SERVICE_URL |
http://localhost:8093 |
8093 | ✅ |
| Tool-Engine | TOOL_ENGINE_URL |
http://localhost:8092 |
8092 | ✅ |
所有 URL 配置一致,端口与实际监听端口匹配。
4.2 AI-Core → 子服务
| 目标服务 | 变量名 | 默认 URL | 状态 |
|---|---|---|---|
| IoT-Debug | IOT_DEBUG_SERVICE_URL |
"" |
✅ (空值时禁用 IoT 功能) |
| Memory-Service | MEMORY_SERVICE_URL |
http://localhost:8091 |
✅ |
4.3 Tool-Engine → IoT
| 目标服务 | 变量名 | 默认 URL | 状态 |
|---|---|---|---|
| IoT-Debug | IOT_SERVICE_URL |
http://localhost:8083 |
⚠️ 变量名不一致 (见 2.3) |
4.4 内部服务认证
gateway/internal/config/config.go 定义了 INTERNAL_SERVICE_TOKEN,默认值为 "cyrene-internal-token-change-me"。此变量:
- ❌ 未在
.env.example中定义 - ✅ 在
router.go中通过InternalNotifyAuth()中间件使用 - ⚠️ 生产环境部署时必须通过环境变量覆盖
4.5 各服务监听地址
所有服务均使用 :{PORT} 格式监听(即 0.0.0.0:{PORT}),无 localhost 绑定限制。这在 Docker 环境中正确(容器需要绑定 0.0.0.0),本地开发也无问题。
5. 第9轮新发现问题汇总
| ID | 严重级别 | 类别 | 问题描述 | 位置 |
|---|---|---|---|---|
| CFG-001 | 🔴 Critical | 配置 | PORT 命名空间冲突:3个服务共用 PORT 变量 |
memory-service, tool-engine, voice-service config |
| CFG-002 | 🔴 Critical | 配置 | Tool-Engine 使用 IOT_SERVICE_URL 而非 IOT_DEBUG_SERVICE_URL |
tool-engine/internal/config/config.go:19 |
| CFG-003 | 🟡 Medium | 配置 | JWT_SECRET 默认值不一致 (.env.example vs 代码) |
gateway/internal/config/config.go:92 |
| CFG-004 | 🟡 Medium | 配置 | ADMIN_PASSWORD 默认值不一致 |
gateway/internal/config/config.go:97 |
| CFG-005 | 🟡 Medium | 配置 | REGISTRATION_ENABLED 默认值不一致 (.env.example=true vs 代码=false) |
gateway/internal/config/config.go:101 |
| CFG-006 | 🟡 Medium | 配置 | .env.example 缺少 28+ 个服务所需环境变量 |
backend/.env.example |
| CFG-007 | 🟡 Medium | 文档 | Deploy.md 多处过时 (端口表、服务状态、Go版本) |
Deploy.md |
| CFG-008 | 🟡 Medium | 安全 | INTERNAL_SERVICE_TOKEN 未在 .env.example 中定义 |
gateway/internal/config/config.go:121 |
| CFG-009 | 🟢 Low | 配置 | POSTGRES_SSLMODE 未在 .env.example 中定义 |
ai-core, memory-service |
| CFG-010 | 🟢 Low | 配置 | Voice-Service TTS/ASR 配置读取方式不透明 | voice-service/internal/config/config.go |
6. 前9轮综合汇总统计
6.1 各轮概况
| 轮次 | 日期 | 主题 | 发现问题 | 已修复 | 待修复 |
|---|---|---|---|---|---|
| 第1轮 | 2026-05-20 | 回归验证 | 3 (REG1-REG3) | 1 (REG1) | 2 (REG2, REG3) |
| 第2轮 | 2026-05-20 | 认证集成 | 0 (验证通过) | — | — |
| 第3轮 | 2026-05-20 | 面板前端 | 3 | 0 | 3 |
| 第4轮 | 2026-05-20 | 子服务数据库 | 0 (全部通过) | — | — |
| 第5轮 | 2026-05-20 | 安全边界审计 | 8 | 0 | 8 |
| 第6轮 | 2026-05-20 | 性能代码质量 | 2 (P3) | 0 | 2 |
| 第7轮 | 2026-05-20 | E2E跨服务 | 2 | 0 | 2 |
| 第8轮 | 2026-05-20 | Docker/PWA/WebSocket | 16 | 0 | 16 |
| 第9轮 | 2026-05-20 | 配置完整性审计 | 10 | 0 | 10 |
| 合计 | 44 | 1 | 43 |
6.2 按严重级别分类汇总
| 严重级别 | 总数 | 已修复 | 待修复 | 占比 |
|---|---|---|---|---|
| 🔴 Critical (P0) | 6 | 1 | 5 | 14% |
| 🟡 Medium (P1/P2) | 21 | 0 | 21 | 48% |
| 🟢 Low (P3) | 17 | 0 | 17 | 38% |
| 合计 | 44 | 1 | 43 | 100% |
6.3 待修复 Critical 问题清单
| ID | 轮次 | 问题 | 位置 |
|---|---|---|---|
| SEC-001 | R5 | 公开端点无限流 | router.go |
| SEC-002 | R5 | JWT 密钥明文硬编码默认值 | config.go |
| DKR-001 | R8 | Caddyfile 缺失 | 项目根目录 |
| CFG-001 | R9 | PORT 命名空间冲突 | 3个子服务 |
| CFG-002 | R9 | Tool-Engine IOT_SERVICE_URL 变量名不一致 | tool-engine/config.go |
6.4 各领域健康度评估
| 领域 | 评分 | 说明 |
|---|---|---|
| 编译与构建 | ⭐⭐⭐⭐⭐ | 所有服务 go build 通过,前端 Vite 构建成功 |
| 运行时稳定性 | ⭐⭐⭐⭐⭐ | 6/6 服务正常运行,无崩溃 |
| 核心功能完整性 | ⭐⭐⭐⭐☆ | 认证/会话/记忆/IoT/工具/语音/E2E 全部通过,缺会话标题更新 |
| 安全性 | ⭐⭐⭐☆☆ | 认证流程正确,但公开端点无限流、JWT默认密钥硬编码 |
| 配置管理 | ⭐⭐☆☆☆ | .env.example 覆盖率不足 50%,多处默认值不一致 |
| 文档完整性 | ⭐⭐⭐☆☆ | Deploy.md 多处过时,端口表不完整 |
| Docker 部署 | ⭐⭐⭐☆☆ | 核心服务可构建,但缺 Caddyfile、部分健康检查 |
| 性能 | ⭐⭐⭐⭐⭐ | 健康检查 <7ms,50 并发仅 53ms |
| 代码质量 | ⭐⭐⭐⭐⭐ | go vet 全通过,goroutine 管理规范 |
| PWA | ⭐⭐⭐⭐☆ | Service Worker + 离线页面就绪,有重复注册问题 |
6.5 综合健康度评分
总体评分: 78/100 (良好)
- ✅ 优势: 运行时稳定、性能优异、代码质量高、核心功能完整
- ⚠️ 短板: 配置管理不统一、文档过时、安全加固不足
- 🔴 风险: Docker 生产部署缺少关键文件 (Caddyfile)
7. 最终健康检查
7.1 服务健康检查 (2026-05-20 15:34 CST)
| 服务 | 端口 | HTTP 状态 | 响应 |
|---|---|---|---|
| Gateway | 8080 | ✅ 200 | {"service":"cyrene-gateway","status":"ok","ws_connections":0} |
| AI-Core | 8081 | ✅ 200 | {"status":"ok","service":"ai-core","model":"deepseek-v4-flash"} |
| IoT-Debug | 8083 | ✅ 200 | {"service":"iot-debug-service","status":"ok"} |
| Memory-Service | 8091 | ✅ 200 | {"status":"ok","service":"memory-service"} |
| Tool-Engine | 8092 | ✅ 200 | {"status":"ok","service":"tool-engine"} |
| Voice-Service | 8093 | ✅ 200 | {"service":"voice-service","status":"ok","stt":{"available":true,...}} |
7.2 冒烟测试结果
| 测试 | 结果 | 说明 |
|---|---|---|
| Gateway 健康检查 | ✅ 200 | CORS 头正确设置 |
| IoT 设备列表 | ✅ 200 | 8 个模拟设备正常返回 |
| 记忆搜索 (无认证) | ✅ 401 | 认证保护正确工作 |
| 会话列表 (无认证) | ✅ 401 | 认证保护正确工作 |
| Chat 端点 (HTTP) | ✅ 404 | 预期行为 (通过 WebSocket 实现) |
7.3 CORS 安全头验证
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin, Content-Type, Authorization, X-Request-ID
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
8. 建议修复优先级
| 优先级 | 问题ID | 行动 | 预计工时 |
|---|---|---|---|
| 🔴 P0 | DKR-001 | 创建 Caddyfile |
30min |
| 🔴 P0 | CFG-001 | 重命名子服务 PORT 为独立变量名 | 1h |
| 🔴 P0 | CFG-002 | 统一 IOT_SERVICE_URL → IOT_DEBUG_SERVICE_URL |
15min |
| 🔴 P0 | SEC-001 | 为公开端点添加速率限制 | 30min |
| 🟡 P1 | CFG-003/004/005 | 统一 .env.example 与代码默认值 | 30min |
| 🟡 P1 | CFG-006 | 补全 .env.example 缺失的 28+ 变量 | 1h |
| 🟡 P1 | CFG-007 | 更新 Deploy.md | 1h |
| 🟡 P1 | CFG-008 | 在 .env.example 中添加 INTERNAL_SERVICE_TOKEN | 5min |
| 🟢 P2 | 其他 | 低优先级渐进修复 | 持续 |
9. 结论
第9轮配置与环境完整性审计发现 10 个新问题 (2 Critical, 6 Medium, 2 Low)。主要发现集中在:
- 配置管理碎片化:
.env.example仅覆盖约 50% 的实际环境变量需求,且存在默认值不一致 - 文档过时:
Deploy.md端口表、服务状态描述、DevTools 端口号均已过时 - 变量命名不一致: Tool-Engine 使用
IOT_SERVICE_URL而其他服务使用IOT_DEBUG_SERVICE_URL - PORT 命名冲突: 3 个子服务共用
PORT变量名
前 9 轮累计发现 44 个问题,已修复 1 个,待修复 43 个。项目整体健康度评分为 78/100,运行时稳定性和性能表现优秀,但配置管理和安全加固是当前最需改进的领域。
报告生成时间: 2026-05-20 15:36 CST
审计工具: 静态代码分析 + 运行时健康检查 + 冒烟测试