ai-bindgen:用 Rust 过程宏让 LLM 在编译时帮你写代码,我试了这个「邪门」项目

这玩意儿到底是个啥?
你有没有想过,写代码的时候让 AI 直接帮你写函数体,而且不是在 IDE 里帮你补全,而是在编译的时候——编译器跑的时候就去找 ChatGPT 要代码?
听起来是不是有点离谱?
但还真有人这么干了。有个叫 ai-bindgen 的 Rust 实验项目,就是干这事的。它用 Rust 过程宏(proc-macro),在你 cargo build 的时候偷偷去调 OpenAI 的 API,实现编译时 AI 的 LLM 代码生成。
这就好比什么呢?想象你是个厨师,菜谱上写着"第三步:做一道美味的红烧肉",然后你直接打电话给米其林大厨,让他远程告诉你具体怎么做。菜谱作者压根没写细节,但你端出来的菜确实能吃。
Reddit 上看到这个项目的网友直接给它打上了"cursed"(邪门/被诅咒)的标签——既惊叹于它的骚操作,又担心它随时可能把你坑了。
它长什么样?
代码简单得吓人:
use ai_bindgen::ai;
#[ai]
extern "C" {
#[ai(prompt = "return the n-th prime number, please")]
fn prime(n: i32) -> i32;
}
fn main() {
println!("The 15th prime number is {}", prime(15)); // 47(但愿是对的)
}
看到没?你只需要写个函数签名,加个提示词告诉 AI 你想要啥,剩下的全交给它。
编译的时候,这个宏会:
- 读取你的函数签名和提示词
- 发请求给 OpenAI(或者兼容的 API)
- 把返回的代码塞进函数体
- 正常编译,就像你自己写的一样
用 cargo expand 看生成的代码,你会发现它就是普通的 Rust 代码——循环、条件判断、向量操作,该有的都有。只不过这些代码不是你写的,是 AI 在编译时临时生成的。

等等,Rust 过程宏真能这么玩?
能。
Rust 过程宏本质上就是「编译时运行的程序」。它接收 Rust 语法树(AST),输出新的 Rust 语法树。这些宏不会出现在你的最终二进制文件里,它们只在编译器构建你的代码时运行。
而且 Rust 并没有规定过程宏不能发网络请求。虽然社区一般认为构建过程应该是「确定性的」「可复现的」,但语言层面上并没有禁止你在编译时搞事情。
这个 crate 就是利用了 Rust 元编程的这个自由度:拿着你的函数签名和提示词,去问大模型,然后把答案变成 Rust 代码塞回去。这种编译时 AI 的玩法,确实让人大开眼界。
为什么说它很酷
说实话,第一次看到这玩意儿,我是有点兴奋的。
1. 探索性编程的新玩法
你可以先随便写几个函数签名,让 AI 去填空,看看它生成的代码和你想的是不是一样。用 cargo expand 一看,发现它的实现比你的还优雅,那感觉,就像交作业前偷看了学霸的答案。
2. 教学价值满满
这是一个活生生的教材,告诉你 Rust 元编程能走多远。Rust 过程宏的能力边界在哪?这个项目给出了一个相当极端的答案。
3. 符合人体工学
你不用切换到浏览器,不用复制粘贴,直接在 Rust 代码里写需求,编译时就给你结果。这种体验,怎么说呢,挺爽的。
为什么说它「邪门」
好了,现在让我们成熟一点,认真聊聊这玩意儿的坑。
1. 构建不确定性
同样的代码,今天编译和明天编译,可能生成完全不同的函数实现。模型更新了、网络抖动了、API 返回的结果变了,你的二进制文件就不一样了。
这在 Rust 社区是大忌。Rust 的哲学是「可复现的构建」,CI/CD 系统也是这么假设的。这玩意儿直接把这个前提给掀了。
这就好比你每次做红烧肉打电话给的大厨不一样,有的爱放糖有的爱放盐,味道能一样才怪。
2. 供应链风险
你在编译器最核心的环节引入了一个外部依赖,而且这个依赖还是可变的。API 挂了?编译失败。API 返回的代码有问题?编译通过但运行出 bug。
3. 安全和正确性
这个宏生成的代码会被编译器完全信任。如果 AI 生成了一个有 off-by-one 错误的代码,或者有潜在的 panic,或者更糟——有未定义行为(UB),你压根不知道,除非你的测试能抓住它。
作者自己都说了:“potentially dangerous… run at your own risk (ideally in a sandbox)"(可能有危险,后果自负,最好在沙箱里跑)。
4. 合规问题
构建时发网络请求会泄露元数据(你的提示词、函数签名)。有些公司的安全策略是禁止构建过程中有任何出站网络请求的。

那我能用它吗?
短答案:不能用在生产环境。
长答案:用它的思路,别用它的机制。
网络化的编译时 AI 代码生成和可复现构建、CI 流程、安全策略都是冲突的。但”AI 辅助编程 + 人工审核验证"这个思路是有价值的。
更安全的 AI 辅助编程方案
如果你真的想在 Rust 项目里玩 LLM 代码生成,这里有个更靠谱的模式:
1. AI 生成放在显式步骤里
用 build.rs 或者单独的 CLI 工具来触发 AI 生成,比如 AIGEN=1 cargo run -p gen。普通构建永远不碰网络。
2. 生成的代码提交到仓库
把 AI 生成的代码写到 src/gen/*.rs,然后 commit。下游用户编译的是确定的源码,不是提示词。
3. 锁定生成参数
在生成的文件头部注释里记录模型名、提示词、参数、seed。每次重新生成都能 diff 审计。
4. 基于 trait 的设计
定义 trait 来描述你想要 AI 实现的行为:
// 库代码
pub trait NthPrime {
fn prime(&self, n: i32) -> i32;
}
// 生成的代码(已提交到仓库)
pub struct NthPrimeImpl;
impl NthPrime for NthPrimeImpl {
fn prime(&self, n: i32) -> i32 {
// AI 生成的,但现在是普通的、已提交的 Rust 代码
/* ... */
}
}
5. 属性测试把关
用 proptest 或 fuzzing 来验证生成的代码满足不变量(比如素数的正确性、单调性)。测试不过的代码不准合并。
6. CI 默认离线
CI 只编译已提交的 .rs 文件。重新生成是另一个可选的流水线,需要显式触发。
这样你既能享受 AI 辅助编程的便利,又保持了可复现构建、可审计的 diff、真实的测试保护。

如果你真的想玩玩
好吧,我知道你心痒痒了。这里是安全玩耍指南:
- 读 README 里的警告,设置好
OPENAI_API_KEY和OPENAI_API_MODEL - 用一个全新的、没有任何重要代码的沙箱项目
- 每次都用
cargo expand看看生成了啥 - 给生成的函数写测试,不要盲目信任
- 只用于原型、教学、演示、写博客(比如这篇)
这东西以后会怎么发展?
我觉得有几个有意思的方向:
- 提示词 schema + 验证器:内置函数契约(前置/后置条件),生成器必须满足这些条件,而且自动生成测试
- 检索增强生成:把你自己代码库的代码片段喂给模型,提高一致性
- AI 当脚手架:让 AI 写样板代码,你写核心逻辑。比如生成 serde 的模型和映射器,然后你来微调
最后说两句
ai-bindgen 是那种让 Rust 变得有趣的「野路子」实验——它展示了 Rust 元编程的强大(和锋利)。作为生产指南,它是个反面教材。作为学习 Rust 过程宏的工具,它是金子。
用 AI 辅助编程来加速你的 Rust 开发——但别用它来搞乱你的构建。保持 LLM 代码生成过程显式化、代码签入仓库、测试严格把关、默认离线构建。这才是编译时 AI 的正确使用姿势。
项目地址:germangb/ai-bindgen
相关技术:ai-bindgen | Rust过程宏 | LLM代码生成 | 编译时AI | Rust元编程 | AI辅助编程
看到这里的朋友,如果这篇文章对你有帮助,或者让你对 Rust 过程宏和 Rust 元编程有了新的认识,不妨动动手指:
- 点个赞:让更多人看到这个有趣的项目
- 转发分享:你的 Rust 爱好者朋友可能也会感兴趣
- 收藏一下:以后想玩的时候方便找到
有什么想法或者问题,欢迎在评论区聊聊。你觉得这种「编译时调 AI」的骚操作,是未来趋势还是昙花一现?