blog / Save File
72 小时,从零到一:一个实时同传项目的极限开发复盘
七牛云议题选拔的 72 小时实战:MVP 一天跑通,让它『像个产品』又花了两周。记录一次被打包、发布、进程管理狠狠教育的全过程。
记一次七牛云议题选拔活动的实践与反思。 同时也是一次对「开发效率」这件事的重新思考——快与稳,从来不是对立的两端。
一、为什么写这篇文章
最近我对七牛云的「议题选拔」活动产生了浓厚的兴趣,规则简单粗暴:
- 给你 72 小时;
- 主办方公布几个候选议题;
- 你任选其一,在规定时间内交付一个可闭环运行的程序;
- 必须有展示视频作为最终验收材料。
听上去像是一场技术黑客松,但它真正的难点不在编码,而在两个看不见的环节:
- 决策:怎么在最短时间内挑出最适合自己的议题?
- 节奏:怎么在 72 小时里同时安排「调研 → 实现 → 调试 → 录制」?
我抱着试一试的心态报名了一个议题,做完之后陆陆续续又花了不少时间打磨细节。这一路踩了不少坑,也有些不太一样的体会。趁着热乎,写下来。
二、项目速览
我选的是实时同声传译助手——一个跑在桌面端的双语字幕应用:
- 捕获系统音频或麦克风输入;
- 通过 OpenAI 兼容的 ASR 接口实时转写英文;
- 调用 LLM 翻译为中文,并基于上下文做术语约束;
- 字幕以
interim → final → corrected三阶段流式展示,自动修正识别和翻译误差。
技术栈最终落在:
| 层 | 选型 |
|---|---|
| 桌面壳 | Tauri(Rust) |
| 前端 | React + Vite + TypeScript |
| 运行时 | Python + FastAPI(作为 sidecar 进程) |
| AI 服务 | OpenAI 兼容 API(Whisper / Chat Completions) |
| 打包 | PyInstaller + Tauri Bundler |
第一天我就跑通了 MVP;但接下来的整整两周——从 v0.4.2 到 v0.4.13——我都在和「桌面应用的工程细节」缠斗。这些版本里至少有 8 个 release 是在修打包、部署或进程管理相关的问题。
这后面会展开聊。
三、我做了什么
1. 选题:不是挑最难的,而是挑「难度可估」的
第三批议题中,我相中了实时翻译这一个。
挑它的理由其实很现实:
- 它的核心链路足够具体——音频流 → ASR → LLM → 字幕渲染——每一段都有成熟方案可参考;
- 它的挑战点足够清晰——延迟、字幕修正、桌面端音频捕获,都是看得见摸得着的硬骨头;
- 相较之下,其他议题要么过于宽泛,要么实现路径过短,做完反而不容易凸显工程能力。
复盘小结:极限开发的选题策略,不是”挑最酷的”,而是”挑边界最清楚的”。 边界清楚,意味着风险可量化,可以在 72 小时的时间盒里被安全地装下。
2. 规划:先和模型对话,再动手
这是我养成的习惯——不在没想清楚之前开仓库。
我先做了几件事:
- 和模型对齐原理:拉着 AI 讨论 ASR、流式翻译、术语注入、字幕状态机等技术点;
- 补术语功课:对不熟的概念(VAD、partial transcript、glossary prompt 等)做小范围搜索;
- 讨论技术栈——这里我后来发现,埋了一颗很大的坑(后文细说)。
整个准备阶段大约花了 2~3 个小时,但它换来的是后续几乎不返工的实现路径。
3. 启动项目:第一天就跑通 MVP
技术栈定下来后(Python 后端 + React 前端 + Tauri 打包),我把和模型聊出来的技术方案整理成一份”开发口播”,整段贴给 Agent,让它按章节推进。
这里又埋了第二颗坑——后文一并展开。
第一天结束时,MVP 已经能跑:
- 桌面应用启动;
- 麦克风音频实时转写;
- 字幕渲染流畅。
中间踩到一个有意思的细节:模型最初实现的字幕只能”追加”,不能”修正”。也就是说,ASR 一旦把一句话识别错了,错的就一直挂在屏幕上。这显然不符合议题里**“实时字幕可被修正”**的要求。
我主动介入,提出了基于上下文的字幕状态机思路——通过比较新一段与前一段是否是同一语义单元的续写,决定是替换、修正、还是新起一行。这才接回了议题原本的要求。
复盘小结:先调研、再动手是值得的。 但更值得记住的是——Agent 会忘记你要做什么,开发者必须始终拿着「需求清单」做主动校准。
4. 事后复盘与打磨:真正花时间的地方
这其实是我写这篇文章的核心动因。
MVP 跑通只用了一天,但让它真正”像一个产品”,我又花了整整两周。这中间的工作包括但不限于:
- runtime 静默启动——Windows 下消除 Python 子进程的黑色 cmd 窗口;
- 应用内自动检测更新——基于 Tauri Updater 的
latest.json发布流; - runtime 生命周期管理——sidecar 启动 / 健康检查 / 重启 / 退出时强杀进程树;
- 更新前关闭 runtime——避免文件占用导致升级失败;
- CI 发布流程修复——
latest.json生成、UTF-8 BOM、签名密钥重置、版本号脚本健壮性……
这些工作没有一项是”算法层面的创新”,但没有它们,这个项目就不能称之为产品。
四、我踩的坑
坑 1:粗糙的技术栈选择
一句话:Web 后端用 Python 没问题,但桌面应用拿 Python 当运行时,打包就是第一道坎。
回头看 Git log 是真的扎心:
v0.4.2 fix: prevent bump-version script from corrupting Cargo.toml
v0.4.3 fix: hide console window when spawning runtime sidecar
v0.4.4 fix: remove BOM from JSON files
v0.4.5 fix: repair UTF-8 handling in bump-version
v0.4.5 fix: repair latest.json URL to match GitHub sanitized asset name
v0.4.7 fix: apply fontSize setting to subtitle rendering
v0.4.8 fix: kill runtime process tree on app exit to prevent port occupation
v0.4.9 fix: redirect uvicorn logs to file to suppress cmd window
v0.4.10 chore: release
v0.4.12 fix: stop runtime before update install
v0.4.13 fix: apply subtitle font size setting
v0.4.13 fix(desktop): show updater check failures
12 个版本里,至少 8 个是在修打包 / 部署 / 进程管理相关的问题。这些坑不是 Python 本身有问题,而是用 Python 做桌面端常驻进程带来的连锁反应:
- 打包体积:PyInstaller 打出的 sidecar 动辄上百 MB;
- 黑窗问题:Windows 下 spawn Python 子进程默认弹 cmd 窗口,要用
CREATE_NO_WINDOW标志屏蔽; - 日志通道:uvicorn 默认写 stderr,会触发 Tauri 把它当错误捕获,得重定向到文件;
- 进程树退出:Python 进程组里还有 worker,主进程退出时不杀子进程,下次启动会端口占用;
- 更新冲突:升级时 runtime 还在运行,旧文件被占用,导致写入失败。
如果重选——我会更慎重地评估桌面端运行时的语言选择。哪怕只是把 ASR/翻译这层换成 Rust 调用第三方 SDK,也会省下后面 8 个版本的工作量。
教训:技术栈选型时,别只看”我熟悉哪个”,要看”它在目标场景的最差表现是什么”。 Web 端的 Python 是甜蜜区,桌面端的 Python 是雷区。
坑 2:跳过文档先行
我之前的那篇关于「AI Coding 时代如何开始一个项目」里一直主张文档先行,但具体到这个项目,我自己只做了一份粗略的技术架构图就直接开工了。
代价是:
- Agent 在长上下文里会丢失关键需求——我前面提到的”字幕可修正”就被它忘得一干二净,要我主动捞回来;
- 多端协议没提前对齐——前端字幕状态机、后端字幕事件、Tauri 命令通道,是我边写边补的,导致一些接口反复调整;
- 打包流程没在设计阶段画进去——所以才会有后面 8 个版本疯狂修打包问题。
教训:文档先行不是”好习惯”,是极限开发的强约束。 极限开发里,时间不够换来的应该是”少返工”,而不是”少思考”。
坑 3:被忽视的发布工程
这是最让我意外的一坑——发布、更新、签名、CI,每一环都比想象中复杂。
举几个具体的例子:
Cargo.toml被自动脚本误改:bump-version 脚本不小心把依赖项的版本也一起替换了;- UTF-8 BOM 杀手:Windows PowerShell 默认写 BOM,导致 JSON 文件被各端解析失败;
latest.jsonURL 不匹配:GitHub 在上传 asset 时会做 URL sanitize,本地拼出来的链接对不上;- 签名密钥失效:updater 的私钥密码不对,整套更新流跑不通,只能重新生成密钥对。
这些问题在文档里看不到,必须在每一次”用户视角的全流程演练”里才会被发现。
教训:MVP 跑通只是项目的开始,不是结束。 真正决定一个项目是不是产品的,是从”我跑通了”到”用户能装上去”中间那道厚厚的墙。
五、我从这次极限开发中带走的几条经验
- 议题选择 > 技术能力。72 小时里,选对题省下的时间,远多于任何编码技巧能省下的。
- 先调研、再动手。哪怕只花 2 小时和模型对齐原理和栈,也会让你后续少走 2 天的弯路。
- AI Agent 是协作者,不是接管者。它会忘需求、会跑偏、会自信地给出错答案——你必须始终是项目的”产品经理”。
- 桌面端选型要看最差表现。一个语言在 Web 上有多甜,不代表它在桌面上没有毒。
- MVP ≠ 产品。能跑只是第 1 公里,发布、更新、签名、进程管理、日志、用户提示,每一项都是必答题。
- 文档先行不是仪式感,是省时间的工具。越是时间紧,越要先把架构、协议、发布流程画清楚。
六、写在最后
这次 72 小时挑战表面上是一场速度赛,但真正考察的是项目工程的全链路思维:
调研 → 选型 → 架构 → 实现 → 联调 → 打包 → 发布 → 修 bug → 再发布。
72 小时之内,我跑通了链路;72 小时之外,我学到了那些只有真正交付过产品的人才会被狠狠教育一遍的细节。
如果下一次还有类似的活动,我想我会做对两件事:
- 更慎重地选技术栈——尤其是任何会进入打包流程的依赖;
- 更老实地写文档——哪怕是 30 分钟的架构草图,也比 0 分钟强得多。
愿这篇复盘,能帮到任何一个准备奔赴下一场”极限交付”的你。
Comments