先月の羊皮紙で書いたWinUI 3という荒野への探索から、数週間が経った。あの時は「気まぐれで踏み込んでみた」という話だった。DataGridという道具が存在しないことに驚き、XAMLの無言クラッシュという砂嵐に揉まれ、それでも前進を選んだ純粋な探索の記録。
今は違う。目的を持って、何かを錬成している最中だ。
この羊皮紙は完成の話ではない。錬成の途中で見えてきたもの――AIと組む本格開発とはどういうことか、WinUI 3の猛獣とは今どう向き合っているか――を、公開前の今のうちに書き残しておくための記録だ。
Claude CodeとGeminiを組み合わせてWinUI 3アプリを本格開発した途中経過。設計書駆動の開発プロセス、AES-256-GCMとArgon2idを使ったセキュアな設計とAIの関係、DispatcherQueueやXAMLの沈黙といったWinUI 3固有の罠の実体験をまとめた。
荒野の探索記が、錬成の記録に変わった。何を作っているかはしばらく伏せる。しかし「どう作っているか」は今書ける。AIが地図を広げ、旅人が道を選ぶ。その哲学が、一枚の設計書と無数のコミットを経て、実体を持ってきた。
この羊皮紙のあらまし
この羊皮紙が導く者
- Claude CodeやGeminiを使った本格アプリ開発に興味があるあんた
- WinUI 3の現場の話が知りたい開発者
- 設計書を先に作り、AIをレビュアーとして活用する開発プロセスを模索しているエンジニア
- AIが出す「正しい答え」とは何かを、体験談として掘り下げたい探求者
- 近いうちに何かが公開されるらしいが、その前振りが気になっているあんた
砂漠の道標
- WinUI 3 ― Microsoftが提供する最新のWindowsアプリ開発魔法体系(フレームワーク)。WPFの後継とされるが、互換はない
- Claude Code ― Anthropicのコード生成・レビューAI(電脳の相棒)。今回のゴーレム錬成でメインを担当
- Gemini ― GoogleのAI(第二の相棒)。設計の俯瞰的な妥当性検証とクロスチェック役として活用
- AES-256-GCM ― 現代の暗号化標準。データを鍵なしでは読めなくする護符の一種
- Argon2id ― 鍵の導出に使うアルゴリズム。ブルートフォース攻撃への耐性が高い
- DispatcherQueue / TryEnqueue ― WinUI 3でUIスレッドへ仕事を投げる仕組み。失敗しても黙っているという罠を持つ
- SQLite ― 組み込み型の軽量宝物庫(データベース)。ファイル一つに全データを格納できる
- BLOB ― バイナリデータをそのまま格納するデータ型。文字列(TEXT)と区別される
- NavigationView ― WinUI 3のサイドナビゲーションコンポーネント。WPFのものとは別物
- WebView2 ― EdgeのレンダリングエンジンをWindowsアプリに埋め込む仕組み。外部プロセス依存という性質を持つ
本格錬成の記録
先月の記事では「WinUI 3という荒野に踏み込んだ」という話を書いた。あれは純粋な探索だった。DataGridという道具がないという現実に直面し、XAMLの洗礼を受け、それでも前進した記録。
今は探索ではない。設計書があり、目的があり、錬成が進んでいる。完成品ではないが、方向は決まっている。近いうちに、このゴーレムを砂漠に解き放つ予定だ。
AIは地図を広げ、旅人が道を選ぶ ― セキュアな設計を詰める
今回のゴーレムは、守るべきものがある設計が必要なアプリだ。最初の判断として、データを平文のままSQLite(宝物庫)に保存するという選択肢を最初から封じた。全フィールドをAES-256-GCMで暗号化し、鍵の導出にはArgon2idを採用する設計を選んだ。
ここでClaude CodeとGemini、二体の相棒に設計の妥当性を問うた。両者ともに同じ方向の答えを出してきた。しかし、パラメータの具体的な選定理由については「一般的に推奨される値」という回答が返ってきた。
その答えは正しかった。ただし、「一般的に正しい」という意味において。このアプリが想定する脅威モデルに対してどのパラメータが最適かは、設計の意図を知っている人間にしか判断できない。AIは地図を広げてくれるが、どの道を行くかは旅人が決める。
もう一つ、面白い気づきがあった。TEXTカラムに文字列として保存した瞬間、メモリ上に不変のインスタンスが生まれ、GCの都合次第でいつまでも残留する。だからバイナリBLOBとして格納する――という設計判断をAIに投げると、判断の妥当性は「正しい」と答えた。しかし実際のコード提案では、文字列を使いがちなコードが出てくることがある。「正しいと言いながら、提案では違う実装をする」という現象を、何度か目撃した。
ここが人間の判断が必要な瞬間だ。
設計書が先で、コードは後 ― 三者会議という開発プロセス
通常のアプリ開発は、コードを書きながら設計が固まっていく。今回は順序を逆にした。要件定義書・基本設計書・各機能の設計書という文書群を先に作り、それをAIとのレビューにかけ、矛盾を潰してからコードに落とす手順を踏んだ。
Claude Codeに設計書を渡して問題点を指摘させ、Geminiに同じ設計書を渡してクロスチェックする。二体の相棒が同じ問題を指摘したときはほぼ確実に修正が必要で、意見が割れたときは自分で判断する。この三者会議が、設計の質を上げる最も効果的な手段だった。
役割分担はこうなっている。Claude Codeはコード生成と設計レビューをメインに担当した。Geminiは設計の俯瞰的な妥当性検証と、Claude Codeの死角を突く役割として使った。二体を同じ問いにぶつけるのではなく、役割を分けて専門性を引き出す使い方が、今回の開発で定着してきた。
AIへの問いが「一般的にどうすべきか」である限り、AIは正しく答える。しかし「このアプリの文脈ではどちらが正しいか」という問いになった瞬間、その判断は設計書の意図を知っている人間にしかできない。三者会議という仕組みは、その非対称を補うための構造として機能した。
WinUI 3の猛獣たち、その後 ― 把握してきた罠と残る牙
先月の記事で「荒野に洗礼を受けた」と書いた。あれから、猛獣の習性を多少把握してきた。しかし手懐けた、とは言えない。
DispatcherQueueとTryEnqueueの罠。WinUI 3でバックグラウンド処理中にUIを更新するには、DispatcherQueueにTryEnqueueで仕事を投げる。問題は、これが失敗しても例外を投げないことだ。戻り値のboolを見ていなければ、UIの更新が黙って失敗する。WPFのDispatcher.InvokeはUIスレッドが生きていれば確実に動いたが、WinUI 3はそうではない。AIのコード提案でもこの戻り値を捨てているコードが頻繁に出てきた。自分で気づいて修正した箇所の一つだ。
NavigationViewとページ遷移の罠。WPFのFrameとPageに相当するものがWinUI 3にもあるが、挙動がかなり異なる。折りたたみ状態でのヘッダー表示の挙動は、ドキュメントを読んでも直感的に理解しにくく、AIの提案も複数の矛盾する実装が混在した。結局、実際に動かして確認するしかなかった。
XAMLの無言クラッシュ。これが一番の難敵だ。先月の記事でも触れたが、今も時々遭遇する。XAMLのバインディング記述で型が合わないと、コンパイルエラーではなく実行時の無言クラッシュとして現れる。スタックトレースすら出ないケースもある。AIはXAMLのコードを提案するときにバインディング先の型を正確に把握していないことが多く、動かないコードを自信満々に出してくることが何度もあった。WinUI 3においてAIのXAML提案を信用しすぎると、原因不明の沈黙という最悪の砂嵐に遭遇する。
設計変更の話も一つ書いておく。当初PDFの表示にWebView2を検討したが、外部プロセス依存・Edge常駐という性質が今回のゴーレムの設計思想と相容れなかった。Windows.Data.Pdfというネイティブの仕組みでPDFをメモリ上でラスタライズする方式に切り替えた。AIはWebView2を第一候補として提案してくることが多かったが、設計思想と照らして判断を変えた典型例の一つだ。
このゴーレムはまだ砂漠を歩いていない。テストが続いている。設計が崩れた箇所は直し、AIが提案した実装でも問題があれば差し戻す。完成した道具はいずれ解き放つ予定だ。
羊皮紙を巻く前に
荒野への探索記が、本格的な錬成の記録へと変わった。この数週間で分かったことを整理しておく。
AIと組む開発の優れた点
- 設計の一貫性を保つレビュアー ― 人間は文書の意図を忘れる。AIは常に与えられた文書に基づいて一貫した答えを出す。矛盾の発見に強い
- 二体のクロスチェック体制 ― Claude CodeとGeminiが同じ問題を指摘するなら修正確実、意見が割れるなら人間が判断する。この構造が設計の質を上げた
- 役割分担による専門性の引き出し ― コード生成役と俯瞰役を分けることで、一体に全てを問うより精度が上がった
- 選択肢の高速展開 ― 「一般的に正しい答え」を素早く並べてもらい、自分で選ぶ。この速度は一人では出せない
注意点
AIの答えは「一般的に正しい」という範囲で正確だ。しかし「このアプリの文脈で正しいか」という問いには、設計の意図を知っている人間だけが答えられる。XAMLの提案を信じすぎる危険、TryEnqueueの戻り値を捨てたコードの放置、文字列保存とBLOB保存の使い分け――いずれも、AIの出力をそのまま使わずに自分で確認した箇所だ。
まとめ
AIと組む開発は、旅人の判断力を免除するものではない。地図が増えるだけだ。どの道を行くかは相変わらず旅人が決める。それを理解した上で使えば、一人では出せない速度と品質が手に入る。
来月、このゴーレムが砂漠に解き放たれる予定だ。そのとき、今書けなかった話を全部書く。
砂漠で見つけた魔法のランプ
- WinUI 3 ドキュメント | Microsoft公式。荒野の地図はここから
- DispatcherQueue.TryEnqueue メソッド | 戻り値を捨てるな、という話の公式リファレンス
- Windows.Data.Pdf 名前空間 | WebView2を使わずPDFをラスタライズする道
- Argon2 - パスワードハッシュ関数 | Password Hashing Competition優勝アルゴリズムの原典
- Claude Code 公式サイト | 電脳の相棒の正体
ラクダの独り言
またご主人が夜中まで光る板と向き合っている。今度はAIに地図を広げてもらいながら、どの道を行くかは自分で決める、という錬金術らしい。聞くけど鵜呑みにはしない、と言うが、それなら最初から全部自分でやればいいんじゃないかとも思う。人間ってのはそういうものなのかもな。もうすぐ完成するらしい。砂漠を渡り切るまで、俺も付き合うとしよう。