ENGINEERING CASE STUDY · SELF-HOSTED AI PIPELINE

סוכן לידים אוטונומי על תשתית עצמית:
n8n, Claude ו-Ollama בצינור אחד.

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

7צמתים בצינור
2מודלי שפה (ענן + מקומי)
~30sקצה-לקצה לכל ליד
0 ₪עלות תשתית קבועה
Design Goals

דרישות התכן

The Pipeline

הצינור: workflow אחד, שבעה צמתים

קנבס ה-workflow ב-n8n: Form Trigger, ניתוח Claude עם Structured Output, טיוטת Ollama, שני צמתי IF, טלגרם, Data Table ו-SMTP { } source

// n8n 2.31.6 self-hosted. הקווים המקווקווים: חיבורי מודל/פרסר לצמתי ה-LLM Chain · לחיצה על התמונה פותחת את ה-JSON המלא (ללא credentials) - אפשר לייבא ישירות ל-n8n

Form Trigger (async) → Claude scoring → Ollama draft → IF score≥70 → TelegramData Table insert → IF score≥20 → SMTP
01 · INTAKEForm Triggerטופס מתארח על n8n עצמו. responseMode: onReceived - הפונה מקבל אישור מיידי וה-pipeline ממשיך אסינכרונית, כך שזמני ה-LLM לא חוסמים את ה-UX.
02 · REASONINGLLM Chain + Claudeקריאה אחת ל-Claude Sonnet עם Structured Output Parser שכופה סכמת JSON. עברית חופשית נכנסת, אובייקט טיפוסי יוצא - בלי regex על טקסט חופשי.
03 · LOCAL LLMOllama on-premaya-expanse:8b על RTX 2070S מנסח טיוטת מענה בעברית. keep_alive קצר משחרר VRAM כשהמודל לא בשימוש.
04 · ROUTINGשני צמתי IFציון 70+ שולח התראת טלגרם. ציון 20+ שולח מייל אישור. מתחת לזה: רק רישום, אפס תעבורה יוצאת - לא שולחים מיילים לכתובות זבל.
05 · PERSISTENCEn8n Data Tableשכבת הנתונים המובנית של n8n משמשת כ-CRM: insert אחד לליד עם הציון, הנימוקים, ההמלצה והטיוטה. בלי DB חיצוני לנהל.
06 · EGRESSTelegram + SMTPBot API לטלפון שלי; Gmail SMTP עם app password ייעודי ל-ilan@ilans.net. שני הערוצים כ-credentials מוצפנים ב-n8n.
Structured Output

החוזה בין המודל לצינור

ההחלטה החשובה בתכן: ה-LLM לא מחזיר טקסט חופשי אלא אובייקט בסכמה קבועה. כל הצמתים במורד הזרם (ניתוב, התראות, CRM) עובדים מול שדות טיפוסיים, וה-workflow נשאר דטרמיניסטי גם כשהקלט הוא עברית חופשית. פלט אמיתי מהמערכת:

{ "score": 92, "tier": "hot", "reasons": [ "תקציב מאושר מעל 20,000 ₪", "צורך מוגדר: בוט תיאום תורים מסונכרן יומן", "כאב תפעולי מיידי - המזכירות קורסות" ], "next_action": "לקבוע שיחת היכרות דחופה תוך 24 שעות" } // lead: רשת 4 קליניקות שיניים, scored by claude-sonnet

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

Hybrid Inference

חלוקת העבודה בין ענן למקומי

Claude Sonnet (API) מקבל את המשימה שדורשת יכולת: הבנת פנייה חופשית בעברית, זיהוי ספאם, שקלול תקציב מול דחיפות, ונימוק. קריאה אחת לליד, עלות של סנטים, ~10 שניות.

Ollama (מקומי) מקבל את המשימה הסלחנית: ניסוח טיוטת מענה. רץ על ה-GPU שלי בעלות שולית אפס, והטקסט של הלקוח לא עוזב את השרת בשביל זה.

העיקרון: inference יקר רק בנקודת ההחלטה; כל השאר on-prem. אם מחר הסטודיו יקבל 500 פניות ביום, עלות המערכת גדלה בסנטים - לא במנוי.

✈️
Ilans Leads BotTelegram Bot API · sendMessage
🔥 ליד חם חדש! ציון 92/100 👤 מיכל ברק | קליניקות שיניים ברק 📧 michal@barak-dental.co.il 💰 מעל 20,000 ₪ 📝 רשת של 4 קליניקות, המזכירות קורסות מתיאומי תורים בטלפון. רוצים בוט שמתאם תורים אוטומטית ומסנכרן עם היומן. יש תקציב מאושר 🎯 המלצה: לקבוע שיחת היכרות דחופה תוך 24 שעות

// ההתראה נשלחת רק בענף score ≥ 70

Server-Rendered Dashboard

דשבורד בלי פרונטאנד

ה-endpoint של הדשבורד הוא workflow שני ב-n8n: צומת Webhook (GET) שולף את כל השורות מה-Data Table, צומת Code בונה HTML מלא (RTL, בלי תלות חיצונית מלבד פונט), ו-Respond to Webhook מחזיר text/html. רענון עצמי עם meta-refresh כל 25 שניות. ההרצות של הדשבורד מוחרגות מהיסטוריית הביצועים (saveDataSuccessExecution: none) כדי שהרענון לא יציף את הלוג.

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

// GET /webhook/dashboard → Data Table query → HTML string → response. אפס JavaScript בצד לקוח

Egress Artifacts

מה יוצא מהמערכת

טופס הקליטה במובייל

נקודת הכניסה

n8n Form ב-viewport מובייל. חמישה שדות, שניים חובה, dropdown תקציב שמוזן ישירות לפרומפט הניתוח

מייל האישור האוטומטי

מייל האישור האוטומטי

HTML inline-styled שנשלח ב-SMTP תוך ~30 שניות מההגשה, כולל echo של תוכן הפנייה. נשלח רק בענף score ≥ 20

Ops

תפעול ופריסה

Self-healing boot. כל שירות - n8n, Ollama, Funnel - רשום כ-Windows Scheduled Task על AtStartup עם restart אוטומטי. ריסטארט חשמל מחזיר מערכת שלמה בלי התערבות.
חשיפה ציבורית בלי port-forwarding. Tailscale Funnel מקצה HTTPS ציבורי עם TLS מנוהל. הראוטר נשאר סגור; ה-editor מאחורי אימות, הטופס והדשבורד ציבוריים by design.
Credentials מבודדים. מפתח Anthropic, טוקן הבוט וה-app password של Gmail שמורים כ-credentials מוצפנים ב-n8n - לא בקוד ולא במשתני סביבה של ה-workflow.
נבנה ביום עבודה אחד. מהתקנת Node על שרת נקי ועד מערכת חיה עם כל הערוצים - כולל בדיקות קצה-לקצה מהאינטרנט הפתוח.
orchestration · n8n 2.31.6 self-hosted · Windows scheduled task (S4U, AtStartup)
reasoning · Claude Sonnet via Anthropic API · LLM Chain + Structured Output Parser
local llm · Ollama · aya-expanse:8b · RTX 2070S 8GB · short keep_alive
channels · Telegram Bot API · Gmail SMTP (app password) · n8n Forms
data · n8n Data Tables · server-rendered HTML dashboard (zero client JS)
network · Tailscale Funnel · public TLS · zero open ports
לקחים מהשטח: התקנת n8n גלובלית על Windows דורשת את node על ה-PATH בזמן ה-build scripts, אחרת נופלים על MODULE_NOT_FOUND רק ב-runtime · על 8GB VRAM מודל תמונה/וידאו ו-LLM לא גרים יחד - keep_alive קצר פותר · ה-cold start של Ollama (30-45 שניות) מחייב חימום לפני דמו חי · טופס ה-test של n8n חד-פעמי; לשיתוף משתמשים רק ב-URL של production.

המערכת חיה עכשיו

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