Skip to main content

sniffable-python

Structure Python so LLMs can understand it in 50 lines.

معلومات المصدر

المستودع
SimHacker/moollm
آخر نشاط في المصدر
٩ فبراير ٢٠٢٦ في ٢١:١٧
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٦٠
التفرعات
٥

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
6 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
sniffable-python
description
Structure Python so LLMs can understand it in 50 lines.
license
MIT
tier
0
allowed-tools
["read_file","write_file"]
related
["moollm","sister-script","play-learn-lift","yaml-jazz","plain-text","postel","adventure","debugging"]
tags
["moollm","python","structure","llm-readable","code"]
credits
["MOOLLM — Dual-audience code structure","Python argparse — Built-in CLI with clean structure/implementation separation","Steve Jobs — Lickable pixels as quality signal (Aqua, 2000)"]
# Sniffable Python > **"Structure code for the first 50 lines. That's all the LLM needs."** Don't invent new syntax — **structure existing syntax** for optimal LLM comprehension. *If your code smells good, the LLM can sniff it from the first whiff.* *Steve Jobs wanted pixels you could lick. We want code you can sniff.* --- ## The Problem LLMs can read Python. But: - Large files overwhelm context - Implementation details bury the API - Comments scattered or missing - No clear entry point for understanding **Solution:** Structure Python so the first ~50 lines contain everything needed to understand and use the tool. Make your code's bouquet apparent from the opening notes. --- ## The Pattern ### Canonical Structure ```python #!/usr/bin/env python3 """skill-name: Brief description of what the script does. This docstring becomes --help output AND is immediately visible to the LLM. It should contain: - Purpose (one sentence) - Usage examples - Key behaviors Usage: python script.py command [options] Examples: python script.py move north --quiet python script.py examine sword --verbose """ import argparse from pathlib import Path import yaml # Configuration DEFAULT_ROOM = "start" VALID_DIRECTIONS = ["north", "south", "east", "west"] MAX_INVENTORY = 10 def main(): """Main entry point — CLI structure only, no implementation.""" parser = argparse.ArgumentParser( description=__doc__.split('\n')[0], # First line of module docstring formatter_class=argparse.RawDescriptionHelpFormatter ) subparsers = parser.add_subparsers(dest="command", required=True) # move command move_parser = subparsers.add_parser("move", help="Move in a direction") move_parser.add_argument("direction", choices=VALID_DIRECTIONS, help="Direction to move") move_parser.add_argument("--quiet", "-q", action="store_true", help="Suppress output") # examine command examine_parser = subparsers.add_parser("examine", help="Look at something") examine_parser.add_argument("target", help="What to examine") examine_parser.add_argument("--verbose", "-v", action="store_true", help="Show details") # status command status_parser = subparsers.add_parser("status", help="Show game state") status_parser.add_argument("--verbose", "-v", action="store_true", help="Show details") args = parser.parse_args() _dispatch(args) # Implementation (LLM only reads past here if modifying behavior) def _dispatch(args): """Route to appropriate handler.""" if args.command == "move": _do_move(args.direction, args.quiet) elif args.command == "examine": _do_examine(args.target, args.verbose) elif args.command == "status": _show_status(args.verbose) def _do_move(direction: str, quiet: bool) -> None: """Internal: Execute movement.""" ... def _do_examine(target: str, verbose: bool) -> None: """Internal: Examine an object.""" ... def _show_status(verbose: bool) -> None: """Internal: Display status.""" ... if __name__ == "__main__": main() ``` ### The Zones | Zone | Lines | Purpose | |------|-------|---------| | **Shebang + Docstring** | 1-15 | Purpose, usage, becomes `--help` | | **Imports** | 16-22 | Dependencies visible at a glance | | **Constants** | 23-30 | Configuration, valid values, limits | | **CLI Structure** | 31-50 | Command tree with types and docs | | **Implementation** | 51+ | Only read if modifying | --- ## Why This Works ### Dual-Audience Design ```yaml # One file, two audiences, same source of truth dual_audience: source: "Python file (sniffable)" audiences: human: entry_point: "--help" sees: "CLI usage, arguments, examples" llm: entry_point: "first 50 lines" sees: "docstring, imports, constants, CLI tree" convergence: "Same source of truth — no duplication, no drift" ``` ### DRY Principle The CLI decorators ARE the documentation: ```python @click.option('--verbose', '-v', is_flag=True, help='Show details') ``` This single line defines: - The flag name (`--verbose`) - The short form (`-v`) - The type (boolean flag) - The help text - The Python parameter name and type No duplication. No drift. One source. --- ## Why Syntax Compression Fails Some argue for compressing syntax to save tokens — dense symbols, sigils, minimal keywords. This is the wrong optimization. **Perl is the cautionary tale.** Its obsessive fetish for compact syntax, sigils, punctuation, and performative TMTOWTDI one-liners — to the point of looking like line noise — is exactly why it's no longer relevant for LLM comprehension and generation. | Approach | Tokens | Comprehension | Training Data | |----------|--------|---------------|---------------| | Dense novel syntax | Fewer | Low (unfamiliar) | Minimal | | Sniffable Python | More | High (known syntax) | Billions | **The LLM already knows Python cold.** Teaching it a novel syntax costs millions of tokens per context window (docs, examples, corrections) — and that cost is paid every single prompt, because prompting is not training. LLMs have no memory. Sniffable Python costs zero tokens to teach — the LLM just reads code it understands deeply from massive pre-training. ### The Symbol Collision Problem Short symbols cause semantic collisions. When `@` appears, it activates Python decorators, shell patterns, email addresses, and more — simultaneously. The model has to do disambiguation work that wouldn't exist with unambiguous keywords. That disambiguation costs compute and introduces error modes. ### Comprehension Fidelity > Token Count You're not optimizing for token count. You're optimizing for **how well the LLM understands your code**. Dense punctuation is anti-optimized for how transformers tokenize and reason. Verbose, well-structured code with semantic comments actually compresses better in the LLM's internal representations. --- ## Comments as YAML Jazz Apply YAML-JAZZ principles to Python comments: ```python # CONSTANTS TIMEOUT = 30 # generous — API is flaky on Mondays MAX_RETRIES = 3 # based on observed failure patterns in prod BATCH_SIZE = 100 # memory-safe for 8GB instances # TODO: Add circuit breaker after next major outage # FIXME: Rate limiting not yet implemented # NOTE: This duplicates logic in api_client.py — consider extracting ``` These comments ARE data. The LLM reads them. Acts on them. Uses them to understand *why*, not just *what*. --- ## Comments: Substance Over Decoration **Don't waste tokens on decorative separators:** ```python # BAD: Decorative separators (long = or - lines add no meaning) # GOOD: Plain and functional # Imports import argparse ``` **Don't trim Christmas trees:** Avoid ASCII art or box-drawing in comments. Use plain section comments instead: ```python # Configuration TIMEOUT = 30 # generous — API flaky on Mondays ``` **Do include useful semantic comments:** ```python # ✓ GOOD: Explains WHY TIMEOUT = 30 # generous — API flaky on Mondays MAX_RETRIES = 3 # based on observed failure patterns BATCH_SIZE = 100 # memory-safe for 8GB instances # ✓ GOOD: Documents intent # TODO: Add circuit breaker after next outage # NOTE: Duplicates logic in api_client.py — consider extracting ``` **The rule:** Every comment token should carry meaning. If it's just decoration, delete it. --- ## Argparse vs Click vs Typer **Argparse is preferred** for sniffable Python because it separates structure from implementation: | Feature | Argparse | Click | Typer | |---------|----------|-------|-------| | Structure/impl separation | ✓ Clean | ✗ Mixed | ✗ Mixed | | Top-down tree order | ✓ | ✗ | ✗ | | Built-in (no deps) | ✓ | ✗ | ✗ | | Training data | Abundant | Abundant | Growing | | LLM familiarity | Highest | High | Medium | ### The Argparse Advantage With Click/Typer, decorators attach to functions — so CLI structure is **interleaved** with implementation: ```python # Click: structure mixed with implementation @cli.command() def examine(target: str): # ← implementation starts here """Look at something.""" do_stuff() # ← can't sniff without reading this ``` With argparse, `main()` contains the **entire CLI tree** with no implementation: ```python # Argparse: clean separation def main(): """CLI structure only — no implementation.""" parser = argparse.ArgumentParser(description="Tool description") subparsers = parser.add_subparsers(dest="command") # examine command examine_parser = subparsers.add_parser("examine", help="Look at something") examine_parser.add_argument("target", help="What to examine") examine_parser.add_argument("--verbose", "-v", action="store_true") # move command move_parser = subparsers.add_parser("move", help="Move in a direction") move_parser.add_argument("direction", choices=VALID_DIRECTIONS) args = parser.parse_args() _dispatch(args) # ← implementation is ELSEWHERE # IMPLEMENTATION (completely separate, below the fold) def _dispatch(args): ... ``` **The LLM reads `main()` and sees the entire command tree** — arguments, types, choices, help text — without any implementation noise. Pure sniffability. No need to hold your nose. --- ## Integration with Sister Scripts Sniffable Python is how sister scripts should be structured: ``` skill/ ├── SKILL.md # Tells LLM how to generate scripts ├── CARD.yml # Interface definition └── scripts/ └── helper.py # Sniffable Python ``` When the skill/SKILL.md instructs the LLM to generate a sister script, it should follow sniffable-python conventions: 1. Docstring with usage at top, no decorations 2. Imports grouped and labeled 3. Constants with explanatory comments 4. CLI structure before implementation 5. Implementation below the fold --- ## Directory-Agnostic Invocation **Critical pattern:** All scripts — including sniffable Python — must work when invoked from ANY directory. Scripts find their skill context using `__file__`, not `os.getcwd()`. For bash scripts, see [sister-script/](../sister-script/) for the equivalent pattern. ### The Pattern ```python from pathlib import Path # Find THIS script's location (not the caller's cwd) SCRIPT_DIR = Path(__file__).resolve().parent SKILL_DIR = SCRIPT_DIR.parent # If script is in skill/scripts/ # Now find sibling files relative to script location CONFIG_FILE = SKILL_DIR / "config.yml" PATTERNS_DIR = SKILL_DIR / "patterns" TEMPLATES_DIR = SKILL_DIR / "templates" ``` **Why `__file__`?** - `Path(__file__)` — path to THIS script file - `.resolve()` — resolve symlinks to get real location - `.parent` — containing directory **Why NOT `os.getcwd()`?** - `os.getcwd()` returns the CALLER's directory - Script invoked from `/home/user/` won't find `skills/foo/patterns/` ### The Complete Template ```python #!/usr/bin/env python3 """sister-tool: Brief description. Usage: python3 skills/my-skill/scripts/sister-tool.py command [options] Can be invoked from any directory — finds its own context. """ from pathlib import Path import argparse import yaml # DIRECTORY CONTEXT # Find script location regardless of caller's cwd SCRIPT_DIR = Path(__file__).resolve().parent SKILL_DIR = SCRIPT_DIR.parent # scripts/ is one level down from skill/ # Skill-relative paths CARD_FILE = SKILL_DIR / "CARD.yml" PATTERNS_DIR = SKILL_DIR / "patterns" TEMPLATES_DIR = SKILL_DIR / "templates" CONFIG_DIR = SKILL_DIR / ".moollm" / "skills" / SKILL_DIR.name # CONFIGURATION def load_card(): """Load skill's CARD.yml for metadata.""" if CARD_FILE.exists(): return yaml.safe_load(CARD_FILE.read_text()) return {} def main(): """CLI structure — sniffable, directory-agnostic.""" card = load_card() parser = argparse.ArgumentParser( description=card.get("description", __doc__.split('\n')[0]) ) # ... CLI structure ... args = parser.parse_args() _dispatch(args) # IMPLEMENTATION def _dispatch(args): ... if __name__ == "__main__": main() ``` ### Why This Matters | Invocation | `os.getcwd()` | `Path(__file__).parent` | |------------|---------------|-------------------------|
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub