Ir al contenido
synsema ¿por qué?
← 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.

Python dentro de DockerPython dentro de Docker: 1987 ms1987 msSynsema run_programSynsema run_program: 34 ms34 ms
Tiempo para ejecutar el código generado de forma segura (mediana de 10 preguntas)Los dos sandboxes: sin red, datos en solo lectura, tiempo límite. Python y DuckDB sin aislamiento tardan 29 ms, pero pueden leer tus claves.

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

Respuestas y costo
SynsemaPython / pandasSQL / DuckDB
Respuestas correctas10 / 1010 / 1010 / 10
Intentos necesarios (mínimo 10)111010
Tiempo de ejecución, mediana34 ms, aislado29 ms sin aislar · 1987 ms en Docker29 ms sin aislar
Qué puede hacer el código generado
PruebaPython execDuckDB por defectoDuckDB restringidoSynsema run_program
Leer .env (tus claves de API)permitidopermitidobloqueadobloqueado
Salir a la redpermitidopermitidobloqueadobloqueado
Sobrescribir los datospermitidopermitidopermitidobloqueado
Bucle infinitono se puede detenerno se probóno se probócortado a los 3 s

El código, lado a lado

Lo habitual
Lo habitual: exec en el mismo procesoEl código generado recibe todos los permisos del proceso.
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)
cases/02-llm-written-analytics/comparison/compare.py · desde la línea 36
Synsema
Synsema: el techo de permisosLeer esta carpeta e imprimir. Nada más, pida lo que pida el código.
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"
cases/02-llm-written-analytics/analyst.syn · desde la línea 8
Synsema: ejecutar con techo y tiempo límiteUn proceso hijo del mismo binario. Sin contenedor.
        let run be run_program(PREAMBLE + code, {"ceiling": CEILING, "profile": "native", "timeout": 20})
cases/02-llm-written-analytics/analyst.syn · desde la línea 61

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

Compartir