arielshemesh1999@gmail.com · ישראל
← כל המאמרים

Obsidian LLM Wiki

מימוש מקצה לקצה של תבנית LLM-wiki של Karpathy ב-Obsidian — מבנה התיקיות, מוסכמות העמודים, ה-workflows של ingest/query/lint, וההגדרות של Smart Connections + Dataview שגורמות לכל זה לעבוד.

מה זה

זהו מימוש מוחשי של תבנית LLM-wiki של Karpathy. התבנית עצמה היא רעיון: במקום שה-LLM יאחזר מסמכי מקור גולמיים בכל שאלה מחדש, הוא בונה ומתחזק wiki מתמשך — ארטיפקט שמצטבר, עם קישורי-צולב קיימים וסינתזה שמשקפת את כל המקורות שנקלטו עד כה. המאמר הזה הוא הגרסה המוחשית של אותו רעיון: מבנה התיקיות המדויק, ה-frontmatter שכל עמוד נושא, ה-workflows שסוכן מריץ ב-ingest / query / lint, ההגדרות שמונעות מה-retrieval להיחנק ברעש, וקובץ הסכמה שמחבר את הכל.

ה-vault יושב על Obsidian — אפליקציית ניהול ידע מבית Dynalist Inc. (Shida Li ו-Erica Xu), local-first, שומרת כל הערה כקובץ Markdown טקסטואלי על הדיסק. היא קניינית אך חינמית לשימוש אישי ומסחרי; רק שירותי הענן האופציונליים (Sync, Publish) בתשלום. הבחירה ב-Obsidian אינה מקרית: כיוון שכל עמוד הוא קובץ .md רגיל, גם הסוכן וגם כלי unix רגילים (grep, git) קוראים וכותבים אותו ישירות — אין פורמט נעול שצריך לפענח.

ה-vault נמצא ב-~/Documents/ObsidianVault/. הסוכן (Claude Code) מופעל מתוך התיקייה הזו כדי שיקרא את CLAUDE.md כמדריך ההפעלה שלו. כל השאר — באיזו תיקייה ליצור עמוד, איזה frontmatter לכתוב, מתי לעדכן את האינדקס — מגיע מהסכמה הזו.

ארכיטקטורה — שלוש שכבות, גשר אחד

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

  • raw/ — מסמכי מקור בלתי-ניתנים לשינוי. Web Clipper שומר כאן, קבצי PDF מגיעים לכאן, צילומי מסך נכנסים ל-raw/assets/. הסוכן קורא מתיקייה זו; הוא לעולם לא כותב אליה. כל נושא מחקרי מקבל תת-תיקייה משלו.
  • wiki/ — השכבה שמתוחזקת על ידי ה-LLM, ובבעלותו המלאה. Markdown בלבד. לכל עמוד יש frontmatter. תת-תיקיות לפי נושא, ועוד מיקומים ייעודיים ל-sources/, comparisons/, projects/, קטלוג index.md, ו-log.md שנכתב רק בהוספה.
  • outputs/ — תוצרים נגזרים: מצגות Marp תחת outputs/slides/, גרפי matplotlib תחת outputs/images/, דוחות חד-פעמיים תחת outputs/reports/. כל דבר בעל ערך מתמשך מוגש חזרה ל-wiki.
  • CLAUDE.md — הסכמה. הסוכן קורא אותה בכל סשן. בבעלות משותפת של אדם ו-LLM, ומשתפרת בכל פעם שמתגלה פער ב-workflow. זוהי השכבה השלישית בתבנית של Karpathy: הקונפיגורציה שמגדירה את המבנה, המוסכמות וה-workflows.

הגשר: עמודי wiki/projects/<slug>.md מקשרים דרך כתובות file:// לתיקיות הפרויקטים במערכת הקבצים (למשל תחת ~/Projects/ או כל ספריית עבודה אחרת). ה-vault הופך לנקודת הכניסה היחידה — פותחים, מוצאים את עמוד הפרויקט, לוחצים על הקישור, ומגיעים לתיקייה הנכונה. אין צורך לזכור היכן הדברים נמצאים.

התקנה והגדרה

התקנה נקייה מקצה לקצה:

# 1. Create the vault skeleton
mkdir -p ~/Documents/ObsidianVault/{raw,wiki,outputs}
mkdir -p ~/Documents/ObsidianVault/raw/assets
mkdir -p ~/Documents/ObsidianVault/wiki/projects
mkdir -p ~/Documents/ObsidianVault/outputs/{slides,images,reports}
cd ~/Documents/ObsidianVault
touch CLAUDE.md README.md wiki/index.md wiki/log.md

# 2. Install Obsidian (free)
#    macOS:  brew install --cask obsidian
#    or download: https://obsidian.md/download

# 3. Open the folder as a vault
#    Obsidian -> “Open folder as vault” -> pick ~/Documents/ObsidianVault
#    Trust the author when prompted (needed for community plugins).

# 4. Point attachments at raw/assets
#    Settings -> Files and links -> Default location for new attachments
#    -> In the folder specified below: raw/assets

# 5. Install the two community plugins
#    Settings -> Community plugins -> Turn on -> Browse:
#      Smart Connections   (by @brianpetro: semantic search + Smart Chat)
#      Dataview            (by blacksmithgu: DQL queries over frontmatter)

# 6. Install the Obsidian Web Clipper browser extension
#    https://obsidian.md/clipper
#    Configure: Save to vault -> ObsidianVault -> Path: raw/{{topic}}/

# 7. Bind the “Download attachments for current file” command to Cmd+Shift+D
#    (Settings -> Hotkeys -> search “Download”)

# 8. Point Claude Code at the vault
cd ~/Documents/ObsidianVault && claude

Smart Connections עושה שני דברים: connections — חיפוש סמנטי שמציף עמודים קרובים תוך כדי כתיבה, ו-Smart Chat — צ'אט מעל ה-wiki. ה-Core עובד local-first: הוא נשען על מודל embedding מקומי שמובנה בתוסף, ולאחר ה-embedding הראשוני האחזור עובד גם לא מקוון — ללא מפתח API. אינטגרציות עם מודלים מבוססי-ענן (ChatGPT, Claude, Gemini) עברו ל-Smart Chat Pro; ה-Core חינמי ו-source available תחת ה-Smart Plugins License.

זה גם המקום שבו רוב ההתקנות מתקלקלות — ברירות המחדל מתירניות מדי וה-wiki מאחזר רעש. מניסיון יומיומי, שתי השגיאות הנפוצות הן: לא להחריג את raw/ מה-embedding (אז מסמכי המקור המלאים מציפים כל אחזור ומטביעים את עמודי ה-wiki המסונתזים), והשארת סף דמיון נמוך מדי (אז כל שאילתה גוררת עשרות התאמות חלשות). תצורה שעובדת טוב בפועל:

# Smart Connections - a tuned config that works in practice
Embed blocks:              ON       # index sub-sections, not just whole notes
Minimum source length:     300 chars
Minimum block length:      100 chars
Similarity threshold:      0.80     # only surface matches that score ≥ 0.80
Excluded folders:
  raw                               # full sources would dominate retrieval
  outputs                           # derivatives, not the source of truth
  .obsidian
  .smart-env
Re-embed:                  after every ingest pass

בחירת מודל ה-embedding היא פשרה בין דיוק לבין RAM וזמן indexing: מודל קל יספיק ל-vault קטן, ומודל עם חלון הקשר ארוך יותר משתלם כשהעמודים ארוכים או כש-ה-vault גדל מעבר לכמה אלפי עמודים. אפשר לחבר את הצ'אט למודל ענן דרך Smart Chat Pro, אבל זה אופציונלי לחלוטין — האחזור הסמנטי שעליו נשען כל ה-workflow רץ מקומית בלי שום מפתח.

מוסכמות עמודים — כל chunk חייב להיות שמיש בנפרד

ההבדל הגדול ביותר בין wiki שעובד לבין כזה שלא: האם כל עמוד שורד אחזור לבדו. שמונה כללים שכל עמוד מקיים:

  1. מושג אחד לעמוד. שני רעיונות? מפצלים.
  2. כותרות H2/H3 עצמאיות. ## Why we picked Postgres over DynamoDB, לא ## Decision.
  3. המשפט הראשון מחזיר הקשר. יוצאים מנקודת הנחה שה-chunk אוחזר לבדו.
  4. ללא מבול של כינויי גוף. מציינים את השם בכל פעם.
  5. תאריך לטענות שמתיישנות. As of 2026-04-13, …
  6. גודל עמוד יעד: 200–1500 tokens (~150–1000 מילים).
  7. ללא mega-notes מתגלגלות. קובץ אחד למושג. עמוד של 50,000 tokens עם "הכל על X" הורס את ה-retrieval.
  8. חוזרים על מילת הנושא בכותרות מקוננות. ## Auth — token rotation, לא ## Token rotation.

כל עמוד נושא את אותו בלוק frontmatter. Smart Connections מסיר את ה-frontmatter לפני ה-embedding, וזו הסיבה שגם שדה ה-summary נכתב מילה במילה כמשפט הראשון של הגוף:

---
title: <human-readable page title>
type: source | entity | concept | summary | comparison | analysis | insight | moc | project
aliases: [alt-name-1, alt-name-2]
topic: <research-topic-slug>
sources: ["[[source-slug-1]]", "[[source-slug-2]]"]
created: 2026-05-13
updated: 2026-05-13
summary: <one sentence — also appears verbatim as the first sentence of the body>
---

Workflows — ingest, query, lint

הסוכן מריץ שלושה workflows. כולם כתובים ב-CLAUDE.md כדי שהסוכן יגיע אליהם אוטומטית.

Ingest — האדם מוסיף מקור חדש ל-raw/:

1. Read raw/<topic>/<source>.md (or PDF, or image).
2. Briefly summarize key takeaways and confirm direction with the human.
3. Create or update the wiki:
   - Summary page  -> wiki/<topic>/sources/<source-slug>.md
   - Entity pages  -> for new people / orgs / products
   - Concept pages -> for new ideas / methods / frameworks
   - Update existing pages the new source contradicts, extends, or refines.
   - Add cross-references both ways.
4. Update wiki/index.md.
5. Append a [YYYY-MM-DD] ingest entry to wiki/log.md.
6. A typical ingest touches 5–15 pages.

Query — האדם שואל שאלה:

1. Read wiki/index.md, find candidate pages.
2. Read those pages, follow wikilinks for context.
3. Synthesize an answer with citations to wiki pages.
4. Choose the right output format:
   - Markdown page for substantive answers
   - Comparison table when contrasting two or more things
   - Marp slide deck at outputs/slides/<topic>--<query>.md
   - Chart at outputs/images/<topic>--<query>.png (matplotlib)
   - Plain chat reply for trivial questions
5. If the answer is non-trivial, file it back as a wiki page.
6. Append a [YYYY-MM-DD] query entry to wiki/log.md.

Lint — בדיקת תקינות תקופתית, מופעל לפי בקשה או לאחר כל ~10 ingests:

- Contradictions between pages              -> flag for human review
- Stale claims newer sources superseded     -> mark superseded
- Orphan pages with no inbound links        -> propose deletion or linking
- Concept gaps (term used in ≥ 3 pages,
  no dedicated page)                        -> propose creating one
- Missing cross-references                  -> add them
- Data gaps the human could fill            -> suggest specific web searches
- Index drift                               -> rebuild wiki/index.md

דוגמאות שימוש

דוגמה 1 — clipping ו-ingest של מאמר. קראתם כתבה ברשת, לחצתם על כפתור Web Clipper (שומר ל-raw/llm-agents/), ואמרתם לסוכן:

You: ingest the new clipping in raw/llm-agents/

Agent:
  read raw/llm-agents/voyager-skill-libraries.md  (3,200 words)
  created wiki/llm-agents/sources/voyager-skill-libraries.md
  created wiki/concepts/skill-library.md          (new concept)
  updated wiki/entities/jim-fan.md
  updated wiki/comparisons/agent-memory-designs.md
  updated wiki/index.md
  appended wiki/log.md  ([2026-05-28] ingest | voyager-skill-libraries)
  touched: 5 pages

דוגמה 2 — אינדקס חי עם Dataview. Dataview (מאת blacksmithgu) הוא מנוע אינדקס ושאילתות חי מעל ה-vault. הוא מספק שפת שאילתות, DQL, עם ארבעה סוגי שאילתה — TABLE, LIST, TASK, CALENDAR — שכל אחת בנויה מסוג, מ-FROM (תיקייה / תג / מקור), ומפקודות נתונים כמו WHERE ו-SORT. הוא קורא גם YAML frontmatter וגם שדות inline בתחביר key:: value. הקטע הבא ב-wiki/index.md בונה טבלה שמתעדכנת לבדה עם כל עמודי המושגים, לפי תאריך עדכון:

```dataview
TABLE topic, summary, updated
FROM "wiki"
WHERE type = "concept"
SORT updated DESC
```

בזכות זה אין צורך לתחזק רשימת מושגים ידנית: כל עמוד שמקבל type: concept ב-frontmatter שלו צץ בטבלה אוטומטית בפעם הבאה שהאינדקס נטען.

דוגמה 3 — פורמט ה-log. wiki/log.md נכתב רק בהוספה עם קידומת אחידה שכלים של unix יכולים לנתח. עשרת הרשומות האחרונות נגישות ב-grep אחד:

grep "^## \[" wiki/log.md | tail -10

## [2026-05-28] ingest | Karpathy “LLM Wiki” gist
## [2026-05-28] query  | RAG vs maintained wiki
## [2026-05-28] lint
## [2026-05-27] ingest | agent-frameworks survey
## [2026-05-27] new-project | example-project
## [2026-05-26] ingest | embeddings-tuning notes
## ...

המחסנית והתוספים

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

  • Obsidian — הקליינט עצמו. local-first, Markdown טקסטואלי, פורמט פתוח. Web Clipper הוא תוסף first-party של Obsidian שממיר כתבות רשת ל-Markdown ושומר אותן ישר ל-raw/.
  • Smart Connections (@brianpetro) — שכבת האחזור הסמנטי. ה-Core חינמי, source available, ורץ מקומית עם מודל embedding מובנה. כדאי לבחור את מודל ה-embedding לפי גודל ה-vault: מודל קל מספיק לכמה מאות עד אלפי עמודים, ומודל כבד יותר משתלם כש-ה-vault גדל או כשהעמודים ארוכים.
  • Dataview (blacksmithgu) — מנוע השאילתות מעל ה-frontmatter, שבונה אינדקסים חיים בלי תחזוקה ידנית.

תוספות אופציונליות שכדאי לשקול: Marp Slides לתצוגה מקדימה של מצגות בתוך Obsidian (התואם לתיקיית outputs/slides/), Templater (אפשר להתקין אך להשבית file_templates — ה-LLM כותב עמודים ישירות במקום מתבנית), ו-Periodic Notes (אופציונלי ולא הכרחי — daily notes אינם חלק מהתבנית הזו). Karpathy עצמו ממליץ בתבנית גם על Git לניהול גרסאות והיסטוריה של ה-vault, ועל Graph view המובנה של Obsidian להמחשת הקשרים בין העמודים.

מגבלות וטעויות נפוצות

התבנית עובדת, אבל יש לה מחיר ויש לה מלכודות. מה שלמדתי בדרך הקשה:

  • ה-ingest הוא העלות. הסינתזה אינה חינמית — כל מקור עובר קריאה, סיכום, ושיבוץ ב-5–15 עמודים. ה-LLM-wiki מעביר את העלות מ-query-time ל-ingest-time: משלמים פעם אחת בכתיבה, ונהנים מ-queries זולים אחר כך. אם לא קולטים מקורות בקצב סביר, ה-wiki נשאר ריק וחסר ערך.
  • chunking גרוע הורס את האחזור. mega-note אחד עם "הכל על X" נשמע נוח, אבל הוא מטביע את ה-embedding בתוך כל-כך הרבה הקשר שאף שאילתה לא תופסת אותו במדויק. קובץ אחד למושג, וכותרות עצמאיות — זה לא קישוט, זו הדרישה שמכריעה בין wiki שעובד לכזה שלא.
  • הסכמה מתיישנת. CLAUDE.md חייב להשתפר בכל פעם שמתגלה פער ב-workflow, אחרת הסוכן ממשיך לפעול לפי הנחות ישנות. בלי משמעת תחזוקה הוא נושר.
  • סתירות מצטברות בשקט. כשמקור חדש סותר עמוד קיים, צריך מישהו שיבחין — לכן workflow ה-lint רץ אחת לכל ~10 ingests ומסמן סתירות, עמודים יתומים, וטענות שהתיישנו. בלעדיו ה-wiki נסחף.
  • הסוכן יכול להמציא. כל טענה מסונתזת צריכה לקשר חזרה לעמוד sources/ שממנו היא נובעת. בלי קישורי-מקור אין דרך לאמת מאוחר יותר אם משהו נכון או שהומצא בסשן.

למה זה חשוב בפועל

בשימוש יומיומי, המנוף הגדול של התבנית הוא שה-vault הופך לנקודת כניסה אחת גם לידע וגם לעבודה. הידע נמצא ב-wiki/, ועמוד פרויקט תחת wiki/projects/ יכול לשאת שדה frontmatter מסוג workspace: שמצביע בכתובת file:// אל תיקיית הקוד המתאימה. במקום לזכור היכן הכול יושב, פותחים את ה-vault, מוצאים את עמוד הנושא או הפרויקט, ולוחצים על הקישור — זה כל ה-workflow. הסוכן יכול לענות על "מה הסטטוס של הפרויקט?" ו"פתח את תיקיית הפרויקט" תוך שימוש ב-vault בלבד.

האפקט המצטבר הוא אמיתי, וזה מה שמרגישים אחרי כמה שבועות של ingest שיטתי: ה-wiki מתחיל לענות גם על שאלות שלא הופנו אליו ישירות, כי החיפוש הסמנטי מציף עמוד ישן שה-embedding שלו קרוב לשאלה החדשה. זו הפשרה המרכזית של הגישה — עלות הסינתזה משולמת פעם אחת, בזמן ה-ingest, ובתמורה כל query קשור אחר כך הוא זול. המסקנה המעשית: כדאי לקלוט מקורות בקצב סביר ולהשקיע ב-chunking נקי, אחרת היתרון הזה לא מתממש.

מקורות

תבנית: Andrej Karpathy, LLM Wiki (gist). gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
מימוש: סכמת ה-vault ב-CLAUDE.md שבשורש ה-vault.
Obsidian (Dynalist Inc., local-first, Markdown, חינמי לשימוש אישי): obsidian.md.
Smart Connections (@brianpetro, Core חינמי ו-source available, local-first): smartconnections.app · GitHub.
Dataview (blacksmithgu, מנוע אינדקס ושאילתות DQL): blacksmithgu.github.io/obsidian-dataview.