最近一直在折腾 RISC-V AI 方向的东西。手上没有真正的开发板,又想验证一条指令、一个算子、甚至一套软件栈能不能在目标芯片上跑通,最后的落点基本都会指向 QEMU。但 QEMU 环境搭建这件事,说简单也简单,说麻烦是真麻烦——交叉工具链、链接脚本、启动流程、rootfs、QEMU 启动参数,任何一个环节出问题,后面全线卡住。这次我试着把整个搭建过程丢给一个 AGENT 来干,让它去读文档、写脚本、跑命令、自己看报错然后改,最后在模拟器里拉起了一块可供 RISC-V AI 芯片做实验的"实验台"。
这篇文章就把整个过程拆开聊一聊:我是怎么设计任务的、AGENT 实际做了哪些事、在哪些地方翻车了、最后怎么救回来的。如果你也想用 AI Agent 帮你搞环境搭建,或者正在纠结怎么在 QEMU 上跑 RISC-V 的 Linux 和 PyTorch,这篇应该能给你一些可以直接抄的思路。
1. 为什么我会把环境搭建整个丢给 AGENT
1.1 从"配置地狱"说起
做 RISC-V 开发环境的人应该都有过这种体验:网上教程一大把,但每一篇的QEMU版本、工具链版本、内核版本都不一样。照着 A 教程配好了工具链,B 教程的启动参数又在 qemu-system-riscv64 上报错"Unsupported machine type"。最难受的是,报错信息往往根本看不懂——它不是告诉你哪一步错了,而是让你自己去理解 QEMU 内部对设备树的解析逻辑。
我之前搭过一次,折腾了整整两个晚上。第二天的状态就是:不想再看终端,不想再看手册,觉得自己像一台没有文档的机器在给另一台机器调参。这次我决定换个思路:反正环境搭建本质上是"查资料、写命令、看报错、修正、再跑"的循环,这恰好是 AGENT 最擅长的事情。我只需要给它一个足够清晰的目标,再给它一台能跑的机器,它就能自己迭代。
传统环境搭建的核心痛点是"人肉同步状态"。你看了教程、改了配置、跑了命令、看到报错,然后你需要在脑子里更新一下"当前环境到底是什么状态",再决定下一步。这个状态更新过程其实非常耗精力,尤其当你同时要兼顾工具链版本、内核配置、rootfs 类型的时候。AGENT 的好处在于,它天然会把每一步操作和执行结果记录下来,等于替你维护了一份"环境状态日志"。哪怕它中途崩了,你也能从日志里复盘它到底干到了哪一步。
1.2 AGENT 到底是"替我做"还是"带我一起做"
实际用下来,我的体会是:AGENT 更接近一个"动手能力很强、偶尔会自作聪明"的实习生,而不是一个全自动机器人。布置任务的时候,你把背景讲清楚、验收标准写明确,它能干得很漂亮。但如果你自己也没想清楚"什么叫搭好了",它就会在某个奇怪的方向上越走越远。
这次我给了它一个非常明确的目标:在 QEMU 上拉起一个能跑 Linux 并能安装 PyTorch 的 RISC-V 环境。验收标准是:能启动到 shell,能执行 uname,能运行 Python 并 import 指定模块。有了这个目标之后,AGENT 开始自己去查 QEMU 对 RISC-V 虚拟机的支持情况,去看哪种 machine type 最合适,去对比 OpenSBI 和直接加载 kernel 的区别。我在旁边做的事情,更多是"审核它的方案,把不合理的路径掐掉"。
换句话说,AGENT 负责把"怎么做"的细节全部填充掉,我负责确认"做出来的东西是不是我想要的"。这个分工模式,在环境搭建这种"过程繁琐但验收标准相对清晰"的任务上,效率高得惊人。
2. 动手之前:想清楚 QEMU 这块"模拟芯片"要提供什么
2.1 AI 芯片实验台到底需要哪些能力
"用 QEMU 搭建 RISC-V AI 芯片实验台"这句话听起来很唬人,实际拆开看就三层需求。
第一层:指令集支持。我要验证的 AI 负载最终要跑在 RISC-V 上,至少 CPU 得支持 RV64GC,最好还能带 V(向量)扩展,因为很多 AI 算子的优化都是围绕向量指令展开的。QEMU 的-cpu rv64默认配置支持 RISC-V 的 IMAFDC 扩展,如果要向量扩展,得在 CPU 型号里显式打开,或者用-cpu rv64,v=true这样的方式。这一层决定了我能不能在模拟器里跑裸机和 Linux 内核。
第二层:系统能力。如果要跑完整 Linux,QEMU 的virtmachine type 是最稳的选择。它自带 PLIC 中断控制器、virtio 总线、串口等外设,而且设备树是 QEMU 自己生成的,不用我们手工维护。对 AI 芯片实验来说,virt 平台就像是块"标准开发板",能把软件栈快速跑起来,先把功能调通。
第三层:AI 软件的运行能力。跑 AI 负载需要用 Python、PyTorch 这样的用户态软件,这要求 rootfs 里有完整的 glibc、Python 解释器和依赖库。光能启动内核还不够,得把用户态的生态环境也铺好,实验台才算真正能用。
这三层需求直接决定了 AGENT 的整个任务分解方向。如果目标只是验证一条汇编指令的效果,那可以用裸机 + 最小启动代码,连内核都不用加载。但我要的是"AI 芯片实验台",那就必须走到完整 Linux + 用户态 AI 框架这一层。
2.2 QEMU 的三种玩法,AGENT 帮我把差异列清楚了
在让 AGENT 干活之前,我让它先做了一次"方案对比"。它从资料库里找出 QEMU 模拟 RISC-V 的三种典型方式,我整理成一张表:
| 模拟方式 | 能模拟到什么程度 | 适用场景 | 典型限制 |
|---|---|---|---|
qemu-system-riscv64(系统模式) | 完整 SoC、中断、外设、virtio、多核 | 跑 Linux 内核、驱动、完整软件栈 | 启动慢,QEMU 层开销大 |
qemu-riscv64(用户态模式) | 单个用户进程的 RISC-V 指令翻译 | 快速跑交叉编译好的程序、跑 Python 单元测试 | 无法验证系统调用之外的内核交互 |
qemu-riscv64+ 自定义设备模型 | 某个特定外设或芯片扩展 | 调试自定义指令或 AI 加速器 | 需要改 QEMU 源码,工作量大 |
对"AI 芯片实验台"这个目标来说,用户态模式适合做算子正确性验证,系统模式适合做完整的软件栈集成验证。两个都保留、配合使用效果最好。AGENT 给出的建议是:先用用户态模式快速验证工具链和 Python 环境,再用系统模式跑完整镜像。
这里有个很重要的点:AGENT 可以做资料采集和方案对比,但最终怎么拍板,还是得靠我自己想清楚实验台的目标。因为同样是"环境搭建",有人想要的是嵌入式系统调试环境,有人想要的是深度学习模型的推理环境,这两者的路径完全不同。如果一开始就丢给 AGENT,不给它需求边界,它大概率会做出来一个"什么都像但什么都不完全对"的环境。
2.3 为什么我最终放弃了真板子
手头没有真芯片,这是核心原因。但有真板子的人,我也建议先在 QEMU 上把软件栈跑通再上板。
真板子的价值在"真实外设行为",比如 PCIe 控制器、DMA 引擎、真实带宽瓶颈,这些都是 QEMU 模拟不了的。但我现在的实验目标是验证 AI 算子的正确性、软件栈的可行性,而不是跑基准测试、测量硬件性能。用 QEMU 搭实验台,最大的好处是可以随时把整个环境"格式化了重新来"——rootfs 坏了、内核配置乱了、环境变量污染了,删掉镜像重新生成就行,真板子可没这么潇洒。
而且 QEMU 支持快照,可以在跑 AI 负载之前保存一份干净的镜像状态。每次实验结束,-loadvm就能回到初始状态,这对反复调试软件栈来说几乎是一种奢侈。AGENT 在这个阶段的作用,是帮我把"QEMU 真板定义"这类资料整理出来,让我在对比时不用自己翻一晚上文档。
3. AGENT 正式接管:从零拉起 QEMU 启动链路
3.1 我给 AGENT 的第一份"任务书"
和 AGENT 协作的第一课,是学会写任务书。我见过太多人让 AGENT 干活失败,不是因为工具不行,而是因为指令里全是"帮我搭个环境"这种模糊需求。AGENT 不是神仙,它没法替你定义"合适的环境"是什么意思。
我当时给的任务书大约是这样:
目标:在 Ubuntu 主机上,用 QEMU 模拟 RISC-V 64 位 virt 机器,跑起一个 Linux 系统。 验收标准:
qemu-system-riscv64能启动到登录 shell,不使用图形界面;- 内核版本和 rootfs 信息能在启动后通过命令行查询到;
- 启动参数和所用镜像文件完整记录到
/root/env_setup.log。 环境限制:主机内存 16GB,磁盘空间 200GB,优先使用系统已安装的软件包,如需编译源码,限制单个任务编译时间不超过 60 分钟。
为什么这样写?因为验收标准是"能启动到 shell",这个标准足够简单,AGENT 知道什么时候算完成。同时我给了环境限制,避免它在某个编译任务上耗时过久。任务书里没有对它说"你去用 buildroot 或者 busybox"——因为我希望它自己去选,我只审核结果,不限定过程。AGENT 最终选择了 busybox 生成精简 rootfs,理由是更快、依赖更少,这个选择很合理,因为它只是一个实验台的内核环境,不需要完整的发行版。
3.2 链接脚本是怎么被 AGENT"折腾"出来的
从一个裸内核镜像到能在 QEMU 上启动,中间有个关键环节:链接脚本。RISCV 的链接脚本(link.ld)要告诉链接器代码段、数据段放哪,从哪里开始执行。AGENT 第一次生成的链接脚本让我印象深刻,因为它自己从riscv64-linux-gnu-ld --verbose里找到了系统默认脚本,然后照葫芦画瓢改出了一个极简版本。
OUTPUT_ARCH(riscv) ENTRY(_start) MEMORY { RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 256M } SECTIONS { . = 0x80000000; .text : { *(.text.init) *(.text*) } .rodata : { *(.rodata*) } .data : { *(.data*) } .bss : { *(.bss*) } /DISCARD/ : { *(.eh_frame) } }看到ORIGIN = 0x80000000我挺意外的,因为 QEMU 的virt机器默认把 DRAM 映射到0x80000000,这个地址写对了,代码烧进去才能被 CPU 取到。你再想想,如果让人手工写这个链接脚本,第一次大概率会从0x00000000开始,然后怎么调都进不了引导。AGENT 之所以能选对地址,是因为它直接在 QEMU 的源码和文档里搜到了内存映射信息,而不是靠猜。
不过链接脚本只是第一步。真正让这块"虚拟芯片"跑起来,还需要一段启动汇编:设置栈指针、清 BSS、跳转到 C 语言入口。AGENT 在这个环节犯了个典型错误——它生成的启动代码忘了设置全局指针寄存器gp,导致后面的 C 代码访问全局变量时总线错误。这个错误很隐蔽,因为它不会在编译阶段报错,只会在运行阶段触发异常。当时我盯着日志看,发现它在反复修改启动汇编,最后自己意识到是gp的问题。这个排查过程花了大概十五分钟,如果换了人来查,可能得对着寄存器规范手册翻半天。
三言两语解释一下为什么必须设栈指针:RISC-V 的栈是向下生长的,sp寄存器必须指向合法的内存区域,否则每次函数调用保存返回地址都会写入一个非法地址。AGENT 生成的启动代码里用了la sp, _stack_top,然后在链接脚本里为栈留了 4MB 空间。这类细节,很多新手写的裸机代码里都缺,但 QEMU 启动时不会给你任何温柔的提示,直接就是无响应。
3.3 那行 QEMU 启动命令,每个参数都值得较真
AGENT 最终生成并验证通过的启动命令大概长这样:
qemu-system-riscv64 \ -machine virt \ -cpu rv64 \ -smp 4 \ -m 2G \ -bios fw_payload.elf \ -kernel Image \ -append "root=/dev/vda rw console=ttyS0" \ -drive file=rootfs.img,format=raw,if=virtio \ -nographic逐个拆开看,每个参数都对应一个之前踩过的坑。
-machine virt指定机器类型,virt 是 QEMU 针对 RISC-V 虚拟化支持的通用板卡,自带了 virtio-mmio 总线、PLIC 中断控制器、串口、RTC 等设备。它不需要我们手动去构建设备树,因为 QEMU 会自动生成一个符合规范的内核设备树。
-cpu rv64默认是一般 RV64GC 配置。凡是涉及 AI 向量指令的场景,要改成-cpu rv64,v=true,否则运行带向量扩展的二进制会直接非法指令。我们调试 PyTorch 的算子时,很多情况就是吃了 CPU 特性没开全的亏。
-bios fw_payload.elf和-kernel Image同时出现,其实是一种比较常用的组合:先用 OpenSBI 作为固件层,再由它把 Linux 内核加载起来。OpenSBI 提供了 M 模式的运行环境和设备树传递逻辑,不然你的内核要在 S 模式下裸奔,少了一个重要的中间层。
-append "root=/dev/vda rw console=ttyS0"是传给内核的命令行参数,告诉它根文件系统在哪个设备上,以及把控制台输出到串口。-nographic把串口重定向到当前终端,这是 headless 环境的标配。
这套参数不是我手动调出来的,AGENT 在跑测试时遇到问题后自己改的。它每次启动失败都会把 QEMU 输出抓下来,跟文档对照,定位到具体参数的错误原因。我当时主要做的是"批准或驳回它每次修改"——比如它曾试图在-append里加console=hvc0,我查了一下它给的参考来源,发现 virt 机器在这个配置下用串口设备更合适,就驳回了。
4. 在"模拟 AI 芯片"上装 PyTorch:这步最能检验 AGENT
4.1 RISC-V 上 PyTorch 的真实情况
系统能启动之后,实验台的下一步是在上面搭 PyTorch。这时候 AGENT 遇到了它整个过程中最头疼的问题:PyTorch 官方并没有提供 RISC-V 架构的预编译 wheel 包。
你去 pip install torch,得到的提示基本是"找不到匹配的发行版"。原因其实很好理解:PyTorch 的底层依赖了 Intel MKL、CUDA、AVX 这些 x86 特有的优化库,官方发布流程没有为 RISC-V 构建产物。想在 RISC-V 上跑,有几个选择:
第一,用源码编译。从 GitHub 拉 PyTorch 源码,用 riscv64 工具链交叉编译。但这个工程量太大,哪怕在 x86 主机上交叉编译一次也要几个小时,在 QEMU 的虚拟环境里编译更是等到天荒地老。
第二,用网友或第三方工程构建好的 RISC-V wheel。有人维护了针对 RISC-V 的 PyTorch 构建,但版本更新慢、依赖库版本也未必匹配。
第三,先验证核心算子,不装完整 PyTorch。用 torch 内部依赖的一些基础库,或者用轻量级的替代方案先跑通 AI 算子的计算流程。
AGENT 做了一个让我觉得很务实的决策:它先查了官方 issue 和社区讨论,确认没有可靠的 wheel 之后,没有硬着头皮去编译完整 PyTorch,而是转向验证"这个环境能不能跑通 AI 相关的 Python 库和 NumPy"。因为实验台的底层目标是验证 AI 算子的正确性,而不是验证 PyTorch 的安装流程。能用 PyTorch 更好,但首先要保证基础数学库能正常工作。
4.2 AGENT 在装 Python 依赖时踩到的一个暗坑
在用户态模式(qemu-riscv64)下跑交叉编译出来的 Python 解释器时,AGENT 遇到一个诡异的报错:Illegal instruction (core dumped)。这条报错本身没什么信息量,但它反复出现,而且出现的时机毫无规律——有时候是 import numpy,有时候是执行一段简单的循环。
排查过程很有意思。AGENT 先尝试换 Python 版本,无效。再尝试重新编译,无效。最后它把报错二进制通过readelf -A查指令集扩展标签,发现编译时默认带了V向量扩展指令,但在 QEMU 用户态模式下运行某个依赖库时,CPU 型号没开向量扩展。我之前说过,qemu-riscv64和qemu-system-riscv64的 CPU 模型设置是独立的,前者默认更保守。AGENT 的修复方式是给用户态模拟器显式加上 CPU 选项,设置环境变量让计算库不触发向量指令路径。
这个坑让我意识到一个问题:在模拟环境里搭 AI 软件栈,指令集扩展一致性比真机更关键。真机上的扩展是确定的,但 QEMU 的 user-mode 和 system-mode 默认配置不一样,很容易出现"system 模式能跑,user 模式崩了"的情况。AGENT 能在日志里对比两种模式下的 CPU 特性,定位效率比人肉翻文档高很多。
4.3 在模拟器上验证 AI 推理流程的实际效果
经过几轮折腾,最终的实验台形态是这样的:
| 组件 | 选型 | 备注 |
|---|---|---|
| CPU 模型 | rv64, v=true | 支持向量扩展,满足 AI 算子验证 |
| 系统模式 | qemu-system-riscv64 + virt | 跑完整 Linux 内核与 rootfs |
| 用户态模式 | qemu-riscv64 + 自定义 CPU | 快速运行交叉编译的 Python/NumPy |
| 运行库 | NumPy / 自定义算子 | PyTorch 暂缓,等待社区构建 |
| 根文件系统 | busybox + 精简 glibc | 减少开销,可随时重建 |
我拿一个小规模的矩阵乘加运算做了验证,流程是:在 x86 主机上写算子源码,用 riscv64 工具链交叉编译,再拷到 QEMU 用户态里执行。整个过程不需要启动完整的 Linux 系统,单条算子的验证时间从分钟级降到了秒级。如果需要验证内核模块、驱动交互、系统调用路径,再切换到 system 模式跑完整镜像。两个模式配合使用,实验台的效率比单靠一个模式高很多。
这段经历让我对"实验台"这个概念有了新的理解。它不是说模拟出一个 AI 芯片的外壳,而是模拟出一个"可以随时验证想法"的环境。AGENT 在这个阶段的价值,是帮我把验证流程自动化了——它把交叉编译、拷贝、执行、比对结果这几个步骤封装成脚本,我只需要改算子代码,跑一遍脚本就完事。
5. AGENT 翻车现场:三个典型事故与救火过程
5.1 事故一:沙盒里"下载工具链"被无声拒绝
AGENT 在环境搭建初期做过一件事:下载 RISC-V 交叉工具链。它选择了从源代码仓库下载预编译压缩包再解压,但整个过程没有产生任何文件。它反复检查磁盘空间、校验网络,都看不出问题,最后卡在一步无限重试。
我看日志才发现,它的执行环境是受限沙盒,对某些网络端口的访问是受限的。压缩包下载请求被静默丢弃,AGENT 还以为是自己命令写错了。后来我直接在主机侧帮它下载好工具链压缩包,放到共享目录,让它在沙盒里只做解压和配置,问题一下解决了。
教训很简单:AGENT 执行环境的网络策略、权限模型和宿主环境不一样,这种"环境自身限制"很难靠 AGENT 自己发现,需要人从外部介入。以后我只要发现它反复执行某个下载命令但一直没结果,会先手动检查沙盒网络策略,而不是让它闷头重试。
5.2 事故二:agent execution terminated due to error
这个报错想必用过 AGENT 编程工具的人都见过。有一段时间它执行任何命令都会走到这个错误终止——不是命令本身报错,而是"执行进程"被整体中断。
第一次遇到,我以为是命令写错了。但看完整日志,发现是 AGENT 在单个回合里塞了太多操作:它试图在一个长命令里同时完成内核编译、rootfs 制作、镜像装配。这个命令的执行时间超过了沙盒进程的超时阈值,然后整个执行进程被强制终止。AGENT 自己对这种超时是无能为力的,因为它不知道沙盒的时限是多少。
我的修复方式是把它的大命令拆成一系列小步骤,每个步骤单独执行,每步之间有明确的中间产物。这一步表面上是在教 AGENT 编程习惯,实际上是在适应沙盒的物理约束。从那时起,我也意识到给 AGENT 分配任务时,要把"单个任务执行时间不可超过 X 分钟"写进任务书,因为它自己不会主动控制单个命令的复杂度。
5.3 事故三:沙盒更新与"无法发送消息"背后的真相
有一段时间,工具提示"沙盒更新中",然后 AGENT 直接无法发送消息。一开始我以为是网络问题,但后来发现,这类工具的后端沙盒有版本更新机制,更新期间会话的执行环境会被重建,进程被冻结。AGENT 卡在等待某个文件生成,但那个文件所在的沙盒已经被替代了。
这种问题没有太多优雅的解决办法,就是把任务拆得更碎、保留中间产物,这样沙盒更新后可以从最近的中间状态继续,不需要全部重来。我后来在任务书里经常加一句话:"每一步完成后都把环境状态写入日志,以便恢复。"这话看起来像废话,但当真遇到沙盒重建时,它省了我大量时间。
5.4 harness 与 AGENT 的职责边界,这问题必须搞清楚
热词里经常看到"harness 和 agent 区别",我对这个话题特别有感触。很多人在用 AI 工具时,看到失败就怪"这个 AGENT 不行",但实际上问题往往出在 harness 那一层。
harness 是 Agent 运行时的"壳":负责工具调用、沙盒管理、记忆存储、上下文窗口轮换、执行进程超时控制。AGENT 是壳里的"大脑":负责推理、决策、生成下一步动作。环境搭建过程中遇到的很多诡异问题,本质是 harness 配置问题——沙盒网络受限、超时阈值太短、上下文窗口不够、工具链路径不对。AGENT 能做的,只是在 harness 给定的框架内想办法。
拿我这次的沙盒举例,harness 决定了 AGENT 能访问哪些目录、能执行哪些命令、有没有 sudo 权限。AGENT 在里面再聪明,也突破不了 harness 给定的边界。所以,当你看到 AGENT 反复执行同一条命令都不成功时,不妨先停一停,去看看 harness 层的配置,而不是单纯让 AGENT 换措辞重试。
6. 实测结论与给想照抄的人的建议
6.1 把 AGENT 用在环境搭建上的正确姿势
这次完整走下来,我认为 AGENT 做环境搭建的价值不在于"省掉人工",而在于"把过程透明化"。它每一步都留日志,每个决定都有出处,你可以事后复盘"为什么当时那么选"。这比绝大多数人手动敲命令留下的记忆要可靠得多。
但它的能力边界也很明显:它不知道你的实验目标,不知道你的验收标准,更不知道你的时间预算。所以正确的协作方式是——你负责定义"什么算完成",AGENT 负责把"完成路径上所有细节"填充掉。我的做法是每次分配任务前写一段非常具体的任务书,包含目标、验收标准、环境限制、优先级。这听起来麻烦,但比起让 AGENT 瞎跑半小时省太多时间。
6.2 哪些事交给 AGENT 划算,哪些事别偷懒
我列一个自己的清单:
适合交给 AGENT 的:
- 资料检索与方案对比:查某个 machine type 的支持情况、查某个库在 RISC-V 上是否有预编译包。
- 可验证的重复操作:交叉编译脚本、rootfs 生成、启动参数调试(只要有明确验收标准)。
- 日志分析:从 QEMU 输出、内核 panic 日志中提取关键错误信息并给出解释。
- 自动化脚本生成:把一连串操作包装成一个可复用的脚本。
不适合交给 AGENT 的:
- 模糊需求:比如"搭一个适合 AI 芯片的环境",它不知道你要跑什么负载、用什么框架。
- 需要真实硬件交互的操作:比如烧录真机、测量功耗、确认物理外设时的调试。
- 涉及大量不可逆操作的步骤:比如格式化磁盘、删除整个镜像仓库,这种我会手动确认,不让 AGENT 直接执行。
6.3 后续还能怎么扩展这套实验台
现在这个实验台已经能跑 Linux、能执行交叉编译的 AI 算子、能在用户态快速验证 Python 计算库。后续我再想加东西,也不会推倒重来,而是沿着现有框架扩展。
一个方向是接入真实的 RISC-V 向量指令优化:把某个算子用内联汇编写成 RVV 向量版本,然后在 QEMU 上对比向量化和非向量化的运行结果,验证正确性。QEMU 虽然不能精确模拟性能,但能帮你验证指令序列的语义是否和预期一致,这对算子开发来说是刚需。
另一个方向是加进更多 AI 算子库的支持,比如把 ONNX Runtime 在 RISC-V 上交叉编译跑通。如果社区后续提供更完善的 PyTorch RISC-V 构建,也能直接替换掉当前实验台上的验证路径,而不需要改底层环境。
我个人最大的体会是:环境搭建最怕的不是复杂,而是不可见。AGENT 把整个过程变成了一份可复现、可复盘、可断点续跑的记录,这比它"替你省下多少小时"更有价值。如果你也打算用 AGENT 搭一套类似的实验环境,记住一件事就好——先写清楚"什么算搭好了",再让 AGENT 开始折腾。