overllm について
overllmは、Python、JavaScript、TypeScriptのコードから不要または設定に問題のあるLLM呼び出しを検出する静的解析ツールです。MCPサーバー経由でファイルやコード片をスキャンし、具体的な代替案を示します。
主な機能
- 01通常のコードで代替できる呼び出しを検出
- 02ループ内呼び出しとプロンプトインジェクションを検出
- 03モデルIDとパラメーター設定を確認
- 04ベースライン、修正、複数の出力形式に対応
- 05モデル呼び出しやコード送信なしでローカル解析
活用シーン
- 01コミットやCIチェックで問題を検出
- 02プロジェクト内の不要なLLM呼び出しを確認
- 03MCP経由でファイルやコード片をスキャン
MCP 対応
MCPサーバーは、ディスク上のファイルやディレクトリ用のscan_pathと、インラインコード用のscan_codeを公開します。コードを変更せず、ルール、位置、代替案を返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
overllm
不要な LLM/AI 呼び出しを見つけましょう。
overllm は、コード内で、普通のコードのほうがうまく処理できるタスクに AI モデルを呼び出している箇所を見つけることに特化した、小さく高速なリンターです。日付を解析するために GPT を呼び出したり、json.loads で処理できる JSON の抽出にモデルを使ったりしていませんか。正規表現で済む処理のために、遅延や費用、非決定性を受け入れているのです。
コードの解析には本物のパーサーを使います。Python には標準ライブラリの ast を、JavaScript と TypeScript には tree-sitter を使用します。モデルの実行も、ネットワークへの接続も、API キーも不要です。同じコードを入力すれば、同じ結果が返ります。プリコミットフックでも十分に高速です。
コストダッシュボードやキャッシュが扱うのは、すでに実行すると決めた呼び出しです。overllm はその前に、「そもそも呼び出す必要があったのか」と問いかけ、何かを実行する前にソースコードから答えを導きます。ほかのツールが AI の書いたコードを lint するのに対し、overllm はライブラリですでにできることに AI を使い、費用をかけている箇所を見つけます。
インストール
pip install overllm # Python
pip install "overllm[js]" # adds JavaScript / TypeScript support
使い方
すべてのコードに対して実行する前に、まずは 1 つのファイルを指定して、どのような指摘が出るか確認しましょう。
overllm app.py # one file
overllm src/ # a folder
overllm . # the whole project
コードを読み取り、見つかった内容を表示します。デフォルトでは何も書き込まず、何も変更しません。通常の実行で最悪の場合に起きるのは、数行の出力だけです。ファイルを編集する唯一のモードは、オプトインの --fix(下記参照)で、機械的に安全な 2 種類の修正だけを行います。
出力例:
app.py:42:5 llm-mechanical LLM call asks the model to sort
resp = client.chat.completions.create(model="gpt-4o", messages=[...])
-> use sorted()
app.py:88:1 llm-in-loop LLM call inside a loop: one API round-trip per iteration
completion(model="gpt-4o", messages=[{"role": "user", "content": f"tag {x}"}])
-> batch the inputs into a single call, cache repeated results, or use a function
2 needless LLM calls in 1 file.
デフォルトでは、出力は控えめです。warning と error の指摘のみが表示されるため、問題のないプロジェクトでは何も出力されず、終了コードは 0 です。ほとんどのコードベースで指摘されるのは、少数か、まったくありません。大量に表示される場合は不具合として、issue を作成してください。
overllm は何かを見つけると、0 以外の終了コードを返すため、コミットや CI チェックのゲートとして使えます。失敗させずに結果を報告するには、--exit-zero を渡してください。
コードは手元に残ります
overllm は静的解析ツールです。ファイルをローカルで解析し、見つかった内容を表示します。コードをアップロードすることも、API を呼び出すこともなく、キーも不要です。テレメトリも送信しません。処理にモデルは関与せず、外部に情報を送ることもありません。ネットワークケーブルを抜いても、まったく同じように動作します。
コア部分は Python 数千行ほどで、必須の依存関係はありません。そのため、信頼する前に全コードを読むことができます。overllm[js] を使うと、JavaScript と TypeScript の解析に tree-sitter が追加されます。これは唯一のオプションの依存関係です。
ルール
各ルールは具体的なコードパターンにのみ適用され、検出結果には決定的な置き換え方法が示されます。確信がない場合は何も報告しません。
デフォルトでは、overllm は warning 以上のみを報告するため、日常的なコードでは静かです。static-prompt は info で、--all または --min-severity info を指定しない限り報告されません。
| ルール | 重大度 | 適用される条件 | 提案 |
|---|---|---|---|
llm-mechanical | error | プロンプトが機械的な変換(ソート、逆順、カウント、合計、重複排除、大文字・小文字の変換、base64、リテラル値の算術演算)を求めている場合。 | 標準ライブラリを使った1行の代替コード |
llm-extraction | error | プロンプトがモデルにメールアドレス、URL、日付、数値の抽出を求めている場合。 | 正規表現、datetime、または urllib.parse |
prompt-injection | error | 信頼できないウェブリクエストの入力(request.args、request.json など)がそのままプロンプトに渡されている場合。 | 別のユーザーメッセージに分け、入力を検証し、モデルの動作を制約する |
llm-in-loop | warning | ループの反復ごとに LLM が呼び出される場合(ストリーミングではなく、実際に N 回呼び出される場合)。 | まとめて処理する、キャッシュする、またはループの外に移動する |
deprecated-model | error / warning | model の ID が廃止済みのモデル(呼び出しが404になる)か、非推奨となり削除が予定されているモデルの場合。 | 指定されている現行モデルに切り替える |
unsupported-params | warning | モデルが受け付けない temperature / top_p / top_k が設定されている場合 — OpenAI の reasoning(o1、o3 など)シリーズと最新の Anthropic モデル。 | パラメーターを削除し、代わりにプロンプトでモデルの動作を調整する |
json-mode-missing-json | error | response_format={"type": "json_object"} が設定されているのに、完全に静的なプロンプトに「json」という語が含まれていない場合 — OpenAI で必ず400エラーになります。 | メッセージに「json」を追加するか、json_schema 形式を使う |
static-prompt | info | ユーザープロンプトがコンパイル時定数で、変数がない場合。入力が固定されているため、呼び出しに意味がありません。 | 結果を事前計算するか、キャッシュする |
最後の2つはプロンプトではなく、呼び出し自体を確認します。存在しなくなったモデル ID、またはモデルが無視するパラメーターが対象です。どちらも既知のリストと厳密に照合するため、現行のモデルやエイリアスが誤検出されることはありません。リストはプロバイダーの非推奨モデルに関するページを追跡しており、随時更新が必要です。
Python の OpenAI、Anthropic、Google、Mistral、Cohere、Groq、AWS Bedrock、HuggingFace、Replicate、LangChain、LiteLLM、Ollama の SDK、JavaScript と TypeScript の Vercel AI SDK(generateText、streamText、generateObject)および openai / anthropic の Node SDK、さらにこれらのホストへの生の HTTP リクエストを検出します。また、LCEL 合成を通じたモデルの追跡にも対応しています。chain = prompt | model | parser のパイプ、バインドされたモデル(.with_structured_output(...))、エイリアスを追跡するため、chain.invoke(...) も検出されます。embeddings の呼び出し(embeddings.create)も対象です。独自のラッパーや overllm が確認できないフレームワーク経由で呼び出す場合は、llm_calls(下記)に名前を指定してください。
誤検出を無視する
resp = client.chat.completions.create(...) # overllm: ignore
resp = client.chat.completions.create(...) # overllm: ignore=llm-in-loop
ファイルの先頭に # overllm: ignore-file を記述すると、ファイル全体がスキップされます。
設定
(Python 3.11 以降)の pyproject.toml で設定します。
[tool.overllm]
ignore = ["llm-in-loop"]
exclude = ["examples/", "migrations/"]
llm_calls = ["myapp.llm.ask", "chat_service.complete"]
またはコマンドラインで、--select、--ignore、--min-severity、--all、--config PATH を指定できます(exclude は設定ファイルでのみ指定できます)。すべてのオプションについては、overllm --help を実行してください。
独自のラッパーを overllm に認識させる
多くのコードでは SDK を直接呼び出さず、ラッパーを介します(def ask(prompt): client.chat.completions.create(...))。overllm は、そのラッパーが同じファイル内にあれば自動的に追跡します。フレームワーク、プロバイダーレイヤー、または **kwargs の展開を経由する場合、overllm は SDK の呼び出しを確認できないため、llm_calls にラッパー名を指定してください。設定後は、ask(...) の呼び出しが LLM 呼び出しとして扱われます。プロンプト引数を読み取り、ループとコストのルールを適用します。名前は、修飾なしの名前(ask)、ドット区切りの名前(myapp.llm.ask)、またはそのドット区切りのパスを短い名前でインポートしたものに一致します。
既存のコードベースに導入する(ベースライン)
古いリポジトリに overllm を導入すると、対処しきれないほど大量の検出結果が出てしまいます。一度スナップショットを作成すれば、CI ではそれ以降に新たに発生した問題だけを検出できます。
overllm . --write-baseline # writes overllm-baseline.json — commit it
overllm . --baseline # reports only findings new since the snapshot
overllm . --update-baseline # ratchet: also drop entries you've since fixed
スナップショットでは、各検出結果を行番号ではなくルール+ファイル+コード+モデルで識別するため、その上の無関係な部分を編集しても無効になりません。また、単純に合計数を比較するのではなく、それぞれの検出結果が何回出現したかを数えるため、別の場所で古い問題を削除していたとしても、新たな問題のある呼び出しがあればチェックに失敗します。
安全な修正を適用する(--fix)
2 つのルールには明確な修正方法が 1 つずつあるため、overllm が自動で適用できます。
overllm . --fix # drop a sampling param the model rejects (safe)
overllm . --fix --unsafe-fixes # also swap a retired model id for its replacement
overllm . --fix --diff # print the patch, don't touch anything
--fix を指定しただけの場合、安全な修正(unsupported-params)のみが適用されます。モデル ID の変更は実行時にコードが実際に行う処理を変えるため、--unsafe-fixes を指定した場合にのみ適用されます。修正は生のテキストではなく構文木を編集するため、コメントや文字列には手を加えません。また、保存前に overllm がファイルを再解析し、編集によって問題が発生する場合は変更を破棄します。残りの 5 つのルールには人間による判断が必要なため、変更されることはありません。
pre-commit フック
.pre-commit-config.yaml に次を記述します。
repos:
- repo: https://github.com/theadamdanielsson/overllm
rev: v0.6.0
hooks:
- id: overllm
GitHub Action
overllm には、プルリクエストをスキャンして、根拠に基づいたコメントを 1 件投稿する Action が付属しています。指摘事項がない場合は、何も通知しません。
name: overllm
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: theadamdanielsson/overllm@v1
with:
paths: "."
その他の出力形式
overllm --format json . # machine-readable
overllm --format sarif . # upload to GitHub code scanning
overllm --format github . # GitHub Actions inline annotations
overllm --format markdown . # the PR-comment body
GitHub コードスキャン(SARIF)
overllm は SARIF を出力できるため、検出結果が Security タブと差分のインラインに表示されます。パブリックリポジトリでは無料で利用できます。
name: overllm-scan
on: [push, pull_request]
permissions:
contents: read
security-events: write # required to upload results
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pipx run overllm . --format sarif --exit-zero > overllm.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: overllm.sarif
category: overllm
エージェントから利用する(MCP サーバー)
overllm には MCP サーバーが付属しているため、AI エージェント(Claude Desktop、Cursor、または MCP に対応するもの)から呼び出して、不要なモデル呼び出しがないかコードを監査できます。2 つのツールを公開しています。scan_path(ディスク上のファイルまたはディレクトリ)と scan_code(インラインで渡すコードスニペット)です。どちらも CLI と同じ検出結果(ルール、場所、具体的な置き換え内容)を返し、ファイルへの書き込みや変更は行いません。
サーバー版をインストールし、クライアントから接続してください(サーバーには Python 3.10 以降が必要ですが、リンター自体は引き続き 3.9 で動作します)。
pip install "overllm[mcp]"
{
"mcpServers": {
"overllm": {
"command": "uvx",
"args": ["--from", "overllm[mcp]", "overllm-mcp"]
}
}
}
その後、エージェントに「このリポジトリをスキャンして、不要な LLM 呼び出しを探して」や「この関数はモデル呼び出しを無駄にしていませんか?」といった質問をすると、推測ではなく、根拠に基づいた再現可能な検出結果が得られます。
AI コードレビュアーだけではだめなのですか?
AI レビュアーや AI スロップを検出するリンターが調べるのは、モデルが生成したコード、つまりコメント、デッドコード、構造などです。overllm が問う「そもそもモデルが必要だったのか」という問いを投げかけるものはありません。これは別の観点であり、単純な静的解析で高い精度とコストゼロで答えられます。
貢献
最も役立つのは、誤検出の報告です。つまり、overllm が呼び出しにフラグを立てるべきではない実際のコード行です。リンターは正しくなければ実行する価値がないため、具体的な誤検出 1 件は機能リクエストよりも価値があります。CONTRIBUTING.md では、報告方法とテストの実行方法を説明しています。
過去のリリースと変更内容については、CHANGELOG.md をご覧ください。
ライセンス
MIT © Adam Danielsson
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。