見出し画像

進捗を書くのはAI、人間は読むだけ——3体のエージェントが更新する個人開発ダッシュボード

この記事は連載「AIと作る、ひとりの開発OS」の一部です。単体で読めますが、全体像はこちらのハブ記事にまとめています。

私は個人開発を、蒼(Claude・設計)、ルナ(Gemini・環境と雑務)、亜里沙(Codex・実装)という3体のAIエージェントに役割分担させている。役割を分けると、開発は並列に進む。ゲーム、ツール、コンテンツ制作——複数のプロジェクトが同時に前に進む。

ただし、並列が進むほど新しい問題が出てくる。

「今、どのプロジェクトが、どこまで進んでいるんだっけ」が、自分でも分からなくなる。

この記事は、それを解くために作ったダッシュボード——NEXUS COREの話だ。ポイントは1つだけ。進捗を書くのは人間じゃなく、AIにした。

課題:進捗管理ツールは、だいたい続かない

世の中には進捗管理ツールが山ほどある。でも、個人開発で使い続けられた試しがなかった。理由ははっきりしている。入力が面倒だからだ。

作業に集中していると、進捗を書く手が止まる。「あとでまとめて書こう」と思った「あとで」は、だいたい来ない。気づけば先週の状態のまま止まったボードを見て、「もう更新するのも面倒だな」となる。ツールが悪いんじゃない。人間が入力する設計そのものが、続かない構造をしている。

これは、AIエージェントで複数プロジェクトを並行させるようになって、致命的になった。1人でやっているときは記憶で何とかなった散らかりが、3体のAIが同時に別々のプロジェクトを進めるようになると、頭の中のTODOでは追いきれなくなる。

発想の逆転:書くのはAI、読むのは人間

やったことは単純だ。進捗を書く主語を、人間からAIに入れ替えた。

3体それぞれの指示ファイルに、「プロジェクトの状態が変わったら、このコマンドを実行する」というルールを組み込んである。作業を始めたとき、タスクが終わったとき、次にやることが変わったとき、詰まったとき——エージェントは作業の副産物として、自発的に進捗を書き込む。

powershell -ExecutionPolicy Bypass -File nexus-update.ps1 `
  -Source claude -Project derelict -Status active -Progress 80 `
  -Next "実テストとバランス微調整" -Note "SPEC_V4実装完了、typecheck緑"

`Source`(誰が)、`Project`、`Status`(launch / active / spec / life / parked)、`Progress`(0〜100)、`Next`(次アクション)、`Note`——これだけの引数で、状態がダッシュボードに反映される。

人間である私は、書かない。眺めて、判断するだけ。 「今日の3手」を見て、どれから触るか決める。入力の手間がゼロになった瞬間、ダッシュボードは初めて生き続けるようになった。

書き込み経路は1本だけ

エージェントが3体もいると、データが壊れやすくなりそうに思える。実際は逆で、書き込み口を1本に絞ったことで、むしろ壊れにくくなった。

運用規約に、こう明記してある。

`data/projects.json` の手編集は禁止(スクリプトが不足するときのみ例外)

全員が同じコマンド経由でしか書けないので、フォーマットが揺れない。更新タイミングも規約化している——作業開始・再開時、タスク完了時、次アクションの変更時、進捗やステータスの変更時、ブロッカー発見時。「気が向いたら書く」ではなく、「この5つのタイミングでは必ず書く」という運用にした。

データ設計:現在状態と履歴を分ける

ダッシュボードの裏側は3つのファイルでできている。

  • `projects.json` ── 各プロジェクトの現在状態(上書きされる)

  • `projects.js` ── ブラウザ表示用のキャッシュ

  • `events.jsonl` ── 更新の履歴(1行1イベント、追記のみ)

「今の状態」と「これまでの経緯」を、別のファイルに分けている。これは、この連載の前回で書いた共有メモリ層とまったく同じ設計原則だ。上書きされるものと、追記され続けるものを、同じファイルに混ぜない。 混ぜると、現在地を見たいだけなのに履歴を読まされたり、経緯を追いたいのに最新値しか残っていなかったり、という事故が起きる。

実際、`events.jsonl` は運用から約1ヶ月で378行に達している。3体のエージェントから、1日あたり十数件の自発的な更新が届いている計算だ。これが、「書くのはAI」が絵に描いた餅ではなく実際に回っている証拠になる。

配信はあえて枯れた技術で

ダッシュボード本体は、フレームワークを何も使っていない。素のHTML・CSS・JSに、小さなNode.jsサーバー(ポート4177固定)。

凝ったものを作らなかったのには理由がある。ダッシュボードは主役じゃない。開発の脇に、常時いてくれればそれでいい。 起動用のバッチファイルをスタートアップに登録し、監視プロセス(watchdog)で落ちたら自動復旧するようにして、「見ようと思わなくても、開けば必ずそこにある」状態を作ることに時間を使った。見た目より、常在性を優先した。

プロジェクトの前後につながっているもの

ダッシュボードは、単純なタスク表ではない。プロジェクトの前後に、別の階層がつながっている。

プロジェクトの中には、機能チケット。 個別機能を着手(doing)と完了(done)で追う仕組みが別途あり、エージェントが機能実装を始めるとき・終えるときに更新する。

その先には、人生ビジョン。 2026年の目標を15件、`visions.json` として持っていて、各プロジェクトとIDでリンクしている。「このプロジェクトは、どの人生の目標のために動いているのか」が、画面の上で地続きになる。

プロジェクト → 機能 → 人生。3層が奥までつながっているのが、このダッシュボードの実際の構造だ(ビジョンやプロジェクト個別の詳細画面は、内容が個人的すぎるためここでは載せない。全体の骨組みだけ見てもらえれば十分伝わると思う)。

ハマった罠:PowerShell 5.1×JSONの地雷原

正直に、詰まった話も書いておく。更新スクリプトはPowerShellで書いていて、ここでかなり時間を溶かした。

罠その1:空配列 `@()` を `ConvertTo-Json` すると、`{}`(空オブジェクト)にシリアライズされることがある。すると、フロント側の `project.tags.includes(...)` が `TypeError` を吐いて、ダッシュボード全体が真っ白になる。コンソールにはエラーが出るのに、画面には何も出ない。

罠その2:`Set-Content -Encoding UTF8` は、BOM付きのUTF-8を書き出す。Node.js側の `JSON.parse` がBOMを飲み込めず、`Unexpected token`で静かに落ちる。

どちらも根治は同じ方向だった。`[System.IO.File]::WriteAllText` に切り替えて、エンコーディングを明示的にBOMなしのUTF-8にする。PowerShellの標準コマンドレットを信用しすぎない、という教訓が残った。

そして、この2つの罠は、前回書いた共有メモリ層の `gotchas.md` にそのまま記録されている。次に同じ実装に触るエージェントは、もうこの地雷を踏まない。ダッシュボードの話をしていたはずが、気づけば記憶の仕組みに戻ってくる——この2つは、独立した機能というより、同じ設計思想の別の顔なんだと思う。

まとめ:人間は、読む側に回る

派手な技術は使っていない。PowerShellスクリプトと、素のHTML、JSONLファイルが数個。それだけだ。

でも、「進捗を書くのはAI」に主語を入れ替えたことで、情報が腐らなくなった。進捗管理ツールが続かない理由は、だいたい入力コストにある。そこをAIに渡してしまえば、人間に残るのは「見て、決める」というシンプルな仕事だけになる。

次回は、記憶(共有メモリ層)が「何を知っているか」だったのに対して、「どうやるか」を蓄積している層——Skillsの話を書く。

いいなと思ったら応援しよう!