AI News HubLIVE
站内改写

UIテストはAIに必要なガードレール:clipboardwireの物語

Waylandでのクリップボード同期の問題に悩まされた著者が、Claude Codeを使ってJavaプロジェクトClipCascadeをRustに書き換え、軽量バイナリのclipboardwireを作成した。発見した要点は、AIのボトルネックはコード生成能力ではなくフィードバックの質であり、UIテストが信頼性のある反復を可能にするガードレールだということ。

記事インテリジェンス

エンジニア中級

要点

  • テストがないと、AI生成コードはバグ修正のループに陥り、新しいバグを生むことがある。
  • UIテストを含む包括的なテストスイートへの投資が、AIの信頼性と速度を劇的に向上させた。
  • 人間の主な貢献は、コーディングではなく方向性の決定(認証の簡略化、脅威モデル、Wayland優先)にあった。
  • 完成したツールclipboardwireは単一バイナリで数MBのRAMしか消費せず、500MBヒープのJavaソリューションを置き換えた。

重要な理由

このニュースが重要なのは、テストがないと、AI生成コードはバグ修正のループに陥り、新しいバグを生むことがあるためです。

技術的影響

モデル選定、推論コスト、プロダクト能力、評価基準に影響する可能性があります。

昨年12月以来、著者は日常的なイライラに耐えていた。彼は2台のマシンを同時に使っている:Waylandを搭載したUbuntuノートパソコンと、Deskflow(旧Synergyの無料版)を使ってLinuxボックスから操作するWindows PCだ。キーボードとマウスは完璧に同期するが、クリップボードが同期しない。DeskflowはX11ではクリップボードを同期できるが、Waylandとは互換性がない。

KDE Connectなどの代替案を試したが、いずれも不安定だった。ある日は機能しても翌日には動かず、再起動や再ペアリングが必要になることが頻繁にあった。常時利用可能であるべきツールにとって、この不安定性はないより悪い。結局、Google Chatを経由して自分にクリップボードを送信するという手間のかかる方法を取らざるを得なかった。

フォーラムで有望な代替案を見つけた:ClipCascadeだ。Linuxクライアント、Windowsクライアント、中央ハブでメッセージを転送する。まさに求めていたものだった。しかし、それはSpring Boot上のJavaアプリケーションで、推奨最小ヒープサイズは500MBだった。自分のネットワーク内でテキストを同期するだけのために、半分ギガバイトのメモリを消費するプロセスを動かしたくはなかった。著者はブラウザを閉じ、Claude Codeを開いた。

「Rustに移植しよう」

著者は本格的なRustコードを書いたことがなかった。本を2章ほど読んだ程度で、プロダクションで使ったことはない。Rustを選んだ理由は2つ:単一バイナリでランタイム不要、そしてメモリ安全な言語であること。ネットワーク上でポートをリッスンするプロセスを動かすなら、バッファオーバーフローよりもパニックで終わってほしい。また、最初からWaylandをX11より優先すると明示した。

Claude Codeとの作業には独特のリズムがあった。高レベルの指示を与え、その間に別の仕事をし、後で戻って差分を確認し、次の指示を出す。数日後には、ネットワーク上で動作するものができた。2つのクライアント、ハブ、WebSocketメッセージ、基本認証。使い始めるには十分だった。

しかし、バグが発生し始めた。バグを報告するとClaudeが修正するが、しばらくすると同じバグが戻ってきたり、新しいバグが発生したりした。AIには「以前ここを修正した」という記憶がない。著者は、問題はClaudeではなく、修正が他の機能を壊していないか確認する手段がないことだと気づいた。このアプリケーションはシステムトレイアプリで、グラフィカルUIと非同期動作を持つため、手動テストでは困難だ。

そこで著者は丸一日かけて、グラフィカルUIを含むテストスイートの作成をClaudeに依頼した。プッシュごとに実行されるスモークテスト、DBus経由のLinuxトレイメニューテスト、UI Automation APIを使ったWindowsトレイアイコンテスト、egui_kittestを使った設定ダイアログのUIテスト、シングルトンロックをチェックする統合テスト。CIはプッシュごとにLinuxとWindowsですべてのテストを実行する。

テストができてからすべてが変わった。AIが何かを壊したらすぐにわかり、修正が実際に正しいことも確認できる。著者は、テストは「やるべき」という負担ではなく、AIエージェントが道を外れないためのガードレールだと結論づけた。

著者が自分で下した重要な決定:

  • 認証の簡略化:ClipCascadeの複雑な認証を、TLS上のHTTP Basic認証に置き換えた。自分のLAN内ではPBKDF2など不要。
  • 正直な脅威モデル:ハブはTLS終了後にプレーンテキストのクリップボードを参照する。クライアント間のエンドツーエンド暗号化は意図的に実装していない。信頼するネットワーク内では、E2EEはセキュリティシアターになる。
  • 単一バイナリの3モード:同じ実行ファイルがクライアント(connect)、ハブ(serve)、またはその両方(host)として動作する。
  • トレイアプリ、デーモンではない:トレイアイコンがリアルタイムの状態を表示し、ペーストする前に状態を確認できる。

Waylandについて、著者は「問題なく動作した」と述べている。GTK + libayatana-appindicatorの実装が初回で成功し、X11フォールバックも不要だった。これは、DeskflowがWaylandをサポートしていないために始まった物語としては価値のある教訓だ。

著者が得た3つの予想外の教訓:

  • ボトルネックはAIが受け取るフィードバックの質であり、コード生成能力ではない。手動デバッグでは速度ゼロ、テストによる二値信号で速度が倍増した。
  • 著者の本当の仕事は方向性の決定であり、プログラミングではない。認証の簡略化、Wayland優先、脅威モデルの定義、UIテストの推進はすべて製品・アーキテクチャの決定であり、コードではない。
  • 「Rustを知らない」という障壁は数時間で消えた。Rustを学んだわけではないが、diffを読み全体構造を理解することで、Rustプロジェクトを指導できるようになった。それは解放的である一方、何かが失われているという複雑な感情も残る。

プロジェクト名はclipboardwire、github.com/davefx/clipboardwireで公開されている。リリースごとに.deb、.rpm、.msiパッケージが用意され、macOS版も準備中。著者は毎日LinuxとWindowsの間で使い、サーバは数MBのRAMしか消費しない。Ctrl+CがGoogle Chatを経由せずに届くようになった。