跳转至

LLM 时代下的内核开发与开源协作范式

已经是 2026 年了, 你还在坚持 "古法编程" 与 "传统合作开发" 吗?

最近有幸学习到 Yixin Shen 学长的讲座内容, 主题是:《Personal Experience of Kernel Development and How to Write Better Code》. 深有感触, 受益匪浅!

同时, 在网上冲浪的过程中, 发现 Google, Linux Kernel Community, Microsoft, IBM 等曾经给出不少关于 kernel dev, open source contribution 的建议, 例如:

同时, 在2026的当下, 很多开源的交互 / kernel dev的方式已经发生了变化, 尤其是 claude code 对于传统开发的"重创"

因此, 在这个时候, 我觉得有必要基于传统方式, 更新一下在LLM时代, 内核开发与开源社区协作的最佳实践.

致谢

本文内容参考了大量前辈的经验与建议, 特此致谢! 如:

  • Yixin Shen 学长的讲座内容
  • 上述关于 kernel dev, open source contribution 的建议
  • with the help of Claude, Gemini :)

笔者会融合自己的理解, 依旧采用 Yixin Shen 的内容划分, 进行一定的改写与补充. 更新点重在"claude code for dev", 如有不当之处, 欢迎指正!

Why this

2026 年,AI 辅助编程工具已经从"尝鲜"走向"日常". Claude Code,GitHub Copilot 等工具正在深刻改变开发者的工作方式.然而,Linux 内核开发社区作为开源世界最成熟的协作体系之一,其核心流程(maillist,patch 格式)依然保持着强大的生命力.

问题来了:如何在尊重传统的同时,合理利用 LLM 提升开发效率?

本文将沿用 Yixin Shen 的四部分框架,逐一探讨 LLM 时代的最佳实践:

  1. Dev Env - 开发环境搭建
  2. Make Patch - 补丁制作与提交
  3. Better Code - 编写更好的代码
  4. Collaboration - 协作与代码审查

Dev Env

Dev Env 即: 开发环境的搭建

内核开发对环境隔离要求较高,以防止对主系统造成破坏.传统上,开发者会使用虚拟机或容器化方案来创建安全的内核开发环境

传统方案回顾

内核开发需要隔离环境以避免破坏主系统.传统选择包括:

工具 特点
VMware / VirtualBox 图形化,易上手
QEMU + KVM 灵活,性能好
Vagrant + libvirt 脚本化,可复现
Firecracker 轻量级 microVM

"自顶向下"这一套 Vagrant + libvirt + QEMU + KVM 组合依然是优秀选择!

LLM辅助开发

Bash
1
2
3
4
5
6
7
8
# 在内核源码目录启动 Claude Code
cd linux
claude

# 示例交互
> 帮我理解 mm/memory.c  do_page_fault 的调用链
> 这个 patch 有没有潜在的并发问题?
> 按照内核编码规范重写这个函数

建议:

  • 将 Claude Code 作为"随时在线的内核专家", 用于理解复杂代码路径 [从这一点来看, 可以平替 DeepWiki]
  • 让 Claude Code 帮你检查 patch 是否符合子系统的惯例
  • Do Not 让 AI 直接生成大段代码后盲目提交! 内核社区对代码来源有严格要求!
    • 建议在本地建立"容器化开发环境", 一方面是为了隔离, 另一方面是为了本地模拟CI/CD流程, 确保每一发提交的合法性与正确性.
    • 建议参考 KIND 的容器化实践, 构建内核开发的"容器化沙箱"

Kernel-dev Checklist

  • VM / Container-based 环境搭建完成
  • 内核源码获取 (git clone)
  • 编译工具链安装 (gcc, make, ncurses-dev, libssl-dev, etc.)
  • Claude Code / AI 工具配置
  • 邮件客户端配置(用于 patch 提交)
  • 编辑器 + LSP 配置(clangd for kernel. 现在claude code也支持LSP了)

Make Patch

Make Patch 的含义是: 将当前的代码库状态提交为一个 patch 文件, 告诉内核社区你做了哪些改动, 为什么要做这些改动.

"我修复了XXX错误, 这个错误会导致YYY问题, 我通过ZZZ方法修复了它"

传统流程

(1) 找到正确的维护者

内核的 /MAINTAINERS 文件是圣经!

Bash
1
2
3
4
5
6
BPF [GENERAL] (Safe Dynamic Programs and Tools)
M:    Alexei Starovoitov <ast@kernel.org>     # 维护者 (M. Maintainer)
R:    Martin KaFai Lau <martin.lau@linux.dev> # 审查者 (R. Reviewer)
L:    bpf@vger.kernel.org                     # 邮件列表 (L. Mailing List)
T:    git git://git.kernel.org/pub/scm/linux/kernel/ # 源码树 (T. Tree)
F:    Documentation/bpf/                      # 相关文件 (F. Files)

使用脚本自动获取:

Bash
1
scripts/get_maintainer.pl -f drivers/net/ethernet/intel/ice/ice_main.c

(2) 制作 Patch

Bash
1
2
3
git format-patch --subject-prefix='PATCH' -1 HEAD~
git format-patch --cover-letter --subject-prefix='PATCH' -N
git format-patch --subject-prefix='PATCH v3 bpf-next' -N

Patch 格式示例:

Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Subject: [PATCH v3 bpf-next 1/2] bpf: Fix memory leak in map_update_elem

Fix a memory leak that occurs when map_update_elem fails after
allocating memory for the new element.

The issue was introduced in commit abc123 ("bpf: Add feature X").

Fixes: abc123def456 ("bpf: Add feature X")
Signed-off-by: Your Name <your@email.com>
---
 kernel/bpf/syscall.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(3) 提交前检查

Bash
1
2
3
4
5
6
# 编译检查
make -j$(nproc)
# 风格检查
scripts/checkpatch.pl --strict 0001-*.patch
# 静态分析
make C=1 drivers/net/ethernet/intel/ice/

(4) 发送 Patch

配置 git send-email:

INI
1
2
3
4
5
6
7
[sendemail]
    smtpencryption = tls
    smtpserver = smtp.gmail.com
    smtpuser = YOUR_ACCOUNT@gmail.com
    smtpserverport = 587
[credential]
    helper = store

发送:

Bash
1
git send-email --to=list@vger.kernel.org --cc=maintainer@email.com 00*.patch

LLM辅助制作Patch

(1) Commit Message 撰写

现在 claude 里有 plugin 专门帮你写 commit message 了! 叫做 commit-commands

Bash
1
2
/commit-commands:commit
/commit-commands:commit-push-pr

以后我们就直接这么用, 纯自然语言即可:

Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
claude

> 帮我改进这个内核 commit message,使其更符合 Linux 内核的惯例:

[你的草稿 commit message]

要求:
1. 标题不超过 75 字符,使用祈使句
2. 说明问题的根因
3. 解释为什么这个修复是正确的
4. 如果是 bugfix,添加 Fixes: 标签

(2) 提交前让 AI 审查你的 patch

上面提到最好要有本地的容器化开发环境, 这样你就可以在本地生成 patch 之后, 让 claude 帮你审查一下:

Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 生成 patch 内容
git diff HEAD~1 > my_patch.diff
# 让 Claude 审查
claude "作为 Linux 内核审查者,审查这个 patch

检查内容包括但不限于:
1. 是否有内存泄漏或资源泄漏
2. 并发安全性(锁的使用)
3. 错误处理路径是否完整
4. 是否符合子系统的编码惯例
5. 是否需要更新文档"

(3) 提交Patch之后: 理解社区维护者的反馈

收到维护者的 review 意见后,AI 可以帮助理解技术细节:

Bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
claude "维护者给我的 patch 回复了这些意见:

'This introduces a TOCTOU race between the check and the actual update.
Consider using RCU or taking the appropriate lock.'

请解释:
1. 什么是 TOCTOU race
2. 在我的代码上下文中具体指哪里
3. 如何用 RCU 修复

给出你自己的修改建议, make a draft for this, in PLAN mode."
AI 生成代码 != 开发者能直接提交

Linux 内核社区对代码来源有严格要求:

  • 你必须理解你提交的每一行代码
  • Signed-off-by 意味着你对代码负责
  • 不要直接复制 AI 生成的大段代码而不理解
  • 如果使用 AI 辅助,建议在 commit message 中说明(部分子系统开始要求披露)
    • co-authored-by: AI Tool <ai@tool.com>

TLDR:

  • ✅ 用 AI 理解现有代码
  • ✅ 用 AI 帮助调试和定位问题
  • ✅ 用 AI 检查你写的代码
  • ✅ 用 AI 润色 commit message 和文档
  • ⚠️ 谨慎: 让 AI 生成代码框架/大量代码, 然后逐行审查和修改
  • ❌ 100%避免: 直接提交 AI 生成的代码, 自己却完全不理解

Better Code

代码开发原则

TODO:

CRISP原则:

原则 含义
Correct 正确性第一
Readable 可读性
Idiomatic 符合惯例
Simple 简单直接
Performant 性能

SOLID 原则:

  • Single Responsibility Principle
  • Open-Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

KISS原则: Keep It Simple, Stupid

YAGNI原则: You Aren't Gonna Need It

DRY原则: Don't Repeat Yourself

SoC原则: Separation of Concerns

LLM辅助代码开发/重构/测试/文档

(1) 代码审查和重构

最近 claude code 推出了 code-simplifier

"Ask Claude to use the code simplifier agent at the end of a long coding session, or to clean up complex PRs!"

为什么这个特别有用?

  1. 绝对的功能守恒定律
    • 提示词的第一条铁律就是: 永远不要改变代码的功能!!!
  2. 强制确保代码风格一致性
  3. 清晰度大于简洁度:
    • 这一点让笔者最开始有点"反直觉". 在 geek community 里,有一种很不好的风气,就是喜欢炫技! 代码越简洁越好, 甚至喜欢用各种"黑魔法"技巧来缩短代码行数...
    • 官方code-simplifier插件的这个提示词,直接对这种行为 Say No!
    • 它遵守: "宁愿代码写得长一点,啰嗦一点,也要让看代码的人一眼就能看懂" 的原则
  4. 拒绝过度简化:
    • 有些时候,为了追求极致的精简,我们可能会把很多不相关的功能硬凑在一起,或者把一些原本有助于理解代码结构的抽象层给去掉了
    • 现在它懂得什么时候该删减,什么时候该保留.不会为了减少代码行数,而牺牲代码的可维护性 5, 聚焦眼下的问题:
    • 它不会试图一次性解决所有问题,而是专注于当前代码段的改进
    • 如果没有特别说明,它默认只改进"最近修改过的代码" (hot-spot原则)

如何使用? 非常简单!

"Use the code-simplifier agent to XXX"

(2) 生成测试用例

众所周知, 写测试用例是非常枯燥乏味的工作, 但是又非常重要. 我们可以通过 claude 来帮助我们完成这个任务:

Bash
1
2
3
4
5
6
7
8
claude "为这个内核函数生成 KUnit 测试用例:

$(cat my_function.c)

要求:
1. 覆盖正常路径
2. 覆盖边界条件
3. 覆盖错误处理路径"

但是注意! 一定要亲自审查生成的测试用例, 确保其正确性与完整性!

(3) 文档生成

写完代码后, 还需要写文档. 这也是一件非常重要的工作, 直接读代码,看注释,读乱七八糟的README文件, 太麻烦. 因此对于用户而言, 一份好的文档是非常重要的.

这里举个例子, 笔者维护的 StarPerf Simulator. 一个要做的事情就是把原本60页的用户文档pdf, 转化成基于Sphinx的在线文档. 参考: StarPerf #PR17

使用方式依然很简单:

Bash
1
2
3
4
5
6
7
8
claude "为这个内核模块生成 kerneldoc 格式的文档:

$(cat my_module.c)

包括但不限于:
- 模块概述
- 每个导出函数的文档
- 使用示例"

Collaboration

Commit Convention

Commit 是指: 一次代码更改的最小单位, 它包含了代码的修改内容以及对这些修改的描述. 一个优秀的 commit message 能够清晰地传达代码更改的意图, 方便代码审查和历史追踪.

因此, 写出清新,有意义的 commit message 是非常重要的!

对于非内核项目,笔者推荐使用 Conventional Commit 格式:

Text Only
1
2
3
4
5
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

(1) 类型包括: feat, fix, refactor, docs, test, chore, ci, perf, revert, style

Type (类型) 含义 说明
feat Feature (新功能) 引入了一个新功能
fix Bug Fix (修复) 修复了一个 Bug
docs Documentation (文档) 仅修改了文档 (如 README, API 文档)
style Styles (格式) 不影响代码含义的修改 (空格, 格式化, 缺少分号等,注意不是 CSS 修改)
refactor Refactor (重构) 既不是修复 Bug 也不是添加功能的代码更改
perf Performance (性能) 提高性能的代码更改
test Tests (测试) 添加缺失的测试或更正现有的测试
build Builds (构建) 影响构建系统或外部依赖项的更改 (如 npm, gulp, broccoli)
ci CI (集成) 修改 CI 配置文件和脚本 (如 Travis, Circle, BrowserStack, SauceLabs)
chore Chores (杂务) 其他不修改 src 或测试文件的更改 (日常事务)
revert Revert (回退) 回退之前的 commit

(2) body 部分用于: 详细描述更改的动机和对比以前的行为

(3) footer 部分用于关闭 issues 或者添加元信息(合作者/参考)

Footer Token 含义 说明与示例
Closes 关闭 Issue 自动关闭 github issue 跟踪器中的存根.

示例:Closes #XXX
Fixes 修复 Issue 更侧重于修复了 bug.

示例:Fixes #XXX
Resolves 解决 Issue Closes.

示例:Resolves #XXX
Refs / See 引用 引用相关联的 issue 或文档, 但不触发关闭操作

示例:Refs #XXX
Co-authored-by 共同作者 给予其他共同贡献代码的人员署名.

示例:Co-authored-by: Name <email>
Signed-off-by 签名 通常用于开源项目,表示开发者同意 DCO (Developer Certificate of Origin).

示例:Signed-off-by: Name <email>
Reviewed-by 代码审查 记录通过谁的人工代码审查.

示例:Reviewed-by: Name <email>
BREAKING CHANGE 破坏性变更 最需要仔细审查的一个 footer. 表示代码不兼容旧版本,相当于语义化版本的 MAJOR (x.0.0).

写法:BREAKING CHANGE: <description>
fix, resolve, close 区别

这三者可以认为没什么区别.仅限语义区别:

  • Fixes #XXX: 用户反馈登录页面报 500 错误,你修复了空指针异常
    • 用 Fixes. (因为它是 Bug)
  • Closes #XXX: 产品经理要求增加一个"dark mode",你开发完成了. -> 用 Closes (因为它不是 Bug)
    • 用 Closes. (因为它不是 Bug)
  • Resolves #XXX: 用户提问“如何配置环境变量?”,你更新了 README 文档回答了这个问题
    • 用 Resolves.

三者触发的动作是一模一样的: 当代码合并到默认分支(main/master)时,系统都会将对应的 Issue 状态从 Open 变为 Closed

示例:

Text Only
1
2
3
4
5
6
7
fix(api): prevent racing of requests

Introduce a request id and a reference to latest request.
Dismiss incoming responses other than from latest request.

Reviewed-by: XXX <xxx@email.xx>
Refs: #XXX

PR Convention

PR (Pull Request) 是指: 在协作开发中,开发者将自己的代码更改提交到一个独立的分支,然后通过 PR 向项目维护者请求将这些更改合并到主分支

(1) 如何提PR

  1. 保持 PR "小而美"
    • 200-400 行代码变更最佳
    • 超级无敌大的 PR (一次更100个文件) 会被忽视或草草审过
  2. 自审后再提交

    • git diff 检查所有变更
    • 用 AI 工具做第一轮审查 (同上!)
  3. 写好 PR 描述

    • 清晰的标题
    • 问题背景
    • 解决方案
    • 测试方法
    • 相关链接

示例:

Markdown
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Description

此 PR 解决了什么问题:
- ...

Related Issue

- Fixes #XXX

Types of changes

- [ ] 🐛 Bug fix (修复 Bug,非破坏性)
- [ ] ✨ New feature (新功能,非破坏性)
- [ ] 💥 Breaking change (破坏性变更,现有功能可能会受影响)
- [ ] 📝 Documentation (仅修改文档)
- [ ] 🎨 Style (代码格式,不影响代码运行的变动)
- [ ] 🤖 CI/Build (CI 配置或构建系统调整)

Testing

1. 运行命令 `npm run test`
2. 打开页面 `http://localhost:3000/xxx`
3. 点击 ...

**环境信息:**

- OS: [e.g. MacOS / Windows]
- Node/Python Version: [e.g. 18.x]

Screenshots

XXX (before vs after)

Checklist

- [ ] 我的代码遵循项目的代码风格 (Lint passed)
- [ ] 我已经对自己提交的代码进行了自我审查 (Self-review)
- [ ] 我已经添加了必要的注释,特别是复杂的逻辑部分
- [ ] 我已经更新了相应的文档 (如果是新功能)
- [ ] 我添加了测试用例,或者已经通过了现有的测试
- [ ] 这是一个 "小而美" 的 PR (行数控制在合理范围内)

(2) 如何审PR

  1. 先审正确性,后审风格
  2. 给出建设性反馈, 而不是 "简单的批评" / "划水式反馈" / "完全不带看的通过(LGTM!)"
    Text Only
    1
    2
    3
    4
    5
    ❌ "This code is bad. Why are you doing a linear search?"
    ❌ "Why this?"
    ❌ "LGTM!" (for the first glance)
    ✅ "This could be optimized with binary search for O(log n) 
      instead of O(n), which matters for large datasets."
    
  3. 敢于提问: 不理解就问,这也是学习机会

LLM 辅助写/审PR

(1) 需求下达:

Bash
1
claude "修复那个导致 user_id 为空的 bug,并补充一个测试用例"

(2) 自主执行:

  • Claude 会自己搜索代码
  • AI 自己修改文件
  • AI 自己运行测试 (看 CLAUDE.md 知道怎么跑测试)
  • 如果测试挂了,它会自己修,直到测试通过

(3) 自动提 PR:

Bash
1
claude "把刚才的改动提交,并用 gh 命令行提一个 PR,标题要符合规范"

它会自动生成:

  • 符合 Conventional Commits 的 commit message
  • 符合 PR 模板的 Description(包含测试步骤,关联 Issue)

注意, 现在 claude code 甚至已经有官方支持做PR/与github交互的插件了:

详见本站的另一篇文章: Claude Code常见用法 里的 CC MCP 部分

LLM 辅助 Github Actions

详见本站的另一篇文章: Claude Code常见用法 里的 Claude Code GitHub Actions (with subscription) 部分

Kernel Dev 特有的基于 Maillist 的协作

内核不用 GitHub PR, 而是邮件列表 + patchwork:

Bash
1
2
# 参考: https://patchwork.kernel.org/
发送 patch  邮件列表  维护者审查  回复意见  修改重发  合并

(1) 邮件礼仪:

  • 使用纯文本邮件
  • 回复在引用内容下方
  • 保持专业和礼貌
  • 耐心等待(维护者很忙)

(2) 切忌"脾气大于实力":

patch 被拒绝是常事,正确态度是:

  1. 理解拒绝的原因 (要认识到能当维护者的人, 实力往往比你强很多)
  2. 学习 + 改进
  3. 如有必要,礼貌地讨论
  4. 不要争吵或灌水

TLDR

  1. AI 是助手,不是替代

    • "你是代码的主人, 不是AI的奴仆"
    • 开发者必须理解每一行提交的代码
    • Signed-off-by = 你的责任
  2. 传统流程依然重要

    • "你不能试图改变所有人, 尤其是那些比你还厉害的人"
    • maillist文化
    • checkpatch.pl
    • 如何找到对应的维护者
  3. AI 对很多场景都有价值

    • "AI 是很好的大内总管"
    • 理解复杂代码
    • 自审和检查
    • 润色文档和 commit message
    • 帮助开发者学习内核知识
  4. 保持谦逊

    • "切忌脾气大于实力"
    • 内核社区有几十年的积累
    • 每一条规则都有其原因
    • 先学习,再创新