From d53de4f33fa3cf54f600b96f132062af5d874275 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Sat, 20 Jun 2026 13:33:05 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20CI/CD=20=E9=83=A8=E7=BD=B2=E5=9B=BA?= =?UTF-8?q?=E5=AE=9A=E5=88=B0=20/root/camtalk=20=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=20compose=20=E8=83=BD=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=AE=A1=E7=90=86=E5=AE=B9=E5=99=A8=E7=94=9F=E5=91=BD?= =?UTF-8?q?=E5=91=A8=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.yml | 11 +++- CamTalk-演讲稿.md | 116 ------------------------------------ backend/config.yaml | 2 +- 3 files changed, 9 insertions(+), 120 deletions(-) delete mode 100644 CamTalk-演讲稿.md diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 44abebb..5c9ae7c 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -14,8 +14,13 @@ jobs: - name: Install Docker CLI run: apk add --no-cache docker-cli docker-cli-compose + - name: Sync to deploy directory + run: | + mkdir -p /root/camtalk + rsync -a --delete --exclude='.env' --exclude='pgdata' --exclude='redisdata' ./ /root/camtalk/ + - name: Build and Deploy run: | - chmod +x deploy.sh - ./deploy.sh build - ./deploy.sh restart + chmod +x /root/camtalk/deploy.sh + /root/camtalk/deploy.sh build + /root/camtalk/deploy.sh restart diff --git a/CamTalk-演讲稿.md b/CamTalk-演讲稿.md deleted file mode 100644 index 1779f00..0000000 --- a/CamTalk-演讲稿.md +++ /dev/null @@ -1,116 +0,0 @@ -## CamTalk — 多模态实时 AI 视觉对话助手 · 演讲稿 - -> 面向面试官,预计 10-15 分钟。建议配合架构图或项目文档做演示。 - ---- - -### 开场(约 1 分钟) - -各位好,今天我想和大家分享一个我主导设计和开发的项目——**CamTalk**,一个多模态实时 AI 视觉对话助手。 - -简单来说,用户打开浏览器,对着摄像头,用语音提问,AI 就能同时"看到"画面、"听到"语音,然后用文字和语音自然地回应。整个过程不需要打字,就像一个面对面的助手。 - -做这个项目的初衷其实很直接——现在的大模型已经具备多模态能力,但大多数产品还是"上传一张图、输入一段文字"的交互方式。我认为真正的多模态交互应该是**无感的**——用户只需要说话,AI 自己去理解视觉场景,就像两个人面对面聊天一样。 - ---- - -### 系统架构(约 3 分钟) - -CamTalk 采用三层架构:**前端做轻量预处理,后端做智能编排,云端 AI 服务按需调用**。 - -**前端**是 React 18 加 TypeScript,跑在浏览器里。它负责三件事:摄像头和麦克风的采集,边缘侧的预处理——比如语音活动检测和关键帧过滤,以及 UI 渲染。通过 WebSocket 与后端通信。 - -**后端**是 Go 写的网关服务,用 Gin 框架做 HTTP 路由,gorilla/websocket 处理长连接。它是整个系统的"大脑",负责会话管理、AI 编排,以及和各家 AI 服务的对接。每个 WebSocket 连接对应一个 goroutine,天然适合这种长连接场景。 - -**AI 服务层**是可插拔的。LLM 默认用 GPT-4o,通过 OpenAI 兼容接口可以随时切换成通义千问等国产模型。语音识别默认 Deepgram,语音合成默认 OpenAI TTS,同时也支持小米的 MiMo 系列作为备选。 - -有人可能会问:为什么不直接让前端调用 AI API?这里有三点考虑。第一是**安全性**,API Key 不应该暴露在客户端。第二是**统一管控**,速率限制、成本监控、模型路由这些逻辑集中在网关层更好维护。第三是**可扩展性**,未来加缓存、做负载均衡、多实例部署,都在网关层解决。 - -部署方面,我们设计了 Nginx 做同源反向代理,前端静态资源和后端 API 在同一个域名下,天然解决跨域问题。Go 网关可以水平扩展,通过 Redis 共享会话状态。目前也已经配置好了 Docker Compose 一键部署方案,包含前端、后端和 PostgreSQL 三个容器。 - ---- - -### 核心交互流程(约 3 分钟) - -我想重点讲一下一次完整的交互流程,因为它串起了整个系统最核心的技术挑战。 - -用户对着摄像头说了一句话,比如"这是什么花"。首先是**前端**的 VAD——语音活动检测模块——在浏览器端实时检测用户何时开始说话、何时说完。这一步完全在端侧完成,用的是 @ricky0123/vad-web,基于 WebRTC VAD 算法。好处是:用户不说话时不需要上传任何音频,节省约 70% 的无效带宽。 - -VAD 检测到语音结束后,前端会同时做两件事:把音频编码成 PCM 格式,以及从摄像头捕获当前画面,一起通过 WebSocket 发给后端。 - -后端收到后,启动一个 **AI 编排管道**(我们叫它 Orchestrator)。第一步,把音频发给 STT 服务做语音识别,拿到文字结果。第二步,把识别出的文字、摄像头画面以及对话历史,一起打包发给多模态 LLM 做推理。LLM 以流式方式逐 token 输出。第三步,也是最关键的优化——我们不等待 LLM 输出完再调用 TTS,而是做**句子级切分**:LLM 每输出一个完整句子,就立即送入 TTS 合成并推送给客户端。 - -所以客户端的体验是这样的:文字一个 token 一个 token 地出现,几乎同时语音就开始播放了。用户**先看到文字、紧接着听到语音**,感知延迟可以控制在 0.5 秒以内。整个端到端的目标延迟是 1.5 到 2 秒。 - -这个"LLM 文本流和 TTS 音频流并行推送"的设计,是我们降低感知延迟最关键的手段。 - ---- - -### 成本控制(约 2 分钟) - -做实时多模态应用,成本是最容易失控的地方。我在设计之初就把成本控制作为架构级别的考量。 - -最直观的例子是视觉链路:如果按 1fps 全量发送画面给 LLM,一个用户每天用 10 分钟,一天就是 60 万帧的 token 消耗,1000 个用户时成本完全不可控。 - -我们的核心策略叫**端云协同**——把适合的计算前置到客户端。 - -在视觉侧,我们做了三个优化:一是降低采样频率,空闲时 5 秒一帧,用户说话时 1 秒一帧;二是关键帧过滤,通过 Canvas 像素比较计算帧间相似度,画面没有显著变化就不发送;三是只在用户提问时捕获画面,而不是持续上传视频流。 - -在语音侧,VAD 在浏览器端检测,只上传有效语音片段,环境噪音和静默时段完全不消耗带宽。 - -在推理侧,我们规划了模型分级策略——简单识别类问题走 GPT-4o-mini,深度分析走 GPT-4o,复杂推理走 o1。同时对话历史做了裁剪,前端保留最近 10 轮,后端保留 20 轮,限制每轮的固定 token 开销。 - -这些策略综合下来,预估月成本可以从无优化的约 5000 美元降到 300 到 500 美元,降幅大约 90%。 - ---- - -### 工程设计与取舍(约 2 分钟) - -除了技术实现,我想分享几个设计上的取舍。 - -**存储方案的分阶段设计**。MVP 阶段我们用进程内存存会话状态,快速验证核心功能。但代码层面我们已经通过 Repository 接口模式做了抽象——HistoryRepository、UsageRepository 这些接口定义好了,底层实现可以是 Memory、Redis 或 PostgreSQL,通过配置切换。目前 Redis 实现已经就绪,PostgreSQL 的 schema 也设计好了,包括 sessions、messages、usage_daily 三张表。这种渐进式设计让我们既能快速交付,又为后续扩展留好了空间。 - -**文档驱动开发**。项目里有一套完整的设计文档,涵盖架构、接口协议、技术选型、成本控制等。我们遵循"文档优先"原则——实现功能前先写设计文档,实现和文档不一致时优先更新文档。这在团队协作中特别重要,接口契约清晰,前后端可以并行开发。 - -**WebSocket 协议的可靠性设计**。客户端每 30 秒发心跳,服务端 60 秒没收到心跳就断开。断线后用指数退避加抖动重连——1 秒、2 秒、4 秒、8 秒,最大 30 秒。消息用统一信封格式,所有消息都带 type 字段做类型分发。 - ---- - -### 用户故事与产品规划(约 2 分钟) - -最后讲一下产品层面的思考。用户故事我按 P0 到 P2 分了三个优先级。 - -P0 是 MVP 必做的四个场景:AI 识别画面中的物体、语音对话无需打字、AI 能看到摄像头画面、AI 用语音回答。这四个跑通了,核心价值就成立了。 - -P1 是体验增强:AI 主动观察画面变化并提示重要事件、识别画面中的文字做 OCR、以及多轮对话的上下文记忆。 - -P2 是进阶探索:比如视障用户的无障碍辅助——AI 实时描述周围环境并提示障碍物,画面中外语内容的实时翻译,以及"观察模式"和"对话模式"的切换。 - -优先级判断用两个维度交叉评估:用户价值和实现成本。P0 是高价值且成本合理的,P1 是高价值但成本较高的,P2 是探索性的,验证后再投入。 - -目前还有几个功能创意在规划中,包括视频录制、对话翻译、对话总结、手动对话输入,以及对话情景选择——比如面试官模式、英语老师模式、辩论赛模式等。 - ---- - -### 总结(约 1 分钟) - -总结一下,CamTalk 这个项目有几个我比较满意的设计点。 - -第一是**架构清晰**:三层分离,每层职责明确,前端做轻量预处理,后端做智能编排,AI 服务可插拔。 - -第二是**体验导向**:从用户感知延迟倒推技术方案,流式并行推送、句子级切分、端侧 VAD 这些手段都是围绕"让对话像真人一样自然"这个目标设计的。 - -第三是**成本意识**:从架构层面就融入了成本控制,端云协同、智能采样、模型分级,不是等功能做完再去优化成本。 - -第四是**工程成熟度**:接口抽象、文档驱动、渐进式存储升级,为项目的长期演进留好了空间。 - -以上就是 CamTalk 项目的整体介绍。谢谢大家,有什么问题我们可以一起讨论。 - ---- - -> **附:讲解提示** -> -> - 如果面试官追问技术深度,可以展开讲 Orchestrator 的管道实现细节(goroutine 并发、context 取消、句子切分算法)或 VAD 参数调优。 -> - 如果追问产品思维,可以展开讲用户故事的优先级判断逻辑,以及观察模式和对话模式的差异设计。 -> - 如果追问可扩展性,可以讲 Redis 共享会话、多 Gateway 水平扩展、模型路由器的规划。 -> - 如果追问成本数据,可以给出具体的 token 消耗计算过程和各种优化手段的量化效果。 diff --git a/backend/config.yaml b/backend/config.yaml index c36ef23..0aafbf6 100644 --- a/backend/config.yaml +++ b/backend/config.yaml @@ -57,7 +57,7 @@ redis: auth: # jwt_secret 通过环境变量 CAMTALK_AUTH_JWT_SECRET 设置 - access_ttl: 15 # Access Token 过期时间(分钟) + access_ttl: 120 # Access Token 过期时间(分钟) refresh_ttl: 10080 # Refresh Token 过期时间(分钟),7 天 log: -- 2.49.1