sniffable-python
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSniffable Python
Sniffable Python(可快速理解的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.
"将代码的核心结构放在前50行。这就是大语言模型(LLM)所需的全部内容。"
无需发明新语法——对现有语法进行结构化处理,以实现LLM的最优理解效果。
如果你的代码“气味宜人”,LLM只需扫一眼开头就能快速理解。
史蒂夫·乔布斯希望界面像素能让人想“舔”一下。我们则希望代码能让人快速“嗅懂”。
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.
LLM能读取Python代码,但存在以下问题:
- 大文件会超出上下文限制
- 实现细节掩盖了API核心
- 注释零散或缺失
- 没有清晰的理解切入点
解决方案: 对Python代码进行结构化处理,让前约50行包含理解和使用该工具所需的全部信息。让代码的核心特性从开头就能一目了然。
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 yamlpython
#!/usr/bin/env python3
"""skill-name: 脚本功能的简短描述。
此文档字符串会成为--help输出,同时能立即被LLM识别。
它应包含:
- 用途(一句话概括)
- 使用示例
- 核心特性
用法:
python script.py command [options]
示例:
python script.py move north --quiet
python script.py examine sword --verbose
"""
import argparse
from pathlib import Path
import yamlConfiguration
配置
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)DEFAULT_ROOM = "start"
VALID_DIRECTIONS = ["north", "south", "east", "west"]
MAX_INVENTORY = 10
def main():
"""主入口点——仅包含CLI结构,无实现细节。"""
parser = argparse.ArgumentParser(
description=doc.split('\n')[0], # 模块文档字符串的第一行
formatter_class=argparse.RawDescriptionHelpFormatter
)
subparsers = parser.add_subparsers(dest="command", required=True)
# move 命令
move_parser = subparsers.add_parser("move", help="向指定方向移动")
move_parser.add_argument("direction", choices=VALID_DIRECTIONS,
help="移动方向")
move_parser.add_argument("--quiet", "-q", action="store_true",
help="抑制输出")
# examine 命令
examine_parser = subparsers.add_parser("examine", help="查看指定对象")
examine_parser.add_argument("target", help="要查看的对象")
examine_parser.add_argument("--verbose", "-v", action="store_true",
help="显示详细信息")
# status 命令
status_parser = subparsers.add_parser("status", help="显示游戏状态")
status_parser.add_argument("--verbose", "-v", action="store_true",
help="显示详细信息")
args = parser.parse_args()
_dispatch(args)Implementation (LLM only reads past here if modifying behavior)
实现细节(仅当需要修改功能时,LLM才会阅读此部分)
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()
undefineddef _dispatch(args):
"""将请求路由到对应的处理函数。"""
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:
"""内部函数:执行移动操作。"""
...
def _do_examine(target: str, verbose: bool) -> None:
"""内部函数:查看对象。"""
...
def _show_status(verbose: bool) -> None:
"""内部函数:显示状态。"""
...
if name == "main":
main()
undefinedThe Zones
结构分区
| Zone | Lines | Purpose |
|---|---|---|
| Shebang + Docstring | 1-15 | Purpose, usage, becomes |
| 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 |
| 分区 | 行数范围 | 用途 |
|---|---|---|
| Shebang + 文档字符串 | 1-15 | 说明用途、用法,同时作为 |
| 导入语句 | 16-22 | 一目了然展示依赖项 |
| 常量定义 | 23-30 | 配置信息、有效值、限制条件 |
| CLI结构 | 31-50 | 包含类型和文档的命令树 |
| 实现细节 | 51+ | 仅在需要修改时阅读 |
Why This Works
为什么这种模式有效
Dual-Audience Design
双受众设计
yaml
undefinedyaml
undefinedOne 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"
undefineddual_audience:
source: "Python文件(可快速理解)"
audiences:
human:
entry_point: "--help"
sees: "CLI用法、参数、示例"
llm:
entry_point: "前50行"
sees: "文档字符串、导入语句、常量、CLI树"
convergence: "同一事实来源——无重复、无偏差"
undefinedDRY Principle
DRY原则(不重复自己)
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.
CLI装饰器本身就是文档:
python
@click.option('--verbose', '-v', is_flag=True, help='Show details')这一行代码定义了:
- 标志名称()
--verbose - 短形式()
-v - 类型(布尔标志)
- 帮助文本
- Python参数名称和类型
无重复、无偏差,单一事实来源。
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.
有人主张压缩语法以节省token——使用密集符号、标记、极简关键字。但这是错误的优化方向。
Perl就是前车之鉴。 它对紧凑语法、标记、标点的过度追求,以及“不止一种方法做某事(TMTOWTDI)”的炫技式单行代码——甚至看起来像乱码——正是它如今在LLM理解和生成场景中不再适用的原因。
| 方法 | Token数量 | 理解难度 | 训练数据量 |
|---|---|---|---|
| 密集的新型语法 | 更少 | 高(不熟悉) | 极少 |
| 可快速理解的Python | 更多 | 低(熟悉语法) | 数十亿条 |
LLM已经精通Python。 教它一种新型语法,每个上下文窗口(文档、示例、修正)都要花费数百万token——而且每次提示都要付出这个成本,因为提示不等于训练。LLM没有记忆。可快速理解的Python无需额外token教学——LLM只需读取它从大规模预训练中就已深度理解的代码。
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.
@短符号会导致语义冲突。当出现时,它会同时触发Python装饰器、shell模式、电子邮件地址等多种语义。模型必须进行消歧工作,而使用明确的关键字就不会有这个问题。消歧会消耗计算资源,还会引入错误。
@Comprehension Fidelity > Token Count
理解准确性 > Token数量
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.
你要优化的不是Token数量,而是LLM理解代码的准确性。
密集的标点符号与Transformer的分词和推理逻辑背道而驰。带有语义注释的、结构清晰的冗长代码,在LLM的内部表示中反而压缩得更好。
Comments as YAML Jazz
注释的YAML Jazz原则
Apply YAML-JAZZ principles to Python comments:
python
undefined将YAML-JAZZ原则应用于Python注释:
python
undefinedCONSTANTS
常量定义
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
TIMEOUT = 30 # 设得较宽松——周一API不稳定
MAX_RETRIES = 3 # 根据生产环境中观察到的失败模式设定
BATCH_SIZE = 100 # 8GB内存实例的安全值
TODO: Add circuit breaker after next major outage
TODO: 下次重大故障后添加断路器
FIXME: Rate limiting not yet implemented
FIXME: 尚未实现速率限制
NOTE: This duplicates logic in api_client.py — consider extracting
NOTE: 此逻辑与api_client.py重复——考虑提取为公共代码
These comments ARE data. The LLM reads them. Acts on them. Uses them to understand *why*, not just *what*.
---
这些注释本身就是数据。LLM会读取它们、依据它们行动、用它们理解代码的“为什么”,而不只是“是什么”。
---Comments: Substance Over Decoration
注释:实质重于形式
Don't waste tokens on decorative separators:
python
undefined不要在装饰性分隔符上浪费token:
python
undefinedBAD: 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:
```pythonimport argparse
**不要使用冗余的ASCII艺术:**
避免在注释中使用ASCII艺术或框线,改用简洁的分段注释:
```pythonConfiguration
配置
TIMEOUT = 30 # generous — API flaky on Mondays
**Do include useful semantic comments:**
```pythonTIMEOUT = 30 # 设得较宽松——周一API不稳定
**应添加有用的语义注释:**
```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
TIMEOUT = 30 # 设得较宽松——周一API不稳定
MAX_RETRIES = 3 # 根据生产环境中观察到的失败模式设定
BATCH_SIZE = 100 # 8GB内存实例的安全值
✓ GOOD: Documents intent
✓ 正确示例:记录意图
TODO: Add circuit breaker after next outage
TODO: 下次故障后添加断路器
NOTE: Duplicates logic in api_client.py — consider extracting
NOTE: 此逻辑与api_client.py重复——考虑提取为公共代码
**The rule:** Every comment token should carry meaning. If it's just decoration, delete it.
---
**规则:** 每个注释token都应承载意义。如果只是装饰,就删掉它。
---Argparse vs Click vs Typer
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 |
优先选择Argparse来编写可快速理解的Python,因为它将结构与实现分离:
| 特性 | Argparse | Click | Typer |
|---|---|---|---|
| 结构与实现分离 | ✓ 清晰分离 | ✗ 混合在一起 | ✗ 混合在一起 |
| 自上而下的命令树顺序 | ✓ 支持 | ✗ 不支持 | ✗ 不支持 |
| 内置模块(无依赖) | ✓ 是 | ✗ 否 | ✗ 否 |
| 训练数据量 | 丰富 | 丰富 | 增长中 |
| LLM熟悉度 | 最高 | 高 | 中等 |
The Argparse Advantage
Argparse的优势
With Click/Typer, decorators attach to functions — so CLI structure is interleaved with implementation:
python
undefined使用Click/Typer时,装饰器附加在函数上——因此CLI结构与实现交织在一起:
python
undefinedClick: structure mixed with implementation
Click:结构与实现混合
@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@cli.command()
def examine(target: str): # ← 实现从这里开始
"""查看指定对象。"""
do_stuff() # ← 不阅读此部分无法理解完整功能
使用argparse时,`main()`函数包含**完整的CLI树**,无任何实现细节:
```pythonArgparse: clean separation
Argparse:清晰分离
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 ELSEWHEREdef main():
"""仅包含CLI结构——可快速理解,无实现细节。"""
parser = argparse.ArgumentParser(description="工具描述")
subparsers = parser.add_subparsers(dest="command")
# examine 命令
examine_parser = subparsers.add_parser("examine", help="查看指定对象")
examine_parser.add_argument("target", help="要查看的对象")
examine_parser.add_argument("--verbose", "-v", action="store_true")
# move 命令
move_parser = subparsers.add_parser("move", help="向指定方向移动")
move_parser.add_argument("direction", choices=VALID_DIRECTIONS)
args = parser.parse_args()
_dispatch(args) # ← 实现部分在其他位置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.
---def _dispatch(args):
...
**LLM读取`main()`函数就能看到完整的命令树**——参数、类型、可选值、帮助文本——没有任何实现细节干扰。纯粹的可快速理解性,无需费力梳理。
---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 PythonWhen the skill/SKILL.md instructs the LLM to generate a sister script, it should follow sniffable-python conventions:
- Docstring with usage at top, no decorations
- Imports grouped and labeled
- Constants with explanatory comments
- CLI structure before implementation
- Implementation below the fold
可快速理解的Python是姊妹脚本的标准结构:
skill/
├── SKILL.md # 告诉LLM如何生成脚本
├── CARD.yml # 接口定义
└── scripts/
└── helper.py # 可快速理解的Python脚本当skill/SKILL.md指示LLM生成姊妹脚本时,应遵循可快速理解的Python规范:
- 顶部是包含用法的文档字符串,无装饰
- 导入语句分组并标记
- 常量带有解释性注释
- CLI结构在实现细节之前
- 实现细节放在核心结构之后
Directory-Agnostic Invocation
与目录无关的调用方式
Critical pattern: All scripts — including sniffable Python — must work when invoked from ANY directory. Scripts find their skill context using , not .
__file__os.getcwd()For bash scripts, see sister-script/ for the equivalent pattern.
关键模式: 所有脚本——包括可快速理解的Python脚本——必须能从任意目录调用。脚本应使用而非来定位skill上下文。
__file__os.getcwd()对于bash脚本,请参考sister-script/中的等效模式。
The Pattern
实现模式
python
from pathlib import Pathpython
from pathlib import PathFind 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/
SCRIPT_DIR = Path(file).resolve().parent
SKILL_DIR = SCRIPT_DIR.parent # 如果脚本位于skill/scripts/目录下
Now find sibling files relative to script location
相对于skill目录的路径
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/`CONFIG_FILE = SKILL_DIR / "config.yml"
PATTERNS_DIR = SKILL_DIR / "patterns"
TEMPLATES_DIR = SKILL_DIR / "templates"
**为什么使用`__file__`?**
- `Path(__file__)` — 当前脚本文件的路径
- `.resolve()` — 解析符号链接以获取真实位置
- `.parent` — 包含当前脚本的目录
**为什么不使用`os.getcwd()`?**
- `os.getcwd()`返回调用者的工作目录
- 如果从其他目录调用脚本,无法正确找到skill上下文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 yamlpython
#!/usr/bin/env python3
"""sister-tool: 简短描述。
用法:
python3 skills/my-skill/scripts/sister-tool.py command [options]
可从任意目录调用——自动定位自身上下文。
"""
from pathlib import Path
import argparse
import yamlDIRECTORY 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/
SCRIPT_DIR = Path(file).resolve().parent
SKILL_DIR = SCRIPT_DIR.parent # scripts/目录位于skill目录下一级
Skill-relative paths
相对于skill目录的路径
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
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)
def load_card():
"""加载skill的CARD.yml元数据。"""
if CARD_FILE.exists():
return yaml.safe_load(CARD_FILE.read_text())
return {}
def main():
"""CLI结构——可快速理解,与目录无关。"""
card = load_card()
parser = argparse.ArgumentParser(
description=card.get("description", doc.split('\n')[0])
)
# ... CLI结构 ...
args = parser.parse_args()
_dispatch(args)
IMPLEMENTATION
实现细节
def _dispatch(args):
...
if name == "main":
main()
undefineddef _dispatch(args):
...
if name == "main":
main()
undefinedWhy This Matters
为什么这很重要
| Invocation | | |
|---|---|---|
| | |
| | |
| | |
Path(__file__).parent| 调用方式 | | |
|---|---|---|
| | |
| | |
| | |
Path(__file__).parentThe Play-Learn-Lift Connection
Play-Learn-Lift的关联
Sniffable Python is the crystallization point of LIFT — where proven procedures become reusable automation.
yaml
undefined可快速理解的Python是LIFT的核心——将经过验证的流程转化为可复用的自动化工具。
yaml
undefinedPLAY → LEARN → LIFT progression
PLAY → LEARN → LIFT 流程
play_learn_lift:
play:
emoji: "🎮"
action: "Jump in! Try things"
artifact: "session-log.md"
quality: "Messy exploration, may fail"
learn:
emoji: "📚"
action: "Patterns emerge, document procedures"
artifact: "PROCEDURE.md"
quality: "Structured notes, works when followed"
lift:
emoji: "🚀"
action: "Automate it! Share the tool"
artifact: "sister-script.py (SNIFFABLE PYTHON)"
quality: "Clean interface, others can use"
**The LIFT stage produces sniffable Python because:**
- Others (human and LLM) need to understand the tool quickly
- The CLI must be discoverable without reading implementation
- The script must be maintainable without spelunking
**See:** [play-learn-lift/](../play-learn-lift/) — The full methodology
---play_learn_lift:
play:
emoji: "🎮"
action: "上手尝试!大胆试错"
artifact: "session-log.md"
quality: "探索过程较杂乱,可能失败"
learn:
emoji: "📚"
action: "模式浮现,记录流程"
artifact: "PROCEDURE.md"
quality: "结构化笔记,按步骤执行即可生效"
lift:
emoji: "🚀"
action: "自动化!分享工具"
artifact: "sister-script.py(可快速理解的Python)"
quality: "清晰的接口,他人可直接使用"
**LIFT阶段生成可快速理解的Python,原因如下:**
- 他人(人类和LLM)需要快速理解工具
- CLI必须无需阅读实现细节就能被发现
- 脚本必须无需深入梳理就能维护
**参考:** [play-learn-lift/](../play-learn-lift/) — 完整方法论
---The Skill-to-Script Flow
Skill到脚本的流程
The skill/ skill describes how skills act as factories that produce instances. When a skill generates a CLI tool, that tool should be sniffable Python.
yaml
undefinedskill/技能描述了技能如何作为工厂生成实例。当技能生成CLI工具时,该工具应采用可快速理解的Python结构。
yaml
undefinedSkill → Script → LLM → Output pipeline
Skill → Script → LLM → 输出 流程
skill_to_script_flow:
- stage: "SKILL.md" role: "The teacher — knows how to build things" action: "instructs LLM to generate"
- stage: "Sister Script"
role: "SNIFFABLE PYTHON"
properties:
- "Docstring = API"
- "main() = CLI tree"
- "Comments = Jazz" action: "LLM sniffs to understand"
- stage: "LLM Comprehension" role: "Reads first 50 lines, understands CLI, can invoke tool" action: "executes"
- stage: "Structured Output" role: "YAML / JSON — LLM can parse, feeds back"
**Example from adventure skill:**
The adventure skill's vision includes a Python CLI that handles deterministic operations:
```python
$ adventure lint examples/adventure-4/ # Validate world
$ adventure move alice north # Update coordinates
$ adventure scan --pending # Find work to doEach of these is a sniffable subcommand. The LLM sniffs (or just reads ) and knows the full API.
adventure --helpmain()skill_to_script_flow:
- stage: "SKILL.md" role: "导师——知道如何构建工具" action: "指导LLM生成脚本"
- stage: "姊妹脚本"
role: "可快速理解的Python"
properties:
- "文档字符串 = API"
- "main() = CLI树"
- "注释 = YAML Jazz" action: "LLM快速理解脚本"
- stage: "LLM理解" role: "阅读前50行,理解CLI,可调用工具" action: "执行脚本"
- stage: "结构化输出" role: "YAML / JSON — LLM可解析,可反馈"
**冒险技能示例:**
冒险技能的愿景包括一个处理确定性操作的Python CLI:
```python
$ adventure lint examples/adventure-4/ # 验证世界一致性
$ adventure move alice north # 更新坐标
$ adventure scan --pending # 查找待处理任务每个子命令都是可快速理解的。LLM只需查看(或直接阅读函数)就能了解完整API。
adventure --helpmain()The Adventure Linter Feedback Loop
冒险代码检查器的反馈循环
The adventure/ skill demonstrates sniffable Python in a feedback loop:
yaml
undefinedadventure/技能展示了可快速理解的Python在反馈循环中的应用:
yaml
undefinedAdventure linter feedback loop
冒险代码检查器反馈循环
linter_feedback_loop:
- step: "LLM generates content" does: "Create rooms, objects, characters in YAML Jazz format"
- step: "Sniffable linter runs" does: "adventure-lint.py validates world consistency"
- step: "LINTER.yml output" does: "Structured findings: errors, warnings, suggestions"
- step: "LLM reads lint results" does: "Understands what needs fixing, generates corrections"
- step: "iterate" does: "Loop back to generation with fixes"
**From [examples/adventure-4/LINTER.yml](../../examples/adventure-4/LINTER.yml):**
```yaml
summary:
rooms_found: 36
objects_found: 37
characters_found: 6
errors: 8
warnings: 36
compile_requests: 9
events:
- type: FOUND_ROOM
severity: INFO
path: pub/ROOM.yml
message: 'Found room: The Gezelligheid Grotto'
data:
exits: [NORTH, UP, BACK]
objects: 15
sub_rooms: 1Why this works:
- The linter is sniffable — LLM understands its CLI
- The output is YAML — LLM parses it naturally
- Events are structured — LLM knows what to fix
- The loop is tight — generate → lint → fix → repeat
This is Python for precision, LLM for poetry.
linter_feedback_loop:
- step: "LLM生成内容" does: "用YAML Jazz格式创建房间、物品、角色"
- step: "可快速理解的检查器运行" does: "adventure-lint.py验证世界一致性"
- step: "LINTER.yml输出" does: "结构化结果:错误、警告、建议"
- step: "LLM读取检查结果" does: "理解需要修复的内容,生成修正版本"
- step: "迭代" does: "带着修复方案回到生成步骤"
**来自[examples/adventure-4/LINTER.yml](../../examples/adventure-4/LINTER.yml):**
```yaml
summary:
rooms_found: 36
objects_found: 37
characters_found: 6
errors: 8
warnings: 36
compile_requests: 9
events:
- type: FOUND_ROOM
severity: INFO
path: pub/ROOM.yml
message: '发现房间:The Gezelligheid Grotto'
data:
exits: [NORTH, UP, BACK]
objects: 15
sub_rooms: 1为什么这有效:
- 检查器是可快速理解的——LLM能理解其CLI
- 输出是YAML格式——LLM可自然解析
- 事件是结构化的——LLM知道需要修复什么
- 循环紧凑——生成→检查→修复→重复
Live Examples in adventure-4
adventure-4中的实际示例
TomTomagotchi — YAML Jazz in Action
TomTomagotchi — YAML Jazz的应用
kitchen/tomtomagotchi.yml demonstrates sniffable structure in YAML:
yaml
abilities:
COMPASS:
description: "Point toward a target"
usage: "COMPASS [target]"
targets:
- start # Always knows home
- home # The surface
- treasure # The goalThe comment "Always knows home" is data. The LLM reads it and understands the semantics. This is YAML Jazz applied to game objects.
kitchen/tomtomagotchi.yml展示了YAML格式的可快速理解结构:
yaml
abilities:
COMPASS:
description: "指向目标"
usage: "COMPASS [target]"
targets:
- start # 始终知道家的位置
- home # 地面
- treasure # 目标宝藏注释“始终知道家的位置”本身就是数据。 LLM会读取它并理解语义。这是YAML Jazz在游戏对象上的应用。
The Pub — Framing Through Comments
酒馆——用注释定义框架
pub/ROOM.yml uses comments to frame the room's purpose:
yaml
framing:
mode: [performance, celebration, socialization, tribute, third_place]
description: |
This is a PLACE OF PERFORMANCE AND CELEBRATION.
This is a THIRD PLACE — neither home nor work, but community.
This is where TRIBUTES are performed with love.Comments explain WHY the pub exists. The LLM uses this framing to generate appropriate content — debates are sport, personas are welcome, tributes are loving.
pub/ROOM.yml使用注释定义房间的用途:
yaml
framing:
mode: [performance, celebration, socialization, tribute, third_place]
description: |
这是一个**表演与庆祝的场所**。
这是一个**第三空间**——既不是家也不是工作场所,而是社区空间。
这是一个充满爱意地进行**致敬表演**的地方。注释解释了酒馆存在的意义。 LLM会利用这个框架生成合适的内容——辩论是娱乐,角色扮演是受欢迎的,致敬是充满爱意的。
Skills as Rooms
技能即房间
From skill/SKILL.md, skills manifest as rooms you can enter:
> enter the adventure skill
You are in the Adventure Workshop.
Exits: pub, maze, character-gallery
Objects: room-templates, npc-catalog, puzzle-designsThe skill directory IS the room. The sister scripts are objects you can pick up and use. Sniffable Python makes those scripts discoverable.
来自skill/SKILL.md,技能表现为可进入的房间:
> enter the adventure skill
你现在在冒险工坊。
出口:pub, maze, character-gallery
物品:room-templates, npc-catalog, puzzle-designs技能目录就是房间。姊妹脚本是你可以拿起使用的物品。可快速理解的Python让这些脚本易于发现。
The Coherence Engine Flow
一致性引擎流程
yaml
undefinedyaml
undefinedCoherence Engine: user request → LLM discovery → execution
一致性引擎:用户请求 → LLM发现 → 执行
coherence_flow:
trigger: "Run the room builder for the kitchen"
steps:
- action: "LLM reads skill/SKILL.md"
discovers: "scripts/room-builder"
- action: "LLM sniffs room-builder.py (first 50 lines)"
sees:
docstring: "Creates rooms..."
commands: [create, modify, list]
options: [--template, --force]
- action: "LLM understands API, generates command"
output: "room-builder create --template kitchen"
The LLM discovers the tool's capabilities by reading its structure, not by loading documentation. One quick sniff and it knows what's cooking.
---coherence_flow:
trigger: "为厨房运行房间构建器"
steps:
- action: "LLM读取skill/SKILL.md"
discovers: "scripts/room-builder"
- action: "LLM快速理解room-builder.py(前50行)"
sees:
docstring: "创建房间..."
commands: [create, modify, list]
options: [--template, --force]
- action: "LLM理解API,生成命令"
output: "room-builder create --template kitchen"
LLM通过读取脚本结构而非加载文档来发现工具的功能。只需快速扫一眼,它就知道该怎么做。
---Checklist
检查清单
When writing sniffable Python:
- Shebang on line 1
- Module docstring with purpose, usage, examples
- Imports grouped at top (no decorative markers)
- Constants with explanatory comments
- CLI structure in using argparse (preferred) or Click/Typer
main() - Each command has a docstring
- Types specified in function signatures
- Implementation below line 50
- Internal functions prefixed with
_ - at bottom
if __name__ == "__main__":
编写可快速理解的Python时,请检查:
- 第一行是Shebang
- 模块文档字符串包含用途、用法、示例
- 导入语句分组在顶部(无装饰性标记)
- 常量带有解释性注释
- 使用argparse(优先)或Click/Typer在中定义CLI结构
main() - 每个命令都有文档字符串
- 函数签名中指定类型
- 实现细节在第50行之后
- 内部函数以开头
_ - 文件底部有
if __name__ == "__main__":
Anti-Patterns (Code Smells You Can't Unsmell)
反模式(无法忽视的代码异味)
❌ Implementation before CLI
python
def _helper():
...
def _another_helper():
...❌ 实现细节在CLI结构之前
python
def _helper():
...
def _another_helper():
...200 lines later...
200行之后...
@click.command()
def main():
...
❌ **No docstrings**
```python
@click.command()
def process(x, y, z):
# What does this do? What are x, y, z?❌ Magic constants
python
if retries > 3: # Why 3? What happens at 4?❌ Scattered imports
python
import os
def foo():
import json # Hidden dependency@click.command()
def main():
...
❌ **无文档字符串**
```python
@click.command()
def process(x, y, z):
# 这个函数做什么?x、y、z是什么?❌ 魔法常量
python
if retries > 3: # 为什么是3?4会发生什么?❌ 分散的导入语句
python
import os
def foo():
import json # 隐藏的依赖Commands
命令列表
| Command | Action |
|---|---|
| Read and summarize a Python file's API |
| Language-agnostic review for sniffability |
| Create new sniffable script from template |
| Check if file follows conventions |
| 命令 | 操作 |
|---|---|
| 读取并总结Python文件的API |
| 与语言无关的可快速理解性检查 |
| 从模板创建新的可快速理解脚本 |
| 检查文件是否符合规范 |
SNIFF CODE — Works on Any Language
SNIFF CODE — 适用于任何语言
The command isn't Python-specific. It reviews any source file:
SNIFF CODE> SNIFF CODE src/api/handler.ts
Sniffability Report for handler.ts:
✓ Purpose clear from first 10 lines
✓ Exports/API visible before implementation
✗ Magic number on line 47 — needs comment
✗ Helper function before main export — reorder
✓ Semantic comments explain WHY not WHAT
Overall: Mostly fresh, minor reordering neededWhat it checks:
| Aspect | Question |
|---|---|
| Purpose | Can you understand what this does in 10 lines? |
| API-first | Are exports/interfaces/main before helpers? |
| Comments | Do comments explain WHY, not just WHAT? |
| No decoration | Are comments semantic, not decorative cruft? |
| Constants | Do magic values have explanatory comments? |
| Dependencies | Are imports/requires visible at top? |
Good for humans. Good for LLMs. Same conventions.
SNIFF CODE> SNIFF CODE src/api/handler.ts
handler.ts的可快速理解性报告:
✓ 前10行就能明确用途
✓ 导出/API在实现细节之前可见
✗ 第47行有魔法数字——需要添加注释
✗ 辅助函数在主导出之前——请重新排序
✓ 语义注释解释原因而非内容
总体评价:整体良好,只需稍作重排检查内容:
| 方面 | 问题 |
|---|---|
| 用途 | 阅读10行以内就能理解它的用途吗? |
| API优先 | 导出/接口/主函数在辅助函数之前吗? |
| 注释 | 注释解释的是原因而非内容吗? |
| 无装饰 | 注释是语义化的,而非装饰性的冗余内容吗? |
| 常量 | 魔法值带有解释性注释吗? |
| 依赖项 | 导入/引用在顶部可见吗? |
对人类友好,对LLM友好,遵循相同规范。
Protocol Symbol
协议标识
SNIFFABLE-PYTHONInvoke when: Generating or reading Python scripts that need to be LLM-comprehensible.
SNIFFABLE-PYTHON调用时机:生成或读取需要让LLM易于理解的Python脚本时。
Dovetails With — The Intertwingularity
与其他技能的关联
Everything in MOOLLM connects. Sniffable Python sits at the intersection of multiple skills:
yaml
undefinedMOOLLM中的所有内容都是相互关联的。可快速理解的Python处于多个技能的交叉点:
yaml
undefinedHow sniffable-python connects to other skills
可快速理解的Python与其他技能的关联
skill_connections:
parent: "constructionism (build to learn)"
center: "sniffable-python"
peers:
- skill: "play-learn-lift"
relation: "LIFT stage produces sniffable Python"
- skill: "yaml-jazz"
relation: "Comments carry semantic meaning"
children:
- skill: "sister-script"
relation: "Sister scripts ARE sniffable Python"
- skill: "skill"
relation: "Skills generate sniffable scripts"
- skill: "adventure"
relation: "Linter exemplifies the feedback loop"
| Skill | Relationship to Sniffable Python |
|-------|----------------------------------|
| [sister-script/](../sister-script/) | Sister scripts ARE sniffable Python |
| [skill/](../skill/) | Skills generate sniffable scripts |
| [yaml-jazz/](../yaml-jazz/) | Comments carry semantic meaning |
| [play-learn-lift/](../play-learn-lift/) | Sniffable Python is LIFT output |
| [constructionism/](../constructionism/) | Build inspectable things |
| [adventure/](../adventure/) | Linter exemplifies the feedback loop |
| [session-log/](../session-log/) | Raw exploration → procedures → scripts |
| [research-notebook/](../research-notebook/) | Documented patterns become scripts |skill_connections:
parent: "constructionism(边做边学)"
center: "sniffable-python"
peers:
- skill: "play-learn-lift"
relation: "LIFT阶段生成可快速理解的Python"
- skill: "yaml-jazz"
relation: "注释承载语义信息"
children:
- skill: "sister-script"
relation: "姊妹脚本就是可快速理解的Python"
- skill: "skill"
relation: "技能生成可快速理解的脚本"
- skill: "adventure"
relation: "检查器体现了反馈循环"
| 技能 | 与可快速理解的Python的关系 |
|-------|----------------------------------|
| [sister-script/](../sister-script/) | 姊妹脚本就是可快速理解的Python |
| [skill/](../skill/) | 技能生成可快速理解的脚本 |
| [yaml-jazz/](../yaml-jazz/) | 注释承载语义信息 |
| [play-learn-lift/](../play-learn-lift/) | 可快速理解的Python是LIFT的输出 |
| [constructionism/](../constructionism/) | 构建可检查的事物 |
| [adventure/](../adventure/) | 检查器体现了反馈循环 |
| [session-log/](../session-log/) | 原始探索 → 流程 → 脚本 |
| [research-notebook/](../research-notebook/) | 已记录的模式转化为脚本 |Live Examples
实际示例
| Example | Location | What It Shows |
|---|---|---|
| Adventure-4 World | examples/adventure-4/ | Complete world with linter-driven generation |
| TomTomagotchi | kitchen/tomtomagotchi.yml | YAML Jazz: abilities documented with usage examples |
| The Pub | pub/ROOM.yml | Semantic comments as framing protocol |
| The Linter Output | LINTER.yml | Structured output the LLM can parse |
| Skill as Room | skill/SKILL.md | Skills manifest as explorable spaces |
| 示例 | 位置 | 展示内容 |
|---|---|---|
| Adventure-4世界 | examples/adventure-4/ | 完整的由检查器驱动生成的世界 |
| TomTomagotchi | kitchen/tomtomagotchi.yml | YAML Jazz:能力带有使用示例文档 |
| 酒馆 | pub/ROOM.yml | 语义注释作为框架协议 |
| 检查器输出 | LINTER.yml | LLM可解析的结构化输出 |
| 技能即房间 | skill/SKILL.md | 技能表现为可探索的空间 |
The Circle Completes
循环闭合
PLAY: Try things, log them
↓
LEARN: Document patterns in PROCEDURE.md
↓
LIFT: Generate sister-script.py in SNIFFABLE PYTHON format
↓
SKILL: Add to skill, expose to LLM
↓
LLM: Sniffs script, understands API, uses tool
↓
OUTPUT: YAML results (linter, builder, etc.)
↓
PLAY: Try new things with the tool...
↓
[repeat]This is the MOOLLM development loop. Sniffable Python is the code interface that makes it work.
PLAY:尝试事物,记录过程
↓
LEARN:在PROCEDURE.md中记录模式
↓
LIFT:生成SNIFFABLE PYTHON格式的sister-script.py
↓
SKILL:添加到技能中,对LLM开放
↓
LLM:快速理解脚本,理解API,使用工具
↓
OUTPUT:YAML结果(检查器、构建器等)
↓
PLAY:使用工具尝试新事物...
↓
[重复循环]这就是MOOLLM的开发循环。 可快速理解的Python是让这个循环运转的代码接口。
Beyond Python: Universal Sniffability
超越Python:通用可快速理解性
While this skill focuses on Python, the principles are language-agnostic:
| Language | Sniffable Structure |
|---|---|
| TypeScript | Exports at top, types before implementation, JSDoc on public API |
| Go | Package doc, exported functions first, internal helpers below |
| Rust | Module doc, pub items at top, private impl below |
| Java | Class Javadoc, public methods before private |
| Bash | Usage comment at top, main at top, functions below |
The universal rule: Whatever a reader (human or LLM) needs to use the code should be visible before whatever they need to modify it.
typescript
// ✓ Sniffable TypeScript
/**
* User authentication service.
* @module auth
*/
export interface AuthConfig { ... }
export function authenticate(config: AuthConfig): Promise<User> { ... }
export function logout(): void { ... }
// Implementation details below
function validateToken(token: string): boolean { ... }Same smell test, any language: Can you understand what this code offers by reading just the head?
虽然本技能聚焦于Python,但这些原则是与语言无关的:
| 语言 | 可快速理解的结构 |
|---|---|
| TypeScript | 顶部导出,类型定义在实现之前,公共API添加JSDoc |
| Go | 包文档,导出函数在前,内部辅助函数在后 |
| Rust | 模块文档,公共项在前,私有实现在后 |
| Java | 类Javadoc,公共方法在前,私有方法在后 |
| Bash | 顶部是用法注释,主逻辑在前,函数在后 |
通用规则: 无论读者是人类还是LLM,使用代码所需了解的内容都应放在前面。
typescript
// ✓ 可快速理解的TypeScript
/**
* 用户认证服务。
* @module auth
*/
export interface AuthConfig { ... }
export function authenticate(config: AuthConfig): Promise<User> { ... }
export function logout(): void { ... }
// 实现细节在后面
function validateToken(token: string): boolean { ... }任何语言都适用的嗅觉测试: 只需阅读开头部分,你能理解这段代码提供的功能吗?
Lickable Pixels, Sniffable Code
像素与代码:设计理念的呼应
When Steve Jobs unveiled Mac OS X's Aqua interface in 2000, he said:
"We made the buttons on the screen look so good you'll want to lick them."
Jobs understood that interfaces aren't just functional — they should be sensually inviting. The translucent droplets, the pulsing default buttons, the candy-colored icons — these weren't decoration. They were signals of quality that drew users in.
Programming languages are user interfaces. The users are humans and LLMs. And just as lickable pixels invite visual exploration, sniffable code invites structural exploration.
| Lickable Pixels (UI) | Sniffable Code |
|---|---|
| Visually inviting | Structurally inviting |
| Draws the eye to affordances | Draws the reader to the API |
| Beauty signals quality | Clarity signals quality |
| Users want to click | Readers want to use |
| First impression matters | First 50 lines matter |
Jobs didn't make Aqua pretty at the expense of function — the visual design reinforced usability. Sniffable code works the same way: the structural clarity that helps LLMs also helps humans. We're not optimizing for machines at human expense. We're optimizing for comprehension, and both benefit.
Perl looks like line noise. Sniffable Python looks like an invitation.
2000年史蒂夫·乔布斯发布Mac OS X的Aqua界面时说:
“我们让屏幕上的按钮看起来如此精美,你会想舔它们。”
乔布斯明白,界面不仅要实用——还应该感官上具有吸引力。半透明的水滴效果、脉动的默认按钮、糖果色图标——这些都不是装饰。它们是体现品质的信号,能吸引用户。
编程语言也是用户界面。 用户是人类和LLM。就像“舔屏级”像素吸引视觉探索一样,可快速理解的代码吸引结构化探索。
| 舔屏级像素(UI) | 可快速理解的代码 |
|---|---|
| 视觉上有吸引力 | 结构上有吸引力 |
| 将目光引向功能入口 | 将读者引向API核心 |
| 美观体现品质 | 清晰体现品质 |
| 用户想要点击 | 读者想要使用 |
| 第一印象很重要 | 前50行很重要 |
乔布斯没有为了美观牺牲功能——视觉设计强化了可用性。可快速理解的代码也是如此:帮助LLM的结构清晰度同样帮助人类。我们不是在以人类为代价优化机器,而是在优化理解性,让两者都受益。
Perl看起来像乱码。可快速理解的Python则像一份邀请。
The Thesis
核心论点
The "ideal LLM syntax" question has the wrong framing.
You don't need new syntax. You need structured familiar syntax.
- Languages LLMs know (Python, TypeScript, Go, Rust...)
- Structured for sniffability (important stuff at top)
- Comments as data (YAML Jazz applied to any language)
- Single source of truth (the code IS the spec)
Dense syntax compresses the wrong thing. Sniffable code structures the right thing.
Jobs made you want to lick the screen. We want you to sniff the source.
"The LLM doesn't need fewer tokens of unfamiliar syntax. It needs familiar syntax, structured for fast comprehension."
Good code doesn't just avoid bad smells — it has an aroma that draws you in from the header.
“理想的LLM语法”这个问题的出发点就错了。
你不需要新语法,你需要结构化的熟悉语法。
- LLM熟悉的语言(Python、TypeScript、Go、Rust等)
- 为可快速理解性进行结构化(重要内容放在前面)
- 注释作为数据(YAML Jazz应用于任何语言)
- 单一事实来源(代码就是规范)
密集语法压缩了错误的内容。可快速理解的代码结构化了正确的内容。
乔布斯让你想舔屏幕。我们让你想“嗅懂”源代码。
“LLM不需要更少的陌生语法token。它需要熟悉的语法,且结构便于快速理解。”
好代码不仅没有坏味道——它的开头部分就有吸引人的“香气”。