(1) מקובץ הנחיה אחד למספר קבצי הנחיה (Markdown)
(2) אבטחת *תהליך* פיתוח בר-שכפול/דטרמיניסטי (repeatable)
(1)+(2) = תהליך חסכוני שקל לדבג ולשכפל
הבעיה והפתרון
מפתחים מגלים די מהר שקובץ הנחיה (Markdown) הוא הכרחי לפיתוח AI.
הנאמר כאן נכון לכל המערכות AI. אתייחס לקלוד כי הוא הבייבי שלי…
הבעיה: כבר בפרויקטים לא מאוד גדולים קל להגיע ל- 900 שורות ויותר בקובץ הנחיה של פרויקט,
כאשר ההמלצה היא לחצי ואפילו פחות. וזה קובץ שמופעל עם כל פרומפט.
כלומר יש עלויות בזמן ואסימונים (Tokens), בקיצור, כסף.
לשמחתנו, ניתן לחסוך על ידי פירוק הקובץ הגדול למספר קבצי הנחיה.
בהזדמנות זו שאנחנו נגדיר מספר קבצי הגדרה נשאף גם להגדיר תהליך פיתוח דטרמניסטי,
שיבטיח יכולת שכפול של אותם השלבים בדיוק – ללא תלות בסביבת ה AI.
כאשר התהליך קבוע, עם שלבים ידועים מראש, ניתן לשכפל וקל לדבג.
הפתרון: הגדרת מספר קבצי הנחיה, לכל אחד המשימה שלו.
זה בדיוק נושא המאמר הזה. גילוי נאות: כל נכתב בעזרת קלוד AI נבדק ויושם במספר פרויקטים שלי.
הרעיון הכללי
בסביבת עבודה מתקדמת של AI, הקובץ החשוב ביותר בדרך כלל אינו קוד האפליקציה ואינו ה-prompt.
אלא קובץ הנחיה Markdown פשוט ששוכב בשקט בתוך הפרויקט.
לדוגמה: AGENTS.md, CLAUDE.md, SKILL.md, DESIGN.md ועוד כמה קטנים נוספים.
המנגנון
קבצי ההנחיה נראים זניחים. שלושים שורות, לפעמים.
אבל הם קובעים איך הסוכן חושב עוד לפני שהוא כותב קוד, עורך מסמך, או נוגע בקבצים שלכם.
הדרך הנכונה להבין אותם היא זו: הם הקשר שמור־במטמון (cached context) בעל סדר קדימות (הפעלה) קבוע.
prompt נקרא פעם אחת ונשכח.
קובץ הנחיה נקרא מחדש בתחילת כל משימה, על ידי כל סוכן, והוא גובר על כל מה שהסוכן היה אחרת מנחש.
זה כל המנגנון. כל מה שנתאר בהמשך הוא רק החלטה מה שייך למטמון הזה ואיזה קובץ מחזיק בו.
קובץ הנחיה הוא רשימת משימות לביצוע
הקפיצה הבאה בעבודה עם AI לא תגיע מ-prompts ארוכים יותר. prompt הוא בקשה.
קובץ הנחיה הוא תוכנית עבודה ("פרוצדורה") – רשימת משימות לביצוע.
הסוכן שלכם צריך שולחן עבודה לפני שהוא צריך משימה — אתם נותנים לו את הכללים פעם אחת
(איך אתם כותבים, איך אתם מתמללים שמות, באילו כלים אתם משתמשים, במה אסור לגעת לעולם,
מה המשמעות של "סיום") ושומרים את הכללים האלה במקום שבו הסוכן קורא אותם (בקובץ הנחיה).
קובץ הנחיה (Markdown) מנצח במשימה הזו לא משום שהוא מתוחכם אלא משום שהוא פשוט, קריא,
מנוהל־גרסאות ונייד: אתם יכולים לפתוח אותו, הצוות יכול לערוך אותו, הסוכן יכול לקרוא אותו, git יכול לעקוב אחריו.
טעות אופיינית היא קובץ־על ענק אחד. התיקון הוא שכבות — לכל קובץ תפקיד אחד.
קובצי ההנחיה
AGENTS.md — החוזה של הפרויקט, ללא תלות בכלי
זה הקובץ שהפך לתקן ממשי ולא רק למוסכמה.
הוא נולד ב-OpenAI ומנוהל כיום על ידי ה-Agentic AI Foundation של קרן לינוקס – אותו גוף שמנהל את MCP –
והוא נקרא באופן מובנה על ידי Codex, Cursor, Copilot, Gemini CLI, Aider, Windsurf, Zed, Factory, Jules
ועוד עשרים־ומשהו כלים, על פני עשרות אלפי מאגרים.
מה שנכנס לתוכו הוא מכוון להיות משעמם ותפעולי: גרסאות השפה וסביבת הריצה המועדפות,
פקודות ה-dev/build/test/lint המדויקות, מוסכמות עיצוב ושמות, ציפיות בדיקה, מוסכמות PR,
וגבולות מפורשים כמו "לעולם אל תַּקְמִיט סודות" או "התיקייה הישנה הזו עדיין משתמשת ב-callbacks".
מודל המחשבה מתוך המפרט הוא README לסוכנים — אין שדות חובה,
וכללי סגנון־הקוד צריכים לכסות רק את מה ששונה מברירות המחדל של השפה.
שני דברים שחשובים לאופן שבו אתם באמת משתמשים בו:
העיקר הוא ביטול הפיצול. לפני AGENTS.md, כל כלי קרא קובץ אחר – קרסור קורא cursorrules.
קלוד את CLAUDE.md – ורוב הסוכנים קראו את מה שמצאו וקיוו לטוב.
הסיבה לשמור על AGENTS.md כקובץ הראשי היא שקובץ אחד מגיע כעת כמעט לכל סוכן;
אתם מוסיפים קובץ ייעודי־לכלי רק כשאתם זקוקים ליכולת שרק לכלי ההוא יש.
במונורפו חל הכלל "הקובץ הקרוב ביותר מנצח". הציבו AGENTS.md בכל חבילה;
הסוכן קורא את הקרוב ביותר לקובץ הנערך. זו התכונה הכי לא־מנוצלת –
הנחיות ברמת ה package עדיפות על קובץ אחד מנופח בשורש המונוריפו.
בשורה אחת: מה הפרויקט הוא, ואיך לבנות, לבדוק ולתרום אליו נכון –
ה-README שסוכן קורא במקום לנחש, נייד על פני כל כלי שקורא את התקן.
דוגמה — AGENTS.md:
# AGENTS.md
## Project
Or Eitan — charitable lifecycle-event matching platform.
WordPress plugin (PHP 8.4) + React SPA mounted via shortcode.
## Stack
- PHP 8.4, WordPress 6.x, custom MySQL tables (not CPTs)
- React 18 (functional components), webpack build
- Auth: cookie + nonce REST; custom roles, least privilege
## Commands
- Install: composer install && npm ci
- Build: npm run build
- Lint: composer lint && npm run lint
- Test: composer test && npm test
- Done gate: ./verify.sh # must exit 0 before any task is "done"
## Conventions
- All DB access via $wpdb->prepare; never interpolate SQL.
- Every REST route declares an explicit permission_callback — no public writes.
- Soft-delete only; never hard-DELETE domain rows.
- RTL Hebrew is the default; design tokens live in DESIGN.md.
## Boundaries
- Never edit /vendor or /node_modules.
- Never read or write .env; never commit secrets.
- Don't touch wp-config.php without explicit approval.
CLAUDE.md — השכבה הייחודית ל-Claude
CLAUDE.md הוא הקובץ הייעודי־לכלי עבור Claude Code (וגם למשטחי ה-skills/memory של ה-Claude API). מערכת היחסים עם AGENTS.md היא החלק שאנשים טועים בו. רוב הכלים קוראים את AGENTS.md וגם את הקובץ המובנה שלהם, כך שכללים משותפים יושבים במקום אחד; Claude Code קורא את CLAUDE.md באופן מובנה ומושך את AGENTS.md בהפניה. הדפוס שהתגבש: שימו כללים חוצי־כלים ומשותפים ב-AGENTS.md, ושִׁמרו את CLAUDE.md למה שבאמת ייחודי ל-Claude.
"ייחודי ל-Claude" בפועל פירושו בחירת מודל והיגיינת סשן, העדפות תקציב־הקשר ו-/compact, הנחיות לתת־סוכנים או ל-context-fork שרק Claude Code מבין, והעדפות אינטראקציה למשטח הצ'אט. ארכיטקטורה, פקודות build ומוסכמות קוד אינן שייכות לכאן אם אתם מריצים גם סוכנים אחרים — הן שייכות ל-AGENTS.md שם כולם רואים אותן.
אזהרה מעשית, כי היא נושכת: CLAUDE.md שעובר כמה מאות שורות עושה פחות ממה שאתם חושבים. הקובץ נקרא לתוך ההקשר בכל משימה, כך שאורך הוא עלות ישירה של טוקנים־וקשב, וקובץ ארוך יחיד קובר את הכללים שמשנים התנהגות מתחת לכאלה שלא. התיקון הוא התזה מיושמת מילולית — משכו את עובדות הפרויקט החוצות־כלים (stack, build/test, מוסכמות, כללי טבלאות־מותאמות ו-REST-auth) אל AGENTS.md; דחפו כללים ספציפיים־לתחום (React frontend מול PHP/REST) לקובצי "הקרוב־ביותר־מנצח" בתיקיות שלהם; הרימו דברים כמו צ'ק־ליסט אבטחה ל-SKILL.md שהסוכן טוען רק כשנוגעים ב-auth או ב-endpoints; ותנו ל-CLAUDE.md להצטמצם לחומר שבאמת ייחודי ל-Claude. אותו ידע, הרבה פחות ממנו מתחרה על קשב בכל משימה לא־קשורה. בונוס: CLAUDE.md/AGENTS.md יציבים שומרים על ה-prompt cache חם (עוד על כך בפרק העלות).
בשורה אחת: קומץ הדברים ש-Claude צריך במיוחד — התנהגות מודל, סשן והקשר — שאינם עובדות פרויקט ואין להם מה לחפש במקום שסוכנים אחרים קוראים.
דוגמה — CLAUDE.md:
# CLAUDE.md
Project facts live in AGENTS.md — read it first. This file is Claude-only.
## Model
- Default to opusplan: plan with Opus, execute with Sonnet.
- Keep planning and execution separate; don't plan during edits.
## Session
- /compact at task boundaries, never mid-task.
- Fresh session per feature, to keep the cached prefix stable.
## Done
- Never declare a task done until ./verify.sh exits 0.
- If a Stop gate blocks you, fix the cause — do not bypass it.
SKILL.md — יכולת, לא פרויקט
זה הקובץ הכי שונה מכולם. AGENTS.md ו-CLAUDE.md מתארים את הפרויקט הזה.
skill מתאר איך לעשות משהו, והוא הולך עם הסוכן על פני כל פרויקט:
skill לכתיבת הודעות commit,
skill לסקריפט מיגרציה,
skill למילוי טופס PDF,
כל skill עצמאי וניתן לשימוש חוזר בכל מקום.
מבחינה מבנית, skill הוא תיקייה המכילה לכל הפחות קובץ SKILL.md,
ובאופן אופציונלי תת־תיקיות לסקריפטים, הפניות ונכסים.
הקובץ הוא frontmatter בפורמט YAML ועוד גוף Markdown חופשי. רק שני שדות הם חובה:
---
name: my-skill-name
description: What it does AND when to use it
---
# instructions in markdown below
האילוצים ספציפיים: name עד 64 תווים, אותיות קטנות / ספרות / מקפים בלבד,
ללא מילים שמורות כמו "anthropic" או "claude"; description עד 1024 תווים
וחייב להסביר גם מה ה-skill עושה וגם מתי להשתמש בו.
סעיף ה"מתי" הזה הוא קריטי — הוא אות הניתוב.
המנגנון שמאפשר ל-skills להתרחב הוא חשיפה הדרגתית.
בתחילת הסשן הסוכן סורק כל תיקיית skill אך קורא רק את ה-frontmatter,
ובונה קטלוג קליל ב-system prompt – לעולם לא את הגוף המלא.
כשמשימה תואמת לתחום של skill, הסוכן טוען את גוף ה-SKILL.md המלא.
קובצי הפניה וסקריפטים אינם עולים אף טוקן הקשר עד שהם נקראים בפועל,
וסקריפטים יכולים לרוץ דרך bash כך שרק הפלט שלהם – לא קוד המקור – צורך הקשר.
זו הסיבה שאפשר להתקין חמישים skills בלי לנפח את ה-prompt:
אתם משלמים תמיד על שמות ותיאורים, על הגוף רק לפי דרישה.
הניתוב עצמו מעניין – Claude Code משתמש בניתוב מבוסס־LLM ולא ב-embeddings או מסווגים;
הוא מעצב את שמות ה-skills והתיאורים לתוך ה-prompt ומניח למודל להחליט איזה חל.
בגלל זה תיאורי skill טובים נכתבים מעט "דחפניים" – מאייתים במפורש את תנאי ההפעלה
במקום לתאר את היכולת באופן יבש — כי תיאור מעורפל לא יופעל.
SKILL.md הוא כיום תקן פתוח בפני עצמו, מפורסם ב-agentskills.io
ונתמך על ידי Claude Code, Codex CLI, Gemini CLI ו-Copilot,
כשהפורמט המרכזי נייד בין כולם – אם כי חלק מהתכונות המתקדמות נשארות יעודיות־לכלי.
בשורה אחת: יכולת אחת לשימוש חוזר, נטענת רק כשמשימה תואמת לה, שנוסעת עם הסוכן על פני כל פרויקט.
דוגמה — wp-rest-security-review/SKILL.md:
---
name: wp-rest-security-review
description: Reviews WordPress REST routes for auth and injection flaws. Use
whenever editing a register_rest_route call, a permission_callback, or any
endpoint that reads or writes the database.
---
# WordPress REST Security Review
When this skill is active, check every touched REST route for:
1. An explicit `permission_callback` — never `__return_true` on a write route.
2. Field whitelisting on input; reject unknown keys.
3. `$wpdb->prepare` on every query; flag any string interpolation.
4. Capability checks that match the least-privilege role for the route.
Then run `./scripts/security-scan.sh` and report findings before finishing.
DESIGN.md — החוזה הוויזואלי
פחות מתוקנן; מוסכמה, לא מפרט. הסיבה שמגיע לו קובץ משלו ולא מגורים בתוך AGENTS.md
היא היקף וקהל: כללי עיצוב נדרשים ספציפית כשהסוכן בונה או מעצב מחדש UI,
ושליפתם לקובץ נפרד שומרת אותם מחוץ להקשר בזמן עבודת backend או תשתית.
מה ששייך לכאן הוא מה שגורם ל-UI מיוצר להפסיק להיראות מתבני – אסימוני העיצוב עצמם (סולם
צבע, סולם טיפוגרפיה, יחידות מרווח), מוסכמות רכיבים, מתי להשתמש באיזו פרימיטיבה של פריסה,
טיפול ב-RTL, מינימום נגישות, ואנטי־דפוסים מפורשים ("אל תושיט יד ל-card כשרשימה תספיק").
לעבודת Elementor/React-ב-WordPress ספציפית, DESIGN.md הוא הבית הטבעי למיפוי kit-JSON-לתֵמה
ולכללים לגבי היכן רכיבים חדשים מותרים מול היכן נשארים על הסגנונות הקיימים – כתובים פעם אחת
כך שהסוכן מיישם אותם בעקביות במקום להחליט מחדש בכל רכיב.
בשורה אחת: איך כל מה שאתם בונים אמור להיראות ולהתנהג – נטען רק כשהסוכן נוגע ב-UI, כך שהוא לא מפריע בזמן עבודת backend.
דוגמה — DESIGN.md:
# DESIGN.md
## Tokens
- Color: --brand #1f6feb --bg #ffffff --text #1a1a1a --danger #d4351c
- Type: 12 / 14 / 16 / 20 / 28 px; body 16px / line-height 1.6
- Spacing: 4-based — 4, 8, 12, 16, 24, 32
## Rules
- Direction is RTL by default; mirror layout, keep numerals LTR.
- New components use MUI, themed from the Elementor kit tokens above.
- Scope MUI styles so they never leak into Elementor-rendered pages.
## Anti-patterns
- No card where a list will do.
- No color outside the tokens.
- No fixed pixel widths on containers — use the spacing scale + flex/grid.
קובץ קול־הכתיבה
אותו היגיון, תחום אחר. כשסוכן מנסח פרוזה – מאמרים, תיעוד, מיילים ללקוחות, הערות גרסה – הוא נופל לרֵגיסטר מזוהה.
קובץ קול עוקף את זה: קצב משפטים, אוצר מילים שאתם נמנעים ממנו, העדפות מבניות,
ובאופן אידיאלי כמה דוגמאות קצרות של לפני/אחרי, כי מודלים מכוילים לפי דוגמאות הרבה יותר טוב
מאשר לפי תארים.
"תמציתי וישיר" כמעט לא עושה דבר; פסקה מהכתיבה האמיתית שלכם לצד שכתוב עושה את רוב העבודה.
הקובץ הזה הוא מה שעוצר את המקצב האחיד והמסגיר של AI.
בשורה אחת: איך פרוזה אמורה להישמע כש-Claude כותב עבורכם – נלמד מדוגמה,
כי מודלים מתאימים את עצמם לדגימה הרבה יותר טוב מאשר לתארים.
דוגמה — VOICE.md:
# VOICE.md
## Sound like
- Direct and technical, no hype. Short sentences, active voice.
- Lead with the answer, then the reason.
## Avoid
- "delve", "leverage", "in today's fast-paced world", emoji
- Hedging stacks ("it might perhaps be worth considering")
## Before → after
Before: "It may be beneficial to consider leveraging caching here."
After: "Cache this — it cuts the query from 400ms to 12ms."
השכבה הלא־פורמלית — instructions.md / prompt.md / memory.md
שלושת אלה הם קטגוריה שונה — לא תקנים, רק מוסכמות שמות שצוותים מאמצים. שווה להפריד לפי תפקיד:
prompt.mdהוא בדרך כלל תבנית prompt או משימה לשימוש חוזר שאתם מדביקים או מפנים אליה, ולא הקשר קבוע שהסוכן קורא אוטומטית.instructions.mdנוטה להיות סל לכללים פרוצדורליים אד־הוק שעדיין לא זכו לבית ספציפי יותר — לעיתים סימן שמשהו אמור בסופו של דבר "להתקדם" אלAGENTS.mdאוSKILL.md.memory.mdהוא הייחודי ביותר: מצב לקריאה־בלבד־בהוספה (append-only) שמשמר עובדות והחלטות בין סשנים — "בחרנו בטבלאות MySQL מותאמות על פני CPTs, והנה למה", "באג שער התשלום היה מרוץ של callback" — כך שהסוכן לא דן מחדש בהחלטות סגורות. במקום ש-AGENTS.mdאומר איך לעבוד,memory.mdמתעד מה כבר הוחלט.
בשורה אחת: שלושה תפקידים קטנים – תבנית משימה לשימוש חוזר (prompt.md),
מכלאה לכללים אד־הוק שטרם קודמו (instructions.md), ויומן הוספה־בלבד של החלטות סגורות (memory.md).
דוגמאות:
# prompt.md (reusable task template)
Add a REST endpoint for {resource}: route + permission_callback + tests.
Follow AGENTS.md conventions. Run ./verify.sh before declaring done.
# instructions.md (ad-hoc rules not yet promoted)
- Prefer dependency injection over the global $wpdb in new classes.
- New migrations go in /migrations with a numbered prefix.
# memory.md (append-only decisions)
- 2026-05: chose custom MySQL tables over CPTs (query perf, FK control).
- 2026-06: Bit gateway "failed" bug was a callback race — guard added.
איך סדר הקדימויות מוכרע
"קובץ אחד, תפקיד אחד" נכון אבל מדלג על שאלת הקדימות, שזה מה שצריך כשקבצים חופפים. הסדר שרוב ההגדרות מגיעות אליו:
AGENTS.md(וצאצאי "הקרוב־ביותר־מנצח" שלו) נושאים את אמת הפרויקט הניידת.- קבצים ייעודיים־לכלי (
CLAUDE.md,GEMINI.md) גוברים רק במקום שבו לכלי יש תכונה ייחודית. - קובצי
SKILL.mdמזריקים יכולת לפי דרישה בלי לתפוס מקום בהקשר (context) בשאר הזמן. DESIGN.mdוקובץ הקול הם תלויי־תחום הנטענים כשהעבודה נכנסת לתחומם.- השכבה הלא־פורמלית מחזיקה תבניות ומצב שנצבר.
המשמעת ששומרת על זה חד היא התנגדות למשיכה לעבר קובץ ענק אחד.
כל כלל שחי בקובץ שהסוכן קורא בכל משימה הוא כלל שמתחרה על קשב עם הכלל שבאמת חשוב למשימה הזו.
קטן, תחום־מוגדר, לפי־דרישה — מנצח את "מקיף־אך־תמיד־טעון" כמעט בכל פעם.
נקודת הקצה: ה-CDE
ברגע שאתם מקבלים שהקבצים הם מערכת עבודה, השאלה הבאה כותבת את עצמה. אם כל קובץ מלמד את הסוכן דבר אחד, למה הם מסתכמים?
לסביבה — עם כללים, שערים והגדרת סיום.
קראו לזה CDE: סביבת הפיתוח של Claude (Claude Development Environment).
השולחן, מסודר לגמרי, עבור מפתח אחד שעובד בדרך אחת מסוימת.
CDE אינו CLAUDE.md גדול יותר. זהו כל הלולאה: קובצי ההנחיה שמתזמרים,
ועוד הכלים שאוכפים, ועוד האימות שמוכיח שהעבודה נעשתה.
קובצי ההנחיה הם החלק שרוב האנשים כבר מכירים.
שני החלקים האחרים הם המקום שבו עוצרים מוקדם מדי, והם ההבדל בין סוכן שבדרך כלל מתנהג לבין סביבה שאפשר לסמוך עליה.
"מתאים למפתח" הוא אילוץ העיצוב שחשוב.
CDE הוא אישי באותו אופן שמאגר dotfiles הוא אישי.
אחד עשוי לקבע PHP 8.4 NTS ו-Node 20, להריץ בדיקות אבטחה לפני שמשהו נשלח,
להניח RTL, ולהתייחס לטבלאות MySQL מותאמות כדבר נורמלי ולא כריח רע.
שלכם מקודד מה שהעבודה שלכם באמת היא.
ה-CDE הוא התשובה המקודדת ל"איך אני עובד", שהפכה ניתנת־להרצה כך שהסוכן יורש אותה במקום לנחש אותה.
להפוך את ה-CDE לדטרמיניסטי
הנה האמת הלא־נוחה שהשיווק נמנע ממנה: אי אפשר להפוך את המודל לדטרמיניסטי.
מודל שפה דוגם טוקנים. אפילו ב-temperature אפס, batching וחומרה הופכים את השחזור המדויק ללא־אמין –
וחשוב מכך, שחזוריות מעולם לא הייתה מה שבאמת רציתם. אתם לא רוצים "אותה תשובה בכל פעם".
אתם רוצים "כל פעולה מוגדרת מתבצעת, בכל פעם". אלה מטרות שונות, וערבובן הוא הטעות השורשית.
אז הפסיקו לנסות להפוך את המוח לדטרמיניסטי. הוציאו את הדטרמיניזם מהמודל אל תוך הרתמה (harness). זה העיקרון שעליו נשען כל ה-CDE:
כל דבר שאתם צריכים להיות בטוחים ב-100% שקורה חייב להיאכף על ידי משהו שאינו ה-LLM.
פרוזה ב-CLAUDE.md היא דחיפה הסתברותית. היא מעלה את הסיכוי שהמודל יעשה את הדבר הנכון ואינה מבטיחה דבר. ברגע ש"בטוח ב-100%" נכנס לדרישה, הנחיות הן הכלי הלא־נכון ושערים הם הכלי הנכון.
ארכיטקטורת שתי השכבות
- השכבה הרכה (
AGENTS.md,CLAUDE.md, skills) מתזמרת — היא אומרת ל-Claude מה לנסות ובאיזה סדר. - השכבה הקשה (hooks, ועוד git pre-commit ו-CI מאחוריהם) אוכפת — היא מבטיחה מה באמת קורה.
תפקיד השכבה הרכה מצטמצם למשפט כן אחד: הפעל את השערים, ואל תכריז על סיום עד שהם ירוקים. השערים עושים את השאר.
השערים: ה-hooks של Claude Code
ב-CDE של Claude Code, השערים הם hooks — פקודות shell מוגדרות־משתמש, נקודות קצה HTTP, או prompts ל-LLM שמתבצעים אוטומטית בנקודות קבועות במחזור החיים, רשומים ב-.claude/settings.json. הניסוח בתיעוד מדויק: hooks נותנים שליטה דטרמיניסטית — לא בקשה דרך prompt, אלא ביצוע מובטח.
אירועי מחזור החיים נחלקים לשלושה קצבים: פעם אחת לסשן (SessionStart, SessionEnd), פעם אחת לתור (UserPromptSubmit, Stop), ובכל קריאת כלי בתוך הלולאה הסוכנית (PreToolUse, PostToolUse). שלושה מהם נושאים את עומס הדטרמיניזם:
PreToolUse— שער האכיפה. נורה לפני שכל כלי רץ (Bash, Edit, Write); יציאה בקוד שאינו אפס חוסמת את הקריאה כליל. כאן "לעולם אל תערוך קונפיג ייצור", "בליrm -rf, בליDROP TABLE" ו"אל תקרא.env" מפסיקים להיות בקשות מנומסות בקובץ Markdown והופכים לקירות שהמודל לא יכול לעבור.PostToolUse— שער התגובה. נורה אחרי שכלי מצליח. אי אפשר לבטל את מה שקרה, אבל אפשר לפרמט, להריץ lint, להריץ את הבדיקות המושפעות, ולהזין את התוצאה בחזרה. כל קובץ ש-Claude נגע בו עובר את ה-linter שלכם אוטומטית, בין אם Claude זכר ובין אם לא.Stop— שער הסיום. זה זה שמספק את ה"בטוח ב-100%". hook מסוגStopיכול לצאת בקוד 2 (או להחזירdecision: "block") כדי לאלץ את Claude להמשיך; אתם מתנים את החסימה בתנאי אמיתי — בדיקה כושלת — ומחזירים יציאה 0 רק כשהוא מתנקה, כך שהסוכן ממש לא יכול לסיים את תורו עד שהשער ירוק. כך "הבדיקות חייבות לעבור לפני סיום" הופך לאמת מכנית.
צורה מינימלית:
// .claude/settings.json
{
"hooks": {
"PreToolUse": [
{ "matcher": "Bash",
"hooks": [{ "type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|DROP TABLE' && exit 2 || exit 0" }] }
],
"PostToolUse": [
{ "matcher": "Write|Edit|MultiEdit",
"hooks": [{ "type": "command",
"command": "npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\"" }] }
],
"Stop": [
{ "hooks": [{ "type": "command", "command": "./verify.sh || exit 2" }] }
]
}
}
הגדרת ה-Done כסקריפט
כווצו את הפעולות הנדרשות לסקריפט אחד — make check, או verify.sh שמריץ lint, typecheck, בדיקות, build, וסריקת האבטחה שלכם. הפעולה הדטרמיניסטית היא "הרץ את הסקריפט הזה". קוד היציאה שלו הוא האמת היחידה במערכת. חַברו אותו ל-hook מסוג Stop והשאלה "האם כל הפעולות המוגדרות בוצעו?" מפסיקה להיות תלויה במילה של Claude.
#!/usr/bin/env bash
# verify.sh — the definition of done. Any non-zero exit blocks "done".
set -euo pipefail
composer lint
composer test # PHP / WordPress unit + integration
npm run lint
npm run typecheck
npm test # React
npm run build # webpack bundle must build
./scripts/security-scan.sh
האם Claude יכול לאמת זאת בכל prompt?
שתי קריאות, וההבחנה היא כל התשובה.
האם המודל יכול לאמת? הוא יכול לטעון שכן. הוא גם יכול לטעות — מודל לעיתים ידווח "הבדיקות עוברות" בלי שהריץ אותן. הצהרה־עצמית היא המודל שבודק את שיעורי הבית של עצמו, והיא לא־דטרמיניסטית בהגדרה. שימושית כ-prompt, חסרת ערך כהבטחה. לעולם אל תיתנו לה להיות הבדיקה היחידה.
האם ה-CDE יכול לאמת? כן — וזו התשובה הנכונה. אימות לכל prompt הוא בדיוק מה שה-hooks ברמת התור נועדו לו. hook מסוג UserPromptSubmit יכול להזריק את צ'ק־ליסט הקידוד שלכם בתחילת כל prompt; PostToolUse מאמת אחרי כל עריכה; ה-hook מסוג Stop מריץ את verify.sh בסוף התור ומסרב לתת ל-Claude לסיים אם משהו נכשל. האימות דטרמיניסטי כי ה-hook עושה אותו, לא כי Claude ביצע אינטרוספקציה.
הפכו את זה לבר־ביקורת ותקבלו את ה"בטוח ב-100%" המילולי. תנו ל-hook מסוג Stop לכתוב .cde/verify-<timestamp>.json — prompt, השערים שרצו, עבר/נכשל לכל אחד. כעת עמידה לכל prompt היא רישום שמכונה הפיקה על הדיסק, לא תחושה.
התקרה הכנה: hooks הופכים את הפעולות המוגדרות לדטרמיניסטיות. הם לא יכולים לגרום לדרישה לא־מוגדרת להופיע, והם לא יכולים להפוך סוויטת בדיקות גרועה לטובה. דטרמיניזם מבטיח שהתהליך רץ; הוא לא אומר דבר על האם התהליך היה הנכון.
דטרמיניזם של עלות מול דטרמיניזם של התנהגות
אלה שתי תכונות שונות, והמלכודת היא להניח שעבודה על אחת קונה לכם את השנייה. הן מושכות זו נגד זו.
דטרמיניזם של התנהגות הוא "כל פעולה מוגדרת רצה, בכל פעם". מקבלים אותו מהשערים. הוא בר־השגה ב-100% כי ההבטחה חיה בכלים, לא במודל.
דטרמיניזם של עלות הוא "אותה בקשה עולה בערך אותם טוקנים ודולרים בכל הרצה". את זה לעולם לא תשיגו במלואו, כי הנתיב של המודל לתוצאה נכונה משתנה גם כשהתוצאה נשערת להיות זהה. אותו יעד, מסע באורך שונה, חשבון שונה.
המתח הוא החלק שאנשים מפספסים: המכונה שמקשיחה התנהגות מערערת את יציבות העלות. hook מסוג Stop שיוצא בקוד 2 מאלץ את Claude להמשיך לעבוד עד שהשער מתנקה — בדיוק מה שאתם רוצים לנכונות, ובדיוק מה שהופך את ההוצאה לבלתי־צפויה, כי הרצה שנכשלת בשער שלוש פעמים עולה כמה מונים מהרצה נקייה. כל לולאת משוב של PostToolUse מוסיפה תור. אז "תמיד תעבור בדיקות" ו"תעלה סכום צפוי" מתחרים ישירות. בחרו בנכונות, ואז תָּחֲמוּ וצפו בעלות במקום לקבע אותה.
הידיות שבאמת מזיזות שונוּת עלות, לפי סדר המנוף:
העבירו עבודה דטרמיניסטית לסקריפטים, לא לטוקנים. הידית האחת שמשפרת את שתי התכונות בבת אחת. כל מה שסקריפט יכול לעשות דטרמיניסטית — lint, פרמוט, הרצת מיגרציות, יצירה מחדש של ה-webpack build, פיגום של CPT או REST route מתבנית — צריך להיות סקריפט שנקרא מ-hook, לא המודל שמנמק את זה טוקן אחר טוקן. סקריפטים רצים דרך bash ורק הפלט שלהם צורך הקשר, לא קוד המקור. כל משימה שעוברת מ"Claude מבין לבד" ל"Claude מריץ את הסקריפט" נעשית זולה וגם דטרמיניסטית יותר. צמצמו את תפקיד המודל לתזמור ולחלקים החדשניים באמת.
קַבעו את המודל לפי שלב. הרצת opusplan — Opus לתכנון, Sonnet לביצוע — היא החלטה של דטרמיניזם־עלות: טוקנים יקרים רק לשלב עתיר־ההיגיון, טוקנים זולים לעריכות המכניות. שִׁמרו על הגבול הזה חד; אל תיתנו לתכנון לדלוף לביצוע, שם המודל היקר שורף כסף על עריכות שהזול מטפל בהן מצוין.
הגבילו את לולאת ה-retry. הכשל הקלאסי הוא לולאת Stop אינסופית — השער מקפיץ את Claude אחורה, הוא נכשל שוב, חוזר חלילה, והחשבון מטפס בלי שום תמורה. התנו את החסימה במונה ניסיונות (כתבו ספירה ל-.cde/attempts, כשלו בקול אחרי N) כך שמשימה שבורה מסתיימת ברעש במקום לטחון. כישלון תחום זול וכן יותר מ-retry פתוח.
שִׁמרו על תחילית המטמון יציבה. prompt caching הופך את חזית ההקשר היציבה — system prompt ועוד מטא־דאטה של CLAUDE.md/AGENTS.md/skills — לזולה לקריאה חוזרת לאורך התורים, אבל המטמון ממופתח על כך שהתחילית יציבה ברמת הבייט. בכל פעם שאתם מערבלים CLAUDE.md ארוך אתם שוברים את המטמון ומשלמים מחיר מלא שוב. סיבה קונקרטית שנייה לכך שקובצי הנחיה רזים ומפוצלים חשובים: קבצים יציבים = מטמון יציב = עלות נמוכה וצפויה יותר.
מַכשירו את זה. תנו ל-hook מסוג Stop להוסיף טוקנים־ותורים־לכל-prompt לאותו ארטיפקט ביקורת .cde/verify-*.json. העלות הופכת נצפית לכל prompt; אתם מזהים את המשימות שמתפוצצות; "האם זה נעשה יקר" מפסיק להיות תחושה.
הסיכום ששווה לשמור על פתק דביק: דטרמיניזם של התנהגות הוא הבטחה; דטרמיניזם של עלות הוא תקציב. אל תבטיחו לעצמכם מחיר קבוע לכל prompt — הבטיחו לעצמכם תקרה ויומן.
דטרמיניזם של סביבת הבדיקות: הסעיף ששובר לכם את השערים בשקט
שער Stop דטרמיניסטי בדיוק כמידת הבדיקות שהוא מריץ. אם סוויטת הבדיקות שלכם רעועה (flaky), השער הופך להטלת מטבע — ושער הטלת־מטבע גרוע משער שאין, כי הוא או מקפיץ את Claude ללולאת retry יקרה על רעש, או מאמן אתכם להתחיל לעקוף את השער, מה שמחבל בכל המערכת.
ל-WordPress/MySQL ספציפית: הריצו בדיקות מול snapshot ידוע של מסד הנתונים או fixtures קבועים, לא מסד dev משתנה; הקפיאו את השעון כך שלוגיקה תלוית־זמן ניתנת לשחזור; וסַפְקו stub לכל HTTP יוצא. הנקודה האחרונה היא זו שנושכת — כל דבר התלוי בקריאות חיצוניות (callbacks של clearing בשער תשלום, לוגיקת משלוח של צד שלישי) הופך את העבר/נכשל של השער לתלוי בזמינות של מישהו אחר. עשו להם stub. CDE דטרמיניסטי שיושב מעל סוויטת בדיקות לא־דטרמיניסטית הוא פשוט דרך בטוחה לשלוח קוד שבור לפי לוח זמנים.
טעויות ברעיון הזה, ואיך לתקן אותן
"בטוח ב-100% דרך הנחיות" הוא טעות קטגוריאלית. אם ההבטחה חיה בפרוזה של CLAUDE.md, יש לכם הצעה חזקה, לא הבטחה. תיקון: כל פעולת־חובה עוברת ל-hook או לבדיקת CI; CLAUDE.md רק מתזמר.
דטרמיניסטי ≠ נכון. תהליך שמריץ דטרמיניסטית את הבדיקות הלא־נכונות מספק תוצאות שגויות באמינות. שערים ירוקים מרגישים כמו ביטחון ואינם, אם השערים חלשים. תיקון: השקיעו בתוכן של השערים — בדיקות אמיתיות, סריקת אבטחה שמבינה את ה-sinks של ה-stack שלכם, build שנכשל על השגיאות שאכפת לכם מהן — לא רק בקיומם. דטרמיניזם הוא מנגנון אספקה לאיכות שאתם מספקים במקום אחר.
hooks מקומיים ניתנים לעקיפה. git commit --no-verify מדלג על pre-commit hooks; מודל תחת לחץ יכול לעקוף פעולה חסומה בדרכים מפתיעות; PostToolUse לא יכול לבטל מה שכבר רץ. תיקון: הגנה לעומק. hooks מקומיים הם נוחות ומשוב מהיר; CI בצד השרת הוא השער היחיד שאי אפשר לדלג עליו. ההבטחה הבלתי־ניתנת־לעקיפה חיה תמיד ב-CI, לעולם לא על המחשב הנייד.
סביבה ייחודית־ל-Claude היא נעילת־ספק חדשה. אם כל מחזור הפיתוח מחוּוט ל-hooks של Claude Code, ההבטחות שלכם מתאדות ביום שתנסו סוכן אחר או שחבר צוות משתמש בכלי אחר. תיקון: שִׁמרו על שכבת האכיפה כללית־לכלי — git hooks, CI, verify.sh, ו-AGENTS.md — כך שההבטחות שורדות החלפת סוכן. ה-"CDE" הוא אז ציפוי דק מול־Claude מעל ליבה ניידת, ולא הליבה עצמה.
המפרט סוטה מהמציאות. CLAUDE.md ארוך וחלקית־מיושן פירושו שה"פעולות המוגדרות" עצמן כבר אינן אמינות — אתם אוכפים דטרמיניסטית את כללי האתמול. תיקון: קובצי הנחיה רזים, מנוהלי־גרסה, מקור־יחיד, ועוד בדיקת סטייה (drift) שמכשילה CI כשה-toolchain המוצהר וקובצי ה-lock בפועל אינם מסכימים.
מוטציית הקשר שוברת שחזוריות. /compact ומערכת ה-memory משנים מה בהקשר בין הרצות, כך שאותו prompt יכול לקבל תזמור שונה. תיקון: אתחלו בגבולות משימה כמדיניות, והישענו חזק יותר על השכבה הקשה דווקא משום שאי אפשר לקבע את הרכה.
הקו המקשר: כל תיקון מעביר הבטחה מהצד ההסתברותי לצד הדטרמיניסטי. זו הידית האמיתית היחידה שיש לכם.
סוגיות נוספות ש-CDE שלם חייב לכסות
מעבר לדטרמיניזם של עלות ובדיקות, שיש להם סעיפים משלהם לעיל:
קיבוע קלט, והתקרה שלו. קַבעו כמעט הכול סביב המודל — .tool-versions / .nvmrc, קובצי lock, מחרוזת גרסת המודל, קובצי ההנחיה ב-git. הדבר היחיד שאי אפשר לקבע הוא הדגימה. קַבעו את הקלטים, שַׁעֲרוּ את הפלטים, וקבלו את המודל כמשתנה החופשי היחיד.
מודל ההרשאות כחלק מה-CDE. רשימות allow/deny של כלים ומצבי הרשאה ב-Claude Code הם גם דטרמיניזם — החלטה מראש באילו כלים הסוכן יכול לגעת בלי לשאול. זה משתלב טבעי עם תפיסה ממוקדת־אבטחה ומגיע לו טיפול מפורש לצד ה-hooks.
סודות בלולאת הסוכן. כלל PreToolUse שחוסם קריאה של .env ומונע מסודות להגיע ללוגים או להקשר המודל. זול להוסיף, יקר להשמיט.
יומן פעולות בהוספה־בלבד. hook מסוג PostToolUse שמתעד כל קריאת כלי ליומן בלתי־ניתן־לשינוי — אותו דפוס audit-log שהייתם משתמשים בו באפליקציה, מיושם על הסוכן עצמו. נצפוּת (observability) היא מה שמאפשר לכם לנפות באגים למה לולאה דטרמיניסטית עשתה משהו לא־צפוי.
התאוששות ואידמפוטנטיות. מה הלולאה עושה כש-verify.sh רץ חצי או כששלב מת באמצע — כניסה מחדש בטוחה, rollback, וזיהוי תקיעות — ממוסגרים כחלק פורמלי מהמחזור ולא כרפלקס אד־הוק.
בחירת המשטח (Surface)
השאלה אינה "מה יותר נחמד" — אלא "איזה משטח יכול לארח את ה-hooks, ה-skills והשערים שעליהם ה-CDE נשען".
Claude Code, טרמינל (CLI). המקורי והכי ניתן לסקריפטינג. זה המשטח שרץ headless ב-CI — claude שנקרא בלי אינטראקציה כשער הסופי הבלתי־ניתן־לעקיפה. שליטה מקסימלית, עובד לצד כל כלי ה-CLI האחרים שלכם. פחות נעים למחזור קרא־כתוב־סקור כי אתם קוראים diffs כטקסט.
Claude Code, תוסף VS Code. העובדה המרכזית: זה לא מוצר אחר — זה אותו מנוע Claude Code, אותם מודלים, אותו CLAUDE.md, אותם hooks ושרתי MCP, אותן פקודות slash ו-skills, עטופים בפאנל שיודע איפה הסמן שלכם ומציג diffs בתוך הקוד. אתם לא מפסידים דבר בשכבת הדטרמיניזם ומרוויחים הרבה בשכבת האדם־בתוך־הלולאה: סקירה ועריכה של תוכניות Claude לפני אישור, אישור אוטומטי של עריכות, אזכור קבצים עם @ וטווחי שורות ספציפיים, היסטוריית שיחות, שיחות מרובות בלשוניות, diff אמיתי זה־לצד־זה עם שער הרשאה, וקריאה ישירה של שגיאות ה-TypeScript/ESLint שלכם (אבחוני LSP). התיעוד של Anthropic מכנה אותו הדרך המומלצת להשתמש ב-Claude Code ב-VS Code. רכיב אבחוני־ה-LSP הוא בשקט תכונת דטרמיניזם — אות דטרמיניסטי שני (פסיקת ה-language server) שמוזן ללולאה לצד ה-hooks שלכם.
Claude Code, תוסף JetBrains. אותה חוויית צ'אט ואותו מערך תכונות כמו תוסף VS Code, והוא חולק קונפיגורציה דרך אותו ~/.claude/settings.json. כך שה-hooks והשערים שלכם ניידים בין שניהם — רלוונטי רק אם תעברו אי־פעם מ-VS Code.
Claude Cowork. חיה אחרת. בנוי על אותם יסודות כמו Claude Code ומובנה לתוך אפליקציית הדסקטופ, אתם מצביעים אותו על תיקייה ונותנים הנחיות בשפה טבעית, אבל הוא במפורש ממשק הדסקטופ לעובדי ידע, במקום ש-Claude Code הוא ממשק הטרמינל למפתחים. הוא מתכנן ומבצע עבודה רב־שלבית על קבצים מקומיים — דוחות, גיליונות, מחקר, ארגון מחדש של קבצים. הוא לא המקום שבו בונים רתמת קידוד דטרמיניסטית: הוא מותאם להאצלת־תוצאות על מסמכים, לא למכונת ה-hook/gate/CI ש-CDE של קוד צריך, והוא עדיין preview מחקרי (אפליקציית הדסקטופ חייבת להישאר פתוחה, לא מתמיד בענן).
ווב / מובייל / Slack. משטחי נוחות להפעלה או בדיקה של עבודה הרחק מהשולחן — Dispatch מאפשר להקצות משימה מהטלפון ולהשלים אותה בדסקטופ — אבל לא המקום שבו ה-CDE נכתב או נאכף.
ההמלצה
לבנייה ולהרצה של ה-CDE הדטרמיניסטי: תוסף VS Code של Claude Code ככלי היומיומי,
עם מצב הטרמינל / headless כגיבוי ה-CI.
זה אותו מנוע שחולק settings.json אחד, כך שאלה לא שתי הגדרות – זה CDE אחד עם שני שערי כניסה.
ההיגיון ספציפי לעבודה. כל אסטרטגיית הדטרמיניזם חיה ב-hooks של .claude/settings.json,
ב-skills וב-AGENTS.md/CLAUDE.md – ותוסף VS Code נושא את כל זה ללא שינוי
תוך שהוא מוסיף שלושה דברים שמחזקים את הלולאה ולא רק מקשטים אותה:
- diffs בתוך הקוד עם שער הרשאה נותנים נקודת ביקורת אנושית חזותית מעל שערי ה-hook המכניים;
- אבחוני LSP מזינים דעה שנייה אמיתית ללולאה;
- וסקירת-תוכנית־לפני־אישור מאפשרת לתפוס גישה גרועה לפני שטוקנים מתבזבזים על ביצועה – גם זה רווח עלות.
ואז הטרמינל ב-CI מריץ את אותם hooks headless כשער שאי אפשר לדלג עליו ממחשב נייד.
hooks מקומיים הם משוב מהיר; CI הוא ההבטחה.
טיפ:
שווה להחזיק את Cowork, אבל לא לבסיס הקוד.
Cowork הוא הכלי הנכון למחצית ה no-code של העבודה. לדוגמה: דוחות אירוע, תיעוד טכני, מסמכים מול לקוח, סינתזת מחקר.
שם אתם רוצים האצלת תוצאות על קבצים ואינכם זקוקים לשערים.
שִׁמרו אותו במסלול הזה: לתת למהל הפיתוח לעשות את עבודת המהנדס זו אי התאמה בזבזנית.
הכלל האחד שהופך את בחירת המשטח לבטוחה ולא לקריטית:
מכונת ה-hook/gate חזקה והחלקים המקומיים שלה ניתנים לעקיפה (--no-verify, prompt הרשאה שנעקף).
ההבטחה הבלתי־ניתנת־לעקיפה חייבת לחיות ב-CI ללא קשר לאיזה שער כניסה אתם משתמשים ביומיום.
סיכום: מבנה ה-CDE
CDE הוא שלוש שכבות ערוכות על רעיון אחד:
- תזמור (רך, הסתברותי):
AGENTS.mdלאמת פרויקט ניידת,CLAUDE.mdלייחודי־ל-Claude,
SKILL.mdליכולת לפי דרישה,DESIGN.mdוקובץ קול לחוזי תחום, השכבה הלא־פורמלית לתבניות והחלטות.
רזה, מפוצל, מנוהל־גרסאות. - אכיפה (קשה, דטרמיניסטי): hooks מסוג
PreToolUse/PostToolUse/Stop,
הגדרת סיום מתוסרטתverify.sh, git pre-commit, ו-CI כשער הסופי הבלתי־ניתן־לעקיפה. - הוכחה (בר־ביקורת): רישום על הדיסק לכל prompt של אילו שערים רצו ועברו, ועוד עלות טוקנים/תורים,
כך ש"בטוח ב-100%" הוא קובץ שאפשר לפתוח ולא טענה שהמודל טוען.
אי אפשר להפוך את המודל לדטרמיניסטי. ניתן להבטיח תהליך דטרמיניסטי, את העלות לנצפית,
ואת התוצאה לברת־הוכחה. זו הסביבה – והיא מתאימה למפתח כי המפתח כתב אותה.
החזון: להיות הטלפון הראשון שלך לעולם האינטרנט.
יזם ומוביל טכנולוגי מחזון ורעיון למוצר מתפקד ומוכר בשטח. פיתח מעל 15 מוצרים טכנולוגיים במהלך השנים וכיום מאות אתרים – בעיקר וורדפרס ו REACT – ומספר אפליקציות אינטרנט ייחודיות.
מתמחה בפיתוח אפליקציות, תוספים ותבניות, בניית אתרים, קידום אתרים, שיפורי אבטחה ואתרים מהירים. מחפש תמיד לעשות את המדויק, מקצועי ואם צריך שיהיה שונה מאחרים.