Deep Agents入門チュートリアル
Deep Agentsは、LangChain公式が提供する、すぐに使える(Batteries Included)Agent開発フレームワークです。複雑なタスク、長いフローの実行、多段階の計画、そして複数Agentの協調シナリオに特化して設計されています。
従来のAgentでは、開発者がPrompt、Tool、Memory、Workflowなどのコンポーネントを自分で組み合わせる必要がありましたが、Deep Agentsはタスク計画、ファイルシステム、子Agentのスケジューリング、コンテキスト圧縮、メモリ管理などのコア機能をすでに内蔵しており、開発者は基盤アーキテクチャの構築ではなく、ビジネスロジックに多くの労力を集中できます。
本チュートリアルは前提知識のない開発者を対象としており、インストールと設定から始めて、Deep Agentsのコアな動作メカニズムを段階的に理解し、DeepSeek APIを使用して実際に動作するAI Agentプロジェクトを構築します。
Deep Agentsとは
Deep Agentsは、本番環境向けの高度なAgentフレームワーク(Agent Harness)と理解できます。
公式では、単なるLLM + Tool呼び出しループではなく、完全なインフラストラクチャを備えたAgent実行フレームワークと定義されています。
インストールが完了すると、追加開発なしで以下の機能をすぐに利用できます:
- 自動タスク計画(Planning)
- ファイルシステムの読み書き(Filesystem)
- 子Agentの連携(Sub Agents)
- コンテキストの圧縮と管理(Context Management)
- 長時間タスクの実行(Long Running Tasks)
- 人間による承認(Human-in-the-Loop)
- 永続化メモリ(Memory)
- ストリーミング出力(Streaming)
Deep Agentsの設計目標
従来のAgentは通常、ReActパターンを採用しています:ユーザー入力 → LLM推論 → ツール呼び出し → LLM推論 → ツール呼び出し → 結果の出力。
タスクの規模が小さい場合、このパターンは良好に動作します。しかし、タスクの複雑さが増すにつれて(例:市場調査レポートの自動生成、複数企業の財務諸表の分析、完全なプロジェクトコードの作成)、以下の問題が徐々に顕在化します:
- コンテキストウィンドウが急速に膨張し、モデルの制限を超える
- 推論チェーンが長すぎてパフォーマンスが低下する
- Agentが以前に完了した作業を忘れやすい
- 複数のタスク間に分離がなく、互いに干渉する
- Tool呼び出しのロジックがますます複雑になり、保守が困難になる
Deep Agentsの核となる目標は、これらの複雑なタスクシナリオにおけるエンジニアリング上の問題を解決することです。
LangChain、LangGraphとの関係
多くの初心者はこの3つのプロジェクトの位置づけを混同しがちですが、実際には異なる抽象レイヤーにあります。
| フレームワーク | レイヤーの位置づけ | 主な役割 | 適用シナリオ |
|---|---|---|---|
| LangChain | 基本コンポーネントレイヤー | Model、Prompt、Tool、Retriever、Output ParserなどのAI基本コンポーネントを提供する | 単一のAgentまたはAIアプリケーションを構築するための基本能力 |
| LangGraph | ランタイムレイヤー | 状態管理、ワークフローオーケストレーション、ノードとエッジ、Checkpointの永続化機能を提供する | カスタムのグラフ構造と実行フローが必要な複雑なシナリオ |
| Deep Agents | アプリケーションフレームワークレイヤー | LangGraphの上に、計画、ファイルシステム、子Agent、メモリ、コンテキスト圧縮などの本番レベルの機能をカプセル化する | アーキテクチャをゼロから設計することなく、複雑な多段階Agentを迅速に構築できる |

3つは相互に代替するものではなく、連携して使用できます:LangChainはブロックを提供し、LangGraphはブロックを組織化するエンジニアリングフレームワーク、Deep Agentsはその上にあるすぐに使える高レベルアプリケーションレイヤーです。任意のLangGraph
CompiledStateGraphはsubagentとしてDeep Agentsに渡すことができ、3つのレイヤーを柔軟に混在させることができます。
コア機能一覧
Deep Agentsには以下のミドルウェアが内蔵されており、追加設定なしで使用できます:
| 機能 | 説明 | コアコンポーネント |
|---|---|---|
| タスク計画 | 内蔵ツールをwrite_todos使用して複雑なタスクを順序立てたステップに分解する | TodoListMiddleware |
| 仮想ファイルシステム | ファイルの読み書き、大きなツール出力をディスクにオフロードしてコンテキストウィンドウを節約する | FilesystemMiddleware |
| 子Agent | サブタスクを独立したコンテキストウィンドウを持つ専用の子Agentに委任する | SubAgentMiddleware |
| コンテキスト圧縮 | 履歴メッセージを自動的に要約し、モデルのコンテキスト制限を超えないようにする | SummarizationMiddleware |
| Human-in-the-loop | 重要なツール呼び出しの前に一時停止し、人間の承認を待つ | HumanInTheLoopMiddleware |
| 長期記憶 | セッションをまたいだ永続化メモリ。LangGraph Storeに基づく | MemoryMiddleware |
| Skills | 再利用可能なドメイン知識と指示セットをオンデマンドで読み込む | SkillsMiddleware |
インストール
Deep AgentsはPyPIで公開されており、パッケージ名はdeepagents。
推奨するのはuvを使用したインストールで、より高速です。従来のpip。
uvを使用したインストール(推奨)
uv init uv add deepagents tavily-python uv sync
pipを使用したインストール
pip install deepagents tavily-python
DeepSeek APIと組み合わせたインストール
DeepSeekはOpenAI APIと互換性があるため、同時にインストールする必要がありますlangchain-openai。
pip install deepagents langchain-openai
Deep Agentsがモデルに対して唯一要求することは、そのモデルがtool calling(ツール呼び出し)をサポートしていることです。DeepSeek V3とDeepSeek R1シリーズはすべてサポートしているため、安心して使用できます。
設定について
create_deep_agentはAgentを作成するためのコア関数であり、以下のパラメータ設定をサポートしています。
| パラメータ | 型 | 必須かどうか | 説明 | デフォルト値 |
|---|---|---|---|---|
model | strまたはモデルインスタンス | 否 | モデル文字列。形式はprovider:model-name、または初期化済みのモデルオブジェクトを直接渡す | anthropic:claude-sonnet-4-6 |
tools | リスト | 否 | カスタムツール関数またはLangChain Toolオブジェクトのリスト | None |
system_prompt | strまたはSystemMessage | 否 | Agentの役割と動作を定義するためのカスタムシステムプロンプト | None |
backend | BackendProtocol | 否 | 仮想ファイルシステムのバックエンド。ファイルの保存場所を決定する | StateBackend |
subagents | リスト | 否 | タスク委任に使用する子Agent定義のリスト | None |
memory | リスト | 否 | 起動時に読み込むAGENTS.mdファイルのパスリスト | None |
skills | リスト | 否 | オンデマンドで読み込むSkillsディレクトリのパスリスト | None |
permissions | リスト | 否 | ファイルシステムのパスレベルでのアクセス権限制御ルール | None |
interrupt_on | dict | 否 | どのツール呼び出しに人間の承認が必要かを指定します。checkpointer と併用する必要があります。 | None |
checkpointer | Checkpointer | 否 | 状態永続化チェックポイント。マルチターン対話や HITL 時には必ず設定します。 | None |
store | BaseStore | 否 | セッションをまたぐ長期保存用バックエンド | None |
response_format | ResponseFormat | 否 | 構造化出力のスキーマ定義 | None |
middleware | リスト | 否 | デフォルトのミドルウェアスタック末尾に追加するカスタムミドルウェア | () |
debug | bool | 否 | デバッグモードを有効にして、詳細なログを出力します。 | False |
ファイルシステムバックエンドの比較
Deep Agents は、Agent がファイルを読み書きする方法を制御するための複数のバックエンドを提供します。
| バックエンド | 保存場所 | セッションをまたぐ永続化 | 適用シーン |
|---|---|---|---|
| StateBackend | LangGraph グラフ状態内 | いいえ(同一スレッド内でのみ有効) | デフォルト。ローカル開発や単純なシーン向け |
| FilesystemBackend | ローカルディスク | である | ローカルファイルを実際に読み書きする必要がある場合に使用。慎重に扱う必要があります。 |
| StoreBackend | LangGraph Store | である | マルチターン対話の永続化、Thread をまたいだ共有 |
| LocalShellBackend | ローカルディスク + Shell | である | Shell コマンドを実行する必要がある場合に使用。信頼できる環境のみに限定 |
| CompositeBackend | 複数のバックエンドへのルーティング | サブバックエンドに依存 | ディレクトリごとの保存戦略を細かく制御 |
初心者はデフォルトのものをそのまま使用StateBackendしてください。FilesystemBackendとLocalShellBackendAgent がローカルファイルシステムを直接操作できるようになるため、権限を厳格に設定してから使用する必要があります。
クイックスタート
この節では、最小限のコードで動作する Deep Agent を作成する方法を説明します。
DeepSeek APIキーの設定
DeepSeek は OpenAI のインターフェース形式と互換性があり、API Key と Base URL の両方を設定する必要があります。
export OPENAI_API_KEY="sk-your-deepseek-api-key" export OPENAI_BASE_URL="https://api.deepseek.com" export TAVILY_API_KEY="your-tavily-api-key"
DeepSeek の API Key はplatform.deepseek.comで取得できます。環境変数
OPENAI_BASE_URLを DeepSeek のアドレスに設定すると、LangChain が自動的にリクエストを転送します。TAVILY_API_KEY は Tavily 公式サイトでhttps://www.tavily.com/ 取得します。生成される tvly-xxxxxxxx 形式のキーを使用します。
最もシンプルな例:Hello World Agent
カスタムツールを備えた Agent を作成し、DeepSeek に最初のメッセージを送信します。
例
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
# ChatOpenAI を使用し、base_url を DeepSeek に向けます。これが最も直接的な接続方法です。
model = ChatOpenAI(
model="deepseek-v4-flash", # 必須:モデル名
api_key=os.environ["OPENAI_API_KEY"], # 必須:DeepSeek API Key
base_url="https://api.deepseek.com", # 必須:DeepSeek の OpenAI 互換エンドポイント
)
# シンプルなカスタムツールを定義します。関数の docstring がツールの説明になります。
def get_weather(city: str) -> str:
"""指定された都市の天気を調べます。"""
# 実際のプロジェクトでは、ここで実際の天気 API を呼び出します。
return f"{city} は今日晴れ、気温 25°C、お出かけに最適です。"
# Agent を作成し、モデルインスタンスとツールリストを渡します。
agent = create_deep_agent(
model=model,
tools=[get_weather],
system_prompt="あなたは天気情報を調べられる、フレンドリーなアシスタントです。",
)
# Agent を呼び出します。messages は OpenAI スタイルのメッセージ形式を受け付けます。
result = agent.invoke({
"messages": [{"role": "user", "content": "今日の北京の天気はどうですか?"}]
})
# Agent の最終的な返信を出力します。
print(result["messages"][-1].content)
# 运行脚本 python hello_agent.py出力内容:
北京は今日**晴れ**、気温 **25°C**、お出かけに最適です。☀️
注意:Agent は完全なメッセージリストを返します(
messages)。最終的な返信はリストの末尾、つまりresult["messages"][-1].content。
詳細な使い方
この節では、いくつかの実際のシーンを通して、Deep Agents のコア機能を段階的に紹介します。
DeepSeek R1を使用した推論タスク
DeepSeek R1 は推論強化モデルで、複雑な分析が必要なタスクに適しています。
例
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
# DeepSeek R1:複雑な推論のために設計されたモデル
model = ChatOpenAI(
model="deepseek-v4-pro", # DeepSeek 思考モデル
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# 数学計算ツールの例
def calculate(expression: str) -> str:
"""数式を安全に評価し、計算結果を返します。"""
try:
# 注意:本番環境では、より安全な式評価ライブラリを使用してください。
result = eval(expression, {"__builtins__": {}}, {})
return f"計算結果: {expression} = {result}"
except Exception as e:
return f"計算エラー: {str(e)}"
agent = create_deep_agent(
model=model,
tools=[calculate],
system_prompt="あなたは数学分析の専門家で、複雑な問題を分解して段階的に解くのが得意です。",
)
result = agent.invoke({
"messages": [{"role": "user", "content": "1から100までのすべての奇数の合計を計算し、結果を検証してください。"}]
})
print(result["messages"][-1].content)
実行出力:
再换一种方法做交叉验证:
- 1 到 100 所有整数之和:\( \frac{100 \times 101}{2} = 5050 \)
- 1 到 100 的偶数之和:\( 2 + 4 + \cdots + 100 = 2 \times \frac{50 \times 51}{2} = 2550 \)
- 奇数之和:\( 5050 - 2550 = 2500 \)
两种方法结果一致。
---
**结论**:1 到 100 的所有奇数之和为 **2500**。
**推导回顾**:
- 奇数序列首项 1,末项 99,项数 \( \frac{99-1}{2}+1 = 50 \)
- 等差数列求和:\( S = \frac{n(a_1 + a_n)}{2} = \frac{50 \times (1+99)}{2} = 2500 \)
カスタムシステムプロンプト
によってsystem_promptパラメータで Agent の役割、タスク目標、行動規範を定義します。
例
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# カスタムシステムプロンプト:Agent のアイデンティティ、責務、行動基準を明確にします。
code_review_instructions = """あなたはシニア Python エンジニアで、コードレビューを専門としています。
あなたの責務:
- コードの可読性、パフォーマンス、セキュリティを確認する
- 潜在的なバグと改善提案を指摘する
- 具体的な修正例を提供する
返信形式:
1. 総合評価(1〜10)
2. 主な問題のリスト
3. 具体的な改善提案(修正後のコードスニペット付き)
"""
agent = create_deep_agent(
model=model,
system_prompt=code_review_instructions,
)
# レビュー対象のコードを提出します
code_to_review = """
def find_user(users, name):
for i in range(len(users)):
if users[i]['name'] == name:
return users[i]
return None
"""
result = agent.invoke({
"messages": [{"role": "user", "content": f"以下のコードをレビューしてください:\n```python{code_to_review}```"}]
})
print(result["messages"][-1].content)
ストリーミング出力
進捗をリアルタイムで表示する必要があるシーンでは、streamメソッドを使用して Agent の出力をチャンク単位で受け取れます。
例
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
agent = create_deep_agent(
model=model,
system_prompt="あなたはテクニカルライティングの専門家で、わかりやすい技術ドキュメントを書くのが得意です。",
)
# stream メソッドはジェネレータを返し、イベントチャンクを 1 つずつ yield します。
for chunk in agent.stream({
"messages": [{"role": "user", "content": "Python デコレータについての短い紹介文を書いてください。"}]
}):
# chunk は増分メッセージを含む辞書です。
if "messages" in chunk:
for msg in chunk["messages"]:
if hasattr(msg, "content") and msg.content:
print(msg.content, end="", flush=True)
print() # 最後の改行
マルチターン会話(チェックポイント付き)
と組み合わせてMemorySaverチェックポイントを使用すると、複数ターンにわたるステートフルな会話を実現できます。
例
import os
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver # メモリチェックポイント。再起動後はデータが失われます。
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# MemorySaver は会話状態をメモリ内に保存するため、プロセス終了後に失われます。
# 本番環境では SqliteSaver または PostgresSaver の使用を推奨します。
checkpointer = MemorySaver()
agent = create_deep_agent(
model=model,
system_prompt="あなたは親切で助けになるプログラミングアシスタントです。",
checkpointer=checkpointer, # 必須で渡す必要があります。渡さないとマルチターン対話でコンテキストを記憶できません。
)
# thread_id は対話スレッドの一意の識別子です。同じ thread_id は同じコンテキストを共有します。
config = {"configurable": {"thread_id": "サンプル-session-001"}}
# 1 ターン目
result1 = agent.invoke(
{"messages": [{"role": "user", "content": "私の名前は サンプル です。Python を勉強しています。"}]},
config=config,
)
print("1 ターン目の返信:", result1["messages"][-1].content)
# 2 ターン目:Agent は前のターンの情報を記憶できます。
result2 = agent.invoke(
{"messages": [{"role": "user", "content": "私の名前は何ですか?何を勉強していますか?"}]},
config=config,
)
print("2 ターン目の返信:", result2["messages"][-1].content)
1回目の返答:你好,サンプル!很高兴认识你,Python 是一门非常适合初学者的语言... 2回目の返答:你叫 サンプル,你正在学习 Python!...
thread_id の役割:同じ
thread_idの下のすべての呼び出しは同じ会話履歴を共有します。異なるthread_idの間は互いに分離されており、干渉しません。「会話の部屋番号」と理解できます。
総合デモ:調査レポートAgent
この節では、DeepSeek V3 をメインモデルとして使用し、カスタム検索ツールを統合した完全なリサーチレポート Agent を紹介し、サブ Agent の使用もデモします。
シナリオの説明
ユーザーのリサーチテーマを受け取り、タスクを自動的に分解し、検索ツールを呼び出して資料を収集し、最終的に構造化されたレポートを出力する Agent を構築します。
例
# デモ:DeepSeek API + Deep Agents を使用してリサーチレポート Agent を構築
# 依存関係のインストール:pip install deepagents langchain-openai requests
import os
import json
from tavily import TavilyClient
from typing import Literal
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
# ──────────────────────────────────────────
# 1. DeepSeek モデルの初期化
# ──────────────────────────────────────────
main_model = ChatOpenAI(
model="deepseek-v4-flash", # 総合能力が高く、企画や作成に適しています。
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
temperature=0.3, # 任意:ランダム性を下げて、レポートをより厳密にします。
)
# Tavily クライアントの初期化(検索ツール用)
tavily_client = TavilyClient(
api_key=os.environ["TAVILY_API_KEY"]
)
# ──────────────────────────────────────────
# 2. 検索ツール Tavily の定義
# ──────────────────────────────────────────
def web_search(
query: str,
max_results: int = 5,
) -> str:
"""Tavilyを使用してインターネット情報を検索する"""
try:
response = tavily_client.search(
query=query,
max_results=max_results,
search_depth="advanced",
include_answer=True,
include_raw_content=False,
)
lines = []
# AI回答の要約
if response.get("answer"):
lines.append(f"要約:{response['answer']}\n")
# 検索結果
for idx, item in enumerate(response.get("results", []), start=1):
lines.append(
f"""
[{idx}] {item.get('title', '')}
URL: {item.get('url', '')}
内容: {item.get('content', '')}
""".strip()
)
return "\n\n".join(lines)
def format_report(title: str, sections: str) -> str:
"""調査内容をMarkdown形式のレポートにまとめます。
Args:
title: レポートのタイトル
sections: 各章の内容をJSON文字列で表します。形式:{"章名": "内容"}
"""
try:
data = json.loads(sections)
lines = [f"# {title}\n"]
for section_name, content in data.items():
lines.append(f"## {section_name}\n")
lines.append(f"{content}\n")
return "\n".join(lines)
except Exception as e:
return f"フォーマットエラー:{str(e)}"
# ──────────────────────────────────────────
# 3. 専用サブAgentを定義する(情報統合エキスパート)
# サブAgentは独立したコンテキストウィンドウを持ち、メインAgentのコンテキスト膨張を防ぐ
# ──────────────────────────────────────────
report_writer_subagent = {
"name": "report-writer", # 必須:サブAgentの一意な名前
"description": "専門的なレポート作成アシスタント。調査資料を構造の明確なレポートに統合します。", # 必須:メインAgentはこの説明を使用してタスクを委任するタイミングを決定する
"system_prompt": "あなたはプロのレポート作成エキスパートです。調査資料を受け取ったら、要約、主要内容、結論の3部構成のレポートにまとめてください。簡潔で明瞭な言葉でお願いします。",
"tools": [format_report], # 任意:サブAgent専用ツール
# modelを指定しない場合は、メインAgentのモデルを継承する
}
# ──────────────────────────────────────────
# 4. Deep Agentを構成して作成する
# ──────────────────────────────────────────
checkpointer = MemorySaver()
research_instructions = """あなたはプロの調査アシスタントで、深い調査とレポート作成を得意としています。
ユーザーが調査テーマを提供した場合、あなたは次のことを行うべきです:
1. web_searchツールを使用して関連情報を検索する(少なくとも2〜3回、異なる角度から検索する)
2. 収集した資料を整理してまとめる
3. report-writerサブAgentに最終レポートの作成を委任する
4. 完全なレポートをユーザーに出力する
注意:毎回異なるキーワードを使用して検索し、より包括的な情報を取得してください。
"""
agent = create_deep_agent(
model=main_model,
tools=[web_search], # メインAgentが利用可能なツール
system_prompt=research_instructions,
subagents=[report_writer_subagent], # サブAgentを登録する
checkpointer=checkpointer,
)
# ──────────────────────────────────────────
# 5. Agentを実行する
# ──────────────────────────────────────────
print("調査中です。少々お待ちください...\n")
result = agent.invoke(
{
"messages": [{
"role": "user",
"content": "LangGraphとは何か、そしてその主な応用シナリオについて調べてください。"
}]
},
config={"configurable": {"thread_id": "サンプル-research-001"}}
)
print("=" * 60)
print("調査レポート")
print("=" * 60)
print(result["messages"][-1].content)
正在研究中,请稍候... ============================================================ 研究报告 ============================================================ # LangGraph 研究报告 ## 摘要 LangGraph 是 LangChain 团队推出的一个用于构建有状态、多角色 LLM 应用的框架... ## 主要内容 ### 核心概念 LangGraph 将 Agent 的执行流程建模为一张有向图... ### 主要应用场景 1. 多步骤推理任务 2. 人机协作(Human-in-the-loop)工作流 3. 多 Agent 协作系统 ... ## 结论 LangGraph 是构建生产级 Agent 应用的重要工具...
Human-in-the-loopの例
デリケートな操作(ファイルの削除やメール送信など)については、Agentが実行前に一時停止して人間の確認を待つように構成できます。
例
# Human-in-the-loop:危険な操作を実行する前にAgentに人間の承認を要求させる
import os
from langchain.tools import tool
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
# @toolデコレータを使用してツールを定義する(langchainパッケージが必要)
@tool
def delete_file(path: str) -> str:
"""指定されたパスのファイルを削除する。"""
# 実際のプロジェクトではここでos.remove(path)を呼び出す
return f"ファイル {path} は削除されました。"
@tool
def read_file(path: str) -> str:
"""指定されたパスのファイル内容を読み取る。"""
return f"ファイル {path} の内容:(サンプル内容)"
# interrupt_onはどのツールに人間の承認が必要かを構成する
# Trueは許可を意味する:承認、パラメータ編集、拒否、カスタム返信の送信
# Falseは承認が不要であることを意味する
# dictは許可される操作タイプを細かく制御できる
checkpointer = MemorySaver() # HITLはcheckpointerと組み合わせて使用する必要がある
agent = create_deep_agent(
model=model,
tools=[delete_file, read_file],
interrupt_on={
"delete_file": True, # 削除操作:完全な承認フローが必要
"read_file": False, # 読み取り操作:承認不要
},
checkpointer=checkpointer,
)
config = {"configurable": {"thread_id": "サンプル-hitl-001"}}
# 最初の呼び出し:Agentがdelete_fileを実行するときに一時停止する
print("Agentを起動中...")
result = agent.invoke(
{"messages": [{"role": "user", "content": "/tmp/test.txt ファイルを削除してください。"}]},
config=config,
)
# 承認待ちの割り込みがあるか確認する
for msg in result.get("messages", []):
print(f"Agentメッセージ: {msg.content if hasattr(msg, 'content') else msg}")
# 実行を再開する:承認決定を渡す
# "approve"はそのツールの実行を承認することを意味する
# "reject"は拒否を意味し、Agentはそのツールを実行しない
print("\nユーザー承認:削除操作を承認")
final_result = agent.invoke(
Command(resume={"decision": "approve"}),
config=config,
)
print("最終結果:", final_result["messages"][-1].content)
interrupt_onの仕組み:Agentがマークされたツールを呼び出そうとすると、LangGraphは割り込みを
interruptトリガーし、Agentの実行が一時停止します。あなたはCommand(resume=...)承認結果を渡すことで実行を再開できます。
よくある質問
以下は、Deep Agentsを使用する際によくある疑問と注意点です。
Deep Agentsを選ぶべきか、それともLangChain/LangGraphを直接使うべきか、どう判断すればよいですか?
| シナリオ | 推奨する選択肢 | 理由 |
|---|---|---|
| 計画、ファイル読み書き、サブAgent、コンテキスト圧縮が必要 | Deep Agents | これらの機能はすぐに使用でき、自分で組み立てる必要がない |
| 軽量なラッパーが必要で、ツール呼び出しループだけでよい | LangChain create_agent | Deep Agentsよりも軽量で、組み込みミドルウェアがない |
| カスタムグラフ構造が必要で、ループが標準のツール呼び出しループではない | LangGraph | グラフのノードとエッジのロジックを完全にカスタマイズ |
| LangGraph CompiledStateGraphをサブAgentとして使用 | 混在利用 | カスタムグラフをsubagentとしてDeep Agentsに渡すことができる |
DeepSeekモデルの選択に関するアドバイス
| モデル | model文字列 | 特徴 | 適用シナリオ |
|---|---|---|---|
| deepseek-v4-flash | deepseek-v4-flash | 総合性能が高く、高速、低価格 | 一般的なタスク、日常会話、文章作成 |
| deepseek-v4-pro | deepseek-v4-pro | 推論能力が高く、思考チェーン内蔵 | 数学、コード、複雑な論理推論 |
Agentがツールを呼び出した後に結果が返らない場合はどうすればよいですか?
ツール関数の戻り値は、文字列または文字列にシリアライズ可能な型である必要があります。
ツールが複雑なオブジェクト(辞書やリストなど)を返す場合は、次のものを使用してjson.dumps(result, ensure_ascii=False)変換してから返すことをお勧めします。
Agentが一度に特定のファイルのみにアクセスできるようにするには?
次のパラメータを使用してpermissionsファイルシステムのアクセス権限を構成すると、Agentが指定したパスのみを読み書きできるように正確に制御できます。
例
from deepagents.permissions import FilesystemPermission
from langchain_openai import ChatOpenAI
import os
model = ChatOpenAI(
model="deepseek-v4-flash",
api_key=os.environ["OPENAI_API_KEY"],
base_url="https://api.deepseek.com",
)
agent = create_deep_agent(
model=model,
permissions=[
FilesystemPermission(path="/workspace/", read=True, write=True), # 作業ディレクトリの読み書きを許可
FilesystemPermission(path="/secrets/", read=False, write=False), # 機密ディレクトリへのアクセスを禁止
],
)
Agentのデフォルトのシステムプロンプトと自分のプロンプトはどのように結合されますか?
Deep Agentsのプロンプトは、4つの部分が固定順序で連結されます:
USER(あなたのsystem_prompt)→BASE(SDKのデフォルトプロンプト)→SUFFIX(モデルベンダー固有の調整)
あなたのプロンプトは常に先頭にあり、上書きされません。SDKのデフォルトプロンプトはモデルに計画ツールとファイルツールの使用方法を伝えるため、ほとんどの場合自分で書き直す必要はありません。
初心者が犯しやすい間違い
よくある間違い1:渡し忘れる
checkpointer。Human-in-the-loop(interrupt_on)またはマルチターン対話を使用する場合、必ずcheckpointerを渡す必要があります。そうしないと状態が保存されず、Agentがエラーを報告します。
よくある間違い2:ツール関数にdocstringが書かれていない。Deep Agentsは関数のdocstringをツールの説明として使用し、モデルにいつこのツールを呼び出すかを伝えます。docstringがないツールは、モデルがいつ呼び出すべきかを認識できず、使用を拒否する可能性もあります。
よくある間違い3:ミドルウェア内で
selfの属性を直接変更する。AgentのサブAgentと並行操作が同時に実行される可能性があるため、ミドルウェアのインスタンス属性を直接変更すると競合状態(race condition)が発生する可能性があります。状態を保存する必要がある場合は、ミドルウェアのインスタンス変数ではなく、グラフのstateを介して渡す必要があります。
その他の資料
詳細については、以下のドキュメントを参照してください: