\usepackage{openai}

PDF de LaTeX con OpenAI mediante function calling

Defina una herramienta compile_latex y deje que GPT-4o la llame automáticamente. FormaTeX se encarga de la compilación: usted obtiene un PDF sin escribir ni una sola línea de LaTeX.

\section{Definición de la función}

Definición de la función para compilar LaTeX

Declare una herramienta compile_latex en el array tools. GPT-4o la llamará cuando el usuario solicite un PDF, pasando como argumentos estructurados el código LaTeX completo, el motor y el nombre de archivo deseado.

tool_definition.py
from openai import OpenAI

client = OpenAI(api_key="your-openai-key")

# Define the compile_latex function that GPT-4 can call
TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "compile_latex",
            "description": (
                "Compile a complete LaTeX document to PDF using the FormaTeX API. "
                "Call this whenever the user wants a PDF output of a LaTeX document. "
                "Returns a confirmation message with the output file path."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "source": {
                        "type": "string",
                        "description": (
                            "Complete LaTeX source code including \\documentclass, "
                            "preamble packages, and \\begin{document}...\\end{document}."
                        ),
                    },
                    "engine": {
                        "type": "string",
                        "enum": ["pdflatex", "xelatex", "lualatex", "latexmk"],
                        "description": "LaTeX engine. Use xelatex for Unicode/custom fonts.",
                    },
                    "output_filename": {
                        "type": "string",
                        "description": "Filename for the saved PDF (e.g. report.pdf).",
                    },
                },
                "required": ["source"],
            },
        },
    }
]

Cómo escribir buenas descripciones de herramientas

GPT-4o lee el campo description para decidir cuándo llamar a la función. Indique explícitamente que debe llamarse siempre que el usuario quiera un PDF compilado, y no solo cuando mencione LaTeX por su nombre.

\section{Ejemplo completo}

Ejemplo completo de chat y compilación

El flujo completo en dos turnos: GPT-4o recibe el mensaje del usuario, llama a compile_latex con el código LaTeX generado y después resume el resultado. El PDF se guarda en disco al terminar el primer turno.

openai_formatex.py
import json
import requests
from openai import OpenAI

openai_client = OpenAI(api_key="your-openai-key")
FORMATEX_API_KEY = "your-formatex-key"
FORMATEX_URL = "https://api.formatex.io/api/v1/compile"

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "compile_latex",
            "description": "Compile LaTeX source to PDF via FormaTeX. Returns output file path.",
            "parameters": {
                "type": "object",
                "properties": {
                    "source": {"type": "string", "description": "Complete LaTeX source code."},
                    "engine": {
                        "type": "string",
                        "enum": ["pdflatex", "xelatex", "lualatex", "latexmk"],
                    },
                    "output_filename": {"type": "string"},
                },
                "required": ["source"],
            },
        },
    }
]

def call_compile_latex(args: dict) -> str:
    """Execute the compile_latex tool call."""
    response = requests.post(
        FORMATEX_URL,
        headers={
            "X-API-Key": FORMATEX_API_KEY,
            "Content-Type": "application/json",
        },
        json={
            "latex": args["source"],
            "engine": args.get("engine", "pdflatex"),
        },
        timeout=30,
    )
    response.raise_for_status()

    filename = args.get("output_filename", "output.pdf")
    with open(filename, "wb") as f:
        f.write(response.content)
    return f"PDF compiled successfully and saved to {filename}"

def chat_and_compile(user_message: str) -> str:
    """Run a GPT-4o chat turn that can call compile_latex."""
    messages = [
        {
            "role": "system",
            "content": (
                "You are a LaTeX expert assistant. When the user asks for a PDF document, "
                "write complete, valid LaTeX source and call compile_latex to produce it."
            ),
        },
        {"role": "user", "content": user_message},
    ]

    # First turn — GPT-4o decides to call compile_latex
    response = openai_client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=TOOLS,
        tool_choice="auto",
    )
    msg = response.choices[0].message

    if not msg.tool_calls:
        return msg.content or ""

    # Execute all tool calls
    messages.append(msg)
    for tool_call in msg.tool_calls:
        args = json.loads(tool_call.function.arguments)
        result = call_compile_latex(args)
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": result,
        })

    # Second turn — GPT-4o summarises the result
    final = openai_client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
    )
    return final.choices[0].message.content or ""


reply = chat_and_compile(
    "Create a one-page LaTeX CV for a software engineer and compile it to PDF."
)
print(reply)

\section{Streaming}

Consideraciones sobre streaming

Cuando el streaming está habilitado, los argumentos de las llamadas a herramientas llegan en fragmentos y deben ensamblarse antes de ejecutarse. El siguiente ejemplo muestra cómo acumular los fragmentos de las llamadas a herramientas transmitidos y ejecutarlos cuando termina el flujo.

streaming_example.py
from openai import OpenAI
import json

client = OpenAI(api_key="your-openai-key")

# Stream the first turn to show GPT-4o "thinking" while it writes LaTeX.
# Tool calls are assembled from streamed chunks before execution.
stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a LaTeX expert. Call compile_latex for PDFs."},
        {"role": "user", "content": "Write a beamer presentation on machine learning basics."},
    ],
    tools=TOOLS,
    tool_choice="auto",
    stream=True,
)

tool_call_chunks: dict[int, dict] = {}

for chunk in stream:
    delta = chunk.choices[0].delta

    # Accumulate streamed tool call arguments
    if delta.tool_calls:
        for tc in delta.tool_calls:
            idx = tc.index
            if idx not in tool_call_chunks:
                tool_call_chunks[idx] = {"id": "", "name": "", "arguments": ""}
            if tc.id:
                tool_call_chunks[idx]["id"] = tc.id
            if tc.function and tc.function.name:
                tool_call_chunks[idx]["name"] = tc.function.name
            if tc.function and tc.function.arguments:
                tool_call_chunks[idx]["arguments"] += tc.function.arguments

# Execute accumulated tool calls after stream finishes
for idx, tc in tool_call_chunks.items():
    args = json.loads(tc["arguments"])
    result = call_compile_latex(args)
    print(f"Tool call {idx}: {result}")

Cuándo usar streaming

Transmita el primer turno para mostrar a GPT-4o escribiendo LaTeX en tiempo real. Esto mejora la latencia percibida por los usuarios que esperan documentos largos.

La compilación siempre es síncrona

El endpoint de compilación de FormaTeX no usa streaming: devuelve el PDF completo cuando termina la compilación. La latencia habitual es inferior a 3 segundos.

\end{openai}

Genere PDF con GPT-4o + FormaTeX

Obtenga una clave de API de FormaTeX, copie el ejemplo completo anterior y publique PDF generados por IA mediante function calling de OpenAI en cuestión de minutos.