AI 代码写到“内核级”了?别激动,先把正确姿势学会
你肯定刷到过类似感叹:“这已经是标志性事件了,AI 代码成熟到可以写内核了。”
是的,AI 确实能写出看起来很像那么回事的内核代码。
问题也很现实:
- 你敢直接 merge 吗?😅
- 你敢不 review 吗?
- 你敢让它改锁、改中断、改内存管理吗?
结论很直白:AI 可以写内核代码,但你要把它当成“能产出补丁的同事”,而不是“免 review 的替身”。
这篇就聊一套你能照着做的流程:让 AI 产出更像内核补丁的东西,减少你在 Review 里抓狂的次数。
先把预期摆正:AI 适合做什么、不适合做什么
更适合交给 AI 的活(很香)
- 把一个小改动变成 规范的 patch(commit message、注释风格、错误处理分支)
- 帮你补齐 边界条件(参数校验、返回值、错误码路径)
- 生成 自测代码(KUnit、简单的 mock、最小复现脚本)
- 帮你查 接口用法(比如
copy_to_user()的错误处理) - 把一坨逻辑拆成 更易 review 的小提交
这些活干好了,你会明显感觉:
Review 变轻松了,心情变好了,下班更早了。
别轻易放给 AI 的活(很容易出事)
- 锁/并发/内存屏障(看着对,跑起来炸)
- 生命周期管理(引用计数、释放时机、错误路径回滚)
- 性能敏感路径(它会“写得优雅”,但可能多一次分配就抖三抖)
- 安全边界(用户态/内核态数据拷贝、越界、未初始化)
你可以让 AI 参与,但要把它放进一套“有护栏”的流程里。
一套能落地的“AI 写内核代码”工作流
目标只有一个:让 AI 产出“可审、可测、可回滚”的补丁。
1)把需求切小:让 AI 有机会写对
别给它一句“优化这个驱动”。你会得到一坨看似合理的重构,然后你开始怀疑人生。
更好的写法是:
- 改动范围:哪个文件、哪个函数
- 行为变化:旧行为是什么,新行为要变成什么
- 约束条件:不能改 ABI/不能改变锁顺序/不能新增睡眠点
- 验证方式:你打算用什么测试证明它没坏
你可以用这种模板:
任务:在
drivers/xxx/yyy.c的foo_handle_event()中,修复当event_len == 0时仍然访问event_buf[0]的问题。要求:
- 不改函数签名
- 保持现有锁顺序
- 错误码用
-EINVAL- 需要补一条 KUnit 测试覆盖该分支
输出:一个 commit(含 commit message)+ patch diff + 测试代码
这类任务,AI 命中率会高很多。
2)把上下文喂够:别让它“靠猜”
内核开发最怕“靠猜”。AI 也一样。
你要给它:
- 相关代码片段(包含调用链关键部分)
- 现有风格(同目录下类似函数怎么写)
- 你们项目的约束(是否允许
devm_*,是否要求goto err_*风格)
场景很常见:你只贴了一个函数,它给你引入了不存在的 helper,或者用错了 API。
贴上下文的成本不高,能省你半小时吐槽时间。
3)让 AI 按“补丁标准”交付,而不是只给代码
你要的不是一段“看起来能跑”的代码。
你要它按内核补丁的交付方式来:
- commit message(问题、原因、修复方式、影响范围)
- diff(保持最小改动)
- 测试说明(怎么跑、覆盖了什么)
你可以直接这么要求:
输出必须包含:
Subject: [PATCH] ...Fixes:(如果能定位到引入问题的 commit)Signed-off-by:留空让我补diff --git完整 diff
AI 会更“像人类写 patch”,Review 体验直线上升。
4)把“Review 点位”提前塞给 AI:你在教它怎么不翻车
你希望 review 看到什么?直接列出来。
常用检查点:
- 错误路径是否回滚完整(资源释放、引用计数)
- 是否引入睡眠点到原子上下文
- 是否改变锁持有范围/锁顺序
- 用户态拷贝是否检查返回值
- 是否新增未初始化读取
把这些写进 prompt:
写完代码后,请逐条自检:锁、并发、内存释放、错误码一致性、用户态拷贝返回值。
这招挺“鸡贼”,但真的好用。
5)用本地工具把 AI 产出“打磨”成能合入的东西
你不需要靠肉眼把关一切。
把这些跑一遍,很多坑会当场现形:
scripts/checkpatch.pl(内核风格雷达)clang-format(按项目约定)sparse(类型、地址空间、可疑用法)smatch(更偏内核生态的静态分析)kunit.py run(如果你写了 KUnit)
如果你是公司内核/定制内核,还有 CI:
- 编译多个配置(
allmodconfig、目标板 config) - QEMU 启动冒烟测试
AI 产出 + 这些工具,组合拳打下去,质量会比“纯手写不跑工具”更稳。
一个实战范式:让 AI 帮你从 bug 描述走到 patch
你可以按这条链路走:
- 你提供:复现方式 / 报错日志 / 相关函数
- AI 输出:问题定位假设 + 修改点
- 你确认:修改点是否合理、范围是否可控
- AI 输出:patch + commit message
- 你执行:checkpatch / 编译 / 测试
- 你 review:锁、生命周期、边界
- 你再让 AI:根据 review 意见改第二版 patch
这里的关键是:
- AI 不需要一次写对
- 你要它 迭代得快
就像带一个聪明新人:方向别跑偏,效率就爆炸。
让人上头的幻想:哪天不需要人类 Review,就完全替代人了?
这句话很刺激,但现实更硬。
内核这类代码的风险点不在“能不能写出来”。
风险点在:
- 你怎么证明它在所有路径都安全?
- 你怎么证明它在并发下不出幽灵 bug?
- 你怎么证明它没引入安全漏洞?
AI 可能越来越强。
但 Review 的意义不会消失,只会变形:从“看语法对不对”,变成“看系统行为、看边界、看风险”。
你要做的是把 Review 变轻,而不是幻想删掉 Review。
避坑清单:AI 写内核代码时最常见的翻车点
- “它编译过了”不等于能用:很多并发 bug 编译器看不出来。
- 它爱重构:一重构就扩大 diff,review 成本爆炸。盯住“最小改动”。
- 它会发明 API:看见不存在的 helper、错误的宏,别笑,真常见。
- 它对上下文很自信:你不给足,它就靠猜,然后猜得很像真的。
- 错误路径经常漏:尤其是
goto err_*链条,特别容易少释放一步。
你每次让 AI 改锁、改引用计数,建议默认加一句:
“不要改变锁顺序;不要扩大锁持有范围;错误路径必须保证资源完全回滚。”
一套可直接复制的 Prompt(拿去就能用)
把下面模板里的代码和路径替换掉就行:
你是 Linux 内核开发者。
背景:我在 <文件路径> 里遇到一个 bug。
目标:输出一个最小改动的 patch,修复问题,不做无关重构。
约束:
- 不改函数签名
- 不改变锁顺序/锁持有范围
- 错误码风格与现有代码一致
- 不引入新的依赖
输入代码片段:
<粘贴相关函数 + 调用链关键片段>
问题描述:
<粘贴日志/复现方式/触发条件>
请输出:
1) 你对根因的判断(简短)
2) `[PATCH]` commit message(含原因、修复方式、测试说明)
3) 完整 diff
4) 自检清单:并发/锁/错误路径回滚/用户态拷贝/边界条件
你现在就能做的练习(10 分钟起步)
- 找一个你仓库里“低风险的小 bug”:空指针、越界、返回值未检查
- 把相关函数和日志喂给 AI
- 让它输出 patch + 自检清单
- 你跑
checkpatch.pl+ 编译 - 你把 checkpatch 的告警丢回给 AI,让它改到干净
你会很直观地感受到:AI 在内核领域的价值,不是“替代你”,而是让你把时间花在真正需要人脑的地方。
如果你愿意,把你要修的那个函数片段贴出来(脱敏也行),我可以按上面的流程给你整理成一版可 review 的补丁骨架。