arrow_forwardAI Engineering / פלטים מובנים ו-Tool Use
רמה: מתחיל-מתקדם עודכן: אוגוסט 2026

פלטים מובנים ו-Tool Use

הצעד שהופך "צ'אט" ל"מוצר": לגרום ל-LLM להחזיר JSON תקין ולהפעיל כלים. בלי זה, אי אפשר לתכנת מעל מודל שפה.

למה זה קריטי

טקסט חופשי נהדר לבני אדם, אבל קוד לא יכול לעבוד איתו. אם המודל עונה "הליד נראה איכותי, בערך 85, כדאי לחזור אליו" — התוכנה שלך לא יודעת מה הציון. אבל אם הוא מחזיר {"score": 85, "priority": "high"} — אפשר להזין את זה ישר למסד נתונים, לתנאי, או לשלב הבא בזרימה.

פלטים מובנים (Structured Outputs) הם היכולת להכריח את המודל להחזיר מבנה נתונים קבוע ותקין. Tool Use (או Function Calling) זה השלב הבא — המודל לא רק מחזיר נתונים, אלא בוחר איזה פונקציה להפעיל ועם אילו פרמטרים. שני אלו הם הבסיס לכל אוטומציה, סוכן או אינטגרציה רצינית.

bolt
כלל אצבע

אם הפלט של ה-LLM נכנס לשלב הבא במערכת (ולא ישר לעיני משתמש) — הוא חייב להיות מובנה ומאומת.

JSON ו-Structured Output

הדרך הבסיסית: לבקש JSON בפרומפט ולהגדיר סכמה. במודלים מודרניים יש מצב ייעודי שמבטיח פלט תקין. דוגמה עם OpenAI (Python):

from openai import OpenAI
client = OpenAI()

resp = client.chat.completions.create(
    model="gpt-5.6",
    response_format={"type": "json_schema", "json_schema": {
        "name": "lead_score",
        "schema": {
            "type": "object",
            "properties": {
                "score": {"type": "integer", "minimum": 0, "maximum": 100},
                "priority": {"type": "string", "enum": ["high", "medium", "low"]},
                "reason": {"type": "string"}
            },
            "required": ["score", "priority", "reason"],
            "additionalProperties": False
        }
    }},
    messages=[
        {"role": "system", "content": "דרג את איכות הליד לפי הפרטים."},
        {"role": "user", "content": "חברת SaaS, 50 עובדים, תקציב מוגדר, דחיפות גבוהה."}
    ],
)
import json
data = json.loads(resp.choices[0].message.content)
print(data["score"], data["priority"])

הסכמה מבטיחה ש-score יהיה מספר בין 0 ל-100 ו-priority אחד מהערכים המותרים. זה הרבה יותר אמין מ"בקש JSON" בפרומפט בלבד.

Tool Use / Function Calling

כאן המודל מחליט לבד אילו כלים להפעיל. אתה מגדיר את הכלים הזמינים, והמודל מחזיר איזה לקרוא ועם אילו פרמטרים. דוגמה עם Anthropic (Claude):

import anthropic
client = anthropic.Anthropic()

tools = [{
    "name": "get_weather",
    "description": "מחזיר את מזג האוויר הנוכחי בעיר נתונה",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
    }
}]

msg = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "מה מזג האוויר בתל אביב?"}],
)

for block in msg.content:
    if block.type == "tool_use":
        print(block.name, block.input)   # get_weather {'city': 'תל אביב'}
        # כאן אתה מריץ את הפונקציה האמיתית ומחזיר את התוצאה למודל

הזרימה המלאה: (1) המודל מבקש להפעיל כלי; (2) הקוד שלך מריץ את הפונקציה האמיתית; (3) מחזירים את התוצאה למודל; (4) המודל מנסח תשובה סופית. זה בדיוק המנגנון שמאחורי סוכני AI ו-MCP.

ולידציה ו-Retry — אל תסמוך, תבדוק

גם עם json_schema, כדאי לאמת בצד שלך לפני שמזינים למערכת. ב-Python נהוג Pydantic; ב-TypeScript — Zod.

from pydantic import BaseModel, Field, ValidationError

class LeadScore(BaseModel):
    score: int = Field(ge=0, le=100)
    priority: str
    reason: str

def parse_with_retry(client, messages, tries=2):
    for attempt in range(tries):
        raw = call_model(client, messages)          # קריאה למודל
        try:
            return LeadScore.model_validate_json(raw)  # אימות
        except ValidationError as e:
            # מחזירים למודל את השגיאה ומבקשים לתקן
            messages.append({"role": "user",
                "content": f"הפלט לא תקין: {e}. החזר JSON תקין בלבד."})
    raise RuntimeError("failed to get valid output")

התבנית הזו — נסה, אמת, ואם נכשל החזר את השגיאה למודל ובקש תיקון — היא סטנדרט תעשייתי. היא הופכת מערכת שבירה ליציבה.

טיפים וטעויות נפוצות

rocket_launch

הצעד הבא

עכשיו שהפלט מובנה — הצעד הבא הוא לחבר ידע (RAG) ולמדוד איכות (Evals).