tensor4all GitHub

誰も逐行で読まないコードをどう検証しているか

tensor4all の Rust スタックの大半は AI エージェントが書いており,我々はそれを逐行でレビューしていません.代わりに何をしているかを説明し,どこまで信頼してよいかを利用者自身が判断できるようにするための記事です.

by 品岡 寛(埼玉大学),tensor4all チームを代表して

🌐 English · 日本語

なぜこの記事を書くのか

tensor4all のスタック(tenferro-rs,tensor4all-rs,およびその下のカーネル群)は大きく,そのほぼすべてをコーディングエージェントが書いています.利用者からは当然,「作者が全行を読んでいないのに,なぜ結果を信じられるのか」という疑問が出ます.

我々の答えはこうです.数値計算コードの信頼性は,逐行レビューだけで担保できたことはありません.レビュアーは見落とし,コードが大きくなるほど見落としは増えます.我々にできるのは,信頼を機械へ移すことです.毎日コードを検査し,結果を公開し,壊れたら大きな音を立てる仕組みです.これがなければ,エージェントの力を使い切れません.エージェントは人間がレビューできる速さを超えてコードを書くので,検査を自動にしない限り,その速さは無駄になります.

tenferro-rs の紹介記事ではこの考え方を短く述べました.本記事では,実際に動いている仕組みを層ごとに説明します.規模の目安として,2026年11月4日時点でスタックは9リポジトリ(tenferro-rs,tensor4all-rs,strided-rs,tcontract-rs,tlinalg-rs,cpueinsum-rs,hataori-rs,tidu-rs,computegraph-rs,テスト込み)で空行を除き約93万行の Rust コードからなり,これに faer のフォークへ追加した約3万6千行が加わります.

図は英語版と共通です.

原則:検査を走らせ続ける

一度だけ走った検査は,ほとんど何も証明しません.コードは毎日変わり,依存も動き,先月速かったベンチマークは今日について何も語りません.そこで我々の検査で最も重要な性質は,定期的に,現在の main に対して走り,結果を公開することです.監査とオラクルの再生は毎日,CPU と GPU のベンチマークは毎週末に走ります.

参照データは独立したリポジトリに置いています.勾配データは tensor-ad-oracles に,性能比較は tenferro-benchmark,tensor4all-benchmark,およびライブラリごとのベンチマークにあります.こうしておくと,参照データの変更はそれ自体が独立した変更として見え,ライブラリのどの版に対しても参照データを再実行できます.

下の図はこのループを示しています.図中の super agent と監査ボットは後の節で説明します.

main に対して走り続ける検査

自動微分の正しさ

誤った勾配は最も気づきにくいバグです.プログラムは動き,損失は下がり,結果だけが微妙にずれます.我々は勾配を,自分たちの推論ではなくデータベースと照合しています.

また,AD 規則のファイルは行カバレッジではなく数値検査で保証すると決めています.カバレッジの数字を上げるためだけのテストを書くことは,そこでは明示的に禁止しています.

線形代数カーネルの正しさ

実例:SVD スイートが捕まえたパニック

10月下旬,SVD スイートが f32 と c32 でパニックを報告しました.svd が「buffer is not large enough」で止まったのです.作業領域は,同じ引数で呼んだ svd_scratch が見積もったものでした.最小の再現例は,分割統治法で計算する 8×8 のランク1行列で,V だけを求める場合でした.

修正(tensor4all/faer#73)では,バッファに余裕を足すのではなく,作業領域の見積もりそのものを直しました.各マージ段階で同時に生きている一時領域を数えるようにしています.修正前に失敗し修正後に通る回帰テストを加え,再帰の境界付近の 4,800 回の呼び出しが4つの型すべてで通り,その後 18,172 回のスイート全体も呼び出しの失敗なく完了しました.同じ実行で,f32 の直交性に関する別の問題も見つかり,#75 として別に追跡しました.この作業領域のバグは上流の faer 0.24.4 にもあるため,再現プログラム付きの上流向け報告を用意しました.

性能

HPC では,性能の退行は誤った答えに近いほど高くつき,しかも何も失敗しないので見落としやすいものです.我々はこれも同じように扱います.

規約と,規約の検査

異なる機関の複数の共同研究者が,同じコードにそれぞれ自分のエージェントを走らせています.共通の規約がなければ,各グループのエージェントが同じ失敗を別々に繰り返し,同じ問いに別々の答えを出すことになります.

そこで,リポジトリをまたいで成り立つ規約は,公開の一か所 tensor4all-agent-rules にまとめ,エージェントと人間の貢献者の両方が従います.内容は,リポジトリ構成と依存境界,リリースの安全性,性能のチェックリストと性能主張の計測方法,ドキュメントとテストの方針(たとえばドキュメントのコード例は一つも飛ばさない),第三者の仕事のクレジット,Rust と Julia の数値・性能の規則などです.各リポジトリの AGENTS.md は短く保ってここを指し,その上に tenferro-rs の REPOSITORY_RULES.md や PERFORMANCE_TIPS.md のようなリポジトリ固有の規約が載ります.

最初の規則は「実装が文書に優先する」です.文書とコードが食い違えば,欠陥は文書の側です.規約で防げたはずの失敗をエージェントがすると,その規約を足し,全共同研究者のエージェントがそれを取り込みます.

ただし規約は文章にすぎないので,機械で強制できるものは CI が強制します.

ワーカーと保守者の間に立つ監督エージェント

コードを書くエージェントに,リポジトリを任せきりにはしていません.日々の実装の大半は,安価なモデルで動くワーカーエージェントが担います.その上に監督役のエージェント,「super agent」(監督エージェント)がいて,注意深い保守者が担う役割を果たします.

super agent は上で述べた機械的な検査を置き換えるものではありません.何を作り,いつ止まるかを決めるのが super agent で,結果が正しく速いかを決めるのは,あくまでオラクル,ベンチマーク,CI です.

super agent が複数のマシン上のエージェントを動かす体制

大量のプルリクエストと issue をどう捌いているか

小さなグループでどうやって追いついているのか,とよく聞かれます.2026年11月4日までの30日間に,8つのリポジトリ(tenferro-rs,tensor4all-rs,strided-rs,tcontract-rs,tlinalg-rs,cpueinsum-rs,faer のフォーク,tenferro-benchmark)で,約920件のプルリクエストがマージされ,約570件の issue が開かれ,約600件が閉じられました.これを回せている理由は次のとおりです.

一つの変更が main に入るまで

マージ済みのコードの監査

CI がプルリクエストを検査するのは一度だけです.先月通ったコードも,周囲が変われば今日は誤っているかもしれません.そこで,マージ済みのコードにも定期的な監査を走らせています.監査は非公開のリポジトリから運用し,報告は通常の公開 issue で行います.

監査役は issue を開き,退行ベンチマークのジョブはプルリクエストを開きます.どちらも他のすべての変更と同じゲートを通ります.

これが保証しないこと

限界もはっきりさせておきます.

信頼できない結果を見つけたら issue を開いてください.それが検査の穴を示しているなら,修正にはコードの変更だけでなく新しい検査も含めます.