5.6 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
根 CLAUDE.md 描述整体架构(lego 框架、反射注册路由、pb 生成);本文件只补充
echomeet模块自身。
模块职责
echomeet 是「会议记录」模块:上传音频 → 转写(Transcribe) → 翻译(Translate) → AI 总结(Summary),产出 overview(短总结)+ summary(按模板的完整纪要)。由 home 服务装载运行(services/home/main.go),不是独立服务。HTTP 接口经反射注册为 echomeet_<方法名小写>,前缀路由示例 /api/home/echomeet_addrecord。
核心设计:一会一服务商,三段同源
每条会议记录在 providers.go 的 ResolveServiceType 解析出唯一服务商,转写/翻译/总结三步都走它,结果记在 record.ServiceType。解析优先级:
- 请求显式
service_type→ - 模块配置
DefaultService→ - 兜底按源语言:字节支持该语言走字节,否则阿里。
四套服务商,每套三件套(见对应 provider_*.go):
| ServiceType | 转写 | 翻译 | 总结(Summarizer) |
|---|---|---|---|
| ByteDance | sys/bytedance/audomodel |
火山翻译 | 豆包 sys/doubao |
| Ali | DashScope sys/aliyun/filetrans |
阿里 MT | 通义千问(sys/openai 兼容端点) |
| Cloud Speech | Cloud Translation | Gemini sys/google/gemini |
|
| Microsoft | Azure Speech | Azure Translator | Azure OpenAI(sys/openai 兼容端点) |
三类能力抽象为 Transcriber / Translator / Summarizer 接口(providers.go),运行期 GetTranscriber/GetTranslator/GetSummarizer(svcType, language) 按 ServiceType 路由。新增服务商 = 写一个 provider_xxx.go 实现三接口 + 在 providersComp.Init 注册进三张 map。
组件与异步流水线
module.go 装配组件:api(HTTP) / model(gorm) / cache(模板缓存) / providers / tasks。
tasks.go 是异步引擎:Redis 队列 + ants 协程池 + cron 每秒调度。
- 两条流水线,各有「等待队列 / 在执行集合」两个 list:短音频转写(
keyShortAwait/Proc)、AI 总结(keyAIAwait/Proc)。队列 key 用service.GetTag()+redissys.RKey(应用分组前缀)命名空间隔离,多应用共用一个 Redis 不串扰。 TaskScheduling(cron*/1 * * * * ?)每秒把等待队列搬进执行集合(受MaxShortAudioProcess/MaxAIAwaitProcess限流),再pool.Invoke真正处理。- 转写完成两条路径:异步回调(字节 api_backcall.go / 阿里 api_alibackcall.go)+ 客户端拉取时主动轮询(
PollTranscribe,由 api_getrecord.go/api_getrecords.go 在状态为 Transcribing 时驱动,TranscribeQueryMinInterval限频)。没有 cron 兜底轮询。 - 短音频走字节 flash 同步通道(
ShortAudioProcess);长音频/其他服务商走异步 submit+query。
状态机见 DBEchoMeetRecordState(proto):Unknow→AwaitTranscribing→Transcribing→AwaitSummarizing→Summarizing→Completed→Readed,失败 TranscribeFail/SummarizFail。转写失败会退还 Meetintegral 时长并冲正统计埋点。
语言码映射(core.go,易错)
输入统一是客户端 BCP-47(zh-CN/en-US…)。每个平台格式不同,core.go 逐家维护 map。铁律:未识别语言一律返回原值,绝不 fallback 成 zh——否则「未知语言→中文」会藏在调用栈深处。翻译时在 TranslateProcess 直接传 BCP-47,由各 provider 内部转换,不要提前转(会被二次转换误判)。
AI 总结输入约定(含图片)
AIProcess(tasks.go)拼 originalText:把 translate(已翻译的分句)按 [说话人]:内容 拼接;若 record.Remark(用户创建时填的备注)非空,用语言中立的结构化标签包裹:<remark>…</remark>\n\n<transcript>\n…\n</transcript>——不要硬编码某语言的提示词,避免污染多语言总结。模板 template.Template/template.Outline 作为 system prompt,分别产出 summary/overview(两路并发)。
图片注释(支持多张):请求 EchomeetAddRecordReq.imageurls 是 repeated string,DB DBEchoMeetRecord.imageurls 是 string 列存 JSON 数组(编码方式同 original:utils.ToString 写、json.Unmarshal 读)。AIProcess 解析出 url 列表后,作为多模态内容随 user 消息一并发给总结模型(要求所配模型支持视觉)。链路:ChatMessage.Images []string → 各 Summarizer.Chat → sys 层(豆包/通义/Azure 用 OpenAI 风格 image_url 直传;Gemini 在 sys/google/gemini 内逐张下载转 base64 内联 inlineData,单张失败仅跳过)。列表为空时完全走原文本路径,不影响既有行为。
重新生成 pb
改了 apps/proto/echomeet/*.proto 后需重生成(protoc-gen-go v1.36.6,已安装),并复刻源项目 pb.py 的 @go_tags 注入(覆盖 json 去掉 omitempty、追加 gorm/自定义 tag):
cd apps/services
protoc --go_out=pb --go_opt=paths=import -I ../proto ../proto/echomeet/echomeet_db.proto
protoc --go_out=pb --go_opt=paths=import -I ../proto ../proto/echomeet/echomeet_msg.proto
# 再对生成的 pb/echomeet_*.pb.go 执行 @go_tags 注入(见根 CLAUDE.md / 源项目 pb.py)
注意:HTTP 层用 jsoniter 按 json tag 收发、DB 用 gorm tag,protobuf 二进制 wire 不参与这些 API,所以字段的 json/gorm tag 必须正确。