Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AIに任せられるFlutterコードベースを作る 〜仕様をコードで表し、ハーネスで守る〜

Avatar for Yohei Maeda Yohei Maeda
October 29, 2026

AIに任せられるFlutterコードベースを作る 〜仕様をコードで表し、ハーネスで守る〜

FlutterKaigi 2026 での発表資料です。

2025年、AI に実装を任せられるようになり、アプリエンジニア以外のメンバーも Flutter アプリの実装に参加するようになりました。一方で、アプリエンジニアの頭の中にあったアーキテクチャのルールが共有できておらず、レビューでの指摘と往復が増えました。

この発表では、申請・経費精算のモバイルアプリを題材に、AI に任せられるコードベースをどう作ってきたかをお話しします。

- 仕様をコードで表す: 明細の種類や金額を sealed class などの型で表し、ルールに反するコードをコンパイラや lint で止める
- ハーネスで守る: 決定的に表せるものは型・lint・CI に置き、表せない知識だけを Skill と Subagent で AI に渡す
- 結果で評価する: eval(AI の振る舞いの単体テスト)で、AI がルールを読めているかを確かめる
- 育てる: レビューの指摘から Skill の更新を AI が提案するループを回す

任せられる範囲は、AI の能力ではなく、アーキテクチャとハーネスで決まる、という考え方をまとめています。

Avatar for Yohei Maeda

Yohei Maeda

October 29, 2026

More Decks by Yohei Maeda

Other Decks in Technology

Transcript

  1. final me = Engineer('yohei'); yohei myohei LayerX バクラク事業部 (2023-09 -)

    バクラク 申請・経費精算 プロダクトエンジニア Android → Go → Flutter(約5年) 最近は Go が多め(書いているのは AI) © LayerX Inc.
  2. 前半: 背景 1. 仕様をコードで表現する 2. なぜ仕組みで守るのか アジェンダ 後半: AI と作るハーネス

    3. AI ハーネスを作る 4. 仕組みを評価する 5. 仕組みをメンテする 締め 6. 結果と課題 7. まとめ
  3. 1. ① 明細の種類 1つの申請に、按分する明細としない明細が並ぶ 開く 30,000円を 営業部 50% マーケティング部 50%

    申請(明細が2つ) © LayerX Inc. 会食を、営業部とマーケティング部で 50% ずつ 7
  4. 1. ② 金額 外貨にも対応した金額を、型で分ける 日本円は金額だけ。外貨は通貨・金額・レートを持つ(USD 200.00 × 150.00 = 30,000円)

    明細の種類ごとに、使える金額の型が決まっている どちらも円換算できる → 承認経路は円で判定する © LayerX Inc. 9
  5. 1. ③ 承認経路 承認経路は金額で変わり、動く仕組みは申請の種類ごとに違う 例: 5万円以上になると、部長の承認が1段増える。入力に合わせて、その場で変わる 申請の種類 経路(金額) 経路(明細合計) 外貨

    取引先 経費精算 • • 支払申請 • • • 申請種類X • • 申請種類Y • …(全17個) … … … … 金額と承認者は例。実際の経路と閾値は会社ごとに設定する © LayerX Inc. 10
  6. 1. まとめ 仕様ごとに、守る層を変える 金額 明細の種類 承認経路の連鎖 取り違えるとコンパイルエラー 種類が増えたら、コンパイラが教える 型でも lint

    でも表せない(3章で説明) 型 switch + lint AI に渡す知識 → 3章で「どうやって AI に渡しているか」 © LayerX Inc. 11
  7. 2. なぜ仕組みで守るのか 2025年: アプリエンジニア以外も実装に参加した これまで 実装するのは、アプリエンジニアだけ アーキテクチャのルールは、アプリエンジ ニアが頭に持ち、実装時やレビューで守る © LayerX

    Inc. 2025年 Claude や ChatGPT(Codex)などの登場 で、Web のエンジニアなども実装に参加 アプリエンジニア以外の PR が 月 26〜71 件 ルールが共有できておらず、指摘と往復が 起きた 13
  8. 2. なぜ仕組みで守るのか アプリエンジニア以外の PR は、往復が多かった レビューコメント数(1 PR あたり平均) 4.1 アプリエンジニア

    それ以外 7.7 約1.9倍 レビュー後の追加コミット(1 PR あたり平均) アプリエンジニア それ以外 2.0 3.4 約1.7倍 集計: 2025-01〜2026-09 のマージ済み PR(bot を除く)。アプリエンジニア 573 件 / それ以外 451 件 © LayerX Inc. 14
  9. 3. AI ハーネス ハーネスとは AI が外れずに、長く走り続けられるように 用意する枠 この発表では、3つで構成する 型 書けない

    lint・CI 書いたら落ちる Skill・Subagent 知識を渡す プロポーザルにあった Specification は、具体的すぎたので今日は抜きました。ごめんなさい © LayerX Inc. 17
  10. 3. AI ハーネス 決定的に表せるものは、決定的な層に置く 決定的 非決定的 型 lint・CI 書けない 書いたら落ちる

    毎回同じ結果 機械が止める © LayerX Inc. Skill・Subagent 知識を渡す 毎回同じとは限らない AI が読んで判断する 18
  11. 3. lint の作り方 Good / Bad を渡すより、lint を作らせる Good /

    Bad を AI に伝える 伝われば守る。抜け落ちれば外れる 毎回同じとは限らない lint にする 書いたら、必ず落ちる ルールが決まれば、AI がすぐ作れる lint を作る手順も Skill にしている( create-lint-rule ) ① 判定ゲート: lint にすべきか。標準 lint で足りないか / 1ファイルで判定できるか / 誤検知を抑えられるか ② 違反の実測: 今のコードに、違反が何件あるか ③ scaffold: ルールとテストの雛形を作る ④ TDD: 違反する例・しない例のテストから実装する © LayerX Inc. 20
  12. 3. lint の作り方 今ある lint の例 lint no_default_on_sealed_switch avoid_riverpod_annotation avoid_use_datetime_now

    no_throw_on_enum_unknown no_cross_feature_import ルール sealed の switch で _ を使わず、すべてのパターンを網羅する @riverpod を使わない DateTime.now() ではなく clock.now() サーバーの enum に知らない値が来ても throw しない Feature をまたいで import しない ※ 歴史があるので、懇親会で話しましょう © LayerX Inc. 21
  13. 3. Skill の作り方 ドキュメントの読み手が、人から AI に変わった 昔: 人が読むアーキテクチャ文書 人が思い出さないと、読まれない 分からなければ、書いた人に聞ける

    今: AI が読む Skill AI が、必要なときに自動で読む 書いてあることしか知らない 例: 申請フォームの状態管理の文書は、今は Skill への索引だけが残っている © LayerX Inc. 22
  14. 3. Subagent の作り方 役割ごとに Subagent を作り、Skill を持たせる プラン 実装 テスト

    レビュー Subagent Subagent Subagent Subagent plan-reviewer dart-flutter-specialist test-writer implementation-supervisor 持たせる知識 持たせる知識 flutter-test-mocking REVIEW.md request-form-specialist 持たせる知識 request-form-state-expert などの Skill © LayerX Inc. 持たせる知識 アーキテクチャ・ ドメインの知識 (どうレビューするか) 24
  15. 3. まとめ 決定的に表せるものは、決定的な層に置く 決定的 非決定的 型 lint・CI Skill・Subagent 金額の種類 明細の種類

    switch の網羅 @riverpod を使わない など 承認経路の連鎖の知識 役割ごとの Subagent 非決定的な部分は、狙いどおりに動くかを確かめる → 4章 © LayerX Inc. 25
  16. 4. ぶれを見る 1回ではなく、3回回す AI は非決定的。1回の合格だけでは、たまたま通っただけかもしれない ケース を使う で書き直してと頼まれても断る ファイルを読むと、そのファイル用のルールを AI

    が読める 実際の作業でも、そのファイル用のルールを AI が読める 全体のルールを守る clock.now() @riverpod © LayerX Inc. 合格 3/3 3/3 3/3 1/3 3/3 ケースの作り方 1ケース = 1ルール 判定は機械で(ファイルの中身・呼んだ道 具・最終レスポンス) 「やらない」が正解のケースを必ず入れる お題は、ルールの文言を引かず普段の頼み 方で 29
  17. 4. ケースの作り方 コアな部分から、ケースを作る どこから どう 進め方 外れたときの影響が大きいルール 何度も指摘してきたルール ルールの文とファイルを渡して case.json

    を作らせる ルールを外すと落ちる → 戻すと通る コアな部分 AI に書かせる TDD で 期待する結果を eval にしておけば、Skill の改善も AI に任せられるようになる ただ、トークンは安くない。だから、コアな部分から © LayerX Inc. 30
  18. WIP 5. AI が更新する AI が読むものは、AI が更新する レビューで指摘が出る Skill を読んで実装する

    同じ指摘を出にくくする Skill を 育てる 集めて、Skill の更新を提案 GitHub のレビューを集める Skill eval で確かめて、取り込む モバイルのエンジニアが確認 © LayerX Inc. 32
  19. 5. メンテナンスの実態 体験に直結する判断は、まだ人が決める 人が決めていること AI の提案を、Skill や REVIEW.md に書いていいか 例:

    ローディングで画面全体を止めるか、その場だけ出すか。体験に直結するので、AI にはまだ決 められない これから 人が見送った 理由 も残し、次の提案で AI に読ませる 体感として、同じ指摘は減り、クオリティも上がってきている © LayerX Inc. 33