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

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

最終更新日:Jan 27, 2026

Qwen-Deep-Research は、調査ステップの計画、複数回のウェブ検索の実行、構造化された調査レポートの生成により、複雑な調査タスクを自動化します。手動での作業なしに、複雑なトピックに関する情報を収集し、統合することができます。

説明

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

クイックスタート

前提条件

このモデルは、2 段階のワークフローを使用します:

  • フォローアップの質問:モデルは最初のクエリを分析し、調査範囲を定義するための明確化の質問をします。

  • 詳細調査:ユーザーの応答に基づき、モデルはウェブ検索を実行し、コンテンツを分析し、構造化された調査レポートを生成します。

現在、このモデルは Java 用の DashScope SDK および 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/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 follow-up question for 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 follow-up question for 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', 'No title')}")
                            if ref.get('url'):
                                print(f"        URL: {ref['url']}")
                            if ref.get('description'):
                                print(f"        説明: {ref['description'][:100]}...")
                            print()

            # WebResearch フェーズの特別情報を処理
            if phase == "WebResearch":
                if extra.get('deep_research', {}).get('research'):
                    research_info = extra['deep_research']['research']

                    # streamingQueries ステータスを処理
                    if status == "streamingQueries":
                        if 'researchGoal' in research_info:
                            goal = research_info['researchGoal']
                            if goal:
                                research_goal += goal
                                print(f"\n   調査目標: {goal}", end='', flush=True)

                    # streamingWebResult ステータスを処理
                    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', 'No title')}")
                                    print(f"        説明: {site.get('description', 'No description')[:100]}...")
                                    print(f"        URL: {site.get('url', 'No link')}")
                                    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 == "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', 'Unknown')}")

            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 follow-up question for 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 follow-up question for 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 follow-up question for 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 applications 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 applications of artificial intelligence in education", 
                "role": "user"
            },
            {
                "content": "Which specific application scenarios of artificial intelligence in education would you like to focus on?", 
                "role": "assistant"
            },
            {
                "content": "I am mainly interested in personalized learning.", 
                "role": "user"
            }
        ]
    },
    "model": "qwen-deep-research"
}'

コア機能

モデルは phasestatus フィールドを使用して進捗を示します。

フェーズ

フェーズ

フェーズの説明

ステータス

ステータスの説明

answer

フォローアップの質問または最終レポートを生成します

typing

テキストを生成しています

finished

テキスト生成が完了しました

ResearchPlanning

調査の概要を作成します

typing

調査計画を生成しています

finished

調査計画が完了しました

WebResearch

ウェブ検索とコンテンツ分析

streamingQueries

検索クエリを生成しています

streamingWebResult

ウェブ検索を実行し、ページコンテンツを分析しています

WebResultFinished

ウェブ検索と情報抽出が完了しました

KeepAlive

長時間実行されるタスク間で接続を維持するために送信されます。このフェーズは無視してください

仕様

モデル

コンテキストウィンドウ (トークン)

最大入力 (トークン)

最大出力 (トークン)

qwen-deep-research

1,000,000

997,952

32,768

課金

モデル

入力価格 (1,000 トークンあたり)

出力価格 (1,000 トークンあたり)

無料クォータ

qwen-deep-research

$0.007742

$0.023367

無料クォータなし

ルール:課金は、入力トークンと出力トークンの合計に基づきます。入力トークンには、ユーザーメッセージとモデルに組み込まれたシステムプロンプトが含まれます。出力トークンには、フォローアップの質問、調査計画、調査目標、検索クエリ、最終レポートなど、生成されたすべてのコンテンツが含まれます。

本番環境への適用

ストリーミング出力の処理

モデルはストリーミング出力 (stream=True) のみをサポートします。phasestatus フィールドを解析して進捗を追跡してください。

エラーの処理

応答ステータスコードが 200 以外でないか確認してください。

トークン使用量の監視

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

よくある質問

  • 一部の応答チャンクで output フィールドが空なのはなぜですか?

    初期のストリーミングチャンクにはメタデータのみが含まれている場合があります。後続のチャンクに実際のコンテンツが含まれます。

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

    status フィールドが "finished" に変わると、フェーズは完了です。

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

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

  • 入力トークンと出力トークンはどのように計算されますか?

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

API リファレンス

Qwen-Deep-Research API リファレンス

エラーコード

呼び出しが失敗した場合は、「エラーメッセージ」をご参照のうえ、トラブルシューティングを行ってください。