🐍

Pythonを書くなら、Ruffのルールページは最高の教材だと思う(AI時代の学び方)

に公開

カバー画像

この記事は LayerX Tech Advent Calendar 2025 23日目の記事です。

Ai Workforce事業部 プロダクト部 FDEグループ エンジニアの です。

本記事では、プログラムを書き始めたばかりの頃に Pythonの静的解析ツールである Ruff のエラー修正を通じて学んだ経験と、それを踏まえて作った ruff-tutor-mcp というMCPサーバー、そしてAIコーディング時代の学び方について書きたいと思います。


最近、エンジニアのみなさんはコーディングエージェントを使っているのではないでしょうか。特に、Claude Codeがリリースされてからその流れが加速したように感じます。私自身も、特にClaude Opus 4.5が出て以来、本当に自分でコードを書くことが減りました。Claude Codeにコンテキストとして与える要件をマークダウンで書く時間が圧倒的に増え、日本語ばかり書いています。

ただ、その中で「自分でコーディングした経験」の重要性も残っていると感じています。誤解のないように言っておくと、これは「今コードをAIではなくて自分で書け」という意味ではありません。「自分でコーディングした経験」はあったほうが良い、という意味です。そういう経験がある人は、AIをより効果的に活用できるのではないかと思います。

例えば、ジュニアのエンジニアが「良いコードとは?」を知らずにAIに頼りっきりだと、「何も知らないまま成長した気になる」ことがあり得るのではないかと思います。私自身、AIに任せっぱなしにしていると、そういう状態に陥ってしまうこともあると感じています。

ちなみに、今回話す「良いコード」とは、あくまでコーディングにおける細かい部分の話です。ソフトウェア設計などの、より高レベルなことは話しません。例えば、Ruffが指摘するような変数名の付け方や関数の書き方といった、コードの書き方そのものについての話だと思ってください。

1. Ruffエラーの修正を通じた学習経験

プログラムを書き始めたばかりの頃に、多くのコードを書きました。その中で、Pythonの書き方を知るのに役立ったと感じたのは、静的解析ツールのRuffのルールに違反しているコードのリファクタリングです。

当時からAIにコードを書かせるという発想はあり、要件定義をして設計を書き、AIにファーストドラフトを書かせたうえで、人間がレビューとリファクタリングを行う、という流れで開発していました。今では Spec Driven Development と呼ばれていますね。ただ、当時はAIのファーストドラフトの質が今に比べて低く、その後のリファクタリングや修正は人間がやることが多かったです。また、Web検索機能を備えたモデルも少なく、今のように一気通貫でやってくれる環境ではありませんでした。

AIが生成したコードが要件に沿っているかを確認した後、「コードを綺麗にする」工程として、静的解析ツールのRuffや型チェッカーのmypyが出すエラーを一つずつ修正していました。エラー内容を読み、対応するルールが書かれたウェブページを調べ、どう直すべきかを理解したうえで自分の手で修正する、という作業です。今であればCursorやClaude Codeが検索から修正まで自動でやってくれますが、当時は完全に手作業でした。

ruff-rules
実際のWebページの例: https://docs.astral.sh/ruff/rules/enumerate-for-loop/

この地道で面倒な作業によって、「綺麗なコードとは」を知ることになりました。PEP(Python Enhancement Proposal)にはこんなルールがあるのか、こういう書き方が推奨されているのか、ということを一つ一つ理解していった経験は、今振り返っても非常に良かったと思っています。

一方で、今のジュニアエンジニア(私自身もまだまだジュニアですが)が、こうした経験を積む機会を持てないまま時間を過ごしてしまうのはもったいないと感じています。AIが自動でエラーを修正してくれる環境は非常に便利ですが、「なぜそのコードが良くないのか」「どんなルールが背景にあるのか」を理解しないまま先に進んでしまう可能性もあります。

2. ruff-tutor-mcp:静的解析を通じたコーディング学習をサポートするMCPサーバー

こうした話をすると、「じゃあAIを使わずに全部人間が実装しましょう!」という結論に飛びつくのは簡単ですが、それは違うと感じています。

今や実装にAIを使うのは特別なことではなく、むしろ前提になりつつあります。しかもAIは、学習にもかなり効きます。例えば初めて触るリポジトリのキャッチアップは、AIがいるだけで速度が段違いですし、自分にはない発想で素晴らしいコードを書いてくれることもあります。冒頭に書きましたが、私自身も今はほとんどのコードをAIに書かせています。

一方で、AIが「正しい修正」を一瞬で出してくれるほど、学びの機会が消えやすいのも事実です。Ruffの警告を直すときに、修正内容だけが反映されて「なぜそれが良いのか」を理解できないまま進んでしまうことがあります。これがもったいないと感じています。

そこで作ったのが ruff-tutor-mcp です。Ruffのルール違反を直す場面で、AIが ルールの内容だけでなく、背景や理由まで説明してくれる MCPサーバーです。狙いは、地道なエラー修正で得られる学びと、AIの効率性の両立です。

使い方はシンプルです。まずMCPサーバーとしてClaudeに追加します。その後は通常のRuffチェックと同じようにコードを指定するだけです。違いは、エラーが検出された際に単なる修正案ではなく、ルールの背景や理由まで含めた解説が返ってくる点です。修正後は再度検証ツールを実行することで、残っている問題があれば追加でガイドしてくれます。

従来のRuffのエラー修正フローはそのままに、間に「理解のための説明」を挟むことで、学びながらコードを改善できるようになっています。

example
ruff-tutor-mcpの使用例

MCPサーバーとして登録する

では、実際に ruff-tutor-mcp を使うための手順を紹介します。

まずはClaude側にサーバーを追加します。Claude Codeならコマンド一発です。

claude mcp add ruff-tutor -- uvx --from git+https://github.com/223mle/ruff-tutor-mcp ruff-tutor-mcp

ツールの使い方

ruff-tutor-mcpが提供する主な機能は2つあります。

  • review_code_and_teach:指定したパスのコードに対してRuffコマンドを実行し、ルールに違反している箇所を「解説付き」で返す
  • verify_fix:修正後に再チェックし、まだ残っているものルール違反があれば追加でガイドする

AIが返すのは単なる修正案ではなく、ルールの背景や理由まで含めた解説です。

  • そのルールが何を禁止・推奨しているか
  • なぜそのルールが存在するのか(設計思想・背景)
  • どう直すのが基本方針か(よくある修正パターン)

また、プロジェクトルートに .ruff-tutor.toml を置くと、説明のレベル感を揃えられます。

mode = "auto"  # beginner / advanced / auto(デフォルトはauto)
max_retry = 2

学習モードは以下の3つから選択できます。

  • beginner: 修正前/修正後のコード例を表示し、詳しい説明付きでユーザーに修正を促す
  • advanced: コード例を表示せず、説明のみでユーザー自身に考えさせる
  • auto: 説明を表示した後、自動修正を実行(デフォルト)

導入方法や細かい挙動(引数や設定)はREADMEにまとめています。

3. おわりに

正直に言うと、この記事を読んで「ruff-tutor-mcpを使って勉強する!」と思う人は、ほとんどいないと思っています。

ただ、「よく分からないけどRuffの警告をAIが修正した」という状態で進む人より、「なぜ修正したのか?なぜそう修正すべきなのか?」を理解している人の方が、今後AIを扱える人材になるのではないかと思います。それは、CLAUDE.md, AGENT.mdに書くプロンプトの質や、AIに出す指示に差が現れてくるはずです。

だから別にこのツールを使えという話ではなく、静的解析を直すときに「なんでこれってダメなんだろう?」と考えることが大事だと思っています。一つ一つのエラーに向き合い、その背景にあるルールや思想を理解することが、長期的な成長につながると考えています。あと、プログラミングが楽しくなってきます(私自身がそうでした)。

そして、こうした学習を積めるようになったら、段階的にアーキテクチャやソフトウェア設計といった、より高いレベルの学習に進んでいくべきです。私自身もまだまだ勉強中ですが、一緒に成長していければと思います。

v-model
V字モデルの上に登っていくイメージ

最近話題のFDE(Foward Deployed Engineer)やLayerXについて興味のある方は是非以下のサイトからカジュアルにお話しましょう!

https://jobs.layerx.co.jp/opendoor/2d3cdd370bae8051a659fdd1dbd9d595/

LayerX

Discussion