mcpField
O
overllm

overllm

本地服务
github.com/theadamdanielsson开发工具317 周前更新

关于 overllm

overllm 是用于 Python、JavaScript 和 TypeScript 的静态分析工具,可发现代码中不必要或配置错误的 LLM 调用。它也提供 MCP 服务,让 Agent 扫描文件或代码片段,并给出具体替代方案。

主要功能

  1. 01识别可由普通代码替代的模型调用
  2. 02检测循环调用及提示词注入风险
  3. 03检查模型 ID 与参数配置
  4. 04支持基线、修复和多种输出格式
  5. 05本地分析,不调用模型或上传代码

适用场景

  1. 01在提交或 CI 检查中拦截问题
  2. 02审查项目中的不必要 LLM 调用
  3. 03通过 MCP 扫描文件或代码片段

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 写出的代码;overllm 则会找出你在哪些地方花钱让 AI 做库已经能做的事。

安装

pip install overllm          # Python
pip install "overllm[js]"    # adds JavaScript / TypeScript support

使用

先对单个文件运行,看看它会标出什么,再对所有文件运行:

overllm app.py       # one file
overllm src/         # a folder
overllm .            # the whole project

它会读取你的代码并打印发现的问题。默认情况下,它不会写入或修改任何内容——直接运行最坏也只会输出几行内容。唯一会编辑文件的模式是选择启用的 --fix(见下文),且仅适用于两种机械式安全修复。

示例输出:

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 退出——大多数代码库只会发现少数问题,甚至没有问题。如果它输出过多,请将其视为 bug 并提交问题。

overllm 发现问题时会以非零状态退出,因此可以用来拦截提交或 CI 检查。传入 --exit-zero 即可只报告问题而不导致失败。

你的代码会留在自己的设备上

overllm 是静态分析工具。它会在本地解析文件,然后打印发现的问题。它绝不会上传你的代码、调用 API、索要密钥或发送遥测数据——整个过程中没有模型参与,也不会向外发送任何数据。拔掉网线,它的运行结果也完全一样。

核心部分只有几千行 Python 代码,没有必需的依赖项,因此你可以先通读全部代码,再决定是否信任它。overllm[js] 会添加用于解析 JavaScript 和 TypeScript 的 tree-sitter;这是唯一的可选依赖项。

规则

每条规则只会在遇到明确的代码模式时触发,并且每条发现都会给出确定的替代方案。无法确定时,它会保持沉默。

默认情况下,overllm 只会报告 warning 及以上级别,因此不会打扰日常编码。static-prompt 的级别是 info,除非你通过 --all 或 --min-severity info 请求检查,否则它会保持沉默。

规则严重级别触发条件建议
llm-mechanicalerror提示词要求进行机械式转换:排序、反转、计数、求和、去重、大小写转换、base64、对字面量进行算术运算。一行标准库等效代码
llm-extractionerror提示词要求模型提取电子邮件地址、URL、日期或数字。正则表达式、datetime 或 urllib.parse
prompt-injectionerror不可信的 Web 请求输入(request.args、request.json 等)直接流入提示词。将其放在单独的用户消息中,验证输入,并限制模型
llm-in-loopwarning每次循环迭代都会运行一次大模型调用(实际调用 N 次,不是流式传输)。批处理、缓存,或将调用移出循环
deprecated-modelerror / warningmodel ID 是已退役的模型(调用会返回 404),或已弃用且计划移除的模型。切换到它所指出的当前模型
unsupported-paramswarning在不支持这些参数的模型上设置了 temperature / top_p / top_k——OpenAI 推理系列(o1、o3 等)以及最新的 Anthropic 模型。移除该参数,改用提示词引导
json-mode-missing-jsonerror设置了 response_format={"type": "json_object"},但完全静态的提示词从未包含单词 "json"——这必定会导致 OpenAI 返回 400。在消息中加入 "json",或使用 json_schema 格式
static-promptinfo用户提示词是编译时常量,不含变量。输入固定不变,因此这次调用没有收益。预先计算或缓存结果

最后两条规则检查的是调用本身,而不是提示词:模型 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.create)也会计入。如果调用经过自定义封装或 overllm 无法识别的框架,请在 llm_calls(见下文)中为其命名。

忽略误报

resp = client.chat.completions.create(...)  # overllm: ignore
resp = client.chat.completions.create(...)  # overllm: ignore=llm-in-loop

在文件顶部添加 # overllm: ignore-file,即可跳过整个文件。

配置

在 pyproject.toml 中(Python 3.11+):

[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(...) 调用会被视为大模型调用——overllm 会读取提示词参数,并运行循环和成本规则。名称可以是简单名称(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)

其中两条规则各自都有一个明确的修复方案,因此 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 会在保存前重新解析文件,如果编辑会导致解析失败,就会放弃此次修改。其余五条规则需要人工判断,因此 overllm 不会修改它们。

Pre-commit 钩子

在 .pre-commit-config.yaml 中:

repos:
  - repo: https://github.com/theadamdanielsson/overllm
    rev: v0.6.0
    hooks:
      - id: overllm

GitHub Action

overllm 提供一个 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

从 Agent 使用(MCP 服务)

overllm 提供 MCP 服务,因此 AI Agent(Claude Desktop、Cursor 或任何支持 MCP 的工具)都可以调用它,检查代码中不必要的模型调用。它提供两个工具:scan_path(磁盘上的文件或目录)和 scan_code(以内联方式传入的代码片段)。两者都会返回与 CLI 相同的问题,包括规则、位置和具体的替代方案,并且都不会写入或更改任何内容。

安装服务版本并将客户端指向它(服务需要 Python 3.10+;检查器本身仍可在 3.9 上运行):

pip install "overllm[mcp]"
{
  "mcpServers": {
    "overllm": {
      "command": "uvx",
      "args": ["--from", "overllm[mcp]", "overllm-mcp"]
    }
  }
}

然后向 Agent 提出类似“扫描此仓库,找出不必要的大模型调用”或“这个函数是不是浪费了一次模型调用?”的问题,它就会给出有依据、确定的检查结果,而不是猜测。

为什么不直接使用 AI 代码审查工具?

AI 审查工具和 AI 代码垃圾检查器关注的是模型生成的代码:注释、死代码和结构。它们都不会提出 overllm 关注的问题:是否根本不需要调用模型。这是一个不同的维度,而普通静态分析就能以很高的准确率、零成本回答这个问题。

贡献

你最能帮上忙的是报告误报:提供一行真实代码,说明 overllm 错误标记了不该标记的调用。只有结果准确,检查器才值得使用,因此一个具体的错误标记比功能请求更有价值。CONTRIBUTING.md 介绍了如何报告误报以及如何运行测试。

以往的版本发布记录和变更内容见 CHANGELOG.md。

许可证

MIT © Adam Danielsson

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。