用 AI 开发 260 个在线工具:3Q工具箱 的工程实践与方法论

简介: 本文非工具推荐或AI教程,而是记录3Q工具箱从几个小工具成长为260+工具、64篇教程过程中,真实卡点的技术决策与AI协作准则。重点剖析三个典型问题:P2P传输中“75%卡死”的并发时序陷阱、30MB WASM的缓存治理、260页预渲染的产物管控——揭示AI写代码“看似正确,实则一上真机就崩”的本质原因。

这不是一篇工具推荐,也不是 AI 使用教程。

3Q工具箱 从一个只有几个小工具的页面,长到今天 260 多个工具页、64 篇教程,其中相当一部分是在 AI 协作下完成的。这篇记录的是这个过程中真正卡住过我的几个技术决策,以及逐渐沉淀下来的几条协作准则——尤其是那些代码看起来完全正确、但一上真机就出问题的地方。


一、缘起:需求是被"长尾"撑大的

工具站有个特点:单个工具很轻,但种类无穷。

最早只有 JSON 格式化、Base64 转换这类东西。后来用户开始问:能不能转 PDF?能不能压视频?能不能识别条码?能不能算个税?每一个需求单独看都很简单,但 260 个堆在一起,维护和一致性的成本会失控。

技术栈是 Vue 2 + webpack,配 @ffmpeg/*、bwip-js、chart.js、cnchar 这些库,构建期做 295 条路由的预渲染。

真正让我把 AI开发 引入到日常工作流里的,是一个很朴素的判断:

如果每新增一个工具,边际成本能从"半天"压到"一小时",那 260 个就不是负担。

后来证明这个判断只对了一半。产出速度确实上去了,但犯错的速度也上去了——下面第三节那个 bug,就是 AI 用十分钟写出来的、我却排查了很久的代码。


二、AI开发 里的分工:先划清界限,再谈提效

我很快放弃了"让 AI 全权负责一个功能"的想法,改成明确分工:

环节 主导 理由
需求取舍、架构决策 人 只有人知道欠下的技术债要怎么还
单个工具的实现初稿 AI 模式固定,是典型的重复劳动
异常路径、边界情况 人提问,AI 补全 AI 默认只写"顺利路径"
并发、时序、缓存相关代码 人必须复核 AI 的高频出错区,见第三节
真机验证 人 AI 看不见运行时

这张表里最有价值的是倒数第二行。它听起来像句正确的废话,直到我为一个 75% 卡了很久。


三、案例一:P2P 文件传输,只有真机才暴露的三个坑

先说清楚这个功能在做什么:两个浏览器之间直接传文件,不经过服务器。数据通道用 WebRTC 的 DataChannel,信令由一个 Node 服务(ws,默认 8788 端口)转发,nginx 把 /p2p/ 反代过去。

做它的动机很直接:几百 MB 的文件走服务器中转,带宽成本扛不住;而且用户的私人文件本来就不该过我们的机器。

3.1 分片、落盘与断点续传

文件按固定大小切片后逐片发送,接收端不是拿到一片就写一次库,而是攒成一批再批量写入 IndexedDB,避免高频事务把主线程拖垮。

同时把文件的元信息(总分片数、名称、大小)也存进 IndexedDB。这样刷新页面虽然会丢掉连接和房间号,但分片还在,重新连上后可以接着传。

3.2 卡在 75%:一个"看起来完全没问题"的并发守卫

这是全过程中最值得讲的一个 bug。

批量写入的函数,AI 给的版本长这样:

async flushChunks() {
   
  if (this.recvFlushing || !this.recvBuffer.length) return   // 正在写就直接跳过
  this.recvFlushing = true
  const batch = this.recvBuffer
  this.recvBuffer = []
  await store.putChunks(batch)
  this.recvFlushing = false
}

读起来无懈可击:一个标准的互斥锁,防止并发事务互相打断。问题在于——跳过不等于完成。

真实的出错时序是这样的:

1. 第 4 片(最后一片)到达,此时前一批还在写库
   → flushChunks 开头命中 recvFlushing,直接 return,什么都没做
2. file-end 到达 → await this.flushChunks() → 又被跳过
3. 这时去数库里的分片数:只有 3 片 → 界面停在 3/4,也就是 75%
4. 兜底定时器稍后把第 4 片写进了库
   → 但没有任何代码再回头更新界面,75% 就永远停在那里

现象极其迷惑:发送端提示完成,接收端卡在 75%,刷新页面后又变成 100%。

原因就藏在最后那句里——库从头到尾都是对的(4 片都在),错的只是界面计数。所以刷新后按库重数,进度"莫名其妙"就恢复了。

如果只看代码,这个 bug 永远不会被发现。 它只在特定时序下触发,而时序恰恰是读代码时看不到的东西。

修复方式是把"跳过"改成"排队":

flushChunks() {
   
  const run = async () => {
   
    // while 而不是 if:写入期间新到的片也一并带走
    while (this.recvBuffer.length) {
   
      const batch = this.recvBuffer
      this.recvBuffer = []
      try {
   
        await store.putChunks(batch)
      } catch {
   
        this.errorMessage = '分片写入本地存储失败,可能是磁盘空间不足'
      }
    }
  }
  this._flushChain = (this._flushChain || Promise.resolve()).then(run)
  return this._flushChain
}

关键差异:并发调用不再被丢弃,而是排到正在写的那批后面等它写完再返回。这样 file-end 里的 await this.flushChunks() 拿到的 promise 必然涵盖所有积压分片,数出来的片数才是准的。

心得:AI 写并发代码时,习惯用布尔量做"互斥",但调用方真正需要的是"等待"。互斥只保证不重入,等待才保证顺序。这个区别在单测里看不出来,只有在真实时序下才暴露,而且暴露的形式(刷新后自己好了)会严重误导排查方向。

3.3 取消要双向同步,删除要真删

第二个坑来自交互设计:用户在发送端点"取消",接收端那条记录还挂着。

信令本身是通的(取消会发 file-cancel,对端收到后清 IndexedDB),缺的是移除条目——只把状态标成"已取消"留在列表里。

这比看起来更糟:半截文件既不能保存、缓存也已经被清了,条目却还显示着,会让人误以为"刷新后还能续传"。所以取消即移除,并且给一条明确提示。

还有个配套的坑:移除必须真的删 IndexedDB。只做数组过滤的话,刷新后它会被恢复逻辑又捞回来,用户会觉得"我明明删了怎么又出现了"。


四、案例二:30MB 的 wasm 该怎么放

视频处理依赖 ffmpeg.wasm。它的体积是:

文件 大小
ffmpeg-core.wasm 30.74 MB
ffmpeg-core.wasm.br 6.94 MB
ffmpeg-core.wasm.gz 9.81 MB

30MB 的静态资源,缓存策略一旦做错,要么用户每次访问都重下一次,要么旧版本被永久锁死在浏览器里。

采用的方案是版本目录 + 构建期注入:资源放在带版本号的目录里(public/ffmpeg/v0.12.15-0.12.10/),目录名由 @ffmpeg/ffmpeg 与 @ffmpeg/core 的版本号拼成。构建时读取 VERSION 文件,通过 DefinePlugin 注入前端:

// vue.config.js
ffmpegRuntimeDir = fs
  .readFileSync(path.join(__dirname, 'public', 'ffmpeg', 'VERSION'), 'utf8')
  .trim()
defs['process.env'].FFMPEG_RUNTIME_DIR = JSON.stringify(ffmpegRuntimeDir)

好处是:内容变了目录名就变。于是线上可以给 /ffmpeg/ 配一年的 immutable 强缓存,既不用牺牲缓存时长,也不会把旧版本锁死。

配套的一点:这么大的东西不能预加载,只有用户真的点"开始处理"时才去拉,工具页本身保持轻量。

心得:大资源的缓存问题,解法从来不是"不缓存"或"缩短缓存时间",而是让 URL 跟着内容变。这是非常经典的方案,但在几十 MB 的 wasm 上,收益被放大到不能忽视的程度。


五、案例三:260 个页面的预渲染与产物治理

SPA 对搜索引擎不友好,所以构建期做预渲染,295 条路由生成 260 个工具页目录和 64 个教程页。产物真实体积约 114 MB,其中 JS 48 MB、ffmpeg 资源 47 MB。

这里踩的坑不在构建本身,而在目录累积。

有次打包,产物比上一版小了 6 MB。第一反应是"是不是少了文件",查完才发现:上一版的 dist 是多次构建叠加出来的,里面还躺着旧版 ffmpeg 的平铺文件(结构改成版本目录之前的残留)。这次是删干净后全新构建的,所以变小了——变小反而是对的。

由此形成一个习惯:

  1. 构建前先清空 dist,杜绝残留
  2. 构建后核对 dist/tool-detail 目录数 与 sitemap 里的 URL 条数是否 1:1
  3. 顺带扫一遍有没有异常小的页面文件(小于 500B 基本就是预渲染失败了)

这三步做完,交付前的焦虑感会少很多。


六、部署环节:反向代理与阿里云AI运维

P2P 的信令服务是这套系统里最容易被部署搞坏的一环,因为 WebSocket 必须显式处理协议升级:

location /p2p/ {
   
    proxy_pass http://127.0.0.1:8788/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

漏掉那两行 Upgrade 头,表现是 WebSocket 握手失败、房间永远连不上,但页面看上去一切正常——这种"半死不活"的故障最难排查。

再就是路由白名单:新工具页上线时如果没同步进 nginx 的白名单配置,访问就是 404,而本地开发完全测不出来。

在阿里云AI运维这一侧,我把两件事固化进了流程:

  • 发布后核对:用脚本对比线上页面数与本地产物,避免上传中断导致的部分更新
  • 日志排查:把 nginx 访问日志和错误日志的片段交给 AI 做模式归纳,定位 502、慢请求和异常爬虫

第二点的性价比意外地高。运维数据都是已经发生的客观记录,AI 擅长从大量文本里找模式,而人看日志看到第三屏就开始疲劳漏看了。

一个必须守住的底线:喂给 AI 之前先脱敏,IP、token、用户数据一律先处理掉。这是用 AI 做运维的先决条件,不是可选项。


七、AI开发 的四条经验:边界在哪里

回顾整个过程,真正让我少踩坑的是这四条:

1. 先让 AI 讲清思路,再让它写代码。
如果它说不清"为什么这样设计",那份代码大概率是按模式拼出来的。讲不清思路的实现,往往也经不起边界推敲。

2. 主动索要边界清单。
每个功能交付时多问一句:"哪些情况下它会出错?" AI 的默认输出只包含顺利路径,异常路径要靠提问才拿得到。

3. 并发、时序、缓存这三类代码必须自己逐行复核。
这是 AI 目前最高频的出错区。原因也合理:它看到的是代码的局部,而 bug 发生在运行的时序里。第三节那个 75%,就是典型。

4. 验证环节不能交给 AI。
它看不到运行时。真实网络、真实磁盘、用户真实的刷新时机——这些只能靠实测。

还有一条更根本的体会:

AI 最大的价值,不是让我少思考,而是让我更快走到"犯错"那一步。

以前写一个功能要半天,错一次的代价太大,于是倾向于保守;现在十分钟能出一版,我可以更快犯错、更快纠正,迭代密度本身就是收益。前提是——省下来的时间要拿去做判断,而不是拿去产出更多没经过验证的代码。


八、写在最后

3Q工具箱 现在有 260 个工具、64 篇教程,这个规模在 AI 协作下是可持续的,但它从来不是"把需求丢进去、把代码拿出来"那么简单。

真正决定产出质量的,始终是那些 AI 给不了的东西:这个功能该不该做、这个方案在极端情况下会怎样、这个取舍对三个月后的维护意味着什么。

如果你的项目也在用 AI 辅助开发,希望你踩的坑比我少一些;如果已经踩了,也希望这篇能帮你少排查几个小时。

更重要的是——别只把它当成一个提效工具。当你能用十分钟验证一个想法时,那些以前因为"太麻烦"而放弃的、更有趣的技术尝试,其实都重新变得可行了。

目录
相关文章
|
4天前
|
人工智能 运维 小程序
1人搞定17家企业年做200万:不裸辞先接单的“AI落地商人“
本文是「OPC一人公司通关手册」第33篇,聚焦AI落地新蓝海:当大模型过剩,真正稀缺的是“把AI装进业务”的前线部署工程师(FDE)。98年北京小伙不裸辞、先接单,一人调度4-5个AI智能体,2025年服务17家企业、实现200万业绩——验证了“先有项目、后有公司”的OPC最稳路径。(239字)
|
9天前
|
人工智能 API 开发者
AI改作文月入近5万:95后解散4人团队单干,一人公司深度拆解
本文是「OPC一人公司通关手册」第28篇,深度拆解一位95后双学位创业者的真实案例:他解散4人团队,用AI打造垂直作文批改工具,专注K12语文/英语老师刚需,注册用户超2万,付费率13–14%(行业均值10%),月入近5万。核心启示:AI不是辅助,而是替代执行层;一人公司的胜负手,在于“细分切口+订阅模式+极简成本”。
|
28天前
|
人工智能 自然语言处理 API
觉得阿里云大模型价格太高怎么办?四种便宜购买与使用方法分享
本文针对阿里云大模型“能力强但调用成本高”的普遍痛点,梳理了一套可落地的全链路省钱方案。从开通百炼领取超7000万Tokens新人免费额度起步,叠加夜间错峰4折起的Night Plan活动,再搭配Token Plan订阅与AI通用型节省计划,四层优惠叠加后,实际调用成本可降至普通按量付费的三到五成,帮助个人开发者与团队大幅降低大模型落地的综合开支。
457 12
|
1月前
|
Web App开发 JavaScript Windows
【bug反馈】Qoder 浏览器连接器(Windows)侧边栏持续显示"未发现客户端"(内有详细原因和修复方案)
Qoder浏览器连接器在Windows上因Chrome调用`.cmd`宿主时无控制台导致通信失败,表现为“未发现客户端”。根本原因是`cmd.exe`在无控制台+管道重定向下无法执行。建议改用console子系统shim进程直启主程序。
413 2
|
1月前
|
缓存 人工智能 索引
你的 AI 每周都在重发同一段历史——Hermes 省 token 实战:9 个开关,缓存开销砍三成
一周 6.54 亿 tokens,88% 是重复发送的历史。这篇文章拆解 Hermes 省 token 的 9 个配置开关:压缩触发点为什么必须钉成绝对值、三条命令怎么测、改完怎么验证真生效,以及一个少有人说的真相——省 token 和省钱不是一回事。附按模型窗口分档的参数表和一条命令回滚。
159 0
|
3月前
|
人工智能
2026 GOAI 世界人工智能开源大赛—新智基座 Agent Infra 赛道正式启动! ¥190万总奖池等你挑战!
2026 GOAI 世界人工智能开源大赛—新智基座 Agent Infra 赛道正式启动!¥190万总奖池等你挑战!
1813 10
|
6月前
|
JSON API 数据格式
Python 1688 拍立淘搜索 API 系列:JSON 数据反馈全解析
1688 拍立淘(item_search_img)是电商开发者高频使用的以图搜货 API,通过图片 URL/Base64 快速匹配同款 / 相似商品,返回标准化 JSON 结构。本文从接口调用、JSON 结构、字段解析、Python 实战、异常处理、数据应用全链路讲解,帮你彻底掌握 1688 拍立淘 API 的 JSON 数据反馈与处理。
|
机器学习/深度学习 负载均衡 数据可视化
性能比肩最强开源,QwQ-32B一键部署,百万Token免费送!
本文介绍如何通过百炼平台调用QwQ-32B开源模型。百炼平台提供的标准化 API 接口,免去了自行构建模型服务基础设施的麻烦,并支持负载均衡及自动扩缩容,确保了 API 调用的高稳定性。此外,结合使用 Chatbox 可视化界面客户端,用户无需进行命令行操作,即可通过直观的图形界面轻松完成 QwQ 模型的配置与使用。
|
安全 关系型数据库 文件存储
Websoft9 服务器面板中 Odoo 安装与群晖 NAS 的对比
传统部署Odoo面临基础设施搭建、镜像供应链、复杂配置及运维监控四大难题,而群晖NAS方案存在Docker依赖、插件更新滞后和配置自由度低的局限。Websoft9提供开箱即用的解决方案:无需预装Docker,三键式安装支持全版本Odoo;具备企业级扩展功能如负载均衡与集群部署;兼容混合云架构,支持公有云、私有云及边缘设备管理;同时确保合规性,自动扫描漏洞并生成修复报告,大幅提升部署效率与系统安全性。