DeepAgent

DeepAgent 技術概要 — LangChain Deep Agentsフレームワークの全容

目次

  1. はじめに
  2. LangChainエコシステムにおける位置づけ
  3. アーキテクチャと設計思想
  4. コアAPI: create_deep_agent()
  5. 組み込み機能
  6. 永続実行とパーシステンス
  7. ストリーミングサポート
  8. Human-in-the-Loop統合
  9. カスタマイズと拡張ポイント
  10. LangSmithとの統合
  11. 実践的なコード例
  12. Deep Agents vs LangChain Agents vs LangGraph
  13. ベストプラクティス

1. はじめに

1.1 Deep Agentsとは何か

Deep Agents(DeepAgent)は、LangChainエコシステム内に位置する、高水準で「バッテリー同梱(batteries-included)」型のエージェントフレームワークである。従来のLLMアプリケーション開発では、プロンプト設計、ツール統合、コンテキスト管理、状態管理などを開発者自身が一つひとつ組み上げる必要があった。Deep Agentsはこれらの煩雑な作業を抽象化し、最小限の設定で実用的なAIエージェントを即座に構築できるように設計されている。

公式ドキュメントでは次のように紹介されている:

"An opinionated, ready-to-run agent out of the box. Instead of wiring up prompts, tools, and context management yourself, you get a working agent immediately."

つまり、プロンプト、ツール、コンテキスト管理を自分で配線する代わりに、すぐに動作するエージェントが手に入る。これがDeep Agentsの根本的な価値提案である。

1.2 なぜDeep Agentsが必要か

現代のLLMアプリケーション開発においては、以下のような課題が存在する:

複雑性の爆発: 単純なチャットボットから、複数のツールを使いこなし、長時間にわたるタスクを計画・実行するエージェントへと要件が高度化している。LangChainの基本コンポーネントだけでこれを実現しようとすると、相当量のボイラープレートコードが必要になる。

コンテキスト管理の難しさ: 長時間稼働するエージェントでは、コンテキストウィンドウの制限に直面する。古いメッセージの要約、ファイルシステムへの情報永続化、サブエージェントへのタスク委譲など、高度なコンテキスト管理戦略が求められる。

プロダクション要件: 耐障害性、ストリーミング、人間による承認ワークフロー、トレーシング・モニタリングなど、本番環境で必要な機能をゼロから実装するのは大きな負担である。

ツールエコシステムの断片化: 様々なツールプロバイダー、モデルプロバイダー、実行環境を統一的に扱える抽象層が必要である。

Deep Agentsは、これらの課題に対する包括的なソリューションとして設計された。

1.3 本記事の構成

本記事では、Deep Agentsの技術的な全容を30ページ相当のボリュームで解説する。アーキテクチャの設計思想から始まり、コアAPI、組み込み機能、永続化メカニズム、ストリーミング、Human-in-the-Loop、カスタマイズ方法、LangSmith統合、そして実践的なコード例まで、網羅的にカバーする。最後に、Deep Agents、LangChain Agents、LangGraphの使い分け指針とベストプラクティスを提示する。


2. LangChainエコシステムにおける位置づけ

2.1 エコシステム階層構造

LangChainエコシステムは、以下のような階層構造を持っている:

┌─────────────────────────────────────────┐
│           Deep Agents (最上位層)          │
│    高水準・batteries-included・即戦力     │
├─────────────────────────────────────────┤
│         LangChain Agents (中間層)        │
│    エージェント構築の基本ビルディングブロック  │
├─────────────────────────────────────────┤
│          LangGraph (基盤層)              │
│    ステートフルな実行ランタイム・グラフ構造   │
├─────────────────────────────────────────┤
│        LangChain Core (コア層)           │
│    プロンプト・モデル・チェーンの基本抽象    │
└─────────────────────────────────────────┘

この階層は、抽象度と利便性のトレードオフを表現している。下層に行くほど柔軟性が高いが、開発者が自分で組み立てる部分が多くなる。上層に行くほど即座に使えるが、カスタマイズの自由度はやや制限される。

2.2 LangChain Coreとの関係

LangChain Coreは、LLMアプリケーション開発の最も基本的な抽象を提供する。チャットモデル、プロンプトテンプレート、出力パーサー、ドキュメントローダーなどがこの層に含まれる。Deep Agentsは、LangChain Coreのチャットモデル抽象(BaseChatModel)を直接利用しており、これにより複数のモデルプロバイダーをシームレスに切り替えられる。

# LangChain Coreのチャットモデル抽象を活用
from langchain.chat_models import init_chat_model

model = init_chat_model("anthropic:claude-sonnet-4-6")

2.3 LangGraphとの関係

LangGraphは、ステートフルでマルチアクターなアプリケーションを構築するためのフレームワークである。ノードとエッジで構成されるグラフ構造により、複雑なワークフローを表現できる。Deep Agentsは、LangGraphの実行ランタイムを内部的に使用しており、以下の機能を継承している:

  • チェックポイント: 実行状態の永続化と障害復旧
  • ストリーミング: リアルタイムな実行状況の観察
  • 割り込み(Interrupts): Human-in-the-Loopワークフローの実装
  • スレッド管理: 複数の会話セッションの並行管理

重要なのは、create_deep_agent()が返すオブジェクトはコンパイル済みのLangGraphグラフであるという点だ。つまり、Deep Agentsで作成したエージェントは、LangGraphのすべての機能(ストリーミング、永続化、LangGraph Studioでの可視化など)をそのまま利用できる。

# create_deep_agent()はLangGraphのコンパイル済みグラフを返す
agent = create_deep_agent(tools=[...])

# LangGraphの標準的な呼び出しパターンがそのまま使える
result = agent.invoke(
    {"messages": [{"role": "user", "content": "タスクの説明"}]},
    config={"configurable": {"thread_id": "session-001"}}
)

2.4 LangChain Agentsとの関係

LangChain Agentsは、LangChain Coreの上に構築された中間レベルのエージェント構築キットである。ツールバインディング、ReActパターン、計画実行パターンなどの基本的なエージェントアーキテクチャを提供する。Deep Agentsは、これらの概念をさらに発展させ、以下を追加している:

  • 自動的なタスク計画: write_todosツールによるタスク分解と進捗追跡
  • コンテキスト管理: 自動要約とファイルシステムベースの情報永続化
  • サブエージェント: taskツールによるコンテキスト分離されたサブタスク委譲
  • ミドルウェアアーキテクチャ: プロンプトキャッシング、メモリ、スキルなどの横断的関心事

2.5 Deep Agents CLI

Deep Agentsには、ターミナルベースのコーディングエージェントとして動作するCLIツールも含まれている。このCLIは以下の特徴を持つ:

  • 対話型インターフェース
  • ウェブ検索統合
  • ヘッドレスモード(CI/CDパイプライン向け)
  • リモートサンドボックスでの実行
  • MCP(Model Context Protocol)ツールのサポート

2.6 ACP統合

ACP(Agent Control Protocol)を通じて、Deep AgentsはZedなどのコードエディタと統合できる。これにより、エディタ内から直接エージェントの能力を活用した開発ワークフローが実現する。


3. アーキテクチャと設計思想

3.1 設計原則

Deep Agentsのアーキテクチャは、以下の設計原則に基づいている:

Batteries-Included(バッテリー同梱): 最初から実用的な機能が揃っている。計画ツール、ファイルシステム操作、コンテキスト管理、自動要約など、エージェントに必要な基本機能がデフォルトで含まれている。

Minimal Configuration(最小構成): ゼロコンフィグでも動作し、必要に応じて段階的にカスタマイズできる。create_deep_agent()を引数なしで呼ぶだけで、デフォルト設定で動作するエージェントが得られる。

Opinionated Defaults(意見のあるデフォルト値): 多くの設計決定がフレームワーク側で行われている。デフォルトのシステムプロンプト、ツールセット、コンテキスト管理戦略など、ベストプラクティスに基づいたデフォルト値が設定されている。

Progressive Disclosure(段階的開示): 単純なユースケースでは単純なAPIを使い、高度なユースケースでは詳細な設定にアクセスできる。初心者は表面のAPIだけで十分であり、上級者は内部のLangGraphグラフに直接アクセスして細かな制御が可能。

Provider Agnostic(プロバイダー非依存): 特定のLLMプロバイダーに依存しない。Anthropic、OpenAI、Google、オープンソースモデルなど、ツール呼び出しをサポートする任意のモデルで動作する。

3.2 内部アーキテクチャ

Deep Agentsの内部アーキテクチャは、以下のコンポーネントで構成される:

┌──────────────────────────────────────────────────┐
│                  Deep Agent                       │
│  ┌────────────────────────────────────────────┐  │
│  │           ミドルウェアスタック               │  │
│  │  ┌────────────┐ ┌────────────┐            │  │
│  │  │ TodoList   │ │ Filesystem │            │  │
│  │  ├────────────┤ ├────────────┤            │  │
│  │  │ SubAgent   │ │ Summarize  │            │  │
│  │  ├────────────┤ ├────────────┤            │  │
│  │  │ PromptCache│ │  Memory    │            │  │
│  │  ├────────────┤ ├────────────┤            │  │
│  │  │  Skills    │ │  Approval  │            │  │
│  │  └────────────┘ └────────────┘            │  │
│  └────────────────────────────────────────────┘  │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐     │
│  │  Model   │ │  Tools   │ │  Backend     │     │
│  │ Provider │ │  Registry│ │  (Storage)   │     │
│  └──────────┘ └──────────┘ └──────────────┘     │
│  ┌────────────────────────────────────────────┐  │
│  │         LangGraph Runtime                  │  │
│  │   (状態管理・チェックポイント・ストリーミング)  │  │
│  └────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────┘

ミドルウェアスタック

Deep Agentsのミドルウェアは、エージェントの動作を横断的に拡張するコンポーネント群である。デフォルトで有効なミドルウェアと、オプションで追加できるミドルウェアがある。

デフォルトミドルウェア:

  • TodoList: タスクの計画と進捗管理を提供するwrite_todosツールを注入
  • Filesystem: ファイルの読み書き、ディレクトリ操作のツールを注入
  • SubAgent: サブエージェント生成のtaskツールを注入
  • Summarization: コンテキストウィンドウが長くなった際の自動要約
  • Prompt Caching: プロンプトキャッシュによるコスト・レイテンシ最適化

オプションミドルウェア:

  • Memory: LangGraphのMemory Storeを使った長期記憶
  • Skills: ドメイン固有のワークフロー定義をAGENTS.mdファイルから読み込み
  • Approval: Human-in-the-Loopの承認ワークフロー

モデルプロバイダー

モデルプロバイダーは、LangChainのBaseChatModel抽象を通じて統一的に扱われる。provider:model形式の文字列指定か、init_chat_model()による詳細設定のいずれかで構成できる。

ツールレジストリ

組み込みツール(計画、ファイルシステム、サブエージェントなど)とユーザー定義のカスタムツールを統合管理する。MCP(Model Context Protocol)経由のツールもサポートされる。

バックエンド

ファイルシステムの実体を決定するプラグイン可能なストレージ層。インメモリ、ローカルディスク、LangGraph Store、サンドボックスなどから選択できる。

3.3 エージェントハーネスとしての役割

Deep Agentsは「エージェントハーネス」として機能する。これは、LLMの能力を最大限に引き出すための周辺インフラを意味する。具体的には:

  1. 入力の前処理: ユーザーメッセージにシステムプロンプトとツールドキュメントを付加
  2. 実行管理: LLMの出力を解析し、ツール呼び出しを実行し、結果をフィードバック
  3. コンテキスト最適化: 長くなったコンテキストを自動的に要約・圧縮
  4. エラーハンドリング: ネットワークエラーやレート制限に対する自動リトライ
  5. 出力の後処理: 結果のストリーミング配信、状態の永続化

3.4 コンテキスト管理戦略

Deep Agentsの最も重要な設計上の特徴の一つが、高度なコンテキスト管理である。長時間稼働するエージェントでは、コンテキストウィンドウの制限が大きな問題となる。Deep Agentsは以下の戦略でこれに対処する:

自動要約: コンテキストウィンドウが一定のしきい値を超えると、古いメッセージが自動的に要約され、圧縮される。これにより、重要な情報を保持しつつ、コンテキストの肥大化を防ぐ。

ファイルシステムへの外部化: 中間結果や重要な情報をファイルとして保存し、必要に応じて読み戻す。これにより、コンテキストウィンドウの制約を超えた情報管理が可能になる。

サブエージェントによるコンテキスト分離: taskツールで生成されるサブエージェントは、独立したコンテキストを持つ。これにより、特定のサブタスクに必要な情報だけが処理され、メインエージェントのコンテキストが汚染されない。


4. コアAPI: create_deep_agent()

4.1 基本的な使い方

create_deep_agent()は、Deep Agentsの中心的なAPIである。この関数一つでエージェントの構築が完了する。

from deepagents import create_deep_agent

# 最小構成 - デフォルト設定でエージェントを作成
agent = create_deep_agent()

# エージェントの呼び出し
result = agent.invoke({
    "messages": [{"role": "user", "content": "Pythonでフィボナッチ数列を計算する関数を書いてください"}]
})

4.2 主要パラメータ

create_deep_agent()は以下の主要パラメータを受け付ける:

model

使用するLLMモデルを指定する。provider:model形式の文字列またはBaseChatModelインスタンスを受け付ける。

# 文字列形式
agent = create_deep_agent(model="anthropic:claude-sonnet-4-6")
agent = create_deep_agent(model="openai:gpt-5.3-codex")
agent = create_deep_agent(model="google_genai:gemini-3-flash")

# BaseChatModelインスタンス
from langchain.chat_models import init_chat_model

model = init_chat_model(
    "anthropic:claude-sonnet-4-6",
    thinking={"type": "enabled", "budget_tokens": 10000}
)
agent = create_deep_agent(model=model)

tools

カスタムツールのリストを指定する。組み込みツール(TodoList、Filesystem、SubAgentなど)に加えて、ユーザー定義のツールが追加される。

def search_web(query: str) -> str:
    """ウェブ検索を実行し、結果を返す。

    Args:
        query: 検索クエリ文字列
    """
    from tavily import TavilyClient
    client = TavilyClient()
    results = client.search(query)
    return str(results)

agent = create_deep_agent(tools=[search_web])

system_prompt

エージェントの動作を指示するシステムプロンプトを指定する。デフォルトのスマートプロンプトに置き換わるか、追加される。

agent = create_deep_agent(
    system_prompt="""あなたはシニアソフトウェアエンジニアです。
    コードレビューを行い、改善提案を提供してください。
    常にベストプラクティスに従い、セキュリティ上の問題を指摘してください。"""
)

backend

ファイルシステムバックエンドを指定する。

from deepagents.backends import FilesystemBackend, StoreBackend

# ローカルファイルシステム
agent = create_deep_agent(
    backend=FilesystemBackend(root_dir="/path/to/workspace")
)

# LangGraph Store(永続ストレージ)
agent = create_deep_agent(
    backend=StoreBackend(namespace_factory=lambda config: ["user", config["user_id"]])
)

4.3 返り値の性質

create_deep_agent()はコンパイル済みのLangGraphグラフを返す。これは以下のメソッドを持つ:

agent = create_deep_agent(tools=[...])

# 同期呼び出し
result = agent.invoke(input, config)

# 非同期呼び出し
result = await agent.ainvoke(input, config)

# ストリーミング
for event in agent.stream(input, config, stream_mode="updates"):
    print(event)

# 非同期ストリーミング
async for event in agent.astream(input, config, stream_mode="updates"):
    print(event)

4.4 入力フォーマット

エージェントへの入力は、LangGraphの標準的なメッセージフォーマットに従う:

# 基本的な入力
input_data = {
    "messages": [
        {"role": "user", "content": "タスクの説明"}
    ]
}

# マルチターン会話
input_data = {
    "messages": [
        {"role": "user", "content": "最初の質問"},
        {"role": "assistant", "content": "最初の回答"},
        {"role": "user", "content": "フォローアップの質問"}
    ]
}

4.5 設定(Config)オブジェクト

LangGraphの設定オブジェクトを使って、スレッドIDやその他の設定を渡す:

config = {
    "configurable": {
        "thread_id": "unique-session-id",
        "user_id": "user-123"
    }
}

result = agent.invoke(input_data, config=config)

5. 組み込み機能

5.1 計画ツール (write_todos)

write_todosは、複雑なタスクを個別のステップに分解するための組み込みツールである。エージェントはこのツールを使って:

  1. タスクを論理的なサブタスクに分割する
  2. 各サブタスクの完了状態を追跡する
  3. 進捗に応じて計画を動的に更新する
# write_todosツールの動作イメージ
# エージェントが内部的に以下のようなTodoリストを管理する:
# [x] Step 1: 要件を分析する
# [x] Step 2: データモデルを設計する
# [ ] Step 3: APIエンドポイントを実装する
# [ ] Step 4: テストを書く
# [ ] Step 5: ドキュメントを更新する

このツールにより、エージェントは「考えてから行動する」パターンを自然に実行できる。特に複数のステップを要する複雑なタスクにおいて、計画性と追跡可能性が大幅に向上する。

5.2 ファイルシステムツール

Deep Agentsには、ファイルシステム操作のための一連の組み込みツールが含まれている:

  • ls: ディレクトリの内容を一覧表示
  • read_file: ファイルの内容を読み取り(画像のマルチモーダル読み取りも対応)
  • write_file: 新規ファイルの作成
  • edit_file: 既存ファイルの部分的な編集

これらのツールは、選択されたバックエンドに応じて、インメモリ、ローカルディスク、LangGraph Storeなど、異なるストレージに透過的にアクセスする。

5.3 シェル実行ツール (execute)

executeツールは、シェルコマンドの実行を可能にする。ただし、このツールはサンドボックスバックエンドまたはLocalShellBackend使用時にのみ利用可能である。

from deepagents.backends import LocalShellBackend

# ローカルシェル実行を有効にする(開発環境のみ推奨)
agent = create_deep_agent(
    backend=LocalShellBackend(root_dir="/path/to/workspace")
)

セキュリティ上の注意: LocalShellBackendはホストマシン上で直接コマンドを実行するため、信頼できない入力を処理する場合は、Modal、Daytona、Denoなどのサンドボックス環境を使用すべきである。

5.4 サブエージェントツール (task)

taskツールは、Deep Agentsの最も強力な機能の一つである。メインエージェントから独立したコンテキストを持つサブエージェントを生成し、特定のサブタスクを委譲する。

# エージェントが内部的にtaskツールを使用するイメージ
# メインエージェント: "大規模なコードベースをリファクタリングしてください"
#
# -> task("モジュールAの依存関係を分析して") -> サブエージェントA
# -> task("モジュールBのテストカバレッジを確認して") -> サブエージェントB
# -> task("リファクタリング計画を立てて") -> サブエージェントC
#
# 各サブエージェントは独立したコンテキストで動作し、
# 結果だけがメインエージェントに返される

この設計により:

  • コンテキストの汚染防止: 各サブタスクのコンテキストが分離される
  • トークン効率: メインエージェントは必要な結果だけを受け取る
  • 並行性の可能性: 将来的にサブエージェントの並行実行が可能

5.5 モデル統合

Deep Agentsは、ツール呼び出しをサポートする幅広いLLMプロバイダーと統合できる:

プロバイダー代表的なモデル設定例
AnthropicClaude Opus, Sonnet, Haiku"anthropic:claude-sonnet-4-6"
OpenAIGPT-5.4, GPT-4o, o3"openai:gpt-5.3-codex"
GoogleGemini 3 Flash/Pro"google_genai:gemini-3-flash"
OpenRouter各種モデル"openrouter:model-name"
Fireworks高速推論モデル"fireworks:model-name"
Ollamaローカル実行モデル"ollama:model-name"
AWS BedrockBedrockモデル"bedrock:model-name"
# 環境変数によるAPIキー設定
import os
os.environ["ANTHROPIC_API_KEY"] = "sk-..."
os.environ["OPENAI_API_KEY"] = "sk-..."

# モデルの切り替え
agent_anthropic = create_deep_agent(model="anthropic:claude-sonnet-4-6")
agent_openai = create_deep_agent(model="openai:gpt-5.3-codex")
agent_google = create_deep_agent(model="google_genai:gemini-3-flash")

5.6 拡張思考(Extended Thinking)

一部のモデルでは、拡張思考機能を有効にすることで、より深い推論が可能になる:

from langchain.chat_models import init_chat_model

model = init_chat_model(
    "anthropic:claude-sonnet-4-6",
    thinking={"type": "enabled", "budget_tokens": 10000}
)

agent = create_deep_agent(model=model)

5.7 システムプロンプト

Deep Agentsは、デフォルトで最適化されたシステムプロンプトを持っている。このプロンプトは以下の要素を含む:

  • エージェントの基本的な振る舞いの指示
  • ツールの使用方法に関するガイダンス
  • 計画立案の推奨パターン
  • コンテキスト管理のベストプラクティス

ユーザーはこのデフォルトプロンプトを完全に置き換えるか、追加のドメイン固有の指示を付加できる。フレームワークは、ミドルウェアによって生成されるツールドキュメントを自動的にシステムプロンプトに付加する。


6. 永続実行とパーシステンス

6.1 チェックポイントメカニズム

Deep AgentsはLangGraphのチェックポイント機能を継承しており、エージェントの実行状態を任意の時点で永続化できる。これにより:

  • 障害復旧: ネットワークエラーやプロセスクラッシュ後に、最後のチェックポイントから実行を再開
  • 長時間タスク: 数時間にわたるタスクを安全に実行し、中断・再開が可能
  • 監査: 実行の各ステップを記録し、後から再現・分析が可能
from langgraph.checkpoint.memory import MemorySaver

# インメモリチェックポインタ
checkpointer = MemorySaver()

# チェックポイント付きでエージェントを使用
agent = create_deep_agent(tools=[...])

# thread_idを指定することで、セッション間の状態が保持される
config = {"configurable": {"thread_id": "persistent-session"}}
result = agent.invoke(
    {"messages": [{"role": "user", "content": "最初のメッセージ"}]},
    config=config
)

# 同じthread_idで再開 - 前回の会話が継続される
result2 = agent.invoke(
    {"messages": [{"role": "user", "content": "続きの質問"}]},
    config=config
)

6.2 バックエンドの種類と選択

Deep Agentsは複数のバックエンドを提供しており、用途に応じて選択できる:

StateBackend(デフォルト)

LangGraphの状態内にファイルを保存する。エフェメラル(一時的)だが、チェックポイントを通じてスレッド内では永続化される。

# デフォルトでStateBackendが使用される
agent = create_deep_agent()

特徴: 追加のインフラ不要。スクラッチパッドとして最適。スレッド間ではデータが共有されない。

FilesystemBackend

ローカルディスクにファイルを保存する。開発やCI/CD環境での使用に適している。

from deepagents.backends import FilesystemBackend

agent = create_deep_agent(
    backend=FilesystemBackend(root_dir="/workspace/project")
)

注意: 本番Webサービスでは使用しないこと。

StoreBackend

LangGraphのStoreインフラを使った永続ストレージ。LangSmithデプロイメントやRedis/Postgresバックエンドと連携する。

from deepagents.backends import StoreBackend

agent = create_deep_agent(
    backend=StoreBackend(
        namespace_factory=lambda config: ["users", config["configurable"]["user_id"]]
    )
)

特徴: スレッド間でデータを共有可能。マルチユーザーデプロイメントに対応。

LocalShellBackend

ファイルシステムアクセスに加えて、シェルコマンド実行のexecuteツールを提供する。

from deepagents.backends import LocalShellBackend

agent = create_deep_agent(
    backend=LocalShellBackend(root_dir="/workspace")
)

警告: ホスト上で直接実行されるため、信頼できる環境でのみ使用。

CompositeBackend

複数のバックエンドを組み合わせて使用する。パスに応じて異なるバックエンドにルーティングする。

from deepagents.backends import CompositeBackend, StateBackend, StoreBackend

agent = create_deep_agent(
    backend=CompositeBackend(
        routes={
            "/memories/": StoreBackend(...),  # メモリは永続化
            "/": StateBackend()                # その他はエフェメラル
        }
    )
)

6.3 サンドボックス環境

本番環境で信頼できない入力を処理する場合、サンドボックス環境が推奨される: Modal(クラウドベース)、Daytona(コンテナベース)、Deno(隔離ランタイム)。

6.4 長期メモリ

LangGraphのMemory Storeを使用することで、会話をまたいだ長期記憶が実現できる。

6.5 接続レジリエンス

Deep Agentsは、ネットワークエラーやレート制限に対する自動リトライ機能を備えている。デフォルトでは6回のリトライが設定されているが、不安定なネットワーク環境では10〜15回に増やすことが推奨される。


7. ストリーミングサポート

7.1 ストリーミングの概要

Deep Agentsは、LangGraphの強力なストリーミング機能を継承している。ストリーミングにより、エージェントの実行過程をリアルタイムで観察できる。

7.2 ストリーミングモード

updatesモード

グラフの各ノードが完了するたびにイベントが発行される。

agent = create_deep_agent(tools=[search_web])

for event in agent.stream(
    {"messages": [{"role": "user", "content": "最新のAI動向を調べてください"}]},
    stream_mode="updates"
):
    for node_name, node_data in event.items():
        if "messages" in node_data:
            for message in node_data["messages"]:
                print(f"[{node_name}] {message}")

valuesモード

グラフの状態全体がステップごとに出力される。

for state in agent.stream(
    {"messages": [{"role": "user", "content": "レポートを作成してください"}]},
    stream_mode="values"
):
    messages = state.get("messages", [])
    if messages:
        latest = messages[-1]
        print(f"最新メッセージ: {latest}")

messagesモード

LLMのトークン生成をリアルタイムで取得する。チャットUIでの表示に最適。

for event in agent.stream(
    {"messages": [{"role": "user", "content": "エッセイを書いてください"}]},
    stream_mode="messages"
):
    if hasattr(event, 'content'):
        print(event.content, end="", flush=True)

7.3 非同期ストリーミング

asyncioを使った非同期ストリーミングも完全にサポートされている:

import asyncio

async def stream_agent():
    agent = create_deep_agent(tools=[search_web])

    async for event in agent.astream(
        {"messages": [{"role": "user", "content": "分析を実行してください"}]},
        stream_mode="updates"
    ):
        for node_name, node_data in event.items():
            print(f"ノード: {node_name}")
            if "messages" in node_data:
                for msg in node_data["messages"]:
                    print(f"  メッセージ: {msg}")

asyncio.run(stream_agent())

7.4 ストリーミングイベントの種類

Deep Agentsの実行中に発生する主なストリーミングイベント:

  1. LLM応答の生成: モデルがテキストを生成する過程
  2. ツール呼び出し: エージェントがツールを使用する決定
  3. ツール実行結果: ツールからの返り値
  4. サブエージェントの活動: taskツールで生成されたサブエージェントの実行
  5. コンテキスト要約: 自動要約が実行された際のイベント
  6. 計画の更新: TodoListの更新
  7. ファイル操作: ファイルの読み書き

8. Human-in-the-Loop統合

8.1 概要

Human-in-the-Loop(HITL)は、エージェントの自律的な実行フローに人間の判断を挿入するパターンである。Deep Agentsは、LangGraphの割り込み(Interrupt)メカニズムを活用して、柔軟なHITLワークフローを提供する。

8.2 承認ワークフロー

特定のツール呼び出しに対して、人間の承認を要求するように設定できる:

agent = create_deep_agent(
    tools=[search_web, execute_trade, send_email],
    approval_tools=["execute_trade", "send_email"]
)

8.3 承認の選択肢

  • 承認(Approve): ツール呼び出しをそのまま実行
  • 拒否(Reject): ツール呼び出しをキャンセルし、エージェントに理由をフィードバック
  • 編集(Edit): ツール呼び出しのパラメータを修正してから実行
config = {"configurable": {"thread_id": "hitl-session"}}

for event in agent.stream(
    {"messages": [{"role": "user", "content": "重要なメールを送信してください"}]},
    config=config,
    stream_mode="updates"
):
    if "__interrupt__" in event:
        interrupt = event["__interrupt__"]
        print(f"承認が必要: {interrupt}")
        approval = input("承認しますか? (approve/reject/edit): ")

        if approval == "approve":
            agent.invoke(None, config=config)
        elif approval == "reject":
            agent.invoke(
                {"messages": [{"role": "user", "content": "送信先を確認してから再度お願いします"}]},
                config=config
            )

8.4 グラニュラーな制御

  • 条件付き承認: 特定の条件でのみ承認を要求
  • 段階的承認: 複数の承認者による段階的な承認プロセス
  • 自動承認: 一定の条件を満たす場合は自動的に承認

8.5 実践的なHITLパターン

# パターン1: 高リスク操作の承認
agent = create_deep_agent(
    tools=[read_database, write_database, call_external_api],
    approval_tools=["write_database", "call_external_api"]
)

# パターン2: デプロイ前の承認
agent = create_deep_agent(
    tools=[write_file, execute_code, deploy],
    approval_tools=["deploy"]
)

# パターン3: コンテンツ公開前の承認
agent = create_deep_agent(
    tools=[draft_post, publish_post, send_email],
    approval_tools=["publish_post", "send_email"]
)

9. カスタマイズと拡張ポイント

9.1 カスタムツールの作成

Python関数として定義されたカスタムツールを簡単に追加できる。型ヒントとdocstringが、ツールのスキーマとして自動的に使用される。

from typing import Dict

def analyze_sentiment(text: str) -> Dict[str, float]:
    """テキストの感情分析を実行する。

    Args:
        text: 分析対象のテキスト

    Returns:
        感情スコアの辞書(positive, negative, neutral)
    """
    from textblob import TextBlob
    blob = TextBlob(text)
    polarity = blob.sentiment.polarity
    return {
        "positive": max(0, polarity),
        "negative": max(0, -polarity),
        "neutral": 1 - abs(polarity)
    }

agent = create_deep_agent(
    tools=[analyze_sentiment],
    system_prompt="あなたは金融アナリストです。"
)

9.2 MCP(Model Context Protocol)統合

from langchain_mcp_adapters import MCPToolkit

toolkit = MCPToolkit(server_url="http://localhost:8080")
mcp_tools = toolkit.get_tools()

agent = create_deep_agent(tools=[*mcp_tools, custom_tool])

9.3 ミドルウェアの設定

agent = create_deep_agent(
    middleware_config={
        "summarization": {"enabled": True, "threshold_tokens": 50000},
        "prompt_caching": {"enabled": True},
        "memory": {"enabled": True},
        "skills": {"enabled": True, "skills_dir": "/path/to/skills"},
        "approval": {"enabled": True, "tools": ["dangerous_tool"]}
    }
)

9.4 スキルシステム

AGENTS.mdファイルや専用のスキルディレクトリに記述され、関連する場合にのみアクティベートされる。トークン消費は必要時のみ。

9.5 ランタイムモデル切り替え

from deepagents.middleware import wrap_model_call

@wrap_model_call
def select_model(config, current_model):
    user_preference = config.get("configurable", {}).get("model_preference")
    if user_preference:
        return init_chat_model(user_preference)
    return current_model

9.6 サブエージェントのカスタマイズ

agent = create_deep_agent(
    tools=[...],
    subagent_config={
        "model": "anthropic:claude-haiku-3-5",
        "tools": [read_file, write_file],
        "system_prompt": "あなたはリサーチアシスタントです。"
    }
)

10. LangSmithとの統合

10.1 トレーシングの有効化

export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY="ls-..."
export LANGSMITH_PROJECT="my-deep-agent-project"

10.2 トレースで確認できる情報

  • LLMの入出力、ツール呼び出し、実行時間、トークン使用量、エラー情報、サブエージェントの実行

10.3 デバッグワークフロー

  1. LangSmithダッシュボードで失敗したトレースを確認
  2. 各ステップのLLM入出力を調べ、原因を特定
  3. プロンプトを修正
  4. 新しいトレースで検証

10.4 評価パイプライン

from langsmith import Client

client = Client()
dataset = client.create_dataset("deep-agent-eval")

client.create_examples(
    inputs=[
        {"messages": [{"role": "user", "content": "Pythonでソートアルゴリズムを実装して"}]},
    ],
    outputs=[
        {"expected": "正しいソートアルゴリズムの実装"},
    ],
    dataset_id=dataset.id
)

11. 実践的なコード例

11.1 例1: リサーチエージェント

import os
from deepagents import create_deep_agent
from tavily import TavilyClient

os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."
os.environ["TAVILY_API_KEY"] = "tvly-..."

def search_web(query: str) -> str:
    """ウェブを検索して最新の情報を取得する。"""
    client = TavilyClient()
    results = client.search(query, max_results=5)
    formatted = []
    for r in results["results"]:
        formatted.append(f"タイトル: {r['title']}\nURL: {r['url']}\n内容: {r['content']}\n")
    return "\n---\n".join(formatted)

research_agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[search_web],
    system_prompt="""あなたは優秀なリサーチアナリストです。
    与えられたトピックについて徹底的に調査し、レポートを作成してください。"""
)

result = research_agent.invoke({
    "messages": [{"role": "user", "content": "2026年のAIエージェント市場の動向について調査してください"}]
})

11.2 例2: コードアシスタント

from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend

code_agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    backend=LocalShellBackend(root_dir="/workspace/project"),
    system_prompt="あなたはシニアソフトウェアエンジニアです。"
)

result = code_agent.invoke({
    "messages": [{"role": "user", "content": "FastAPIでREST APIを作成してください"}]
})

11.3 例3: マルチエージェントシステム

from deepagents import create_deep_agent

orchestrator = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[search_web],
    system_prompt="""あなたはプロジェクトマネージャーです。
    taskツールを使ってサブエージェントに委譲してください。"""
)

result = orchestrator.invoke({
    "messages": [{"role": "user", "content": "新しいSaaSプロダクトのローンチ計画を作成してください"}]
})

11.4 例4: ストリーミング付きチャットアプリケーション

import asyncio
from deepagents import create_deep_agent

async def chat_application():
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",
        system_prompt="あなたは親切なアシスタントです。"
    )
    config = {"configurable": {"thread_id": "chat-session-1"}}

    while True:
        user_input = input("\nあなた: ")
        if user_input.lower() in ["quit", "exit", "終了"]:
            break

        print("\nアシスタント: ", end="", flush=True)
        async for event in agent.astream(
            {"messages": [{"role": "user", "content": user_input}]},
            config=config,
            stream_mode="messages"
        ):
            if hasattr(event, 'content') and event.content:
                print(event.content, end="", flush=True)
        print()

if __name__ == "__main__":
    asyncio.run(chat_application())

11.5 例5: 永続化とセッション管理

from deepagents import create_deep_agent
from deepagents.backends import StoreBackend

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    backend=StoreBackend(
        namespace_factory=lambda config: ["users", config["configurable"]["user_id"]]
    )
)

config = {"configurable": {"thread_id": "session-001", "user_id": "user-abc"}}
result = agent.invoke({
    "messages": [{"role": "user", "content": "私の好みのプログラミング言語はPythonです。覚えておいてください。"}]
}, config=config)

# 別のスレッドでも過去の情報にアクセス可能
config2 = {"configurable": {"thread_id": "session-002", "user_id": "user-abc"}}
result2 = agent.invoke({
    "messages": [{"role": "user", "content": "私の好みのプログラミング言語は何でしたっけ?"}]
}, config=config2)

12. Deep Agents vs LangChain Agents vs LangGraph

12.1 比較概要

特性Deep AgentsLangChain AgentsLangGraph
抽象レベル
セットアップ時間最短(分単位)中程度(時間単位)最長(日単位)
柔軟性中程度最高
組み込みツール豊富基本的なし
コンテキスト管理自動手動手動
タスク計画組み込み手動実装手動実装
サブエージェント組み込み手動実装手動実装
ストリーミング自動部分的完全制御
永続化自動要設定完全制御
学習曲線

12.2 Deep Agentsを選ぶべき場面

  • 複雑なマルチステップタスク
  • 迅速なプロトタイピング
  • コーディングエージェント
  • 長時間実行タスク
  • 定型的なエージェントパターン

12.3 LangChain Agentsを選ぶべき場面

  • カスタムエージェントロジック
  • 軽量なエージェント
  • 既存のLangChainパイプラインへの統合
  • 細かなプロンプトエンジニアリング

12.4 LangGraphを選ぶべき場面

  • 高度にカスタマイズされたワークフロー
  • 非標準的なアーキテクチャ
  • マルチアクターシステム
  • 最大限のパフォーマンス最適化

12.5 段階的な移行パス

  1. Deep Agentsで開始: 素早くプロトタイプを構築
  2. カスタマイズの必要性を評価: デフォルトの動作が合わない部分を特定
  3. 段階的にLangGraphの機能を活用: 細かな制御を追加
  4. 必要に応じてフルLangGraphに移行: 完全にカスタムなグラフを構築

13. ベストプラクティス

13.1 モデル選択

  1. メインエージェントには高性能モデルを使用
  2. サブエージェントにはコスト効率の良いモデルを使用
  3. 拡張思考を適切に活用

13.2 ツール設計

  1. 明確なdocstringを書く
  2. 型ヒントを必ず付ける
  3. エラーハンドリングを含める
  4. ツール数を10〜15個程度に抑える

13.3 システムプロンプト

  1. 役割を明確に定義
  2. 制約条件を列挙
  3. 出力形式を指定
  4. 例を含める

13.4 バックエンド選択

  1. 開発環境: StateBackend(デフォルト)
  2. ローカル開発: FilesystemBackend
  3. 本番(信頼できる入力): StoreBackend + Redis/Postgres
  4. 本番(信頼できない入力): サンドボックス
  5. ハイブリッド: CompositeBackend

13.5 セキュリティ

  1. APIキーは環境変数で管理
  2. 本番環境ではサンドボックスを使用
  3. 高リスク操作にはHITLを設定
  4. 入力バリデーションでプロンプトインジェクションを防止

13.6 モニタリング

  1. LangSmithトレーシングを常に有効化
  2. トークン使用量とコストを監視
  3. エラー率のアラートを設定
  4. ユーザーフィードバックを収集

13.7 テスト

  1. ツールのユニットテスト
  2. エージェント全体の統合テスト
  3. LangSmith評価パイプライン
  4. プロンプト変更時の回帰テスト

まとめ

Deep Agents(DeepAgent)は、LangChainエコシステムにおいて、AIエージェント開発の民主化を推進する重要なフレームワークである。「batteries-included」の設計思想により、数行のコードで実用的なエージェントを構築できる一方、LangGraphとの完全な互換性により、必要に応じて高度なカスタマイズも可能である。

本記事で解説したように、Deep Agentsは以下の価値を提供する:

  1. 即座に動作するエージェント: 最小限の設定で実用的なエージェントが得られる
  2. 包括的な組み込み機能: 計画、ファイルシステム、サブエージェント、コンテキスト管理が標準装備
  3. プロダクション対応: 永続化、ストリーミング、HITL、モニタリングが統合済み
  4. 段階的な拡張: シンプルな開始から、高度なカスタマイズまでスムーズに移行
  5. エコシステム統合: LangChain、LangGraph、LangSmith、MCPとのシームレスな連携

AIエージェント開発の次のフェーズにおいて、Deep Agentsは開発者の生産性を劇的に向上させる存在となるだろう。


本記事は2026年4月時点の情報に基づいています。Deep Agentsは活発に開発が進められているプロジェクトであり、APIや機能は変更される可能性があります。最新の情報については、公式ドキュメント(https://docs.langchain.com/oss/python/deepagents/overview)を参照してください。