- אייג'נט Hello World עובד — CopilotClient שמריץ לולאה אגנטית מלאה מתוך קוד TypeScript שלכם
- כלי מותאם (Custom Tool) פעיל —
defineToolעם handler שהאייג'נט קורא לו אוטונומית - חיבור MCP Server לאייג'נט SDK — אותם שרתים שהכרתם בפרק 5, עכשיו מקוד
- הגדרת אימות כפולה — Copilot Subscription (דרך GitHub) ו-BYOK (מפתח API ישיר)
- אייג'נט עם Streaming — תוצאות בזמן אמת במקום המתנה לתשובה מלאה
- פרויקט Capstone: אייג'נט סורק ריפוזיטורי שמייצר דוח Markdown עם כלים מותאמים ו-MCP
- קובץ הגדרות production-ready עם error handling, retry logic ו-rate limit management
- תוכלו להתקין ולהגדיר את Copilot SDK בפרויקט Node.js ולהריץ אייג'נט ראשון תוך 5 דקות
- תוכלו להגדיר כלים מותאמים (Custom Tools) שהאייג'נט משתמש בהם אוטונומית לביצוע משימות
- תוכלו לחבר MCP Servers חיצוניים לאייג'נט SDK — STDIO ו-HTTP
- תוכלו להגדיר אימות — דרך מנוי Copilot או BYOK עם מפתח API ישיר מ-OpenAI, Anthropic ואחרים
- תוכלו לבנות אייג'נט production-ready עם streaming, זיכרון מתמשך, error handling ו-infinite sessions
- פרקים קודמים: פרק 5 (MCP — הבנת שרתי MCP וחיבורם), פרק 6 (CLI — עבודה עם Copilot CLI ואימות). מומלץ גם פרק 1 (Agent Mode — הלולאה האגנטית) ופרק 3 (מודלים ומכפילים)
- כלים נדרשים: Node.js 18 ומעלה, Copilot CLI מותקן ומאומת (
copilot auth status), חשבון GitHub עם מנוי Copilot פעיל (Pro / Pro+ / Business / Enterprise), עורך קוד (VS Code מומלץ) - זמן משוער: 3-4 שעות (כולל Capstone Project)
בפרק 5 למדת לחבר MCP servers ל-Copilot ב-VS Code וב-CLI — שרתי filesystem, GitHub, ושרתים מותאמים. בפרק הזה תיקח את אותה לולאה אגנטית שמריצה את Copilot CLI ותטמיע אותה באפליקציה שלך — עם כלים מותאמים, MCP servers ומודלים לבחירה. בפרק 12 תשלב את כל הכלים — SDK, CLI, GitHub.com וסוכני צד שלישי — בזרימת עבודה מקצה לקצה שפותרת בעיות אמיתיות.
| מונח באנגלית | הסבר בעברית |
|---|---|
| Copilot SDK | ערכת פיתוח תוכנה (Software Development Kit) שמטמיעה את הלולאה האגנטית של Copilot CLI בתוך האפליקציה שלך |
| CopilotClient | האובייקט הראשי ב-SDK — יוצר ומנהל סשנים, מקביל ל-"מנוע" שמפעיל את האייג'נט |
| Agentic Execution Loop | לולאת ביצוע אגנטית — הלולאה שבה האייג'נט מקבל משימה, מתכנן, בוחר כלי, מפעיל, בודק תוצאה, וחוזר עד שהמשימה מושלמת |
| defineTool | פונקציה ב-SDK להגדרת כלי מותאם — שם, תיאור, פרמטרים (JSON Schema) ופונקציית handler שמבצעת את הפעולה בפועל |
| BYOK (Bring Your Own Key) | אימות עם מפתח API ישיר מספק מודלים (OpenAI, Anthropic וכו'), בלי לעבור דרך GitHub — חיוב ישיר לספק |
| Streaming | קבלת תשובות בזמן אמת, חלק אחרי חלק (token by token), במקום לחכות שהתשובה המלאה תסתיים |
| Infinite Sessions | סשנים ללא הגבלת אורך — כש-context window מתמלא, ה-SDK דוחס את ההיסטוריה אוטומטית ומשחרר מקום |
| Session Persistence | שמירת מצב הסשן (היסטוריה, כלים, מצב) לדיסק, כך שאפשר לחדש אותו מאוחר יותר — גם אחרי restart |
מה זה Copilot SDK — ולמה זה משנה את הכל
עד עכשיו ב-Copilot עבדתם בתוך סביבות מוכנות — VS Code, טרמינל, GitHub.com. הייתם משתמשים של הלולאה האגנטית. ה-Copilot SDK (ראשי תיבות: Software Development Kit — ערכת פיתוח תוכנה) הופך אתכם לבונים.
הרעיון פשוט ומשנה כללי משחק: אותו מנוע שמריץ את Copilot CLI — אותה לולאה אגנטית (Agentic Execution Loop) של קלט, תכנון, בחירת כלי, הפעלה, בדיקת תוצאה וחזרה — עכשיו זמין כספריה שאפשר לייבא לכל אפליקציה. לא clone, לא חיקוי — ממש אותו קוד battle-tested שמפעיל את Copilot.
בשורה תחתונה: Copilot ב-VS Code הוא אפליקציה אחת שבנויה מעל הלולאה הזו. עם ה-SDK, אתם בונים את האפליקציה. רוצים בוט שסורק PRs כל לילה? אייג'נט שעונה ללקוחות? כלי שמנתח קוד לפי סטנדרט של הצוות? ה-SDK מאפשר את כל זה.
למה לא פשוט לקרוא ל-API של OpenAI ישירות?
שאלה לגיטימית. הרי אפשר לקרוא ישירות ל-API של OpenAI, Anthropic או Google — אז למה לעבור דרך ה-SDK? התשובה: הלולאה האגנטית. כש-API רגיל מקבל פרומפט ומחזיר תשובה (one-shot), ה-SDK מריץ לולאה שלמה: הוא שולח את הפרומפט, המודל מחליט אם צריך כלי, ה-SDK מפעיל את הכלי, מחזיר את התוצאה למודל, והמודל ממשיך — שוב ושוב עד שהמשימה מושלמת. זה בדיוק מה שקורה ב-Agent Mode ב-VS Code.
אם הייתם רוצים לבנות את הלולאה הזו בעצמכם, הייתם צריכים:
- ניהול שיחה מרובת סיבובים (multi-turn)
- ניתוח תשובות המודל לזיהוי קריאות כלים (tool calls parsing)
- הפעלת כלים, טיפול בשגיאות, והחזרת תוצאות
- לוגיקת retry כשכלי נכשל
- ניהול context window ודחיסה כשהשיחה ארוכה
- streaming token-by-token
ה-SDK נותן את כל זה מוכן. כמות הקוד שחוסכים: מאות שורות של boilerplate שמישהו כבר כתב, בדק ותיקן.
5 תרחישי שימוש שווים
כדי שהרעיון יהפוך לקונקרטי — הנה תרחישים שאנשים כבר בונים עם ה-SDK:
- בוט Code Review אוטומטי: רץ ב-GitHub Actions על כל PR, סורק שינויים, מוצא בעיות, ומשאיר הערות — בלי שמפתח אנושי ייגע
- Slack Bot לשאלות קוד: חבר צוות שואל "@copilot מה עושה הפונקציה X?", הבוט קורא את הקוד מ-GitHub ומסביר — בתוך Slack
- סורק תיעוד: אייג'נט שרץ כל לילה, קורא את הקוד, ומעדכן אוטומטית את ה-README ואת ה-API docs
- מנתח dependencies: בודק חבילות ישנות, CVEs, ופותח PRs אוטומטיים לעדכון — מותאם לסטנדרט הצוות
- עוזר onboarding: מפתח חדש מקבל בוט אישי שמכיר את כל ה-codebase ועונה על שאלות בזמן אמת
שפות נתמכות
ה-SDK זמין רשמית ב-4 שפות:
| שפה | חבילה | סטטוס |
|---|---|---|
| Node.js / TypeScript | @github/copilot-sdk | Technical Preview (רשמי) |
| Python | copilot | Technical Preview (רשמי) |
| Go | github.com/github/copilot-cli-sdk-go | Technical Preview (רשמי) |
| .NET | GitHub.Copilot.SDK | Technical Preview (רשמי) |
בנוסף, הקהילה פיתחה SDK-ים לא-רשמיים ל-Java, Rust ו-C++ — אבל שימו לב: אלה community-maintained ועשויים להישבר כש-API משתנה.
למה בפרק הזה נעבוד עם Node.js?
שתי סיבות מעשיות. ראשית, ה-SDK ל-Node.js הוא הכי בוגר — הוא יצא ראשון ויש לו הכי הרבה דוגמאות ותיעוד. שנית, הקונספטים זהים בכל השפות. אם תבינו את ה-API ב-TypeScript, המעבר ל-Python או Go הוא בעיקר תרגום syntax — לא שינוי חשיבה.
הנה השוואה מהירה של אותו "Hello World" בשתי שפות:
| Node.js / TypeScript | Python |
|---|---|
import { CopilotClient } from "@github/copilot-sdk" |
from copilot import CopilotClient |
const client = new CopilotClient() |
client = CopilotClient() |
const session = await client.createSession({...}) |
session = await client.create_session(...) |
await session.sendAndWait({prompt: "..."}) |
await session.send_and_wait(prompt="...") |
כמו שאתם רואים — ההבדל הוא camelCase מול snake_case. הלוגיקה זהה. אם אתם מפתחי Python, תרגישו בבית. הדוגמאות בפרק הזה ב-TypeScript, אבל כל קונספט מתורגם 1:1.
ה-SDK בהקשר של המערכת האקולוגית
איפה ה-SDK יושב ביחס לכלים שכבר הכרתם? בואו נסדר:
| כלי | סביבה | שליטה שלכם | מתי |
|---|---|---|---|
| Copilot Chat (VS Code) | IDE | נמוכה — ממשק מוכן | פיתוח אינטראקטיבי |
| Agent Mode (VS Code) | IDE | בינונית — פרומפט + כלים | משימות מורכבות בזמן פיתוח |
| Copilot CLI | טרמינל | בינונית — פקודות וסקריפטים | אוטומציה בסיסית, scripting |
| Copilot SDK | הקוד שלכם | מלאה — כלים, מודלים, UI | אפליקציות, שירותים, בוטים |
ככל שעולים בטבלה, השליטה שלכם גדלה — אבל גם כמות הקוד שצריך לכתוב. ה-SDK נותן שליטה מלאה במחיר של יותר אחריות. זו הסיבה שרוב המפתחים ישתמשו ב-Agent Mode ל-90% מהמשימות, וב-SDK ל-10% — אבל אותם 10% הם בדיוק המקרים שה-SDK בלתי ניתן להחלפה: אוטומציות, בוטים, ושירותים.
מה ה-SDK מספק — ומה לא
חשוב להבין את הגבולות:
| ה-SDK נותן | ה-SDK לא נותן |
|---|---|
| לולאה אגנטית מוכנה | ממשק משתמש (UI) |
| חיבור מודלים (multi-model) | אירוח (hosting) — אתם מריצים |
| כלים מותאמים (defineTool) | כלים עסקיים מוכנים (CRM, DB) |
| MCP server integration | MCP servers עצמם — תתקינו בנפרד |
| Streaming ו-events | WebSocket server לדפדפן |
| אימות (Copilot / BYOK) | ניהול משתמשים, RBAC |
ה-SDK הוא המנוע. את המכונית — ה-UI, ה-hosting, האינטגרציות — אתם בונים.
ה-Copilot SDK הושק בינואר 2026 בסטטוס Technical Preview — מה שאומר שה-API עובד ואפשר לפתח איתו, אבל ממשקים עשויים להשתנות. אל תבנו production system בלי שכבת הפשטה (abstraction layer) שמפרידה את הקוד שלכם מה-SDK ישירות. ככה, כשה-API משתנה, תתקנו במקום אחד.
פתחו טרמינל והריצו: copilot auth status. וודאו שאתם מחוברים ושיש לכם מנוי Copilot פעיל. אם לא — חזרו לפרק 6 והגדירו CLI auth. גם בדקו גרסת Node: node --version — צריך 18 ומעלה.
התקנה ו-Hello World — האייג'נט הראשון שלך
הגיע הזמן לכתוב קוד. תוך 5 דקות יהיה לכם אייג'נט חי שרץ מתוך קובץ TypeScript שלכם. בואו נבנה אותו שלב אחרי שלב.
שלב 1: יצירת פרויקט
פתחו תיקייה חדשה וצרו פרויקט Node.js:
mkdir my-copilot-agent
cd my-copilot-agent
npm init -y
npm install @github/copilot-sdk tsx
tsx מאפשר להריץ TypeScript ישירות בלי שלב build — מושלם לפיתוח מהיר.
שלב 2: קובץ האייג'נט הראשון
צרו קובץ agent.ts:
import { CopilotClient } from "@github/copilot-sdk";
async function main() {
// יצירת הלקוח — מתחבר ל-Copilot CLI מאחורי הקלעים
const client = new CopilotClient();
// יצירת סשן עם מודל ספציפי
const session = await client.createSession({
model: "gpt-4.1"
});
// שליחת פרומפט והמתנה לתשובה מלאה
const response = await session.sendAndWait({
prompt: "Analyze this project structure and suggest improvements"
});
console.log(response?.data.content);
// ניקוי
await client.stop();
process.exit(0);
}
main();
שלב 3: הרצה
npx tsx agent.ts
מה שקורה מאחורי הקלעים: CopilotClient מפעיל מופע של Copilot CLI, שולח את הפרומפט דרכו, ומחזיר את התשובה. ה-CLI משתמש באימות שלכם (שהגדרתם בפרק 6) ובקרדיטים של המנוי שלכם.
הבנת הזרימה — מה קורה בין השורות
בואו נפרק את מה שקורה כשמריצים את הקוד הזה:
new CopilotClient()— יוצר מופע שמתחבר ל-Copilot CLI ברקע. אם ה-CLI לא מותקן או לא מאומת, כאן תקבלו שגיאהclient.createSession({ model: "gpt-4.1" })— פותח סשן חדש. הסשן שומר את ההיסטוריה של השיחה, הכלים הזמינים, ומצב הביצוע. אפשר לפתוח כמה סשנים במקבילsession.sendAndWait({ prompt: "..." })— שולח את הפרומפט, ממתין שהלולאה האגנטית תסתיים (כולל קריאות כלים אם צריך), ומחזיר את התשובה הסופיתresponse?.data.content— הטקסט של התשובה. ה-?.כי response יכול להיות null (למשל אם הייתה שגיאה)client.stop()— מנקה את כל המשאבים וסוגר את תהליך ה-CLI
נקודה חשובה: הסשן הוא stateful — הוא זוכר את כל מה שנאמר. אם תשלחו פרומפט שני, המודל יכיר את ההקשר מהפרומפט הראשון. זה מה שמאפשר שיחות multi-turn:
const r1 = await session.sendAndWait({ prompt: "List all .ts files in this project" });
console.log(r1?.data.content);
// הסשן זוכר! לא צריך לחזור על ההקשר
const r2 = await session.sendAndWait({ prompt: "Now count the lines in each of those files" });
console.log(r2?.data.content);
אם לא קוראים ל-client.stop() ו-process.exit(0), התהליך נשאר חי ברקע ותופס משאבים. זה מפתה לשכוח כי הקוד "עובד" בלי זה — אבל תגלו תהליכים זומבי שצורכים זיכרון. תמיד סגרו את ה-client.
צרו את הפרויקט, העתיקו את הקוד, והריצו. שנו את הפרומפט ל-"What files are in the current directory?" והריצו שוב. שימו לב: האייג'נט מקבל גישה לכלי הקריאה של ה-CLI ויכול לקרוא קבצים אמיתיים.
מה קורה כשמשנים את המודל?
החליפו "gpt-4.1" ב-"claude-sonnet" או "gemini-2.5-pro" — והריצו שוב. תשובה שונה, סגנון שונה, אותו API. זו אחת הנקודות החזקות של ה-SDK: בחירת מודל היא פרמטר, לא ארכיטקטורה. אתם לא נעולים על ספק אחד.
פתרון בעיות נפוצות בהתקנה
כמה דברים שיכולים להשתבש בשלב ההתקנה — והפתרונות:
| שגיאה | סיבה | פתרון |
|---|---|---|
Error: copilot CLI not found | Copilot CLI לא מותקן או לא ב-PATH | התקינו: npm install -g @githubnext/github-copilot-cli או ודאו שה-CLI בנתיב |
Error: Not authenticated | לא עשיתם login | הריצו copilot auth login ועקבו אחרי ההוראות |
Error: No Copilot subscription | חשבון GitHub בלי מנוי Copilot | שדרגו ל-Pro ($10/חודש) ב-github.com/settings/copilot |
ERR_MODULE_NOT_FOUND | TypeScript לא מוגדר נכון | ודאו ש-tsx מותקן: npx tsx --version |
כלים מותאמים — defineTool
האייג'נט הבסיסי שכבר יש לכם חכם — אבל מוגבל לכלים המובנים של Copilot CLI (קריאת קבצים, עריכה, חיפוש וכו'). עם defineTool אתם מרחיבים את יכולותיו: מגדירים כלי חדש, ואומרים לאייג'נט "אתה יכול להשתמש בזה".
אנטומיה של כלי מותאם
כל כלי מוגדר עם 4 חלקים:
| חלק | תפקיד | דוגמה |
|---|---|---|
| name | שם ייחודי שהאייג'נט רואה | "count_files" |
| description | מה הכלי עושה — באנגלית, למודל | "Count files in a directory by extension" |
| parameters | פרמטרים ב-JSON Schema | { type: "object", properties: { path: { type: "string" } } } |
| handler | פונקציה שמבצעת את הפעולה | async (args) => { ... return result; } |
דוגמה מלאה: כלי ספירת קבצים
import { CopilotClient, defineTool } from "@github/copilot-sdk";
import { readdirSync, statSync } from "fs";
import { join, extname } from "path";
// הגדרת הכלי
const countFiles = defineTool("count_files", {
description: "Count files in a directory, grouped by extension",
parameters: {
type: "object",
properties: {
directory: {
type: "string",
description: "Path to the directory to scan"
}
},
required: ["directory"]
},
handler: async (args: { directory: string }) => {
const counts: Record<string, number> = {};
const files = readdirSync(args.directory);
for (const file of files) {
const fullPath = join(args.directory, file);
if (statSync(fullPath).isFile()) {
const ext = extname(file) || "(no extension)";
counts[ext] = (counts[ext] || 0) + 1;
}
}
return { directory: args.directory, total: files.length, by_extension: counts };
}
});
// שימוש בכלי בסשן
async function main() {
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
tools: [countFiles] // <-- רישום הכלי
});
const response = await session.sendAndWait({
prompt: "Count all files in the current directory and tell me the breakdown"
});
console.log(response?.data.content);
await client.stop();
process.exit(0);
}
main();
מה קורה כשמריצים: האייג'נט קורא את הפרומפט, מזהה שצריך לספור קבצים, קורא אוטונומית ל-count_files עם הנתיב הנוכחי, מקבל את התוצאה, ומנסח תשובה מפורטת. אתם לא צריכים לכתוב את הלוגיקה של "מתי לקרוא לכלי" — הלולאה האגנטית עושה את זה.
איך המודל "יודע" מתי להשתמש בכלי?
זה קורה בזכות ה-description שכתבתם. כשהמודל מקבל את הפרומפט "Count all files", הוא רואה גם את רשימת הכלים הזמינים עם התיאורים שלהם. תיאור טוב = המודל ידע מתי לקרוא לכלי. תיאור גרוע = המודל לא ישתמש בכלי גם כשצריך. כמה כללים:
- כתבו באנגלית ברורה — המודל מבין אנגלית הכי טוב
- תארו מה הכלי עושה, לא איך — "Count files in a directory by extension" ולא "Uses readdirSync to iterate"
- ציינו את סוג הקלט והפלט — "Takes a directory path, returns a count by file type"
- תנו דוגמה אם לא ברור — "e.g., returns { '.ts': 5, '.json': 2 }"
כלים מרובים — האייג'נט מתאם בעצמו
כשרושמים כמה כלים, האייג'נט מחליט לבד באיזה סדר להשתמש בהם. למשל, אם יש לכם count_files ו-get_file_size, והפרומפט הוא "Find the largest TypeScript file" — האייג'נט עשוי:
- קודם לקרוא ל-
count_filesכדי לראות אילו קבצי .ts קיימים - אז לקרוא ל-
get_file_sizeעל כל אחד מהם - לנתח את התוצאות ולהגיד לכם מה הקובץ הגדול ביותר
כל זה בלי שכתבתם שורה אחת של לוגיקת תיאום. הלולאה האגנטית מטפלת בזה.
אם תגדירו כלי בשם read_file או edit_file, ה-SDK יזרוק שגיאה — כי אלה שמות של כלים מובנים. אם בכוונה אתם רוצים להחליף כלי מובנה, תוסיפו overridesBuiltInTool: true להגדרה. אבל ברוב המקרים — פשוט בחרו שם ייחודי.
מה ה-handler יכול להחזיר?
ל-handler יש גמישות מלאה בסוג הערך המוחזר:
- אובייקט JSON — הכי נפוץ. האייג'נט מפרש את הנתונים ומשלב אותם בתשובה. דוגמה:
return { count: 42, files: ["a.ts", "b.ts"] } - מחרוזת פשוטה — מתורגמת אוטומטית לתוצאה. דוגמה:
return "Found 42 files" - ToolResultObject — שליטה מלאה על metadata של התוצאה, כולל שגיאות. שימושי כשרוצים לסמן שהכלי נכשל בלי לזרוק exception:
return { content: "File not found: /path/to/file", isError: true };
כלל אצבע: החזירו JSON כשהתוצאה מובנית (מספרים, רשימות, אובייקטים). החזירו מחרוזת כשהתוצאה היא טקסט חופשי. השתמשו ב-ToolResultObject כשצריך לסמן שגיאה.
Best Practices לכתיבת כלים
אחרי שכתבתי עשרות כלים מותאמים, הנה הכללים שלמדתי:
- שם ברור ב-snake_case:
count_files,parse_config,write_report— לאdoStuff - description באנגלית תיאורית: המודל צריך להבין בדיוק מה הכלי עושה. שורה אחת מספיקה, אבל ספציפית
- פרמטרים מינימליים: כל פרמטר צריך description. שימו required על מה שחובה, optional על שאר
- Handler שלא זורק: עטפו ב-try/catch ותחזירו
{ error: "..." }במקום לתת ל-exception לעוף. האייג'נט מטפל טוב יותר בהודעת שגיאה מפורשת מאשר ב-crash - תוצאה מידית: אם ה-handler לוקח יותר מ-30 שניות — שקלו לפרק אותו לשני כלים
הוסיפו כלי שני לקוד: get_file_size שמקבל נתיב קובץ ומחזיר את הגודל בבייטים. הגדירו parameter בשם filePath מסוג string, וב-handler השתמשו ב-statSync(filePath).size. הריצו שוב עם הפרומפט "What's the largest file in the current directory?".
חיבור MCP Servers לאייג'נט
בפרק 5 חיברתם MCP servers ל-Copilot ב-VS Code — קבצי mcp.json, שרתי GitHub, filesystem ועוד. עכשיו תעשו את אותו דבר — אבל מקוד. ה-SDK תומך באותם שני סוגי שרתים שלמדתם:
| סוג | תקשורת | דוגמה | מתי |
|---|---|---|---|
| Local / STDIO | תהליך מקומי, stdin/stdout | Filesystem MCP, Git MCP | שרת שרץ על אותה מכונה |
| HTTP / SSE | HTTP request לשרת מרוחק | שרת ענן, API gateway | שרת חיצוני או בענן |
חיבור שרת STDIO (מקומי)
const session = await client.createSession({
model: "gpt-4.1",
mcpServers: {
filesystem: {
type: "local",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"],
tools: ["*"] // כל הכלים של השרת זמינים
}
}
});
מה קורה: ה-SDK מפעיל את תהליך ה-MCP server, מתחבר אליו דרך stdin/stdout, וחושף את כל הכלים שלו לאייג'נט. מרגע זה, האייג'נט יכול לקרוא קבצים, לכתוב קבצים, ולחפש — בדיוק כמו שהיה יכול דרך VS Code.
חיבור שרת HTTP (מרוחק)
שרתי HTTP מתאימים כשה-MCP server רץ על מכונה אחרת — ענן, שרת צוות, או שירות SaaS. ה-SDK מתחבר דרך SSE (Server-Sent Events) לקבלת עדכונים בזמן אמת:
const session = await client.createSession({
model: "claude-sonnet",
mcpServers: {
"my-api": {
type: "http",
url: "https://my-mcp-server.example.com/sse",
headers: {
"Authorization": "Bearer my-token"
},
tools: ["*"]
}
}
});
ה-headers מאפשרים להעביר authentication — ככה ה-MCP server יודע מי אתם. שימו את הטוקן במשתנה סביבה, לא בקוד: headers: { "Authorization": `Bearer ${process.env.MCP_TOKEN}` }
חיבור מרובה — כמה שרתים בו-זמנית
אפשר לחבר כמה MCP servers לסשן אחד. האייג'נט יכול להשתמש בכלים מכולם:
mcpServers: {
filesystem: { type: "local", command: "npx", args: [...], tools: ["*"] },
github: { type: "local", command: "npx", args: ["-y", "@github/mcp-server"], tools: ["*"] },
database: { type: "http", url: "https://db-mcp.example.com/sse", tools: ["query", "schema"] }
}
שימו לב לפרמטר tools: עם ["*"] כל הכלים של השרת זמינים. אפשר גם לפרט רשימה ספציפית — כדי להגביל את האייג'נט רק לכלים מסוימים. זה שימושי כשאתם רוצים שהאייג'נט יוכל רק לקרוא מ-database אבל לא לכתוב.
Custom Tools + MCP — חלוקת תפקידים
שאלה שעולה: אם MCP server נותן כלים, ו-defineTool גם נותן כלים — למה צריך את שניהם? התשובה: חלוקת תפקידים.
| סוג כלי | מתי | דוגמה |
|---|---|---|
| MCP Server | שרת קיים עם כלים מוכנים | filesystem, GitHub, database |
| Custom Tool | לוגיקה ספציפית שלכם | ניתוח לפי סטנדרט צוות, חישוב metrics מותאם |
בפרויקט טיפוסי, תשתמשו ב-MCP servers לגישה לתשתיות (קבצים, Git, DB) ובכלים מותאמים ללוגיקה העסקית. הם משלימים זה את זה.
Troubleshooting — כשהחיבור נכשל
בעיות נפוצות עם MCP servers ב-SDK:
- "Command not found": ה-MCP server לא מותקן. ודאו ש-
npx -y @modelcontextprotocol/server-filesystemעובד בטרמינל רגיל לפני שמכניסים ל-SDK - "Connection refused" (HTTP): ה-URL לא נגיש. בדקו ש-URL נכון, שה-port פתוח, ושה-headers מוגדרים נכון
- הכלים לא נראים: ודאו ש-
tools: ["*"]מוגדר, או שפירטתם את שמות הכלים הנכונים - Timeout: אם שרת MCP לוקח יותר מדי זמן לענות, ה-SDK יתנתק. ודאו שהשרת מגיב מהר
הוסיפו לאייג'נט שלכם את ה-filesystem MCP server מהדוגמה למעלה. שלחו את הפרומפט "List all JavaScript files in the project and summarize their purpose". האייג'נט ישתמש בכלי הקריאה של ה-MCP server בנוסף לכלים שלכם.
בחירת מודל — כל מודלי Copilot בידיים שלך
כשאתם בונים אייג'נט עם ה-SDK, בחירת המודל היא שלכם. כל המודלים שזמינים ב-Copilot — אותם מודלים שלמדתם בפרק 3 — זמינים גם כאן:
| מודל | מזהה ב-SDK | מכפיל | מתי |
|---|---|---|---|
| GPT-4.1 | "gpt-4.1" | 1x | ברירת מחדל מאוזנת |
| GPT-4.1 mini | "gpt-4.1-mini" | 0.25x | משימות פשוטות, חסכון |
| GPT-5 | "gpt-5" | בדיקה | חשיבה מורכבת |
| Claude Sonnet | "claude-sonnet" | 1x | כתיבת קוד, ניתוח |
| Claude Opus | "claude-opus" | בדיקה | חשיבה עמוקה, משימות מורכבות |
| Claude Haiku | "claude-haiku" | 0.25x | מהיר וזול |
| Gemini 2.5 Pro | "gemini-2.5-pro" | 1x | קונטקסט ארוך, multi-modal |
המכפילים חשובים: כשאתם בונים אייג'נט שרץ 100 פעמים ביום, ההבדל בין מודל 1x למודל 0.25x הוא משמעותי. אייג'נט שמשתמש ב-Claude Haiku או GPT-4.1 mini צורך רבע מהקרדיטים — מה שאומר שתוכלו להריץ אותו פי 4 יותר עם אותו תקציב.
Multi-Model Strategy — מודל שונה לכל שלב
אין חובה לבחור מודל אחד לכל האייג'נט. ה-SDK מאפשר ליצור סשנים שונים עם מודלים שונים. זו אסטרטגיה חכמה שחוסכת כסף בלי לוותר על איכות:
// שלב 1: סיווג — מודל זול
const classifySession = await client.createSession({ model: "gpt-4.1-mini" });
const classification = await classifySession.sendAndWait({
prompt: "Classify this file: is it a configuration, source code, test, or documentation?"
});
// שלב 2: ניתוח מעמיק — מודל חזק (רק אם צריך)
if (classification?.data.content.includes("source code")) {
const analyzeSession = await client.createSession({ model: "claude-sonnet" });
const analysis = await analyzeSession.sendAndWait({
prompt: "Analyze this source file for code quality issues and security vulnerabilities"
});
}
בדוגמה הזו, 80% מהקבצים מסווגים במודל 0.25x (זול). רק קבצי קוד מקור עוברים ניתוח מעמיק ב-1x. החיסכון: ~60% בקרדיטים לעומת הפעלת מודל 1x על הכל.
ב-VS Code, Copilot יכול לבחור מודל אוטומטית. ב-SDK, אתם בוחרים. זו גם אחריות וגם הזדמנות — אתם יכולים לבנות A/B testing: להריץ את אותו prompt על שני מודלים ולהשוות תוצאות. אייג'נט חכם בוחר את המודל הנכון לכל משימה, לא מודל אחד לכל דבר.
חשבו על אייג'נט שאתם רוצים לבנות. כמה פעמים ביום הוא ירוץ? איזה מודל מתאים? חשבו את העלות החודשית (הרצות × מכפיל). האם נכנסים בתקרת המנוי? כתבו שורה אחת: "האייג'נט שלי ירוץ [X] פעמים ביום עם [מודל] = [Y] קרדיטים/חודש."
אימות — Copilot Subscription מול BYOK
ל-SDK יש שני מסלולי אימות. ההבדל ביניהם משפיע על המחיר, המודלים הזמינים, ואופן החיוב:
מסלול 1: Copilot Subscription (ברירת מחדל)
כשיוצרים CopilotClient בלי הגדרות מיוחדות, ה-SDK משתמש באימות של Copilot CLI. זה אומר:
- גישה לכל מודלי Copilot (טבלה למעלה)
- חיוב מ-premium requests של המנוי שלכם
- לא צריך מפתח API נפרד
- מוגבל לתקרת הקרדיטים של התוכנית (Pro: 300, Pro+: 1,500)
מסלול 2: BYOK (Bring Your Own Key)
עם BYOK תעבדו ישירות עם ספק מודלים — בלי לעבור דרך GitHub:
const session = await client.createSession({
provider: {
type: "openai-compatible",
baseURL: "https://api.openai.com/v1",
bearerToken: process.env.OPENAI_API_KEY
},
model: "gpt-4.1"
});
ספקים נתמכים ב-BYOK: OpenAI, Anthropic, Google AI Studio, AWS Bedrock, Microsoft Foundry, xAI, וכל ספק תואם OpenAI API.
דוגמה: BYOK עם Anthropic (Claude)
const session = await client.createSession({
provider: {
type: "openai-compatible",
baseURL: "https://api.anthropic.com/v1",
bearerToken: process.env.ANTHROPIC_API_KEY
},
model: "claude-sonnet-4-20250514"
});
דוגמה: BYOK עם AWS Bedrock
const session = await client.createSession({
provider: {
type: "openai-compatible",
baseURL: "https://bedrock-runtime.us-east-1.amazonaws.com",
bearerToken: process.env.AWS_SESSION_TOKEN,
headers: {
"X-Amz-Security-Token": process.env.AWS_SESSION_TOKEN
}
},
model: "anthropic.claude-sonnet"
});
מגבלה חשובה: BYOK עובד עם static tokens בלבד. ה-SDK לא מרענן טוקנים אוטומטית. אם הטוקן שלכם פג תוקף (כמו ב-AWS sessions), הבקשות יכשלו ותצטרכו ליצור סשן חדש עם טוקן חדש. לכן, ב-production, תכננו מנגנון רענון מחוץ ל-SDK.
מתי כל מסלול? — ההשוואה המלאה
| קריטריון | Copilot Subscription | BYOK |
|---|---|---|
| הגדרה | שורה אחת — model: "gpt-4.1" | provider + baseURL + bearerToken |
| חיוב | Premium requests מהמנוי | ישירות מהספק |
| מודלים זמינים | כל מודלי Copilot | מודלי הספק בלבד |
| תקרה | Pro: 300, Pro+: 1,500 | לפי תוכנית הספק (בד"כ ללא תקרה) |
| אבטחה | GitHub מנהל | אתם מנהלים מפתחות |
| Enterprise compliance | GitHub privacy policy | privacy policy של הספק |
process.env) ולא בקוד קשיח.
| שאלה | אם כן | אם לא |
|---|---|---|
| יש לצוות מנוי Copilot Pro/Pro+? | Subscription — הכי פשוט | BYOK — אם יש מפתח ספק |
| צריכים מודל ספציפי שלא ב-Copilot? | BYOK — גישה ישירה לספק | Subscription — כל מודלי Copilot זמינים |
| שליטה מלאה בעלויות קריטית? | BYOK — חיוב ישיר, ברור יותר | Subscription — נוח, תקרה ברורה |
| פשטות הגדרה חשובה? | Subscription — שורה אחת | BYOK — לא מסובך, אבל דורש מפתח |
כלל אצבע: התחילו עם Subscription. עברו ל-BYOK רק כשיש סיבה ספציפית — מודל חסר, עלות גבוהה מדי, או דרישת compliance.
מעבר בין מסלולים — אפשר גם את שניהם
שימו לב: לא חייבים לבחור אחד. באפליקציה מורכבת, אפשר ליצור סשנים שונים עם מסלולי אימות שונים:
// סשן 1: Copilot subscription למשימות רגילות
const regularSession = await client.createSession({
model: "gpt-4.1-mini" // שימוש בקרדיטים של Copilot
});
// סשן 2: BYOK למשימות שדורשות מודל ספציפי
const specialSession = await client.createSession({
provider: {
type: "openai-compatible",
baseURL: "https://api.anthropic.com/v1",
bearerToken: process.env.ANTHROPIC_API_KEY
},
model: "claude-opus-4-20250514" // מודל שלא זמין דרך Copilot
});
הגישה הזו מאפשרת אופטימיזציית עלות: משימות רגילות עוברות דרך מנוי Copilot (חינם עד התקרה), ומשימות מיוחדות דרך BYOK (חיוב לפי שימוש).
בדקו איזה סוג מנוי יש לכם: copilot auth status. אם יש לכם גם מפתח OpenAI או Anthropic, נסו ליצור סשן BYOK עם הדוגמה למעלה (שימו את המפתח במשתנה סביבה: export OPENAI_API_KEY=sk-...).
Streaming — תוצאות בזמן אמת
עד עכשיו השתמשנו ב-sendAndWait — שולחים פרומפט ומחכים שהתשובה כולה תגיע. זה פשוט, אבל לא אידיאלי לממשקי משתמש: אם התשובה ארוכה, המשתמש רואה מסך ריק ארוך ואז הכל מופיע בבת אחת.
עם Streaming, התשובה מגיעה חלק-אחרי-חלק (token by token), בדיוק כמו שאתם רגילים לראות ב-ChatGPT או ב-Copilot Chat.
הפעלת Streaming
const session = await client.createSession({
model: "claude-sonnet",
streaming: true // <-- זה כל מה שצריך
});
// האזנה לחלקי תשובה בזמן אמת
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.content); // הדפסה ללא ירידת שורה
});
// האזנה לסיום
session.on("session.idle", () => {
console.log("\n--- Response complete ---");
});
// שליחת הפרומפט (לא sendAndWait!)
await session.send({
prompt: "Write a detailed analysis of the package.json in this project"
});
ההבדל המרכזי: session.send() (לא sendAndWait) — שולח את הפרומפט ומיד חוזר. התשובה מגיעה דרך ה-event listeners.
אירועים זמינים
| אירוע | מתי נשלח | שימוש |
|---|---|---|
assistant.message_delta | כל חלק חדש של תשובה | הצגת טקסט בזמן אמת |
tool.call | האייג'נט קורא לכלי | לוגים, ניטור |
tool.result | כלי החזיר תוצאה | לוגים, debugging |
session.idle | סיום מלא של התשובה | ניקוי, UI update |
דוגמה מעשית: CLI app עם progress indicator
הנה דוגמה שלמה שמציגה progress בזמן שהאייג'נט עובד — מושלם ל-CLI tool:
let toolCallCount = 0;
let charCount = 0;
session.on("tool.call", (event) => {
toolCallCount++;
process.stdout.write(`\r🔧 Using tool: ${event.data.toolName} (#${toolCallCount})...`);
});
session.on("assistant.message_delta", (event) => {
if (charCount === 0) process.stdout.write("\r" + " ".repeat(60) + "\r"); // נקה שורת progress
process.stdout.write(event.data.content);
charCount += event.data.content.length;
});
session.on("session.idle", () => {
console.log(`\n\n--- Done! ${toolCallCount} tool calls, ${charCount} characters ---`);
});
המשתמש רואה: קודם "Using tool: read_file (#1)..." שמתעדכן, ואז כשהתשובה מתחילה — הטקסט זורם. זה חוויה טובה יותר מאשר מסך ריק שמחכה 30 שניות.
sendAndWait מול send — סיכום
| מתודה | מתי | יתרון | חיסרון |
|---|---|---|---|
sendAndWait() | סקריפטים, batch processing | פשוט, קוד נקי | אין feedback בזמן אמת |
send() + events | UI, CLI apps, ממשקי chat | חווית משתמש טובה, ניטור | יותר קוד, צריך event handlers |
העתיקו את דוגמת ה-Streaming, הריצו, וצפו בטקסט שזורם לטרמינל. עכשיו הוסיפו listener ל-tool.call שמדפיס: console.log(`[TOOL] ${event.data.toolName}(${JSON.stringify(event.data.args)})`) — כך תראו בדיוק מתי האייג'נט קורא לכלים.
זיכרון מתמשך ו-Infinite Sessions
בברירת מחדל, כל סשן ב-SDK חי בזיכרון. כשהתהליך נסגר — הכל נעלם. לפעמים זה בדיוק מה שרוצים. אבל יש שני מצבים שצריכים יותר:
Session Persistence — חידוש סשן
אם אתם רוצים לחדש סשן אחרי restart (למשל, אייג'נט שעובד על משימה ארוכה), ספקו sessionId ייחודי:
// סשן ראשון
const session = await client.createSession({
model: "gpt-4.1",
sessionId: "my-project-scan-001"
});
// ... עבודה ...
await session.disconnect(); // שומר מצב לדיסק, לא מוחק
// אחרי restart — חידוש
const resumed = await client.createSession({
model: "gpt-4.1",
sessionId: "my-project-scan-001" // אותו ID!
});
// הסשן ממשיך מאיפה שעצר
חשוב: disconnect() שומר את המצב לדיסק ומשחרר זיכרון. deleteSession() מוחק הכל לצמיתות. אל תתבלבלו ביניהם.
Infinite Sessions — סשנים ללא הגבלת אורך
כל מודל מוגבל ב-context window — כמות הטוקנים שהוא יכול "לראות" בבת אחת. כשהשיחה ארוכה מדי — למשל, אייג'נט שסורק 50 קבצים ומנתח כל אחד — ה-context מתמלא ואי אפשר להמשיך. Infinite Sessions פותרות את הבעיה: ה-SDK דוחס אוטומטית את ההיסטוריה — מסכם את מה שהיה ומשחרר מקום:
const session = await client.createSession({
model: "gpt-4.1",
infiniteSessions: {
enabled: true,
backgroundCompactionThreshold: 0.80, // התחל דחיסה ב-80%
bufferExhaustionThreshold: 0.95 // חובה לדחוס ב-95%
}
});
איך זה עובד:
- כשהקונטקסט מגיע ל-80% (
backgroundCompactionThreshold), ה-SDK מתחיל דחיסה ברקע — בלי לחסום אינטראקציה - כשמגיעים ל-95% (
bufferExhaustionThreshold), הדחיסה כפויה ומיידית - הדחיסה מסכמת את ההיסטוריה בצורה אינטליגנטית — החלטות ותוצאות נשמרות, דקויות ופרטים משניים נמחקים
מתי להשתמש בכל אפשרות?
| תרחיש | persistence? | infinite? | למה |
|---|---|---|---|
| סקריפט חד-פעמי | לא | לא | הסשן חי וימות עם התהליך |
| אייג'נט שרץ שעות | כן | כן | צריך לשרוד restart ו-context ארוך |
| Slack bot | כן (לכל user) | אפשרי | כל משתמש שומר את ההיסטוריה שלו |
| CI/CD pipeline | לא | לא | כל run הוא עצמאי |
| ניתוח ריפו גדול | אפשרי | כן | Context מתמלא מהר עם קבצים רבים |
disconnect() מול deleteSession() — אל תתבלבלו
ההבדל קריטי:
await session.disconnect()— משחרר זיכרון, שומר מצב לדיסק. אפשר לחדש אחר כך עם אותוsessionIdawait session.deleteSession()— מוחק הכל לצמיתות. אין חזרה
אם אתם לא בטוחים — השתמשו ב-disconnect(). תמיד אפשר למחוק אחר כך.
חשבו על אייג'נט שאתם רוצים לבנות. הוא חד-פעמי (סקריפט) או מתמשך (שירות)? אם מתמשך — איזו קומבינציה של persistence ו-infinite sessions תבחרו? כתבו שורה אחת: "האייג'נט שלי הוא [סוג], ולכן אני צריך [persistence: כן/לא] ו-[infinite: כן/לא]."
פרויקט: אייג'נט שסורק ריפוזיטורי ומייצר דוח
הגיע הזמן לחבר את כל מה שלמדתם לפרויקט אחד שלם. נבנה אייג'נט שסורק ריפוזיטורי ומייצר דוח Markdown מסודר — עם כלים מותאמים, MCP server, streaming ו-error handling.
הקוד המלא
import { CopilotClient, defineTool } from "@github/copilot-sdk";
import { readFileSync, writeFileSync, readdirSync, statSync } from "fs";
import { join, extname } from "path";
// === כלי 1: ספירת שורות ===
const countLines = defineTool("count_lines", {
description: "Count lines of code in a file",
parameters: {
type: "object",
properties: {
filePath: { type: "string", description: "Path to the file" }
},
required: ["filePath"]
},
handler: async (args: { filePath: string }) => {
const content = readFileSync(args.filePath, "utf-8");
const lines = content.split("\n");
return {
file: args.filePath,
totalLines: lines.length,
nonEmptyLines: lines.filter(l => l.trim()).length
};
}
});
// === כלי 2: ניתוח package.json ===
const parsePackageJson = defineTool("parse_package_json", {
description: "Parse package.json and extract key info",
parameters: {
type: "object",
properties: {
directory: { type: "string", description: "Project root directory" }
},
required: ["directory"]
},
handler: async (args: { directory: string }) => {
try {
const pkg = JSON.parse(readFileSync(join(args.directory, "package.json"), "utf-8"));
return {
name: pkg.name,
version: pkg.version,
dependencies: Object.keys(pkg.dependencies || {}),
devDependencies: Object.keys(pkg.devDependencies || {}),
scripts: Object.keys(pkg.scripts || {})
};
} catch {
return { error: "No package.json found" };
}
}
});
// === כלי 3: כתיבת דוח ===
const writeReport = defineTool("write_report", {
description: "Write a markdown report to a file",
parameters: {
type: "object",
properties: {
filePath: { type: "string", description: "Output file path" },
content: { type: "string", description: "Markdown content" }
},
required: ["filePath", "content"]
},
handler: async (args: { filePath: string; content: string }) => {
writeFileSync(args.filePath, args.content, "utf-8");
return { success: true, path: args.filePath, bytes: args.content.length };
}
});
// === הרצת האייג'נט ===
async function main() {
const client = new CopilotClient();
const session = await client.createSession({
model: "claude-sonnet",
streaming: true,
tools: [countLines, parsePackageJson, writeReport],
mcpServers: {
filesystem: {
type: "local",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", process.cwd()],
tools: ["*"]
}
}
});
// ניטור כלים
session.on("tool.call", (event) => {
console.log(`\n[TOOL] ${event.data.toolName}(${JSON.stringify(event.data.args).slice(0, 80)}...)`);
});
// Streaming output
session.on("assistant.message_delta", (event) => {
process.stdout.write(event.data.content);
});
// מחכים לסיום
const done = new Promise<void>((resolve) => {
session.on("session.idle", resolve);
});
// הפרומפט — מנחה את האייג'נט לסרוק ולדווח
await session.send({
prompt: `Scan this repository thoroughly. Use the following steps:
1. List all files and directories
2. Parse package.json for dependencies and scripts
3. Count lines of code in the top 10 largest source files
4. Identify the tech stack and architecture patterns
5. Write a comprehensive report to REPORT.md
Include: project overview, tech stack, file structure summary,
dependency analysis, code metrics, and 3 improvement suggestions.
Format as clean Markdown.`
});
await done;
console.log("\n\n=== Report generated! Check REPORT.md ===");
await client.stop();
process.exit(0);
}
main();
מה קורה כשמריצים:
- האייג'נט קורא את הפרומפט ומתכנן את המשימה
- משתמש בכלי ה-filesystem MCP כדי לסרוק את מבנה התיקיות
- קורא ל-
parse_package_jsonכדי להבין את ה-dependencies - קורא ל-
count_linesעל הקבצים הגדולים - מנתח את כל המידע ומייצר דוח
- קורא ל-
write_reportכדי לשמור את הדוח לקובץ
וכל זה — אוטונומית. אתם כותבים פרומפט אחד והאייג'נט מחליט איך לבצע.
שדרוג: הוספת סשן מרובה סיבובים
בגרסה מתקדמת יותר, אפשר לפצל את הפרויקט לכמה שלבים ולנהל שיחה מרובת סיבובים:
// שלב 1: סריקה ואיסוף נתונים
await session.send({ prompt: "First, scan the project structure and list all source files" });
await waitForIdle(session);
// שלב 2: ניתוח מעמיק (הסשן זוכר את שלב 1!)
await session.send({ prompt: "Now analyze the top 5 largest files for code quality" });
await waitForIdle(session);
// שלב 3: כתיבת הדוח
await session.send({ prompt: "Write a comprehensive REPORT.md based on everything you found" });
await waitForIdle(session);
היתרון: כל שלב בנוי על התוצאות של הקודם. האייג'נט מצטבר ידע ומייצר דוח עשיר יותר. זה בדיוק הכוח של סשנים stateful — השיחה שומרת context, ולא צריך לחזור על מידע שכבר נאסף.
הרחבה: הוספת כלי analyze_deps
לסורק ריפוזיטורי מלא, שווה להוסיף כלי שמנתח dependencies. הנה דוגמה:
const analyzeDeps = defineTool("analyze_deps", {
description: "Analyze node_modules to count installed packages and find outdated ones",
parameters: {
type: "object",
properties: {
directory: { type: "string", description: "Project root directory" }
},
required: ["directory"]
},
handler: async (args: { directory: string }) => {
const nodeModules = join(args.directory, "node_modules");
try {
const packages = readdirSync(nodeModules)
.filter(d => !d.startsWith("."));
return {
totalPackages: packages.length,
scopedPackages: packages.filter(d => d.startsWith("@")).length,
topLevel: packages.slice(0, 20)
};
} catch {
return { error: "node_modules not found. Run npm install first." };
}
}
});
שימו לב ל-error handling — אם node_modules לא קיים (למשל, אחרי git clone בלי npm install), הכלי מחזיר הודעת שגיאה ידידותית במקום crash.
התמודדות עם שגיאות בפרויקט
בפרויקט אמיתי, דברים ישברו. הנה כמה תרחישים נפוצים:
- הכלי מחזיר שגיאה: האייג'נט ינסה גישה אחרת או ידווח על הבעיה. לא צריך לטפל ב-handler — המודל מתמודד
- הקובץ לא קיים: ודאו שה-handler שלכם מחזיר הודעת שגיאה ברורה (לא crash).
return { error: "File not found" }עדיף על exception - Timeout: הוסיפו timeout ל-handlers ארוכים. אייג'נט שתקוע על כלי אחד חוסם את כל השיחה
לפני שמתחילים את התרגילים — ודאו שהסביבה מוכנה: הריצו copilot auth status (מאומת?), node --version (18+?), npx tsx --version (עובד?). אם אחד מהם נכשל — תקנו לפני שממשיכים.
מטרה: לבנות אייג'נט SDK ראשון עם כלי מותאם שעובד.
- צרו תיקיית פרויקט חדשה והריצו
npm init -y && npm install @github/copilot-sdk tsx - צרו קובץ
agent.tsעםCopilotClientבסיסי (העתיקו מדוגמת Hello World מסעיף ההתקנה) - הגדירו כלי מותאם בשם
count_filesשמקבל נתיב תיקייה ומחזיר ספירת קבצים לפי סיומת (השתמשו בדוגמה מסעיף "כלים מותאמים") - הוסיפו כלי נוסף בשם
get_file_sizeשמחזיר גודל קובץ בבייטים. הנה הקוד:const getFileSize = defineTool("get_file_size", { description: "Get the size of a file in bytes", parameters: { type: "object", properties: { filePath: { type: "string", description: "Path to the file" } }, required: ["filePath"] }, handler: async (args: { filePath: string }) => { const stats = statSync(args.filePath); return { file: args.filePath, sizeBytes: stats.size, sizeKB: Math.round(stats.size / 1024), lastModified: stats.mtime.toISOString() }; } }); - רשמו את שני הכלים ב-
tools: [countFiles, getFileSize] - שלחו פרומפט:
"Analyze the current directory. Count all files by type, find the largest file, and summarize."
תוצאה צפויה: האייג'נט ישתמש בשני הכלים ויציג סיכום עם ספירת קבצים וגודל הקובץ הגדול ביותר. שימו לב לסדר הקריאות — האייג'נט אמור קודם לספור קבצים, אז לבדוק גודל של כל אחד, ואז לסכם.
נקודת בדיקה: אם הכלי לא נקרא — בדקו את ה-description. אם הוא לא ברור מספיק, המודל לא ידע מתי להשתמש בו.
מטרה: לחבר MCP server לאייג'נט SDK ולהפעיל streaming.
- התחילו מהקוד של תרגיל 1 — אותו פרויקט, אותם כלים מותאמים
- הוסיפו את ה-filesystem MCP server לתוך
createSession:mcpServers: { filesystem: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", process.cwd()], tools: ["*"] } } - הפעילו
streaming: trueב-createSession - הוסיפו listeners:
assistant.message_delta— הדפסת תשובה:process.stdout.write(event.data.content)tool.call— לוג כלים:console.log(`\n[TOOL] ${event.data.toolName}`)session.idle— סיום:console.log("\n--- Done ---")
- שנו ל-
session.send()(לא sendAndWait!) ושלחו פרומפט:"Read the package.json and README.md files, then write a 3-paragraph summary of this project."
תוצאה צפויה: תראו את התשובה זורמת בזמן אמת, עם לוגים של קריאות כלים בזמן שהאייג'נט עובד. שימו לב לרגע שה-streaming עובר מ-"waiting for tool result" לטקסט זורם — זה הרגע שהלולאה האגנטית חוזרת מהכלי למודל.
אתגר נוסף: הוסיפו timer שמודד כמה שניות עברו מתחילת הבקשה עד סיומה. השתמשו ב-Date.now() לפני ואחרי.
שיקולי Production — מ-prototype לפרודקשן
הקוד שכתבתם עובד מצוין ב-development. אבל לפני שמריצים אותו ב-production — ב-cron job, ב-CI/CD, או כשירות — צריך להתייחס לכמה נקודות קריטיות:
1. Rate Limits
Copilot מגביל שימוש כדי למנוע עומס. כשפוגעים ב-rate limit, אתם מקבלים שגיאה זמנית. הגישה חוזרת אחרי כמה דקות, אבל אייג'נט אוטומטי צריך לדעת לטפל בזה:
async function sendWithRetry(session: any, prompt: string, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await session.sendAndWait({ prompt });
} catch (error: any) {
if (error.status === 429 && attempt < maxRetries) {
const waitTime = Math.pow(2, attempt) * 1000; // exponential backoff
console.log(`Rate limited. Waiting ${waitTime/1000}s...`);
await new Promise(r => setTimeout(r, waitTime));
} else {
throw error;
}
}
}
}
2. Error Handling
לעטוף כל אינטראקציה ב-try/catch. סוגי שגיאות נפוצים:
| שגיאה | סיבה | פתרון |
|---|---|---|
| 429 (Rate Limit) | יותר מדי בקשות | Exponential backoff |
| 401 (Unauthorized) | אימות לא תקין | בדקו copilot auth status |
| Connection Error | CLI לא מותקן/מופעל | ודאו ש-copilot בנתיב |
| Tool Timeout | Handler של כלי מותאם לא חוזר | הוסיפו timeout ל-handler |
3. שכבת הפשטה (Abstraction Layer)
ה-SDK ב-Technical Preview. ה-API עשוי להשתנות. אל תפזרו קריאות SDK בכל הקוד — צרו wrapper:
// agent-wrapper.ts — שכבת הפשטה
export class MyAgent {
private client: CopilotClient;
private session: any;
async init(model: string, tools: any[]) {
this.client = new CopilotClient();
this.session = await this.client.createSession({ model, tools });
}
async ask(prompt: string): Promise<string> {
const response = await sendWithRetry(this.session, prompt);
return response?.data.content || "";
}
async cleanup() {
await this.client.stop();
}
}
כשה-SDK ישתנה, תתקנו רק ב-agent-wrapper.ts — לא בכל הקוד.
4. עלות — חישוב שכדאי לעשות מראש
כל פרומפט שהאייג'נט שולח צורך premium requests לפי מכפיל המודל. בואו נעשה חשיבון מהיר:
| תרחיש | הרצות/יום | מודל | מכפיל | קרדיטים/יום | קרדיטים/חודש |
|---|---|---|---|---|---|
| סורק PR | 20 | Claude Sonnet | 1x | 20 | 600 |
| סורק PR (חסכוני) | 20 | GPT-4.1 mini | 0.25x | 5 | 150 |
| ניתוח ריפו | 2 | GPT-4.1 | 1x | 2 | 60 |
| בוט Slack | 50 | Claude Haiku | 0.25x | 12.5 | 375 |
Pro (300 קרדיטים/חודש) מספיק ל"סורק PR חסכוני" + "ניתוח ריפו". Pro+ (1,500 קרדיטים) מספיק לכל הארבעה. מעבר לתקרה — $0.04 לכל premium request נוסף.
אסטרטגיית חיסכון:
- השתמשו במודלים 0x/0.25x למשימות פשוטות (סיווג, תיוג, formatting)
- שמרו מודלים 1x למשימות שדורשות חשיבה (ניתוח, כתיבת קוד)
- שמרו מודלים יקרים (GPT-5, Claude Opus) לתרחישים שבאמת דורשים חשיבה עמוקה
- שקלו BYOK אם הנפח גבוה — לפעמים חיוב ישיר לספק זול יותר מ-$0.04/request
- הוסיפו cache לתשובות חוזרות — אם אותה שאלה חוזרת, אל תקראו למודל שוב
5. לוגים וניטור
אייג'נט אוטומטי שרץ בלי פיקוח יכול לייצר תוצאות גרועות בלי שתדעו. הוסיפו לוגים מהיום הראשון:
import { appendFileSync } from "fs";
function log(level: string, message: string, data?: any) {
const entry = JSON.stringify({
timestamp: new Date().toISOString(),
level,
message,
data
});
appendFileSync("agent.log", entry + "\n");
if (level === "error") console.error(message);
}
// שימוש
session.on("tool.call", (event) => {
log("info", `Tool called: ${event.data.toolName}`, event.data.args);
});
session.on("tool.result", (event) => {
log("info", `Tool result`, { tool: event.data.toolName, success: !event.data.error });
});
בדקו את agent.log כל בוקר. חפשו שגיאות, rate limits, וכלים שנקראו בצורה לא צפויה.
6. Technical Preview — מה צפוי להשתנות?
ה-SDK בסטטוס Technical Preview מינואר 2026. בהתבסס על דפוסים מוכרים של GitHub, הנה מה צפוי:
- שמות מתודות: עשויים להשתנות.
sendAndWaitיכול להפוך ל-sendעם פרמטר. לכן — wrapper - הגדרת כלים: ה-schema של
defineToolעשוי להתרחב (למשל, הוספת metadata). לא סביר שיישבר לחלוטין - אימות: BYOK צפוי לתמוך ב-OAuth ו-managed identities — היום רק static tokens
- מודלים: חדשים יתווספו, ישנים יוסרו. שם המודל ב-SDK ישתנה. אל תעשו hard-code
העיקרון: כל מה שיכול להשתנות — הפרידו לקובץ config או ל-wrapper. מה שלא סביר שישתנה (הקונספט של client, session, send) — כנראה יישאר.
7. סיכום: רשימת בדיקה ל-Production Launch
לפני שמעלים אייג'נט SDK ל-production, וודאו:
- ☐ Abstraction layer: יש wrapper שמפריד את קוד ה-SDK מהלוגיקה העסקית
- ☐ Error handling: כל קריאה עטופה ב-try/catch עם retry
- ☐ Rate limit handling: exponential backoff מוגדר
- ☐ לוגים: tool.call, tool.result, errors — הכל נשמר לקובץ
- ☐ עלות: חישוב חודשי עם מודל, תדירות, ומכפיל
- ☐ Secrets: מפתחות API במשתני סביבה, לא בקוד
- ☐ client.stop(): נקרא תמיד בסיום — גם במקרה שגיאה (finally block)
- ☐ מודל נכון: מודל זול למשימות פשוטות, יקר רק למורכבות
כמפתחים, אנחנו אוהבים לעבוד ישירות עם ה-API. אבל כשהסטטוס הוא Technical Preview, הממשק ישתנה. מפתחים שמפזרים קריאות CopilotClient ב-20 קבצים יצטרכו לתקן ב-20 מקומות. מפתחים שיוצרים wrapper מתקנים במקום אחד. תמיד צרו שכבת הפשטה.
| תרחיש | הכלי הנכון | למה |
|---|---|---|
| משימה חד-פעמית בזמן פיתוח | Agent Mode (VS Code) | הכי מהיר, לא צריך קוד |
| סקריפט אוטומציה שרץ ב-cron | CLI | הפעלה מטרמינל, בלי UI |
| אוטומציה משובצת באפליקציה | SDK | שליטה מלאה, כלים מותאמים |
| ממשק משתמש מותאם (chat UI) | SDK | streaming, events, UI control |
| CI/CD pipeline — PR review | SDK + GitHub Actions | אינטגרציה עם workflow |
| Slack bot שעונה על שאלות קוד | SDK | חיבור ל-API חיצוני + כלים |
כלל אצבע: אם צריך כלים מותאמים או ממשק מותאם — SDK. אם מספיק CLI command — CLI. אם זה interactive בזמן פיתוח — Agent Mode.
| סוג משימה | מודל מומלץ | מכפיל | הנימוק |
|---|---|---|---|
| סיווג, תיוג, מיון | GPT-4.1 mini / Claude Haiku | 0.25x | זול, מהיר, מספיק למשימות פשוטות |
| כתיבת קוד, ניתוח | GPT-4.1 / Claude Sonnet | 1x | איזון בין יכולת לעלות |
| ארכיטקטורה, תכנון מורכב | GPT-5 / Claude Opus | גבוה | שמרו ליד משימות שבאמת דורשות חשיבה עמוקה |
| קונטקסט ארוך מאוד | Gemini 2.5 Pro | 1x | חלון קונטקסט גדול, multi-modal |
אסטרטגיה: התחילו עם מודל זול (0.25x), בדקו את התוצאות. שדרגו למודל יקר יותר רק אם האיכות לא מספקת. רוב המשימות האוטומטיות לא צריכות את המודל החזק ביותר.
מטרה: לבנות אייג'נט מלא שסורק ריפוזיטורי ומייצר דוח — עם כל מה שלמדתם בפרק.
- צרו פרויקט חדש:
mkdir repo-scanner && cd repo-scanner && npm init -y && npm install @github/copilot-sdk tsx - העתיקו את הקוד המלא מסעיף "פרויקט: אייג'נט שסורק ריפוזיטורי" למעלה
- הוסיפו כלי רביעי:
analyze_deps— שקורא אתnode_modulesוסופר כמה חבילות מותקנות - הוסיפו
sendWithRetryמסעיף Production במקוםsession.sendישיר - הוסיפו abstraction layer: צרו
agent-wrapper.tsוייבאו אותו ב-repo-scanner.ts - הריצו על ריפוזיטורי אמיתי שלכם (גם קטן בסדר)
- בדקו את קובץ
REPORT.mdשנוצר — האם המידע מדויק? - בונוס: שנו את המודל ל-
gpt-4.1-miniוהשוו את איכות הדוח. שימו לב להבדל בעלות (0.25x מול 1x)
תוצאה צפויה: קובץ REPORT.md מפורט שכולל: סיכום פרויקט, tech stack, מבנה קבצים, ניתוח dependencies, מדדי קוד, ו-3 הצעות לשיפור. אם עובדים עם streaming — תראו את הכל בזמן אמת בטרמינל.
שגרת עבודה
| תדירות | משימה | זמן |
|---|---|---|
| יומי | בדקו לוגים של אייג'נטים אוטומטיים — שגיאות, rate limits, תוצאות | 5 דקות |
| יומי | בדקו צריכת premium requests — שהאייג'נטים לא שורפים קרדיטים | 2 דקות |
| שבועי | סקירת איכות דוחות/תוצאות שאייג'נטים ייצרו — האם המודל הנכון נבחר | 15 דקות |
| שבועי | בדקו עדכוני SDK — npm outdated @github/copilot-sdk | 5 דקות |
| שבועי | נסו מודל חדש/שונה על אחד האייג'נטים — האם יש שיפור? | 10 דקות |
| חודשי | סקירת ארכיטקטורה: האם צריך להוסיף/להסיר כלים מותאמים? | 30 דקות |
| חודשי | בדקו שה-abstraction layer מעודכן ומכסה את כל שימושי ה-SDK | 20 דקות |
אם אתם עושים רק דבר אחד
צרו פרויקט Node.js, התקינו @github/copilot-sdk, והריצו את דוגמת ה-Hello World. 5 דקות. אחרי שזה עובד — הוסיפו כלי מותאם אחד. ברגע שאתם רואים את האייג'נט קורא לכלי שאתם כתבתם — הבנתם את הרעיון. הכל אחרי זה הוא הרחבה.
בדקו את עצמכם
- למה ה-SDK משתמש ב-Copilot CLI מאחורי הקלעים, ומה ההשלכה על דרישות ההתקנה? (רמז: חשבו מה קורה אם CLI לא מותקן)
- מה ההבדל בין
sendAndWaitל-sendעם streaming, ומתי תבחרו כל אחד? (רמז: חשבו על UX מול פשטות קוד) - למה חשוב ליצור שכבת הפשטה (wrapper) מעל ה-SDK, ומה יקרה בלעדיה? (רמז: מה הסטטוס של ה-SDK — ומה זה אומר על API stability)
- איך infinite sessions מטפלות בבעיית context window, ומה ה-tradeoff? (רמז: מה נאבד בדחיסה)
- מתי עדיף BYOK על Copilot Subscription, ומה החיסרון המרכזי? (רמז: חשבו על ניהול מפתחות ואבטחה)
סיכום הפרק
בפרק הזה עשיתם מעבר מהותי: ממשתמשים של Copilot לבונים עם Copilot. גיליתם שאותה לולאה אגנטית שמפעילה את Copilot CLI — תכנון, בחירת כלי, הפעלה, בדיקת תוצאה — זמינה כספריה שאפשר לייבא לכל אפליקציה. למדתם להגדיר כלים מותאמים עם defineTool שהאייג'נט קורא להם אוטונומית, לחבר MCP servers מסוג STDIO ו-HTTP, לבחור מודלים בצורה חכמה שחוסכת קרדיטים עם אסטרטגיית multi-model, ולהגדיר אימות — גם דרך Copilot subscription וגם BYOK ישיר מול OpenAI, Anthropic ואחרים. בניתם אייג'נט שלם שסורק ריפוזיטורי ומייצר דוח Markdown, עם streaming בזמן אמת ו-error handling. והכי חשוב — הבנתם שב-Technical Preview צריך שכבת הפשטה כדי לא להישבר כש-API משתנה, ותכננתם אסטרטגיית עלות שתכסה אתכם ב-production.
המעבר מ"משתמש Copilot" ל"בונה עם Copilot" הוא לא רק שדרוג טכני — זו שינוי פרספקטיבה. עם ה-SDK, כל בעיה שחוזרת על עצמה הופכת לאייג'נט שפותר אותה אוטומטית. כל workflow ידני הופך ל-automation. וכל זה עם אותו מנוע battle-tested שכבר הוכיח את עצמו ב-Copilot CLI.
בפרק הבא — פרק 12 ואחרון — תשלבו את כל הכלים שלמדתם: SDK, CLI, Agent Mode, GitHub.com, וסוכני צד שלישי (Claude, Codex) — בזרימת עבודה אחת מקצה לקצה שפותרת בעיה אמיתית מקצה לקצה.
- ☐ התקנתי
@github/copilot-sdkבפרויקט Node.js - ☐ הרצתי את דוגמת Hello World ראשונה וקיבלתי תשובה
- ☐ הגדרתי כלי מותאם (
defineTool) והאייג'נט קרא לו אוטונומית - ☐ חיברתי MCP server (STDIO) לסשן SDK
- ☐ ניסיתי לפחות 2 מודלים שונים (למשל
gpt-4.1ו-claude-sonnet) - ☐ הגדרתי streaming ורשמתי listener ל-
assistant.message_delta - ☐ הבנתי את ההבדל בין Copilot Subscription ל-BYOK
- ☐ כתבתי או קראתי את הקוד המלא של פרויקט סורק הריפוזיטורי
- ☐ הוספתי error handling עם retry ו-exponential backoff
- ☐ יצרתי (או תכננתי) שכבת הפשטה (wrapper) מעל ה-SDK
- ☐ השלמתי לפחות 2 מתוך 3 התרגילים
- ☐ הרצתי את ה-Capstone על ריפוזיטורי אמיתי וקיבלתי REPORT.md