Middleware
Middleware הוא המימוש הקונקרטי של ה-Harness
בפרק הראשון בנושא הזה קבענו ש-createAgent בונה בפועל את אותו "הארנס" שנלמד בנושא AI Agents — model, tools, ו-middleware. middleware הוא בדיוק החלק השלישי הזה: המנגנון שמאפשר להתערב בלולאה האגנטית עצמה, לא רק לספק לה כלים או מודל.
כל מה שראינו בפרק ה-Harness (הרשאות, sandboxing, תקציבים, לוגים) הוא דוגמה קונקרטית למה ש-middleware יכול לממש בקוד LangChain אמיתי.
ה-hook lifecycle: איפה middleware מתערב
middleware נתלה בנקודות קבועות לאורך הלולאה האגנטית: לפני שקוראים למודל, אחרי שהמודל מחזיר תשובה, לפני שמפעילים כלי, ואחרי שהכלי מחזיר תוצאה. בכל נקודה כזו middleware יכול לקרוא את המצב הנוכחי, לשנות אותו, או — כפי שנראה בהמשך — לעצור את הפעולה לגמרי.
שמות ה-hooks המדויקים והחתימה שלהם תלויים בגרסת LangChain שבה אתם משתמשים — כדאי לבדוק את התיעוד הרשמי לפרטים העדכניים; הדוגמאות בפרק הזה ממחישות את העיקרון, לא מצטטות API קפוא בזמן.
Middleware מובנה מראש
LangChain מגיע עם קטגוריות שלמות של middleware מוכן לשימוש, בלי לכתוב אותו בעצמכם: guardrails לזיהוי מידע רגיש (PII) וסינון תוכן, fault tolerance עם retries ו-fallbacks כשקריאה למודל נכשלת, וsteering ל-human-in-the-loop — עצירה לאישור אנושי לפני פעולה מסוימת, בדיוק כמו שראינו ברמת העיקרון בפרק ה-Harness.
היתרון של middleware מובנה מראש הוא שאין צורך לממש מחדש לוגיקה גנרית כמו retry-with-backoff או זיהוי PII בכל פרויקט — מוסיפים אותו לרשימת ה-middleware ומקבלים את ההתנהגות מוכנה.
כתיבת middleware מותאם אישית
כשצריך התנהגות ספציפית לפרויקט — לוגים בפורמט מסוים, מדדים, או כלל עסקי ייחודי — כותבים middleware משלכם: אובייקט עם פונקציות ל-hooks הרלוונטיים, שמועבר לרשימת middleware ב-createAgent.
const loggingMiddleware = {
beforeModel: async ({ messages }: { messages: Message[] }) => {
console.log(`שולח ${messages.length} הודעות למודל`);
},
afterToolCall: async ({ toolName, result }: { toolName: string; result: unknown }) => {
console.log(`כלי ${toolName} החזיר:`, result);
},
};
const agent = createAgent({
model: "anthropic:claude-sonnet-5",
tools: [getWeather],
middleware: [loggingMiddleware],
});דוגמה מלאה: חסימת כלי מסוכן בלי אישור
בפרק ה-Harness בנושא AI Agents ראינו דוגמת JSON של agent עם הרשאות מוגבלות (code-review-worker עם scope שאוסר כתיבה ורשת). middleware הוא המקום שבו אכיפה כזו קורית בפועל בקוד: לפני שכלי רץ, ה-middleware יכול לבדוק את הפרמטרים שלו ולחסום את הקריאה אם היא חורגת מהמדיניות שהוגדרה — בלי לסמוך על כך שהמודל 'יבחר' לא לקרוא לכלי.
בדוגמה הבאה beforeToolCall בודק בקשת זיכוי גדולה מדי, וזורק שגיאה במקום לתת לכלי לרוץ — בדיוק אותו עקרון של least privilege ו-approval gates שכבר נלמד, רק הפעם אכוף ב-middleware אמיתי.
const approvalMiddleware = {
beforeToolCall: async ({
toolName,
args,
}: {
toolName: string;
args: Record<string, unknown>;
}) => {
if (toolName === "issue_refund" && Number(args.amount) > 1000) {
throw new Error("זיכוי מעל 1000 ש\"ח דורש אישור אנושי לפני ביצוע");
}
},
};
const agent = createAgent({
model: "anthropic:claude-sonnet-5",
tools: [getWeather, issueRefundTool],
middleware: [approvalMiddleware],
});