すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:Deep Research (Qwen-Deep-Research)

最終更新日:Mar 11, 2026

複雑な研究テーマの場合、従来の人の手による検索は時間と労力がかかります。大規模言語モデル (LLM) と Web 検索を組み合わせた場合、詳細かつ体系的な分析が困難なことがよくあります。Deep Research モデル (Qwen-Deep-Research) は、調査ステップを自動的に計画し、複数回の詳細な検索と情報統合を実行し、最終的に構造化された調査レポートを生成します。

説明

このドキュメントは、中国本土 (北京) リージョンにのみ適用されます。モデルを使用するには、中国本土 (北京) リージョンの API キー を使用してください。

クイックスタート

API キーを取得し、API キーを環境変数としてエクスポートします。SDK を使用して呼び出しを行う場合は、DashScope SDK をインストールします。

このモデルは、クエリ確認 (調査範囲を明確にするため) と詳細調査 (検索を実行し、レポートを生成するため) の 2 段階のワークフローを使用します。以下の例は、両方のステップを含む完全な呼び出しフローを示しています。

現在、このモデルは DashScope SDK を介してのみ呼び出すことができます。DashScope SDK の Java 版はサポートされておらず、OpenAI 互換 API 呼び出しもサポートされていません。
import os
import dashscope

# API キーを設定します
# 環境変数が設定されていない場合は、次の行を Model Studio API キーに置き換えてください: API_KEY = "sk-xxx"
API_KEY = os.getenv('DASHSCOPE_API_KEY')

def call_deep_research_model(messages, step_name):
    print(f"\n=== {step_name} ===")
    
    try:
        responses = dashscope.Generation.call(
            api_key=API_KEY,
            model="qwen-deep-research",
            messages=messages,
            # qwen-deep-research モデルは現在、ストリーミング出力のみをサポートしています
            stream=True
            # incremental_output=True 増分出力を有効にするには、このパラメーターを追加します
        )
        
        return process_responses(responses, step_name)
        
    except Exception as e:
        print(f"API の呼び出し中にエラーが発生しました: {e}")
        return ""


# フェーズの内容を表示します
def display_phase_content(phase, content, status):
    if content:
        print(f"\n[{phase}] {status}: {content}")
    else:
        print(f"\n[{phase}] {status}")

# 応答を処理します
def process_responses(responses, step_name):
    current_phase = None
    phase_content = ""
    research_goal = ""
    web_sites = []
    references = []
    keepalive_shown = False  # KeepAlive プロンプトが表示されたかどうかを確認するフラグ

    for response in responses:
        # 応答のステータスコードを確認します
        if hasattr(response, 'status_code') and response.status_code != 200:
            print(f"HTTP リターンコード: {response.status_code}")
            if hasattr(response, 'code'):
                print(f"エラーコード: {response.code}")
            if hasattr(response, 'message'):
                print(f"エラーメッセージ: {response.message}")
            print("詳細については、以下をご参照ください: https://www.alibabacloud.com/help/zh/model-studio/error-code")
            continue

        if hasattr(response, 'output') and response.output:
            message = response.output.get('message', {})
            phase = message.get('phase')
            content = message.get('content', '')
            status = message.get('status')
            extra = message.get('extra', {})

            # フェーズの変更を検出します
            if phase != current_phase:
                if current_phase and phase_content:
                    # フェーズとステップ名に基づいて異なる完了説明を表示します
                    if step_name == "Step 1: Model query confirmation" and current_phase == "answer":
                        print(f"\n クエリ確認フェーズが完了しました")
                    else:
                        print(f"\n {current_phase} フェーズが完了しました")
                current_phase = phase
                phase_content = ""
                keepalive_shown = False  # KeepAlive プロンプトフラグをリセットします

                # フェーズとステップ名に基づいて異なる説明を表示します
                if step_name == "Step 1: Model query confirmation" and phase == "answer":
                    print(f"\n クエリ確認フェーズに入ります")
                else:
                    print(f"\n {phase} フェーズに入ります")
                    
            # Answer フェーズでリファレンス情報を処理します
            if phase == "answer":
                if extra.get('deep_research', {}).get('references'):
                    new_references = extra['deep_research']['references']
                    if new_references and new_references != references:  # 重複表示を回避します
                        references = new_references
                        print(f"\n   リファレンス ({len(references)}):")
                        for i, ref in enumerate(references, 1):
                            print(f"     {i}. {ref.get('title', 'タイトルなし')}")
                            if ref.get('url'):
                                print(f"        URL: {ref['url']}")
                            if ref.get('description'):
                                print(f"        説明: {ref['description'][:100]}...")
                            print()

            # WebResearch フェーズで特別な情報を処理します
            # 注: qwen-deep-research-2025-12-15 モデルでは、streamingThinking ステータスが使用され、
            # streamingQueries および streamingWebResult の代わりに使用されます
            if phase == "WebResearch":
                if extra.get('deep_research', {}).get('research'):
                    research_info = extra['deep_research']['research']

                    # streamingThinking (スナップショットモデル) または streamingQueries (メインラインモデル) ステータスを処理します
                    if status in ("streamingThinking", "streamingQueries"):
                        if 'researchGoal' in research_info:
                            goal = research_info['researchGoal']
                            if goal:
                                research_goal += goal
                                print(f"\n   研究目標: {goal}", end='', flush=True)

                    # streamingWebResult ステータス (メインラインモデル) を処理します
                    # スナップショットモデルでは、このステータスは streamingThinking を使用して統合されます
                    elif status == "streamingWebResult":
                        if 'webSites' in research_info:
                            sites = research_info['webSites']
                            if sites and sites != web_sites:  # 重複表示を回避します
                                web_sites = sites
                                print(f"\n   関連するウェブサイト {len(sites)} 件が見つかりました:")
                                for i, site in enumerate(sites, 1):
                                    print(f"     {i}. {site.get('title', 'タイトルなし')}")
                                    print(f"        説明: {site.get('description', '説明なし')[:100]}...")
                                    print(f"        URL: {site.get('url', 'リンクなし')}")
                                    if site.get('favicon'):
                                        print(f"        ファビコン: {site['favicon']}")
                                    print()

                    # WebResultFinished ステータスを処理します
                    elif status == "WebResultFinished":
                        print(f"\n   ウェブ検索が完了しました。{len(web_sites)} 件のリファレンスソースが見つかりました。")
                        if research_goal:
                            print(f"   研究目標: {research_goal}")

            # コンテンツを蓄積して表示します
            if content:
                phase_content += content
                # コンテンツをリアルタイムで表示します
                print(content, end='', flush=True)

            # フェーズのステータス変更を表示します
            if status and status != "typing":
                print(f"\n   ステータス: {status}")

                # ステータスの説明を表示します
                if status == "streamingThinking":
                    print("   → 研究タスクの分解およびウェブコンテンツの要約 (WebResearch フェーズ)")
                elif status == "streamingQueries":
                    print("   → 研究目標および検索クエリの生成 (WebResearch フェーズ)")
                elif status == "streamingWebResult":
                    print("   → 検索の実行、ウェブページの読み取り、およびコード実行 (WebResearch フェーズ)")
                elif status == "WebResultFinished":
                    print("   → ウェブ検索フェーズの完了 (WebResearch フェーズ)")

            # ステータスが finished の場合、トークン使用量を表示します
            if status == "finished":
                if hasattr(response, 'usage') and response.usage:
                    usage = response.usage
                    print(f"\n    トークン使用量の統計:")
                    print(f"      入力トークン: {usage.get('input_tokens', 0)}")
                    print(f"      出力トークン: {usage.get('output_tokens', 0)}")
                    print(f"      リクエスト ID: {response.get('request_id', '不明')}")

            if phase == "KeepAlive":
                # KeepAlive フェーズに初めて入ったときのみプロンプトを表示します
                if not keepalive_shown:
                    print("現在のステップが完了しました。次のステップの準備をしています。")
                    keepalive_shown = True
                continue

    if current_phase and phase_content:
        if step_name == "Step 1: Model query confirmation" and current_phase == "answer":
            print(f"\n クエリ確認フェーズが完了しました")
        else:
            print(f"\n {current_phase} フェーズが完了しました")

    return phase_content

def main():
    # API キーを確認します
    if not API_KEY:
        print("エラー: DASHSCOPE_API_KEY 環境変数が設定されていません")
        print("環境変数を設定するか、コード内の API_KEY 変数を直接修正してください")
        return
    
    print("ユーザーが会話を開始しました: 人工知能の教育への応用を調査する")
    
    # ステップ 1: モデルクエリの確認
    # モデルはユーザーの質問を分析し、調査方向を定義するために明確化の質問を行います
    messages = [{'role': 'user', 'content': '人工知能の教育への応用を調査する'}]
    step1_content = call_deep_research_model(messages, "Step 1: Model query confirmation")

    # ステップ 2: 深層調査
    # ステップ 1 のクエリ確認に基づき、モデルは完全な調査プロセスを実行します
    messages = [
        {'role': 'user', 'content': '人工知能の教育への応用を調査する'},
        {'role': 'assistant', 'content': step1_content},  # モデルのクエリ確認コンテンツを含みます
        {'role': 'user', 'content': '主にパーソナライズされた学習とインテリジェントな評価に焦点を当てます'}
    ]
    
    call_deep_research_model(messages, "Step 2: Deep research")
    print("\n 調査が完了しました!")

if __name__ == "__main__":
    main()
echo "Step 1: Model query confirmation"
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \
--header 'X-DashScope-SSE: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "input": {
        "messages": [
            {
                "content": "Research the application of artificial intelligence in education", 
                "role": "user"
            }
        ]
    },
    "model": "qwen-deep-research"
}'

echo -e "\n\n" 
echo "Step 2: Deep research"
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \
--header 'X-DashScope-SSE: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "input": {
        "messages": [
            {
                "content": "Research the application of artificial intelligence in education", 
                "role": "user"
            },
            {
                "content": "Tell me which specific application scenarios of artificial intelligence in education you want to focus on?", 
                "role": "assistant"
            },
            {
                "content": "I mainly focus on personalized learning", 
                "role": "user"
            }
        ]
    },
    "model": "qwen-deep-research"
}'

モデル一覧

Model Name

コンテキスト長 (トークン)

最大入力 (トークン)

最大出力 (トークン)

qwen-deep-research

1,000,000

997,952

32,768

qwen-deep-research-2025-12-15

説明

qwen-deep-research は継続的に更新・最適化されるメインラインモデルです。qwen-deep-research-2025-12-15 は、より優れた調査の深さとレポート品質を提供するスナップショット版であり、MCP ツール呼び出し機能もサポートしています。どちらのモデルも画像入力をサポートしています。どちらも別途課金されます。

コア機能

モデルは phase フィールドと status フィールドを使用してワークフローを表示します。phase は現在実行中のコアタスクを示し、status はそのタスクの内部進行状況を示します。

クエリ確認とレポート生成 (phase: "answer")

モデルはユーザーの初期質問を分析し、調査範囲を明確にするために明確化のための質問をします。このフェーズは、最終レポートの生成中にも使用されます。

状態の変更:

  • typing: テキストコンテンツの生成中

  • finished: テキストコンテンツの生成が完了

調査計画 (phase: "ResearchPlanning")

ユーザー要件に基づいて調査概要を作成できます。

状態の変更:

  • typing: 調査計画の生成中

  • finished: 調査計画が完了

Web 検索 (phase: "WebResearch")

モデルは複数回の検索と情報処理を実行します。WebResultFinished 状態は各検索ラウンドの終了時に返されます。finished 状態はフェーズ全体が完了した後に返されます。

状態の変更:

  • streamingThinking: 調査タスクの分解と Web コンテンツの要約 (qwen-deep-research-2025-12-15 モデルに固有、streamingQueries および streamingWebResult を置き換えます)

  • streamingQueries: 検索クエリの生成 (qwen-deep-research モデルのみ)

  • streamingWebResult: Web 検索の実行と Web コンテンツの分析 (qwen-deep-research モデルのみ)

  • WebResultFinished: 単一の検索ラウンドが完了

  • finished: Web 検索フェーズが完了

永続接続 (phase: "KeepAlive")

このフェーズは、接続を維持するために長時間のタスク間隔中に送信されます。このフェーズにはビジネスコンテンツは含まれておらず、無視できます。

画像入力

Deep Research モデルは、ユーザーメッセージで画像を渡すことをサポートしています。モデルは画像コンテンツを理解し、画像に基づいて詳細な調査と分析を実行します。画像を渡す場合、content フィールドは、image オブジェクトと text オブジェクトを含む配列形式を使用する必要があります。

  • モデルは、JPEG、PNG、BMP、WEBP などの一般的な画像形式をサポートしています。単一の画像は 10 MB を超えてはなりません。

  • 単一のリクエストには最大 5 つの画像を含めることができます。パブリックネットワーク URL と Base64 エンコーディングの両方がサポートされています。

  • 応答形式はプレーンテキストリクエストと一貫しています。モデルは画像コンテンツに基づいて調査し、レポートを返します。

リクエスト例

import os
import dashscope

API_KEY = os.getenv('DASHSCOPE_API_KEY')

messages = [
    {
        "role": "user",
        "content": [
            {"image": "https://example.aliyuncs.com/example.png"},
            {"text": "Analyze the data trends in this chart and conduct in-depth research on key findings"}
        ]
    }
]

responses = dashscope.Generation.call(
    api_key=API_KEY,
    model="qwen-deep-research",
    messages=messages,
    stream=True
)

for response in responses:
    if hasattr(response, 'output') and response.output:
        message = response.output.get('message', {})
        content = message.get('content', '')
        if content:
            print(content, end='', flush=True)
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \
--header 'X-DashScope-SSE: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "input": {
        "messages": [
            {
                "content": [
                    {"image": "https://example.aliyuncs.com/example.png"},
                    {"text": "Analyze the data trends in this chart and conduct in-depth research on key findings"}
                ],
                "role": "user"
            }
        ]
    },
    "model": "qwen-deep-research"
}'

MCP ツール呼び出し

説明

MCP ツール呼び出しは、qwen-deep-research-2025-12-15 モデルのみでサポートされています。メインラインモデル qwen-deep-research はこの機能をサポートしていません。

qwen-deep-research-2025-12-15 モデルは、research_tools パラメーターを介して MCP (Model Context Protocol) サービスへのアクセスをサポートしており、モデルが調査中に情報取得のために外部ツールを呼び出すことを可能にします。応答形式は標準的な呼び出しと一貫しています。モデルは WebResearch フェーズ中に MCP Server を介して指定されたツールを呼び出します。

research_tools および MCP ツール仕様の詳細については、「Qwen-Deep-Research Deep Research Model」をご参照ください。

リクエスト例

import os
import dashscope

API_KEY = os.getenv('DASHSCOPE_API_KEY')

messages = [
    {
        "role": "user",
        "content": "Use the knowledge base to search for recently published product update announcements and compile them into a research report"
    }
]

responses = dashscope.Generation.call(
    api_key=API_KEY,
    model="qwen-deep-research-2025-12-15",
    messages=messages,
    stream=True,
    enable_feedback=False,
    research_tools=[{
        "type": "mcp",
        "server_label": "my-server",
        "server_url": "https://your-mcp-server.example.com/sse",
        "allowed_tools": ["search", "fetch"],
        "authentication": {
            "bearer": "your_jwt_token_here"
        }
    }]
)

for response in responses:
    if hasattr(response, 'output') and response.output:
        message = response.output.get('message', {})
        content = message.get('content', '')
        if content:
            print(content, end='', flush=True)
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' \
--header 'X-DashScope-SSE: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "input": {
        "messages": [
            {
                "content": "Use the knowledge base to search for recently published product update announcements and compile them into a research report",
                "role": "user"
            }
        ]
    },
    "model": "qwen-deep-research-2025-12-15",
    "parameters": {
        "enable_feedback": false,
        "research_tools": [{
            "type": "mcp",
            "server_label": "my-server",
            "server_url": "https://your-mcp-server.example.com/sse",
            "allowed_tools": ["search", "fetch"],
            "authentication": {
                "bearer": "your_jwt_token_here"
            }
        }]
    }
}'

課金

Model Name

入力コスト (1,000 トークンあたり)

出力コスト (1,000 トークンあたり)

無料クォータ

qwen-deep-research

$0.007742

$0.023367

無料クォータなし

qwen-deep-research-2025-12-15

未定

未定

無料クォータなし

課金方法: 課金は、入力および出力トークンの合計数に基づいています。入力トークンには、ユーザーメッセージの内容と、モデルに組み込まれたシステムプロンプトが含まれます。出力トークンには、クエリ確認、調査計画、調査目標、検索クエリ、最終調査レポートなど、調査プロセス全体でモデルによって生成されたすべてのコンテンツが含まれます。

本番環境への適用

ストリーミング出力処理

モデルはストリーミング出力 (stream=True) のみをサポートしています。応答を処理する際は、phase フィールドと status フィールドを正しく解析して、現在のフェーズと完了状態を判断してください。

エラー処理

応答状態コードを確認してください。200 以外の状態の場合はエラーを処理します。ストリーミング応答の初期段階では、一部の応答ブロックにはメタデータのみが含まれる場合があります。後続のブロックには実際のコンテンツが含まれます。

トークン消費量の監視

statusfinished の場合、response.usage を介して入力トークン、出力トークン、リクエスト ID などのトークン消費統計を取得します。

接続管理

モデルは、接続を維持するために長時間のタスク間隔中に KeepAlive フェーズ応答を送信する場合があります。このフェーズの内容は無視し、後続の応答の処理を続行してください。

よくある質問

  • 一部の応答ブロックの output が空なのはなぜですか?

    ストリーミング応答の初期段階では、一部の応答ブロックにはメタデータのみが含まれる場合があります。後続のブロックには実際のコンテンツが含まれます。

  • フェーズが完了したかどうかを判断するにはどうすればよいですか?

    status フィールドが "finished" になると、現在のフェーズは完了です。

  • モデルは OpenAI 互換 API 呼び出しをサポートしていますか?

    現在、モデルは OpenAI 互換 API 呼び出しをサポートしていません。

  • モデルの入力および出力トークン数はどのように計算されますか?

    入力トークンには、ユーザーの質問、ユーザーの回答、システムプロンプトなど、ユーザーメッセージの内容とモデルに組み込まれたシステムプロンプトが含まれます。出力トークンには、クエリ確認コンテンツ、調査計画、調査目標、検索クエリ、最終調査レポートなど、調査プロセス全体でモデルによって生成されたすべてのコンテンツが含まれます。

  • qwen-deep-research と qwen-deep-research-2025-12-15 の違いは何ですか?

    qwen-deep-research は継続的に更新されるメインラインモデルです。qwen-deep-research-2025-12-15 は、より優れたパフォーマンスと MCP ツール呼び出し機能の追加サポートを備えたスナップショット版です。どちらのモデルも画像入力をサポートしています。どちらも別途課金され、スナップショット版はメインライン版よりもわずかに高価です。

  • 調査のために画像を渡すにはどうすればよいですか?

    content フィールドを、{"image": "Image URL"}{"text": "Text description"} を含む配列形式に設定します。どちらのモデルも画像入力をサポートしています。

  • クエリ確認をスキップして、モデルに直接調査に進ませるにはどうすればよいですか?

    parametersenable_feedbackfalse に設定すると、クエリ確認フェーズをスキップできます。その後、モデルは直接調査プロセスに進みます。

API リファレンス

Qwen-Deep-Research モデルの入力および出力パラメーターの詳細については、「Qwen-Deep-Research Deep Research Model」をご参照ください。

エラーコード

モデル呼び出しが失敗し、エラーメッセージが返された場合は、解決策として「エラーメッセージ」をご参照ください。

レート制限

モデルのレート制限トリガー条件の詳細については、「レート制限」をご参照ください。