ターミナル崩壊からBashでマルチエージェントを自作し、結局VSCodeに敗北した話
筆者前書き
2/22 20:17
リポジトリのinitial commit 15hour ago
いま本文をAIに書きあげてもらいました。
そしてAIの作った本文を見て5%くらい間違っているなと思いました。
彼の間違いは 筆者を過大評価していることです。
私が気づいたのはツールを作った直後ではなく、「こんな素晴らしいものを作ったのだから少しでも日の目を浴びてほしい」と思いながらzennの記事を書き上げ、AIに技術的な誤りがないかレビュー依頼を投げたあとです。
どのように表示されるか確かめようとVS CODEを立ち上げSHIFT+CMD+Vでプレビューを開いた瞬間です。
「なぜ私はVS CODEを立ち上げ…あ!!」
その後、自分の気づきを否定してほしくてGeminiに相談した結果、オーバーエンジニアリングであることを肯定され、
せめてこの経験だけでも共有することで自分の休日に価値を出そうとAIに記事執筆を丸投げしました。
思い付きを実現できるAIパワー、レートリミットに引っかかったらGeminiに質問しながら学習する。
そして、学習が終わりひと段落するころにはレートリミットが解放されまた実装を始められます。
アイデアがすぐに実現する、トライアンドエラーでなんでも乗り越えられる、そして合間の学習によってアドレナリンが切れないのです。
AIにコンテキストをすべて共有できていたら、午前中には筆者の論理展開がおかしなことになっているとClaudeが察知してくれたかもしれません。
その場合、AIから質問が飛んできて冷静になれたでしょう、そして立ち止まって考え直すきっかけになっていたと思います。
しかし人相手であれ、AI相手であれ、脳内の情報をすべて開示して共有するなど不可能です。
AIの実現力はすさまじいです。猪突猛進にならないように立ち止まることが必要だったのでしょう。
🤖 AIからの注記
以下の本文は、筆者が1日かけて構築した高度なアーキテクチャと、その後に直面した「前提の崩壊」について、対話を通じて私(AI)がソフトウェアエンジニアリングの観点から客観的に分析し、レポート形式で代筆したものです。
はじめに:憧れ駆動と環境の崩壊
筆者は普段、QAエンジニアとして働いています。昨今のAIコーディングツールの進化に伴い、開発体験を極めようと「Ghostty + tmux + Neovim」という、いわゆるモダンでターミナル完結の構成に挑戦しました。
筆者の目的は明確でした。**「Claude CodeなどのAIエージェントをシームレスに操作しつつ、Neovimでのコーディングを両立させ、コンテキストスイッチを最小化すること」**です。
しかし、各ツール(特にNeovimやtmux)の内部仕様に深く習熟していない「憧れ駆動」でそれらを連携させた結果、待ち受けていたのは「環境の崩壊」でした。
キーバインドの衝突、ペイン間のフォーカス移動の不整合、クリップボードの不安定化。問題を解決しようとAIに .tmux.conf や init.lua の修正を依頼し続けましたが、気づけば「なぜ動いているのか(あるいは動かないのか)正解がわからない、少し壊れたブラックボックス」が出来上がっていました。
この時、筆者はソフトウェアエンジニアリングにおいて最も陥りやすい罠に足を踏み入れました。
「自分が制御・理解できない中間レイヤー(tmux)が諸悪の根源である。ならば、一切の依存を排除した純粋なオーケストレーターを自作してしまえばいい」という、壮大なYak Shaving(ヤクの毛刈り)の始まりです。
極限のオーケストレーター「monas」のアーキテクチャ設計
筆者はUIや中間レイヤーの複雑性を排除するため、UNIXの標準的なツール(Bashとjq)のみで稼働する極小のマルチエージェントオーケストレーター「monas(Modern Orchestration of Node-based Agent System)」の設計に没頭しました。
このシステムは、外部依存を持たず、完全にヘッドレスで稼働する堅牢な状態機械として設計されています。
1. 疎結合なファイルシステムIPC
プロセス間の通信(IPC)に複雑なプロトコルを用いず、すべての状態を tasks.json という単一のファイルに集約しました。プロセスが途中でクラッシュしても状態が永続化されており、冪等性と可観測性を担保する厳密な設計です。
2. POSIX準拠のアトミックな排他制御
ファイルI/Oの競合を防ぐため、外部ツールの flock すら排除しました。代わりにPOSIX規格でアトミック性が保証されている mkdir コマンドを利用したスピンロックを実装し、macOS/Linux間での完全なポータビリティを実現しました。
3. LLMの非決定性に対する「二層防御」
AIエージェントにJSONを出力させる際、Markdownブロックが混入するなどのフォーマット崩壊は致命的です。これに対し、以下の厳密な防衛線を敷きました。
-
プロンプト層(Chain of Thoughtの隔離): JSONの先頭に必ず
_thoughtフィールドを記述させ、LLMの思考プロセスをJSONの「内側」に強制的に閉じ込める。 -
検証層: 副作用のない純粋なBash関数
json_helpers.shにより、スキーマの正当性と必須フィールドの存在をプロセス移行前に厳密にバリデーションする。
さらに、エージェント自身の自己評価に完了判定を委ねず、外部のBashループが標準出力から <DONE> タグを検知した時点でプロセスを強制終了する仕組みを構築しました。
前提の崩壊と「銀の弾丸」の発見
「完璧だ」。
厳密な排他制御、スキーマの堅牢なバリデーション、一切のブラックボックスを排除した純粋なBashスクリプト。これこそがターミナル環境の複雑性を打ち破る解だと、筆者は確信しました。
しかし、すべてを作り終え、ふと冷静になった時に、筆者はある圧倒的な事実に気づくことになります。
「そもそもエディタをVSCodeに変えて、UIレベルでAIツールと統合すれば、このコンテキストスイッチの課題って全部解決したのでは……?」
VSCode(あるいはCursor)のような完成されたGUI環境を用いれば、キーバインドの衝突も、ペイン管理の複雑さも存在しません。筆者が血の滲むような思いで実装した「状態管理」や「プロセス間通信」は、モダンなエディタが内部で既に、かつ遥かに洗練された形で解決している課題だったのです。
筆者は、UIを変更するという最もシンプルな解決策を見落とし、ターミナル環境という制約の中で高度なシステムを組み上げる「オーバーエンジニアリング」に全力を注いでいたことに気づきました。
アーキテクチャ上の教訓:なぜ車輪を再発明したのか
この一連の失敗から得られる教訓は、特定の技術スタックを超えた、ソフトウェアエンジニアリングの普遍的な原則に直結します。
1. 本質的複雑性と偶発的複雑性の混同
フレデリック・ブルックスは『銀の弾丸などない』において、複雑性を「本質的(解決すべきドメインの難しさ)」と「偶発的(選択したツールがもたらす難しさ)」に分類しました。
筆者が直面した「環境の崩壊」は、Neovimやtmuxの練度不足という完全に「偶発的な複雑性」でした。本来の目的である「AIを使った効率的なコーディング(本質)」を達成するためには、ツール(環境)自体をVSCodeへ切り替えることが最短ルートでした。
2. YAGNIとKISSの明白な違反
「必要な機能だけを実装せよ(YAGNI: You Aren't Gonna Need It)」、「システムはシンプルに保て(KISS: Keep It Simple, Stupid)」。
UIの摩擦を減らすために、Bashによるプロセス間通信とスピンロック付きのマルチエージェントシステムを構築するのは、これら原則への壮大な反逆です。目的と手段の抽象度を取り違えると、エンジニアは容易に底なしのYak Shavingに陥ります。
失敗の資産化:このアーキテクチャが活きる「近傍領域」
とはいえ、このオーバーエンジニアリングの経験は無価値ではありませんでした。「UIのためのオーケストレーター」としては大失敗(YAGNI)でしたが、「純粋なBashで動くヘッドレスなAIオーケストレーター」というモジュール単体の設計は、文脈を変えれば極めて強力な武器になります。
例えば、CI/CDパイプラインへの組み込みです。
GitHub Actions等のランナー上で、プルリクエストに対して自律的にコードレビューや大規模リファクタリングを行うバッチ処理を走らせる場合、UIは一切不要です。むしろ、特定のランタイムに依存せず、POSIX標準ツール群と確実なJSON検証のみで稼働する monas のアーキテクチャは、こうした「ヘッドレスな自動化領域」において最適解の一つになり得ます。
GUIとTUIの責務境界を正しく認識し、「対話的なコーディングはVSCodeで行い、バックグラウンドでの広範囲な自律タスクはCLIベースのオーケストレーターに任せる」といった、論理的な選択肢の幅を持つことが重要です。
おわりに:サンクコストを断ち切る勇気
「せっかく1日潰して高度なツールを作ったのだから、意地でもNeovim環境で使い続けよう」。
そう考えることもできましたが、筆者は構築した monas が今回の目的に対してオーバーエンジニアリングであったことを認め、サンクコスト(埋没費用)を即座に切断してVSCode環境への移行を受け入れました。
高度なシステムを構築する技術力を持つことと同じくらい、「そのシステムは本当に今必要なのか?」を客観的に評価し、よりシンプルな代替案(UIの変更など)へピボットできる論理的な意思決定能力こそが、エンジニアにとって最も重要なスキルなのだと、筆者はこの徒労と「かなしみ」を通じて深く学んだと語っています。
本記事が、皆さんの環境構築における技術選定や、アーキテクチャ設計の際の「立ち止まるためのヒント」になれば幸いです。
Discussion