我用 AI 给 CNB 仓库造了个 NPC,踩了一路坑
背景:什么是 CNB NPC?
先解释几个名词。
CNB(Cloud Native Build,腾讯云原生构建平台)是一个类似 GitHub 的代码托管平台,但它有一个很酷的功能:你可以在仓库里放一个 NPC。
NPC 这个词来自游戏——Non-Player Character,非玩家角色。在 CNB 里,NPC 就是你仓库中的一个 AI 助手。你在 Issue 或 PR(Pull Request,合并请求)里 @它,它就会自动读取你的代码、跑测试、分析结果,然后回复你。
我的项目叫 lighthouse_audit,目标是让 NPC 自动对网站做 Lighthouse 审计(Google 的网页性能检测工具),然后把报告上传到 Issue 里。
听起来很酷对吧?实际做下来,我踩了一路坑。
坑一:NPC 镜像和插件镜像搞混了
镜像混淆经过
我的仓库里有两个 Dockerfile:
- 根目录的
Dockerfile:NPC 运行时镜像(有 CNB CLI、skills 框架等) plugin/Dockerfile:Lighthouse 插件镜像(只有 Chromium + Lighthouse)
我一开始搞混了,把 plugin/Dockerfile 构建推送上去当 NPC 镜像用。
坑一修复
PR #18 拆分了两个镜像的职责:
- 根目录 Dockerfile:只管 NPC 运行时(接收评论、调用 skills、回复结果)
- plugin/Dockerfile:只管 Lighthouse 测试(装 Chromium、跑审计、输出报告)
💡 教训:一个镜像只干一件事。NPC 镜像 ≠ 测试工具镜像。
坑二:AI “固执己见”,重复安装 Lighthouse
这是最贵的一个坑。
AI 重复安装经过
我的设计是分两步走:
- Stage 0(构建阶段):在容器里跑 Lighthouse,生成报告
- NPC 分析阶段:AI 读取已有的报告,分析后回复 Issue
但 AI 不知道报告已经生成好了。它收到”请分析性能”的指令后,自己又 npm install -g lighthouse 装了一遍,然后重新跑测试。
数据触目惊心
| 构建记录 | AI 行为 | 耗时 |
|---|---|---|
| cnb-j6o-… | 安装 1 次 | 142 秒 |
| cnb-moo-… | 安装 1 次 | 324 秒 |
| cnb-8pg-… | 安装 lighthouse + puppeteer + chromium | 304 秒 |
| cnb-6ro-… | 反复安装 5 次 ⚠️ | 763 秒(12.7 分钟) |
| cnb-3jo-… | puppeteer + lighthouse + apt chromium | 237 秒 |
6 次构建里有重复安装,最离谱的一次装了 12 分钟。
根因
NPC 的 prompt(提示词)没有明确告诉 AI:”报告已经在 lighthouse-report/ 目录里了,你只需要读取分析,不要重新运行测试。”
坑二修复
修改 NPC prompt,写死产物路径:
你只需要读取 lighthouse-report/ 目录下的报告文件,进行分析后回复。
严禁重新安装或运行 Lighthouse 测试——这一步已经在构建阶段完成了。
💡 教训:Prompt 是 NPC 的灵魂。你不说清楚,AI 就会”自由发挥”——而自由发挥是要烧钱的。
坑三:文件上传,10 次提交的血泪史
看 git log,main 分支上只有 10 个 commit,全部在同一天(06-02),全部围绕同一个功能:把 Lighthouse 报告上传到 Issue。
2026-06-02 2f9dbda3 fix: 更新上传逻辑以支持 Issue 和 PR 事件的文件上传
2026-06-02 2d4fe22b feat: 重构上传测试报告逻辑,新增脚本处理文件上传
2026-06-02 0d828b33 refactor: 简化文件上传,移除冗余代码
2026-06-02 25de4b7a fix: 修正上传测试报告脚本路径 ← 路径错了
2026-06-02 e5185292 chore: 优化上传测试报告脚本路径逻辑 ← 还是错
2026-06-02 1cee5b3e feat: 新增上传报告脚本并优化上传逻辑 ← 换方案
2026-06-02 68ccba8a feat: 更新上传脚本为 upload-report.sh
2026-06-02 9189ef95 feat: 替换为动态下载 upload-report.sh
2026-06-02 a818d8ac feat: 移除脚本内联,添加 Dockerfile
2026-06-02 52879c2f fix: 修正镜像路径为正确的仓库名称 ← 又错了
脚本放置方案变了 3 次
- 内联在构建脚本里 → 太长,不好维护
- 外部脚本文件 → 容器里找不到路径
- 运行时动态下载 → URL 也不对
- 放进 Dockerfile → 最终方案
路径错误 × 3
容器内的路径和仓库路径是不一样的。你在本地看是 ./scripts/upload.sh,在容器里可能变成 /workspace/.cnb/scripts/upload.sh。这个坑我踩了 3 次。
还有一堆 [skip ci]
7 个 commit 加了 [skip ci]——因为我意识到每次 push 都会触发构建,光调路径就烧了好几次构建额度。
💡 教训:文件上传看似简单,但在 CI/CD 容器环境里,路径、权限、脚本位置每个都是坑。先在本地验证,再推到 CI。
坑四:Token 权限不够,白跑一趟
NPC 尝试读取构建日志来定位问题,结果返回:
当前 Token 缺少 repo-cnb-trigger:r 权限,无法通过 API 获取构建日志
NPC 瞎猜了一通,分析结果全错。
坑四修复
提前配齐 Token 权限:
repo-cnb-trigger:r:读取构建触发信息repo-cnb-history:r:读取构建历史和日志
💡 教训:权限配置是基础设施,不是”到时候再说”的事。
坑五:Credits 爆炸 💸
来算一笔账:
| 事项 | 消耗 |
|---|---|
| #21 第 1 次分析(读构建日志) | 76.4 credits(¥3.8) |
| #21 第 2 次分析(读完整日志) | 188.5 credits(¥9.4) |
| #19 上传测试 × 13 次触发 | 26.6+ credits |
| #20 E2E 测试 | 34.4 credits |
仅”AI 固执己见”这一个坑,两次分析就烧了 ¥13。原因是 CodeBuddy 读取了 120 万+ tokens 的构建日志。
省钱心得
- Prompt 写清楚:别让 AI 自己猜,猜就是烧钱
- 用
[skip ci]:调试阶段的 commit 别触发构建 - 控制触发频率:别像我一样 Issue 里触发 13 次
- 精简日志输出:AI 读的日志越短,花的 tokens 越少
最终方案:PR #22 NPC 驱动重构
踩完所有坑后,我开了 PR #22 做了一次系统性重构:
- 镜像分离:NPC 镜像只管调度,Lighthouse 镜像只管测试
- Prompt 重写:明确告诉 AI 产物在哪、不要重复操作
- 上传逻辑封装:统一用
upload-report.sh,路径写死 - 权限预配置:Token 权限一次性配齐
时间线总览
05-27~29 基础搭建
├─ 镜像混淆 → Issue #17 对比 dockerfile 才发现
├─ 流水线重复执行 → Issue #14
└─ AI 重复安装 Lighthouse → Issue #21(最贵的坑)
06-01 权限调整
└─ Token 权限不足 → NPC 瞎分析
06-02 文件上传攻坚
└─ 10 个 commit,路径错 × 3,方案改 × 3
06-04 系统重构
└─ PR #22:把所有教训整合成新架构
06-05 开源上架
└─ FunASR 插件注册到 CNB 插件市场 opensource 目录(PR #740)
└─ 最终选择不带 mark 字段,留空即可
给后来者的建议
- 一个镜像干一件事:别把工具和运行时塞一起
- Prompt 是核心:NPC 的行为 90% 取决于你怎么写 prompt
- 路径!路径!路径!:容器内路径 ≠ 本地路径,提前验证
- 权限先配好:别等报错才发现 Token 权限不够
- [skip ci] 是你的好朋友:调试阶段别浪费构建额度
- 先本地验证,再推 CI:别在 CI 上调脚本路径
这个项目仓库在 xzzlwl/lighthouse_audit,欢迎围观。