先说个我踩过的坑
上周我让AI帮我写一个数据清洗的脚本,两分钟出了两百多行,跑起来直接报了个空指针。我下意识想打断点单步跟一下——结果傻眼了。
变量名全是它自己起的,`_tmp_buf`、`res_map`、`item_x`,我根本不知道哪个是我关心的那条数据。函数嵌了四五层,我想在中间那层停下来看看,断点打上去要么没进,要么一进去就是一堆我看不懂的中间态。
折腾了快一个小时,我才意识到一件事:
我不是不会调试,我是在调一段**别人写的、我完全不熟的代码**——只不过这个「别人」是AI。
这个感受挺微妙的。模型能写代码,这事现在没人怀疑了。
可它写完之后,那段代码对你来说是个黑盒。你不知道它内部的数据是怎么流动的,不知道它在哪一步做了个你没预料到的假设。
传统调试那套方法,前提是你对代码结构有肌肉记忆,而AI恰恰把这个前提抽走了。
为什么断点在AI代码里经常「失灵」
我后来想明白了,断点这东西的效率,本质取决于你对代码的熟悉度。
你自己写的代码,你脑子里有张地图,知道数据大概会在哪几个关键节点出问题,断点往那一打,一步就命中。可AI生成的代码你没这张地图。
它可能把逻辑拆得很碎,也可能塞了一堆防御性判断,你打十个断点,九个是废的,单步走半天走的全是无关分支。
这让我想起V2EX上那个「许愿AI」的帖子——有人说,很多时候不是模型脑子不好使,是用的人自己都不清楚正确的结果该是什么,一句「帮我做个登录」丢过去,出了问题自己也定位不了。我觉得这话说到点子上了。
你连预期的运行时状态都描述不清,断点自然无从下手。
还有个更隐蔽的问题:日志。你自己写代码,习惯在关键路径埋几行日志。
但AI生成的代码是「一次成型」的,它不会替你埋你想要的观测点。等你发现要看某个中间变量时,代码已经跑完了,现场没了。
我的转弯:别再让AI猜,先把现场录下来
试过两次让AI「你自己看看哪错了」之后,我放弃了这条路。
说真的,让AI去调它自己写的代码,经常是改了又改,这里补一句那里加个判断,报错换了个样子,根本原因没动。这跟那位做Ozon工具的老哥描述的一样——特定类目上架总有报错,与其反复猜,不如「抓到日志打个补丁」。
关键词是**抓日志**,不是猜。
所以我的思路彻底反过来了:**不追着AI改,先把运行时现场完整录下来给自己看。**
具体做法是写一个很小的Python装饰器,给我关心的那几个函数自动插桩。每次进函数记一下入参,出函数记一下返回值和耗时,中间关键变量做个快照。
不用改AI的核心逻辑,只在外面套一层。这样跑一遍,整条执行路径、每一步的变量值就全落下来了。
这个插桩脚本本身也不复杂,我经常直接在Python在线运行环境里先把装饰器逻辑验证通,确认它能正确抓到入参出参、不会因为参数里有不可序列化的对象就崩,再套到真实代码上。在线跑的好处是我不用在本地反复搭环境,改一版立刻看效果,「这段到底卡在哪」几分钟就有答案,比在IDE里来回打断点快多了。
把执行路径落进数据库,事后慢慢看
光打印到控制台不够,一多就刷屏了,而且看不出规律。
我的做法是把每次插桩记录的东西写进一张SQLite表:函数名、调用时刻、入参、返回值、这一层的调用深度。跑完之后不用盯着滚动的日志,直接查表——按函数名筛,按耗时排序,一眼就能看出哪个函数被调了异常多次,哪个入参长得跟我预期不一样。
这招其实是从CC-Monitor那个审计工具偷来的。它监测Claude Code的每次操作,`tool_input`和`tool_response`全量落盘到SQLite,事后能按会话、按事件类型慢慢下钻。
我看完就想,调试AI代码不也是一回事吗?把「AI在运行时干了什么」当成一份审计日志来存,总比现场看强。
数据落进去之后,想看某张表的结构、随手翻几条记录对一下,用SQLite编辑器直接打开看就行,不用再单独写查询脚本。我通常先扫一眼数据长啥样,确认插桩没记漏字段,再决定要不要加索引或者换个维度筛。
这个来回比想象中重要——很多时候你以为的bug,在表里一看数据分布就露馅了。
一个反常识的发现
本以为给AI代码做插桩会很麻烦,毕竟结构陌生。结果恰恰相反:**正因为我不熟这段代码,自动插桩反而比手工打断点靠谱。
**
手工断点依赖你的直觉,不熟就容易打偏。而自动插桩是无差别地把所有关键函数的现场都录下来,你事后再筛。
它不需要你「猜」哪里有问题,它把选择权留到了你手上数据最全的时候。这跟那篇聊陶哲轩的随想里说的有点像——过程里那张「地图」不会自动出现,你得自己走一遍才有。
调试也一样,现场录全了,地图才画得出来。
对独立开发者来说,这套东西的价值在于:你可以把它做成一个站内小工具沉淀下来。今天调这个项目用得上,下个项目照样用。
想系统补一补插桩、调用栈这些底层概念,再决定怎么设计自己的观测层,可以顺着AI编程相关的内容捋一遍思路,别上来就硬写。
今天就能试的一个小动作
别整套框架,先从最小的开始。
挑你手上那个「AI写完但你没底」的函数,写一个十几行的Python装饰器,进函数打印入参、出函数打印返回值,套上去跑一遍。就这一步,你大概率能立刻看出之前断点没看清的东西。
跑通了,再考虑把记录写进SQLite做事后分析。别一开始就追求完美,先让现场「看得见」,调试AI代码这事就已经赢了一半。