agentleFS
h-watah-wata/claude-skills/skills/split-advisor/SKILL.md

split-advisor

Skill0 starsChanged 6 months agoApache-2.0View on GitHub

既に肥大化した Python の関数 / クラスを対象に「どう分割すべきか」の方針を提案する。ruff の複雑度違反と ast の行数から分割候補を機械的に選び、責務境界に沿った分割案を出す。提案のみでコードは変更しない。「この関数を分割したい」「大きくなったファイルを整理したい」「どこで切ればいいか分からない」「肥大化した関数の分割方針が欲しい」と言われたとき、または ruff の C901 / PLR0912 / PLR0915 違反への対処方針を立てるときに使う。

The file

Files
SKILL.md

Split Advisor

肥大化した Python の関数 / クラスについて、どこで・なぜ切るかの方針を提案する。

lint(ruff の C901 / PLR09xx)は「ここが複雑だ」までは言えるが「どう分割するか」は言わない。 その空白を埋めるのがこの skill。

絶対遵守ルール

  1. 提案のみ。コードを 1 行も変更しない。 ファイルの編集・作成・削除、フォーマッタの実行、 git の書き込み系コマンドをすべて行わない。対象リポジトリは read-only で参照する。 実際のリファクタは、提案をユーザーがレビューして別途タスク化してから行う。
  2. 行数だけを根拠に切らない。 「300 行あるので 3 つに分ける」は分割方針ではない。 必ず責務境界を根拠として示す(後述の判断軸)。
  3. 実物を読まずに提案しない。 対象定義の全行を Read してから書く。読んでいない依存関係や 呼び出し元を推測で語らない。呼び出し元の情報が必要なら Grep で確認する。
  4. 分割後の姿を確認できない提案(「適切に整理する」等の一般論)は出力しない。 各提案は「新しい関数名 / 引数 / 移動する行範囲」まで具体化する。

手順

1. 分割候補を機械的に選ぶ

対象リポジトリのルートで実行する(read-only):

python3 <skill-directory>/scripts/find_split_candidates.py src -n 10
  • --ruff-cmd "ruff check" で ruff の起動方法を変えられる(既定は uv run ruff check)。
  • --min-lines N で「違反は無いが長い」定義を拾う閾値を変えられる(既定 150)。
  • --json で機械可読出力。

出力は ファイル:開始行-終了行 種別 名前 行数 score 違反ルール一覧。 score は 行数 × (1 + 違反した異なるルール数) で、長さと複雑さの両方を効かせている (違反数だけで並べると、長いが分岐の浅い巨大関数が沈む)。score は候補の優先順位付けだけに 使うヒューリスティックであり、分割の容易さや実装の優先度を意味しない。 score が高いからと いって「先に分割すべき」「安全に分割できる」とは限らない。順位はあくまで「次にどれを読むか」を 決めるための足がかりであり、実際の分割可否は 3〜4 節の判断軸と自己検証で個別に判定する。

ユーザーが対象を明示している場合はこの手順を飛ばしてよいが、その場合も 対象の行範囲と違反ルールは確認する(--json で当該定義だけ見ればよい)。

2. 対象を読む

候補の中から 1 件を選び、定義の全行を Read する。あわせて次を確認する:

  • 呼び出し元(Grep で 関数名( を検索)。公開 API なら分割してもシグネチャを変えられない。
  • 対象が触っているモジュールグローバル / インスタンス属性。
  • 既存のテスト(分割の安全網があるか。無いなら提案にその旨を書く)。

3. 判断軸に沿って切れ目を探す

以下の軸で「切れる場所」を探す。該当した軸を根拠として提案に明記する。

軸見つけ方分割後の形
責務の境界入力の検証 / 外部 I/O / 純粋な計算 / 出力の整形 が 1 つの定義に同居していないか層ごとに関数を分ける。純粋な計算部分は単体テストしやすい形で切り出す
局所変数のクラスタある一群のローカル変数が特定の連続した区間でしか使われていないその区間を helper に切り出し、クラスタを引数 / 戻り値にする
早期 return での平坦化ネストが深い(PLR1702)。ガード節にできる条件が先頭にないか条件を先頭のガード節に移し、本体のネストを 1 段浅くする
共通の前処理 / 後処理分岐の各枝が同じ準備・後始末をしている前後を外側に括り出し、枝は差分だけを持つ
分岐ファミリ同じ変数に対する長い if/elif 連鎖(PLR0912)。各枝が独立した処理枝ごとの関数 + ディスパッチ表(dict)にする
逐次的なフェーズ「まず集める → 次に判定する → 最後に書く」と読める区切りコメントがあるフェーズごとの関数にし、呼び出し側を手順書のように読ませる
クラスの属性クラスタ(PLR0904)メソッド群が触る属性で 2 つ以上のグループに分かれるグループを協調オブジェクトとして別クラス / 別モジュールに切り出す

4. 分割案の妥当性を自己検証する

提案を書く前に、各分割単位について次を確認する。1 つでも引っかかったら境界の取り方が 間違っているので、切れ目を引き直す。

  • 切り出した helper の引数が 5 個以上になっていないか(多い=クラスタが本当は分かれていない)
  • helper が呼び出し元の状態を書き戻す必要がないか(必要=責務が切れていない)
  • 名前が _part2 / _helper / _process のような無内容な名前にしかならないか (=そこは意味の境界ではない)
  • 分割後に呼び出し側が読みにくくなっていないか(helper への往復が増えただけになっていないか)
  • 公開 API のシグネチャを変えていないか(変える必要があるなら、それは別の判断としてリスクに書く)
  • 定量的な主張(テスト件数・呼び出し箇所数・行数など)を出力に含める場合は、その数を 得た実行コマンドと生の出力を必ず併記する。 コマンドを示さない数値は、書いた本人にも 読み手にも検算できない。TASK-471 の試走レポートで「テスト実行が160箇所」という未検証の 主張が独立レビューで実測15件と食い違い、修正が必要になった前例がある (実際には計測条件の違いで、より広い一致条件では154件が正しかった。数値そのものより 「コマンドを示さなかったこと」自体が問題だった)。

5. 提案を出力する

対象 1 件につき、次の形式で出力する。ここで終わり。コードは書かない。

## 対象: <file>:<start>-<end> <name> (<lines> 行, <violated rules>)

### 現状の構造
<定義が実際に何をしているかを、行範囲つきで 3-6 個のブロックに分けて記述>

### 分割案
1. `<新しい関数名>(<引数>) -> <戻り値>`
   - 移動する範囲: L<start>-L<end>
   - 根拠となる軸: <判断軸の名前>(なぜそこが境界なのか 1-2 文)
2. ...

### 残る本体
<分割後に元の関数に残るもの。何行程度になるか>

### リスク / 注意
- <公開 API か、テストの有無、スレッド安全性やロック順序など、分割時に壊しやすいもの>

### 提案しなかったこと
- <目についたが分割対象にしなかった箇所と、その理由>

由来

分割の判断軸と「過剰な抽象化を避ける」方針は trailofbits/skills-curated の plugins/python-code-simplifier(Anthropic 公式 anthropics/claude-plugins-official の code-simplifier を Python 向けに書き換えたもの)を土台にした。

変えた点:

  • 対象を「直近で変更されたコード」から「既に肥大化している定義」に変えた。対象は 会話の文脈ではなく scripts/find_split_candidates.py の機械的な選定結果から取る。
  • 目的を「単純化してコードを書き換える」から「分割方針を提案する(コードは変更しない)」に変えた。
  • 命名規約・import 順・型注釈といった整形寄りの指針は落とした(それらは ruff / formatter の担当)。
  • 分割の判断軸と、境界が間違っていることを検出する自己検証項目を新設した。

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.