非技术背景做 Vibe Coding,我踩过的最大坑是 API Key 泄露
一位运营出身的 vibe coder 复盘自己一把 3 月创建的 DeepSeek Key,从 8 月 23 日起被连续盗用一个整月(¥80.58 / 1,752 次请求 / 1.07 亿 token)的全过程:真正的问题不是「谁偷的」,而是「这把 Key 为什么会出现在本机的 22 个文件里」——AI 把「能跑通」当成了唯一目标,没人告诉它什么东西不能到处放。
基本信息
- 来源类型:文章(人人都是产品经理 · 作者「张亮-leo」,微信公众号「张记杂货铺」)
- 原文位置:
raw/articles/2026-09-24-093247-tg-94c8dc.md - 原文 URL:https://www.woshipm.com/ai/6469237.html
- 原文正文来源:
scripts/http_capture.py抓取的预取正文(raw 内嵌 Prefetched Article Content) - 消化日期:2026-09-24
- 作者背景:《从零开始做运营》作者、张记杂货铺铺主,131 篇作品、245 万+ 总阅读量;自述「做运营的,刚接触开发」,2026 年 3 月才开始 vibe coding
核心观点
-
事故的真实形状:Key 在 22 个文件里,任何一处外流都够喝一壶:作者按 Key 字符串全盘扫描本机项目目录,找到 22 个命中文件并归为 7 类藏法——① 代码里的 fallback(
process.env.DEEPSEEK_API_Key || 'sk-a559a…',源码一份、编译产物又一份);② 各种.env(开发/生产/服务端,每个项目各一份);③.env.example里放的却是真 Key;④ 部署脚本和docker-compose(一个脚本里 3 处明文);⑤ 测试文件里写死的测试桩;⑥ 文档 7 份(修复报告、部署总结、测试计划、手动部署指南……全部原样粘贴);⑦ AI 工具的项目记忆——它把 Key 当成「需要记住的信息」记下来了。另外还有一个仓库连.gitignore都没有,另一个仓库的.gitignore只忽略了.env、漏掉了.env.production。「一把 Key 躺在 22 个地方,其中任何一个外流,都够我吃一壶的。」 -
归因不是「AI 做错了」,而是「没人告诉它不能到处放」:作者的判断是——它每一步都没做错,都是在认真完成交代的任务。AI 让服务跑通最省事的做法就是在代码里给 Key 写一个 fallback 保证不报错;让它写部署文档,它把能跑通的完整命令连 Key 一起抄进去;让它写测试报告,它把「用的是哪把 Key」当成有用信息写进去。真正的问题是:没人给它「这个东西不能到处放」的约束——连作者自己当时也没这个意识。 所以这是开发过程中的卫生问题,不是事故定性问题,但对非技术背景的 vibe coder 几乎必然复现。
-
泄露发生了但溯源几乎不可能——所以防御点必须前移:作者回忆不出泄露路径(部署用的那台服务器早已到期注销),最后只能接受「天知地知我不知道」。这也解释了为什么事后排查价值有限:当同一把 Key 出现在 22 个位置时,溯源问题已经退化成「猜哪一个先漏」,唯一可执行的策略是不让它出现在第 2 个位置。
-
成本失控的真正原因是「掩体」而不是「盗用者的胆量」:盗用者是渐进的——一开始每天只几毛钱,发现没人管就逐步加大;而作者之所以一个月都没发现,是因为同期时间线撞在一起:自己也进了产品内测(本来就有消耗)、邀测开放后更多人体验、加上 DeepSeek 涨价——三重噪音把异常用量盖住了。直到 9 月 22 日邀测结束、按道理不该再有消耗,却看到「早上还用掉了 7 块钱」,才顺藤摸瓜发现有一把 3 月 16 日创建、6 月已在关停服务器上「应该早就偃旗息鼓」的 Key 从 8 月 23 日起每天都在被调用,一天都没断过。最终账单:8/23–9/22 消耗 ¥80.58、1,752 次请求、1.07 亿 tokens(作者原话吐槽:「这特么是 DeepSeek!」)。
-
止损动作本身有优先级:先撤销,再排查:作者复盘里明确点出自己犯的操作错误——发现异常时先排查、没先撤销 Key,结果「上午烧了 7 块,下午排查继续烧了 2 块」。这给出一个很具体的顺序结论:异常发现后的第一动作是吊销凭证(止血),排查是第二动作。
-
关键背景是「vibe coding 把安全习惯挤出了工作流」:评论区高赞(「别叫我静姐」)补充了一个反方视角——认可「AI 只是完成指令」这个判断,但主流 AI coding 工具基本都有敏感信息拦截提醒,作者全程没触发过一次,要么用得太早期、要么当时光盯着「跑通」结果、连工具警告都忽略了;做运营出身对线上服务的安全基线其实是有感知的,只是 vibe coding 时把「先跑通」优先级放得太高,把安全习惯直接丢了。这条评论把病因从「AI 的锅」进一步推到「人在新工作流里丢掉了旧纪律」。
实操内容保留
代码/配置
原文给出的反面样例(以下为泄露形态,切勿照抄):
# ❌ fallback 写死真 Key:环境变量没配就用真 Key 顶上
process.env.DEEPSEEK_API_Key || 'sk-a559a…'
# ❌ .gitignore 只忽略了一个后缀
.env # .env.production / .env.development 全部泄漏
对应的正确形态(依据作者 8 条建议归纳):
# ✅ .gitignore:所有 .env* 都要忽略
.env
.env.*
*.env
# ✅ .env.example:只放占位符,不放真值
DEEPSEEK_API_KEY=sk-your-key-here
Prompt 模板
(本文无 Prompt 模板)
操作步骤
作者把「用真金白银换来的」8 条止损纪律完整列出,按其原始顺序保留:
- 一个项目一把 Key:不要舍不得写完整的名字,比如写成「项目名-环境-云服务商」——出了问题,看名字就知道去哪找。
- API Key 只放在环境变量里,代码里不留 fallback:「少了无所谓,报错呗。报错好,能报错,比悄悄用上一把真 Key、然后被别人拿去薅要好 1000 倍。」
- 新建仓库,第一件事是写
.gitignore:所有.env*都要忽略,不只是.env。 .env.example里只放占位符。- 不把 Key 贴进任何对话框:AI 会记住,会写进它的笔记和文档里,而你不知道它最后会藏在哪儿。
- 设消费限额:被盗用的时候,限额就是止损线。
- 项目或服务器下线时,顺手作废它用过的 Key:这次就是「服务器没了,Key 还活着」。
- 发现异常,先把 Key 撤销掉:本次教训是「先排查没撤销——上午烧了 7 块,下午排查继续烧了 2 块」。
排查方法(可复用):
- 先看云服务后台用量/账单:确认「按道理不该有消耗的时间段」是否仍在产生费用。
- 定位是哪把 Key:核对创建时间与近 30 天调用曲线,找出与已知业务不匹配的那一把。
- 从部署平台(如 Railway)翻各项目环境变量,逐项排除。
- 排除不掉时做本机全盘扫描:遍历所有项目目录,按 Key 字符串全文搜索,把命中文件分类(代码 fallback /
.env/.env.example/ 部署脚本与 docker-compose / 测试文件 / 文档 / AI 工具项目记忆)。
关键概念
- API Key 泄露 — 本文的主题概念,本批新建实体页:密钥多副本扩散 → 被薅 → 靠限额与吊销止损的完整链路
- Vibe Coding — 本文的语境本体:不写代码、用自然语言驱动 AI 完成开发;本文补上这套范式长期缺席的一环——非技术背景使用者的凭证与安全卫生
- DeepSeek — 本次被滥用的 Key 所属服务商;作者特别强调「这特么是 DeepSeek」,即 80 元在低价模型上意味着 1.07 亿 token 的异常调用量
- Token经济 — 「80 元 = 1,752 次请求 = 1.07 亿 token」提供了一组具体单价换算,可作为判断「账单是否异常」的量级参照
- AI产品成本核算 — 本文给出成本失控的一个非典型成因:消耗本身不异常,异常被正常业务的增长噪音(内测 + 涨价 + 用户变多)掩盖
- BYOK — 「一把 Key 在 22 个地方」是 BYOK(自备密钥)模式下最典型的失败形态:密钥进入代码、文档与 AI 记忆等非授权载体
- Token中转站 — 对照面:自建中转/代理是「密钥不落在业务代码里」的一种工程解法,与本文的「Key 只放环境变量」属同一条防线
- 产品经理AI工具选型 — 与本文同源命题「算账要按真实任务算」,本文补上被忽略的一项成本:凭证泄露的尾部风险(原文未点名该框架,属本页汇整时的关联)
- AI幻觉 — 本文的 AI 记忆把 Key 当「需要记住的信息」记下,是敏感信息被当成知识沉淀的典型场景
与其他素材的关联
- 与 2026-07-23-woshipm-ai-token-cost-six-tips 的关系:那篇讲 Token 定价/计费机制(怎么让成本可预期),本文讲成本失控的另一种路径——不是定价贵,而是有人在用别人的钱跑自己的调用;两者合起来才是完整的「AI 成本管理」问题面。
- 与 2026-07-23-woshipm-vibe-coding-system-pitfalls 的关系:那篇系统梳理 vibe coding 的工程坑(架构/上下文/验证),本文补上一个非技术使用者最容易漏掉的坑——凭证卫生,且这个坑的代价是钱和账号安全,不是代码质量。
- 与 2026-06-26-vibe-coding-to-vibe-using 的关系:从「vibe coding(让人把东西做出来)」到「vibe using(让人把东西用对)」的推进中,本文是最硬的一课——做出来之后,运行期资产(Key、服务器、账单)的治理义务落在真人身上。
- 与 2026-07-08-woshipm-ai-coding-harness 的关系:harness 层负责上下文、记忆、工具与技能,AI 工具的项目记忆正是其中一环;本文说明这个记忆若不做敏感信息过滤,会把密钥固化成「知识」长期留存。
- 与 2026-05-27-pm-vibe-coding-5-products 的关系:那篇是 vibe coding 的成功叙事(5 个产品、没亲手敲代码),本文给出同一路径的对称风险叙事——不写代码的人同样要承担不写代码所带来的安全债。
原文精彩摘录
这把 Key 是 3 月 16 日创建的。3 月、4 月、5 月有零星的调用,这些我有印象,因为我当时把这把 Key 用在了好些地方:又是监控任务,又是视频转文字,又是写作工具的。但是 6 月,我已经把服务器关停注销了。按道理,这把 Key 早就应该偃旗息鼓才是。结果,我发现从 8 月 23 日开始,它每天都在被调用,一天都没断过。
结果是找到了 22 个文件。我把它们分了一下类,你看看有没有眼熟的:代码里的 fallback……各种 .env 文件…….env.example:这个文件本来是给别人看格式用的样例,里面放的却是真 Key……文档:修复报告、部署总结、测试计划、手动部署指南,一共 7 份,全都把 Key 原样贴了进去。AI 工具的项目记忆:它把 Key 当成「需要记住的信息」记下来了。
我冷静下来,开始拼图:3 月份我刚开始接触 vibe coding,那时候我的注意力全在一件事上:能不能跑起来?AI 也一样。你让它把服务跑通,它最省事的做法,就是在代码里给 Key 写一个 fallback,保证不报错;你让它写部署文档,它就把能跑通的完整命令抄进去,Key 也跟着进去了;你让它写测试报告,它会把「用的是哪把 Key」当成一个有用的信息写上。**它每一步都没做错,都是在认真完成我交代的任务。**问题是:没人告诉它「这个东西不能到处放」——连我自己当时也没这个意识。
API Key 只放在环境变量里,代码里不留 fallback:少了无所谓,报错呗。报错好,能报错,比悄悄用上一把真 Key、然后被别人拿去薅要好 1000 倍。
先说一下损失吧:8 月 23 日到 9 月 22 日,一共消耗了 80 块人民币。这特么是 DeepSeek!