- Worker חי עם 3 routes שקוראים ל-
AI.run(): completion (glm-4.7-flash), embedding (bge-small, 384-dim), ו-image (flux-1-schnell) — שלושתם על URL ציבורי. - RAG chatbot חי על המסמכים האישיים שלך: Vectorize + Workers AI + D1 ל-metadata, עם תשובה מוזרמת (streaming), כולו ב-free tier.
- טבלת neuron-budget אישית: לכל מודל → כמה neurons לקריאה → כמה קריאות נשארות לך מתוך 10,000 ביום.
- החלטה מודעת בין Vectorize (DIY, שליטה מלאה) ל-AI Search (מנוהל, אפס תשתית) — לפי הפרויקט שלך.
- endpoint
/v1/chat/completionsתואם-OpenAI שעוטף את Workers AI, עם מונה rate-limit ב-KV שמחזיר 429 בחציית סף — כל כלי שמדבר OpenAI מצביע עליו. wrangler.tomlמורחב: אותו קובץ מפרק 2, עכשיו עם[ai]ו-[[vectorize]]נוספים ל-bindings הקיימים.- רשימת מודלי ה-GA לשימוש ב-2026 (ומה הוסר) — שמורה ב-README, כי זה הפקט הכי מהיר-להשתנות בקורס.
- להריץ inference מ-Worker על Workers AI — chat (מודל GA), embedding (
bge) ו-image (Flux) — ולחשב כמה קריאות נשארות מתוך 10,000 neurons ביום. - לבנות RAG pipeline מלא: chunk → embed → אחסון ב-Vectorize → query → top-k → context → תשובה מבוססת-מקור (לא הזיה).
- להחליט בין Vectorize (DIY, ~13,020 מסמכים חינם) ל-AI Search (מנוהל, 20,000 שאילתות/חודש) לפי tolerance למורכבות ול-real-time.
- לזהות מודל deprecated לפני שמקבעים אותו בקוד, ולנתב Workers AI דרך AI Gateway ל-caching שחוסך neurons.
- סיימת את פרק 2: יש לך Worker חי עם
wrangler.tomlשכבר מכיל bindings של KV ו-D1 (ואולי R2). נשתמש בהם מחדש כאן. - אתה זוכר את
npx wrangler devו-npx wrangler deployמפרק 1, ויודע לקרוא TypeScript (לא לכתוב מאפס). - חשבון Cloudflare חינמי — אותו אחד מפרק 1. אין צורך בכרטיס אשראי כדי לגעת ב-Workers AI.
- אזהרה לפני שמתחילים: זה הפרק הכי רגיש-לזמן בקורס. שמות מודלים ומספרי neurons משתנים תכופות — תמיד אמת מול הקטלוג והדף הרשמי לפני שמקבעים string בקוד.
הפרק הקודם (פרק 2 — Workers ו-Storage): סיימת עם Worker חי + wrangler.toml שכבר מכיל bindings של KV / D1 / R2 / Durable Objects, אתה מבין את קיר ה-10ms CPU ואת המגבלה החינמית של כל primitive.
הפרק הזה: ממשיכים על אותו Worker ו-אותו wrangler.toml — מוסיפים binding [ai] (ובהמשך [[vectorize]]), משתמשים מחדש ב-D1 לאחסון טקסט ה-chunks וב-KV ל-rate-limiting. בונים RAG chatbot חי וגם facade תואם-OpenAI.
הפרק הבא (פרק 4 — שכבת media ב-$0): R2 + Image Transforms ל-CDN תמונות, Browser Run ל-screenshot API, ו-Cloudflare Calls לווידאו. תיכנס לשם כשבידך כבר יכולת image generation מ-Flux, ו-R2 binding שכבר מוצהר מפרק 2.
| מונח | בעברית | הסבר |
|---|---|---|
| Workers AI | וורקרז AI | פלטפורמת inference של Cloudflare שמריצה מודלים hosted על GPU ב-edge (200+ ערים). קוראים אליה מ-Worker דרך binding [ai] → env.AI.run(modelId, options). 10,000 neurons ביום חינם. |
| Neurons | נוירונים | יחידת compute שמנרמלת את מחיר ה-AI inference על פני מודלים שונים. ה-free tier הוא 10,000 neurons ביום (reset 00:00 UTC), overage $0.011 ל-1,000. רוב ה-burn מגיע מ-output tokens. |
| AI.run() binding | בּיינדינג AI | ה-API לקריאת מודל מ-Worker: env.AI.run("@cf/...", { messages | text | prompt, max_tokens, stream }). ה-binding מוגדר ב-wrangler.toml בבלוק [ai] עם binding = "AI". |
| hosted vs proxied | מאוחסן מול מתווך | hosted = מודלים שרצים על ה-GPU של Cloudflare ונספרים מול 10k neurons/day החינמיים. proxied = ניתוב דרך AI Gateway לספק חיצוני (OpenAI/Anthropic) — 0 neurons חינמיים, מחויב אצל הספק. |
| glm-4.7-flash | — | @cf/zai-org/glm-4.7-flash — מודל chat GA קטן, מהיר ורב-לשוני (כולל עברית) עם tool-calling. ברירת המחדל של הקורס ל-free tier, החליפה את llama-3.1-8b שהוסר ב-2026-05-30. |
| model deprecation | הסרת מודל | מודל מסומן להסרה (deprecation date) ואז מפסיק לעבוד או מבצע auto-substitution שקטה. ב-2026-05-30 הוסרו 18 מודלים כולל llama-3.1-8b/70b. variants עם -fast/-lora נשארים. השתמש רק ב-GA ובדוק את הקטלוג החי. |
| bge embeddings | — | משפחת מודלי embedding של BAAI: bge-small-en-v1.5 (384 dims, אנגלית, מקסימום מסמכים חינם), bge-base (768), bge-large (1024), bge-m3 (1024, רב-לשוני). ה-dims של הוקטור חייבים להתאים ל-Vectorize index. |
| Flux-1-schnell | — | @cf/black-forest-labs/flux-1-schnell — מודל יצירת תמונות GA (12B transformer). env.AI.run מחזיר bytes של תמונה. ~130 תמונות ביום בתקציב 10k neurons (תלוי tiles × steps). |
| Vectorize | וקטורייז | vector DB מנוהל של Cloudflare ל-RAG. חיוב לפי dimensions לא לפי מסמכים: 5M stored + 30M queried dims/חודש חינם. ה-dims נקבעים בעת יצירת ה-index (--dimensions) ואי אפשר לשנותם במקום. |
| vector dimensions billing | חיוב לפי ממדים | Vectorize נמדד לפי סך ה-dims המאוחסנים/נשאלים, לא לפי מספר מסמכים: 5M / 384 ≈ 13,020 מסמכים, / 768 ≈ 6,510, / 1024 ≈ 4,883. מודל embedding גדול יותר = פחות מסמכים חינם. |
| RAG | שליפה-מוגברת-יצירה | Retrieval-Augmented Generation: embed מסמכים לוקטורים, על שאלה embed אותה, מצא top-k דומים, הזרק את הטקסט שלהם כ-context ל-LLM כדי לקבל תשובה מבוססת-מקור במקום הזיה. |
| top-k similarity | k הדומים ביותר | שליפת k הוקטורים הקרובים ביותר לוקטור השאלה (VECTORIZE.query(vector, {topK})) לפי מטריקת דמיון (cosine). ה-chunks המתאימים הם ה-context שמוזרק ל-LLM. |
| AI Search | חיפוש מנוהל (RAG) | RAG-as-a-service של Cloudflare (open beta, אפריל 2026): crawl+chunk+embed+index אוטומטי. 20k שאילתות/חודש, 500 דפים/יום חינם. נקרא דרך [[ai_search]] binding (לא autorag() ה-deprecated). indexing בעיכוב יום — לא ל-real-time. |
| AI Gateway | שער AI | שכבת proxy/cache/observability מול ספקי AI. 100,000 logs לכל החשבון (לא פר-gateway); caching ו-rate limiting חינם. ניתוב Workers AI דרכה בשינוי config יחיד חוסך neurons על תשובות חוזרות. |
| rate limit (~300 req/min) | מגבלת קצב | מגבלת הקצב של Workers AI: ברירת מחדל ~300 בקשות לדקה ל-text generation, אך משתנה 150–1,500 לפי מודל. לא קבוע אוניברסלי — לבדוק לפי המודל. |
למה הפרק הזה: מ-API key חיצוני ל-inference שכבר משולם ב-$0
אם אתה Vibe Coder, סביר שכבר הרצת AI דרך API — מפתח של OpenAI או Anthropic, קריאת fetch לענן, וחיוב לפי tokens שמטפס בשקט. זה עובד מצוין, אבל יש שם שני דברים שכואבים: צריך לנהל מפתח סודי, וכל קריאה עולה כסף מהשנייה הראשונה. בפרק הזה אנחנו עוברים למודל אחר לגמרי — ה-inference כבר משולם, והוא יושב בתוך אותו Worker שכבר פרסת.
Workers AI (וורקרז AI) היא פלטפורמת inference של Cloudflare. במקום שאתה תרים שרת עם GPU או תשלם לספק חיצוני, Cloudflare מחזיקה מודלים hosted — כלומר רצים על ה-GPU שלה — ב-200+ ערים ב-edge. אתה קורא אליהם מ-Worker בשורה אחת: env.AI.run(modelId, options). אין שרת לנהל, אין מפתח חיצוני, וה-free tier נותן לך 10,000 neurons ביום — מספיק לאפליקציה אמיתית, אם יודעים לנהל אותו.
הקשר לפרק 2 ישיר ופשוט: אותו Worker, אותו wrangler.toml. בפרק 2 הוספת bindings של KV, D1 ו-R2 — כאן אתה מוסיף עוד אחד, [ai], ופתאום ל-Worker שלך יש מוח. אתה לא בונה פרויקט חדש; אתה מרחיב את הקיים.
מה תבנה עד סוף הפרק
שני דברים מוחשיים. הראשון: Worker שקורא ל-AI.run() ל-3 משימות — מייצר טקסט (completion), מייצר embedding (וקטור מספרי שמייצג טקסט), ומייצר תמונה. השני, והגדול: RAG chatbot חי שעונה על שאלות מתוך המסמכים שלך — לא מהזיכרון של המודל, אלא מטקסט שאתה הזנת. זו בדיוק היכולת שהופכת "צ'אט גנרי" ל"עוזר שיודע את מה שאתה יודע".
למה זה משנה דווקא ל-Vibe Coder
כשאתה בונה עם Claude Code או Cursor, ה-AI כותב לך את הקוד. אבל ברגע שהאפליקציה עצמה צריכה AI בזמן ריצה — צ'אט שמדבר עם המשתמש, סיכום אוטומטי, חיפוש סמנטי — אתה צריך מקור inference שרץ בשרת, לא ב-IDE שלך. עד היום הברירה היחידה היתה לשלם לספק חיצוני מהקריאה הראשונה. עכשיו יש לך אלטרנטיבה שיושבת באותו Worker, באותו deploy, ובאותו חשבון חינמי — וזה משנה את חשבון העלות של כל פרויקט צד שאתה מתחיל. אפליקציית demo שמראים ללקוח לא צריכה כרטיס אשראי כדי לדבר.
ועוד נקודה מעשית: כי ה-inference רץ ב-edge — באותם 200+ ערים שבהם רץ ה-Worker — ה-latency נמוך. אין hop נוסף לשרת מרכזי של ספק שלישי; המודל קרוב פיזית למשתמש. לאפליקציה אינטראקטיבית (צ'אט שמזרים תשובה) זה ההבדל בין תחושת "מיידי" ל"תקוע".
הערה על המספרים בפרק: כל שמות המודלים, ספירת ה-neurons והמגבלות אומתו מול התיעוד הרשמי בתאריך הכנת הפרק (מאי 2026). זה התחום שמשתנה הכי מהר בכל הקורס — תראה לאורך הדרך שאני שולח אותך לאמת מול הקטלוג החי, ולא לזכור מספר.
פתח את https://dash.cloudflare.com → AI → Workers AI → Playground. בחר את המודל @cf/zai-org/glm-4.7-flash ושלח prompt קצר בעברית ("כתוב משפט אחד על Cloudflare"). ודא שחזרה תשובה — זה בדיוק ה-inference שתפעיל מקוד עוד מעט, רק שכאן עשית אותו בלחיצה.
Neurons מוסברים: מה זה, כמה יש, ומתי הקיר נופל
לפני שכותבים שורת קוד אחת, חייבים להבין את המטבע. ב-Workers AI לא סופרים "קריאות" ולא "tokens" ישירות — סופרים neurons (נוירונים). neuron הוא יחידת compute שמנרמלת את מחיר ה-inference על פני מודלים שונים, כך שאפשר לתת מכסה אחת שמכסה את הכל: מודל טקסט גדול, מודל קטן, embedding ויצירת תמונה — כולם נמדדים באותה מטבע.
ה-free tier נדיב ופשוט לזכור: 10,000 neurons ביום, בחינם. המספר הזה זהה גם ב-Workers Free וגם ב-Workers Paid — כלומר אתה מקבל אותו בלי לשלם $5 בכלל. כל המגבלות מתאפסות מדי יום ב-00:00 UTC (לא לפי השעון המקומי שלך — שים לב אם אתה בישראל, זה 02:00–03:00 בלילה אצלך). עוברים את ה-10,000? ה-overage הוא $0.011 לכל 1,000 neurons נוספים — זול, אבל הנקודה של הקורס הזה היא להישאר בתוך החינם.
למה Cloudflare המציאה יחידה חדשה במקום פשוט לחייב לפי tokens, כמו כולם? כי Workers AI מריץ סוגי מודלים שונים מאוד: מודל שפה שמודד tokens, מודל תמונה שמודד tiles ו-steps, מודל אודיו שמודד דקות. אין מטבע משותף בין "1,000 tokens" ל"דקת אודיו" ל"תמונה 1024×1024". ה-neuron הוא המכנה המשותף — הוא משקף את ה-compute בפועל על ה-GPU. ככה מכסה אחת (10,000) מכסה את כל סוגי העבודה, ואתה לא צריך לנהל ארבעה מונים נפרדים. החיסרון: צריך לתרגם — כמה neurons עולה הקריאה שלי? זה בדיוק מה שנעשה בסעיף הבא.
למה זה מפתה: אתה רואה גרף יפה בדשבורד שמראה כמה neurons ניצלת, ומניח שהוא מקור האמת.
למה זה טעות: יש דיווח operational (לא תיעוד רשמי) שגרף השימוש עלול להראות 0 neurons בזמן שה-API כבר מחזיר error 4006 ("daily limit exceeded"). הגרף מתעדכן באיחור; השגיאה אמיתית עכשיו.
מה לעשות במקום: סמוך על 4006. אם הקוד שלך מקבל את השגיאה הזו — נגעת בקיר, גם אם הגרף אומר אחרת. תכנת fallback (תשובה ידידותית למשתמש) לקוד 4006, ואל תחכה שהגרף יאשר.
איך מטפלים ב-4006 בקוד? עוטפים את קריאת ה-AI ב-try/catch ובודקים את הקוד. אם נגעת בקיר היומי, אתה לא רוצה שהמשתמש יראה stack trace — אתה רוצה תשובה ידידותית, ואולי fallback. דוגמה מייצגת:
try {
const res = await env.AI.run("@cf/zai-org/glm-4.7-flash", { messages, max_tokens: 512 });
return Response.json(res);
} catch (err) {
// 4006 = daily neuron limit exceeded — סמוך על השגיאה, לא על הגרף
if (String(err).includes("4006")) {
return new Response("שירות ה-AI הגיע למכסה היומית, נסה שוב אחרי 00:00 UTC", { status: 503 });
}
throw err; // שגיאה אחרת — תן לה לעלות
}
ההרגל הזה — לתפוס את 4006 ולהחזיר הודעה אנושית — הוא ההבדל בין אפליקציה שנראית שבורה לבין אפליקציה שמתנהגת יפה כשהיא נוגעת בגבול החינמי. זכור: זה גבול יומי שמתאפס, לא תקלה. תכנן לזה.
הבחנה קריטית: hosted מול proxied
זו אחת ההבחנות החשובות בכל הפרק, כי היא קובעת אם אתה משלם או לא. יש שני סוגי מודלים שאתה יכול לקרוא להם דרך התשתית של Cloudflare:
- hosted (מאוחסן) — מודלים שרצים על ה-GPU של Cloudflare עצמה (
glm-4.7-flash,bge,Fluxוכו'). אלה נספרים מול 10,000 ה-neurons החינמיים. - proxied (מתווך) — ניתוב דרך AI Gateway לספק חיצוני (OpenAI/Anthropic). אלה 0 neurons חינמיים — כל קריאה מחויבת אצל הספק לפי המחירון שלו. ה-10,000 לא מכסים אותם.
כלומר: אם אתה רוצה inference חינמי, אתה משתמש במודלים hosted. אם אתה מנתב ל-OpenAI דרך AI Gateway, אתה משלם ל-OpenAI — ה-Gateway נותן לך caching ו-observability, לא "OpenAI בחינם". נחזור לזה בסעיף ה-AI Gateway. (ההבחנה הזו נישאה מ-baseline המחקר ולא אומתה חי בריצה הנוכחית — להציג כ-caution operational חזק, אבל היא עקבית עם אופן החיוב של הפלטפורמה.)
פתח את https://developers.cloudflare.com/workers-ai/platform/pricing/ ומצא בטבלה את שורת ה-output neurons של @cf/meta/llama-3.3-70b-instruct-fp8-fast (204,805 לכל מיליון tokens). רשום אותה בקובץ הערות — נשתמש בה בסעיף הבא כדי לחשב כמה קריאות "מודל גדול" נשארות לך ביום.
חישוב ה-neuron budget בפועל: למה output tokens שורפים, ולמה מודל קטן הוא ברירת המחדל
עכשיו הקסם: נראה למה בחירת המודל היא ההחלטה הכי משפיעה על העלות שלך. ניקח את המודל הגדול, llama-3.3-70b-instruct-fp8-fast, ונחשב כמה עולה קריאה אחת טיפוסית.
המחירון אומר: 26,668 neurons לכל מיליון input tokens, ו-204,805 neurons לכל מיליון output tokens. שים לב לפער — ה-output יקר פי ~8 מה-input. זו הסיבה שאומרים "output tokens שורפים". נניח קריאה עם 500 tokens קלט ו-2,000 tokens פלט (תשובה בינונית):
- input: 500 / 1,000,000 × 26,668 ≈ 13 neurons
- output: 2,000 / 1,000,000 × 204,805 ≈ 410 neurons
- סה"כ לקריאה ≈ ~423 neurons (כמעט הכל מ-output)
עכשיו חלק: 10,000 / 410 ≈ ~24 קריאות ביום. זהו. עם המודל הגדול, אם כל תשובה היא 2,000 tokens, נגמר לך התקציב היומי אחרי 24 שאלות. זו הסיבה שמודל קטן הוא ברירת המחדל בקורס הזה — לא קמצנות, מתמטיקה.
שני המנופים שמשנים את התקרה
חשוב להבין: יש לך שני ידיות, לא אחת. לבחור שם מודל אחר זה רק חצי מהסיפור:
- מודל קטן יותר.
glm-4.7-flash(קטן ומהיר) עולה הרבה פחות neurons לאותו פלט מ-70b. עצם המעבר מגדיל את התקרה בסדר גודל. - הגבלת
max_tokens. כיוון שה-output הוא רוב ה-burn, הגבלת התשובה ל-512 tokens במקום 2,000 חותכת את העלות לכל קריאה בערך פי ארבעה — גם באותו מודל.
שלב את שני המנופים — מודל קטן וגם max_tokens מוגבל — ואתה עובר מ-~24 קריאות ביום ל-מאות. בתרגיל 3 תבנה טבלה שמראה את זה במספרים שלך.
וההמרות לסוגי המודלים האחרים? באותו עיקרון, אבל ביחידות שלהם. embedding זול מאוד יחסית (וקטור קצר, פלט קטן) — אלפי embeddings ביום. flux-1-schnell ליצירת תמונה: בערך 4.80 neurons ל-tile של 512×512 ו-9.60 neurons ל-step — מה שמסתכם ב-~130 תמונות ביום בתקציב 10k (תלוי ברזולוציה ובמספר ה-steps). whisper לתמלול אודיו: ~41 neurons לדקת אודיו → ~240 דקות ביום. שים לב למילה החוזרת — "תלוי". אין מספר קסם אחד "כמה קריאות ביום"; הכל תלוי בכמה אתה מבקש מהמודל לעבוד בכל קריאה. לכן בתרגיל 3 אתה מאמת מול הטבלה החיה ולא משנן מספר.
נקודה אחרונה ש-Vibe Coders נופלים עליה: ה-reset הוא ב-00:00 UTC, ו-יומי. זה אומר שאם אתה בונה demo ללקוח ושורף את כל ה-10k בבדיקות בבוקר, ה-demo ייכשל אחר הצהריים עד חצות UTC. כלל: בזמן פיתוח אקטיבי השאר max_tokens נמוך ובדוק עם prompts קצרים, ושמור את התקציב ל-demo עצמו. אם אתה צריך נפח גדול בזמן פיתוח — שקול לעבור זמנית ל-Workers Paid (אותם 10k חינם, אבל overage זול אם תחרוג).
הערה על rate limit: בנוסף ל-neuron budget היומי יש גם מגבלת קצב — ברירת מחדל ~300 בקשות לדקה ל-text generation. אבל זה לא קבוע אוניברסלי: לפי המודל זה נע בין 150 ל-1,500 בקשות לדקה. אל תזכור "300" כמספר קדוש — בדוק לפי המודל הספציפי שלך בדף ה-limits.
קח 10,000 וחלק ב-410 (קריאת 70b עם 2,000 פלט). רשום את התוצאה (~24). עכשיו דמיין שהורדת את max_tokens ל-512 ועברת ל-glm-4.7-flash — כתוב בשורה אחת למה התקרה היומית קופצת בסדר גודל. (רמז: output הוא רוב ה-burn, ושינית גם את הכמות וגם את המחיר-לכל-token.)
קטלוג 2026: אילו מודלים GA, ומה הוסר ב-2026-05-30
זה הסעיף הכי חשוב לתשומת לב, כי כאן נמצאת המלכודת הגדולה של הפרק. ב-2026-05-08 Cloudflare פרסמה changelog בשם "Planned model deprecations" — רשימה של 18 מודלים שמוסרים בתאריך 2026-05-30. בראש הרשימה: @cf/meta/llama-3.1-8b-instruct (וגם -awq) — בדיוק המודל שכל מדריך, וגם הסילבוס הישן של הקורס הזה, ממליצים עליו "לאפליקציות free tier".
במילים אחרות: ההמלצה הנפוצה ביותר באינטרנט ל-"מודל חינמי על Cloudflare" כבר לא תקפה. אם תעתיק קוד מ-Stack Overflow או אפילו מהדוגמה הרשמית של Cloudflare עצמה (שעדיין מציגה את ה-string הזה), אתה מקבע מודל מת.
וזה לא אירוע חד-פעמי — זה הקצב של התחום. קטלוג המודלים של Workers AI מכיל עשרות מודלים (מעל 70 בריצה האחרונה), והוא משתנה כל כמה שבועות: מודלים חדשים נכנסים כ-beta, מתבגרים ל-GA, וישנים מסומנים ל-deprecation. בתור Vibe Coder שמקבע שמות מודלים בקוד, אתה צריך הרגל אחד פשוט שיציל אותך: לפני שאתה כותב string של מודל, פתח את הקטלוג ואמת שהוא GA. זה לוקח 30 שניות וחוסך באג שמתגלה רק בפרודקשן, בלי שום שגיאת deploy.
מה ההבדל בין GA ל-beta בהקשר הזה? GA (General Availability) = מודל יציב שיש עליו התחייבות; אם הוא יוסר, תקבל deprecation date מראש. beta = זמין לניסוי, אבל עלול להשתנות או להיעלם בלי הרבה התראה. ל-RAG בפרודקשן — תמיד GA. ל-ניסויים והשוואות — beta בסדר, רק אל תקבע עליו אפליקציה חיה.
מה GA ובטוח לשימוש (מאי 2026)
| קטגוריה | מודלים GA (אומתו חי) |
|---|---|
| Chat — ברירת מחדל | @cf/zai-org/glm-4.7-flash (קטן, מהיר, רב-לשוני כולל עברית, tool-calling) |
| Chat — step-up | @cf/google/gemma-4-26b-a4b-it (vision + tools), @cf/moonshotai/kimi-k2.6 (agentic), @cf/openai/gpt-oss-120b, @cf/meta/llama-4-scout-17b-16e-instruct (multimodal), @cf/qwen/qwen3-30b-a3b-fp8 |
| Chat — "מודל גדול" להמחשה | @cf/meta/llama-3.3-70b-instruct-fp8-fast (עדיין GA — וריאנט -fast לא הוסר) |
| Embeddings | @cf/baai/bge-small-en-v1.5 (384), bge-base (768), @cf/baai/bge-large-en-v1.5 (1024), @cf/baai/bge-m3 (1024, רב-לשוני), @cf/qwen/qwen3-embedding-0.6b |
| Image | @cf/black-forest-labs/flux-2-dev, @cf/black-forest-labs/flux-1-schnell |
| Audio | @cf/openai/whisper-large-v3-turbo |
מה הוסר (2026-05-30) — אל תקבע בקוד
נמנעים מ-: llama-3.1-8b-instruct (+-awq), llama-3.1-70b-instruct, llama-3-8b-instruct, mistral-7b-instruct-v0.1 / v0.2, gemma-3-12b-it, ועוד — 18 מודלים סך הכל. כלל אצבע: וריאנטים עם סיומת -fast ו--lora נשארים פעילים — לכן llama-3.3-70b-instruct-fp8-fast דווקא לא deprecated, למרות ש-llama-3.1-70b הרגיל כן.
llama-3.1-8b שהדוקס עדיין מציגים)
למה זה מפתה: הדוגמה הרשמית של Cloudflare ב-get-started עדיין כתובה עם env.AI.run("@cf/meta/llama-3.1-8b-instruct", ...). אתה מעתיק, זה עובד בזמן הכתיבה — אז למה לא?
למה זה טעות: אחרי 2026-05-30 ה-string הזה עלול (א) להתחיל להחזיר שגיאה, או (ב) — גרוע יותר — לבצע auto-substitution שקטה למודל אחר עם פלט שונה. שני המקרים שוברים אפליקציית RAG בלי שום שגיאת deploy. ה-deploy יעבור בהצלחה, ורק בזמן ריצה התשובות ישתנו או ייעלמו.
מה לעשות במקום: השתמש ב-GA — ברירת המחדל @cf/zai-org/glm-4.7-flash. אל תעתיק את ה-string מהדוגמה; בדוק את https://developers.cloudflare.com/workers-ai/models/ לפני שמקבעים שם. ובאפליקציה — מפה את שם המודל למקום אחד (facade, סעיף 9) כדי שעדכון יהיה שינוי בנקודה אחת.
אם אתה צריך chat רב-לשוני זול ומהיר ל-free tier (כולל עברית) →
- ברירת המחדל
@cf/zai-org/glm-4.7-flash(burn נמוך, מתאים ל-10k/day).
אם אתה צריך יכולת חזקה יותר / vision / tool-calling אגרסיבי →
- step-up ל-
@cf/google/gemma-4-26b-a4b-itאו@cf/moonshotai/kimi-k2.6(יקרים יותר ב-neurons).
אם אתה רק משווה "מודל גדול" לתקציב →
@cf/meta/llama-3.3-70b-instruct-fp8-fast(GA-fast) — רק כדי להדגים שזה ~24 קריאות ביום.
בכל מקרה: cap את max_tokens, ו-לעולם אל תקבע בקוד מודל deprecated (llama-3.1-8b/70b, mistral-7b-v0.1) — בדוק את הקטלוג החי לפני שמקבעים string.
פתח את https://developers.cloudflare.com/workers-ai/models/ וחפש glm-4.7-flash. אמת שהוא מופיע כ-GA והעתק את ה-ID המדויק @cf/zai-org/glm-4.7-flash לקובץ הערות — זה ה-string שתשתמש בו בקוד במקום המודל הישן שהדוקס עוד מציגים.
AI.run() בפועל: text, embedding ו-image מתוך Worker
עכשיו לקוד. כל קריאת AI נתלית על binding אחד. ב-wrangler.toml — אותו קובץ מפרק 2 — מוסיפים שתי שורות:
[ai]
binding = "AI"
זהו. עכשיו env.AI זמין ב-Worker, בדיוק כמו env.DB (D1) ו-env.RATE (KV) מפרק 2. החתימה הכללית: env.AI.run(modelId, options). שים לב לדפוס — זה אותו רעיון של binding שראית בפרק 2: אתה לא מייבא ספרייה ולא מחזיק מפתח, אלא מקבל אובייקט מוכן דרך env ש-Cloudflare מזריקה ל-Worker בזמן ריצה. ה-options משתנה לפי סוג המודל: מודל שפה מקבל messages, מודל embedding מקבל text, מודל תמונה מקבל prompt. נראה את שלושתם.
הוסף ל-wrangler.toml של הפרויקט מפרק 2 את שתי השורות [ai] ו-binding = "AI". שמור. עדיין לא כותבים קוד — רק מצהירים על ה-binding שעליו תיתלה כל קריאת AI.
1. Text generation (completion)
שתי הערות חשובות: השתמש ב-messages (פורמט שיחה) ולא ב-prompt בלבד — זה מה שמאפשר system prompt ו-multi-turn. ושים לב לשם המודל: GA, לא llama-3.1-8b, גם אם הדוקס מציגים אחרת.
// GA model — אל תשתמש ב-string של llama-3.1-8b מהדוגמה הרשמית (הוסר 2026-05-30).
const res = await env.AI.run("@cf/zai-org/glm-4.7-flash", {
messages: [
{ role: "system", content: "ענה רק מתוך ה-context שסופק." },
{ role: "user", content: question }
],
max_tokens: 512, // תקרת פלט — מגן על תקציב ה-10k neurons/day
stream: true // החזרת tokens בזרם ללקוח
});
כש-stream: true, ה-Worker מחזיר ReadableStream שאפשר להחזיר ישירות ל-response — הלקוח רואה את התשובה נכתבת token-by-token, בדיוק כמו ChatGPT. (קוד ה-piping המדויק של ה-stream תלוי-גרסה — אמת את הדוגמה ב-workers-ai/text-generation לפני בלוק "העתק בדיוק".)
למה בכלל להזרים? שני טעמים. הראשון UX: על תשובה ארוכה, streaming מראה למשתמש שמשהו קורה כבר אחרי חלקיק שנייה, במקום ספינר ארוך עד שכל התשובה מוכנה. השני טכני וקריטי דווקא ב-Worker: יש קיר CPU (ראית בפרק 2 את 10ms-50ms ה-CPU), ויש זמן מקסימלי לתגובה. כש-LLM מחזיר תשובה ארוכה, הזרמה מאפשרת ל-Worker לשלוח bytes תוך כדי שהמודל עובד, במקום לחכות לתשובה השלמה בזיכרון. בפרקטיקה: כמעט תמיד תרצה stream: true ל-chat, ו-stream: false רק כשאתה צריך את כל התשובה כאובייקט אחד (למשל כדי לנתח JSON שהמודל החזיר).
וכשלא מזרימים? בלי stream, AI.run מחזיר אובייקט עם השדה response שמכיל את הטקסט המלא — נוח כשאתה רוצה לעבד את התשובה לפני ששולחים אותה ללקוח (למשל לחתוך, לסנן, או לעטוף במבנה JSON — בדיוק מה שנעשה ב-facade בסעיף 9).
2. Embedding
embedding הופך טקסט לוקטור מספרי — שורה של מספרים שמייצגת את ה"משמעות". זה הלב של RAG. אפשר לחשוב על זה כעל "קואורדינטות במרחב המשמעות": טקסטים שמשמעותם דומה מקבלים וקטורים קרובים, וטקסטים שונים מקבלים וקטורים רחוקים. מודל bge-small-en-v1.5 מחזיר וקטור באורך 384 — כלומר 384 מספרים שמקודדים את המשמעות של הטקסט. שים לב ש-text מקבל מערך, כך שאפשר ל-embed כמה קטעים בקריאה אחת (חוסך neurons וזמן):
const { data } = await env.AI.run("@cf/baai/bge-small-en-v1.5", {
text: ["טקסט לדוגמה"]
});
const vector = data[0]; // מערך של 384 מספרים
// אמת: vector.length === 384
3. Image generation
flux-1-schnell מקבל prompt טקסטואלי ומחזיר bytes של תמונה. ה-schnell (גרמנית ל"מהיר") הוא הווריאנט הזריז של משפחת Flux — פחות steps, מהיר וזול יותר ב-neurons מ-flux-2-dev, ומספיק לרוב השימושים (avatars, תמונות תוכן, mockups). אתה מחזיר את ה-bytes עם Content-Type: image/png:
const img = await env.AI.run("@cf/black-forest-labs/flux-1-schnell", {
prompt: "a red bicycle"
});
// flux-1-schnell מחזיר bytes בינאריים של PNG — מזרימים אותם ישר ל-Response,
// בלי JSON ובלי base64. רק חשוב לקבוע את ה-Content-Type הנכון:
return new Response(img, { headers: { "content-type": "image/png" } });
ב-src/index.ts הוסף שורת קריאה אחת: const res = await env.AI.run("@cf/zai-org/glm-4.7-flash", { messages: [{ role: "user", content: "שלום" }], max_tokens: 64 }); הרץ npx wrangler dev ובדוק שחוזרת תשובה. (messages + max_tokens, ה-string GA — לא llama-3.1-8b.)
- הוסף
[ai]/binding = "AI"ל-wrangler.tomlשל הפרויקט מפרק 2. - route
/chat:env.AI.run("@cf/zai-org/glm-4.7-flash", { messages, max_tokens: 256 })והחזר את הטקסט. - route
/embed:env.AI.run("@cf/baai/bge-small-en-v1.5", { text: ["טקסט לדוגמה"] })והחזר את אורך הוקטור — אמת שהוא 384. - route
/image:env.AI.run("@cf/black-forest-labs/flux-1-schnell", { prompt: "a red bicycle" })והחזר את התמונה כ-image/png. - הרץ
npx wrangler dev→ קרא לשלושת ה-routes ואמת שכל אחד מחזיר פלט תקין. - הרץ
npx wrangler deploy→ אמת ששלושתם עובדים ב-URL החי. - תעד: ליד כל route רשום את שם המודל ה-GA שבחרת, ולמה לא
llama-3.1-8b.
פלט נראה לעין שתסיים איתו: Worker חי עם 3 routes — /chat (completion ב-glm-4.7-flash), /embed (וקטור 384-dim מ-bge-small), /image (PNG מ-flux-1-schnell). שמור צילום מסך של שלושת הפלטים ואת ה-URL ב-README.
Vectorize ו-RAG ה-DIY: embed → אחסון → query → top-k → תשובה
זה הלב של הפרק. RAG (Retrieval-Augmented Generation) פותר את הבעיה הגדולה של LLMs: הם לא מכירים את המסמכים שלך, ואם תשאל אותם הם יזיפו בביטחון. הרעיון פשוט: במקום לסמוך על הזיכרון של המודל, אנחנו שולפים את הטקסט הרלוונטי ממסמכים שלנו ומזריקים אותו ל-prompt כ-context. המודל עונה מתוך מה שנתנו לו, לא מתוך מה שהוא "זוכר".
שאלה שעולה תמיד: למה RAG ולא פשוט לאמן (fine-tune) מודל על המסמכים שלי? שלוש סיבות מעשיות. ראשית, fine-tuning יקר ואיטי — צריך GPU, דאטה מסומן, וזמן; RAG עובד מהרגע הראשון בלי אימון. שנית, RAG מתעדכן מיידית — הוספת מסמך = upsert אחד, בלי לאמן מחדש; מודל מאומן "תקוע" עם מה שלמד. שלישית, RAG מצטט מקור — אתה יודע בדיוק מאיזה chunk הגיעה התשובה, אז אפשר להציג למשתמש "לפי המסמך X" ולהפחית הזיות. בקיצור: לרוב המוחלט של אפליקציות "צ'אט על הדאטה שלי", RAG הוא התשובה הנכונה, ו-fine-tuning הוא over-engineering.
כדי לשלוף "טקסט רלוונטי" צריך לחפש לפי משמעות, לא לפי מילים מדויקות. כאן נכנס Vectorize — vector DB מנוהל. אתה הופך כל קטע טקסט (chunk) לוקטור (embedding), שומר את הוקטורים ב-Vectorize, ואז על שאלה אתה הופך גם אותה לוקטור ומבקש את k הוקטורים הקרובים ביותר (top-k).
למה חיפוש לפי משמעות ולא לפי מילים? תחשוב על שאלה כמו "כמה זמן לוקח deploy?" כשבמסמך כתוב "הפריסה נמשכת בערך 30 שניות". חיפוש טקסט רגיל (כמו LIKE ב-SQL) יחפש את המילה "deploy" ולא ימצא — כי במסמך כתוב "פריסה". embedding פותר בדיוק את זה: הוא ממפה גם את השאלה וגם את המשפט למרחב מספרי שבו "deploy" ו"פריסה" קרובים זה לזה, כי המשמעות דומה. ה-top-k מחזיר את הקטעים הקרובים במשמעות, גם אם המילים שונות לגמרי. זו ההבחנה שהופכת RAG ל-RAG ולא ל-"חיפוש מילולי עם LLM למעלה".
chunking — ההחלטה השקטה שקובעת את האיכות
שלב ה-chunk נראה טריוויאלי אבל הוא משפיע ישירות על איכות התשובות. אם ה-chunks גדולים מדי (עמוד שלם), כל וקטור "מורח" יותר מדי משמעות והדמיון נהיה מטושטש — ה-top-k מחזיר קטע גדול שרק חלקו רלוונטי. אם הם קטנים מדי (משפט בודד), אתה מאבד הקשר — קטע שמתחיל ב"זה עולה $5" בלי לדעת מה "זה". כלל אצבע מעשי להתחיל ממנו: chunk של פסקה–שתיים (בערך 200–500 מילים), עם חפיפה קטנה בין chunks סמוכים (overlap) כדי לא לחתוך משפט באמצע רעיון. אתה תכוונן את זה אחרי שתראה את התשובות הראשונות — אבל התחל פשוט.
החיוב: לפי dimensions, לא לפי מסמכים
זו ההפתעה של Vectorize, ונקודת החלטה אמיתית. ה-free tier הוא 5,000,000 stored dimensions + 30,000,000 queried dimensions לחודש. שים לב — לא "מסמכים", אלא ממדים. כל מסמך תופס מספר ממדים השווה לאורך הוקטור של מודל ה-embedding. לכן מודל ה-embedding קובע ישירות כמה מסמכים נכנסים בחינם:
| מודל embedding | ממדים (dims) | תקרת מסמכים חינם (5M ÷ dims) | שפה |
|---|---|---|---|
bge-small-en-v1.5 | 384 | ~13,020 | אנגלית |
bge-base-en-v1.5 | 768 | ~6,510 | אנגלית |
bge-large-en-v1.5 | 1024 | ~4,883 | אנגלית |
bge-m3 | 1024 | ~4,883 | רב-לשוני (כולל עברית) |
הבחירה שלנו לתרגיל: bge-small-en-v1.5 (384 ממדים) — הוא GA, והוא נותן את התקרה הגבוהה ביותר של מסמכים חינם (~13,020 וקטורים מתוך 5M). אם המסמכים שלך בעברית ואיכות ה-retrieval קריטית, יש שיקול אמיתי לעבור ל-bge-m3 (רב-לשוני) — אבל זה מרבע את מספר המסמכים החינמיים. החלטה, לא free lunch (framework בהמשך).
נשים את המספרים בפרספקטיבה: ~13,020 וקטורים זה הרבה בשביל מסמכים אישיים. README, הערות, תיעוד פרויקט, מאגר ידע של צוות קטן — כל אלה נכנסים בנוחות מתחת לתקרה החינמית, גם אחרי chunking. אתה מתקרב לקיר רק כשאתה מאנדקס משהו כמו אתר תוכן גדול או ארכיון של אלפי מאמרים. כלומר: לרוב הפרויקטים של Vibe Coder, Vectorize הוא חינם בפועל, ולא "חינם עד שתיגע בקיר מהר". וגם אם תיגע — ה-overage הוא $0.05 ל-100 מיליון stored dimensions, כלומר סנטים, לא דולרים.
הבחנה חשובה נוספת שמבלבלת מתחילים: יש שתי מכסות נפרדות — stored (5M) ו-queried (30M לחודש). stored הוא כמה וקטורים אתה מחזיק; queried הוא כמה ממדים אתה "קורא" בשאילתות. כל שאילתה שמשווה את וקטור השאלה מול ה-index צורכת queried dimensions. עם 384 ממדים, 30M queried = הרבה מאוד שאילתות חודשיות. בפועל ה-stored הוא המגבלה שתרגיש קודם, לא ה-queried — אבל טוב לדעת ששתיהן קיימות.
ה-pipeline המלא
שש שכבות, וכולן רצות בתוך ה-Worker שלך:
- chunk — חתוך את המסמכים לקטעים קצרים (פסקה–שתיים).
- embed — לכל chunk קרא
env.AI.run("@cf/baai/bge-small-en-v1.5", { text: [chunk] })→ וקטור 384. - upsert — שמור את הוקטורים ב-Vectorize (
env.VECTORIZE.upsert) ואת הטקסט/metadata ב-D1 (reused מפרק 2) או ב-metadata של הוקטור. - query — על שאלה, embed אותה באותו מודל, ואז
env.VECTORIZE.query(vector, { topK: 5, returnMetadata: true }). - context — אסוף את טקסט ה-chunks שחזרו והרכב אותם ל-context.
- generate —
env.AI.run("@cf/zai-org/glm-4.7-flash", { messages, stream: true })עם ה-context ב-system prompt → תשובה מוזרמת מבוססת-מקור.
שים לב לסימטריה החשובה בין שלב 2 לשלב 4: אתה חייב להשתמש באותו מודל embedding כדי לאנדקס וכדי לשאול. למה? כי כל מודל embedding בונה "מרחב משמעות" משלו — וקטור של bge-small ווקטור של bge-m3 פשוט לא מדברים את אותה שפה, גם אם שניהם 1024 ממדים. אם תאנדקס ב-bge-small ותשאל ב-bge-m3, ה-top-k יחזיר זבל. זה אחד הבאגים הכי נפוצים ב-RAG, והוא שקט — אין שגיאה, רק תשובות גרועות. נעל את מודל ה-embedding במקום אחד בקוד.
ושלב 6 — ה-system prompt — הוא שם שמרוויחים או מפסידים את ה-grounding. ה-system prompt צריך להגיד למודל במפורש: "ענה רק מתוך ה-context שסופק; אם התשובה לא שם, אמור שאינך יודע". בלי ההוראה הזו, המודל יערבב את ה-context עם הזיכרון הכללי שלו ויחזור להזות. עם ההוראה, הוא נשאר נאמן למסמכים שלך — וזו כל הנקודה של RAG.
שים לב לחלוקה בין "פעם אחת" ל"בכל פעם" (תראה אותה גם בדיאגרמה למטה): שלבים 1–3, האינדוקס, רצים פעם אחת כשאתה מעלה מסמכים — או כל פעם שמסמך משתנה. שלבים 4–6, השאילתה, רצים בכל שאלה של משתמש. זו הבחנה מעשית חשובה: אל תבנה את ה-ingest בתוך ה-request של המשתמש; הוא איטי ויקר. ה-ingest הוא תהליך נפרד (route ייעודי, או סקריפט שאתה מריץ ידנית), וה-query route הוא מה שהמשתמש פוגש. ב-Worker אחד יכולים לחיות שני ה-routes — רק אל תערבב אותם.
ולמה D1 (מפרק 2) ולא רק ה-metadata של הוקטור? כי Vectorize שומר את הוקטור ומעט metadata, אבל הוא לא נועד להחזיק את הטקסט המלא של כל chunk בנוחות. הדפוס הנקי: שמור את הטקסט המלא, המקור, וכל מידע נוסף ב-D1 (טבלת chunks), ושמור ב-Vectorize רק את הוקטור עם id שמצביע חזרה לשורה ב-D1. על query אתה מקבל מ-Vectorize את ה-id-ים של ה-top-k, ואז שולף את הטקסט המלא מ-D1. ככה כל primitive עושה מה שהוא טוב בו — בדיוק רוח ה-bindings מפרק 2.
ה-binding וה-index נוצרים כך:
# יצירת ה-index — ה-dimensions חייבים להתאים למודל (384 ל-bge-small)
npx wrangler vectorize create my-docs-index --dimensions=384 --metric=cosine
npx wrangler vectorize list # אמת שהוא מופיע
# wrangler.toml — נוסף ל-bindings מפרק 2
[[vectorize]]
binding = "VECTORIZE"
index_name = "my-docs-index"
וקוד ה-query עצמו:
// 1) embed את השאלה באותו מודל ששימש לאינדוקס (bge-small, 384)
const { data } = await env.AI.run("@cf/baai/bge-small-en-v1.5", { text: [question] });
const queryVector = data[0];
// 2) top-k similarity ב-Vectorize
const matches = await env.VECTORIZE.query(queryVector, { topK: 5, returnMetadata: true });
// 3) בנה context מטקסט ה-chunks שחזרו
const context = matches.matches.map(m => m.metadata.text).join("\n---\n");
// 4) תשובה מבוססת-context עם מודל GA
const answer = await env.AI.run("@cf/zai-org/glm-4.7-flash", {
messages: [
{ role: "system", content: `השתמש אך ורק ב-context הזה:\n${context}` },
{ role: "user", content: question }
],
stream: true
});
הקטע למעלה הוא רק שלב ה-query. כדי שתהיה לך copy-paste מלא מקצה-לקצה — מ-ingest ועד תשובה מוזרמת — הנה כל ה-pipeline. שלב 1: טבלת D1 שמחזיקה את הטקסט (Vectorize מחזיק רק וקטורים), בדיוק כמו env.DB מפרק 2:
-- פעם אחת, ב-schema של D1 (מפרק 2): הטקסט חי כאן, הוקטור ב-Vectorize
CREATE TABLE IF NOT EXISTS chunks (id TEXT PRIMARY KEY, text TEXT, source TEXT);
שלב 2: ingest — חותכים מסמך ל-chunks, עושים embed לכל chunk, מבצעים upsert ל-Vectorize (שים לב לצורת ה-payload: id + values + metadata), ושומרים את הטקסט עצמו ב-D1 לפי אותו id:
// chunks = string[] (קטעים של 200–500 מילים מתוך README/הערות)
const { data } = await env.AI.run("@cf/baai/bge-small-en-v1.5", { text: chunks });
// data הוא מערך של וקטורים 384-dim, אחד לכל chunk — באותו סדר
const vectors = chunks.map((text, i) => ({
id: `${docId}:${i}`, // מזהה יציב לכל chunk
values: data[i], // הוקטור 384-dim של ה-chunk הזה
metadata: { docId, source } // מספיק כדי לשלוף את הטקסט מ-D1 אחר כך
}));
await env.VECTORIZE.upsert(vectors); // כותב את כל הוקטורים בבת אחת
for (const v of vectors) { // ושומר את הטקסט המקביל ב-D1
await env.DB.prepare("INSERT OR REPLACE INTO chunks (id, text, source) VALUES (?, ?, ?)")
.bind(v.id, chunks[Number(v.id.split(":")[1])], source).run();
}
שלב 3: query מלא — embed לשאלה, top-k מ-Vectorize, שליפת הטקסט מ-D1 לפי ה-id-ים שחזרו, ובניית ה-context:
const { data: qd } = await env.AI.run("@cf/baai/bge-small-en-v1.5", { text: [question] });
const matches = await env.VECTORIZE.query(qd[0], { topK: 5, returnMetadata: true });
const ids = matches.matches.map(m => m.id); // ה-id-ים של ה-chunks הקרובים
const ph = ids.map(() => "?").join(","); // placeholders ל-SQL
const rows = await env.DB.prepare(`SELECT text FROM chunks WHERE id IN (${ph})`)
.bind(...ids).all();
const context = rows.results.map(r => r.text).join("\n---\n");
שלב 4: תשובה מוזרמת — מזריקים את ה-context ל-system prompt וקוראים למודל GA עם stream: true. ה-stream שחוזר הוא ReadableStream שמעבירים ישר ל-Response כ-text/event-stream (SSE), כך הלקוח רואה tokens תוך כדי הקלדה ולא נופלים על קיר ה-CPU:
const stream = await env.AI.run("@cf/zai-org/glm-4.7-flash", {
messages: [
{ role: "system", content: `ענה אך ורק מתוך ה-context:\n${context}` },
{ role: "user", content: question }
],
max_tokens: 512,
stream: true
});
// מעבירים את ה-ReadableStream ישר ל-Response — בלי לאסוף הכל בזיכרון
return new Response(stream, { headers: { "content-type": "text/event-stream" } });
צורת ה-streaming-response היא היציבה כיום, אבל זה החלק הכי תלוי-זמן — אמת מול workers-ai text-generation docs לפני production. אם אתה רוצה להתחיל פשוט: השמט stream: true, קרא result.response והחזר אותו כ-JSON — streaming הוא שדרוג, לא תנאי.
למה זה מפתה: bge-large או bge-m3 (1024 ממדים) "נשמעים חזקים יותר", אז למה לא להתחיל איתם?
למה זה טעות: Vectorize מחויב לפי dimensions — 5M / 1024 ≈ 4,883 מסמכים בלבד, מול ~13,020 ב-bge-small (384). וגרוע מכך: ה-dims של ה-index קבועים בעת היצירה. index שנוצר ב-384 מקבל רק וקטורים 384 — החלפת מודל ל-1024 דורשת index חדש, אי אפשר לשנות במקום. טעות כאן מחייבת בנייה מחדש באמצע הפרויקט.
מה לעשות במקום: החלט על מודל ה-embedding לפני wrangler vectorize create. למקסימום מסמכים חינם באנגלית → bge-small (384). רק אם retrieval רב-לשוני קריטי — שלם את מחיר ה-1024 של bge-m3 ביודעין.
הרץ npx wrangler vectorize create my-docs-index --dimensions=384 --metric=cosine. אם נוצר — הרץ npx wrangler vectorize list ואמת שהוא מופיע. (384 = bge-small, התקרה הכי גבוהה של מסמכים חינם.)
- הרץ
npx wrangler vectorize create my-docs-index --dimensions=384 --metric=cosineוהוסף[[vectorize]]/binding = "VECTORIZE"ל-wrangler.toml. - ודא ש-
[[d1_databases]]/binding = "DB"קיים (מפרק 2); צור טבלהchunks(id, text, source). - ingest: קח 3–5 מסמכים אישיים (README, הערות), חתוך ל-chunks, embed כל chunk ב-
bge-small,VECTORIZE.upsertאת הוקטורים ושמור את הטקסט ב-D1. - query route: embed את שאלת המשתמש ב-
bge-small→VECTORIZE.query(vector, { topK: 5, returnMetadata: true })→ אסוף את טקסט ה-chunks. - הזרק את ה-context ל-system prompt →
env.AI.run("@cf/zai-org/glm-4.7-flash", { messages, stream: true })והחזר תשובה מוזרמת. - הרץ
npx wrangler deployושאל שאלה שהתשובה לה רק במסמכים שלך — אמת שהתשובה מבוססת על ה-context ולא הזיה. - תעד: כמה stored dims ניצלת (
chunks × 384) מתוך 5M, וכמה מסמכים עוד נשארים חינם.
פלט נראה לעין שתסיים איתו: RAG chatbot חי על *.workers.dev שעונה משאלות על המסמכים האישיים שלך (Vectorize 384 + bge-small + D1 metadata + glm-4.7-flash streaming), כולו בתוך ה-free tier. שמור צילום מסך של שאלה+תשובה מבוססת-מסמך ואת ספירת ה-dims שנוצלו.
AI Search המנוהל: הדרך בלי תשתית — ומה-binding החדש
בנית RAG ידנית — שלטת בכל שלב. אבל מה אם אתה לא רוצה לכתוב את ה-pipeline בכלל? כאן נכנס AI Search (open beta, אפריל 2026): RAG-as-a-service. אתה מצביע אותו על מקור מסמכים (אתר, bucket), והוא עושה לבד את ה-crawl, ה-chunk, ה-embed וה-index. אתה רק שואל.
ה-free tier: 20,000 שאילתות לחודש, עד 500 דפים crawl ביום, 100,000 קבצים per instance, ו-100 instances per account — בלי חיוב, עם התחייבות ל-30 יום התראה לפני כל billing. נוח מאוד לתיקיית מסמכים יציבה.
הסיבה ש-AI Search מרגיש כמו קסם היא שהוא מחביא ממך בדיוק את שלושת השלבים שבנית ידנית בתרגיל 2: ה-crawl (איסוף המסמכים), ה-chunking (חיתוך), וה-embedding (וקטוריזציה) — כולם קורים מאחורי הקלעים, עם מודל embedding ש-Cloudflare בוחרת. אתה לא רואה את ה-Vectorize index, לא בוחר dims, ולא כותב את לולאת ה-upsert. זה גם החיסרון: כשמשהו לא עובד טוב (תשובות לא רלוונטיות), יש לך פחות ידיות לכוונן. ב-Vectorize, אם ה-retrieval גרוע, אתה משנה chunking או מודל; ב-AI Search, אתה תלוי בברירות המחדל. זו בדיוק ה-trade-off של "מנוהל מול DIY" שראית לאורך כל הקורס — ב-Workers, ב-storage, ועכשיו ב-RAG.
מתי AI Search באמת מנצח? כשהמקור הוא אתר או תיקייה ש-Cloudflare יכולה לסרוק — תיעוד מוצר, בלוג, knowledge base. אתה מצביע אותו על ה-URL, הוא סורק עד 500 דפים ביום, ותוך יום יש לך RAG מלא בלי שורת pipeline אחת. ל-Vibe Coder שרוצה "צ'אט על התיעוד של הפרויקט שלי" שמתעדכן לאט — זה הניצחון הברור.
env.AI.autorag("name").aiSearch(...)
למה זה מפתה: כל מדריך, פוסט ובלוג שנכתב לפני ~אפריל 2026 מראה את הדפוס env.AI.autorag("name").aiSearch(...). הוא מופיע בעשרות תוצאות חיפוש.
למה זה טעות: דפוס ה-autorag() הוסר ("no longer recommended for use"). קוד שמסתמך עליו יישבר או יתנהג לא צפוי. אם מדריך שאתה קורא משתמש בו — הוא ישן, בלי קשר לכמה הוא נראה מסודר.
מה לעשות במקום: הצהר [[ai_search]] binding (עם binding = "MY_SEARCH" ו-instance_name) והשתמש ב-env.MY_SEARCH.search({messages}) ל-chunks גולמיים, או env.MY_SEARCH.chatCompletions({messages, model, ai_search_options}) ל-retrieve+generate בקריאה אחת.
ה-binding החדש וקוד הקריאה:
# wrangler.toml — ה-binding המנוהל (במקום autorag הישן)
[[ai_search]]
binding = "MY_SEARCH"
instance_name = "my-instance"
// chunks + scores גולמיים:
const chunks = await env.MY_SEARCH.search({
messages: [{ role: "user", content: question }]
});
// retrieve + generate בקריאה אחת:
const response = await env.MY_SEARCH.chatCompletions({
messages: [{ role: "user", content: question }],
model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", // GA -fast, לא deprecated
ai_search_options: { retrieval: { max_num_results: 5 } }
});
ההבדל המעשי בין שתי הפונקציות: search() מחזיר לך את ה-chunks הגולמיים והציונים שלהם — אתה מקבל את חומר הגלם ומחליט מה לעשות איתו (אולי להזריק ל-prompt משלך, אולי להציג למשתמש כ"מקורות"). chatCompletions() עושה הכל בקריאה אחת — שולף וגם מנסח תשובה — ומחזיר אותה כבר מוכנה. אם אתה רוצה שליטה על ה-prompt → search(). אם אתה רוצה את התשובה הכי מהר עם הכי פחות קוד → chatCompletions(). שים לב שהמודל בדוגמה הוא llama-3.3-70b-instruct-fp8-fast — וריאנט -fast שהוא GA ובטוח לשימוש חוזר, לא אחד מה-18 שהוסרו.
שתי הערות: ה-indexing מבוסס crawl ועובד בעיכוב של יום — לא ל-real-time content. אם המסמכים שלך משתנים בזמן אמת, חזור ל-Vectorize הישיר. והערה על תאריכים: ההבחנה בין "new instances" (אחרי 2026-04-16) ל"previous instances" (מהגרים עד 2026-06-03) שייכת ל-AI Search, לא ל-Vectorize — אל תייחס אותם בטעות ל-Vectorize.
גם פקודת היצירה: AI Search instances נוצרים דרך Dashboard, REST API, או Wrangler CLI — אבל התחביר המדויק של ה-CLI לא אומת בריצה הנוכחית, אז אל תבטיח "one-liner" עד שתאמת מול הדוקס. wrangler vectorize create כן אומת.
פתח את https://developers.cloudflare.com/ai-search/usage/workers-binding/ ואתר את החתימה env.MY_SEARCH.chatCompletions(...). רשום בהערות אם מדריך/קוד ישן שאתה מכיר עדיין משתמש ב-env.AI.autorag(...) — אם כן, הוא deprecated.
Vectorize מול AI Search: מתי כל אחד — ושכבת AI Gateway ל-caching
שני מסלולים, שתי פילוסופיות. Vectorize (DIY) נותן לך שליטה מלאה — אתה קובע את מודל ה-embedding, את ה-dims, את ה-chunking, ויכול לעדכן בזמן אמת. המחיר: אתה כותב את ה-pipeline. AI Search (מנוהל) נותן אפס תשתית — crawl+embed+index אוטומטי, פחות קוד. המחיר: עיכוב של יום באינדוקס, ופחות שליטה.
הדרך הכי טובה לחשוב על זה: Vectorize הוא כמו לבנות את ה-RAG מ-Lego — כל חלק בידיים שלך, מתכוונן בדיוק לצרכים, אבל אתה מרכיב. AI Search הוא כמו מכשיר מוכן — מחברים לחשמל ועובד, אבל אתה לא פותח את המכסה. ל-Vibe Coder שבונה פרויקט אמיתי שהמסמכים בו משתנים (אפליקציה עם תוכן שנוצר על ידי משתמשים, למשל), Vectorize הוא הבחירה — כי AI Search יראה את התוכן החדש רק אחרי ה-crawl הבא, יום אחרי. אבל ל"צ'אט על התיעוד שלי" שבו המסמכים יציבים, AI Search חוסך לך את כל ה-pipeline שכתבת בתרגיל 2.
אגב — אתה לא חייב לבחור אחד לתמיד. דפוס נפוץ: מתחילים ב-AI Search לדמו מהיר (להוכיח שהרעיון עובד), ואם מגלים שצריך שליטה עדינה יותר על chunking או על real-time, מהגרים ל-Vectorize. כי בנית את ה-Vectorize pipeline בתרגיל 2, המעבר הזה כבר לא מפחיד.
שכבת AI Gateway: caching שחוסך neurons
AI Gateway היא שכבת proxy/cache/observability מול קריאות ה-AI שלך. ה-free tier כולל 100,000 logs לכל החשבון (לא פר-gateway — נקודה שמבלבלת), ו-caching + rate limiting מלאים בחינם. הקסם: אם אתה מנתב את קריאות Workers AI דרך ה-Gateway בשינוי config יחיד, תשובות חוזרות (אותו prompt) נשרתות מ-cache — בלי לשרוף neurons בכלל. לאפליקציה עם שאלות חוזרות זה חיסכון ענק על ה-10k היומיים.
מעבר ל-caching, ה-Gateway נותן לך גם observability — אתה רואה כל קריאה: כמה היא עלתה, כמה זמן לקחה, מה ה-prompt ומה התשובה. בשלב פיתוח זה זהב: אתה מגלה אילו prompts יקרים, איפה ה-latency, ואילו תשובות חוזרות (ולכן כדאי ל-cache). שלוש היכולות — cache, rate-limit, observability — כולן חינם, וכולן נדלקות בלי לגעת בלוגיקה של ה-Worker; הן יושבות בשכבה מעל. ההמלצה המעשית: ברגע שאפליקציית ה-AI שלך עוברת מ"דמו" ל"אנשים אמיתיים משתמשים בה", נתב דרך AI Gateway. ה-caching לבדו יחזיר לך נתח מהותי מה-neurons היומיים.
למה זה מפתה: "אני מנתב דרך התשתית של Cloudflare, אז זה חלק מה-10k neurons, נכון?"
למה זה טעות: ניתוב ל-OpenAI/Anthropic דרך AI Gateway = proxied model = 0 neurons חינמיים. כל קריאה מחויבת אצל הספק החיצוני לפי המחירון שלו. רק hosted models על ה-GPU של Cloudflare נספרים מול ה-10,000. (נישא מ-baseline המחקר, לא אומת חי בריצה זו — caution חזק.)
מה לעשות במקום: ל-inference חינמי השתמש ב-hosted (glm-4.7-flash וכו'). נתב דרך AI Gateway כדי לעשות caching לאותם hosted models ולחסוך neurons על תשובות חוזרות — לא כדי "לקבל את OpenAI בחינם".
אם אתה צריך שליטה מלאה על chunking/embedding/dims, או שהמסמכים מתעדכנים ב-real-time →
- Vectorize (DIY): אתה קובע את המודל ואת ה-dims, אבל כותב את ה-pipeline.
אם יש לך תיקיית מסמכים יציבה, רוצה אפס תשתית, ועיכוב של יום בעדכון מקובל →
- AI Search: 20k שאילתות/חודש, פחות קוד, אבל לא ל-real-time.
אם הקהל בעברית ואיכות retrieval קריטית →
- שקול
bge-m3(1024, רב-לשוני) ב-Vectorize — אבל זה מרבע את מספר המסמכים החינמיים מולbge-small(384).
אם אתה רק רוצה דמו מהיר → AI Search.
בכל מקרה: השתמש ב-[[ai_search]] binding, לא ב-env.AI.autorag() ה-deprecated.
כתוב בשורה אחת לאיזה משני המסלולים מתאים הפרויקט שלך: "מסמכים שמתעדכנים בזמן אמת והדגש על שליטה" → Vectorize; "תיקיית מסמכים יציבה ורוצה אפס תשתית" → AI Search. שמור — זו ההחלטה לתרגיל ה-RAG.
פרויקט יצירתי: AI API facade תואם-OpenAI עם rate-limiting ב-KV
הנה דפוס שהופך את כל מה שבנינו לכלי מעשי. facade הוא Worker שעוטף את Workers AI וחושף endpoint תואם-OpenAI: /v1/chat/completions. למה זה שימושי ל-Vibe Coder? כי כל כלי שכבר יודע לדבר עם OpenAI — SDK, curl, אפליקציה קיימת — יכול להצביע על ה-Worker שלך במקום על OpenAI, ולקבל inference חינם עד 10k neurons ביום, בלי לשנות שורת קוד אצל הלקוח.
שני רכיבים קריטיים מגנים על התקציב יחד:
- rate-limiting ב-KV (reused מפרק 2) — מונה לכל API key/IP. לפני כל קריאת AI בודקים את המונה; אם חצה סף, מחזירים 429 לפני שורפים neuron.
max_tokensמוגבל — תרגום הבקשה ל-env.AI.runתמיד מגביל את הפלט. גם אם מישהו מבקש תשובה ענקית, אתה לא נותן לו לשרוף את כל התקציב.
בונוס: ה-facade ממפה את שם המודל הפנימי ל-GA אחד — אם מודל מוסר (כמו llama-3.1-8b), אתה משנה במקום אחד ולא בכל הלקוחות. זו הגנת ה-deprecation בפועל.
למה הדפוס הזה כל-כך חזק ל-Vibe Coder? כי הוא הופך את ה-Worker שלך ל"ספק AI" שכל העולם כבר יודע לדבר איתו. ה-OpenAI API הוא דה-פקטו התקן: ספריות פייתון, ה-SDK של JavaScript, כלי CLI, אפילו אפליקציות דסקטופ — כולם יודעים לשלוח POST /v1/chat/completions עם { model, messages }. אם ה-Worker שלך מדבר את אותו פורמט, כל אחד מהכלים האלה יכול להצביע עליו בשינוי של שורה אחת (ה-base URL), ולקבל את ה-inference החינמי שלך במקום לשלם ל-OpenAI. זה גם מאפשר לך להחליף ספק בלי לגעת באפליקציה — היום Workers AI, מחר OpenAI דרך AI Gateway, והלקוח לא יודע.
וההגנה על התקציב היא לא "nice to have" — היא חובה ברגע שאתה חושף endpoint ציבורי. בלי rate-limit, מישהו שמצא את ה-URL שלך יכול לשרוף את כל ה-10k neurons שלך בדקה אחת בלולאה. שני המנגנונים שבנינו — מונה ב-KV שמחזיר 429, ו-max_tokens מוגבל בכל קריאה — עובדים יחד: ה-KV מגביל כמה קריאות, וה-max_tokens מגביל כמה כל קריאה עולה. זה בדיוק אותו KV מפרק 2, רק בתפקיד חדש של שומר-סף.
// rate-limit ב-KV לפני קריאת AI — מגן על תקציב ה-neurons
const used = Number(await env.RATE.get(apiKey) ?? 0);
if (used > LIMIT) {
return new Response("Rate limit exceeded", { status: 429 });
}
await env.RATE.put(apiKey, String(used + 1), { expirationTtl: 86400 });
// מיפוי מודל פנימי ל-GA יחיד — נקודת שינוי אחת
const res = await env.AI.run("@cf/zai-org/glm-4.7-flash", {
messages, max_tokens: 512
});
הוסף ל-Worker בדיקת KV אחת לפני קריאת ה-AI: const n = await env.RATE.get(key); אם המספר חוצה סף — החזר 429 לפני שאתה שורף neuron. (KV binding מפרק 2.) שמור; נחבר את המונה המלא בתרגיל.
- פתח טבלה עם עמודות: מודל | neurons/M input | neurons/M output | neurons לקריאה טיפוסית | קריאות ביום מ-10,000.
- מלא שורת
llama-3.3-70b-fp8-fast(26,668 in / 204,805 out) עם 500 input + 2,000 output → ~410 neurons → ~24 ביום. - מלא שורת
glm-4.7-flashעםmax_tokens=512(אמת את ה-neuron/M שלו בטבלה החיה) → חשב קריאות ביום ותראה שהן בסדר גודל גבוה יותר. - הוסף שורת embedding (
bge— אמת את ה-neuron/M למודל שבחרת), שורתflux-1-schnell(~130 תמונות ביום), ושורתwhisper(~240 דקות ביום). - אמת מספר אחד מול
https://developers.cloudflare.com/workers-ai/platform/pricing/(הטבלה משתנה — אל תזכור, תאמת). - בתחתית כתוב: "באפליקציה שלי המגבלה שתיפול ראשונה ב-Workers AI היא ___ כי ___", וציין את שני המנופים (מודל קטן +
max_tokens).
פלט נראה לעין שתסיים איתו: טבלת neuron-budget (Markdown/Sheets) עם ≥4 מודלים, עמודת "קריאות ביום מ-10,000" מחושבת, מספר אחד מאומת מול הדף הרשמי, ומשפט מסקנה שמזהה את המגבלה הראשונה ואת שני המנופים.
- ודא ש-
[[kv_namespaces]]/binding = "RATE"קיים (מפרק 2). - route
POST /v1/chat/completions: קרא את גוף הבקשה בסגנון OpenAI ({ model, messages }). - rate-limit:
const used = Number(await env.RATE.get(apiKey) ?? 0);אם> LIMIT→ החזר 429; אחרתenv.RATE.put(apiKey, used+1, { expirationTtl: 86400 }). - מפה את שם המודל הפנימי ל-GA יחיד (
@cf/zai-org/glm-4.7-flash) — נקודת שינוי אחת אם המודל מוסר. - קרא
env.AI.runעםmessages+max_tokensמוגבל, ועטוף את התשובה במבנה OpenAI-compatible (choices[].message.content). - הרץ
npx wrangler deploy→ קרא ל-endpoint עםcurlבפורמט OpenAI ואמת תשובה תקינה + שה-429 קופץ אחרי חציית הסף. - תעד: למה
max_tokensמוגבל + rate-limit ב-KV מגנים יחד על ה-10k neurons/day.
לאימות מהיר (שלב 6) — אותה קריאה שכל כלי תואם-OpenAI שולח, רק עם ה-URL שלך. הרץ אותה כמה פעמים ברצף כדי לראות את ה-429 קופץ אחרי חציית הסף:
curl https://YOUR-WORKER.workers.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer my-test-key" \
-d '{
"model": "gpt-4o-mini",
"messages": [{ "role": "user", "content": "שלום, מה שלומך?" }]
}'
# הצלחה → 200 עם { "choices": [{ "message": { "content": "..." } }] }
# חצית את ה-LIMIT → 429 "Rate limit exceeded" (לפני ששרפת neuron)
ה-model בגוף הבקשה הוא שם לוגי מהלקוח — ה-facade ממפה אותו ל-@cf/zai-org/glm-4.7-flash בצד שלך (נקודת שינוי אחת אם המודל מוסר). זו בדיוק הגנת ה-deprecation בפעולה.
פלט נראה לעין שתסיים איתו: endpoint חי /v1/chat/completions תואם-OpenAI שעוטף את Workers AI (glm-4.7-flash), עם מונה rate-limit ב-KV שמחזיר 429 בחציית סף. שמור צילום מסך של קריאת curl מוצלחת ושל ה-429, והערה על הגנת התקציב.
סיכום ומה הלאה: מ-RAG חי לשכבת ה-media
בפרק הזה ה-Worker שלך קיבל מוח. הוספת binding אחד ([ai]) ופתאום אותו Worker שמכיר KV ו-D1 מפרק 2 מריץ inference על ה-GPU של Cloudflare — chat, embedding ויצירת תמונה — בלי שרת ובלי מפתח חיצוני. ואז בנית את הדבר האמיתי: RAG chatbot שעונה מתוך המסמכים שלך, לא מההזיות של המודל.
שים לב כמה הכל נשען על פרק 2: ה-D1 שמאחסן את טקסט ה-chunks, ה-KV ששומר על תקציב ה-neurons ב-facade — אלה אותם primitives, רק בתפקידים חדשים. זה בדיוק היופי של ה-bindings על Worker אחד: כל יכולת חדשה לא דורשת תשתית חדשה, אלא binding נוסף על מה שכבר יש. הוספת [ai] ו-[[vectorize]], וה-Worker שלך עבר מ"מאחסן נתונים" ל"מבין נתונים".
אבל אם יש דבר אחד לקחת מהפרק, הוא לא טכני אלא הרגלי: הקטלוג משתנה. llama-3.1-8b — המודל שכל מדריך עדיין ממליץ עליו — הוסר ב-2026-05-30. בחרת glm-4.7-flash במקומו, למדת לבדוק את הקטלוג החי לפני שמקבעים string, ובנית facade שמרכז את שם המודל בנקודה אחת. גם autorag() פינה מקום ל-[[ai_search]], וגם החיוב הוא per-dimension, לא per-doc.
שגרת עבודה
| תדירות | פעולה |
|---|---|
| לפני כל קביעת מודל בקוד | בדוק את /workers-ai/models/ שה-string GA וחי — אל תעתיק מדוגמה שעלולה להציג מודל deprecated. |
| לפני יצירת Vectorize index | החלט על מודל ה-embedding (וה-dims) — הם קבועים בעת היצירה ואי אפשר לשנותם במקום. |
| בכל קריאת chat | cap את max_tokens ושקול ניתוב דרך AI Gateway ל-caching של תשובות חוזרות. |
| יומי/חודשי | עקוב אחרי neuron usage; סמוך על error 4006 ולא על גרף הדשבורד שעלול לפגר. |
פרוס את ה-RAG chatbot באמת ושאל אותו שאלה שהתשובה לה רק במסמך שלך. הרגע שבו הוא עונה נכון מתוך הטקסט שאתה הזנת — ולא מהזיכרון הגנרי — הוא מה שהופך את כל הפרק ממושגים למיומנות. זו היכולת היחידה הכי גבוהת-מינוף בפרק.
שמור ב-README של הפרויקט את ה-URL של ה-RAG chatbot החי, את שם ה-Vectorize index, ואת טבלת ה-neuron-budget. בפרק 4 נוסיף R2 לאותו wrangler.toml לשכבת media.
- למה output tokens שורפים יותר neurons מ-input tokens, ואיך זה משפיע על מספר הקריאות שנשארות לך ביום? (רמז: השווה 26,668 ל-204,805 לכל מיליון.)
- איך תזהה שמדריך ישן משתמש ב-binding ה-deprecated של AI Search, ובמה תחליף אותו? (רמז:
autorag()מול[[ai_search]].) - מתי תבחר Vectorize ולא AI Search, ולמה? (רמז: real-time מול עיכוב יום, ושליטה על dims.)
- איך בחירת
bge-m3במקוםbge-smallמשפיעה על מספר המסמכים החינמיים, ולמה זה trade-off ולא שדרוג חינם? (רמז: 1024 מול 384 ממדים, 5M מחולק.) - למה ניתוב ל-OpenAI דרך AI Gateway לא משתמש ב-neurons החינמיים, ומתי כן כדאי להשתמש ב-Gateway? (רמז: hosted מול proxied, ו-caching.)
נכנסת לפרק עם Worker שיש לו זיכרון (KV, D1) ויצאת עם Worker שיש לו מוח. ראית ש-Workers AI מריץ מודלים hosted על ה-GPU של Cloudflare, ש-neurons הם המטבע (10,000 ביום, reset 00:00 UTC), ושרוב ה-burn מגיע מ-output tokens — ולכן מודל קטן + max_tokens מוגבל הם שני המנופים שמכפילים את התקרה.
ובעיקר — בנית. Worker עם 3 קריאות AI.run(), RAG chatbot חי על המסמכים שלך עם Vectorize + D1 + glm-4.7-flash streaming, טבלת neuron-budget אישית, ו-facade תואם-OpenAI עם rate-limiting ב-KV. וחשוב מכל — פיתחת את ההרגל לאמת את הקטלוג החי, כי llama-3.1-8b כבר לא שם.
בפרק הבא ניקח את ה-Worker החכם הזה ונוסיף לו שכבת media ב-$0: R2 + Image Transforms ל-CDN תמונות, Browser Run ל-screenshot API, ו-Cloudflare Calls לווידאו — והפעם יצירת תמונה מ-Flux כבר ביד.
צ'קליסט — סיכום פרק 3
- הרצתי prompt ב-Workers AI Playground עם
glm-4.7-flashוקיבלתי תשובה בעברית. - אני מבין מה זה neuron, שיש 10,000 ביום (reset 00:00 UTC), ושהם נספרים רק על hosted models.
- אני יודע למה output tokens שורפים יותר מ-input, ומחשב כמה קריאות נשארות לי מ-10,000.
- אני מזהה את שני המנופים: מודל קטן (
glm-4.7-flash) +max_tokensמוגבל. - אני יודע ש-
llama-3.1-8b/70b,llama-3-8bו-mistral-7b-v0.1הוסרו ב-2026-05-30 — ולא מקבע אותם בקוד. - הוספתי
[ai]/binding = "AI"ל-wrangler.tomlשל פרק 2. - בניתי Worker עם 3 routes:
/chat,/embed(אימתתי 384-dim),/image(PNG מ-Flux). - יצרתי Vectorize index ב-
--dimensions=384ואני מבין שה-dims קבועים בעת היצירה. - אני מחשב את תקרת המסמכים החינמית: 5M ÷ ממדי המודל (~13,020 ל-
bge-small). - בניתי RAG chatbot חי שעונה מתוך המסמכים שלי (Vectorize + D1 + streaming), בתוך ה-free tier.
- אני יודע להשתמש ב-
[[ai_search]]binding ולא ב-env.AI.autorag()ה-deprecated. - אני יודע מתי לבחור Vectorize (real-time, שליטה) ומתי AI Search (אפס תשתית, עיכוב יום).
- אני מבין ש-proxied models = 0 neurons חינמיים, ושׁ-AI Gateway caching חוסך neurons על hosted.
- בניתי facade תואם-OpenAI עם rate-limit ב-KV שמחזיר 429 בחציית סף.
- שמרתי ב-README את ה-URL של ה-chatbot, שם ה-index, וטבלת ה-neuron-budget לקראת פרק 4.