ゴッドオブジェクト(God Object)とは、本来は別々の責務に分けるべき処理・データ・状態を、ひとつの巨大なクラスやモジュールに詰め込んでしまった設計のことです。本来は分けるべき役割(UI、永続化、権限、外部APIなど)が、ひとつの巨大なクラスやモジュールに全部入っており、あらゆる変更がそこに集中します。その結果、影響範囲が読みにくくテストもしづらく、バグや設計の腐敗が進みやすい、というのが問題とされる点です。

ゴッドオブジェクトは悪い設計とされつつも、バイブコーディングでコード生成のやり方が変わる中では処理が一箇所にあるぶんLLMにも追いやすいのでは?という疑問があります。小規模・一人・試作では入口が一つにまとまっているほうが速いことも多いです。

以上から試作ではゴッド寄りの集約でもよいが、恒久設計として優れているわけではないことや、ツール・状態・権限・秘密・永続化が増えたら責務分離が必要になります。最初は大きめでもよいが長く育てるなら外はシンプルなまま中は少しずつ分けていくのが良い結論です。機能や連携が増えると一つに詰め込んだ設計は急に直しにくく壊れやすくなります。

なぜLLMはコードをゴッド化しやすいのか

LLMは、今見えている範囲に新しい機能を継ぎ足すのが得意です。既存の大きなクラスやファイルがあると、そこへ続きを書くほうが最短で動く答えになりやすいです。認証も状態管理も外部APIも、ひとつの中心に集まりやすくなります。分割された設計では、責務の置き場や依存の扱いまで考える必要があり、動くコードを早く返すことより難しいので、中央集権的な形に流れやすいです。

さらに、バイブコーディングでは「これを追加して、この関数から呼んで」と頼むと、LLMは最短経路でつなぎ込みます。設計の美しさより、いま動くことが優先されます。テストも、動いた・通った・便利、で先へ進みやすいため、構造的な悪化はかなり育つまで気づきにくいです。

要するに、LLMは責務を分けて育てるより、見えている中心へ最短で機能を足すほうが得意だから、コードはゴッド化しやすいのです。

ゴットオブジェクト化の具体例

ゴッドオブジェクト型にすると、部品のほとんどを一つのクラスに寄せて一つの入口だけで動かす形になります。下のコードはそのイメージです。モデル、文章の組み立て、検索、ツール、ログ、許可、状態の保存などを、GodAgentが持ちます。

# Python: 典型的なゴッドオブジェクト的 Agent
class GodAgent:
    def __init__(self, model_client, prompt_builder, retriever, tools, logger, auth, state_store):
        self.model = model_client      # LLMモデルクライアント
        self.prompt = prompt_builder   # プロンプト生成
        self.retriever = retriever     # RAG検索器
        self.tools = tools             # ツール名→実行関数マップ
        self.logger = logger           # ログ/監査
        self.auth = auth               # 認可チェック
        self.state = state_store       # セッション状態保存
    async def run(self, user_input, user_id, session_id):
        # 履歴・状態復元
        history = await self.state.load(session_id)
        docs = await self.retriever.search(user_input)
        prompt = self.prompt.build(input=user_input, history=history, docs=docs)
        # LLM呼び出しループ
        resp = await self.model.chat(prompt, tools=[name for name in self.tools.keys()])
        while resp.tool_call:
            name = resp.tool_call.name
            args = resp.tool_call.args
            # 認可チェック
            self.auth.check(user_id, name, args)
            # ツール実行
            result = await self.tools[name](args, user_id)
            self.logger.log_tool(name, args, result)
            resp = await self.model.chat(resp.next_prompt, tool_output=result)
        # 結果保存
        await self.state.save(session_id, resp.text)
        return resp.text

上記のように、GodAgentクラスが各機能の責務を持つため、呼び出し側は単一のrunメソッドのみを操作すれば全処理が完結します。一見コードがまとめやすく開発は高速化されますが、内部は多数の依存とロジックが混在しており、役割が肥大・複雑化しています。

利点と欠点

ゴッドオブジェクト型と、仕事ごとに分けた設計を表で比べます。小さく試すときは、ゴッドオブジェクト型のほうが速く動かせることが多いです。長く育てると、直しにくさや安全の弱さが目立ちます。機能を足すたびに、同じ中心が太っていくので、あとからの負担が急に重くなります。表の読み方は、速さや試作なら左の列、長く使う・チームで書く・安全を重んじるなら右の列、と思ってもらうとわかりやすいです。

観点ゴットオブジェクト型設計分割・モジュール化設計
性能メソッド呼び出しやDIオーバーヘッドが減り単純処理は高速な場合もあります。マイクロコントローラ的環境では一元化による最適化が可能です。個別コンポーネント間の通信や抽象化コストが増えますが、並列実行やキャッシュ効果、スケールアウトで総合性能を向上できます。
保守性初期はコードが少なく保守が容易に見えますが、規模が大きくなると依存関係が複雑化し、変更の影響範囲が広がります。関心事ごとに変更でき、コードの責務分離によって変更影響を局所化しやすいです。各部品でチーム分担しやすいです。
テスト容易性単体テストはGodAgent全体の振る舞いを検証する必要があり、モック範囲が巨大になりがちです。ユニットテストでテストが結合テスト化する恐れがあります。各コンポーネントが小さく疎結合なので、ユニットテストやモックが容易です。個別テストで不具合切り分けや再利用もしやすいです。
セキュリティ全権限を中央で管理するため、万一流出すると大規模な被害につながるリスクが高いです。権限分離が困難で、秘密情報も一箇所に集中しやすいです。役割ごとに権限を細分化しやすく、最小権限原則を適用可能です。秘密管理も機能単位に分けられ、局所的な監査が可能です。
拡張性新機能追加はGodAgentクラスの肥大として現れます。コード間の依存を意識しないとすぐに複雑化します。新しいツールや機能は独立したモジュールを追加するだけで済み、既存部分への影響が少ないです。機能拡張が安全に行えます。
デバッグ性ログが集中していれば追跡は可能ですが、状態と処理が絡まり合うと再現が困難です。副作用の全体把握が難しいです。各コンポーネントの入出力が明確なため、原因追跡がしやすいです。明示的なインターフェースでデバッグ範囲を絞り込めます。
チーム開発変更点が1箇所に集中し競合しやすいです。クラス所有者が曖昧になりがちで、レビュー対象が膨大になります。担当範囲が明確になり、チーム間の衝突を低減できます。複数人が並行して開発できます。モジュールオーナー制やインターフェース契約が明確になります。
バイブコーディングコードが一箇所にまとまり、プロンプト入力→即時実行で動作確認しやすいため、迅速なプロトタイピングに向きます。一度設計を分割・抽象化するコストがかかるため、初動は遅く感じますが、反復性が高い大規模開発では安定感が出ます。

トレードオフと判断基準

いつゴッド寄りでいいかは、次のような条件で考えるとよいです。最初は速くてシンプルに見えますが、大きくなるほど壊れやすく運用も重くなります。だから機能が少ない試作や、人が少ない実験のときだけに寄せて、長く続くなら分ける準備をしておくのがおすすめです。

かんたんに言えば、一人でお試しならまとめてもよいが、大人数・本番・秘密が多いなら分ける。速さと安全のトレードオフ、ということになります。

  • プロジェクト規模・複雑度: 小規模で機能が少ないPoCやプロトタイプ開発では、ゴッドオブジェクトで迅速に動作させたほうが開発スピードが速い場合があります。一方、機能数が増え続ける大規模開発ではアーキテクチャが破綻しやすいです。
  • チーム体制: 開発者が少人数で役割分担が明確ならゴッド化で開発速度を優先できます。大人数や部門横断型開発では責任分界が曖昧になり衝突するため避けるべきです。
  • バイブコーディングの優先度: 要件定義が流動的でとにかく早く動くものを見たいフェーズ、すなわちバイブコーディングでは中央集約型が楽に感じられます。しかし要件が固まりCI/CD適用が必要な段階では、分割化してテスト可能性と安全性を確保した方がよいです。
  • セキュリティ・コンプライアンス要件: マルチテナント、厳格な監査ログやデータ保持方針が求められる環境では、権限境界をはっきり切らないゴッドオブジェクトはリスクが大きいです。支払・医療など機密性の高い領域では基本的に避けるべきです。
  • パフォーマンス要求: リソース制限のある組み込み環境など、単一プロセスでの軽量高速処理が絶対に必要な場合は、設計をシンプルにし中央管理を認めることも検討できます。
  • 既存資産との親和性: 既存に共通モジュールやインフラがあればそれを流用し、ゴッドオブジェクトにせずとも開発できます。逆に既存がない場合は一時的にまとめて実装し、後で分割するというアプローチもあります。

代替設計パターンと移行

全部を一つの箱にしないで済ませる、よくある作り方を並べます。名前は難しく見えますが、やっていることは、仕事を分ける・入口だけ一つに見せる・外から部品を差し込むのどれかです。

  • モジュール化・依存性注入: 機能ごとにクラスやサービスを分割し、依存性注入、DIコンテナで組み立てます。Semantic KernelのKernelオブジェクト例では、AIサービスやプラグインをKernelに登録し、DIコンテナで単一インスタンスを共有する設計が取られています。これはゴッドオブジェクト的に見えますが、役割ごとに明確に分かれた複数インスタンスを注入して組み合わせる形でゴッド化の弊害を抑制する手法です。
  • ファサード: システムの入口を単一に見せつつ、内部で複数のサービスに処理を委譲します。いわばゴッドオブジェクトに見えるインターフェースを残し、裏では分散処理する方法です。バイブコーディングの体験を維持しつつ、実装は分割できます。Facadeパターンは、Service LayerやAdapterパターンと組み合わせて用いられます。
  • コマンドパターン: ツール呼び出しをコマンドオブジェクトとして抽象化し、実行器、Invokerで各コマンドを処理します。ツール名・入力スキーマをコマンドクラスに持たせ、Invoker側が許可チェックと実行を担うことで、GodAgent内部でのツール実行ロジック集約を防げます。
  • ワークフロー/オーケストレーター: 関数呼び出しの流れをワークフローエンジンで定義し、ノード単位で役割分担します。LangChainのAgent実装がこれに近く、モデルノード、ツールノード、ミドルウェアノードなどをノード化して処理しています。これにより動的フローが可視化され、GodObject的な集中ロジックを回避できます。
  • マイクロサービス: 大規模なシステムではサービス単位でAPI化し、各サービスがそれぞれモデル呼び出しやログを持つ形に分割します。サービス間通信でデータを渡すため、単一プロセス化はされませんが、責務境界が明確になります。
  • プラグインアーキテクチャ: ツールや拡張機能をプラグインとして扱い、外部から登録・呼び出します。OpenAIのFunction Callingはアプリ側のカスタム関数をモデルに呼ばせる仕組みです。MCP(Model Context Protocol)は、serverがtools・resources・promptsを公開し、clientがそれらを利用する構造です。いずれの場合も、ツール実装はGodAgentの外部にあり、GodAgentは単にプラグインの呼び出し側となります。

どのパターンも、外から見た一か所管理のわかりやすさは残しつつ、中身は分けやすくする、という方向です。Semantic KernelのKernelのように中心はあるが、プラグインや履歴は別クラス、という形も典型です。

セキュリティ上の注意点

全部が一つに集まると、安全の面でもリスクが出やすくなります。

  • 権限分離の欠如: すべての処理を1つのオブジェクトが担うと、権限チェックが一元化され分散しません。結果として、万が一認可ミスやバグがあればアプリ全体に影響します。最小権限の原則を適用し、機能ごとに権限を細分化することが重要です。
  • 秘密情報管理: APIキーやモデルトークン、データベース接続情報などの機密情報をGodAgentに埋め込むと、漏洩時の影響が大きいです。秘密は分離管理し、環境変数やシークレットマネージャー経由で参照すべきです。
  • プロンプト/設定漏洩: プロンプトやシステムメッセージに機密データを含める運用は危険で、ゴッドオブジェクト化でこの情報がさらに集中します。アクセスログでプロンプトを平文保存せず暗号化や取り扱い規定を設ける必要があります。
  • 監査ログ不足: 動作が一箇所で行われるため、誰がどの機能をいつ呼んだかを個別に追いにくくなります。運用では、ユーザID・セッションID・コンテキストをログに含め、監査証跡を確実に取ることが重要です。
  • 過剰な権限: ゴッドオブジェクトにより処理が多くの機能を持つと、意図しない行動をするリスクが増大します。各機能呼び出しには最小権限の許可を設定し、与える権限を厳しく絞る必要があります。
  • 入力妥当性検証: システム全体を一箇所が管理するため、どの入力がどの機能に渡されるか監査が必要です。特にマルチテナント環境では、他テナントのデータを誤って参照しないよう、入力検証を徹底します。攻撃者が悪意ある命令を注入してデータ漏洩や不正行動を誘発する可能性を抑える工夫が必要です。

実例調査

世の中のLLM向けライブラリを見ると、中心を一つに見せつつ、中は分けていく例が増えています。最初は一つに見えるが、育つほど分ける、という方向に寄せていく例が多いです。

  • Semantic Kernel (Microsoft): Kernelオブジェクトがモデル呼び出しとプラグイン管理を担う中心コンポーネントと位置づけられています。開発者はKernelにAIサービスやプラグインを登録し、依存性注入で単一インスタンスを共有する設計となっており、一見ゴッドオブジェクト的ですが、プラグインは独立クラスであり、Kernelは実行の中心点に留めています。
  • OpenAI Agents SDK: 専門化したエージェントへの処理委譲や、エージェント間のhandoffsを実装しやすくする構成を推奨しています。複数の専門エージェントを組み合わせる設計が想定されており、単一の巨大エージェントを作ることは推奨されていません。
  • LangChain Agents: 近年の実装では、内部でLangGraph、ワークフローグラフを使い、プロンプトや状態の分離を図る設計が増えています。各エージェントはAPI呼び出しやツール実行をノードとして扱い、ノード化しやすい構造になっています。
  • AutoGPT / BabyAGI (2023-2024年頃の初期バージョン): これらの初期バージョンでは、Agentクラスがゴッドオブジェクト的に作られていることが多かったです。具体的には1つのAgentでPlan/Exec/Tool全て処理するケースです。後続のコミュニティ版では機能を分割し、TaskManagerやMemoryManagerを導入する流れがあります。

なお、規制産業(金融や医療など)では、権限の分離と監査性の確保が重要視される傾向があります。複数の機能を一つに集める設計より、役割ごとに分けた構成が好まれる場合が多いです。

短期~中長期の推奨事項

短期的対応: まずはGodAgentのような入口を一つ残しつつ、中身はサービスやヘルパーに任せる形から始めるとよいです。特に、ツールの実行、誰に何をさせるか、秘密の情報は、早めに分けます。プロンプトは型を決めて版を付け、出した結果は記録しておきます。バイブコーディングの速さは残しつつ、急な肥大を抑えられます。

中長期的対応: 流れ全体をワークフローツールや状態機械で表し、司令塔と仕事別のエージェントに分けていく計画を立てます。CI/CDに品質と安全の関所を入れ、テストと攻撃想定の練習を回します。権限分離や監査性のガイドラインは、レビューの話題出しに使えます。

参考資料

https://learn.microsoft.com/en-us/semantic-kernel/overview/
https://platform.openai.com/docs/guides/function-calling
https://github.com/modelcontextprotocol/specification
https://python.langchain.com/docs/concepts/architecture/
https://www.nist.gov/itl/ai-risk-management-framework
https://en.wikipedia.org/wiki/God_object
https://en.wikipedia.org/wiki/Vibe_coding

本記事の更新情報(版権管理)

  • 2026-04-05-01
  • 2026-04-05-02
  • 2026-04-05-03
  • 2026-04-05-04
  • 2026-04-05-05
  • 2026-04-05-06
  • 2026-04-06-07
  • 2026-04-06-08
  • 2026-04-06-09
  • 2026-04-06-10
  • 2026-04-06-11
  • 2026-04-06-12

関連記事