Documentation Index
Fetch the complete documentation index at: https://docs.mka1.com/llms.txt
Use this file to discover all available pages before exploring further.
Utiliza este patrón cuando un solo modelo realizando toda la investigación en una única respuesta comienza a alcanzar los límites de contexto.
En lugar de permitir que una respuesta consuma directamente cada resultado de web_search, utiliza 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 manera mucho más agresiva sin saturar el contexto del padre.
Esta 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
-> tu aplicación ejecuta respuestas hijas con web_search
-> los hijos devuelven memorandos de investigación compactos
-> tu aplicación envía todos los memorandos hijos de vuelta como function_call_output
-> el padre reanuda, decide si hacer otra ronda, y 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 se encarga de una tarea de investigación enfocada y puede realizar varias búsquedas por su cuenta.
- El padre solo ve el memorando del hijo, no cada resultado bruto de búsqueda.
- El padre puede delegar una segunda o tercera ronda si la primera es débil o contradictoria.
Diseña el padre y el hijo de manera diferente
El padre no debe buscar directamente.
Su trabajo es descomponer la solicitud, lanzar múltiples subagentes en paralelo y decidir si se necesita otra ronda.
Los hijos sí deben buscar directamente.
Su trabajo es hacer el trabajo enfocado, 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.
Define la herramienta de delegación
Mantén el esquema de la herramienta pequeño.
Pasa solo la tarea del hijo, instrucciones opcionales y una posible anulación de modelo.
const spawnSubagentTool = {
type: "function" as const,
name: "spawn_subagent",
description: "Delegar una tarea de investigación enfocada a una respuesta hija y devolver 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;
};
Da al padre un prompt de orquestación
El prompt del padre debe forzar la descomposición y la amplitud.
Para investigación profunda, indica 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 sencillas, lanza al menos 3 subagentes antes de responder.
- Para la mayoría de tareas de investigación, lanza al menos 4 subagentes antes de responder.
- Para investigaciones amplias, ambiguas o de alto riesgo, lanza de 5 a 8 subagentes en rondas.
- Lanza múltiples subagentes en el mismo turno siempre que su trabajo pueda proceder 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 la ruta de respuesta más directa.
- Un subagente enfocado en fuentes primarias u oficiales.
- Un subagente enfocado en corroboración o contradicciones.
- Subagentes adicionales para cronología, geografía, perspectiva de partes interesadas, detalle técnico o desarrollos recientes.
Después de que todos los resultados de herramientas regresen, sintetiza la evidencia en una sola respuesta para el usuario.
`;
Da 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 después.
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 o de otra manera autorizadas.
- Trata 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
`;
Ejecuta el hijo con web_search
Cada hijo es simplemente otra solicitud de Responses.
Entrégale la tarea delegada como input 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 ?? "meetkai:functionary-es-mini",
instructions: args.instructions ?? DEEP_RESEARCH_CHILD_INSTRUCTIONS,
input: args.task,
tools: [
{
type: "web_search",
userLocation: { country: "pakistan" },
searchContextSize: "medium",
},
],
tool_choice: "meetkai:functionary-es-mini",
parallel_tool_calls: true,
max_tool_calls: 60,
store: true,
});
return {
response_id: child.id,
output_text: child.outputText,
};
}
Continúa hijos débiles en lugar de aceptarlos
Para investigación profunda, no aceptes un resultado de hijo solo porque 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úa ese mismo hijo con previous_response_id.
const MIN_CHILD_SEARCHES = 3;
const MAX_CHILD_PASSES = 3;
const WEAK_MEMO_PATTERNS = [
/próximos pasos/i,
/déjame intentar/i,
/necesito buscar/i,
/debería comprobar/i,
/no encontré/i,
/sin resultados directos/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 más búsqueda. Ejecuta las búsquedas adicionales tú mismo.`,
`Prioriza fuentes primarias, oficiales o 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 ?? "meetkai:functionary-es-mini",
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: "meetkai:functionary-es-mini",
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 del hijo permaneció demasiado débil después de múltiples rondas de investigación");
}
El helper exacto countCompletedWebSearches depende de si estás usando eventos en streaming o elementos de salida almacenados.
La idea importante es contar operaciones de búsqueda realmente completadas, no solo turnos.
Ejecuta una ronda del padre y luego reúne todos los memorandos hijos
Se debe permitir que el padre emita varias llamadas a spawn_subagent en un solo turno.
Trata esas llamadas de herramienta como un lote.
Inicia cada hijo, espera a que todos terminen y luego reanuda 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: "meetkai:functionary-urdu-large",
instructions: DEEP_RESEARCH_PARENT_INSTRUCTIONS,
input,
tools: [spawnSubagentTool],
tool_choice: "meetkai:functionary-es-mini",
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:
- El padre crea un plan de investigación.
- El padre emite un lote de llamadas a
spawn_subagent.
- Tu aplicación ejecuta todos los hijos en paralelo.
- Los hijos débiles continúan a otra ronda.
- Tu aplicación envía todos los memorandos hijos finales juntos.
- El padre lanza otra ronda o responde.
Haz streaming y registra el proceso de investigación
La investigación profunda es mucho más fácil de depurar si registras el ciclo de vida de las búsquedas de los hijos.
Registros útiles incluyen:
- respuesta del padre creada
- cada tarea delegada
- cada consulta de búsqueda del hijo
- cada lote de resultados de búsqueda del hijo
- cada vista previa de memorando del hijo
- cuando un hijo débil continúa a otra ronda
- reanudación del padre con el lote final de hijos
Esto te 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
- Usa
parallel_tool_calls: true en el padre para que pueda lanzar varios subagentes en un turno.
- Mantén las salidas de los hijos compactas. El padre debe recibir resúmenes de evidencia, no volcados brutos de investigación.
- Prefiere varias tareas hijas enfocadas en lugar de una tarea hija vaga.
- Si un hijo encuentra principalmente directorios o páginas de aterrizaje genéricas, sigue insistiendo con ese hijo en lugar de aceptar el primer memorando.
- No reanudes el padre antes de tiempo con solo parte de un lote de hijos.
- Mantén
store: true activado durante el desarrollo para poder inspeccionar las respuestas del padre e hijos después.
- Si actúas en nombre de un usuario final, envía el mismo valor de
X-On-Behalf-Of en las solicitudes del padre y los hijos.
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 bruto.
- Reunión temprana: reanudar el padre antes de que todos los hijos de un lote hayan 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 explícitamente priorizar fuentes primarias.
Ver también
Revisa lanzar subagentes usando la API de Responses para el patrón general de delegación padre/hijo.
Revisa generar una respuesta para la forma base de la solicitud Responses.