Saltar al contenido principal
Utilice este patrón cuando un solo modelo realizando toda la investigación en una única respuesta comience a alcanzar los límites de contexto. En lugar de permitir que una respuesta consuma directamente cada resultado de web_search, use una respuesta principal para delegar tareas de investigación enfocadas a respuestas hijas. Cada hijo realiza sus propias búsquedas y devuelve un memorando compacto. La respuesta principal solo consume esos memorandos, lo que permite que el flujo de trabajo general investigue de forma mucho más agresiva sin saturar el contexto del padre. Este es una versión especializada del patrón general de subagentes. Aquí el padre es un orquestador de investigación y los hijos son trabajadores de investigación. Flujo de investigación profunda -> la respuesta principal planifica la investigación -> el padre llama a spawn_subagent varias veces -> su aplicación ejecuta respuestas hijas con web_search -> los hijos devuelven memorandos de investigación compactos -> su aplicación envía todos los memorandos hijos de vuelta como function_call_output -> el padre retoma, decide si hacer otra ronda, luego responde

Por qué usar subagentes para investigación profunda

En un ciclo clásico de investigación profunda con un solo agente, una respuesta sigue llamando a web_search. Eso funciona hasta que la respuesta ha visto demasiados resultados de búsqueda y comienza a quedarse sin presupuesto de contexto útil. Los subagentes solucionan esto dividiendo el trabajo:
  • El padre mantiene el plan global y la síntesis final.
  • Cada hijo maneja una tarea de investigación enfocada y puede realizar varias búsquedas por sí mismo.
  • El padre solo ve el memorando del hijo, no cada resultado de búsqueda en bruto.
  • El padre puede delegar una segunda o tercera ronda si la primera es débil o contradictoria.

Diseñe el padre y el hijo de forma diferente

El padre no debe buscar directamente. Su trabajo es descomponer la solicitud, lanzar múltiples subagentes en paralelo y decidir si es necesaria otra ronda. Los hijos sí deben buscar directamente. Su trabajo es realizar la tarea enfocada, superar resultados iniciales débiles y devolver evidencia compacta para el padre. Una buena división se ve así:
  • Padre: planificación, descomposición de tareas, resolución de conflictos, respuesta final.
  • Hijo: refinamiento de consultas, búsqueda repetida, evaluación de fuentes, redacción de memorandos.

Defina la herramienta de delegación

Mantenga el esquema de la herramienta pequeño. Pase solo la tarea del hijo, instrucciones opcionales y una anulación de modelo opcional.
const spawnSubagentTool = {
  type: "function" as const,
  name: "spawn_subagent",
  description: "Delegue una tarea de investigación enfocada a una respuesta hija y devuelva un memorando compacto.",
  strict: true,
  parameters: {
    type: "object",
    properties: {
      task: { type: "string" },
      instructions: { type: "string" },
      model: { type: "string" },
    },
    required: ["task"],
    additionalProperties: false,
  },
};

type SpawnSubagentArgs = {
  task: string;
  instructions?: string;
  model?: string;
};

Dé al padre un prompt de orquestación

El prompt del padre debe forzar la descomposición y la amplitud. Para investigación profunda, indique al padre que use varios subagentes por defecto y que lance otra ronda cuando la primera sea débil.
const DEEP_RESEARCH_PARENT_INSTRUCTIONS = `
Eres un orquestador de investigación profunda.

No investigas directamente.
Utiliza la herramienta spawn_subagent para delegar tareas de investigación enfocadas a respuestas hijas.

Reglas de delegación:
- Para búsquedas fácticas directas, lanza al menos 3 subagentes antes de responder.
- Para la mayoría de las tareas de investigación, lanza al menos 4 subagentes antes de responder.
- Para investigaciones amplias, ambiguas o de alto impacto, lanza de 5 a 8 subagentes en rondas.
- Lanza múltiples subagentes en el mismo turno siempre que su trabajo pueda avanzar de forma independiente.
- Si la primera ronda es incompleta, repetitiva, débil o contradictoria, lanza otra ronda en lugar de adivinar.

Ejemplos de delegación:
- Un subagente para el camino de respuesta más directo.
- Un subagente enfocado en fuentes primarias u oficiales.
- Un subagente enfocado en corroboración o contradicciones.
- Subagentes adicionales para línea de tiempo, geografía, perspectiva de partes interesadas, detalle técnico o desarrollos recientes.

Después de que regresen todos los resultados de herramientas, sintetiza la evidencia en una sola respuesta para el usuario.
`;

Dé al hijo un prompt de investigación más estricto

El prompt del hijo debe restaurar la intensidad de búsqueda que la investigación profunda de un solo agente suele tener de forma natural. Sin esto, un hijo puede detenerse tras una búsqueda débil y devolver un memorando diciendo lo que haría a continuación.
const DEEP_RESEARCH_CHILD_INSTRUCTIONS = `
Eres un subagente especialista en investigación profunda.

Tienes la herramienta web_search y debes usarla de forma agresiva.
Concéntrate solo en la tarea delegada.

Disciplina de búsqueda:
- Para tareas no triviales, realiza al menos 3 búsquedas web distintas antes de devolver resultados.
- Si la primera búsqueda es débil, vacía, genérica o mayormente resultados de directorios, sigue buscando.
- No devuelvas "próximos pasos". Ejecuta esas búsquedas tú mismo antes de devolver resultados.
- Prefiere fuentes primarias, oficiales y de otra manera autorizadas.
- Trata los directorios y sitios de perfiles como pistas para corroborar, no como prueba única cuando debería existir una fuente más sólida.

Devuelve un memorando compacto para otro modelo:
1. Hallazgos clave
2. Evidencia y fuentes
3. Preguntas abiertas o advertencias
`;
Cada hijo es solo otra solicitud de Responses. Entréguele la tarea delegada como entrada y la herramienta web_search.
import { SDK } from "@meetkai/mka1";

const sdk = new SDK({
  bearerAuth: process.env.MKA1_API_KEY!,
});

async function runResearchChild(args: SpawnSubagentArgs) {
  const child = await sdk.llm.responses.create({
    model: args.model ?? "gpt-5",
    instructions: args.instructions ?? DEEP_RESEARCH_CHILD_INSTRUCTIONS,
    input: args.task,
    tools: [
      {
        type: "web_search",
        userLocation: { country: "pakistan" },
        searchContextSize: "medium",
      },
    ],
    tool_choice: "auto",
    parallel_tool_calls: true,
    max_tool_calls: 60,
    store: true,
  });

  return {
    response_id: child.id,
    output_text: child.outputText,
  };
}

Continúe hijos débiles en lugar de aceptarlos

Para investigación profunda, no acepte un resultado hijo solo porque el hijo devolvió texto. Si el hijo solo buscó una vez, produjo un memorando corto o dijo cosas como “próximos pasos” o “necesito buscar más”, continúe ese mismo hijo con previous_response_id.
const MIN_CHILD_SEARCHES = 3;
const MAX_CHILD_PASSES = 3;
const WEAK_MEMO_PATTERNS = [
  /next steps/i,
  /let me try/i,
  /need to search/i,
  /should check/i,
  /didn't find/i,
  /no direct results/i,
];

function isWeakMemo(outputText: string) {
  const trimmed = outputText.trim();
  if (!trimmed) return true;
  if (trimmed.length < 250) return true;
  return WEAK_MEMO_PATTERNS.some((pattern) => pattern.test(trimmed));
}

function buildChildContinuationPrompt(args: {
  task: string;
  searchCount: number;
  previousOutput: string;
}) {
  return [
    `Continúa la tarea de investigación delegada: ${args.task}`,
    `Solo has completado ${args.searchCount} búsquedas web hasta ahora.`,
    `Realiza al menos ${MIN_CHILD_SEARCHES} búsquedas web distintas antes de devolver resultados a menos que ya tengas una respuesta directa de evidencia autorizada.`,
    `No devuelvas "próximos pasos" ni digas que se necesita buscar más. Ejecuta las búsquedas adicionales tú mismo.`,
    `Prioriza fuentes primarias, oficiales y de otra manera autorizadas. Usa directorios solo como pistas para corroborar.`,
    ``,
    `Memorando anterior:`,
    args.previousOutput,
  ].join("\n");
}

async function runResearchChildWithContinuation(args: SpawnSubagentArgs) {
  let previous_response_id: string | undefined;
  let nextInput = args.task;
  let totalSearchCount = 0;

  for (let pass = 0; pass < MAX_CHILD_PASSES; pass += 1) {
    const child = await sdk.llm.responses.create({
      model: args.model ?? "gpt-5",
      instructions: args.instructions ?? DEEP_RESEARCH_CHILD_INSTRUCTIONS,
      ...(previous_response_id
        ? { previous_response_id, input: nextInput }
        : { input: nextInput }),
      tools: [
        {
          type: "web_search",
          userLocation: { country: "pakistan" },
          searchContextSize: "medium",
        },
      ],
      tool_choice: "auto",
      parallel_tool_calls: true,
      max_tool_calls: 60,
      store: true,
    });

    const passSearchCount = countCompletedWebSearches(child.output);
    totalSearchCount += passSearchCount;

    if (totalSearchCount >= MIN_CHILD_SEARCHES && !isWeakMemo(child.outputText)) {
      return {
        response_id: child.id,
        output_text: child.outputText,
        search_count: totalSearchCount,
      };
    }

    previous_response_id = child.id;
    nextInput = buildChildContinuationPrompt({
      task: args.task,
      searchCount: totalSearchCount,
      previousOutput: child.outputText,
    });
  }

  throw new Error("La respuesta hija siguió siendo demasiado débil después de varios ciclos de investigación");
}
El helper exacto countCompletedWebSearches depende de si está utilizando eventos transmitidos o elementos de salida almacenados. La idea importante es contar operaciones de búsqueda realmente completadas, no solo turnos.

Ejecute una ronda del padre y luego reúna todos los memorandos hijos

Se debe permitir que el padre emita varias llamadas a spawn_subagent en un turno. Trate esas llamadas de herramienta como un lote. Inicie cada hijo, espere a que todos terminen y luego retome el padre una vez con todas las salidas de los hijos.
export async function runDeepResearch(input: string) {
  let response = await sdk.llm.responses.create({
    model: "gpt-5",
    instructions: DEEP_RESEARCH_PARENT_INSTRUCTIONS,
    input,
    tools: [spawnSubagentTool],
    tool_choice: "auto",
    parallel_tool_calls: true,
    max_tool_calls: 18,
    store: true,
  });

  while (true) {
    const toolCalls = response.output.filter(
      (item): item is {
        type: "function_call";
        name: string;
        call_id: string;
        arguments: string;
      } => item.type === "function_call" && item.name === "spawn_subagent",
    );

    if (toolCalls.length === 0) {
      return response.outputText;
    }

    const toolOutputs = await Promise.all(
      toolCalls.map(async (toolCall) => {
        const args = JSON.parse(toolCall.arguments) as SpawnSubagentArgs;
        const childResult = await runResearchChildWithContinuation(args);

        return {
          type: "function_call_output" as const,
          call_id: toolCall.call_id,
          output: JSON.stringify(childResult),
        };
      }),
    );

    response = await sdk.llm.responses.create({
      model: response.model,
      previous_response_id: response.id,
      input: toolOutputs,
      tools: [spawnSubagentTool],
      parallel_tool_calls: true,
      max_tool_calls: 18,
      store: true,
    });
  }
}
Este es el ciclo central de investigación profunda:
  1. El padre crea un plan de investigación.
  2. El padre emite un lote de llamadas a spawn_subagent.
  3. Su aplicación ejecuta todos los hijos en paralelo.
  4. Los hijos débiles continúan en otro ciclo.
  5. Su aplicación envía todos los memorandos hijos finales juntos.
  6. El padre lanza otra ronda o responde.

Transmita y registre el proceso de investigación

La investigación profunda es mucho más fácil de depurar si registra el ciclo de vida de búsqueda de los hijos. Registros útiles incluyen:
  • respuesta principal creada
  • cada tarea delegada
  • cada consulta de búsqueda de hijo
  • cada lote de resultados de búsqueda de hijo
  • cada vista previa de memorando de hijo
  • cuando un hijo débil continúa en otro ciclo
  • reanudación del padre con el lote final de hijos
Esto le permite distinguir fallos de orquestación de fallos de calidad de investigación. Por ejemplo, si el sistema responde mal pero los registros muestran solo un hijo con una búsqueda, eso es un problema de prompt o de continuación, no de transporte.

Reglas prácticas para investigación profunda

  • Use parallel_tool_calls: true en el padre para que pueda lanzar varios subagentes en un turno.
  • Mantenga las salidas de los hijos compactas. El padre debe recibir resúmenes de evidencia, no volcados de investigación en bruto.
  • Prefiera varias tareas hijas enfocadas en lugar de una tarea hija vaga.
  • Si un hijo encuentra principalmente directorios o páginas genéricas, siga empujando a ese hijo en lugar de aceptar el primer memorando.
  • No reanude el padre antes de tiempo con solo parte de un lote de hijos.
  • Mantenga store: true activado mientras desarrolla para poder inspeccionar las respuestas de padres e hijos después.
  • Si actúa en nombre de un usuario final, envíe el mismo valor de X-On-Behalf-Of en las solicitudes de padre e hijo.

Errores comunes

  • Muy pocos subagentes: el padre sintetiza antes de que la investigación tenga verdadera amplitud.
  • Hijos débiles: un hijo devuelve resultados tras una búsqueda débil con “próximos pasos” en lugar de hacer más trabajo.
  • Memorandos de hijos demasiado grandes: el padre gana poco porque el hijo pasa demasiado contexto en bruto.
  • Reunión temprana: reanudar el padre antes de que cada hijo de un lote haya terminado hace que el flujo de trabajo sea menos predecible.
  • Deriva en la calidad de las fuentes: los hijos pueden abusar de directorios, sitios de perfiles y agregadores a menos que el prompt les indique priorizar fuentes primarias.

Véase también

Revise spawn subagents using the Responses API para el patrón general de delegación padre/hijo. Revise generate a response para la forma básica de la solicitud de Responses.