プログラミング自動化の果てに

Claude Code を個人で1日10万円使い続けると見える

ウィッシュリスト駆動開発

@mizchi | AOAI DevDay 2025

About Me

今日のコンテキスト: 「CLINE に全部賭けろ」

  • https://zenn.dev/mizchi/articles/all-in-on-cline
    • 賭けてますか?
    • ※当時CLINE以外にコーディングエージェントがない
    • あまりに便利すぎて「使えないと困る」
  • 今日話す内容
    • AI コーディングの泥臭い話
    • 既存のプログラミングに対する考察

今のAIコーディングの肌感

  • 実装アイデア+自動テスト手法が思いつけば、プロト実装は終わる
    • アイデアだけでは自動実装は無理。検証手法とセット
  • LLM は人間を模倣している宇宙人であり、専用言語を必要とする
  • 自分のAIの用途
    • プロトタイピング/Lighthouseのログ分析/大規模コードの解析
    • 今は GUI 関連を作るのはコスパ悪い (後述)
  • 今月の Claude Code は先月ほどブン回らない(先月の7割ぐらい)

AIエージェントによる開発=自動テスト設計

  • 自動テストループが書けた時点で、無限回の試行を前提に実装できる
    • 無限の猿定理 - Wikipedia
    • 猿がタイプライターの鍵盤をいつまでもランダムに叩きつづければ、ウィリアム・シェイクスピアの作品を打ち出す

    • 高品質モデルは、試行ごとの確度が上がる
  • 一瞬で破綻するサイズに到達できる
    • 人間による開発は逆にそこまで数ヶ月~数週間かかっている
    • 高品質モデルは、コード品質により破綻を遠ざけることができる
  • 人間の判断速度は、既に明確なボトルネックである

AI の生成物とどう向き合うか

  • 破綻することはもはや前提
    • 破綻するまでコードを書き続ける(無限の体力がある)
    • 破綻した時点で、その結果を分析する(させる)
  • 「つよくてニューゲーム」する
    • 人間が理解可能な、現実的に採用可能なコード断片を取り出す
    • テストコードや仕様だけ持ち越して、新しいバージョンへ
  • 良い仮説、良いゴール設計があれば、良い解にたどり着く
    • なので勉強をサボるわけにはいかない...

強いデッキを作る

  • 良いアーキテクチャを選べる審美眼
    • TDD / DDD / 技術選定 / ドメイン境界
  • 良い資料を集める
    • 明快な仕様のドキュメント集
    • ベストプラクティスへのリンク集
    • 適切なMCPを選択して注入
  • 矛盾を指摘できるようになる能力をつける
    • 実装とドキュメントの乖離によってAIが劣化する

実践AIプログラミング

自分の開発モード

  • メインタスク集中モード
  • 並列モード
  • アイデアモード

※ 適当に名前をつけています

メインタスク集中モード

  • エディタの右半分で Claude Code を走らせる
  • リアルタイムで生成コードを見ながら、即座にレビューする
    • 反射神経がいる(正直疲れる)
    • もう一つターミナルを立ち上げて、CLIやテスト結果を確認して回る
  • ペアプログラミングのナビゲーター
fig

並列モード

  • 事前準備: Google Calendar Tasks に乱雑にメモを書き留めてる
  • 特にやることを決めずに tmux(or zellij) で3分割で並べる
    • メモを拾って投げ込む
    • ログが止まってないかだけを見ている
  • メインタスクのトークン消費を圧迫しない範囲で、他タスクの流量を調節
    • Approaching Usage Limit... がでてないと、仕事してる気にならない

アイデアモード

  • 並列モードの一つを「思いつきための実験するための枠」に
    • 「このURL/論文読んで、試しに実装して再現して」
    • 「こういう Lint プラグインがほしいんだけど作れる?」
    • 「WebGPU で pytorch 移植できる?」
  • 重要: 中身をまったく見てない
    • 一通り走りきった後で、どのように成功/失敗したかを確認
    • うまくいったらGitリポジトリや利用単位に切り出す

ゴール設定からワークフロー設計

  • ゴールを定義する(最重要)
    • 「このプロジェクトでは何をしたいか?」を CLAUDE.md に書く
    • Claude には既存実装の調査をさせつつ、 docs/* に要点をまとめさせる
  • 実装計画を立てる
    • どういう自動テストがあれば目視確認をスキップできる?で考える
    • 「実装計画を立てて」「じゃあやっといて」
  • メインタスク => 並列モードに移行
    • たまに覗いて「今何がうまくいってない?」
    • 追加で欲しい機能を思いついたら Issue や TODO.md に書き込んでおく

作例紹介

作例: mizchi/readability

https://github.com/mizchi/readability

  • mozilla の本文抽出アルゴリズムの fork
  • 発想: cloudflare-worker の BOT 用に使いたかったが jsdom に依存
    • 「DOM API への依存を剥がして」
    • 「モダンな TS に書き直して」
    • 「HTMLからMarkdownに変換する処理を入れて」
    • 「元実装が古く2003年ぐらいなので、HTML5のタグを考慮して」
  • 分析: 本文抽出というタスクが AIが自己再帰的に判断できる処理だった

作例: similarity-ts/py/rs/...

作例: similarity の改善

  • v1: TypeScript 特化
    • TypeScript Compiler API でTS用に実装
    • 途中から V8 OOM(MAX HEAP ERROR)でテストが通らない!
  • v2: Rust
    • Rust + oxc_parser で再実装
    • v1 のテストコードはそのまま引き継ぐ
  • v3: 多言語対応+並列化
    • oxlint を参考にマルチスレッド化し、CPUを全部使い切るように
    • 5万行 のコードに対して 300ms で重複コードの検出✌
    • tree-sitter でTS以外も対応

作例: mizchi/tui-poc

  • https://github.com/mizchi/tui-poc
  • 動機: react-ink (TUI基盤) が IME が制御できないよなぁ...
    • もしかして今 TUI 基盤を作れば覇権とれる?
  • 指示
    • 「helix-editor の既存の実装を調べて」
    • 「emoji の表示幅の計算について調べて」
    • 「React Ink を参考に yoga layout engine を組み込んでみて」
    • 「Sixel によるピクセル制御を実装して」

学び: mizchi/tui-poc

  • 枯れたプロコトル(標準入出力)は既存実装を調査する
  • IME 表示位置の制御自体は不可能ではないが、だるい
  • TUI上の emoji 表示の表示幅の計算は未解決問題
  • Sixel の出力は膨大すぎて、アニメーションさせるとヤバいかも...

AI 前提のコーディング、最終的にどうなる?

  • 思いつきを書き出す TODO.md が機能要望ウィッシュリストに
    • 人間は次に作りたい機能を考えている(だけ)
    • ユーザーは願望生成器であり、「願望の品質」が問われる
  • Claude Code は定期的に TODO.md を確認して実装する係
    • TODO.md => GitHub Issues でも可
  • ゴール設定が悪いと、早期に頓挫することがわかる
    • 「何が難しかった?」とポストモーテムして、次のサイクルへ
  • 就寝前に時間がかかりそうな実行計画を作って流す
    • 寝る。朝起きると「何か」が出来ている

テクニック: AIには定量的な評価指標を与える

  • 具体的な目標値を与えて、その達成まで自動化(放置)
    • 「テストカバレッジを90%に上げたい」
    • 「CIの初期化で10分掛かっている処理を3分以内にしたい」
    • 「このクエリの処理を 1500ms から 800ms にしたい」
  • How だけではなく Why
    • 「今 Dependbot を導入するにはカバレッジが足りない」
    • 「CIの共通処理が全ワークフローのボトルネックになっている」
  • 数値を与えた場合、厚めにレビューが必要
    • 前提の捏造や、勝手にテストを省略していることが多い
    • it.skip(...)

テクニック: 再帰的E2Eチェックリストプロンプティング

  • 「リリース前に実施するチェックリストを作って」
  • 「それを実施して」
    • チェックリストを満たせない場合、その部分を修正する計画を立て、それを修正する
    • チェックリスト自体の品質を検証する。分かりづらい点があったら反映して
    • 検証した内容を自動テストに変換
  • 人間がやること
    • チェックリストそのものの妥当性を評価
    • AIのチェックリスト実施ログの検証

(今は) GUI は作らない

  • 今GUIを作り込むのはコスパが悪い
    • VLMが非常に高価 (コストが x100)
    • 目視確認が致命的なボトルネック
  • どうせ対AIインターフェースはテキストベース
    • AI同士で疎通する前提で効率化しておくと後でスケールする(はず)
    • 人間用のインターフェースは後回し
  • どうしてもやる場合: v0 でワンショット
    • 今のAIが得意な React+ShadcnUI+Tailwind に寄せる
    • GUI を実装上の契約にしない

今のプログラミングそのものへの考察

言語選択の方針

  • (自分は)プロトタイプは Node/TypeScript/Deno
    • 慣れてる言語ならなんでもいい
    • プロトタイプを作りながら、仕様を言語化する
  • CPU ボトルネックになったら Rust
    • cargo bench (+criterion) 書かせて、AI自身に速度改善させる
    • さすがに非同期 Rust (tokio) は(自分が)レビューが難しい
  • CS 的に難しいなら Haskell 等の関数型言語へ
    • 再帰的なアルゴリズムは明確に関数型言語が得意
    • マイナーなモナド出てくると怪しくなる

LLMとプログラミング言語の相性

  • メジャー言語(ex. TypeScript/Python)の場合
    • 学習量が多いので初動が安定するが、スケールにやや難
    • 特にランタイム整合性が崩れた時の復旧が難しい
  • コンパイラが厳密な言語(ex. Rust/Haskell)
    • ブートストラップが遅いが一定量を超えても破綻しづらい印象がある
    • 言語自体の難しさはモデル性能/試行回数/コンパイラの警告品質で(将来的に)踏み倒せる可能性が高そう

考察: とにかく厳しい言語として Lean 4

  • 依存型をもつ純粋関数型の定理証明支援言語
  • tactic(戦術) を組み合わせて theorem(定理) を証明する
  • 実装手法が正しいかどうかを形式的に検証できる
-- 「nに0を足してもn」という帰納法を使った証明
theorem add_zero (n : Nat) : n + 0 = n := by
  exact Nat.add_zero n  -- 標準ライブラリの定理を使用

考察:自分の Lean 4 の体験

  • 雑な証明体験:
    • 命題を与えて15分ぐらい放置すると確率的に証明されている
    • 出力をみても意味があるのか判断できない!(勉強が足りていないので)
  • わかったこと
    • 概念を形式的な命題で表現するための訓練がいる(知ってた)
    • その上前提で AI の補助手段として使える可能性がある
      • 「実装対象を形式的に解釈して」「証明しといて」
      • とはいえ、まだモデル性能が足りない
    • AWSの応用例: AWS と定理証明 〜ポリシー言語 Cedar 開発の舞台裏
      • 証明された形式を持つ実装として、参照実装に使う

考察: 今のプログラミング言語はAIに優しくないのでは

  • LSP を叩く MCP を作ってみたが...
    • https://github.com/mizchi/lsmcp
    • AIが直接型チェックや複数ファイルのリネームができる!
    • ワードカウントが下手なAIとファイル操作体系 line:character が噛み合わない
  • 人間用のテキスト表現が邪魔
    • AIはパース済みの構造化データを直接見たほうが(たぶん)いい
    • ファイルに書き込んだ結果ではなく、コンパイラに直接ききたい
    • コード編集単位は AST の木構造に対するコマンド列としたい

発想を探す: Unison 言語

  • 紹介記事: Unison 言語から、「次」の言語を考察したい
  • 超訳
    • 言語自体に差分検出とバージョン管理が組み込まれている
    • 純粋関数で環境を固定し、差分検知で型/テストをインクリメンタルに更新
    • 純粋関数の依存と環境が固定されてるなら、テスト結果はキャッシュ可能!
-- Ability(EffectSystem)
helloWorld : '{IO, Exception} ()
helloWorld _ = printLine "Hello World"

発想を探す: Unison UCM の体験

  • ファイルという実体はない
  • ucm> edit helloWorld すると関連コードが scratch.u に展開される
  • scratch.u というファイルで一旦実装する
  • ucm> update すると現在の scratch.u がコードベースに取り込まれる
  • 内部的にはテキストコードではなく、ASTと参照構造だけが保持されている

発想を探す: Nushell

  • https://www.nushell.sh/ POSIX 非互換なシェル
    • 型付きの bash script みたいに使える(TSっぽい)
  • 構造化データをパイプで処理できる
    • 例: ls | weher type == file | sort-by size | reverse
      • 「ls の結果からファイルで絞って、サイズでソートして、逆順に」
    • 構造化パイプの元ネタは Windows PowerShel
    • bash/zsh はテキストが基本で、構造化データが一級市民ではない
      • 一応 jq で出来なくもないが...

Git/GitHub も再考したい

  • 現代: フォーマッターは git diff のためのもの
    • フォーマッターが普及して、逆にスタイルに意味が込められなくなった
    • もはやバイナリASTで保存して、エディタ側で展開していい
  • GitHub(gh) はコミュニケーション層の拡張ストレージ
    • 今 VCS を設計するならコマンド体系にIssues/PR/Merge を織り込んでよい
  • Issues は git notes に変換できないか?
    • Issues や PR の内容は、git notes のようなVCS内の情報に格納したい
    • git notes: Git の新機能(v2.50.0)でコミットにメモを付与
    • 実装してみた https://github.com/mizchi/git-notes-gh-sync

もし今プログラミング言語を設計するなら...

  • AI 用に構造化されたREPL/シェルを与える (nushell)
    • AI には 人間には厳しいワンライナーを要求していい
      • 例: > add a:Int b:Int -> Int = { a + b }; test { add 1 2 == 3 }
    • うまくいったコードを収集して処理に事後的に構造化
  • 構造の自己参照ハッシュでコードを保存する (Unison, Nix)
    • コード検索は型やASTに対するクエリで行う (tree-sitter, ast-grep)
    • テキスト表現は人間用のおまけ
  • 実行権限とエフェクト推論を一致させたい (Deno, Unison, Koka)
    • 例: Deno の実行時パーミッション deno run --deny-env --allow-ent code.ts
    • Effect System で副作用の型を追跡して、権限を推論してシェル側に渡す

...という言語をAI に作らせてみた

  • https://github.com/mizchi/x-lang-proto
    • 自分「...という発想で、言語を作って」
    • Claude「わかりました」
    • 自分「この言語どう思う?使いやすい?」
    • Claude「学術的なおもちゃって感じですね
  • たぶん、またゼロから書き直します

まとめ

まとめ

  • 設計/自動テスト/品質検証のパターンを学ぼう
    • AIの手数を前提にすると、自動化が成立したときの見返りが大きい
  • 人間の生産性とは、AIに良質なアイデアを供給し続ける速度
    • エコシステムが変化すること前提にアイデアを柔軟に受け止める
    • 自分が言語やエコシステムを考察するのも、その受け入れ準備
  • 余談: 最近の悩み
    • 高速にログを追い続けるので眼精疲労がすごい
    • 「代わりに祈る時間が増えた」ので、エアロバイクを買った

おしまい