\usepackage{openai}

إنشاء PDF من LaTeX عبر OpenAI باستخدام Function Calling

عرّف أداة compile_latex ودع GPT-4o يستدعيها تلقائيًا. يتولى FormaTeX التجميع، فتحصل على ملف PDF دون أن تكتب سطرًا واحدًا من LaTeX بنفسك.

\section{تعريف الدالة}

تعريف الدالة لتجميع LaTeX

صرّح عن أداة compile_latex في المصفوفة tools. سيستدعيها GPT-4o عندما يطلب المستخدم ملف PDF، ويمرّر كود LaTeX المصدري الكامل والمحرك واسم الملف المطلوب كوسائط منظمة.

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"],
            },
        },
    }
]

كتابة أوصاف جيدة للأدوات

يقرأ GPT-4o الحقل description ليقرر متى يستدعي الدالة. وضّح أنه ينبغي استدعاؤها كلما أراد المستخدم ملف PDF مجمّعًا، وليس فقط عندما يذكر LaTeX بالاسم.

\section{مثال كامل}

مثال كامل للمحادثة والتجميع

التدفق الكامل على دورين: يتلقى GPT-4o رسالة المستخدم، ويستدعي compile_latex مع كود LaTeX المصدري الذي ولّده، ثم يلخّص النتيجة. يُحفظ ملف PDF على القرص بعد اكتمال الدور الأول.

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}

اعتبارات البث

عند تفعيل البث، تصل وسائط استدعاء الأداة على دفعات ويجب تجميعها قبل التنفيذ. يوضح المثال أدناه كيفية تجميع أجزاء استدعاء الأداة المبثوثة وتنفيذها بعد انتهاء البث.

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}")

متى تستخدم البث

ابثّ الدور الأول لعرض كتابة GPT-4o لكود LaTeX في الوقت الفعلي. يحسّن ذلك زمن الاستجابة المحسوس للمستخدمين الذين ينتظرون مستندات طويلة.

التجميع متزامن دائمًا

نقطة نهاية التجميع في FormaTeX لا تبثّ الاستجابة، بل تعيد ملف PDF كاملًا بعد انتهاء التجميع. زمن الاستجابة المعتاد أقل من 3 ثوانٍ.

\end{openai}

إنشاء ملفات PDF باستخدام GPT-4o وFormaTeX

احصل على مفتاح FormaTeX API، وانسخ المثال الكامل أعلاه، وأطلق ملفات PDF المولّدة بالذكاء الاصطناعي من OpenAI function calling خلال دقائق.