Skip to content

AIエージェントのプロセスリーク(ゾンビ蓄積)とコンテナ一括破棄による根絶設計

1. 概要

自律型AIエージェントが検証のためにローカルサーバーを起動する、あるいは非同期でサブエージェントやMCP(Model Context Protocol)サーバーを立ち上げる際、セッション終了後にこれらのプロセスが生存し続ける「プロセスリーク(ゾンビプロセス蓄積)」は、システムリソースを枯渇させる重大なインフラ課題である。 Claude Code(anthropics/claude-code#36204 および #28126)や OpenCode(anomalyco/opencode#11602)で発生したゾンビ蓄積バグは、ホストPC上でAIエージェントを直接実行するモデルが抱えるプロセス管理の脆さを示している。 本稿では、このプロセスリークのメカニズムを分析し、サンドボックス(sunaba)の「コンテナ破棄による一括クリーンアップ設計」の優位性について考察する。


2. インシデントの分析:AIエージェントによるゾンビプロセス爆増

2.1. 死んだセッションから取り残されるMCPサーバー群

エージェントがサブプロセスとして起動したMCPサーバーやサブエージェントのNode.jsプロセスが、親セッションがクラッシュまたは強制終了(Ctrl+C 等)した際に道連れで kill されず、孤立したまま裏で動き続けるバグが報告されている(claude-code#28126)。

  • 結果: PCのメモリ上に同一のMCPサーバーの残骸プロセスが重複して大量に蓄積し、ストレージ(~/.claude/tasks/ 等)の不要なリークとリソース枯渇を引き起こす。ユーザーが手動でゾンビNodeプロセスを殺すスクリプトを自作するなどの泥臭い対策を迫られた。

2.2. lsofコマンドの1,000個超のゾンビ蓄積

エージェントがファイルの排他制御やポート監視のためにバックグラウンドで実行した lsof コマンドが、CLIセッションの終了後も終了せず、ゾンビプロセス(PPID=1)としてシステムに残留するバグが発生した(claude-code#36204)。

  • 結果: ps コマンドで確認すると、1,000個を超える lsof -a -d cwd プロセスが残留し、OSのプロセステーブルの上限を圧迫する大惨事となった。

2.3. タイムアウト時のシャットダウンハンドリングの漏れ

サーバー起動チェックがタイムアウトでコケた際、起動途中のサーバープロセスが kill されないまま放置され、次回起動時に「ポートが既に使用されています(Port already in use)」のエラーを多発させるバグが発生した(opencode#11602)。

2.4. 実体験:コラム執筆中にホスト環境を ps したら、ゾンビと見紛う「現役のAI労働者たち(CPU 50分超)」が稼働していた話

本稿の執筆中、著者が「まさか自分の環境は大丈夫か?」と不安になり、開発PCのホスト環境で ps -a を実行したところ、衝撃的なプロセス群が捕獲された。

shell
$ ps -a
    PID TTY          TIME CMD
   7785 pts/7    00:22:55 claude
   8294 pts/5    00:00:05 opencode
  15714 pts/6    00:52:10 opencode  <-- CPU 52分占有
  21718 pts/9    00:50:06 agy       <-- CPU 50分占有
  22810 pts/5    00:13:17 opencode

一見すると、過去のセッションの残骸(ゾンビプロセス)がCPUを50分以上も暴走占有しているかのように見え、あわや kill -9 で成仏させられる寸前であった。しかし確認したところ、これらはゾンビではなく、**「裏で別のタスクや調査を並行して実行している、現役で稼働中のAIエージェントたち」**そのものであった。

CPUタイムの50分という数字は、暴走の証拠ではなく、AIたちが主人の指示を受けて実地で働き続けてきた「流した汗(自律実行の歴史)」そのものであった。

このエピソードは、AIネイティブ開発において、複数のエージェント(Agy, Claude, OpenCode)を日常的に並行して「マルチタスク稼働」させることがもたらす、新たなプロセスマネジメントの複雑さを示している。現在進行形で複数のAIがローカルPCをフル稼働させる環境だからこそ、コンテナ等によるプロセスライフサイクルの厳格な管理が、ホストPCを健全に保つためにますます不可欠となる。


3. sunaba におけるコンテナ寿命連動による「プロセス根絶」

ホスト環境でのシグナルハンドリング(process.on('exit')child.kill())に頼るプロセス管理は、エージェントが例外で急死した際や強制終了された際に、容易に破綻する。 sunaba(コンテナサンドボックス)は、AIの検証環境を Docker コンテナ内に完全に押し込めることで、この課題を構造レベルで根絶している。

3.1. 物理的なプロセス空間の分離(PIDネームスペース)

  • sunaba 内部でAIが起動したテストサーバー(npm run dev 等)、MCPサーバー、または監視コマンドプロセスは、コンテナ内のPID空間(Namespace)に完全に隔離される。
  • ホストPC(開発者の実機環境)のプロセステーブルは一切汚染されず、ホストの稼働性能に影響を与えることはない。

3.2. コンテナ破棄による一括ガベージコレクション(Docker stop / rm)

  • アプリケーションのコードレベルで子プロセスや孫プロセスを一つずつ走査して kill するコードを書く必要はない。
  • セッションの正常終了時、タイムアウト時、あるいは予期せぬクラッシュ時、sunaba はホスト側からコンテナ自体を docker stop(SIGTERM➔SIGKILLの強制シグナル)および docker rm で破壊する。
  • OSカーネルの機能(コンテナのライフサイクル制御)により、コンテナ内部のPID=1から派生したすべての子孫プロセスが一滴残らず瞬時に、かつ100%確実に消滅(ガベージコレクション)する。ポートフォワード設定も同時に消去されるため、「ポートが使用中」で次回セッションが立ち上がらなくなる競合も発生しない。

4. 結論

AIエージェントに自律的なコマンド実行を任せる以上、プロセスの終了ハンドリング漏れによるゾンビの蓄積は避けられない宿命である。 sunaba が構築した 「すべてのプロセス空間をコンテナに閉じ込め、セッション終了と同時にコンテナごとOSレベルで一括消去する」 設計は、アプリケーションのバグや異常終了に左右されず、常にホストPCのリソースをクリーンで安全な状態に保ち続けるための、極めて堅牢で信頼性の高いインフラアプローチであるといえる。


5. 参考文献 / 一次情報

Shiori pointer-RAG automation experiment.