Legwork

Habilidad de investigación de decisiones para Claude Code y Codex. Cada afirmación indica qué tan bien está respaldada y cuándo la evidencia no puede resolverla. Una herramienta gratuita de DBHQ.

¿Qué es Legwork?

Legwork es una habilidad de investigación de decisiones diseñada para asistentes de IA como Claude Code y Codex. A diferencia de la investigación académica, Legwork se enfoca en preguntas prácticas como "¿qué deberíamos hacer sobre X?", y su resultado se juzga por su utilidad, no por su exhaustividad. La habilidad opera en tres niveles de profundidad (rápido, estándar y profundo) que aumentan el rigor sin alargar el texto. El proceso consta de cuatro fases: Enmarcar la decisión, Recopilar evidencia, Desafiar los hallazgos y Escribir el informe final. Legwork incluye un índice de investigaciones previas para evitar repeticiones, un registro detallado de recuperación de fuentes, y un sistema de verificación que asegura que cada afirmación esté respaldada correctamente. Solo se detiene ante errores críticos o consultas incomprensibles.

Compatible con✓Claude Code✓Codex CLI~Cursor
npx skills add dbhq-uk/legwork-skill

Installed? Explore more Investigación y análisis de datos skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace Legwork?

Para qué sirve

Investigación de decisiones. No investigación académica. La pregunta siempre es alguna versión de "¿qué deberíamos hacer sobre X?", y el resultado se juzga por su utilidad, no por su exhaustividad.

Eso da forma a todo lo siguiente. Una afirmación se juzga por si su fuente es el tipo adecuado de cosa para esa afirmación, no por si su dominio es respetable. Tres fuentes que coinciden solo cuentan si podrían haber discrepado. Y una ejecución que no puede responder la pregunta lo dice en lugar de producir una extensión llena de matices.

Principio de autonomía. Infiera lo que necesite del contexto, elija un nivel y comience. Anuncie el nivel en una línea y proceda; no le pida al usuario que elija. Pueden redirigir a media ejecución, lo que cuesta mucho menos que una pregunta bloqueante en cada solicitud. Deténgase solo ante un error crítico o una consulta incomprensible.

Niveles

La profundidad aumenta el rigor. Nunca aumenta la extensión.

rápidoestándarprofundo
EnmarcarDecisión más 2-3 subpreguntasMás falsadores nombradosMás ángulos de segundo orden
RecopilarFragmentos de SERP; recuperar solo para fijar una cifraRecuperación directa de las fuentes principales por hallazgoUna fuente primaria para cada hallazgo
DesafiarSolo agrupación por independenciaUna búsqueda de confirmación negativa por hallazgoPasada de confirmación negativa por hallazgo más una auditoría de origen
Formatobrevebreve o informeinforme
Nivel de puerta--level quick--level standard--level deep
Tiempo aproximado3-5 min8-12 min20-40 min

El valor predeterminado es estándar. Use el nivel que el usuario nombre (quick, standard, deep, o un equivalente como "escaneo rápido" o "ir a fondo"), si no $LEGWORK_DEFAULT_MODE, si no estándar. "Investigación profunda" por sí solo es una frase de invocación para esta habilidad, no una solicitud del nivel profundo - continúe hasta el valor predeterminado.

Escale silenciosamente un nivel si el alcance revela que la pregunta es materialmente de mayor importancia de lo que implicaba la solicitud, y dígalo en la misma línea de apertura.

Línea de apertura, luego directamente a la Fase 1:

Ejecutando estándar (~8-12 min). Diga "profundo" para fuentes primarias y una pasada de confirmación negativa.

Canalización

Cuatro fases. Instrucciones completas en methodology.md.

  1. Enmarcar - nombre la decisión, las subpreguntas que la resolverían y qué evidencia cambiaría la respuesta.
  2. Recopilar - recupere para cada subpregunta, registrando cada recuperación.
  3. Desafiar - busque el caso de confirmación negativa; agrupe las fuentes por independencia.
  4. Escribir - ensamble el resultado, luego aplique la puerta.

Las fases 2 y 3 se intercalan por hallazgo en lugar de ejecutarse como puertas estrictas.

Antes de comenzar

Fije la fecha. Ejecute date -u +%Y-%m-%d y use esa cadena para la ejecución, en el nombre de la carpeta de salida, y en cada consulta de búsqueda que pueda devolver material fechado. Nunca confíe en su propio sentido del año actual, y nunca deje que un subagente lo resuelva por sí mismo.

Verifique si esta ejecución ya se ha realizado. Lea el índice primero. Es un despachador: una fila por ejecución pasada, y la columna de resumen existe para que pueda decidir si abrir un informe sin pagar por abrirlo.

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py list --base "$OUTPUT_BASE"

Luego elija uno de cuatro caminos, y diga cuál en su línea de apertura:

El índice diceHaga esto
Una ejecución cubre esto y no está desactualizadaResponda a partir de ella. Lea ese informe, no la web.
Una ejecución cubre esto pero está marcada como desactualizadaActualícela
Una ejecución es cercana pero responde una pregunta diferenteNueva ejecución, y haga referencia cruzada
No coincide nadaNueva ejecución

Responder a partir de una ejecución anterior es un éxito, no un atajo. Abra el informe, lea los hallazgos que se relacionan con la pregunta, y responda con sus bandas de confianza intactas. Diga claramente que proviene de una ejecución de una fecha determinada. Volver a ejecutar una investigación que ya se realizó y aún se mantiene es el desperdicio que este índice existe para prevenir.

Actualizar en lugar de volver a ejecutar

Una actualización actualiza el informe existente en el mismo lugar - misma carpeta, mismo archivo. No cree una segunda carpeta: dos carpetas que describen una pregunta es cómo un lector termina actuando según la que le tocó abrir.

  1. Reanude el registro de recuperación en lugar de comenzar uno nuevo. Todo lo que contiene ya está pagado.

    python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py resume --tsv "$OUT/$BASE.tsv"
    

    Eso imprime los ángulos ya trabajados, las páginas ya recuperadas y cuáles de ellas aún no tienen una cita. Trabaje los ángulos descubiertos y vuelva a verificar las afirmaciones que deciden la respuesta; no vuelva a recuperar lo que ya está registrado y actual.

  2. Mueva cada afirmación que ahora sea incorrecta a ## Reemplazado con la fecha y el motivo. Nunca elimine una afirmación en silencio. Alguien puede haber actuado sobre ella, y una ejecución futura necesita saber que este terreno ya se ha cubierto. Si la misma respuesta ha sido ahora anulada dos veces, dígalo en voz alta: esa es la señal más fuerte en el documento de que la pregunta es inestable.

  3. Agregue una línea ## Línea de tiempo que indique qué cambió.

  4. Actualice la fila del índice.

Archivar la ejecución

Cada ejecución termina en el índice, incluida una que no pudo responder - "miramos y no encontramos nada" es exactamente lo que una sesión futura necesita para no volver a mirar.

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py add --base "$OUTPUT_BASE" \
  --folder "$BASE" --topic "Triage de Outlook para pequeñas consultas" --level deep \
  --one-liner "No hay triage nativo por debajo de E5; la brecha es real pero estrecha"

El resumen dice lo que la ejecución concluyó, no de qué se trataba. "Notas sobre la galería de complementos" es inútil dentro de seis meses; "No existe ruta de envío, la instalación es mediante URL o no es posible" responde la pregunta por sí sola. La puerta advierte cuando una ejecución falta en un índice que existe.

Política de recuperación

Dos escaleras, primeros peldaños gratuitos. Suba solo hasta donde necesite.

Para buscar:

PeldañoLlamadaCuándo
1WebSearchSiempre. Tres variantes de consulta por ángulo.
2platforms.py search --on ...La respuesta es un registro que una plataforma posee: un hilo, un paquete, un repositorio, un elemento de noticias fechado, el registro de cambios de un proveedor. Gratuito, sin clave, y devuelve el registro en lugar de una página sobre él.
3bd_search.py -m general --engine bing --country XX --language yyEscaso después de tres variantes, o la pregunta es geo-específica. Un segundo motor es la razón para pagar.
4bd_search.py -m discover --intent "..."Dos motores aún escasos.

Para abrir una página:

PeldañoLlamadaCuándo
1fetch.py "<url>" --find "término"Siempre primero. Gratuito, y el único transporte gratuito que produce texto de página, por lo que las cifras se pueden rastrear y las citas se pueden verificar.
2WebFetchfetch.py salió con código 3 y la página no vale la pena pagar por ella.
3bd_search.py "<url>" -m scrapeBloqueada: protección contra bots, muro de pago, 403.
4bd_search.py "<url>" -m renderUn shell renderizado por el cliente.
5bd_search.py "<url>" -m pipeline --pipeline NOMBREUna plataforma que bloquea todo lo anterior. Se factura por registro; -m reddit es donde es la única ruta, no un último recurso.

Ejecute platforms.py list para las diez plataformas gratuitas, y bd_search.py --help para los modos de pago. En caso de código de salida 2 (autenticación o cuota), dígale al usuario que ejecute brightdata login. No lo reintente.

Un resultado de búsqueda es una pista, no una página que se lee. En estándar y profundo, abra lo que cita: la puerta trata una cita que se basa solo en filas de websearch como no abierta, una advertencia en estándar y un error en profundo. Rápido está diseñado para ser solo fragmentos y no se le pide.

Registre el fallo antes de la alternativa. Una página que no se abre es evidencia sobre la ejecución - --status blocked - y el recibo lo cuenta.

Limite lo que recupera. --max-chars 8000 en llamadas de scrape, y prefiera --find a un límite ciego: en una página larga, los primeros ocho mil caracteres suelen ser la navegación.

Qué fuentes puede usar

La investigación es lo que un externo podría establecer. Ese límite importa en ambas direcciones.

Nunca presente los propios registros del usuario como un hallazgo. Si la pregunta trata sobre la propia empresa, producto o posición de mercado del usuario, no acceda a sus cuentas privadas - su registrador, su facturación, su bandeja de entrada, sus archivos internos - e informe lo que encontró allí como si hubiera sido descubierto. Ellos ya lo saben. Es circular, infla la evidencia aparente y disfraza cuán poco puede ver realmente un externo. Busque el equivalente público e informe lo que un externo encontraría, incluido nada.

Sí use el acceso exclusivo que el usuario le ha dado, sobre terceros. Una suscripción pagada, un conjunto de datos privado o una base de datos interna que el usuario ha ofrecido explícitamente es una ventaja genuina al investigar competidores, proveedores o un mercado. Úselo, regístrelo como una fuente como cualquier otra, y anote en Limitaciones que el hallazgo se basa en un acceso que el lector puede no tener.

Cuando una entidad resulta no tener ningún rastro público en absoluto, esa es la respuesta. Enumere lo que verificó, diga que la existencia o escala no se pudo verificar desde fuera, y no llene el vacío con acceso privilegiado. Es la forma de "no pudo responder" aplicada a una entidad en lugar de a toda la pregunta.

El registro de recuperación

Cada recuperación, en cada nivel, agrega una fila:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log \
  --tsv "$OUT/$BASE.tsv" \
  --url "https://acme.example/precios" \
  --kind precios_proveedor \
  --angle "¿cuánto cobra el actual titular?" \
  --via webfetch \
  --date 2026-07-01 \
  --title "Precios" \
  --quote "Plan Team: 30 dólares estadounidenses por usuario por mes, facturado anualmente." \
  --text-file /tmp/pagina.txt

Dos campos tienen el peso, y ninguno puede ser verificado por nada aguas abajo.

--angle es la subpregunta que esta recuperación estaba respondiendo. La corroboración se cuenta por ángulos en lugar de por fuentes porque la propia dispersión de legwork infla los recuentos de fuentes. Registre el ángulo honestamente - reutilizar una cadena en una ejecución destruye silenciosamente la verificación, y ningún script puede detectar que lo hizo.

--quote es la oración textual que hizo que la fuente valiera la pena citarse. Registre una para cada fuente que tenga la intención de citar, a medida que la lee. Alrededor de la mitad de todos los hallazgos no llevan cifra, por lo que para esos, la cita es la única evidencia que existe, y es la única parte que sobrevive a que la página cambie. Cuando el texto de la página está en disco - cualquier cosa abierta con fetch.py, o un -m scrape con --out - la cita se verifica contra él y quote_verified: false significa que ha citado mal la página.

--from-fetch completa la URL, el título, la fecha y el texto de la página a partir del sidecar que esos dos escriben, por lo que no es necesario volver a escribir nada:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log --tsv "$OUT/$BASE.tsv" \
  --from-fetch /tmp/legwork/ab12cd34ef56.json \
  --angle "¿cuánto cobra el actual titular?" --kind precios_proveedor \
  --query "site:acme.example pricing" --quote "Team plan: 30 US dollars ..."

sources.py log --help cubre el resto: --via transportes (incluyendo api, local y mcp), --text-file extracción numérica, --kind. Registre el transporte que realmente utilizó - volver a recuperar una página a través de uno diferente para hacerla registrable distorsiona el rastro en lugar de registrarlo. sources.py kinds imprime qué tipos de fuente se adaptan a qué afirmaciones.

Subagentes

La recuperación es la única fase que vale la pena paralelizar, un subagente por ángulo. Bríndeles instrucciones desde subagent-brief.md, que lleva la plantilla textual, la forma de retorno requerida y la razón de por qué cada línea está en ella. Un subagente tiene contexto cero, por lo que todo lo que necesita va en las instrucciones.

Tres cosas se quedan con usted en lugar de las instrucciones:

  • Combine el modelo con la forma del ángulo. La recopilación de fragmentos y la fijación de una cifra conocida funcionan bien en un modelo económico - pase la anulación explícitamente, nunca deje que uno herede el modelo de la sesión por accidente. Pero el trabajo de fuente primaria de nivel profundo, y cualquier cosa que reconstruya una enumeración, se queda en el modelo del orquestador. Medido: en una comparación, los orquestadores abrieron 3, 8 y 32 páginas de proveedores en el rango de económico a capaz, y solo el más débil llenó cada celda de la cuadrícula desde un solo agregador mientras informaba éxito.
  • Nunca pegue la transcripción de un subagente en su síntesis. Tome la estructura de retorno, verifique que la cadena del ángulo haya vuelto sin cambios, registre cada fila, trabaje a partir del registro.
  • El alcance, el desafío y la síntesis son juicio. Se quedan en el modelo principal.

Scripts

Todos solo con la biblioteca estándar. Sin virtualenv. Cualquier python3 >= 3.9.

ScriptPropósito
fetch.py "<url>" --find TÉRMINOAbrir una página gratis y mantener su texto; sale con código 3 en un bloqueo o un shell
platforms.py list | search --on XDiez fuentes nativas de plataforma gratuitas, que devuelven registros en lugar de páginas
sources.py kinds | log | scoreVocabulario de tipos de fuente, el registro de recuperación, puntuación de idoneidad por tipo de afirmación
sources.py receiptLos recuentos de recuperación para la línea de recibo, tomados del registro
sources.py stale --claim-kind KQué fuentes registradas han caducado, según la vida media de ese tipo de afirmación
sources.py resumeLo que una ejecución anterior ya recuperó, para que una re-ejecución lo omita
independence.py groups | checkColapsar fuentes en voces independientes; contar corroboración consciente del ángulo
independence.py portfolioConcentración de fuentes en toda la ejecución, no dentro de un hallazgo
index.py add | listEl índice de investigación - archivar una ejecución, encontrar una pasada, detectar las desactualizadas
matrix.py check --report RUTAIntegridad de una matriz de comparación
check.py --report RUTA --level NIVELLa puerta de capacidad de envío
finish.py --report RUTA --level NIVELPuerta, barrido de desactualización y archivo en una sola llamada
`bd_search.py "<consultaurl>" -m MODO --json`

Salida

Resuelva la base de salida una vez al inicio de la ejecución:

OUTPUT_BASE="${LEGWORK_OUTPUT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)/docs/research}"
BASE="[Tema]_Research_$(date +%Y%m%d)"
OUT="$OUTPUT_BASE/$BASE"; mkdir -p "$OUT"

…

[truncado para traducción]

Skills relacionados