Todos los productos
Search
Centro de documentos

Alibaba Cloud Model Studio:Investigación profunda (Qwen-Deep-Research)

Última actualización: Oct 12, 2026

Automatiza investigaciones complejas mediante planificación, múltiples rondas de búsquedas web y generación estructurada de informes. Recopila y sintetiza información sin esfuerzo manual.

NotaEste documento se aplica únicamente a la región de China continental (Beijing). Para utilizar el modelo, debe emplear una clave de API de la región de China continental (Beijing).

Introducción

Obtenga una clave API y exporte la clave API como variable de entorno. Si utiliza un SDK para realizar las llamadas, instale el SDK de DashScope.

El modelo utiliza un flujo de trabajo de dos pasos: un paso de pregunta de seguimiento (el modelo aclara el alcance de su investigación) y un paso de investigación profunda (el modelo busca, analiza y genera un informe). La pregunta de seguimiento permite al modelo comprender exactamente qué investigar antes de iniciar una ejecución de investigación prolongada.

Actualmente, el modelo no es compatible con el SDK de DashScope para Java ni con llamadas a la API compatible con OpenAI.

import os
import dashscope

# The following is the base_url for the Beijing region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

# Configure the API key
# If not set, replace the following line with your Model Studio API key (format: 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,
            # The qwen-deep-research model currently only supports streaming output
            stream=True
            # incremental_output=True Add this parameter for incremental output
        )

        return process_responses(responses, step_name)

    except Exception as e:
        print(f"An error occurred when calling the API: {e}")
        return ""

# Display phase content
def display_phase_content(phase, content, status):
    if content:
        print(f"\n[{phase}] {status}: {content}")
    else:
        print(f"\n[{phase}] {status}")

# Process the response
def process_responses(responses, step_name):
    current_phase = None
    phase_content = ""
    research_goal = ""
    web_sites = []
    references = []
    keepalive_shown = False  # Flag to check if the KeepAlive prompt has been shown

    for response in responses:
        # Check the response status code
        if hasattr(response, 'status_code') and response.status_code != 200:
            print(f"HTTP return code: {response.status_code}")
            if hasattr(response, 'code'):
                print(f"Error code: {response.code}")
            if hasattr(response, 'message'):
                print(f"Error message: {response.message}")
            print("For more information, see: 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', {})

            # Phase change detection
            if phase != current_phase:
                if current_phase and phase_content:
                    # Display different completion descriptions based on phase and step names
                    if step_name == "Step 1: Model query confirmation" and current_phase == "answer":
                        print(f"\n Query confirmation phase completed")
                    else:
                        print(f"\n {current_phase} phase completed")
                current_phase = phase
                phase_content = ""
                keepalive_shown = False  # Reset KeepAlive prompt flag

                # Display different descriptions based on phase and step names
                if step_name == "Step 1: Model query confirmation" and phase == "answer":
                    print(f"\n Entering query confirmation phase")
                else:
                    print(f"\n Entering {phase} phase")

            # Process reference information in the Answer phase
            if phase == "answer":
                if extra.get('deep_research', {}).get('references'):
                    new_references = extra['deep_research']['references']
                    if new_references and new_references != references:  # Avoid duplicate display
                        references = new_references
                        print(f"\n   References ({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"        Description: {ref['description'][:100]}...")
                            print()

            # Process special information in the WebResearch phase
            # Note: The qwen-deep-research-2025-12-15 model uses the streamingThinking status
            # instead of streamingQueries and streamingWebResult
            if phase == "WebResearch":
                if extra.get('deep_research', {}).get('research'):
                    research_info = extra['deep_research']['research']

                    # Process streamingThinking (snapshot model) or streamingQueries (mainline model) status
                    if status in ("streamingThinking", "streamingQueries"):
                        if 'researchGoal' in research_info:
                            goal = research_info['researchGoal']
                            if goal:
                                research_goal += goal
                                print(f"\n   Research goal: {goal}", end='', flush=True)

                    # Process streamingWebResult status (mainline model)
                    # The snapshot model merges this status using streamingThinking
                    elif status == "streamingWebResult":
                        if 'webSites' in research_info:
                            sites = research_info['webSites']
                            if sites and sites != web_sites:  # Avoid duplicate display
                                web_sites = sites
                                print(f"\n   Found {len(sites)} relevant websites:")
                                for i, site in enumerate(sites, 1):
                                    print(f"     {i}. {site.get('title', 'No title')}")
                                    print(f"        Description: {site.get('description', 'No description')[:100]}...")
                                    print(f"        URL: {site.get('url', 'No link')}")
                                    if site.get('favicon'):
                                        print(f"        Icon: {site['favicon']}")
                                    print()

                    # Process WebResultFinished status
                    elif status == "WebResultFinished":
                        print(f"\n   Web search completed. Found {len(web_sites)} reference sources.")
                        if research_goal:
                            print(f"   Research goal: {research_goal}")

            # Accumulate and display content
            if content:
                phase_content += content
                # Display content in real-time
                print(content, end='', flush=True)

            # Display phase status changes
            if status and status != "typing":
                print(f"\n   Status: {status}")

                # Display status description
                if status == "streamingThinking":
                    print("   → Decomposing research tasks and summarizing web content (WebResearch phase)")
                elif status == "streamingQueries":
                    print("   → Generating research goals and search queries (WebResearch phase)")
                elif status == "streamingWebResult":
                    print("   → Performing searches, web page reading, and code execution (WebResearch phase)")
                elif status == "WebResultFinished":
                    print("   → Web search phase completed (WebResearch phase)")

            # When status is finished, display token consumption
            if status == "finished":
                if hasattr(response, 'usage') and response.usage:
                    usage = response.usage
                    print(f"\n    Token consumption statistics:")
                    print(f"      Input tokens: {usage.get('input_tokens', 0)}")
                    print(f"      Output tokens: {usage.get('output_tokens', 0)}")
                    print(f"      Request ID: {response.get('request_id', 'Unknown')}")

            if phase == "KeepAlive":
                # Only display the prompt the first time entering the KeepAlive phase
                if not keepalive_shown:
                    print("Current step completed. Preparing for the next step.")
                    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 Query confirmation phase completed")
        else:
            print(f"\n {current_phase} phase completed")

    return phase_content

def main():
    # Check API key
    if not API_KEY:
        print("Error: DASHSCOPE_API_KEY environment variable not set")
        print("Set the environment variable or modify the API_KEY variable directly in the code")
        return

    print("User initiates conversation: Research the application of artificial intelligence in education")

    # Step 1: Model query confirmation
    # The model analyzes the user's question and asks clarifying questions to define the research direction
    messages = [{'role': 'user', 'content': 'Research the application of artificial intelligence in education'}]
    step1_content = call_deep_research_model(messages, "Step 1: Model query confirmation")

    # Step 2: Deep research
    # Based on the query confirmation from Step 1, the model performs the full research process
    messages = [
        {'role': 'user', 'content': 'Research the application of artificial intelligence in education'},
        {'role': 'assistant', 'content': step1_content},  # Includes the model's query confirmation content
        {'role': 'user', 'content': 'I mainly focus on personalized learning and intelligent assessment'}
    ]

    call_deep_research_model(messages, "Step 2: Deep research")
    print("\n Research completed!")

if __name__ == "__main__":
    main()
echo "Step 1: Model query confirmation"
# The following is the base_url for the Beijing region.
curl --location 'https://{WorkspaceId}.cn-beijing.maas.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"
# The following is the base_url for the Beijing region.
curl --location 'https://{WorkspaceId}.cn-beijing.maas.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"
}'

Especificaciones

Modelo

Ventana de contexto (tokens)

Entrada máxima (tokens)

Salida máxima (tokens)

qwen-deep-research

1,000,000

997,952

32,768

qwen-deep-research-2025-12-15

Notaqwen-deep-research: modelo principal, actualizado continuamente. qwen-deep-research-2025-12-15: versión instantánea con mayor profundidad, calidad y llamada a herramientas MCP. Ambos admiten entrada de imágenes y se facturan por separado.

Capacidades principales

Rastree el progreso mediante phase (tarea actual) y status (progreso de la tarea).

Generación de preguntas de seguimiento e informe (fase: "answer")

Analiza su consulta, formula preguntas aclaratorias para definir el alcance y genera el informe final de investigación.

Valores de estado:

  • typing: Generando contenido de texto
  • finished: Generación de contenido de texto completada
Planificación de la investigación (fase: "ResearchPlanning")

Crea un esquema de investigación a partir de su consulta.

Valores de estado:

  • typing: Generando el plan de investigación
  • finished: Plan de investigación completado
Búsqueda web (fase: "WebResearch")

Realiza múltiples rondas de búsquedas web y análisis de contenido. WebResultFinished señala el final de cada ronda. finished señala el final de la fase.

Valores de estado:

  • streamingThinking: Descomposición de tareas de investigación y resumen de contenido web (específico de qwen-deep-research-2025-12-15, reemplaza a streamingQueries y streamingWebResult)
  • streamingQueries: Generando consultas de búsqueda (solo para qwen-deep-research)
  • streamingWebResult: Realizando búsquedas web y analizando contenido web (solo para qwen-deep-research)
  • WebResultFinished: Ronda de búsqueda completada
  • finished: Fase de búsqueda web completada
Keepalive de conexión (fase: "KeepAlive")

Mantiene la conexión entre tareas de larga duración. Ignore esta fase y continúe con el procesamiento.

Entrada de imagen

Ambos modelos admiten entrada de imágenes. El modelo analiza la imagen e incorpora ese contenido a su investigación. Utilice el formato de matriz para el campo content, pasando juntos los objetos image y text.

  • Formatos admitidos: JPEG, PNG, BMP, WEBP. Máximo de 10 MB por imagen.
  • Hasta 5 imágenes por solicitud. Admite URL públicas y codificación Base64.
  • El formato de respuesta es idéntico al de las solicitudes de solo texto. El modelo genera un informe basado en el contenido de la imagen.
Ejemplo de solicitud
import os
import dashscope

# The following is the base_url for the Beijing region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

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://{WorkspaceId}.cn-beijing.maas.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"
}'

Llamada a herramientas MCP

NotaLa llamada a herramientas MCP solo es compatible con qwen-deep-research-2025-12-15. qwen-deep-research no admite esta función.

La llamada a herramientas del Protocolo de Contexto de Modelo (MCP) permite que qwen-deep-research-2025-12-15 extraiga datos de fuentes privadas o específicas de dominio durante la fase WebResearch, como una base de conocimientos, documentos internos o una base de datos propietaria, además de las búsquedas web estándar. Pase la configuración del servidor MCP a través del parámetro research_tools. El formato de respuesta es idéntico al de las llamadas estándar.

Para obtener detalles sobre research_tools y las especificaciones de herramientas MCP, consulte Qwen-Deep-Research .

Ejemplo de solicitud

import os
import dashscope

# The following is the base_url for the Beijing region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

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://{WorkspaceId}.cn-beijing.maas.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"
            }
        }]
    }
}'

Facturación

Modelo

Costo de entrada (por 1K tokens)

Costo de salida (por 1K tokens)

Cuota gratuita

qwen-deep-research

$0.007742

$0.023367

Sin cuota gratuita

qwen-deep-research-2025-12-15

Por determinar

Por determinar

Sin cuota gratuita

La facturación se basa en los tokens de entrada (mensajes del usuario e instrucciones del sistema) y los tokens de salida (preguntas de seguimiento, planes de investigación, objetivos, consultas de búsqueda y el informe final). Los dos modelos se facturan por separado.

Puesta en marcha

Uso de salida por streaming

El modelo solo admite salida por streaming (stream=True). Una sola tarea de investigación puede ejecutarse durante varios minutos a lo largo de docenas de ciclos iterativos de búsqueda y lectura, lo cual excede el tiempo de espera de una solicitud síncrona. Utilice el streaming para mantener la conexión abierta y rastrear el progreso mediante los campos phase y status.

Gestión de errores

Verifique el código de estado de la respuesta en cada fragmento. Para códigos de estado distintos de 200, lea los campos code y message y manéjelos adecuadamente.

Supervisión del uso de tokens

Cuando status es finished, recupere el uso de tokens desde response.usage (tokens de entrada, tokens de salida e ID de solicitud).

Gestión del keepalive de conexión

La fase KeepAlive mantiene la conexión entre tareas de larga duración. Ignore esta fase y continúe procesando el flujo.

FAQ

  • ¿Por qué el campo de salida está vacío en algunos fragmentos de respuesta?

    Los primeros fragmentos contienen únicamente metadatos. El contenido llega en fragmentos posteriores a medida que el modelo lo genera.

  • ¿Cómo determino si una fase está completa?

    Una fase se completa cuando status cambia a finished.

  • ¿El modelo admite llamadas a la API compatible con OpenAI?

    No. No se admiten llamadas a la API compatible con OpenAI.

  • ¿Cómo se calculan los tokens de entrada y salida?

    Tokens de entrada: mensajes del usuario e instrucciones del sistema. Tokens de salida: preguntas de seguimiento, planes de investigación, objetivos, consultas de búsqueda y el informe final.

  • ¿Cuál es la diferencia entre qwen-deep-research y qwen-deep-research-2025-12-15?

    qwen-deep-research: modelo principal, actualizado continuamente. qwen-deep-research-2025-12-15: versión instantánea con mayor profundidad, calidad y soporte para MCP. Ambos admiten entrada de imágenes y se facturan por separado.

  • ¿Cómo paso imágenes para la investigación?

    Utilice el formato de matriz para content: pase {"image": "URL"} y {"text": "description"} como objetos en la matriz. Ambos modelos admiten entrada de imágenes.

  • ¿Cómo omito la pregunta de seguimiento y paso directamente a la investigación?

    Establezca enable_feedback en false dentro de parameters. El modelo omite la pregunta de seguimiento e inicia la investigación inmediatamente.

Referencia de API

Para consultar los parámetros de entrada y salida, véase Qwen-Deep-Research.

Códigos de error

Si la llamada al modelo falla y devuelve un mensaje de error, consulte Códigos de error para su resolución.

Limitación de tasa

Consulte Límites de tasa.