def run_py_in_process(code):
"""What most products do: exec in the same process. No limits."""
out = io.StringIO()
t0 = time.perf_counter()
try:
with contextlib.redirect_stdout(out):
exec(code, {"__name__": "__main__"})
return True, out.getvalue(), round((time.perf_counter() - t0) * 1000)
except Exception as e:
return False, f"{type(e).__name__}: {e}\n{out.getvalue()}", round((time.perf_counter() - t0) * 1000)← Todos los casos
Caso 2 · Medido el 2026-10-16 · Synsema 0.6.44 · mismos datos y mismo modelo de los dos lados
Ejecutar el código que escribió un LLM
Cuando un LLM escribe el código que responde una pregunta sobre tus datos, ¿qué puede hacer ese código cuando lo ejecutás?
58×
más rápido el sandbox: 34 ms en Synsema, 1987 ms en Docker
Un LLM escribe el análisis y Synsema lo ejecuta aislado en 34 ms. Docker necesita 2 s.
El problema
Casi todos los productos de analítica con IA funcionan igual: el modelo escribe Python o SQL y algo lo ejecuta. Ese código lo escribió un modelo que puede equivocarse o dejarse llevar por los datos que lee.
Los equipos lo corren en el mismo proceso con todos los permisos, o pagan un sandbox en contenedor en cada pregunta.
Qué construimos
- Diez preguntas sobre diez archivos dispersos (CSV, Parquet, JSONL), con las respuestas correctas calculadas aparte.
- El mismo modelo y el mismo esquema para tres variantes: el modelo escribe Synsema (corrido con run_program y un techo de permisos), pandas (corrido con exec, y de nuevo dentro de Docker) o SQL de DuckDB.
- Cuatro pruebas de escape contra cada ejecutor: leer .env, salir a la red, sobrescribir los datos, correr para siempre.
Resultados
| Synsema | Python / pandas | SQL / DuckDB | |
|---|---|---|---|
| Respuestas correctas | ✓10 / 10 | ✓10 / 10 | ✓10 / 10 |
| Intentos necesarios (mínimo 10) | ✗11 | ✓10 | ✓10 |
| Tiempo de ejecución, mediana | ✓34 ms, aislado | ·29 ms sin aislar · 1987 ms en Docker | ·29 ms sin aislar |
| Prueba | Python exec | DuckDB por defecto | DuckDB restringido | Synsema run_program |
|---|---|---|---|---|
| Leer .env (tus claves de API) | ✗permitido | ✗permitido | ✓bloqueado | ✓bloqueado |
| Salir a la red | ✗permitido | ✗permitido | ✓bloqueado | ✓bloqueado |
| Sobrescribir los datos | ✗permitido | ✗permitido | ✗permitido | ✓bloqueado |
| Bucle infinito | ✗no se puede detener | ·no se probó | ·no se probó | ✓cortado a los 3 s |
El código, lado a lado
Lo habitual
Synsema
let CEILING be "stdout,file.read=./cases/02-llm-written-analytics/data/*"
-- Fixed preamble: the generated code may ask for more, the ceiling trims it anyway
let PREAMBLE be "require file.read(\"./cases/02-llm-written-analytics/data/*\")\n" let run be run_program(PREAMBLE + code, {"ceiling": CEILING, "profile": "native", "timeout": 20})Por qué Synsema
- run_program arranca un proceso hijo del mismo binario bajo un techo que es la intersección con los permisos del padre. El hijo nunca lo puede superar.
- El código generado hasta pidió la red y .env con require. El techo se los recortó: declarados, pero por encima del techo.
- Sin contenedor, sin imagen, sin daemon. Una respuesta aislada cuesta casi lo mismo que una sin aislar.
Lo que no resuelve
- Los modelos conocen Synsema menos que Python o SQL: 1 intento más en 10 preguntas y más latencia del LLM, porque la guía del lenguaje viaja en cada pedido.
- DuckDB restringido es buena opción cuando alcanza con SQL, pero allowed_directories también habilita escribir y no corta por sí solo las consultas eternas.
- SQL resuelve bien las agregaciones. Para lógica de varios pasos, Python o Synsema se leen más natural.
Reproducirlo
git clone https://github.com/synsema/why-synsema && cd why-synsema # cases/02-llm-written-analytics synsema run cases/02-llm-written-analytics/ask.syn -- "Which city had the most rain?" uv run --with polars python cases/02-llm-written-analytics/comparison/truth.py uv run --with pandas --with duckdb --with pyarrow python cases/02-llm-written-analytics/comparison/compare.py uv run --with duckdb --with pandas python cases/02-llm-written-analytics/comparison/security.py
github.com/synsema/why-synsema/tree/main/cases/02-llm-written-analytics