CommunityRedacción y edicióngithub.com

kcy4334-lgtm/translate-book-arxiv

Traduce artículos de arXiv a PDFs con calidad de libro mediante subagentes en paralelo. Lee el código fuente LaTeX, por lo que las ecuaciones y la numeración original del artículo se conservan.

¿Qué es translate-book-arxiv?

Esta habilidad traduce libros completos (principalmente artículos de arXiv) de un idioma a otro, produciendo PDFs con calidad de libro. Utiliza una tubería de varios pasos con subagentes en paralelo para manejar eficientemente documentos grandes. Las características clave incluyen: convertir la fuente LaTeX de arXiv en fragmentos Markdown, preservar ecuaciones reales ($...$ y $$...$$), figuras rasterizadas y citas; utilizar un glosario compartido para garantizar la coherencia terminológica entre fragmentos; soportar comprobaciones de cordura y recuperación mediante archivos de registro (KNOWLEDGE.md y KNOWHOW.md); y emplear cuatro 'asesores' especializados (old-man, question-monster, fast-finder, referee) para la resolución dirigida de problemas. La habilidad está diseñada para su uso con agentes de IA como Claude Code, Codex o Cursor, y evita errores comunes como la eliminación silenciosa de contenido, la suposición incorrecta de que algo no está presente, o la rendición prematura en comandos LaTeX no soportados. El flujo de trabajo incluye recopilar parámetros (ruta del archivo, idioma de destino, concurrencia), preprocesar a fragmentos, traducirlos con subagentes paralelos y ensamblar la salida final.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add kcy4334-lgtm/translate-book-arxiv

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

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

Documentación

Habilidad de Traducción de Libros

Eres un asistente de traducción de libros. Traduces libros completos de un idioma a otro orquestando una tubería de varios pasos.

Antes de comenzar

KNOWLEDGE.md en este directorio es el registro de hallazgos: cosas que salieron mal en ejecuciones reales, por qué y cómo se solucionaron. Léelo en el momento en que la salida parezca incorrecta: su índice de síntomas mapea lo que ves con la causa, y su cadena de diagnóstico muestra qué artefacto intermedio verificar primero. El fallo característico de esta tubería es la eliminación silenciosa: contenido que simplemente no está, sin error y sin basura en la página.

KNOWHOW.md es su contraparte, y vale la pena conocer la división antes de comenzar: KNOWLEDGE contiene hechos sobre cómo se comportan las herramientas, KNOWHOW contiene cómo proceder con el trabajo. ¿Por qué se rompió esto? contra ¿cómo debería proceder? Su tabla "Qué documento, para qué tarea" dice qué leer antes de qué, y su índice de tareas cubre los pasos que son fáciles de hacer de la manera costosa.

Se espera que agregues a ambos — ver Paso 9.

No leas ninguno de los dos archivos completos. Superan los 110 KB en más de 130 entradas y solo crecen; leer ambos para responder una pregunta cuesta más que la respuesta. En su lugar, busca:

python scripts/kb.py find "<síntoma, archivo, función o comando LaTeX>"
python scripts/kb.py list          # id + título de todo, para navegar
python scripts/kb.py show K102 H26 # entradas nombradas, completas

kb.py analiza ambos archivos frescos en cada llamada, por lo que nunca está desactualizado con ellos, y no hay un archivo de índice que se desvíe. Cuando la respuesta necesita criterio en lugar de una coincidencia — cuál de seis candidatos realmente se aplica a tu caso — llama a fast-finder (abajo). Cuando no coincide nada, esa es una respuesta real: esto es nuevo, y estarás escribiendo una entrada en lugar de encontrando una.

Cuatro asesores, y cuándo llamarlos

KNOWLEDGE y KNOWHOW registran lo que ya ha sucedido. Estos dos no: trabajan en la decisión que tienes frente a ti, y cada uno existe debido a un fallo que los registros no podrían haber prevenido.

Ambos son baratos — un subagente de solo lectura, una pregunta, una respuesta. Ninguno escribe código, y ninguno tiene veto. Si un asesor no puede nombrar algo específico, procede con lo que tenías. Un asesor que solo dice "piensa más ampliamente" o "esfuérzate más" no te ha dicho nada, y estancarse en eso es peor que nunca preguntar.

old-man — llámalo ANTES de concluir que algo está ausente

El fallo para el que sirve: se escribe una comprobación para la forma que el corpus ha mostrado, se encuentra con un artículo con forma diferente, e informa ausente en lugar de desconocido. Esto sucedió cuatro veces en una tarde en el cuarto artículo — se asumió que una referencia que comenzaba con images/ era una que ya habíamos extraído, se asumió que el primer \end{tabular} terminaba la tabla, un \caption dentro de un comentario % se contó como un título, y un título escrito \captionof no se contó en absoluto. Cada uno es el mismo error: el patrón se leyó como la definición.

Actívalo cuando estés a punto de:

  • concluir que la fuente no contiene algo, porque una búsqueda no encontró nada;
  • escribir un patrón cuya coincidencia decide que algo está presente o ausente;
  • generalizar una regla a partir de los artículos que ya has traducido.

Pregúntale: lo que estás a punto de concluir, el patrón que usaste y el archivo que buscaste. Espera como respuesta: alternativas de ortografía y diseño nombradas que derrotarían ese patrón — \captionof junto a \caption, wrapfigure junto a figure, un .bbl en línea junto a \bibitem — cada una lo suficientemente específica para hacer grep. Luego haz grep para ellas. El consejo vale la pena solo si una búsqueda que nombró encuentra algo; anota en tu informe cuando lo haga.

question-monster — llámalo DESPUÉS de concluir que algo es imposible

El fallo para el que sirve: rendirse en el primer intento. Siete de las ocho ecuaciones de DeeR-VLA fueron rechazadas por \setlength, una directiva de espaciado sin nada que leer, y la octava por \sideset — para la cual existía un equivalente exacto, \sum\nolimits_{X}, y la misma ecuación ya lo usaba más adelante. La concesión se escribió antes de buscar la alternativa, y solo un lector que seguía preguntando "¿de verdad, de ninguna manera?" la encontró.

Actívalo cuando estés a punto de escribir no soportado, no se puede expresar, no hay manera de, tiene que ser eliminado, o perdemos esto — en un informe, un mensaje de commit o un comentario.

Pregúntale: lo que declaraste imposible, lo que intentaste y el error o rechazo exacto. Espera como respuesta: candidatos concretos para probar, no ánimo. Se detiene cuando la respuesta es genuinamente no, y la prueba para eso es K100: el límite no está donde un comando no está implementado, es donde el subconjunto soportado no tiene forma de decir lo mismo. Un comando no implementado con un equivalente es una reescritura que aún no has hecho.

fast-finder — llámalo EN LUGAR de leer los dos registros

El fallo para el que sirve: los registros solo son útiles si la entrada correcta se encuentra en segundos, y con 130 entradas eso dejó de ser cierto leyendo. Ejecuta kb.py, juzga cuáles de las coincidencias realmente se aplican a tu pregunta, y las devuelve textualmente — una línea de estado que diga que un enfoque ya fue probado y revertido es todo el valor de una entrada, y un resumen lo pierde.

Actívalo cuando de otro modo abrirías KNOWLEDGE.md o KNOWHOW.md, y siempre que estés a punto de cambiar una función y quieras saber lo que ya se sabe sobre ella. kb.py find solo es suficiente para un símbolo exacto; el agente gana su valor en los difusos.

También mantiene los registros localizables: kb.py check detecta una entrada a la que ninguna fila del índice llega (invisible, por lo que escribirla fue en vano), y kb.py stale detecta una entrada que nombra una función que el repositorio ya no tiene. Ejecuta ambos después del Paso 9.

referee — llámalo UNA VEZ que toda la ejecución haya sido evaluada, no por fragmento

El fallo para el que sirve: verify_chunk rechaza un fragmento y no te dice nada sobre la ejecución. Un defecto que se activa una vez es un accidente; el mismo defecto en un tercio de los fragmentos es la INSTRUCCIÓN, porque cada instancia de un rol leyó el mismo mensaje; el mismo defecto en un tercio del libro es algo que nadie ha arreglado. Nada de eso es visible desde dentro de un fragmento.

python scripts/referee.py tally  <temp_dir> --lang <lang>   # juzga esta ejecución
python scripts/referee.py record <temp_dir> --lang <lang>   # y recuérdalo
python scripts/referee.py history                           # todas las ejecuciones hasta ahora

tally solo cuenta y compara. De quién es la culpa no está en el conteo — una herramienta en desacuerdo, una instrucción que preguntó de manera ambigua y un rol que se equivoca producen el mismo número, y en esta tubería el primero es el caso común (K57). El agente lee el código de la comprobación antes de atribuir cualquier cosa, y su libro de contabilidad es REFEREE.md, buscable a través de kb.py con los otros dos registros para que una advertencia planteada sobre un rol se encuentre cuando un rol diferente hace lo mismo.

Las tarjetas son para una repetición, nunca para una primera ocurrencia, y nunca para una falla de las herramientas o la instrucción. El silencio es una salida frecuente y válida: un árbitro escuchó cada ejecución es ignorado para la tercera, y un rol que duda porque espera una tarjeta es más lento sin ser más correcto.

Qué hace crecer a old-man

scripts/corpus_census.py registra qué forma tenía realmente cada artículo — qué entornos flotantes, ortografía de títulos, construcciones de tablas, estilo de bibliografía, matemáticas y material preliminar utilizó. merge_and_build.py escribe una fila al final de cada compilación exitosa, por lo que el registro crece por sí mismo y no se puede olvidar.

python scripts/corpus_census.py digest

lo convierte en frecuencia ("wrapfigure en 1 de 5, figure* en 4 de 5") y, al final, NUNCA VISTO — las formas que ningún artículo en el corpus ha contenido nunca. Esa segunda lista es el punto: un patrón que decide sobre uno de ellos nunca ha sido probado contra uno real, y tampoco quien lo escribió.

El censo gana una fila por artículo por sí mismo; su VOCABULARIO no. Cuando te encuentres con una forma que digest no puede ver, agrega un marcador a MARKERS en corpus_census.py — así es como el asesor mejora en lugar de simplemente estar más ocupado.

Genera cada uno con un subagente de propósito general; las definiciones en .claude/agents/ llevan las instrucciones completas. Dales las rutas que necesitan — leen, no ejecutan la tubería.

Flujo de trabajo

1. Recopilar parámetros

Determina lo siguiente a partir del mensaje del usuario:

  • file_path: Ruta al archivo de entrada (PDF, DOCX o EPUB) — REQUERIDO
  • target_lang: Código de idioma de destino (por defecto: zh) — ej. zh, en, ja, ko, fr, de, es
  • concurrency: Número de subagentes paralelos por lote (por defecto: 8)
  • temp_root: Directorio opcional bajo el cual se debe crear {filename}_temp/
  • epub_cover: Ruta de imagen de portada opcional explícita para la salida EPUB
  • export_name: Tallo de nombre de archivo opcional para alias de salida orientados al usuario
  • custom_instructions: Cualquier instrucción de traducción adicional del usuario (opcional)

Si no se proporciona la ruta del archivo, pregunta al usuario.

2. Preprocesar — Convertir a fragmentos Markdown

Ejecuta el script de conversión para producir fragmentos:

python {baseDir}/scripts/convert.py "<file_path>" --olang "<target_lang>"

Si el usuario proporcionó temp_root, añade --temp-root "<temp_root>". El nombre de la hoja del directorio temporal permanece {filename}_temp/; solo cambia el directorio padre.

Artículos académicos: usa la fuente LaTeX de arXiv

Si la entrada es un artículo de arXiv, el backend de fuente LaTeX es el único camino que preserva las ecuaciones. El backend predeterminado (calibre) ejecuta el PDF a través de pdftohtml, que dispersa cada fórmula en tramos de texto posicionados — no queda ningún objeto matemático que recuperar, por lo que ninguna combinación de banderas puede recuperar una ecuación. El texto interno de las figuras (etiquetas de ejes, números de marca) también se filtra en la prosa del cuerpo en ese camino.

convert.py detecta un preprint de arXiv automáticamente (marca de página 1 más los metadatos del productor arXiv GenPDF) y lo informa. Debido a que usarlo requiere descargar la fuente del artículo de arxiv.org, pregunta al usuario antes de pasar --allow-network:

python {baseDir}/scripts/convert.py "<file_path>" --olang "<target_lang>" --allow-network

Banderas relacionadas:

  • --backend {auto,calibre,arxiv} — auto (predeterminado) prefiere arxiv cuando el PDF es un preprint detectado Y se da --allow-network, de lo contrario recurre a calibre. arxiv falla ruidosamente en lugar de degradarse silenciosamente.
  • --arxiv-id <id> — anular la detección (ej. 2606.04980). Implica el backend arxiv.
  • --no-math-guard — solo depuración; deshabilita la colocación de marcadores de fórmulas.

En la ruta arXiv, espera: matemáticas reales $...$/$$...$$, figuras rasterizadas de los PDF vectoriales originales con títulos adjuntos, y citas renderizadas por citeproc cuando la fuente incluye un .bib. Dos límites conocidos que vale la pena contarle al usuario: las tablas LaTeX sin procesar se conservan textualmente en lugar de traducirse, y las figuras dibujadas con tikz/pgfplots no tienen un archivo de imagen en la fuente.

Cuenta las figuras con respecto al PDF original antes de creer que una falta es una figura tikz. El lector LaTeX de pandoc conoce un conjunto fijo de construcciones; cualquier otra cosa pasa como LaTeX sin procesar, y resolve_images solo reescribe imágenes que pandoc ya emitió. Por lo tanto, la imagen se elimina, su título aún se imprime y nada informa de un problema, que se ve exactamente como un gráfico tikz. Tres construcciones separadas hicieron esto, todas ahora manejadas en la ingesta y todas vale la pena reconocerlas en un artículo nuevo: \subfloat (subfig), \begin{SCfigure} y sus parientes wrapfigure/sidewaysfigure, y \includegraphics[page=N] en un PDF de figura de varias páginas — este último no produjo ningún error, solo el gráfico incorrecto y un duplicado de otro. dry_run.py detecta los tres.

Comprueba el número de columnas de una tabla contra su preámbulo tabular, no contra las otras filas. pandoc reforma una tabla sin procesar a la salida de dos maneras que ningún recuento detecta: vuelve a emitir un *{9}{r} expandido junto con el original, por lo que una tabla de 12 columnas se convierte en 21 con nueve columnas vacías después de cada fila; y elimina \rotatebox/\multirow por completo, por lo que la etiqueta que lleva una columna de grupo estrecho desaparece y las filas se quedan sin atribuir. Ambos se manejan en la ingesta, y ambos son reparables posteriormente en los sidecars matemáticos sin tocar la prosa — ver K53.

Esto crea un directorio {filename}_temp/ que contiene:

  • input.html, input.md — archivos intermedios (input.html solo en el backend calibre)
  • chunk0001.md, chunk0002.md, ... — fragmentos fuente para traducción
  • chunk0001.math.json, ... — sidecars de marcadores de fórmulas/citas (ruta arXiv)
  • flat.tex, arxiv_src/ — fuente LaTeX aplanada y el tarball desempaquetado (ruta arXiv)
  • manifest.json — manifiesto de fragmentos para seguimiento y validación
  • source_fingerprint.json — identidad SHA-256 de los bytes fuente a partir de los cuales se construyó este directorio temp
  • config.txt — configuración de la tubería con metadatos, incluido qué backend lo construyó

Un directorio temp recuerda su backend. Volver a ejecutarlo con uno diferente aborta en lugar de mezclar un input.md derivado de arXiv con imágenes derivadas de calibre.

Si convert.py aborta porque el directorio temp fue creado a partir de bytes fuente diferentes, no lo reutilices — elimina el directorio temp o pasa un --temp-root nuevo, luego vuelve a ejecutar. Los directorios temp creados antes de que existiera la huella digital se adoptan con una advertencia y se les asigna una huella digital en la próxima ejecución exitosa.

3. Descubrir fragmentos fuente

Usa Glob para encontrar todos los fragmentos fuente:

Glob: {filename}_temp/chunk*.md

Excluye output_chunk*.md de la lista fuente. El plan de retraducción selectiva a continuación decide qué fragmentos realmente necesitan trabajo.

3.5. Construir glosario (coherencia terminológica)

Un subagente separado traduce cada fragmento con un contexto nuevo. Sin estado compartido, el mismo nombre propio puede derivar en múltiples traducciones. El glosario hace que cada subagente vea la misma traducción canónica para los términos que aparecen en su fragmento.

Si <temp_dir>/glossary.json ya existe, omite la reconstrucción — volver a ejecutar la habilidad no debe sobrescribir el glosario a menos que se solicite explícitamente.

Para construir o reconstruir el glosario:

python {baseDir}/scripts/build_glossary.py "<temp_dir>" --lang "<target_lang>"

Esto analiza todos los fragmentos fuente en busca de nombres propios, términos técnicos y frases hechas, y los compara con traducciones de fragmentos anteriores si están disponibles, produciendo un mapeo JSON que los subagentes de traducción leen antes de comenzar.

4. Traducir fragmentos (paralelamente)

Para cada fragmento fuente, genera un subagente de traducción que:

  1. Lee el fragmento fuente y su sidecar matemático (si existe).
  2. Lee el glosario para términos relevantes.
  3. Traduce el contenido del fragmento al idioma de destino.
  4. Conserva todos los marcadores de fórmulas, citas y referencias cruzadas.
  5. Escribe el resultado como output_chunkNNNN.md en el directorio temp.

Usa el nivel de concurrencia especificado para ejecutar múltiples traducciones de fragmentos en paralelo.

5. Verificar y fusionar

Después de que todos los fragmentos estén traducidos:

python {baseDir}/scripts/merge_chunks.py "<temp_dir>" --lang "<target_lang>"

Esto:

  • Verifica que todos los fragmentos fuente tengan una salida correspondiente.
  • Comprueba la coherencia en el manejo de fórmulas y citas.
  • Fusiona los fragmentos traducidos en un solo documento Markdown.
  • Produce una vista previa de la salida.

6. Construir PDF/EPUB de salida

python {baseDir}/scripts/build_output.py "<temp_dir>" --lang "<target_lang>" --format pdf
python {baseDir}/scripts/build_output.py "<temp_dir>" --lang "<target_lang>" --format epub

El formato predeterminado es PDF. Para EPUB, pasa --format epub.

7. Informar al usuario

Informa al usuario dónde se encuentra la salida, cualquier problema encontrado y un resumen de la traducción.

8. Registrar hallazgos (KNOWLEDGE y KNOWHOW)

Si encontraste nuevos problemas, soluciones o ideas durante esta ejecución, agrega entradas a KNOWLEDGE.md y/o KNOWHOW.md según corresponda.

9. Actualizar censo

Ejecuta corpus_census.py para actualizar el censo con la forma de este artículo.

python scripts/corpus_census.py update "<temp_dir>"
python scripts/corpus_census.py digest

10. Referee (opcional)

Si la ejecución tuvo problemas significativos, ejecuta el árbitro para registrar el resultado para referencia futura.

Skills relacionados