דלג לתוכן הראשי

תפעול סוכני AI ומישורי בקרה

שליטה מלאה בניהול, מעקב ובטיחות של סוכני בינה מלאכותית

32 שעות
קורס מתקדם
8 מודולים

מה תלמד בקורס זה

הבנת ארכיטקטורה של סוכני AI ומושגי בקרה מרכזיים
יכולת לתכנן ולהטמיע מישורי בקרה (Control Planes) מורכבים
ניהול מעקב, logging ו-observability של סוכנים בסביבת ייצור
יישום מנגנוני בטיחות, הרשאות ומגבלות על סוכנים חכמים
1

יסודות סוכני AI ובקרה

משך המודול

3 שעות

נושאים בקורס

מבוא לסוכנים אוטונומיים ומקרי שימוש
ארכיטקטורה של סוכני AI - components ויחסים
מושגי בקרה: Governance, Policy, Enforcement
השוואה בין סוגי בקרה שונים

מבוא למודול

סוכני AI אוטונומיים הם אחד מהטרנדים החזקים ביותר בתעשייה כיום. מ-customer support עד supply chain optimization, סוכנים אלה פועלים בעצמאות וקוראים החלטות בזמן אמת. אך עם עצמאות רבה באה אחריות גדולה — וזו בדיוק תפקידה של בקרה.

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

נלמד על ארכיטקטורה של סוכנים, על הדרגות השונות של אוטונומיה, וגם מה ההבדל בין governance (מנהלויות) לבין control (בקרה משפיעה). זה הבסיס עליו מתבנים כל המודולים הבאים.

אדריכלות סוכנים — רכיבים מרכזיים

כל סוכן AI מורכב מכמה רכיבים ליבה. ראשית, יש לו מודל — זה יכול להיות LLM כמו GPT-4 או Llama, או מודל מיוחד שהוכשר עבור משימה ספציפית. שנית, יש לו perception — יכולת לתפוס את המצב בעולם דרך חיישנים או APIs. שלישית, יש לו action — היכולת לבצע פעולות כמו שליחת מידע, עדכון בסיסי נתונים, או הפעלת מכשירים.

הרכיב הרביעי, והחשוב ביותר עבורנו, הוא ה-decision-making engine — המוח שמחליט מה לעשות בהינתן מצב מסוים. וגם כאן נכנסת בקרה: לא נרצה שהסוכן בוחר כל דבר שהוא רוצה. נרצה שהוא יבחור דברים שנכונים עבור הארגון, בטוחים, ותוך שמירה על עלויות.

// דוגמה: ארכיטקטורה בסיסית של סוכן AI const AgentArchitecture = { perception: { sensors: ["API calls", "Database queries", "Real-time events"], context: "Current state of the world" }, cognition: { model: "LLM (GPT-4, Claude, Llama)", memory: "Short-term (context), Long-term (vector DB)", reasoning: "Chain-of-thought, reflection loops" }, control: { policies: "Rules defining what agent can do", constraints: "Resource limits, approval workflows", monitoring: "Real-time observation of decisions" }, action: { executors: ["API calls", "Database updates", "Messages"], feedback: "Outcomes and error handling" } }; // Governance vs Control const Governance = "WHO decides WHAT the agent can do" const Control = "HOW we make sure the agent does ONLY that"

טיפ חשוב

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

סוגי בקרה ודרגות אוטונומיה

לא כל סוכנים חייבים להיות באותה רמת אוטונומיה. SAE (Society of Automotive Engineers) הגדיר 6 דרגות של אוטונומיה למכוניות; אנחנו יכולים להשתמש בהגדרה דומה לסוכנים. Level 0 הוא "ללא אוטונומיה" — אדם עושה הכל. Level 5 הוא "אוטונומיה מלאה" — הסוכן עושה הכל בכל נסיבות.

בעולם של סוכני AI, רוב המקרים ימצאו את עצמם בין Levels 2-4. Level 2 היא "חצי אוטונומיה" — הסוכן מוציא מלמחשבה אבל אדם מאשר. Level 3 היא "מותנית" — הסוכן עושה לבד בדברים שגרתיים, אבל מבקש עזרה בעניינים מורכבים. Level 4 היא "גבוהה" — הסוכן עשוי לעשות הכל לבד, אם כי עם ערנות כלשהי.

סוגי בקרה שונים כוללים: Preventive (מניעה מראש — לא מאפשרים משהו בעיקרון), Reactive (תגובה לאחר־כדי — הסוכן עשה משהו לא בסדר, חוזרים בו), ו-Predictive (חיזוי — אם זה יוביל לבעיה, עצרו ועברו לדיוני אחרים).

// דוגמה: מודל דרגות אוטונומיה וסוגי בקרה const AutonomyLevels = { level0: { name: "ללא אוטונומיה", example: "אדם מפעיל את הסוכן לכל אקשן", control: "Preventive + Reactive (אדם מחליט הכל)" }, level2: { name: "חצי אוטונומיה", example: "סוכן מייצר הצעות, אדם מאשר", control: "Preventive (מה מותר לבחור) + Reactive (אישור סופי)" }, level3: { name: "אוטונומיה מותנית", example: "סוכן עושה דברים שגרתיים בעצמו", control: "Preventive (דברים שגרתיים מקודמים בעיקרון) + Predictive (מעקב אחרי תוצאות)" }, level4: { name: "אוטונומיה גבוהה", example: "סוכן עושה הכל, אבל עם צפייה", control: "Predictive (צפייה בדפוסים משונים) + Reactive (כשמשהו לא בסדר)" } }; // Preventive Control Example const PreventiveControl = { policy: "סוכן customer-service אינו רשאי לשנות מחירי מוצרים", implementation: "API endpoint שמעדכן מחירים לא מקבל קריאות מסוכן זה" }; // Reactive Control Example const ReactiveControl = { policy: "אם סוכן ביצע החלטה שגויה, תן למשתמש אפשרות לעקוף", implementation: "Undo mechanism, approval request system" }; // Predictive Control Example const PredictiveControl = { policy: "צפה בתבניות של החלטות שגויות ובצע בדיקות מראש", implementation: "ML model שמנבא אם החלטה היא סיכון גבוה, גרימה בקשת אישור" };

Governance vs Control vs Compliance

שלושת המונחים הללו מעלים בלבול, אבל הם שונים. Governance עוסקת בשאלה: "מי החליט מה מותר?" זה קיבול החלטות ברמה ארגונית — מנהלים קובעים מדיניות, חוקים, ותחומי סמכות. Control עוסקת בשאלה: "איך משיגים שעובדים בפועל?" זה המנגנונים הטכניים שמוודאים שסוכנים עושים בדיוק את מה שקבוע להם. Compliance עוסקת בשאלה: "האם התוצאה תואמת לכללים?" זה הבדיקה והדיווח.

בקורס זה נתמקד בעיקר בשניים הראשונים — governance (קביעת המדיניות) ו-control (יישום מחקק של המדיניות). אבל compliance חשוב לשם הם מחוברים — אתה צריך להוכיח שמה שהסוכן עושה בפועל תואם את מה שקבעת שהוא צריך לעשות.

בסוף מודול זה תוכל:

  • ✓ להסביר את ההבדל בין סוכן אוטונומי לבקרה
  • ✓ לתאר רכיבים ליבה של ארכיטקטורה של סוכן
  • ✓ לזהות את דרגת האוטונומיה המתאימה למקרה שימוש
  • ✓ להבדיל בין Governance, Control, ו-Compliance
  • ✓ להבחין בין Preventive, Reactive, ו-Predictive control
2

ديزיין מישורי בקרה

משך המודול

4 שעות

נושאים בקורס

Management Plane - ניהול מעגל חיים של סוכנים
Control Plane - הגדרת ותכיפות מדיניות
Data Plane - ביצוע פעולות ותקשורת
Security Plane - אמון ואימות

מהו מישור בקרה (Control Plane)?

מישור בקרה הוא ארכיטקטורה שנוצרה כדי לנהל וללוות מערכות מורכבות. המונח עצמו בא מרשתות תקשורת וKubernetes, אבל הוא משתלם במיוחד לסוכני AI. הרעיון הוא לחלק את המערכת לכמה "מישורים", כל אחד עם אחריות ברורה.

ארבעת המישורים הקלאסיים הם: Management (ניהול כללי), Control (קביעת כללים), Data (ביצוע בפועל), ו-Security (אבטחה). בקורס זה נתמקד בכל אחד מהם בהעמקה, וגם נראה איך הם מחוברים זה לזה. פעם אחת שתבין את ארבעת המישורים הללו, תוכל לתכנן מערכת בקרה חזקה וניתנת להרחבה עבור כמעט כל סוג של סוכנים.

Management Plane — ניהול מעגל חיים

ה-Management Plane עוסקת בשאלות ארגוניות גדולות. איך הסוכן נוצר? איך הוא משודרג? איך הוא מושבת? זה המישור שבו מנהלי מערכות וmultiple engineers מתמודדים עם lifecycle ארוך של סוכנים. כאן קיימות תיעוד פרויקטים, חלוקת משאבים, ותכנון קיבולת.

בפרט, ה-Management Plane דואגת לכך שנוכל לשדרג סוכנים בבטחה (ללא downtime), לסיים את חייהם כשהם לא נדרשים עוד, להקצות משאבים כך שלא יהיה congestion, ולנהל versions שונות של אותו סוכן בו-זמנית (כמו running v1.2 ו-v1.3 באותה עת עם gradual rollout).

// Management Plane: Lifecycle Management class AgentLifecycleManager { constructor() { this.agents = new Map(); } // Creation createAgent(agentConfig) { const agentId = generateUUID(); const agent = { id: agentId, config: agentConfig, version: "1.0.0", status: "created", // created, deployed, running, paused, terminated deployedAt: null, createdAt: new Date(), resources: { cpu: "1", memory: "2Gi", storage: "10Gi" } }; this.agents.set(agentId, agent); return agentId; } // Versioning & Deployment deployAgentVersion(agentId, newVersion) { const agent = this.agents.get(agentId); agent.version = newVersion; agent.status = "deploying"; // Blue-Green deployment: run old and new in parallel return { blueDeployment: agent.version - 1, greenDeployment: newVersion, trafficSplit: { blue: 90, green: 10 } // Start with 10% traffic to new }; } // Scaling scaleAgent(agentId, replicas) { const agent = this.agents.get(agentId); agent.replicas = replicas; agent.resources.memory = `${replicas}Gi`; // Scale memory accordingly return { agentId, replicas, memoryAllocated: agent.resources.memory }; } // Termination terminateAgent(agentId) { const agent = this.agents.get(agentId); agent.status = "terminated"; agent.terminatedAt = new Date(); // Graceful shutdown: allow in-flight requests to complete return { agentId, status: "terminating", gracefulTimeout: "30s" }; } }

Control Plane — הגדרת כללים ומדיניות

ה-Control Plane היא הלב של מערכת הבקרה שלנו. כאן מגדירים את הכללים והמדיניות שיסדירו את ההתנהגות של הסוכנים. זו הרמה בה מנהלי מדיניות (policy managers), security officers, ו-compliance specialists עובדים.

Control Plane מגדירה דברים כמו: "סוכן פרסום אינו רשאי להציג מודעות לקטינים", "החלטות הקשורות למכירה מעל $10,000 דורשות אישור אנושי", "סוכן לא רשאי לגשת לנתוני אשראי של לקוחות מאזור מסוים". כללים אלה מוקדשים לתוך מערכת, ובדרך כלל מומשים דרך Enforcement Engine בData Plane.

Control Plane גם מטבעה לא-סטטית. כשמדיניות משתנה (חברה משנה את מנהגה, או רגולציה חדשה נכנסת), ניתן לעדכן את הכללים בלי שצריך לעצור את כל הסוכנים. זה יתרון ענק על הקודדינג של ההגבלות ישירות לקוד הסוכן.

// Control Plane: Policy Definition Engine class PolicyEngine { constructor() { this.policies = new Map(); } // Define a policy definePolicy(policyId, policyConfig) { const policy = { id: policyId, name: policyConfig.name, description: policyConfig.description, scope: policyConfig.scope, // e.g., "sales_agent", "all_agents", "customer_support" rules: policyConfig.rules, // Array of rules enforcementMode: policyConfig.enforcementMode, // "block", "warn", "approve" createdAt: new Date(), updatedAt: new Date(), version: "1.0.0" }; this.policies.set(policyId, policy); return policyId; } // Example policy examplePolicy() { return { id: "pol_high_value_tx", name: "High-Value Transaction Approval", scope: "transactions_agent", rules: [ { condition: "transaction.amount > 10000", action: "require_human_approval", approvers: ["finance_manager", "cfo"], timeout: "24h" }, { condition: "transaction.amount > 50000", action: "block_immediately", notifyTeam: ["compliance", "security"] }, { condition: "transaction.destination_country == 'restricted'", action: "block_immediately", reason: "Sanctions compliance" } ], enforcementMode: "block" // Don't even allow the transaction to proceed }; } // Update policy updatePolicy(policyId, updates) { const policy = this.policies.get(policyId); Object.assign(policy, updates); policy.updatedAt = new Date(); policy.version = this.incrementVersion(policy.version); return policy; } // Versioning incrementVersion(version) { const [major, minor, patch] = version.split('.').map(Number); return `${major}.${minor}.${patch + 1}`; } // Policy evaluation: Should an action be allowed? evaluatePolicy(agentId, action, context) { const applicablePolicies = Array.from(this.policies.values()) .filter(p => p.scope === "all_agents" || p.scope === agentId); for (const policy of applicablePolicies) { for (const rule of policy.rules) { if (this.evaluateCondition(rule.condition, context)) { return { allowed: rule.action !== "block_immediately", action: rule.action, policy: policy.name, rule: rule }; } } } return { allowed: true, reason: "No blocking policies apply" }; } evaluateCondition(condition, context) { // This is a simplified version; in reality, use a proper expression evaluator return eval(condition); // In production, use a safe expression language! } }

חשוב: שפות מדיניות

כשמתכננים Control Plane, בחרו בשפה לציון מדיניות שפשוטה, מהנדסים יכולים לתחזוקה, ובעלי עסק יכולים להבין. דוגמאות: OPA/Rego, Cedar (מ-AWS), או YAML בעיצוב משלכם. הימנעו מלשפות מורכבות מדי — מדיניות צריכה להיות ברורה וקלה לביקורת.

Data Plane — ביצוע ותקשורת

ה-Data Plane היא שם חם של פעולות. כאן הסוכנים בפועל פועלים, מחשבים, וקוראים החלטות. זה גם המקום בו אנחנו מיישמים את המדיניות שהוגדרה בControl Plane. ה-Data Plane כוללת את הסוכנים עצמם, את המנוע שלהם ל-inference, ואת כל ה-APIs והשירותים שהם קוראים אליו.

בעיצוב של Data Plane, אנחנו חושבים על דברים כמו: איך הסוכן קורא ל-policy engine כדי לווידוא שהחלטתו מותרת? איך הוא תומך retractions אם הוא בחר משהו לא בסדר? איך הוא מעביר דיווח לחזרה ל-Management Plane? זה גם המקום בו אנחנו עשויים לבצע caching (כדי להאיץ דברים) ו-rate limiting (כדי להגן על משאבים).

בחירה של Data Plane צריכה לקחת בחשבון: latency (כמה מהר הסוכן צריך לפעול?), throughput (כמה סוכנים באותו זמן?), fault tolerance (מה קורה אם משהו נשבר?), ו-cost (כמה יוקר זה לשדר?). שונות כמו edge deployment (סוכנים בקרוב לנתונים) לעומת centralized (כל הסוכנים בנחלת אחד) צריכות שיקול.

Security Plane — אמון ואימות

Security Plane היא הבעיה הרביעית, אבל כמו כל אבטחה, היא אינה אפשרות — היא חובה. כאן אנחנו מטפלים בשאלות כמו: "איך נודע שהסוכן הוא באמת סוכן וקיבול לחתום על בקשות?" (Authentication), "איך נודע שלסוכן יש רשות לבצע פעולה מסוימת?" (Authorization), "איך אנחנו מנקים שגויויות?" (Audit), וגם "איך אנחנו מגנים על סוכן מפני התקפות?" (Security).

ברמה הפרקטית, Security Plane מיישמת דברים כמו: mutual TLS (mTLS) בין סוכנים והשירותים שהם קוראים אליו, API keys ו-tokens שמחדשים בקביעות, audit logs של כל החלטה שהסוכן עשה, ו-encryption של נתונים בעברות (both in transit and at rest).

חלק חשוב של Security Plane הוא גם "Sandboxing" — הפרדה בין סוכנים כך שסוכן "רע" לא יכול להשפיע על אחרים. בתוך Kubernetes, זה יכול להיות Network Policies או Pod Security Policies. בתוך LLM, זה יכול להיות הגבלת ה-functions שהסוכן רשאי לקרוא אליהן.

// Security Plane: Authentication & Authorization class SecurityPlane { constructor() { this.agents = new Map(); this.permissions = new Map(); } // Register agent with cryptographic identity registerAgent(agentId, agentConfig) { const agent = { id: agentId, publicKey: generatePublicKey(), privateKey: generatePrivateKey(), // Stored securely (e.g., in Vault) certificate: issueCertificate(agentId), permissions: [], createdAt: new Date(), lastRotatedAt: new Date() }; this.agents.set(agentId, agent); return agent.publicKey; } // Define roles and permissions defineRole(roleId, permissions) { this.permissions.set(roleId, { id: roleId, permissions: permissions, // e.g., ["read:database", "write:api", "execute:functions"] createdAt: new Date() }); } // Assign role to agent assignRoleToAgent(agentId, roleId) { const agent = this.agents.get(agentId); const role = this.permissions.get(roleId); agent.roles = agent.roles || []; agent.roles.push(roleId); return { agentId, roleId, permissions: role.permissions }; } // Authenticate: Verify agent signature authenticateRequest(agentId, request, signature) { const agent = this.agents.get(agentId); const isValid = verifySignature(request, signature, agent.publicKey); if (!isValid) { return { authenticated: false, reason: "Invalid signature" }; } // Check if certificate is not expired if (agent.certificate.expiresAt < new Date()) { return { authenticated: false, reason: "Certificate expired" }; } return { authenticated: true, agentId, roles: agent.roles }; } // Authorize: Check if agent has permission for action authorizeAction(agentId, action) { const agent = this.agents.get(agentId); const allPermissions = agent.roles .flatMap(roleId => this.permissions.get(roleId).permissions); const isAuthorized = allPermissions.includes(action); return { authorized: isAuthorized, agentId, action, reason: isAuthorized ? "Permission granted" : "Permission denied" }; } // Audit Log logAction(agentId, action, result, context) { const auditEntry = { timestamp: new Date().toISOString(), agentId, action, result, // "success" or "failure" context, // What was the request? What was the response? ipAddress: context.ipAddress, userId: context.userId // If human approved/initiated }; // Store in audit database this.storeAuditLog(auditEntry); return auditEntry; } // Rotate credentials rotateAgentCredentials(agentId) { const agent = this.agents.get(agentId); agent.privateKey = generatePrivateKey(); agent.publicKey = generatePublicKey(); agent.certificate = issueCertificate(agentId); agent.lastRotatedAt = new Date(); return { agentId, newPublicKey: agent.publicKey }; } } // Audit Logging Example const AuditLogEntry = { timestamp: "2025-01-15T10:23:45Z", agentId: "agent_sales_001", action: "create_order", result: "success", context: { orderId: "ord_12345", amount: 5000, customerId: "cust_67890", approvedBy: "user_admin_001" } };

בסוף מודול זה תוכל:

3

תפעול וניהול סוכנים בייצור

משך המודול

3.5 שעות

נושאים בקורס

Deployment ו-Scaling של סוכנים
Health checks, heartbeats ו-self-healing
Resource management ו-cost optimization
Update strategies: Blue-Green, Canary, Rolling

Deployment וScaling — מעבר לייצור

כשאתה מוכן להוציא סוכן לייצור, צריך תוכנית מפורשת. לא פשוט "להדליק ולתקווה הטוב". צריך deployment strategy, rollback plan, ודרך למעקב שהכל עובד. בחלק זה של הקורס, נדברת על אסטרטגיות כמו Blue-Green (שתי סביבות זהות, אתה מעביר תנועה מ-blue ל-green), Canary (תחילה 1% תנועה לגרסה חדשה, אם הכל בסדר הגדל ל-10%, וכו'), ו-Rolling (סדרתי, סוכן אחד בזמן).

Scaling היא גם ממש חשובה. אם יש לך כמות גדולה של בקשות, אתה צריך להיות מסוגל להעלות עוד instances של הסוכן. במערכות מודרניות (מבוססות Kubernetes), זה בדרך כלל אוטומטי: אתה מגדיר "אם CPU עולה מעל 70%, הוסף עוד instance", וKubernetes עושה את זה בעבורך. אבל צריך להבין את ה-tradeoffs: יותר instances = יותר עלות, אבל גם יותר עכזבות.

עבור סוכנים שמריצים LLMs, scaling היא גם יותר מורכבת. LLM server (כמו vLLM או Ollama) יכול להיות יקר מבחינת זיכרון וCPU, ויש הנחות על batching (טובעים בקשות ביחד כדי להשתמש בGPU ביעילות יותר). אתה צריך לחשוב על הא בחזקה.

// Deployment & Scaling Strategy class DeploymentManager { constructor() { this.deployments = new Map(); } // Blue-Green Deployment blueGreenDeploy(agentId, newVersion) { const deployment = { agentId, strategy: "blue_green", blue: { version: "1.0.0", replicas: 5, status: "serving" }, green: { version: newVersion, replicas: 5, status: "warming_up" }, switchPoint: null }; // Step 1: Deploy green in parallel deployment.green.status = "warming_up"; // Step 2: Run smoke tests on green const testsPass = this.runSmokeTests(deployment.green); if (testsPass) { // Step 3: Switch 100% traffic to green deployment.green.status = "serving"; deployment.blue.status = "standby"; deployment.switchPoint = new Date(); // Step 4: After stability period, remove blue setTimeout(() => { deployment.blue.status = "terminated"; }, 30 * 60 * 1000); // Keep blue for 30 minutes } else { // Rollback: terminate green deployment.green.status = "terminated"; return { success: false, reason: "Smoke tests failed" }; } return deployment; } // Canary Deployment canaryDeploy(agentId, newVersion) { const deployment = { agentId, strategy: "canary", stable: { version: "1.0.0", replicas: 10, trafficPercentage: 100 }, canary: { version: newVersion, replicas: 1, trafficPercentage: 0 }, schedule: [] }; // Gradual rollout schedule deployment.schedule = [ { time: "0min", traffic: 1 }, // 1% to canary { time: "10min", traffic: 5 }, // 5% to canary { time: "30min", traffic: 10 }, // 10% to canary { time: "1hour", traffic: 25 }, // 25% to canary { time: "2hour", traffic: 50 }, // 50% to canary { time: "4hour", traffic: 100 } // 100% to canary ]; this.executeCanarySchedule(deployment); return deployment; } // Auto-Scaling based on metrics autoScale(agentId, metrics) { const { cpuUsage, memoryUsage, requestsPerSecond } = metrics; const targetReplicas = Math.ceil(requestsPerSecond / 100); // Assume each replica can handle 100 RPS if (cpuUsage > 80) { return { action: "scale_up", newReplicas: targetReplicas + 2, reason: "High CPU" }; } else if (cpuUsage < 20 && targetReplicas > 1) { return { action: "scale_down", newReplicas: Math.max(1, targetReplicas - 1), reason: "Low CPU" }; } return { action: "no_change", currentReplicas: targetReplicas }; } runSmokeTests(deployment) { // Simple smoke tests const tests = [ () => deployment.health === "healthy", () => deployment.latency < 500, // ms () => deployment.errorRate < 1 // % ]; return tests.every(test => test()); } executeCanarySchedule(deployment) { deployment.schedule.forEach(step => { setTimeout(() => { deployment.canary.trafficPercentage = step.traffic; deployment.stable.trafficPercentage = 100 - step.traffic; console.log(`Canary: ${step.traffic}% traffic to new version`); }, this.parseTime(step.time)); }); } parseTime(timeStr) { // Convert "10min", "1hour" to milliseconds const mapping = { "min": 60 * 1000, "hour": 60 * 60 * 1000, "day": 24 * 60 * 60 * 1000 }; for (const [unit, ms] of Object.entries(mapping)) { if (timeStr.includes(unit)) { const num = parseInt(timeStr); return num * ms; } } return 0; } }

Health Checks וSelf-Healing

סוכן בייצור צריך להיות "self-aware" — להבין את עצמו אם הוא עובד. זה קורה דרך health checks. בדרך כלל, מנהל אורכסטרציה (כמו Kubernetes) מבחן בקבע: "האם הסוכן עדיין תגובה?" אם לא, הוא אומר "בואו נהרוג את התהליך ונתחיל מחדש", או "בואו נעביר את התנועה לעותק אחר".

heartbeat הוא mechanic קל: הסוכן שולח כל כמה שניות לומר "אני בחיים!" לrouter מרכזי. אם ה-router לא מקבל heartbeat במשך זמן מנויים (נגיד 30 שניות), הוא מניח שהסוכן מת וכושל. self-healing פירוש שהמערכת עושה דברים בעצמה כדי להתאושש — הצעה חדשה של הסוכן, ניקוי של זיכרון נדיפים, וכו'.

ויש גם orchestration-level healing: אם סוכן כשל במהרה 5 פעמים ברציפות, אל תשחזור עוד, פשוט תן עלות וודא שנשים בעיה. זה נקרא "circuit breaker" pattern.

Resource Management וCost Optimization

סוכנים תורמים עלויות: servers, GPU (אם משתמשים LLM), bandwidth, storage. על מנהלים להיות חכמים בניהול משאבים. דברים כמו Resource Requests (Kubernetes: "סוכן זה צריך לפחות 2GB RAM") ו-Resource Limits ("אבל לא יותר מ-8GB") עוזרים לא להשלות מכונה אחת בעודפות.

ניתוב פנימי של בקשות יכול גם לעזור. אם בקשה פשוטה לא צריכה full GPU, שלח אותה לCPU-only instance כדי לחסוך בעלויות GPU. אם בקשה נדירה דורשת GPU קשה, קק לה וטיפול עדיפות.

ריכוך תקציב גם חשוב: בצע כל חודש דוח על עלויות לפי סוכן, מצא את הבזבזנים, ושתתוו על הם קמעא. cloud providers (AWS, GCP, Azure) מספקים כלים כמו Cost Explorer ו-Budgets Alerts כדי לעזור בזה.

טיפ מעשי: Spot Instances

אם הסוכן שלך יכול להיתקל בעיכובים קטנים (כמו 2-3 דקות בזמן סיום של משימה), שקול לרוץ על Spot Instances (AWS) או Preemptible VMs (GCP). הם זולים 70% יותר מ-On-Demand, אך ענן יכול להשהות אותם בהודעה קצרה. דברים כמו batch processing, backtesting, וtraining עשויים להיות טובים לזה.

Update Strategies בעומקים

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

Blue-Green: הנדוש והבטוח

יש לך שתי סביבות זהות (blue ו-green). Blue משרת תנועה "real", green חומיות בקביעות רק תנועה בדיקה. כשאתה מוכן לעדכון, אתה מפרסם את הגרסה החדשה ל-green, מריץ בדיקות, ואחרי כן משנה את routing כך שכל התנועה ל-green. אם משהו נשבר, תחזור ל-blue מיד — זה קל, כי blue עדיין רץ.

חסרון: יקר. אתה צריך להשלים סביבות זהות, כך שהעלויות כפולות

Canary: עמידה בזהירות

התחל עם 1% תנועה לגרסה החדשה. אם הכל בסדר לפי מטריקות (latency, error rate), הגדל ל-5%, אחרי כן ל-10%, וכו'. אם בכל שלב ראית בעיה, תחזור לגרסה הישנה.

יתרון: מגנון בכניסה, תוך זיהוי מהיר של בעיות. חסרון: יש לך שני גרסאות רצות, אבל שיתוף משאבים יכול להקטין עלויות בהשוואה לBlue-Green.

Rolling: פירוש בהדרגה

אתה מפסיק את הגרסה הישנה בהדרגה ותוך כדי מתחיל את החדשה. תחילה, תחזיק 4 מתוך 5 instances של גרסה ישנה ו-1 של חדשה. אחרי כן 3+2, אחרי כן 2+3, וכו'.

יתרון: משאבים יציבים — אתה לא צריך כפל. חסרון: מורכב, קצת יותר הולך לזמן (אתה צריך להמתין בין כל "גל").

בסוף מודול זה תוכל:

4

Monitoring, Logging ו-Observability

משך המודול

3.33 שעות

נושאים בקורס

Setup של Observability Stack לסוכנים
Metrics חיוניות: latency, throughput, error rates
Distributed tracing בין סוכנים
Alerting ו-incident response automation

Observability vs Monitoring — הבדל חשוב

אנשים רבים משתמשים במילים "monitoring" ו"observability" כחליפה, אך הם לא בדיוק אותו הדבר. Monitoring הוא בדיקה של דברים שאתה מצפה כבר לראות — "האם ה-HTTP status 200?" או "האם CPU נמוך מ-80%?" observability הוא היכולת לשאול שאלות חדשות על מערכת שלך בלי שצריך לשנות קוד. "למה בקש זה לקח 5 שניות?" אתה יכול לחפור עומק לתוך logs ו-traces כדי להבין.

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

ה-three pillars של observability הם: Metrics (מדידות מספריות), Logs (רצפי טקסט), ו-Traces (שטחות של בקשה דרך מערכת). יחד, הם נותנים לך תמונה מלאה.

// Observability Stack Setup for Agents class ObservabilityStack { constructor() { this.metrics = []; this.logs = []; this.traces = []; } // Metrics Collection (using Prometheus format) recordMetric(metricName, value, labels = {}) { const metric = { name: metricName, value, labels, // e.g., { agent_id: "agent_123", action: "classify" } timestamp: Date.now() }; this.metrics.push(metric); // In real setup, send to Prometheus console.log(`METRIC: ${metricName} = ${value}`, labels); } // Key Metrics for AI Agents recordAgentMetrics(agentId, context) { // Latency: How long did the agent take? this.recordMetric("agent.latency_ms", context.duration, { agent_id: agentId, action: context.action }); // Throughput: How many requests per second? this.recordMetric("agent.requests_per_second", context.rps, { agent_id: agentId }); // Error Rate: What percentage failed? this.recordMetric("agent.error_rate", context.errorRate, { agent_id: agentId }); // Token Usage: How many tokens did the LLM use? if (context.tokensUsed) { this.recordMetric("agent.tokens_used", context.tokensUsed, { agent_id: agentId, model: context.model }); } // Decision Time: How long to make a decision? this.recordMetric("agent.decision_time_ms", context.decisionTime, { agent_id: agentId }); // Approval Rate: How many decisions needed human approval? this.recordMetric("agent.approval_rate", context.approvalRate, { agent_id: agentId }); } // Structured Logging log(level, message, context = {}) { const logEntry = { timestamp: new Date().toISOString(), level, // "info", "warn", "error", "debug" message, context, // Add structured data traceId: context.traceId // Link to trace }; this.logs.push(logEntry); console.log(JSON.stringify(logEntry)); } // Distributed Tracing: Track a request through multiple services createTrace(traceId, requestId) { return { traceId, requestId, spans: [], startTime: Date.now() }; } addSpan(trace, spanName, startTime, endTime, attributes = {}) { trace.spans.push({ name: spanName, startTime, endTime, duration: endTime - startTime, attributes }); } exampleTrace() { const traceId = "trace_12345"; const requestId = "req_67890"; const trace = this.createTrace(traceId, requestId); // Span 1: Agent receives request this.addSpan(trace, "agent.receive_request", 0, 10, { agent_id: "agent_sales_001", action: "classify_lead" }); // Span 2: Agent calls LLM this.addSpan(trace, "llm.inference", 10, 250, { model: "gpt-4o", tokens: 150 }); // Span 3: Agent evaluates policy this.addSpan(trace, "policy.evaluate", 250, 270, { policy_id: "pol_lead_quality" }); // Span 4: Agent writes to database this.addSpan(trace, "database.write", 270, 290, { table: "leads", operation: "insert" }); // Span 5: Agent sends response this.addSpan(trace, "agent.send_response", 290, 300, { status: "success" }); return trace; } } // Example Metrics const KeyAgentMetrics = { latency: "How long until the agent responds?", throughput: "How many requests per second?", error_rate: "What % of requests fail?", token_usage: "How many LLM tokens consumed?", decision_time: "Time to make a decision (excluding I/O)", policy_violations: "How many times was a policy violated?", approval_rate: "What % of decisions needed human approval?", cost_per_request: "Average cost per request (tokens, compute)", hallucination_rate: "What % of responses had hallucinations?" };

Distributed Tracing בין סוכנים

כשיש לך סוכנים מרובים שעובדים ביחד (multi-agent systems), ישנה סכנה שבקשה תחליק ביניהם בלא שיודע. Distributed tracing עוזרת לעקוב אחרי בקשה כשהיא עוברת מסוכן לסוכן, שירות לשירות. כל קטע של העבודה מתויג כ"span", וביחד הם יוצרים "trace".

כלים כמו Jaeger ו-Zipkin הם קלאסיים. הם מסתכלים בכל ה-spans ויוצרים waterfall diagram שמראה היכן בזבזו זמן. "אה, סוכן A קרא לסוכן B, וסוכן B חכה 3 שניות לתשובה מAPI חיצוני" — דברים כאלה קלים לראות בtraces.

OpenTelemetry היא התקן הקדום כיום. זה ספרייה שמקלה על שליחה של metrics, logs, וtraces לכל destination (Datadog, New Relic, Prometheus, וכו'). זה מסיר coupling בין קוד שלך לבין observability backend.

Alerting ו-Incident Response

ניטור הוא טוב, אבל אם אתה לא תגיד לאדם על בעיה, מה התועלת? Alerting היא המקום שבו metrics הופכות לפעולה. אתה מגדיר rules: "אם error rate עלה מעל 5%, שלח לי Slack". "אם latency p95 גבוה מ-1 שנייה, פתח issue ב-GitHub". "אם agent crashed 3 פעמים ברציפות, trigger ל-PagerDuty וגרום למהנדס לעירור מהשינה".

incident response automation פירוש שהמערכת עושה דברים בעצמה כשמשהו נשבר. "Error rate גבוה? בואו נחזור לגרסה הישנה." "Latency גבוה? בואו נשדרג." "Agent crashed? בואו נתחיל מחדש." זה מקטין את MTTR (Mean Time To Recovery) — כמה מהר אתה חוזר לנורמל.

כלים כמו Prometheus Alertmanager, Datadog, ו-PagerDuty משמשים. אבל החשוב ביותר הוא להגדיר alerts שיותר אינטליגנטיים — לא "trigger on every anomaly" (כי אחרי כן תתרגל להם), אלא "trigger only if this is bad enough to require human action".

Alert Fatigue

אם יש לך יותר מדי alerts, מהנדסים יתחילו להתעלם מהם (הידע כ-"alert fatigue"). הקפד על איכות alerts: trigger רק אם זה באמת חשוב, תן context מהיר (מה קרה? למה זה רע?), ותן טיפים לפתרון ("spikes usually resolve themselves in 2-3 minutes, או "check XYZ for common issues").

בסוף מודול זה תוכל:

5

בטיחות והרשאות בבקרה

משך המודול

3.33 שעות

נושאים בקורס

Authentication ו-Authorization עבור סוכנים
Role-Based Access Control (RBAC) לפעולות
Audit logging וגילוי חריגויות
Sandboxing ו-isolation של סוכנים

Authentication: "Who Are You?"

מחבור שלך צריך לדעת: "מי זה הסוכן שקורא לי?" זה authentication. סוכנים, כמו אנשים, צריכים להוכיח זהות. בעיות רבות עולות אם אתה לא עושה זה נכון — סוכן זומם יכול להתחזות לסוכן אחר, זריבה או חולה מתוך בקרה יכול לעשות דברים בשמך.

דרכים יש אחדות. API Keys הן פשוטות אך חלשות (אם מישהו גונב את המפתח, הוא בעיה). OAuth 2.0 ו-OpenID Connect הן טובות יותר, מכיוון שהן מאפשרות קשר עם identity provider מרכזי. Mutual TLS (mTLS) היא חזקה ביותר — כל צד (סוכן וחומר הרשתות) חתום על תעודה דיגיטלית ומאומת כזה לזה.

עבור סוכנים בייצור, אנחנו בדרך כלל מומלץ mTLS או token-based (JWT) כזה חתום. חשוב לעיתים גם ל-rotate credentials — אם מישהו גנב מפתח, בעבור כמה זמן הוא תקף? אחרי כמה ימים, החלפו אותו.

Authorization: "What Can You Do?"

Authentication אומרת מי אתה. Authorization אומרת מה אתה יכול לעשות. זה לעתים קרובות לא משהו פשוט בינארי (yes/no), אלא ביצוע של תביעות. "סוכן_sales_001 יכול לקרוא leads מבסיס נתונים, אבל לא להוציא אותם. הוא יכול לעדכן status, אבל לא לעדכן מחיר." בעזרת Role-Based Access Control (RBAC), אתה מגדיר roles (e.g., "sales_agent", "finance_auditor"), וכל role יש לו קבוצה של permissions (e.g., "read:leads", "write:lead_status").

באחרונה, Attribute-Based Access Control (ABAC) הופכת פופולרית יותר — במקום roles קשורות, אתה כותב כללים בהתאם לattributes: "אם (agent.department == 'sales' AND time_of_day == 'business_hours'), אז allow read:customer_data". זה קל מפעם לנהל מורכבות.

עבור סוכנים, important is the fact that permissions change dynamically. אם סוכן נוצר באותה שנייה, אל תתן לו הרשאות עד שהוא "approved". אם סוכן כשל בדרך מרובה, הסר הרשאות מכדי למנוע עוד נזק.

// Authorization: RBAC and ABAC class AuthorizationEngine { constructor() { this.roles = new Map(); this.agents = new Map(); } // Define roles defineRole(roleId, permissions) { this.roles.set(roleId, { id: roleId, permissions: permissions // e.g., ["read:leads", "write:order", "execute:email"] }); } // Assign role to agent assignRole(agentId, roleId) { if (!this.agents.has(agentId)) { this.agents.set(agentId, { id: agentId, roles: [] }); } const agent = this.agents.get(agentId); agent.roles.push(roleId); } // RBAC Check: Does agent have permission? checkPermissionRBAC(agentId, requiredPermission) { const agent = this.agents.get(agentId); if (!agent) return false; for (const roleId of agent.roles) { const role = this.roles.get(roleId); if (role.permissions.includes(requiredPermission)) { return true; } } return false; } // ABAC: Evaluate policies based on attributes evaluateABAC(agentId, action, context) { const agent = this.agents.get(agentId); const policies = [ { id: "policy_business_hours", condition: `agent.department == 'sales' && context.hour >= 9 && context.hour <= 17`, permission: "write:order", effect: "allow" }, { id: "policy_sensitive_data", condition: `action == 'read:ssn' && agent.clearance_level < 3`, permission: "read:customer_ssn", effect: "deny" }, { id: "policy_high_value_approval", condition: `action == 'approve_order' && context.orderAmount > 50000`, permission: "approve_order", effect: "require_human_review" } ]; for (const policy of policies) { if (this.evalCondition(policy.condition, agent, context)) { return { allowed: policy.effect !== "deny", effect: policy.effect, policy: policy.id }; } } return { allowed: true, reason: "No policies restrict this action" }; } evalCondition(condition, agent, context) { // Simplified; use a proper policy language in production return eval(condition); } // Revoke permissions revoke(agentId, roleId) { const agent = this.agents.get(agentId); agent.roles = agent.roles.filter(r => r !== roleId); } } // Example Roles const Roles = { sales_agent: { permissions: [ "read:leads", "write:lead_status", "read:customer_contact", "execute:send_email", "execute:create_followup_task" ] }, finance_agent: { permissions: [ "read:invoices", "write:invoice_status", "read:payments", "read:accounts", "require_approval_for_write" ] }, admin_agent: { permissions: ["*"] // All permissions } };

Audit Logging וגילוי חריגויות

אפילו עם authentication ו-authorization, יש סיכוי שסוכן או גורם אחר יעשו משהו הם לא היו צריכים. Audit logging היא הדרך שלך לתופס זה. כל פעם שסוכן עושה משהו חשוב (read sensitive data, update record, execute action), רישום כניסה נוצר. "בשעה 2:37pm, agent_sales_001 קרא את SSN של customer 12345."

גילוי חריגויות פירוש שאתה אומר למערכת: "זה לא נראה נכון". דוגמה: "agent_sales_001 בדרך כלל קורא 50 leads ביום. היום הוא קרא 5,000. זה חריג." או "agent_finance_001 בדרך כלל כותב לטבלה A. היום הוא כתב 100 times לטבלה B שהוא בדרך כלל לא נוגע. דגל!"

כלים כמו ELK (Elasticsearch, Logstash, Kibana) או Splunk עוזרים לחיפוש ו-analysis של audit logs. ML tools יכול לזהות חריגויות בעצמי בלי שצריך לכתוב כללים קשורים.

Sandboxing וIsolation

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

בKubernetes, זה קורה דרך Network Policies (הגבל תקשורת לצד מוגבל של Pod), Resource Limits (אם סוכן משתמש בכל זיכרון, זה לא יכול להשפיע על זה לצדו), ו-seccomp / AppArmor (הגבל system calls שחדשוי עושה).

עבור LLM-based agents, sandboxing פירוש להגבל את ה-functions שהם יכול לקרוא (agent can only call read_customer_data, not delete_database), וגם להגבל את המודלים שהם יכול להשתמש (מודל יכול לקרוא גדול מדי = עלויות גבוהות, limit זה).

Zero-Trust Principle

בתור מערכת בקרה לסוכנים, אל תניח אפילו סוכנים פנימיים בטוחים. "Zero-Trust" פירוש: מאמתים הכל, יוצא קוד, כל יום. אם סוכן בקש הרשאה, בדקו אותה. לא משנה כמה הוא "פנימי".

בסוף מודול זה תוכל:

6

מגבלות, Guardrails וגיבוי בקרה

משך המודול

3.5 שעות

נושאים בקורס

הגדרת boundaries וmission scope לסוכנים
Implementation של Rate Limiting ו-Resource Quotas
Human-in-the-loop ו-approval workflows
Automatic rollback ו-emergency stops

Guardrails: Keeping Agents in Bounds

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

מגבלות פיזיות: "agent_customer_support יכול רק לקרוא customer profiles ו-FAQ. הוא לא יכול גם לגשת לנתוני payroll או לבצע refunds מעל $100." מגבלות חוקיות: "חוק GDPR אומר שאנחנו לא יכול לשמור נתוני אישיים זמן יותר מ-30 יום — agent צריך להיות מודע לזה."

בעיצוב guardrails, בואו להבדיל בין חוקים קשירים (hardcoded ב-system) לבין חוקים נוזלים (בPolicy Engine שיכול להשתנות). קשירים טובים כי הם לא יכול להיות מובס. נוזלים טובים כי הם קלים לשנות כשneedsים משתנים.

Rate Limiting וResource Quotas

סוכן שנבקר או בתקלה עלול לטלטל משאבים. Rate limiting מגנה על המערכת. "agent_sales_001 רשאי לעשות לפחות 1,000 בקשות ליום, אך לא יותר מ-100 בשעה" — זה מניעה burst usage שעלול להכעיס APIs. Resource quotas דברים דומה עבור זיכרון, CPU, וstorage. "agent X יכול להשתמש עד 4GB RAM, לא יותר."

בפרקטיקה, יש דרכים שונות לעשות זה. Token-bucket algorithm היא קלאסית — כל שנייה, אתה מוסיף "tokens" לbucket. כל בקשה עולה token אחד. אם bucket ריק, ממתין. Simple ו-effective.

עבור LLM-based agents, קוטה גם אומרת "כמה tokens יכול להשתמש ביום?" LLM tokens יקרים — gpt-4o costs ~$0.15 per 1M input tokens. אם סוכן יכול להשתמש בלי מגבלה, חשבון הוא יכול להתפוצץ.

// Rate Limiting and Quotas class RateLimiter { constructor() { this.buckets = new Map(); this.quotas = new Map(); } // Token Bucket Algorithm checkRateLimit(agentId, limit) { if (!this.buckets.has(agentId)) { this.buckets.set(agentId, { tokens: limit, lastRefill: Date.now() }); } const bucket = this.buckets.get(agentId); const now = Date.now(); const timePassed = (now - bucket.lastRefill) / 1000; // seconds // Refill tokens: 1 token per second bucket.tokens = Math.min(limit, bucket.tokens + timePassed); bucket.lastRefill = now; if (bucket.tokens >= 1) { bucket.tokens -= 1; return { allowed: true, tokensRemaining: Math.floor(bucket.tokens) }; } return { allowed: false, reason: "Rate limit exceeded", retryAfter: 1 }; } // Resource Quotas setQuota(agentId, resource, limit) { if (!this.quotas.has(agentId)) { this.quotas.set(agentId, {}); } this.quotas.get(agentId)[resource] = { limit, used: 0 }; } // Check quota checkQuota(agentId, resource, amount) { const agentQuota = this.quotas.get(agentId); if (!agentQuota || !agentQuota[resource]) { return { allowed: true, reason: "No quota set" }; } const quota = agentQuota[resource]; if (quota.used + amount <= quota.limit) { quota.used += amount; return { allowed: true, remaining: quota.limit - quota.used }; } return { allowed: false, reason: `Quota exceeded for ${resource}`, limit: quota.limit, used: quota.used }; } // Example: LLM Token Quota checkTokenQuota(agentId, tokensNeeded) { return this.checkQuota(agentId, "llm_tokens", tokensNeeded); } // Reset quotas daily resetQuotasDaily() { for (const agentQuotas of this.quotas.values()) { for (const resource in agentQuotas) { agentQuotas[resource].used = 0; } } } } // Example Quotas for Different Agents const QuotaExamples = { sales_agent: { requests_per_hour: 100, requests_per_day: 1000, memory_mb: 512, llm_tokens_per_day: 100000 // ~$15/day at GPT-4o pricing }, support_agent: { requests_per_hour: 500, requests_per_day: 5000, memory_mb: 1024, llm_tokens_per_day: 500000 // Higher for support }, research_agent: { requests_per_hour: 10, // Careful, research is resource-intensive requests_per_day: 100, memory_mb: 4096, // Lots of memory for processing llm_tokens_per_day: 1000000 // Expensive, but needed } };

Human-in-the-Loop ו-Approval Workflows

סוכנים חזקים, אבל הם לא מושלמים. לעתים קרובות, משימות חשובות או גדולות צריכות בדיקה אנושית לפני החלתן. זה "Human-in-the-Loop" (HITL). סוכן מרות "כאן הצעה שלי", ואדם בודק ואומר "מאושר" או "דחוי".

דוגמה: סוכן e-commerce צעבר refund request. זה עשוי להיות בדוק: אם הסכום קטן ($50) וה-customer יש עיד טוב, approve בעצמי. אם הסכום גדול ($5,000) או customer חדש, "בואו ניחנהו למנהל פרויקט לבדוק".

Approval workflows צריכה להיות קלה להגדרה וליישום. tools כמו Zapier, n8n, או workflow engines מיוחדים עוזרים. מה שחשוב: אל תעשה את ההקדמה עד שהאדם אישר או לפחות תוודא שהאדם יכול לעקוף אם צריך.

Automatic Rollback ו-Emergency Stops

סוכן עשה משהו קשוט? וקט לחיסול מוד. אוטומטי rollback פירוש שהמערכת עובדת בעצמה כדי להתאושש בלי הפרעה אנושית. "סוכן עשה 100 טעויות בעשר דקות? בואו נחזור לגרסה הישנה מיד."

אבל לפעמים אתה צריך עצירה מיידית. Emergency stop ("kill switch") היא כפתור שעוצר הכל עכשיו. "אנחנו תחת התקפה! בואו נעצור את כל הסוכנים!" סוכנים צריכים להיות נתפסים כדי לקבל "stop" ביטחון ולהכיל בו מיד, תוך סיום פעולות בעיצומן בבטחה.

ב-Kubernetes, זה "delete pod". בפרויקט שלך, זה יכול להיות "POST /agents/{id}/stop" endpoint שמסמן את הסוכן למוות. משהו פשוט, אבל קריטי.

Recovery Goals

בעת תכנון rollback ו-stop mechanisms, הגדר RTO (Recovery Time Objective — כמה מהר חייבים להתאושש?) ו-RPO (Recovery Point Objective — כמה נתונים יכול להאבד?). אם RTO הוא 5 דקות ו-RPO הוא 10 דקות, תוכנן בהתאם.

בסוף מודול זה תוכל:

7

Orchestration וקואורדינציה מרובה סוכנים

משך המודול

3 שעות

נושאים בקורס

Multi-agent coordination patterns
Consensus mechanisms וקבלת החלטות מבוזרת
Event-driven architecture לסוכנים
Workflow engines וDAG-based execution

Multi-Agent Coordination — From Solo to Ensemble

סוכן יחיד חזק, אבל צבר של סוכנים עם התמחות שונה יכול להיות עוד יותר חזק. דוגמה: בעיה e-commerce complex כמו "עיבוד קנייה". חלק אחד — agent_classification — סוככנת את הבקשה ("זה חתונה? או אלכוהול? צריך שליש מ-age verification?"). חלק אחר — agent_pricing — קובעת מחיר. חלק שלישי — agent_fraud_detect — בודק אם זה נראה כמו fraud. וכל אלה צריכים לעבוד ביחד.

תבניות של coordination כוללות: Sequential (agent A נעשה, אחרי כן agent B), Parallel (A ו-B רצים באותו זמן), Hierarchical (agent_boss מחליט מה לתן לאנשים), ו-Market-based (agents "bid" עבור משימות).

בקורס זה נתמקד בעיקר Sequential ו-Parallel, כי הן הפשוטות ביותר. אנחנו גם נראה איך להעביר מידע בין סוכנים בבטחה וביעילות — גם context passing (סוכן A מעביר ל-B את מה שהוא עשה) וגם result caching (אם סוכן B עשה בדיוק את הבעיה הזאת קודם, תשתמש בתוצאה הישנה).

Event-Driven Architecture

סוכנים בדרך כלל פועלים בתגובה לאירועים. "Customer submitted a purchase request" → "classify_agent woke up" → "pricing_agent woke up" → וכו'. זה event-driven. במקום כל דברים לשאול "מה אני צריך לעשות?", הם מאזינים לstream של אירועים ופועלים כשאחד אחד משעניהם.

Event bus או message queue (כמו Kafka, RabbitMQ) מטפלת בזה. סוכן A שולח event, event bus מעביר לכל מי ש-subscribed. זה loosely coupled — סוכנים לא צריכים לדעת זה על זה, רק על event schema.

יתרון: קל להוסיף סוכנים חדשים (בדרך כלל רק תא-subscribe לאירועים). קל לsidecar-tasks (analytics, logging). קשה יותר לdebug (תנועה של מידע בין יותר מעט places), אבל זה ידוע.

// Multi-Agent Orchestration class MultiAgentOrchestrator { constructor() { this.agents = new Map(); this.workflows = new Map(); this.eventBus = new EventBus(); } // Register agents registerAgent(agentId, agentConfig) { this.agents.set(agentId, { id: agentId, type: agentConfig.type, // "classifier", "pricing", "fraud_detector" status: "ready", lastExecution: null }); } // Sequential Coordination: Agent A → Agent B → Agent C async executeSequential(agentIds, context) { let result = context; for (const agentId of agentIds) { const agent = this.agents.get(agentId); try { console.log(`Executing ${agentId}...`); result = await this.executeAgent(agentId, result); agent.lastExecution = { status: "success", timestamp: Date.now() }; } catch (error) { agent.lastExecution = { status: "failed", error, timestamp: Date.now() }; throw error; // Stop the sequence if one fails } } return result; } // Parallel Coordination: Run A, B, C at the same time async executeParallel(agentIds, context) { const promises = agentIds.map(agentId => this.executeAgent(agentId, context)); const results = await Promise.all(promises); // Merge results return this.mergeResults(results); } async executeAgent(agentId, context) { // Simplified: in reality, call agent API or service const agent = this.agents.get(agentId); return { ...context, [`${agentId}_result`]: `Processed by ${agentId}`, timestamp: Date.now() }; } mergeResults(results) { return results.reduce((acc, res) => ({ ...acc, ...res }), {}); } // DAG-based workflow: Define which agents run and in what order defineWorkflow(workflowId, dag) { this.workflows.set(workflowId, { id: workflowId, dag: dag, // { "classify": ["price", "fraud_check"], "price": [...] } status: "defined" }); } // Example DAG Workflow exampleWorkflow() { return { purchase_order_workflow: { nodes: { classify: { agent: "agent_classify", inputs: ["order_data"] }, price: { agent: "agent_pricing", inputs: ["classify.output"] }, fraud: { agent: "agent_fraud_check", inputs: ["order_data", "classify.output"] }, approve: { agent: "agent_approval", inputs: ["price.output", "fraud.output"] } }, edges: [ ["classify", "price"], ["classify", "fraud"], ["price", "approve"], ["fraud", "approve"] ] } }; } // Consensus: If multiple agents give different opinions, how to decide? async consensusDecision(agentIds, decision, threshold = 0.6) { const opinions = await Promise.all( agentIds.map(async (agentId) => ({ agentId, opinion: await this.getAgentOpinion(agentId, decision) })) ); const votes = opinions.filter(o => o.opinion.agree).length; const consensus = votes / opinions.length >= threshold; return { decision, consensus, votes, agreementRate: (votes / opinions.length) * 100, opinions }; } async getAgentOpinion(agentId, decision) { // Simplified return { agree: Math.random() > 0.5, confidence: Math.random() }; } } // Example: Event Bus for Agent Communication class EventBus { constructor() { this.subscribers = new Map(); } subscribe(eventType, handler) { if (!this.subscribers.has(eventType)) { this.subscribers.set(eventType, []); } this.subscribers.get(eventType).push(handler); } async publish(eventType, data) { const handlers = this.subscribers.get(eventType) || []; console.log(`Event published: ${eventType}`, data); return Promise.all(handlers.map(h => h(data))); } } // Usage const orchestrator = new MultiAgentOrchestrator(); orchestrator.registerAgent("agent_classify", { type: "classifier" }); orchestrator.registerAgent("agent_price", { type: "pricing" }); orchestrator.registerAgent("agent_fraud", { type: "fraud_detector" }); // Sequential: Classify → Price → Fraud Check → Approve const result = await orchestrator.executeSequential( ["agent_classify", "agent_price", "agent_fraud"], { orderId: "ord_123", amount: 500 } );

Workflow Engines וDAG Execution

כשיש לך הרבה סוכנים עם תלויות מורכבות, זה קשה לניהול ידנית. Workflow engines (כמו Apache Airflow, Prefect, או Temporal) עוזרים. אתה מגדיר DAG (Directed Acyclic Graph) — "agent A תלוי ב-B ו-C, C תלוי ב-D" — ו-engine מטפלת בביצוע בסדר נכון, טיפול בביכלים, ו-retries.

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

טיפול הודעות חשוב: אם צעד A נכשל, האם צעדים C (תלוי ב-A) ו-D צריכים לבטל? או להמתין? Workflow engine צריך להיות עם סדרה של fail strategies — "retry N times", "skip and continue", "alert human".

בסוף מודול זה תוכל:

  • ✓ לתכנן multi-agent coordination patterns
  • ✓ ליישם sequential ו-parallel execution
  • ✓ לבנות event-driven agent systems
  • ✓ להגדיר ולהשדר DAG workflows
  • ✓ לניהל consensus ודעות מרובות
8

Case Studies וטיפול בבעיות מורכבות

משך המודול

4 שעות

נושאים בקורס

מקרה בחינה 1: e-commerce agent control system
מקרה בחינה 2: autonomous vehicle decision control
Troubleshooting: deadlocks, cascading failures
Best practices ו-lessons learned מתעשייה

מקרה בחינה 1: E-Commerce Agent Control System

דוד בחרות e-commerce בגודל בינוני פטונשים קנותים בארוח כ-10,000 ליום. כיום, כל הזה מטפל בתהליך ידי. הם רוצים "עכשיו בואו נשתמש בסוכנים". סוכנים לא צריכים להיות מושלמים, אך הם צריכים להפחית בעבודה ידנית ב-80%.

הארכיטקטורה: agent_intake (קיבול order חדש) → agent_classify (זה חוקי/זהו fraud?) → agent_pricing (קובע מחיר, עם ה-dynamic pricing) → agent_fulfillment (קובע warehouse שידי) → agent_customer_service (עיבוד returns).

בקרה: שדר ordersערוך $5,000 דורשים אישור אנושי. orders שלא הוצאו כמו 24 שעות דורשים בדיקה. agents לא רשאים לבצע refunds בעצמם, רק לציע בקשה. אם agent יצא מבחינה לא בסדר (e.g., דחויות שיעור 50%), עוצרים אותו וביקורתו ידנית.

בעיות בדרך: agents רגילים לבחור בדרך "safe" (תמיד דחה order שמורכבת), לכן התפוקה נמוכה. הקבוצה צריך להתאמץ policies: "כן, בדוק fraud, אבל אל תהיה דרך too cautious". גם צריך training ו-feedback loops — לכל סוכן, תן דוחות שבועיים: "בן שבוע זה, לך חטא 95% מהזמן — טוב!" או "אתה טעית ב-15% מקרים, בואו נעביר את הpolicies".

מקרה בחינה 2: Autonomous Vehicle Decision Control

רכב אוטונומי צריך לקבל החלטות בזמן אמת: "לעצור?" "להשתנות נתיבים?" "לעמוד בקצב 30mph או 60mph?" בשונה מ-e-commerce, שגיאה יכולה להיות קטלנית. בקרה כאן היא שונה.

בקרה לרכבים אוטונומיים: systems לא יכול לוותר לsafety. אם סוכן בחר משהו לא בטוח, וקטו בעזרת מערכת בטיחות. גם צריך "fallback": אם העיבוד בעיבוד מחזור קרדיום יותר מ-100ms, עברו למערכת Fallback מקודמת ש-simply slows down (בטוח יותר מאשר להמשיך כאילו כום). Perception data צריך לו monitored קרוב — אם camera או lidar בלתי מתפקדים, דיווח וslow down.

טוב לרכבים אוטונומיים זה גם "Humans are in the loop". במהרה שהצצו ביותר שטרידות, אם הסוכן לא בטוח, המנהל (או מערכת קשקשת) לוקח על עצמו. זה לא כמו e-commerce — לא מנוהל "fully autonomous", הוא "levels 2-3 autonomy" עם אדם עדיין vigilant.

Troubleshooting: Deadlocks וCascading Failures

בעיה מיתולוגית: סוכן A חוכה על סוכן B לשלוח תוצאות. סוכן B חוכה על C. סוכן C חוכה על A. זה deadlock. מנהל מערכות צריך לגנוב זה. בפרקטיקה, זה קורה כשאתה משתמש ב-synchronous coordination (agent A calls agent B and waits). פתרון: משתמש async/event-driven (agent A posts event, agent B שומע וועד, תוצאה חוזרת דרך event).

Cascading failures: סוכן A נכשל, וזה גורם לסוכן B לפשול כי B הוא תלוי בתוצאה של A. פיתרון: הגדר retry strategies. אם A נכשל, B לא צריך להמשיך בעצמו — חכה, retry, או skip (אם הנתון optional). Circuit breaker: אם A נכשל יותר מ-N פעמים רצופות, אל תנסה יותר לעשר דקות. בואו נעצור את השרשרת כדי לתן ל-A לתאושש.

טוב גדול זה גם יציבות. Bulkheads: אם agent_A יצא משולט (consuming all CPU), זה לא צריך להשפיע על agent_B שרץ בצד שלך. בKubernetes, זה resource limits ו-namespace isolation.

// Troubleshooting: Handling Deadlocks and Cascading Failures class ResilientCoordinator { constructor() { this.agents = new Map(); this.circuitBreakers = new Map(); this.retryStrategies = new Map(); } // Circuit Breaker Pattern initCircuitBreaker(agentId, failureThreshold = 5, resetTimeout = 60000) { this.circuitBreakers.set(agentId, { state: "closed", // closed, open, half-open failureCount: 0, failureThreshold, resetTimeout, lastFailureTime: null }); } // Check Circuit Breaker canExecuteAgent(agentId) { const cb = this.circuitBreakers.get(agentId); if (!cb) return true; if (cb.state === "open") { const now = Date.now(); if (now - cb.lastFailureTime > cb.resetTimeout) { // Try again cb.state = "half-open"; cb.failureCount = 0; return true; } return false; // Still open, don't execute } return true; // Closed or half-open, safe to execute } // Record failure recordFailure(agentId) { const cb = this.circuitBreakers.get(agentId); if (!cb) return; cb.failureCount++; cb.lastFailureTime = Date.now(); if (cb.failureCount >= cb.failureThreshold) { cb.state = "open"; console.warn(`Circuit breaker OPEN for ${agentId}: Too many failures`); } } // Record success recordSuccess(agentId) { const cb = this.circuitBreakers.get(agentId); if (!cb) return; if (cb.state === "half-open") { cb.state = "closed"; cb.failureCount = 0; console.log(`Circuit breaker CLOSED for ${agentId}: Recovery successful`); } } // Timeout Detection (prevent deadlocks) async executeWithTimeout(agentId, action, timeoutMs = 30000) { return Promise.race([ action(), new Promise((_, reject) => setTimeout(() => reject(new Error(`Agent ${agentId} timed out after ${timeoutMs}ms`)), timeoutMs) ) ]); } // Exponential Backoff Retry async retryWithBackoff(agentId, fn, maxRetries = 3) { let lastError; for (let attempt = 0; attempt < maxRetries; attempt++) { try { if (!this.canExecuteAgent(agentId)) { throw new Error(`Circuit breaker open for ${agentId}`); } const result = await this.executeWithTimeout(agentId, fn); this.recordSuccess(agentId); return result; } catch (error) { lastError = error; this.recordFailure(agentId); if (attempt < maxRetries - 1) { const delayMs = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s console.log(`Retry ${attempt + 1}/${maxRetries} for ${agentId} after ${delayMs}ms`); await new Promise(resolve => setTimeout(resolve, delayMs)); } } } throw lastError; } // Bulkhead Isolation: Run agents in separate thread pools executeBulkhead(agentId, fn) { const bulkheadId = `bulkhead_${agentId}`; if (!this.agents.has(bulkheadId)) { // Create isolated execution context (e.g., separate worker thread) this.agents.set(bulkheadId, { executor: "isolated" }); } return fn(); // In real system, run in dedicated thread pool } } // Example: Detect and prevent cascading failures class CascadeDetector { constructor() { this.dependencies = new Map(); // agent -> [dependencies] this.failureChain = []; } registerDependency(agentId, dependsOn) { this.dependencies.set(agentId, dependsOn); } // Detect if failure will cascade willCascade(failedAgentId) { const affected = []; for (const [agent, deps] of this.dependencies.entries()) { if (deps.includes(failedAgentId)) { affected.push(agent); } } return affected; } // Notify dependents and allow graceful degradation notifyFailure(failedAgentId) { const affected = this.willCascade(failedAgentId); console.warn(`Agent ${failedAgentId} failed. Affected agents: ${affected.join(", ")}`); return { failedAgent: failedAgentId, affectedAgents: affected, recommendation: affected.length > 0 ? "Implement fallback logic" : "No cascading impact" }; } }

Best Practices ו-Lessons Learned

כאן כמה דברים שפרויקטים בעולם אמתי לומדים קשה:

תמיד תן לאדם בקרה סופית

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

Test in Production, Carefully

אתה לא יכול לבדוק סוכנים בעולם של 100 תכניות שונות במעבדה. Canary deployments, feature flags, ו-monitoring אמיתי הם קריטיים. בדוק עם 1% תנועה ראשונה, אחרי כן הגדל.

Observe Everything, Alert on Meaningful

אל תצא ממערכת בלי observability. אבל אל תעשה את זה נרחב מדי — זה מובילה לאזעקה fatigue. Focus on "golden signals": latency, throughput, errors, saturation.

Version Everything

Policies, models, agents, APIs. תוכל להחזיר מהירות אם משהו נשבר. Git לקוד, model registry לmodelim, policy versioning לpolicies.

Cost tracking from Day 1

LLM API קריאות יוקרות. Agents רצים 24/7. בלי tracking, עלויות יחסה להתפוצץ. Tag everything (agent, model, environment), track בדקה וביום.

Communication is Key

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

Start Small, Iterate

אל תנסה לבנות 10 סוכנים רב-פיקסלים עם בקרה מוקשים ביום ראשון. תחילה, בנה agent אחד לעבודה אחת. Test extensively. אחרי כן, הוסיפו עוד עם זהירות.

The Most Important Lesson

בקרה על סוכנים אינה רק טכנולוגיה. היא תרבות, ארגון, וחוקים. טכנולוגיה טובה ללא clear governance, accountability, וfeedback loops תכשל. Invest in both.

בסוף מודול זה תוכל:

  • ✓ לתכנן control plane עבור סוגי שונים של סוכנים
  • ✓ להתמודד עם דידוקים, deadlocks, וcascading failures
  • ✓ ליישם best practices מתעשייה
  • ✓ לבצע post-mortem על תקלות ולמידה ממהם
  • ✓ לתכנן על הרחבה קומית של מערכת בקרה

שאלות נפוצות (FAQ)

מה דרוש לי לפני התחלת הקורס?
ידע בסיסי במערכות מחשוב מוזרות, הכרת microservices, וניסיון עם APIs יהיה מועיל. רקע בPython או Go יוסיף ערך. אנחנו נכסה הרבה טכנולוגיות בקורס, אבל ניסיון קודם עם systems design יהיה יתרון.
האם הקורס כולל פרויקטים מעשיים?
כן, בקורס 4 פרויקטים מעשיים. ראשון: בנו Control Plane פשוט עם Policy Engine. שני: setup observability stack עם Prometheus ו-Jaeger. שלישי: implement מערכת RBAC לסוכנים. רביעי: בנו multi-agent orchestration עם DAG workflow. כל פרויקט צריך להיות בנוי בקוד אמיתי, לא תיאורטי.
איך שונה זה מקורס ריגיל ב-AI?
קורסים ב-AI בדרך כלל מתמקדים בשכלול מודלים, fine-tuning, וdata science. קורס זה מתמקד בתפעול וניהול סוכנים, לא בשכלול. אנחנו מדברים על איך להריץ סוכנים בצורה בטוחה, מקובלת ויעילה בייצור. אם אתה מפתח AI ורוצה להבין איך להעביר אותה לייצור בבטחה — זה הקורס.
האם נעבור טכנולוגיות ספציפיות?
כן. נלמד Kubernetes, Prometheus, Jaeger, OpenTelemetry, ו-tools ל-Policy Management (כמו OPA/Rego). גם OpenAI, Anthropic ו-local LLMs (Ollama, vLLM) ישמשו דוגמאות. אבל הדגש הוא על concepts, לא על tool-specific knowledge.
האם זה קורס תיאורטי או מעשי?
50:50 תיאוריה ותרגול. כל מודול כולל הרצאות, דיאגרמות, demos חיים, וסשיות תרגול מעשיות עם קוד וכלים אמיתיים. לא תהיה "ספר", תהיה hands-on מאז התחלה.
כמה זמן אני צריך להקדיש לשיעורי בית?
בממוצע 4-6 שעות בשבוע ללימוד עצמי, ניסיון עם הקוד, ופתרון תרגילים. הפרויקטים המסכמים דורשים 15-20 שעות כל אחד. אם אתה עובד במקביל, הקדש יום Ъ׳רי לקורס הזה.
מה אגיע לגזור בסוף הקורס?
תעודת סיום (אם השקמת את כל הפרויקטים), Repository GitHub עם 4 פרויקטים ייצור-ready, ו-architecture document לבניית מערכת בקרה עבור סוכנים. הפוליו הזה אמור להיות טוב בהרשים מעסיקים או בהחלתה לקליינטים.
האם הקורס מעודכן לשנת 2025?
כן! הקורס מכוסה מודלים חדשים (GPT-4o, Claude 3.5, Gemini 2.0), agents frameworks חדשים (LangGraph, OpenAI Swarm), וטרנדים הנוכחיים בתעשייה כמו agentic AI. הוא מתעדכן מידי רבעון כי השדה משתנה במהירות.

מוכן להתחיל?

קורס זה יתן לך את הכלים והידע כדי לבנות מערכות בקרה חזקות, מאובטחות, ויעילות עבור סוכני AI. בין אם אתה מהנדס, מנהל מערכות, או team lead, תרגיל שלם בקורס זה יהיה ערכי.

32 שעות של תוכן, 4 פרויקטים מעשיים, ו-best practices מתעשייה. בואו נבנה עתיד של סוכנים בטוחים ומבוקרים.