blog / Save File

72 小时,从零到一:一个实时同传项目的极限开发复盘

七牛云议题选拔的 72 小时实战:MVP 一天跑通,让它『像个产品』又花了两周。记录一次被打包、发布、进程管理狠狠教育的全过程。

2026.06.11 · 8 min read ·Thoughts
  • #Project Management
  • #Tauri
  • #Desktop App
  • #AI Coding
  • #Release Engineering

记一次七牛云议题选拔活动的实践与反思。 同时也是一次对「开发效率」这件事的重新思考——快与稳,从来不是对立的两端。

一、为什么写这篇文章

最近我对七牛云的「议题选拔」活动产生了浓厚的兴趣,规则简单粗暴:

  • 给你 72 小时
  • 主办方公布几个候选议题;
  • 任选其一,在规定时间内交付一个可闭环运行的程序;
  • 必须有展示视频作为最终验收材料。

听上去像是一场技术黑客松,但它真正的难点不在编码,而在两个看不见的环节:

  1. 决策:怎么在最短时间内挑出最适合自己的议题?
  2. 节奏:怎么在 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.2v0.4.13——我都在和「桌面应用的工程细节」缠斗。这些版本里至少有 8 个 release 是在修打包、部署或进程管理相关的问题。

这后面会展开聊。

三、我做了什么

1. 选题:不是挑最难的,而是挑「难度可估」的

第三批议题中,我相中了实时翻译这一个。

挑它的理由其实很现实:

  • 它的核心链路足够具体——音频流 → ASR → LLM → 字幕渲染——每一段都有成熟方案可参考;
  • 它的挑战点足够清晰——延迟、字幕修正、桌面端音频捕获,都是看得见摸得着的硬骨头;
  • 相较之下,其他议题要么过于宽泛,要么实现路径过短,做完反而不容易凸显工程能力。

复盘小结:极限开发的选题策略,不是”挑最酷的”,而是”挑边界最清楚的”。 边界清楚,意味着风险可量化,可以在 72 小时的时间盒里被安全地装下。

2. 规划:先和模型对话,再动手

这是我养成的习惯——不在没想清楚之前开仓库

我先做了几件事:

  1. 和模型对齐原理:拉着 AI 讨论 ASR、流式翻译、术语注入、字幕状态机等技术点;
  2. 补术语功课:对不熟的概念(VAD、partial transcript、glossary prompt 等)做小范围搜索;
  3. 讨论技术栈——这里我后来发现,埋了一颗很大的坑(后文细说)。

整个准备阶段大约花了 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 时代如何开始一个项目」里一直主张文档先行,但具体到这个项目,我自己只做了一份粗略的技术架构图就直接开工了。

代价是:

  1. Agent 在长上下文里会丢失关键需求——我前面提到的”字幕可修正”就被它忘得一干二净,要我主动捞回来;
  2. 多端协议没提前对齐——前端字幕状态机、后端字幕事件、Tauri 命令通道,是我边写边补的,导致一些接口反复调整;
  3. 打包流程没在设计阶段画进去——所以才会有后面 8 个版本疯狂修打包问题。

教训:文档先行不是”好习惯”,是极限开发的强约束。 极限开发里,时间不够换来的应该是”少返工”,而不是”少思考”。

坑 3:被忽视的发布工程

这是最让我意外的一坑——发布、更新、签名、CI,每一环都比想象中复杂。

举几个具体的例子:

  • Cargo.toml 被自动脚本误改:bump-version 脚本不小心把依赖项的版本也一起替换了;
  • UTF-8 BOM 杀手:Windows PowerShell 默认写 BOM,导致 JSON 文件被各端解析失败;
  • latest.json URL 不匹配:GitHub 在上传 asset 时会做 URL sanitize,本地拼出来的链接对不上;
  • 签名密钥失效:updater 的私钥密码不对,整套更新流跑不通,只能重新生成密钥对。

这些问题在文档里看不到,必须在每一次”用户视角的全流程演练”里才会被发现。

教训MVP 跑通只是项目的开始,不是结束。 真正决定一个项目是不是产品的,是从”我跑通了”到”用户能装上去”中间那道厚厚的墙。

五、我从这次极限开发中带走的几条经验

  1. 议题选择 > 技术能力。72 小时里,选对题省下的时间,远多于任何编码技巧能省下的
  2. 先调研、再动手。哪怕只花 2 小时和模型对齐原理和栈,也会让你后续少走 2 天的弯路。
  3. AI Agent 是协作者,不是接管者。它会忘需求、会跑偏、会自信地给出错答案——你必须始终是项目的”产品经理”。
  4. 桌面端选型要看最差表现。一个语言在 Web 上有多甜,不代表它在桌面上没有毒。
  5. MVP ≠ 产品。能跑只是第 1 公里,发布、更新、签名、进程管理、日志、用户提示,每一项都是必答题。
  6. 文档先行不是仪式感,是省时间的工具。越是时间紧,越要先把架构、协议、发布流程画清楚。

六、写在最后

这次 72 小时挑战表面上是一场速度赛,但真正考察的是项目工程的全链路思维

调研 → 选型 → 架构 → 实现 → 联调 → 打包 → 发布 → 修 bug → 再发布。

72 小时之内,我跑通了链路;72 小时之外,我学到了那些只有真正交付过产品的人才会被狠狠教育一遍的细节。

如果下一次还有类似的活动,我想我会做对两件事:

  • 更慎重地选技术栈——尤其是任何会进入打包流程的依赖;
  • 更老实地写文档——哪怕是 30 分钟的架构草图,也比 0 分钟强得多。

愿这篇复盘,能帮到任何一个准备奔赴下一场”极限交付”的你。

Comments