mcpField
O
overllm

overllm

ローカル
github.com/theadamdanielsson開発ツール317 週間前に更新

overllm について

overllmは、Python、JavaScript、TypeScriptのコードから不要または設定に問題のあるLLM呼び出しを検出する静的解析ツールです。MCPサーバー経由でファイルやコード片をスキャンし、具体的な代替案を示します。

主な機能

  1. 01通常のコードで代替できる呼び出しを検出
  2. 02ループ内呼び出しとプロンプトインジェクションを検出
  3. 03モデルIDとパラメーター設定を確認
  4. 04ベースライン、修正、複数の出力形式に対応
  5. 05モデル呼び出しやコード送信なしでローカル解析

活用シーン

  1. 01コミットやCIチェックで問題を検出
  2. 02プロジェクト内の不要なLLM呼び出しを確認
  3. 03MCP経由でファイルやコード片をスキャン

MCP 対応

MCPサーバーは、ディスク上のファイルやディレクトリ用のscan_pathと、インラインコード用のscan_codeを公開します。コードを変更せず、ルール、位置、代替案を返します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"theadamdanielsson-overllm": {
"command": "uvx",
"args": [
"overllm"
]
}
}
}
起動コマンドuvx overllm

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypioverllm0.7.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

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-mechanicalerrorプロンプトが機械的な変換(ソート、逆順、カウント、合計、重複排除、大文字・小文字の変換、base64、リテラル値の算術演算)を求めている場合。標準ライブラリを使った1行の代替コード
llm-extractionerrorプロンプトがモデルにメールアドレス、URL、日付、数値の抽出を求めている場合。正規表現、datetime、または urllib.parse
prompt-injectionerror信頼できないウェブリクエストの入力(request.args、request.json など)がそのままプロンプトに渡されている場合。別のユーザーメッセージに分け、入力を検証し、モデルの動作を制約する
llm-in-loopwarningループの反復ごとに LLM が呼び出される場合(ストリーミングではなく、実際に N 回呼び出される場合)。まとめて処理する、キャッシュする、またはループの外に移動する
deprecated-modelerror / warningmodel の ID が廃止済みのモデル(呼び出しが404になる)か、非推奨となり削除が予定されているモデルの場合。指定されている現行モデルに切り替える
unsupported-paramswarningモデルが受け付けない temperature / top_p / top_k が設定されている場合 — OpenAI の reasoning(o1、o3 など)シリーズと最新の Anthropic モデル。パラメーターを削除し、代わりにプロンプトでモデルの動作を調整する
json-mode-missing-jsonerrorresponse_format={"type": "json_object"} が設定されているのに、完全に静的なプロンプトに「json」という語が含まれていない場合 — OpenAI で必ず400エラーになります。メッセージに「json」を追加するか、json_schema 形式を使う
static-promptinfoユーザープロンプトがコンパイル時定数で、変数がない場合。入力が固定されているため、呼び出しに意味がありません。結果を事前計算するか、キャッシュする

最後の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

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。