BLOG
エンジニアブログ

「このコード、実はよく分かってない」を卒業!eli5とcritが効きすぎた

山下
山下
「このコード、実はよく分かってない」を卒業!eli5とcritが効きすぎた

はじめに

こんにちは。クラウドセントリック株式会社の山下です。普段はAWSを活用したフルスタックアプリ開発に携わっています。

その開発の中で、実装をAIエージェントに任せる割合がこの半年でかなり増えました。そして増えた分だけ、「このコード、実はよく分かってない」と感じる場面も増えました。

この記事では、Claude Codeのプラグイン eli5 と crit を組み合わせて、コードを図にして、その図の分からない部分を直接指して質問する、という回し方に変えた話を書きます。片方だけでも便利なのですが、2つを組み合わせたときの効きが想像以上だったので、その組み合わせ方を中心に紹介させてください。

1. コードを読んで理解する時間が、いつのまにか無くなっていた

その感覚がはっきり強くなったのは、私が複数のプロジェクトを並行で進めるようになってからです。私がコードを読んで理解することに使える時間は、以前とは比べものにならないくらい減りました。手は動いているし成果も出ているのに、これは自分の身になっているのだろうか、と不安になることがしばしばあります。同じような感覚を持っている方も、いるのではないでしょうか。

原因は単純に自分の時間が足りていないことだと思っています。差分を読んで納得するまでにかかる時間は、以前と変わりません。そこに並行して動いているタスクとプロジェクトの数が乗るので、読む時間から先に削られていきます。

しかもAIが書く量が増えるほど、書かれたものを理解しておく必要は大きくなっているはずです。それなのに、実際に理解できている度合いは下がっている。この差が「理解の負債」として溜まっていきます。

削られた時間を取り戻すのは難しいので、短い時間で理解できる形に変えるほうに寄せることにしました。そうやって探して見つけたのが、次の2つの組み合わせです。

2. 結論:eli5で図にして、critで図に質問する

先に結論です。やっていることは2つだけです。

  1. eli5 に、理解したいコードやissueを「図で説明するHTML」にしてもらう
  2. crit でそのHTMLをブラウザに開き、図の分からない部分を直接指して質問する

実際の呼び出しは、こういう1行です。

/crit /eli5 このissueについて何が原因でどう対応するべきか、実装方法の比較も含めて教えて

この2つが噛み合うのは、出力と入力の形が揃っているからです。eli5が作るのはHTMLファイルで、critはHTMLファイルを開いてDOM要素単位でコメントを付けられます。だから「図のこの部分が分からない」が、そのまま質問として成立します。

言葉で説明を受けるのではなく、図を受け取って、図に質問して、図で返してもらう。私にとって一番大きかったのは、この変化でした。

ここから、2つの道具がそれぞれ何なのかを順に見ていきましょう。

3. eli5スキルとは?

eli5は、Claude Codeのプラグインとして配布されているスキルです。名前は「Explain Like I’m 5」から来ていて、なるべく図を使ったビジュアル解説にするのが特徴です。実際に読みやすい説明が返ってきます。本当に5歳児に分かるのかは怪しいところですが(笑)

導入は2コマンドで終わります。

/plugin marketplace add anthropics/claude-plugins-community
/plugin install eli5@claude-community

記事執筆時点のバージョンは1.0.0です。

3-1. 中身は実質3行

SKILL.md が1枚あるだけです。名前と説明を書くfrontmatterを除くと、中身は次の3行しかありません。

# eli5

Explain like I'm someone who knows nothing about this topic, using a HTML artifact with big pictures and few words.

Topic: $ARGUMENTS

(引用元: eli5 の SKILL.md。anthropics/claude-plugins-community)

1行目は見出しで、指示の本体は2行目の1文だけです。意訳すると「そのトピックを何も知らない人に向けて、大きな絵と少ない言葉でHTMLアーティファクトを作って説明する」になります。3行目の $ARGUMENTS には、/eli5 の後ろに書いた文字列がそのまま入ります。設定項目もオプションもなく、これだけです。

3-2. eli5自身を説明させてみる

どんな図が返ってくるのかを見るために、この記事で使う題材そのもの、つまりeli5自身を説明させてみました。打ったのはこの1行です。

/eli5 eli5について画面一枚分で教えて

出力はこうなります。

eli5を実行したターミナル。HTMLファイルを書き出し、ブラウザで開くよう促し、3コマ構成であることを説明している

やっているのはHTMLファイルの生成だけです。ターミナルには「ブラウザで開いてください」と表示され、実際の説明はそのHTMLの中にあります。開いてみると、こういう1枚が返ってきました。

eli5が生成したHTML。「わからない」「こう打つ」「絵で届く」の3コマと、いいところ・使いどころ・注意の補足が並んでいる

「わからない → こう打つ → 絵で届く」の3コマで、下段に「いいところ」「使いどころ」「注意」が並んでいます。文章で説明されるより先に構造が目に入るので、読む前に形が掴めます。

図の下に自分から注意書きを添えているのも、この出力の面白いところでした。「わざと省いて単純にしている。正確な仕様や細部が必要なときは、普通に質問するほうが向いている」と書かれています。ここは後で5-4に効いてきます。

3-3. eli5だけだと引っかかる2つのこと

説明そのものは分かりやすいのですが、使い始めてすぐに2つ引っかかりました。

  • 出力がHTMLファイルなので、開くのが地味に面倒。3-2のターミナルにも「ブラウザで開いてください」と出ているとおり、エディタのプレビューを開いたり、ローカルサーバーを立てたりする手間が毎回かかります
  • 図を見ていると「ここと、ここと、ここが聞きたい」と疑問が同時に複数出てきます。それをチャットに文章で書くのが難しく、しかも書けたとしても会話が脱線して、本来見たかった出力が上に流れていってしまいます

正直、2つ目のほうが困りました。図の中の位置を言葉で指す作業(「左下の四角から出ている矢印の……」)が挟まると、質問するコストが理解のコストを上回ってしまいます。

この2つを埋めるのが、次のcritです。

4. critとは?

critは、ブラウザでレビューコメントを付けて、それをそのままAIエージェントに渡すツールです。導入にはCLI本体とClaude Code側のプラグインの両方が必要です。

brew install crit                              # CLI本体
/plugin marketplace add tomasz-tomczyk/crit    # Claude Code側
/plugin install crit@crit

この記事の内容を確認したのは、CLIが0.18.4、プラグインが1.8.6です(記事執筆時点でのCLIの最新版は0.20.1でした)。番号の系統が別なので、crit --version の値とプラグインのバージョンは一致しません。 気づかないうちにCLIだけ何世代も古くなることがあるので、brew upgrade crit を時々かけておくのがおすすめです。

普段の使い方はレビューです。crit と打つとブラウザが開き、差分にコメントを書けます。GitHubのレビューをローカルでやる感覚に近いです。

4-1. HTMLは「DOM要素」で指してコメントできる

critで効くのは、コメントを付ける単位が対象によって変わるところです。コードや差分に対しては、GitHubのレビューと同じように行番号で指せます。ただ今回の使い方で本題になるのはもう一方で、HTMLを対象にすると、行番号ではなく画面の要素そのものを指してコメントできます。

3-2で作ったHTMLを、そのままcritに開いてもらいます。

/crit 上記を開いて

ブラウザが開き、ページの上をクリックすると要素が選択されてコメント欄が出ます。

critで開いたeli5の説明HTML。見出し下の1行が選択され、右のコメント欄に質問が書かれている

見出し下の1行を選んで、「それでもわからなかったらさらに追加の図とかで説明してくれますか?」と質問してみました。このとき渡っているのは行番号ではなく、選んだ要素そのものです。 図のどのブロックを選んだのかが要素として伝わるので、「この部分」という指し方が言葉を介さずに成立します。

4-2. 「Finish Review」でコメントがそのままClaude Codeに渡る

コメントを書き終えて右上の「Finish Review」を押したところが、個人的に一番気持ちよかったところです。

Finish Reviewを押した直後のダイアログ。Review Complete と表示され、Agent notified と書かれている

Agent notified、つまり書いたコメントがまとめてClaude Code側に自動で渡ります。 コメントをコピーして貼り直す作業も、「3箇所目のあれを直して」と言い直す作業も要りません。ここは初めて試したときに素直に驚きました。実際にClaude Code側を見ると、コメントを受け取ってHTMLを直し、次のラウンドを開くところまで進んでいます。

Claude Code側の画面。critのコメントを受け取ってHTMLに2行追加し、次のラウンドを開いたことが表示されている

そして、書いたコメントにはcrit側で返信が付きます。 次のラウンドを開くと、返信と一緒に直したHTMLがそのまま表示されます。

次のラウンドのcrit画面。コメントに返信が付き、図の下段に「おかわりできる」チップが増え、見出し下にも1行追加されている

下段に緑の「おかわりできる」が1枚増え、見出しの下にも「わからないところは、そこだけ聞き返せば絵が増える。」の1行が足されています。ブラウザ側でレビューを書くこととエージェントに指示を出すことが、同じ操作になっている状態です。

4-3. 出力の種類ごとにレビューUIが変わる

critには対象に応じたモードがあり、引数から自動で判別されます。

打つコマンド 何を見るか 指す単位
crit 現在のブランチの差分 行番号
crit <ファイル> そのファイル1枚 行番号
crit --pr <番号> GitHubのプルリクエスト 行番号
crit live <URL> 起動中のWebアプリ DOM要素
crit preview <HTMLファイル> HTMLをブラウザに表示 DOM要素

この表の最後の行が、eli5と組み合わせる部分です。

5. 組み合わせたことで何が変わったか

4章では、eli5に作らせたHTMLを別の指示でcritに開いてもらいました。この2手も1行にまとめられます。2章のコマンドを打つと、図を作るところからcritで開くところまでが1度の指示で通ります。

そのうえで、3-3で挙げた2つの引っかかりがどうなったかを順に書きます。

5-1. HTMLを開く手間が消える

1つ目の引っかかりは、そもそも操作が要らなくなることで消えました。エディタのプレビュー機能を探したり、ローカルサーバーを立てたり、ファイルをブラウザにドラッグしたりしていた手間がまとめてゼロになります。

地味な違いに見えますが、図を見るまでの距離が短くなると、図を見る回数そのものが増えます。ここは思っていたよりずっと効きました。

5-2. 「この図のここ」を指して質問できる

2つ目の引っかかり、つまり深刻だったほうがここです。図の中の分からないブロックを選んでコメントすると、選んだ要素そのものが質問に添えられます。

4-1で投げた「それでもわからなかったらさらに追加の図とかで説明してくれますか?」がまさにそれです。テキストで同じことを聞くなら「見出しのすぐ下にある、スキルの説明をしている1行について……」という前置きが必要になります。critだと前置きが要りません。指せば伝わるので、疑問が浮かんだ形のまま投げられます。

そして返ってくるのが図だという点も大きいです。4-2に載せた画面がまさにそれで、この質問への答えは文章ではなく元の図の更新として返ってきました。質問した図の隣に答えが生えてくるので、テキストで長い説明を読み直す代わりに、増えた部分だけを見れば済みます。

ファイルが書き換わるとcritのライブリロードでブラウザに即反映されるため、この間にこちらがやったことは「指してコメントする」「Finish Reviewを押す」の2つだけです。

5-3. 質問でチャットが脱線しない

3-3に書いた「会話が脱線して本来見たかった出力が流れる」問題も、これで消えました。質問と回答のやりとりがcrit側のコメントに載るので、Claude Codeのセッションには実装のやりとりだけが残ります。

理解のための質問は、後から読み返したい種類の記録ではありません。それが実装の流れに混ざると、遡るときに邪魔になります。質問は図の横に、実装のやりとりはセッションに、という分担ができました。

5-4. 図をうのみにはしない

ここまで良かった点を並べてきましたが、1つだけ気をつけていることがあります。eli5が出すのは「腹落ちするための図」であって、仕様書ではありません。

これはこちらの推測ではなく、eli5の出力自身がそう書いています。 3-2の図の右下にある注意書きです。

注意 わざと省いて単純にしている。正確な仕様や細部が必要なときは、普通に質問するほうが向いている。 (引用元: eli5 が生成したHTMLの注記)

条件分岐やエラー処理は、図では1本の矢印に丸められることがあります。そのため、少しでも引っかかるところが残っていたら、納得するまで何度でも質問と指摘を繰り返すようにしています。5-2のように聞き返せば図が増えるので、分からないまま先に進むより早いです。図を見て分かった気になったまま次に行かないことだけを守る、というルールです。

6. 決済Webhookのコードでやってみる

ここまではeli5自身を題材にしてきたので、最後にコードで通しておきます。使うのは、この記事のために書いた決済Webhookのワーカーです。約120行、外部ライブラリなしで、持っている仕事は3つだけです。

  • 同じイベントが2回届いても1回しか決済しない(冪等性)
  • 一時的な失敗はバックオフしながら3回までリトライする
  • リトライを使い切ったイベントはデッドレターに退避する

動かすとこうなります。再送された evt_001 が無視され、金額が負の evt_003 が退避されています。

受信: evt_001
  決済しました: order=ord_1001 amount=12000
受信: evt_002
  決済しました: order=ord_1002 amount=3500
受信: evt_001
  すでに処理済みなので無視します: evt_001
受信: evt_003
  リトライしても直らない失敗: 金額が不正です: -100

処理済み: 3件 / 退避: 1件

6-1. 状態遷移とリトライを図にしてもらう

打つのは2章と同じ1行です。

/crit /eli5 webhook_worker.py の状態遷移とリトライの流れを画面一枚分で教えて

返ってきたのがこの1枚です。

eli5が生成したwebhookワーカーの解説。3コマの流れ、4つの状態、待ち時間が倍になるリトライ、道が分かれる2箇所、まとめのチップが並んでいる

PENDING から PROCESSING を通って DONE か DEAD に落ちる一方通行、待ち時間が0.5秒→1.0秒と倍になっていくリトライ、道が分かれる2箇所。コードを1行も読まないうちに、構造のほうが先に頭に入ります。 これは素直に助かります。

6-2. 図を並べたことで出てきた疑問

引っかかったのは、離れた場所にある2つの説明でした。片方は状態の説明に付いていた1文です。

手を付ける前に PROCESSING を書いて保存するので、途中で落ちても「触った跡」は残ります。 (引用元: eli5 が生成したHTMLの記述)

もう片方は、道が分かれるところの説明です。

札が DONE なら、何もせず「すでに処理済み」と返します。 (引用元: eli5 が生成したHTMLの記述)

跡は残しているのに、入口で見ているのは DONE だけです。PROCESSING のまま落ちたイベントが再送されてきたら、入口を素通りしてもう一度決済に進むのではないか、という疑問になります。

該当箇所を指してcritで聞き、コードに戻って確認したのがここでした。

def already_done(self, event_id: str) -> bool:
    event = self.processed.get(event_id)
    return event is not None and event.status is Status.DONE

確かに DONE しか見ていません。落ちた処理の跡は保存されているのに、その跡を使う側がいない状態です。

6-3. 図が間違っていたわけではない

ここで大事なのは、図はどちらの説明も正しかったことです。「跡は残る」も「DONE なら無視する」も、コードのとおりです。ただ、この2つを突き合わせると穴になる、という一段先までは書かれていませんでした。

5-4に書いた「引っかかったところは納得するまで聞く」が要るのはこういう場面です。図は構造を先に渡してくれますが、書かれていないことは図を眺めても出てきません。 出てくるのは、図を見て「あれ?」と思った側が指して聞いたときです。

7. おまけ:呼び出しをまとめて、ループにする

ここまでの話は2章の1行だけで回りますが、毎回同じ書き方を思い出すのも、下に挙げる決まりごとを毎回添えるのも面倒になってきました。そこで /teach という自作スキルにまとめています。

呼び出しはこうなります。

/teach webhook_worker.py の状態遷移とリトライの流れ

やっていることは次のループです。

/teachのループ図。理解したいコードをeli5で図にし、crit previewで表示し、図にピンを立てて質問し、疑問に答える図をHTMLに追加してライブリロードで反映する流れ

SKILL.md の要点は以下です。

  • eli5の出力をディスク上のHTMLファイルとして必ず残す(~/.claude 配下の決まった場所に保存する)。critに渡すため
  • HTMLを自己完結させる(CSSやSVGはインライン、CDNに依存しない)。critはこのファイルをそのまま配信するため
  • 説明の単位でブロックを分けて、意味のある id を付ける。critのピンはCSSセレクタで要素を掴むので、1枚の巨大な要素にすると質問の精度が落ちる
  • コメントの位置はDOMアンカーで特定する(行番号は当てにしない)。プレビューは仮想パスに紐づくため、HTMLソースの行とは対応しない
  • 返信するときに --resolve を付けない。解決したかどうかを決めるのは質問した人なので

このループで一番気に入っているのは、疑問に答えるときに文章を足すのではなく、図を足すという部分です。ここは何度やっても楽しいところです。ファイルを書き換えるとcritのライブリロードでブラウザに即反映されるので、質問した図の隣に答えの図が生えてくるような見え方になります。

止め方も自分で決めなくて済みます。コメントを1件も付けずに「Finish Review」を押すと、それは承認扱いになり、ループは勝手に止まります。 逆に1件でも書けば、それがそのままClaude Codeに渡って次のラウンドが始まります。分からないところが残っているかどうかだけを見ていれば、進むか止まるかは向こうが判断してくれる形です。

「分かった」の判定が自分の手元にあるのも、この形にしてよかった点です。理解できたかどうかを決めるのは説明した側ではなく、説明を受けた側なので。

まとめ

この記事の要点です。

  • eli5 は「大きな絵と少ない言葉」でHTMLの解説を作るスキル。中身は SKILL.md 1枚、実質3行
  • crit はブラウザでレビューコメントを付けてエージェントに渡すツール。HTMLはDOM要素で指せるうえ、「Finish Review」を押すとコメントがそのままClaude Codeに渡る
  • eli5の出力がHTMLで、critがHTMLをDOM要素単位で指せるので、「図のここが分からない」がそのまま質問になる。答えも図の更新として返ってくるし、質問がチャットを脱線させることもない
  • /crit /eli5 <聞きたいこと> の1行で回せる。決まりごとを固定したいなら /teach のような自作スキルにまとめられる
  • ただし図は単純化されるので、気になったところは納得するまで質問と指摘を繰り返す

AIが書く量が増えるほど、「動いているが説明できない」コードは増えていきます。理解の負債を増やさない方法として、図にして図に質問するという回し方は、想像以上に効きました。使い始めてからは、コードを読む前にまず図を出すのが癖になっています。

導入も2コマンドずつなので、気軽に試せます。まずは手元の分かりにくいファイル1枚を選んで、/crit /eli5 このファイルが何をしているか教えて と打ってみてください。「このコード、実はよく分かってない」が少しでも減ったら嬉しいです。

参考サイト

eli5 / crit

Claude Code のプラグインとスキル

山下
著者:山下
目指せAIマスター

エンジニア積極採用中!

クラウドセントリックでは、業務拡大に伴いエンジニアを積極採用中です。
一緒に働きたいと思った方は、採用フォームからぜひご応募ください。
MENU