一键导入
linting-and-formatting
Code style guidelines for NeMo-RL (Python and shell). Covers naming, indentation, comments, docstrings, reflection avoidance, and uv usage.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Code style guidelines for NeMo-RL (Python and shell). Covers naming, indentation, comments, docstrings, reflection avoidance, and uv usage.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Configuration conventions for NeMo-RL. YAML is the single source of truth for defaults. Covers BaseModel/TypedDict usage, dataclass for internal classes, exemplar YAML updates, and forbidden default patterns.
Error handling guidelines for NeMo-RL. Covers exception specificity, minimal try bodies, and else blocks.
Interactive code review for NVIDIA-NeMo/RL pull requests. Checks out PR locally, reads existing comments, applies coding guidelines from skills, previews findings, and posts review comments. Also supports reviewing the current branch locally.
Build and dependency management for NeMo-RL. Covers Docker image building and running, uv usage, venv setup, and adding dependencies.
CI/CD reference for NeMo-RL. Covers GitHub Actions pipeline structure, CI triggering via /ok to test, and CI failure investigation.
Contribution conventions for NeMo-RL. Covers PR title format, commit sign-off, and CI triggering.
| name | linting-and-formatting |
| description | Code style guidelines for NeMo-RL (Python and shell). Covers naming, indentation, comments, docstrings, reflection avoidance, and uv usage. |
| when_to_use | Reviewing code style; writing or checking Python or shell code; 'is this naming right', 'docstring format', 'style violation', 'how should I format this', during code review. |
This repository is Python-first.
Use uv run to execute scripts. Do not activate a virtual environment and call python directly.
Do:
uv run examples/run_grpo.py
Don't:
source .venv/bin/activate
python examples/run_grpo.py
Exception: Dockerfile.ngc_pytorch is exempt from this rule.
Code must conform to Python 3.13.13+.
Indent with 4 spaces. Do not use tabs.
| Kind | Convention | Example |
|---|---|---|
| Files | snake_case | some_file.py |
| Classes | PascalCase | class SomeClass |
| Functions/methods | snake_case | def my_awesome_function(): |
| Local variables | snake_case | my_variable = ... |
| Variables starting with a number | prefix k | k_99th_percentile = ... |
| Global variables | upper snake_case + prefix G | G_MY_GLOBAL = ... |
| Constants | upper snake_case | MY_CONSTANT = ... |
Use Google style docstrings (parseable by Sphinx).
When a function has multiple parameters of the same type that could easily be swapped by mistake, use a bare * to force keyword-only arguments starting from where the ambiguity begins. This prevents callers from accidentally transposing arguments.
Don't:
def loss_fn(input: Tensor, cp_group: ProcessGroup, tp_group: ProcessGroup, cp_rank: int, tp_rank: int):
...
# Caller can silently swap cp_group/tp_group or cp_rank/tp_rank
loss_fn(x, tp_group, cp_group, tp_rank, cp_rank) # wrong order, no error
Do:
def loss_fn(input: Tensor, *, cp_group: ProcessGroup, tp_group: ProcessGroup, cp_rank: int, tp_rank: int):
...
# Caller must name every argument — swaps are impossible
loss_fn(x, cp_group=cp_group, tp_group=tp_group, cp_rank=cp_rank, tp_rank=tp_rank)
Do not use reflection when functionality can be achieved without it.
Don't:
def make_complex(*args):
x, y = args
return dict(**locals())
Do:
def make_complex(x, y):
return {'x': x, 'y': y}
Annotate new functions and methods — both parameters and return type. When you add a parameter to an
existing signature, type it, and match the type already used at the call site (don't leave a new arg
untyped while the caller already declares it, e.g. def __init__(self, teacher_worker_groups=None) when the
caller passes teacher_worker_groups: Optional[dict[str, Any]]).
When you add a new module under a type-checked area, add it to pyrefly.toml project-includes.
pyrefly checks an explicit allow-list of files, so a new file that isn't listed silently escapes
type-checking and its annotations are never verified.
Put imports at module top. Defer an import into a function body ONLY to break a circular import or to avoid
loading a heavy/optional dependency in a path that shouldn't need it — and when you do, add a one-line comment
saying which. An in-function import with no such reason should move to the top. In particular, deferring
stdlib (concurrent.futures, collections, …) or a module that is already imported at module top buys
nothing — hoist it.