Back to Blog
RustTauriAIコーディングコンパイルエラーLLM活用

AIにRustを書かせて詰まった場所を全部分類した——Tauriバックエンドで出たコンパイルエラーと、人間が介入すべき境界

【編集メモ(公開前に削除)】 件数・割合・ツール名・日付など、実際の検証ログが必要な箇所は 【要記入】 としています。実測値に差し替えてください。数値のない定性的な記述(エラーの性質や Tauri の仕様)は一般的な Rust / Tauri の挙動に基づいています。


AIにRustを書かせて詰まった場所を全部分類した——Tauriバックエンドで出たコンパイルエラーと、人間が介入すべき境界

リード:AIが書いたRustは、どこまでコンパイルを通ったのか?

Tauri(Rustでデスクトップアプリを作るフレームワーク)のバックエンドをAIに実装させ、発生したコンパイルエラーをすべて記録・分類する検証が【要記入:実施時期】に行われた。コンパイルエラーとは、プログラムを実行可能な形に変換する段階でコンパイラ(変換ソフト)が出す「このままでは動かせない」という指摘のことである。

検証の前提は次のとおり。

項目 内容
対象機能 ファイルの読み書き、設定の保存・読み込み、フロントエンド(画面側)とのコマンド連携
使用したAIツール 【要記入:ツール名・モデル名・バージョン】
Tauriのバージョン 【要記入:v1 または v2】
試行条件 機能ごとに【要記入】回生成し、エラーが出るたびにAIへ修正を依頼。エラー全文を渡す
記録対象 発生したコンパイルエラーの総数【要記入】件

結論を先に述べると、エラーの多くはAIが自力で修正できた一方、データの持ち主をどう設計するかといった判断を伴う一部のエラーでは、人間の介入が必要だったと見られる。以下、その内訳と、介入の目安を整理する。

なぜRustはAIにとって難しいと言われるのか?

所有権と借用チェッカーという独特の仕組み

Rustには所有権(値を誰が持っているかを厳密に管理する仕組み)と、その規則を検査する借用チェッカー(コンパイラの機能)がある。

Excelに例えると、同じセルを複数人が同時に書き換えられないよう、ファイルを開く時点で強制的にルールが適用される仕組みと言える。共有ブックで「他のユーザーが編集中です」と表示される状況が、実行前の段階で厳密に検査されるイメージである。

誤りが「エラー」として見えやすい

他の多くの言語では、似た誤りが実行時に初めて問題化する場合がある。Rustでは実行前の検査が厳しいため、AIの出力の誤りがコンパイルエラーとして表に出やすい。AIの弱点が可視化されやすい言語であり、同時に、誤りを見逃しにくい言語でもあると位置づけられる。

Tauri特有の「重なり」

Tauriのバックエンドでは、次の要素が同時に絡む。

  • 非同期処理(時間のかかる処理の完了を待たずに他の作業を進める仕組み)
  • 状態管理(アプリ全体で共有するデータの保持)
  • フロントエンドとのデータ受け渡し(画面側のJavaScriptとRust側の間でのやり取り)

所有権のルールが、非同期と状態共有の文脈で複雑に作用する構造であり、AIにとって難度が上がりやすい領域と見られる。

実際にどんなコンパイルエラーが出たのか?分類の方法と全体像

分類の軸

エラーは2つの軸で分類した。

軸1:原因

  • 型(データの種類の不一致)
  • 所有権
  • ライフタイム(参照が有効である期間)
  • 非同期
  • 依存関係(外部ライブラリ=クレートの扱い)
  • API仕様(ライブラリの使い方の誤り)

軸2:修正の主体

  • AI単独:エラーメッセージを渡すだけで解消
  • 人間の指示で解決:人間が方針やヒントを与えて解消
  • 人間が設計変更:データ構造や処理の構成を人間が見直して解消

件数の分布(クロス集計)

Excelのピボットテーブルのように、原因×修正主体で見ると全体像をつかみやすい。

原因\修正主体 AI単独 人間の指示で解決 人間が設計変更 合計
型 【 】 【 】 【 】 【 】
所有権 【 】 【 】 【 】 【 】
ライフタイム 【 】 【 】 【 】 【 】
非同期 【 】 【 】 【 】 【 】
依存関係 【 】 【 】 【 】 【 】
API仕様 【 】 【 】 【 】 【 】
合計 【 】 【 】 【 】 【 】

頻出カテゴリと「1回で直った割合」

  • 発生件数の上位カテゴリ:【要記入:1位〜3位】
  • 修正指示1回で解消した割合:全体で【 】%
  • カテゴリ別では、型・構文系で高く、ライフタイム・非同期系で低い傾向が見られた【要記入:実測で確認】

以降の章では、この表の「列」ごとに、どんな性質のエラーが並んだのかを見ていく。

AIが自力で直せたエラーにはどんな特徴があったのか?

修正方針がメッセージに書いてあるエラー

Rustコンパイラのエラーメッセージは、原因と修正案が具体的に書かれていることで知られる。AI単独で解消したエラーには、次のようなものが多かった。

  • 型の不一致:String が必要な箇所に &str を渡した、など
  • use宣言の漏れ:必要な機能の取り込み(use)を書き忘れた
  • 軽微な構文ミス:セミコロンや括弧の過不足
  • トレイト(共通の機能を定義する仕組み)の未実装:#[derive(...)] の付け忘れなど

たとえば次のようなエラーである。

error[E0308]: mismatched types
expected `String`, found `&str`
help: try using a conversion method: `.to_string()`

このメッセージを貼るだけで、AIは .to_string() を補って解消した。Excelで言えば、「数値が入るべきセルに文字列が入っています」という警告に従ってセルの書式を直すような作業に近い。

共通項は「ローカルで完結する」こと

これらの修正は、変更箇所が1か所か数行に収まり、他の関数やデータ構造の設計に影響しない。影響範囲が局所的で、正解が実質1つに定まるエラーは、AIに任せやすいと見られる。

借用チェッカーとライフタイムのエラーでAIが詰まったのはなぜか?

修正するたびに別のエラーが出る堂々巡り

人間の介入が必要になった事例の中心は、借用チェッカーとライフタイムに関するものだった。典型的なのは、次のような経過である。

  1. 関数が参照(データの「貸し出し」)を返そうとして「ライフタイム指定が必要」とのエラーが出る
  2. AIが 'a などのライフタイム指定を追加する
  3. 今度は「参照先の値が先に破棄される」というエラーが出る
  4. AIが別の箇所に指定を足す
  5. さらに別のエラーが出て、最初の状態に近い形へ戻る

【要記入:この堂々巡りが発生した件数と、収束までの修正回数】

エラーを「消す」ための対処に流れやすい

詰まった場面では、設計意図から外れた対処が見られた。

  • clone() の多用:データを丸ごとコピーして所有権の問題を回避する。動くが、大きなデータでは無駄が増え、「共有して更新する」という本来の意図が失われる場合がある
  • 参照を避ける:本来は参照で渡すべき箇所を、所有権ごと渡す形に書き換える
  • 'static の付与:「アプリ終了まで有効」と宣言して検査を通す。根本解決にならない場合がある

Excelでたとえるなら、「セルの参照エラー」を解消するために、数式を値で貼り付けてしまうような対処である。エラーは消えるが、元データが変わっても結果が更新されなくなる。

本質は「誰がデータを持つか」という設計判断

これらのエラーの根底には、そのデータの所有者を誰にするかという問いがある。設定データを、アプリ全体で共有する状態として持つのか、読み込みのたびに生成して返すのか。この判断はコードの一部を直すだけでは決まらず、機能の使われ方の理解が前提になる。局所的な修正では解決しにくく、人間が方針を決める領域と言える。

Tauri特有の非同期処理・状態管理ではどこで問題が起きたのか?

Mutexと非同期ランタイム

Tauriでは、アプリ全体で共有するデータを State(状態)として管理し、複数のコマンドから参照する。更新の競合を防ぐため Mutex(同時に1か所からしか書き換えられないようにする「鍵」)で包むのが一般的である。

ここで次のようなエラーが見られた。

  • ロックを保持したまま await(非同期処理の待ち)をまたぐ:標準ライブラリの Mutex のロックを持ったまま待機すると、Send(スレッド間で安全に受け渡せる条件)を満たさないというエラーになる
  • Send / Sync 関連のエラー:Sync は複数のスレッドから同時に参照しても安全であることを示す条件
error: future cannot be sent between threads safely

このメッセージは原因の箇所が分かりにくく、AIが「Arc で包む」「tokio::sync::Mutex に変える」と試行錯誤するパターンが確認された【要記入:件数】。どちらが適切かは、ロックを保持する時間や処理の流れによって変わるため、構成の判断が要る。

コマンドの引数・戻り値の制約

フロントエンドからRustの関数を呼ぶ #[tauri::command] には、データの受け渡しに制約がある。受け渡しにはシリアライズ(データを送れる形式に変換すること。ここではJSON形式)が使われる。

  • 引数は Deserialize、戻り値は Serialize を実装している必要がある
  • エラー型にも Serialize が必要で、std::io::Error をそのまま Result のエラーとして返すとコンパイルが通らない
  • 非同期コマンドで &str のような参照型の引数を使う場合は、戻り値を Result にする必要がある

これらはTauri固有のルールであり、一般的なRustの知識だけでは気づきにくい。AIは Result<T, String> に変換する形で対処することが多かったが、エラーの種類を後から区別したい場合には不向きで、エラー処理の方針を人間が決めたうえで型を設計し直す必要があった【要記入:該当事例】。

v1とv2の混在

Tauriにはv1とv2があり、APIが大きく変わっている。一例を挙げる。

項目 v1 v2
パス取得 tauri::api::path 系の関数 app.path() 経由
ファイル・ダイアログ等 本体に内蔵 プラグインとして分離
権限設定 tauri.conf.json の allowlist capabilities(権限定義ファイル)

AIの出力には、v2の指定にもかかわらずv1の書き方が混ざる現象が見られた【要記入:件数】。学習データにはv1の情報が多く含まれていることが一因と見られる。

依存クレートやバージョン差によるエラーはAIに任せられるのか?

存在しないメソッドの生成

クレート(Rustのライブラリ)は、バージョンアップでAPIが変わる。AIは古いバージョンの書き方を前提にするため、次のような誤りが出た。

  • 現在は存在しないメソッドや関数の呼び出し
  • 名称が変更された型の使用
  • Cargo.toml(依存ライブラリを管理する設定ファイル)に必要な機能指定(features)が足りない

エラーメッセージは「そのメソッドは見つからない」と伝えるだけで、正しい代替が何かまでは示さない場合がある。このとき、AIがもっともらしい別名を推測して再びエラーになる流れが見られた。

情報を渡すと改善した

次の情報を明示的に渡すと、解消率が上がった【要記入:渡す前後の比較】。

  • Cargo.toml の内容(使用バージョンの確定)
  • 公式ドキュメントの該当箇所
  • 移行ガイドの抜粋(v1→v2など)

最新情報は人間が補給する領域

AIの知識は学習時点で固定されるため、変化の速いライブラリでは、最新の仕様を人間が探して渡す運用が有効と見られる。Excelのバージョン違いで関数が使えないとき、公式のヘルプを確認して手順を伝えるのと似た作業である。

人間が介入すべき境界はどこにあるのか?

判断基準

検証の結果から、境界は次のように整理できる。

介入が不要な領域(AIに任せやすい)

  • エラーメッセージに修正案が含まれる機械的なエラー
  • 変更が1関数の中で完結するもの
  • use 追加、型変換、derive 付与など

介入が必要な領域

  • データの所有権の設計
  • 非同期構成(どのMutexを使い、どこで待つか)
  • エラー処理の方針
  • セキュリティ権限(Tauriの許可設定)

セキュリティ権限は、コンパイルエラーとして現れにくい点に注意が必要である。Tauriは、画面側からアクセスできるファイルやAPIの範囲を設定で制限する。AIが「動かすために」広い権限を付与しても、コンパイルは通る。エラーが出ないぶん、人間の確認が不可欠な領域と位置づけられる。

目安:2〜3回で収束しなければ設計を疑う

同じ種類のエラーが2〜3回の修正で収束しない場合は、局所修正の限界に達しているサインと言える。この段階で、人間が設計の見直しに入るのが目安になる。

境界チェックリスト

  • エラーメッセージに「help:」で修正案が出ているか → 出ていればAIに任せる
  • 修正が1関数内で完結するか → 完結するならAIに任せる
  • 同じエラーが2〜3回の修正で収束したか → 収束しなければ人間が設計を見直す
  • clone() や 'static が急に増えていないか → 増えていれば設計意図を確認する
  • 非同期とMutexの組み合わせで詰まっていないか → 構成を人間が決める
  • 存在しないメソッドが出ていないか → 使用バージョンと公式資料を渡す
  • 権限設定が広がっていないか → 最小限かどうか人間が確認する

AIにRustを書かせる際、実務ではどう進めればよいのか?

プロンプトで先に伝えること

  • 設計方針:データを誰が持つか、共有状態の有無
  • 使用バージョン:Tauri、主要クレートのバージョン(Cargo.toml を貼る)
  • 制約条件:非同期ランタイムの種類、エラー型の方針、追加してよい依存の範囲

運用のコツ

  • 小さな単位で生成し、そのたびにコンパイルする。大量に生成してから直すと、エラーが連鎖して原因の切り分けが難しくなる
  • エラーログは要約せず全文を渡す。コンパイラのメッセージが修正の手がかりになる
  • 大きな変更を指示する前に、現在のコードをバージョン管理(変更履歴の記録)しておく

Rustならではの利点

Rustは、コンパイラが厳格な検査役として機能する。AIが書いたコードの誤りを人が目で全部追わなくても、一定の水準まではコンパイラが検出してくれるため、検証コストを抑えやすい点は利点と見られる。ただし、コンパイルが通ることと意図どおりに動くことは別であり、動作確認とテストは別途必要である。

非エンジニアの実務者が検討する際の留意点

  • エラーの文面が読めなくても、「全文をAIに渡す」「2〜3回で直らなければ専門家に相談する」という基準を持てば運用できる
  • 権限設定やデータの保存先など、業務データの扱いに関わる部分は、動くかどうかだけで判断せず、技術者のレビューを入れることが望ましい
  • Excelのマクロ開発と同様、「誰が保守するのか」を最初に決めておく必要がある

まとめ:AIとRustの協業で見えた分担のあり方とは?

  • 機械的なエラーはAI、設計判断は人間という分担が現実的と言える。エラーメッセージに修正方針があるものはAIが自力で解消し、所有権・非同期構成・エラー方針・権限といった設計に関わるものは人間の判断が必要だった
  • Rustのコンパイラの厳格さが、AI出力の品質担保に寄与している側面がある。誤りが実行前に表面化するため、AIとの相性は一概に悪いとは言えないと見られる
  • 今回の検証の限界:
    • 対象範囲:ファイル操作・設定管理・コマンド連携に限られる
    • モデル:【要記入:使用モデル】のみで、他のAIでは傾向が異なる可能性がある
    • 時期:【要記入:時期】時点の結果であり、モデルやTauri、クレートの更新で変わりうる
    • 試行回数が限られており、統計的な一般化には至らない

AIの進化やドキュメント参照機能の拡充により、境界線は今後移動する可能性がある。ただ、「データを誰が持ち、どこまで権限を与えるか」という判断の責任は、当面は人間側に残ると見られる。

Share:
View all posts