EnriqueMark
ai運用

rust在ai開發中的優勢

2026-07 繁體中文

我最近一直在想rust的特性,這種強編譯時驗證的語言可以把大部分潛在問題都攔截在編譯期,意味著哪怕不寫測試,它只要寫出來天然就是一個自帶測試的語言,這種高度可驗證的特性讓其非常適合 ai 時代。甚至說,如果我能通過一套良好的設計,把業務邏輯直接包裹在它的型別驗證裡面,在一定程度上甚至節省了寫測試的功夫。

當然我不覺得它能代替測試,但至少作為約束可以限制ai的胡亂發揮。其次是它直接把class砍了,強迫你只能用組合去實現業務,也連帶著把一些潛在的耦合危險消除了,從結構上就保證了邊界必須清晰。而ai時代最需要的就是清晰,做不到這一點agent在編碼時就會飄,而為了防止他飄,我必須用大量的「可驗證」內容去保證他的正確性。

// C#
User user = GetUser();     // 可能返回 null
Console.WriteLine(user.Name);  // 编译过。运行时如果 user 是 null → NullReferenceException

// Rust
let user: Option<User> = get_user();
println!("{}", user.name);  // ❌ 编译直接失败:Option<User> 没有 .name 这个字段

而像上述這種編譯期前置的特性,也迫使編寫者必須在編譯期就去處置潛在的不存在情況,否則會直接過不了編譯,因而從根源上就堵住了一些編譯上很完美,但執行時出錯的邊界突破問題。ai編碼最怕的就是程式碼看上去沒問題,但執行時才炸掉的情況——而此種情況下,找bug會浪費大量的時間,這也是開發時最棘手的問題。

其次則是多併發時的競爭問題,所有權這個rust最獨特的特性,可以將這種執行時才會出現的問題,直接在編譯期暴露出來。比如對於單一依賴的變數,完全可以將所有權(或使用權)固定(或臨時固定)在使用者身上,直到他使用完再釋放,這期間其他併發競爭者會直接無法使用,從編譯上就直接解決爭搶問題。當然,這一套對天然就是共享的變數無效(比如計數器),那這個時候,rust會迫使你用Mutex去明確處理這個問題,將無法在編譯時檢測的問題強迫顯示,而不像其他語言一樣自覺的鎖去維護。

// 共享计数器,下面的写法会出错
let mut counter = 0;
let handle = thread::spawn(|| {
    counter += 1;     // 新线程想改 counter
});
counter += 1;         // 主线程也想改 counter

use std::sync::{Arc, Mutex};

// Arc:多线程共享所有权;Mutex:同一时刻只放一个线程进去改
// 被迫显式处理此种共享情况
let counter = Arc::new(Mutex::new(0));   
let c = Arc::clone(&counter);
let handle = thread::spawn(move || {
    let mut num = c.lock().unwrap();   // 想碰里面的值?先拿锁。拿不到就等着
    *num += 1;
});                                    // num 离开作用域 → 锁自动释放

換言之,在rust的情況下,競爭問題要麼用所有權保證單一時刻只有一個使用者,要麼就是用顯式處理將邊界明確包裹在編譯好的處理範圍內。

我始終覺得,要保證 AI 的質量,可驗證性非常重要。測試只是這種可驗證性的一個體現之一。但是從語言層面上怎麼去保證可驗證性呢?那就是像 Rust 的設計哲學一樣,把一切都顯式化,讓它明確的在編譯時就暴露各種各樣問題出來,沒寫好就直接不過編譯,把該約束的都約束完全,這種東西從來都是人寫起來會很痛苦的玩意,可 AI 根本就不在意這些,就無論怎麼看都非常合適。

編譯層面上保證一切都顯式化的嚴格約束,就像 Rust 這樣。而另一條同樣的必不可少的方面,就是在業務邏輯的層面上,用測試,尤其是強覆蓋的測試去保證。而一套設計嚴格的語言,可以讓編寫測試的時候更加方便。比如說單測、整合測試。如果這個語言從編譯上就把你各種各樣的混同,乃至不可測試的寫法給極大程度遏制了——或者應該這樣講,rust本身的設計使得一套指定良好的結構成為了預設選擇,儘管爛程式碼還是無法靠語言保證,但只要遵循基本的原則,其基底質量就會是較高的。

一段程式碼是否可測試,嚴格意義上來講是結構所保證的,而語言只是工具,一個規定更嚴格的語言就是好用的工具,我在這個層面上贊同rust。但沒說規定不嚴格的語言就不能用結構去保證。像 TS 啊、 Python 呢,也能通過純函式的形式去保證測試。但是對於 AI 來講,它會有一些編譯上的問題,以及要編寫更多執行時才會暴露出來的問題。對 Rust 來講,它可以在編譯期間就直接解決。因為執行時的問題麻煩點在於,你不知道會遇到什麼,Rust 它那種迫使你去覆蓋邊界的兜底強制要求,就會把很大一部分執行時才暴露的問題,至少收住一個尾,不至於災難性崩塌。而且其實這個角度上去考慮的話,還涉及到一個 loop 的問題。尤其是那種自動化執行的 AI,如果你不給它一個明確的錯誤導向,它根本就沒辦法去 debug,這是很難的。它不像人類一樣能去察覺到某些味道。所以說,一個顯式的漂亮的錯誤處理,對於 AI 的 debug 來說非常重要。