SafeXL
Edita archivos .xlsx y .xlsm y deja intactas las macros, tablas dinámicas y gráficos. No puede eliminar filas ni columnas, y no recalcula.
Documentación
SafeXL
SafeXL permite que un agente de IA edite libros de Excel y deje todo lo que no toca tal como estaba. Cambia el XML del archivo directamente en lugar de cargar y volver a guardar todo el libro. Los gráficos, tablas dinámicas, macros, validación de datos y el resto salen byte-idénticos a menos que una edición tenga que cambiarlos. Lo escribí para personas cuyos agentes trabajan en hojas de cálculo de las que otros dependen.
Se distribuye como CLI (safexl), un servidor MCP (safexl-mcp) y un plugin de Claude Code. Una versión alojada está en Apify: https://apify.com/herakles-dev/safexl-workbook
Lo que medí
El benchmark son 8 tareas difíciles sobre libros reales, 3 ejecuciones cada una, es decir, 24 ejecuciones por brazo. Un calificador determinista las puntúa. "Intacto" significa que la comprobación de preservación del calificador pasó. "Aprobado" significa que el resultado fue correcto, preservado y válido.
Esto no es una prueba fuera de muestra. Construí SafeXL contra estas 8 tareas, y escribí la guía del plugin después de ver fallar a los modelos en ellas. La guía no contiene ninguna de las respuestas, y una prueba en el repositorio lo verifica. Espera menos en tareas que no he visto.
Claude Haiku 4.5 con la habilidad xlsx de Anthropic, indicado en una línea para usarla (2026-10-05): 6 de 24 intactos, 5 de 24 aprobados.
Claude Haiku 4.5 con el plugin SafeXL 0.2 y sin instrucción del operador (2026-10-05): 22 de 24 intactos, 21 de 24 aprobados. Las 24 ejecuciones costaron $1.862 en total, lo que equivale a $0.078 por ejecución y $0.089 por ejecución aprobada. Esos son precios de lista de API según los informó la CLI. Las ejecuciones usaron una suscripción de Claude.
Los dos brazos no son la misma configuración. El brazo de habilidad tenía la habilidad de Anthropic, una pista de una línea y sin hooks. El brazo del plugin tenía el plugin con su hook de guardia activado y la habilidad de Anthropic bloqueada. Su mensaje de inicio le dice al modelo que use safexl y que nunca guarde con openpyxl o pandas. Así que el modelo recibió un empujón, y no fue una prueba a ciegas. Los brazos se ejecutaron como lotes separados el mismo día.
Las tres ejecuciones que fallaron. Una vez el modelo escribió una fórmula de búsqueda que evalúa a #N/A. Dos veces insertó una fila completa donde la tarea necesitaba una inserción limitada a algunas columnas, y eso movió dos nombres definidos.
Un fallo pertenece al propio SafeXL. En mi propia comprobación después de las ejecuciones, safexl verify dijo "intacto" para las 24 salidas, incluidas las dos que movieron nombres definidos. No puedes repetir esa comprobación desde este repositorio, porque los archivos de salida no están en él. La versión 0.2.0, que usaron estas ejecuciones, no marcó una referencia que se movió. La versión 0.2.1 lista cada nombre definido y rango de tabla que cambió. Lo ejecuté de nuevo sobre las salidas registradas: las dos ejecuciones fallidas ahora nombran los dos nombres movidos, dropdown y droptable, junto con dos nombres que la tarea pretendía ampliar. El veredicto sigue siendo "intacto", porque el recibo informa del cambio y no puede saber si fue deseado. El hook de guardia no tuvo nada sobre lo que actuar en ninguna de las 24 ejecuciones.
También ejecuté otros modelos solo con las herramientas MCP de SafeXL. No ejecuté ninguno de ellos sin SafeXL. Estas filas muestran lo que cada modelo logró con las herramientas. No muestran lo que las herramientas añadieron.
La tabla cubre 7 de las 8 tareas, 21 ejecuciones por modelo. El prompt del sistema de esa ronda contenía la fórmula de una tarea como ejemplo, así que dejé esa tarea fuera. El resumen de la ronda cita las líneas.
| Modelo | Aprobados | Costo por ejecución |
|---|---|---|
| DeepSeek V4 Flash (OpenRouter) | 21 de 21 | alrededor de $0.011, alrededor de 29 s |
| Qwen 3.8 27B (nivel gratuito) | 18 de 21 | sin facturar |
| Nemotron 3 Super 120B (nivel gratuito) | 17 de 21 | sin facturar |
| Laguna S 2.1 (nivel gratuito) | 16 de 21 | sin facturar |
| Mistral Small 3.2 | 13 de 21 | $0.0030 |
| GPT-OSS 120B | 12 de 21 | $0.0021 |
| Claude Haiku 4.5, mismo arnés | 6 de 7 (una repetición, parcial) | $0.0933 |
La otra guía del prompt se escribió después de ver fallar a los modelos en estas tareas, así que estas filas también están dentro de la muestra. Cuatro modelos más ejecutaron solo de 5 a 7 veces y aprobaron de 2 a 4 de esas. Están en el resumen de esa ronda. Algunas filas incluyen fallos de API y respuestas vacías.
Veinticuatro ejecuciones por brazo en 8 tareas es una muestra pequeña, y el benchmark es mío.
Compruébalo tú mismo
git clone https://github.com/herakles-dev/safexl
cd safexl
pip install -e 'packages/safexl[scan,test]'
python3 research/xlsx-bench/fetch_corpus.py
python3 research/xlsx-bench/grade.py --tasks research/xlsx-bench/tasks_hard8.json --runs <runs dir> --summary
fetch_corpus.py descarga los 14 libros de prueba de sus fuentes originales y verifica sus hashes. Ninguno de ellos está en este repositorio. La calificación necesita LibreOffice (soffice) en el PATH. Ejecutar una ronda necesita la CLI claude.
Las calificaciones están en research/xlsx-bench/results/. Cada ronda tiene su propia carpeta. Las ejecuciones crudas están en research/xlsx-bench/recordings/. Puedes leer cada ejecución y volver a ejecutar el benchmark. No puedes volver a calificar mis archivos exactos, porque los libros de salida de mis ejecuciones no están en el repositorio. Las rutas locales, mi nombre de usuario y el nivel de suscripción están reescritos en las grabaciones.
Instalación
SafeXL no está en PyPI. Instálalo desde la URL de git:
pip install "git+https://github.com/herakles-dev/safexl#subdirectory=packages/safexl"
command -v safexl
Para Claude Code, añade el plugin:
claude plugin marketplace add herakles-dev/claude-plugins
claude plugin install safexl@herakles-plugins
O añade solo el servidor MCP:
claude mcp add safexl -- safexl-mcp
Lo que no puede hacer
No puede eliminar filas ni columnas. No puede insertar columnas. No puede crear gráficos, tablas dinámicas ni formato. No recalcula fórmulas; marca el libro para recalcular al abrir. Las hojas de cálculo con un prefijo de espacio de nombres (archivos .NET OpenXML SDK) se rechazan. La salida se abrió en LibreOffice. Nunca se ha abierto en Excel de escritorio.
Qué hay en el repositorio
packages/safexl/contiene el motor, la CLI, el servidor MCP y el plugin de Claude Code enclaude-plugin/.research/xlsx-bench/contiene el benchmark: tareas, calificador, ejecutor,fetch_corpus.py, y las grabaciones y resultados de tres rondas.research/safexl-moat/fixtures/contiene un manifiesto y un pequeño libro mío.
Licencia
MIT. Los libros de prueba de terceros permanecen bajo sus licencias originales. Ver research/xlsx-bench/THIRD_PARTY.md.