$57
The model must identify its ROLE_TYPE and echo the following statement:
My ROLE_TYPE is "<the role type>". I follow instructions given to "the model" and "<role name>".
Where:
<the role type> is either "orchestrator" or "sub-agent" based on the ROLE_TYPE identification rules in CLAUDE.md<role name> is "orchestrator" if ROLE_TYPE is orchestrator, or "sub-agent" if ROLE_TYPE is sub-agentExample for orchestrator:
My ROLE_TYPE is "orchestrator". I follow instructions given to "the model" and "orchestrator".
Example for sub-agent:
My ROLE_TYPE is "sub-agent". I follow instructions given to "the model" and "sub-agent".
Orchestration guide for Python development using specialized agents and modern Python 3.11-3.14 patterns.
Reference Documentation:
Command Templates and Guides (commands/):
Scripts and Assets:
Agents (install to ~/.claude/agents/):
@agent-python-cli-architect - Python CLI development with Typer and Rich@agent-python-pytest-architect - Test suite creation and planning@agent-python-code-reviewer - Post-implementation code review@agent-python-portable-script - Standalone stdlib-only script creation@agent-spec-architect - Architecture design@agent-spec-planner - Task breakdown and planning@agent-spec-analyst - Requirements gatheringSlash Commands (install to ~/.claude/commands/):
/modernpython - Python 3.11+ pattern enforcement and legacy code detection/shebangpython - PEP 723 inline script metadata validationSystem Tools (install via package manager or uv):
uv - Python package and project manager (required)ruff - Linter and formatterpyright - Type checker (Microsoft)mypy - Static type checkerpytest - Testing frameworkpre-commit - Git hook frameworkmutmut - Mutation testing (for critical code)bandit - Security scanner (for critical code)Installation Notes:
uv skill for comprehensive uv documentation and package management guidanceThis skill provides orchestration patterns, modern Python 3.11+ standards, quality gates, and reference documentation for Python development.
Commands (external - in ~/.claude/commands/):
/modernpython - Validates Python 3.11+ patterns, identifies legacy code/shebangpython - Validates correct shebang for all Python scriptscommands/ directory, not the actual slash commandsReference Documentation:
Docstring Standard: Google style (Args/Returns/Raises sections). See User Project Conventions for ruff pydocstyle configuration (convention = "google").
CRITICAL: Pyproject.toml Template Variables:
All pyproject.toml examples use explicit template variables (e.g., {{project_name_from_directory_or_git_remote}}) instead of generic placeholders. The model MUST replace ALL template variables with actual values before creating files. See Tool & Library Registry sections 18-19 for:
Understand the complexity vs portability trade-off when creating Python CLI scripts:
Scripts with dependencies (Typer + Rich via PEP 723):
stdlib-only scripts:
Default recommendation: Use Typer + Rich with PEP 723 unless you have specific portability requirements that prevent network access.
See:
Common Problem: Rich containers (Panel, Table) wrap content at 80 characters in CI/non-TTY environments, breaking URLs, commands, and structured output.
Two Solutions Depending on Context:
For plain text output that shouldn't wrap:
from rich.console import Console
console = Console()
# URLs, paths, commands - never wrap
console.print(long_url, crop=False, overflow="ignore")
For Panel and Table that contain long content, crop=False alone doesn't work because containers calculate their own internal layout. Use get_rendered_width() helper with different patterns for Panel vs Table:
from rich.console import Console, RenderableType
from rich.measure import Measurement
from rich.panel import Panel
from rich.table import Table
def get_rendered_width(renderable: RenderableType) -> int:
"""Get actual rendered width of Rich renderable.
Handles color codes, Unicode, styling, padding, borders.
Works with Panel, Table, or any Rich container.
"""
temp_console = Console(width=9999)
measurement = Measurement.get(temp_console, temp_console.options, renderable)
return int(measurement.maximum)
console = Console()
# Panel: Set Console width (Panel fills Console width)
panel = Panel(long_content)
panel_width = get_rendered_width(panel)
console.width = panel_width # Set Console width, NOT panel.width
console.print(panel, crop=False, overflow="ignore", no_wrap=True, soft_wrap=True)
# Table: Set Table width (Table controls its own width)
table = Table()
table.add_column("Type", style="cyan", no_wrap=True)
table.add_column("Value", style="green", no_wrap=True)
table.add_row("Data", long_content)
table.width = get_rendered_width(table) # Set Table width
console.print(table, crop=False, overflow="ignore", no_wrap=True, soft_wrap=True)
Executable Examples: See ./assets/typer_examples/ for complete working scripts:
console_no_wrap_example.py - Plain text wrapping solutionsconsole_containers_no_wrap.py - Panel/Table width handling with get_rendered_width()Instruction: In Rich console output, always use Rich emoji tokens instead of literal Unicode emojis.
Use Rich emoji tokens: :white_check_mark: :cross_mark: :magnifying_glass:
Why: Cross-platform compatibility, consistent rendering, markdown-safe alignment
Example:
from rich.console import Console
console = Console()
# Correct - Rich emoji tokens
console.print(":white_check_mark: Task completed")
console.print(":cross_mark: Task failed")
console.print(":sparkles: New feature")
console.print(":rocket: Performance improvement")
Benefits:
get_rendered_width()See: Rich Emoji Documentation for complete emoji token reference.
Catch exceptions only when you have a specific recovery action. Let all other errors propagate to the caller.
Reason: Fail-fast principle surfaces issues early rather than hiding them behind generic error messages.
Pattern:
def get_user(id):
return db.query(User, id) # Errors surface naturally
def get_user_with_handling(id):
try:
return db.query(User, id)
except ConnectionError:
logger.warning("DB unavailable, using cache")
return cache.get(f"user:{id}") # Specific recovery action
When adding try/except, answer: "What specific error do I expect, and what is my recovery action?"
See: Exception Handling in Python CLI Applications for comprehensive patterns including Typer exception chain prevention.
REQUIREMENT: All Python code MUST be comprehensively typed using Python 3.11+ native type hints.
Python Version: Python 3.11+ is required unless explicitly documented otherwise. Older versions are rare, documented exceptions.
The model MUST read the official mypy documentation examples before implementing type patterns. Each subsection links to authoritative mypy docs.
Use generics for type-safe container classes and functions that work with multiple types.
Applicable scenarios:
MUST read examples before implementing: Mypy Generics Documentation
Python 3.11 Generic Pattern (TypeVar with Generic):
from typing import TypeVar, Generic, Sequence
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
def first(seq: Sequence[T]) -> T:
return seq[0]
Python 3.12+ Generic Pattern (Native Syntax):
class Stack[T]:
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
def first[T](seq: Sequence[T]) -> T:
return seq[0]
Type Variable Bounds (restrict to subtypes):
from collections.abc import Sequence
from typing import Protocol
class SupportsAbs[T](Protocol):
def __abs__(self) -> T: ...
def max_by_abs[T: SupportsAbs[float]](*xs: T) -> T:
return max(xs, key=abs)
Value Restrictions (limit to specific types):
def concat[S: (str, bytes)](x: S, y: S) -> S:
return x + y # Type-safe for str OR bytes, but not mixed
Generic Method Chaining (precise return types):
from typing import Self
class Shape:
scale: float = 1.0
def set_scale(self, scale: float) -> Self:
self.scale = scale
return self # Returns precise subclass type
Use protocols for structural subtyping when you need duck typing with type safety. Protocols check whether an object has required methods/attributes regardless of inheritance.
Applicable scenarios:
MUST read examples before implementing: Mypy Protocols Documentation
Basic Protocol Pattern:
from typing import Protocol
class SupportsClose(Protocol):
def close(self) -> None: ...
def close_resource(resource: SupportsClose) -> None:
resource.close() # Works with ANY object having close() method
# No inheritance needed - structural match
class FileHandler:
def close(self) -> None:
print("Closing file")
close_resource(FileHandler()) # ✅ Type-safe
Read-Only Attributes (use @property to avoid invariance issues):
from typing import Protocol
class Named(Protocol):
@property
def name(self) -> str: ... # Read-only via property
Recursive Protocols (tree structures):
from typing import Protocol
class TreeLike(Protocol):
value: int
@property
def left(self) -> TreeLike | None: ...
@property
def right(self) -> TreeLike | None: ...
Runtime Checks:
from typing import Protocol, runtime_checkable
@runtime_checkable
class Drawable(Protocol):
def draw(self) -> None: ...
def render(obj: object) -> None:
if isinstance(obj, Drawable): # Runtime check enabled
obj.draw()
WARNING: isinstance() with protocols only verifies attribute existence, NOT type correctness. Use for structural validation, not precise type guarantees.
Use TypedDict for dictionaries with fixed schemas and string keys where each key has a specific value type.
Applicable scenarios:
MUST read examples before implementing: Mypy TypedDict Documentation
Required Fields Pattern (all keys required):
from typing import TypedDict
class Movie(TypedDict):
name: str
year: int
director: str
movie: Movie = {
"name": "Blade Runner",
"year": 1982,
"director": "Ridley Scott"
} # All keys required
Optional Fields Pattern (total=False):
from typing import TypedDict
class MovieOptions(TypedDict, total=False):
subtitles: bool
audio_language: str
options: MovieOptions = {} # ✅ Empty dict valid
options2: MovieOptions = {"subtitles": True} # ✅ Partial valid
Mixed Required/Optional Pattern:
from typing import TypedDict
class MovieBase(TypedDict):
name: str # Required
year: int # Required
class Movie(MovieBase, total=False):
director: str # Optional
rating: float # Optional
movie: Movie = {"name": "Alien", "year": 1979} # ✅ Valid
CRITICAL: Always annotate variables when assigning TypedDict literals. Without annotation, mypy infers dict[str, Any]:
# ❌ Wrong - inferred as dict[str, Any]
movie = {"name": "Alien", "year": 1979}
# ✅ Correct - explicitly typed
movie: Movie = {"name": "Alien", "year": 1979}
Use type narrowing to refine broad union types to specific types based on runtime checks.
Applicable scenarios:
str | int | None)MUST read examples before implementing: Mypy Type Narrowing Documentation
isinstance() Narrowing:
def process_value(value: str | int) -> str:
if isinstance(value, str):
return value.upper() # Narrowed to str
else:
return str(value * 2) # Narrowed to int
None Checks:
def greet(name: str | None) -> str:
if name is not None:
return f"Hello, {name}" # Narrowed to str
return "Hello, stranger"
Type Guards (custom narrowing functions):
from typing import TypeGuard
def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
return all(isinstance(x, str) for x in val)
def process(values: list[object]) -> None:
if is_str_list(values):
# Narrowed to list[str] in this branch
print(" ".join(values))
TypeIs (Python 3.13+, more powerful than TypeGuard):
from typing import TypeIs
def is_str(val: object) -> TypeIs[str]:
return isinstance(val, str)
def process(val: str | int) -> None:
if is_str(val):
print(val.upper()) # Narrowed to str
else:
print(val * 2) # Narrowed to int (complement type)
Key difference: TypeGuard narrows only the if-branch; TypeIs narrows both branches (if-branch to the specified type, else-branch to the complement).
Decision Matrix:
| Feature | attrs | dataclasses | pydantic |
| ---------------------- | ---------------------------------- | -------------------------------------- | ---------------------------------------- |
| Performance | Fastest (compiled) | Fast (native) | Slower (validation overhead) |
| Validation | Basic (via converters/validators) | None (requires custom __post_init__) | Comprehensive (built-in) |
| Immutability | @frozen | frozen=True | frozen=True (v2) |
| Evolution | Excellent (evolve()) | Basic (replace()) | Good (model_copy()) |
| Slots | Automatic | Manual (slots=True) | Automatic (v2) |
| Type Coercion | Manual | None | Automatic |
| JSON Serialization | Manual | Manual | Native (model_dump_json()) |
| Use When | High-performance, pure Python data | Stdlib-only requirement | External data validation (APIs, configs) |
attrs Pattern (high performance, pure Python):
from attrs import define, field
@define
class User:
name: str
age: int = field(validator=lambda i, a, v: v >= 0)
email: str | None = None
MUST read examples: Mypy Additional Features - Attrs
dataclasses Pattern (stdlib-only):
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class User:
name: str
age: int
email: str | None = None
def __post_init__(self) -> None:
if self.age < 0:
raise ValueError("Age must be non-negative")
pydantic Pattern (external data validation):
from pydantic import BaseModel, Field, field_validator
class User(BaseModel):
name: str
age: int = Field(ge=0)
email: str | None = None
@field_validator('age')
@classmethod
def validate_age(cls, v: int) -> int:
if v < 0:
raise ValueError('Age must be non-negative')
return v
Recommendation:
attrs for internal data structures (best performance, most features)dataclassespydantic (if already a dependency)NEVER add pydantic as a dependency solely for dataclasses. Use attrs or stdlib dataclasses instead.
MUST read before using advanced patterns: Mypy Additional Features
Generic Dataclasses:
from dataclasses import dataclass
from typing import Generic, TypeVar
T = TypeVar('T')
@dataclass
class Box(Generic[T]):
value: T
int_box: Box[int] = Box(value=42)
str_box: Box[str] = Box(value="hello")
Self Type for Method Chaining:
from typing import Self
class Builder:
def set_name(self, name: str) -> Self:
self.name = name
return self
def set_value(self, value: int) -> Self:
self.value = value
return self
# Type-safe chaining
builder = Builder().set_name("test").set_value(42)
Strict Mode Configuration (pyproject.toml):
[tool.mypy]
python_version = "3.11"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_any_generics = true
check_untyped_defs = true
no_implicit_reexport = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
Per-Module Overrides (for gradual typing):
[[tool.mypy.overrides]]
module = "third_party_lib.*"
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = "legacy_code.*"
disallow_untyped_defs = false
See: Tool & Library Registry - Mypy Configuration for complete configuration examples.
<section ROLE_TYPE="orchestrator">The orchestrator delegates Python development tasks to specialized agents rather th
<!-- Content truncated for initial SEO render. Open the source file tab for the full file. -->npx skills add BbgnsurfTech/python3-development下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer