编程 Bun 百万行 Rust 重写背后:AI 代码生成的速度与安全之辩

2026-06-15 14:50:27 +0800 CST views 11

Bun 百万行 Rust 重写背后:AI 代码生成的速度与安全之辩

2026 年 5 月 14 日,一个编号为 #30412 的 PR 被合并进 Bun 的主分支。超过 100 万行 Rust 代码、6755 次提交,几乎全部由 Claude Code 智能体在短短 9 天内生成完成。这个 PR 的体积大到把 GitHub 的页面渲染直接搞崩——你点开它,浏览器只会转圈。

Bun 的创建者 Jarred Sumner 在公开场合说了一句话:"我们已经好几个月没有亲手敲代码了。"这句话让一个本该是日常代码合并的事件,演变成了 Hacker News 上 685 分热度的讨论帖,PR 本身的点赞和点踩数量几乎各占一半。

有人说这是 AI 编程的里程碑,有人说这是"vibecoded 垃圾"的典型。但如果你仔细看,这场争论的核心并不是"AI 行不行",而是一个更深层的问题:当代码生成的速度远超代码审查的速度,我们该如何证明这些代码值得信任?

这篇文章不站队,只拆解。我会从架构决策、迁移策略、unsafe 争议、AI 代码验证方法论四个维度,把这件事的技术逻辑彻底讲透。

背景:为什么是 Rust,为什么是现在

Zig 的困境

Bun 从诞生起就是 Zig 语言的旗舰项目。Zig 有它的优势:零隐藏控制流、comptime 元编程、与 C 的无缝互操作。但 Zig 的痛点同样明显:

  • 语言本身还在快速迭代,经常引入破坏性变更,Bun 团队不得不维护自己的 Zig fork
  • Zig 项目有严格的反 AI 贡献政策,Bun 团队用 AI 辅助做的编译器优化无法合并到 Zig 上游
  • 内存安全靠程序员自律,use-after-free、double-free 这些经典 bug 在大型 Zig 代码库中难以杜绝

Jarred Sumner 多次在公开场合提到,Zig 代码库让团队花费了大量时间去调试内存相关问题。对于一个每天处理数十亿次请求的 JavaScript 运行时来说,这种调试成本不是可以忽略的小事。

Anthropic 收购的催化剂

2025 年 12 月,Claude 背后的 Anthropic 收购了 Bun。外界普遍认为,Anthropic 看中的不仅是一个每月下载量超过 700 万次、GitHub 星标超过 9.2 万的 JavaScript 运行时,更是一块验证 AI 编程能力的最佳试验田。

几个月后,这个判断得到了验证——如果从结果倒推的话。

迁移的技术约束

Bun 团队给这次迁移定了两个关键约束:

  1. 相同的架构设计——不推倒重来
  2. 相同的数据结构——保持内存布局兼容

这意味着重写不是"重新设计",而是"翻译"。用 Jarred 的话说,是"用更安全的语言替换底层实现"。Bun 依然使用极少的第三方库,依然不依赖 async Rust。

这个约束决定了后面发生的一切。

迁移策略拆解:忠实翻译 vs 惯用重写

两种迁移哲学

把一个项目从语言 A 迁移到语言 B,本质上只有两条路:

路线一:忠实翻译(Faithful Translation)

  • 逐文件、逐函数地翻译
  • 保持原有架构和数据结构不变
  • 遇到目标语言不支持的模式,用 unsafe/escape hatch 绕过
  • 优点:行为一致性好,测试通过率高
  • 缺点:目标语言的优势发挥不出来

路线二:惯用重写(Idiomatic Rewrite)

  • 基于规范(spec)重写,原代码只作参考
  • 使用目标语言的惯用写法和安全机制
  • 需要完整的行为规范文档
  • 优点:真正获得目标语言的安全/性能收益
  • 缺点:工作量大,行为一致性需要更多验证

Bun 选择了路线一,而且是以 AI 为执行者的路线一。

为什么选忠实翻译?

从工程决策的角度看,这个选择并不难理解:

  1. Bun 有庞大的测试套件——忠实翻译能最大化测试通过率,用测试套件作为迁移正确性的主要验证手段
  2. AI 翻译比 AI 设计更可靠——LLM 擅长模式匹配和代码翻译,不擅长从零开始做架构设计
  3. 时间压力——Anthropic 需要一个足够轰动的 AI 编程案例来证明收购的价值
  4. Zig 的实现已经稳定——与其冒险重新设计,不如在已验证的架构上"换皮"

从结果看,99.8% 的测试通过率证明了这个策略在"行为一致性"这个维度上是成功的。

但问题在于,Bun 团队公开给出的重写理由是安全性,而忠实翻译策略恰恰无法实现安全性目标。

这两者之间的张力,才是整个事件的核心。

unsafe 争议:一万个绕过编译器的后门

数据对比

迁移后的 Bun Rust 代码中,分布在 700 多个文件里的 unsafe 代码块超过了一万个。

为了理解这个数字意味着什么,我们需要一个参照物:uv——同样来自 Python/JS 生态领域、体量也大致相当的 Rust 项目,整个项目中只有 73 个 unsafe 块。

这不是数量级上的小差异,而是整整相差两个数量级。

为什么会有这么多 unsafe?

原因很简单:每当原始 Zig 代码中的逻辑无法通过 Rust 借用检查器验证时,迁移过程就会使用 unsafe 来绕过限制。

Rust 的借用检查器(borrow checker)是 Rust 安全保证的核心机制。它通过所有权(ownership)、借用(borrowing)和生命周期(lifetime)三个概念,在编译时确保:

  • 不会有悬垂指针(dangling pointer)
  • 不会有数据竞争(data race)
  • 不会有缓冲区溢出(buffer overflow)
  • 不会有 use-after-free

unsafe 关键字本质上是对借用检查器说:"相信我,我知道自己在做什么。"一旦使用了 unsafe,上述所有保证都可能失效。

在惯用的 Rust 代码中,unsafe 只在极少数不可避免的地方使用(比如 FFI 调用、底层内存操作),并且每一个 unsafe 块都有详细的安全论证(safety comment)。

但在 Bun 的忠实翻译中,unsafe 变成了一种"翻译胶水"——每当 Zig 的手动内存管理模式无法映射到 Rust 的安全抽象时,就用 unsafe 糊过去。

忠实翻译的悖论

这里出现了一个深刻的悖论:

  • 测试通过率高,是因为翻译足够忠实
  • unsafe 数量多,也是因为翻译足够忠实

忠实翻译的目标是"让新代码的行为和旧代码一模一样",这个目标实现了。但旧代码本身就是一套手动内存管理的系统,忠实翻译只是把它变成了"披着 Rust 外衣的手动内存管理实现"。

借用检查器恰恰在这些地方失去了作用——而这些地方,恰恰是它原本最应该发挥价值的地方。

一个关键的错失机会

开发者 Todd Smith 指出,事情未必一定会发展成这样。Bun 团队完全可以设置约束,例如明确规定"禁止使用 unsafe",甚至通过 Git 的 pre-commit hook 在提交前强制检查。

// 理想中的迁移方式:寻找安全抽象
// Zig 代码: 手动管理缓冲区
// fn process_buffer(buf: [*]u8, len: usize) void { ... }

// Rust 忠实翻译(当前做法):
unsafe {
    let buf_ptr = buf.as_ptr();
    // 直接操作裸指针,绕过借用检查器
    std::ptr::copy(src, buf_ptr, len);
}

// Rust 惯用重写(应该做的):
fn process_buffer(buf: &mut [u8]) {
    // 借用检查器保证安全
    buf.copy_from_slice(&src[..buf.len()]);
}

在"禁止 unsafe"的限制下,一个足够优秀的大语言模型理论上会寻找其他实现方式,在迁移过程中逐步引入真正的内存安全机制。

当然,即便如此,也仍然需要大量人工审查。而正如 Todd 所说的那样,这本身就已经构成了一个充分理由:不要轻易尝试这种迁移方式。

AI 代码验证:一个尚未解决的难题

测试通过率不等于安全性

这是整个事件中最需要被理解的一点:

99.8% 的测试通过率与超过 1 万个 unsafe 引用之间,其实并不存在任何矛盾。

它们本质上是在描述同一件事:

  • 测试通过率如此之高,是因为这次迁移足够忠实
  • unsafe 数量如此之多,同样也是因为这次迁移足够忠实

测试套件验证的是行为一致性(behavioral equivalence)——新实现的外部可观察行为是否与旧实现一致。而安全性是一个实现属性(implementation property)——底层实现是否真正避免了内存安全问题。

这两个维度完全正交。一个全部通过的测试套件,只能说明新实现的行为与旧实现一致。如果旧实现本身是一套依赖手动内存管理的系统,而新实现只是对它进行了忠实翻译,那么测试全部变绿所证明的,仅仅是:翻译工作完成得很好。

至于底层实现是否真正安全,测试套件完全无法告诉你。

unsafe 验证的学术前沿

验证 Rust 中一段 unsafe 代码是否真正安全,本身就是一件极其困难的事情。

Amazon 曾联合 Rust 基金会发起专门的社区项目,目的就是验证 Rust 标准库中的 unsafe 代码。这个标准库远比百万行智能体生成的运行时代码规模小得多,也经过了更严格的审查,而且是由人工编写的。

之所以需要专门成立这样的项目,是因为 unsafe 代码重新打开了通往未定义行为(undefined behavior)的大门。只要某个 unsafe 代码块中存在一个错误,就可能让周围所有依赖 Rust 类型系统保护的代码失去保障。

事实上,即便是 Rust 标准库本身,在过去这些年里也出现过二十多个可以追溯到 unsafe 代码的 CVE 漏洞——尽管这些代码已经接受了数十年专家级别的审查。

当前学术界在验证 unsafe Rust 方面最先进的方法,也不过是:

  1. 半自动化分析工具——如 Miri(Rust 的未定义行为检测器),可以检测部分 UB,但覆盖率有限
  2. 形式化验证器——如 Prusti、Kani,需要人工编写规范,且仍是实验性工具
  3. 模糊测试(Fuzzing)——可以触发部分 UB,但无法穷举所有路径

不存在一个按下按钮就能完成的"让这段 unsafe 代码变得安全"的工具,而且在可预见的未来,也看不到这种工具出现的可能。

代码生成与验证的不对称

这是真正值得关注的问题:

代码生成能力正在指数级扩张,而代码验证能力却没有。

9 天生成 100 万行代码,但审查这 100 万行代码需要多少人力和时间?按照一个经验丰富的 Rust 开发者每天审查 500 行关键基础设施代码的速度,审查完 100 万行代码需要 2000 个工作日——大约 8 年。

当然,这不是说每行代码都需要同等级别的审查。但即使只有 10% 的代码(10 万行)需要深度审查,也需要接近 1 年的时间。

而在这期间,新的代码还在以更快的速度生成。

这种不对称,才是整个事件真正值得关注的新闻。而且这并不仅仅是 Bun 的问题——Bun 可能只是迄今为止规模最大、曝光度最高的案例而已。

从工程实践看:如果你要做一个类似的迁移

假设你是一个技术负责人,面对类似的迁移决策,应该怎么做?基于 Bun 的经验教训,以下是一个更合理的迁移框架。

第一步:产出完整的行为规范

在写任何代码之前,先产出一份详细的行为规范文档。这份规范应该描述:

## 模块:HTTP Server

### 外部可观察行为
- 监听指定端口,接受 TCP 连接
- 解析 HTTP/1.1 和 HTTP/2 请求
- 支持请求体流式读取,背压传播
- 超时行为:连接超时 30s,请求超时 60s
- 错误行为:端口占用返回 EADDRINUSE

### 性能约束
- 单连接吞吐 ≥ 100k req/s(hello world 场景)
- 内存占用 ≤ 10MB/1000 并发连接
- P99 延迟 ≤ 2ms(本地回环)

### 安全属性
- 不存在 use-after-free
- 不存在数据竞争
- 不存在缓冲区溢出
- unsafe 块数量上限:50 个,每个必须有 safety comment

第二步:约束 AI 的迁移策略

# 迁移约束配置
constraints:
  max_unsafe_blocks: 50        # 全局 unsafe 上限
  require_safety_comments: true # 每个 unsafe 必须有安全论证
  forbid_raw_pointers: true     # 禁止裸指针操作
  prefer_safe_abstractions: true # 优先使用安全抽象
  
  # Pre-commit 检查
  pre_commit_hooks:
    - command: "cargo clippy -- -D clippy::unsafe_removed_from_name"
    - command: "cargo geiger"  # 统计 unsafe 使用量
    - command: "./scripts/check_unsafe_count.py --max 50"

第三步:分阶段迁移,而非一次性替换

// 阶段一:建立安全的外部接口层
// 新代码用惯用 Rust,旧代码通过 FFI 调用

mod http_server {
    // 安全的 Rust 接口
    pub struct Server { 
        inner: OwnedServer  // 封装底层实现
    }
    
    impl Server {
        pub fn listen(addr: &str) -> Result<Self, ServerError> {
            // 安全抽象层
        }
        
        pub async fn accept(&self) -> Result<Connection, ServerError> {
            // 安全抽象层
        }
    }
}

// 阶段二:逐模块替换底层实现
// 每次替换一个模块,保持测试通过
// 新模块用惯用 Rust,不使用 unsafe

// 阶段三:移除所有 FFI 桥接
// 全部迁移完成后,删除旧代码的 FFI 绑定

第四步:建立验证管道

#!/bin/bash
# CI 验证管道

# 1. 标准测试
cargo test --all-features

# 2. Miri 检测未定义行为
cargo miri test --target x86_64-unknown-linux-gnu

# 3. AddressSanitizer
RUSTFLAGS="-Z sanitizer=address" cargo test --target x86_64-unknown-linux-gnu

# 4. ThreadSanitizer
RUSTFLAGS="-Z sanitizer=thread" cargo test --target x86_64-unknown-linux-gnu

# 5. 模糊测试关键路径
cargo fuzz run http_parser -- -max_total_time=3600

# 6. unsafe 计数检查
UNSAFE_COUNT=$(cargo geiger 2>/dev/null | grep "unsafe" | wc -l)
if [ "$UNSAFE_COUNT" -gt 50 ]; then
    echo "FAIL: unsafe count ($UNSAFE_COUNT) exceeds threshold (50)"
    exit 1
fi

这个框架的核心思想是:让 AI 在约束下工作,而不是在自由下工作。 约束不是限制 AI 的能力,而是确保 AI 的输出落在可验证的范围内。

对行业的启示

AI 辅助迁移的正确姿势

Bun 的案例告诉我们,AI 辅助代码迁移是一把双刃剑。关键不在于 AI 能不能写代码——答案已经是"能"。关键在于我们如何定义"成功"。

如果"成功"的定义是"测试全部通过",那 Bun 的迁移已经成功了。但如果"成功"的定义是"真正获得了 Rust 的安全保证",那这次迁移还有很长的路要走。

正确的方法论应该是:

  1. 先定义你想要的目标属性(安全性、性能、可维护性)
  2. 设计验证手段来度量这些属性(不仅限于测试通过率)
  3. 让 AI 在约束下迁移(限制 unsafe、要求 safety comment)
  4. 分阶段验证,而非事后验证

代码审查的未来

Bun 的案例暴露了一个更深层的行业问题:当代码生成速度远超审查速度时,我们如何保证代码质量?

传统的代码审查模式是人工逐行审查。这个模式在 AI 辅助开发时代面临根本性挑战——没有人能以每天 10 万行的速度审查代码。

可能的解决方案包括:

  • 自动化形式化验证工具——但如前所述,这仍是开放研究问题
  • 分层审查策略——AI 生成的代码只做结构级审查,关键路径做深度审查
  • 契约驱动开发——先定义接口契约,AI 在契约约束下生成实现
  • 渐进式信任——AI 生成的代码先在沙箱中运行,通过生产流量灰度验证后才获得信任

但这些方案都还在探索阶段,没有银弹。

对 Rust 生态的影响

Bun 的迁移对 Rust 生态有两个截然不同的影响:

正面影响:

  • 向业界证明了大规模 Rust 迁移是可行的
  • 让更多开发者关注 Rust 作为 C/C++/Zig 替代方案的可能性
  • 推动了 AI 辅助 Rust 开发的工具链建设

负面影响:

  • "10000+ unsafe" 可能被误读为"Rust 也就那样",损害 Rust 的安全声誉
  • 可能导致其他团队效仿这种忠实翻译策略,产生更多披着 Rust 外衣的不安全代码
  • 让人对 AI 生成 Rust 代码的质量产生不信任

真正对 Rust 生态有益的,是惯用重写——真正利用 Rust 的安全机制,而不是用 unsafe 绕过它们。

实战:如何用 Rust 惯用写法替代 unsafe 模式

让我们看几个典型的"忠实翻译 unsafe"场景,以及如何用惯用 Rust 重写。

场景一:字符串缓冲区操作

// ===== 忠实翻译(unsafe)=====
unsafe fn process_string(buf: *mut u8, len: usize, input: &str) {
    // 直接写入裸指针,不做边界检查
    std::ptr::copy_nonoverlapping(input.as_ptr(), buf, len.min(input.len()));
}

// ===== 惯用 Rust(safe)=====
fn process_string(buf: &mut [u8], input: &str) -> usize {
    let bytes = input.as_bytes();
    let copy_len = bytes.len().min(buf.len());
    buf[..copy_len].copy_from_slice(&bytes[..copy_len]);
    copy_len
}

惯用写法的优势:

  • 借用检查器保证 bufinput 不会同时被可变引用
  • 边界检查由切片操作自动完成
  • 没有未定义行为的风险

场景二:自引用数据结构

// ===== 忽略忠实用 unsafe =====
// Zig 中常见的自引用结构,在 Rust 中需要特殊处理

// ===== 惯用 Rust:使用 Pin + 安全抽象 =====
use std::pin::Pin;

struct SelfReferential {
    data: String,
    // 指向 data 的引用,通过 Pin 保证安全
    pointer: *const str,  // 但我们用安全封装
}

// 更好的方式:使用 ouroboros crate 或手写安全封装
#[ouroboros::self_referencing]
struct SelfReferential {
    data: String,
    #[borrows(data)]
    pointer: &str,
}

// 或者用索引替代指针
struct SelfReferentialSafe {
    data: String,
    pointer_range: (usize, usize),  // 用索引范围代替指针
}

impl SelfReferentialSafe {
    fn get_pointer(&self) -> &str {
        &self.data[self.pointer_range.0..self.pointer_range.1]
    }
}

场景三:并发数据共享

// ===== 忠实翻译(可能用 Mutex<RawPtr> 或 Arc<UnsafeCell>)=====
struct SharedBuffer {
    ptr: Arc<UnsafeCell<Vec<u8>>>,
}

unsafe impl Sync for SharedBuffer {}  // 危险!手动声明 Sync

// ===== 惯用 Rust =====
struct SharedBuffer {
    data: Arc<Mutex<Vec<u8>>>,  // Mutex 提供安全同步
}

// 或使用无锁结构
struct SharedBuffer {
    read_buf: Arc<RwLock<Vec<u8>>>,  // 读写锁,适合读多写少
}

// 或使用 crossbeam 的无锁队列
use crossbeam::queue::SegQueue;
struct SharedBuffer {
    queue: SegQueue<u8>,  // 完全无锁,完全安全
}

场景四:FFI 桥接层的安全封装

// ===== 忠实翻译:裸 FFI 调用散落各处 =====
unsafe fn call_javascript_runtime(ctx: *mut JSContext, code: *const c_char) -> *mut JSValue {
    jsc_evaluate_script(ctx, code, std::ptr::null_mut(), std::ptr::null(), 1)
}

// ===== 惯用 Rust:安全封装层 =====
mod js_runtime {
    use std::ffi::CString;
    use std::os::raw::c_char;

    pub struct JSValue(*mut bindings::JSValue);
    pub struct JSContext(*mut bindings::JSContext);

    // unsafe 被限制在最小范围内
    impl JSContext {
        pub fn evaluate(&mut self, code: &str) -> Result<JSValue, JSError> {
            let c_code = CString::new(code)
                .map_err(|_| JSError::NulByte)?;
            
            // unsafe 块尽量小,且附带安全论证
            let result = unsafe {
                // SAFETY: c_code 保证是有效的 C 字符串
                // self.0 保证指向有效的 JSContext(由构造函数保证)
                bindings::jsc_evaluate_script(
                    self.0,
                    c_code.as_ptr(),
                    std::ptr::null_mut(),
                    std::ptr::null(),
                    1,
                )
            };
            
            if result.is_null() {
                Err(JSError::RuntimeError)
            } else {
                Ok(JSValue(result))
            }
        }
    }
    
    // JSValue 的 Drop 实现,确保资源释放
    impl Drop for JSValue {
        fn drop(&mut self) {
            unsafe {
                // SAFETY: JSValue 只能通过 evaluate 创建,保证有效
                bindings::js_value_release(self.0);
            }
        }
    }
}

关键原则:

  1. unsafe 块尽量小——只包裹真正需要 unsafe 的操作
  2. 安全论证(SAFETY comment)——每个 unsafe 块解释为什么这段操作是安全的
  3. 安全封装——对外暴露的接口全部是 safe 的
  4. 资源管理——用 Drop trait 确保资源释放,避免 use-after-free

性能视角:Rust 重写真的更快了吗?

Bun 的官方基准测试显示,Rust 版本与 Zig 版本相比性能持平甚至略有提升,二进制文件体积也缩小了几兆字节。

这看起来是个好消息,但需要注意:

  1. 当前版本还在优化中——Jarred Sumner 坦诚提醒,优化工作仍在进行
  2. 大量 unsafe 意味着编译器优化空间受限——unsafe 代码绕过了借用检查器,也绕过了部分优化机会
  3. 真正的性能收益可能来自后续的惯用重写——当 unsafe 逐步被安全抽象替代后,编译器能做更积极的优化
// unsafe 可能阻碍优化的例子
unsafe fn process_array(data: *const u8, len: usize) -> u8 {
    let mut sum = 0u8;
    for i in 0..len {
        // 编译器不知道 data[i] 是否会与 sum 别名
        // 因此无法做向量化优化
        sum = sum.wrapping_add(*data.add(i));
    }
    sum
}

// safe 版本,编译器可以做更好的优化
fn process_array_safe(data: &[u8]) -> u8 {
    // 编译器知道 data 不会与其他引用别名
    // 可以安全地进行 SIMD 向量化
    data.iter().fold(0u8, |acc, &b| acc.wrapping_add(b))
}

所以,当前的"性能持平"可能还不是终点。如果 Bun 团队能逐步将 unsafe 替换为安全抽象,Rust 版本的性能天花板实际上比 Zig 版本更高。

对开发者的实际影响

如果你在用 Bun

  • 短期风险不大——忠实翻译意味着行为一致,99.8% 的测试通过率说明基本功能是稳的
  • 长期需要关注——10000+ unsafe 块意味着潜在的安全漏洞,尤其是边缘场景
  • 建议:生产环境使用 stable 频道,canary 频道仅用于测试

如果你在考虑类似迁移

  • 不要照搬 Bun 的策略——忠实翻译适合作为第一步,但不应该是最后一步
  • 先规范,再迁移——产出详细的行为规范,让 AI 在规范约束下工作
  • 限制 unsafe——设置全局上限,每个 unsafe 都要有安全论证
  • 分阶段验证——测试 + Miri + ASan + TSan + Fuzzing,多维度验证
  • 预留审计资源——迁移完成不是结束,而是审计的开始

如果你在做 AI 辅助开发

  • 约束比自由更重要——给 AI 明确的边界(禁止 unsafe、要求特定模式),产出质量反而更高
  • 测试不是唯一的验证——行为一致性 ≠ 实现正确性 ≠ 安全性
  • 人类审查不可省略——AI 生成的代码需要以基础设施级别的标准审查
  • 记录决策过程——每个 AI 生成的关键决策都应该有人工评审记录

结语:速度不是唯一的度量

Bun 的 Rust 重写在工程上是一个令人惊叹的成就——9 天、100 万行代码、99.8% 测试通过率。这些数字足以让任何开发者感到震撼。

但如果我们诚实地面对这些数字背后的技术逻辑,就会发现一个更微妙的事实:

一个全部通过的测试套件,只能说明翻译工作完成得很好。它完全无法告诉你:这套系统是否真正安全。

真正能够回答"是否安全"这个问题的指标,是大家最想看到、却至今没人能够给出的那个指标。因为如何可靠地证明这一点,直到今天依然是一个尚未解决的难题。

Bun 的迁移得出的结论不是"AI 不行",也不是"Rust 不行"。Rust 是优秀的语言,AI 也是优秀的工具——前提是像使用其他工具一样,以负责任的方式使用它。

真正值得吸取的,是一种评估和验证的思维方式:当有人拿测试通过率来证明某种安全属性时,首先确认测试套件是否真的在测量那个属性。

行为一致性和内存安全性,是两个完全不同的维度。速度和质量,也不是同一个维度上的两个方向。

当你看到"AI 在 N 天内完成了 X 行代码的重写"这样的标题时,别急着感叹速度。先问一个更根本的问题:

这些代码,谁审查了?怎么审查的?审查够了吗?

答案可能不如速度那样令人兴奋,但它远比速度重要。


参考资料:

复制全文 生成海报 Rust AI编程 代码迁移 Bun unsafe 代码安全

推荐文章

Vue3中的自定义指令有哪些变化?
2024-11-18 07:48:06 +0800 CST
三种高效获取图标资源的平台
2024-11-18 18:18:19 +0800 CST
解决 PHP 中的 HTTP 请求超时问题
2024-11-19 09:10:35 +0800 CST
网站日志分析脚本
2024-11-19 03:48:35 +0800 CST
API 管理系统售卖系统
2024-11-19 08:54:18 +0800 CST
liunx服务器监控workerman进程守护
2024-11-18 13:28:44 +0800 CST
程序员茄子在线接单