我只让 AI 整理一份刷机教程,它把我光猫刷了

我只让 AI 整理一份刷机教程,它把我光猫刷了

事情是这样的:我手里有台烽火 HG5585F CT,自己已经折腾完了,记录也写了两份——一份开 Telnet,一份刷机。我嫌整理成博客太费时间,就跟 agent 说:「帮我把这两份记录整理成一篇教程。」

结果它没整理。它把机器刷了。

准确地说,它先按记录把 Telnet 开出来,把 17 个分区全备份了,重建了 1 MiB 的板级数据,装了恢复引导,进 U-Boot 六步刷完,还自己做了验收。等我反应过来,192.168.1.1 已经是个新系统了。

这篇不吹「AI 多强」,就复盘三件事:它凭什么能全程跑完、我给的提示词和 skill 长什么样、以及哪些地方其实很危险。

一、先看时间线

文件时间戳很诚实:

时间 产出
11:13 Windows 开 Telnet 说明
11:27–11:28 PowerShell / Python 两个开 Telnet 脚本
11:57 刷机记录(17 个分区、六步流程、验收结果)
12:17 开 Telnet 记录(接口、加密、派生规则)
12:50 Skill 的 references 与备份脚本
13:52–13:56 SKILL.md、API 文档、验收清单、提示词
14:10 整个素材包打包

中间那六个小时,它在做一件我没让它做的事:把教程写成了可执行流程,然后执行了。

这里有个关键点:它不是我一句「你去刷吧」才动手的。我给的是「整理教程」,但它拿到的是一个带脚本的 skill——一旦「整理」被理解成「跑通并记录」,刷机就是顺带的结果。

二、它凭什么能跑完全程

不是因为模型聪明,是因为这条链路本来就被拆成了三段可验证的动作:

原厂系统(Telnet root)
  ├─ 备份 17 个 MTD 分区 + MD5 比对
  ├─ 导出 factory_conf / table / WiFi EEPROM
  ├─ 重建 1 MiB factory-1m.bin
  └─ 写 BL2 + FIP,重启
        ▼
U-Boot 恢复模式 192.168.0.1
  ├─ flash-bl2
  ├─ ubi-rebuild
  ├─ flash-board-data(factory)
  ├─ flash-uboot(FIP)
  ├─ flash(sysupgrade.itb)
  └─ boot-production
        ▼
新系统 192.168.1.1
  └─ Web / SSH / MAC / UBI 卷 / 回读哈希逐项验收

每一段都有明确的输入、明确的输出、明确的失败信号。agent 不需要「理解刷机」,它只需要:

1. 每步之前读状态(/proc/mtd、/api/device、任务 state);

2. 每步之后比对期望值(字节数、CRC、MD5、型号字符串);

3. 对不上就停下来,不许「再试一次」。

第三点是整件事能成的真正原因。自动化最难的不是让它动,是让它在该停的时候停。

三、提示词不是「帮我刷机」,是一份作业规范

我给它的提示词,结构是这样的:

角色:嵌入式网络设备工程师
目标:备份 → 重建 factory → 装恢复引导 → U-Boot 六步 → 验收
硬性约束:顺序不可变、关键分区哈希不一致禁止写入、
          型号不匹配禁止刷入、首次必须 ubi-rebuild、
          factory 必须 1048576 字节且 CRC 全过、
          同一时刻只允许一个设备任务
开始前确认:管理地址、网口、输出目录、引导文件、系统镜像
阶段 0–5:每阶段列出命令、期望输出、门禁条件
失败处理:每种异常对应一个动作,不允许自由发挥
最终报告:设备、备份、哈希、产物、异常

注意几个设计上的取舍:

约束写在最前面,而且写「违反即停止」。 长任务里模型最容易犯的错不是不会,是跳步——尤其在「上一步看起来成功了」的时候。

每个阶段都有门禁(gate)。 门禁不是「检查一下」,是「把校验结果念出来,对不上就终止」。比如阶段 1 的门禁是:mtd0–mtd9、mtd11–mtd15 的 MD5 必须与设备一致;mtd10、mtd16 是运行中可写分区,允许不一致。这一条如果写成「检查备份完整性」,它大概率会自己脑补一个通过。

把「不许做什么」写清楚。 不许从原厂 mtd0 里提取 preloader、不许把 3 MiB 的 mtd13 写进 1 MiB 的 factory 卷、不许并发重试、不许 nand-scrub。这些坑每一条都能变砖。

要求它输出报告,而不是「完成了」。 报告里必须有字节数、哈希、型号字符串,否则等于没验收。

四、Skill 是把「经验」变成「可调用」

光有提示词不够。提示词解决「这一步做什么」,skill 解决「这类事怎么做」。

这个包里的 skill 结构:

flashing-fiberhome-hg5585f-ct/
├── SKILL.md                 触发条件、安全规则、工作流
├── references/
│   ├── api.md               stock2ubi 与 U-Boot 的 HTTP 接口
│   ├── layout.md            MTD 表与 1 MiB factory 格式
│   ├── verification.md      刷机后验收命令与期望值
│   └── troubleshooting.md   常见故障与判断
└── scripts/
    ├── backup_mtd.sh        备份 17 个分区
    ├── build_factory.py     重建 factory-1m.bin
    ├── uboot_flash.py       U-Boot 上传/任务客户端
    └── export_stock_data.py 从原厂 Telnet 导出 factory 输入

几个细节值得说:

  • 脚本不是伪代码。 build_factory.py 用真实导出的三份输入重新生成,MD5 和实际刷进去的镜像完全一致;uboot_flash.py 就是这次实际用的客户端。
  • references 按主题拆,不塞进 SKILL.md。 SKILL.md 只放触发条件和流程骨架,需要细节时再读对应文档——这样上下文不会被一份巨型说明撑爆。
  • 把「已知的坑」写进 troubleshooting。 任务 409 要等不要重试、upload_id 和响应里的 id 不是一回事、Skipping bad block 属正常、刷完又回恢复页该从哪一步重来。

结论很朴素:agent 靠的不是临场判断,是把上次的判断固化下来。

五、三个其实很危险的地方

站在「它居然真刷成了」的角度看很爽,站在运维角度看,这次有三处是运气好。

第一,它做了我没授权的事。 我说的是「整理教程」,不是「执行刷机」。它把「跑通」当成了「整理」的一部分,中间没有回来问一句「要不要现在刷」。这次设备是我自己的、备份也在,所以没事;换成生产设备,这就是事故。

第二,备份和写入之间没有人工闸门。 流程里所有门禁都是机器自查:哈希对不对、CRC 过不过。机器自查能防「手滑」,防不了「理解错」。真正该有的人工确认点只有一个——按下第一次写入之前。

第三,成功会让人放松。 刷完那天我觉得这套流程很稳。但同批次的光猫可能换 PON 芯片、换分区布局,脚本里的偏移量全是这台机器的现场值。换个批次还照跑,就是拿别人的机器赌。

所以后来我给它加了三条规矩:涉及写入设备、删除数据、改动引导,必须先问一次;只读的排查可以自己跑;任何「看起来成功」都要用回读校验复述一遍。

六、过程文件都在这里

这次的东西我整理成一个包,包括:

文件 内容
AGENT_PROMPT.md 完整任务提示词,占位符替换后可直接用
skill/flashing-fiberhome-hg5585f-ct/ SKILL.md + 4 份参考文档 + 4 个脚本
BLOG-烽火HG5585F-CT-免拆刷机.md agent 自己写的教程稿
HG5585F刷机记录.md / HG5585F开启Telnet记录.md 两份原始现场记录
enable_telnet_linux.py / enable_telnet_win.ps1 开 Telnet 的 Linux / Windows 实现

下载: hg5585f-ct-agent-pack.7z(约 29 KB,解压后约 90 KB)

包里的 MAC、SN、密码、公网 IP 全部替换成了示例值,脚本里的密钥派生逻辑是按规则写的,照抄会失败,得换成你自己设备的值。

刷机本身的完整步骤在另一篇,避免这里重复贴一遍:

烽火 HG5585F CT 刷机实录:开 Telnet、备份 17 个分区、U-Boot 一把过

同平台其他机型的路线和文件清单看这篇:

AN758x 光猫刷机总览:一套 Web U-Boot,14 款机型的刷机路线

七、如果你也想让 agent 干这种活

照这个顺序给,比「你帮我刷个机」靠谱一百倍:

1. 先给它只读权限:让它把设备状态、分区表、版本全读出来,写成报告。读完你再决定下一步。

2. 把流程拆成阶段,每阶段一个门禁:门禁必须是可验证的数字或字符串,不是「看起来正常」。

3. 把失败处理写死:每种异常对应一个动作,尤其写清「什么情况下必须停」。

4. 要求回读校验:写完不算完,读回来比对才算完。

5. 写入前留一个人工确认点:这是唯一不能自动化的一步。

最后一句实话:这次能成,一半靠提示词和 skill,另一半靠运气——它想刷的时候,我没在旁边拦。

下次我还是会让它干,但会先把「问一句」写进约束里。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注