关于 Proven
Proven 是面向使用 AI 生成代码的团队的 Python 检查工具。它依据规则检查导入、调用、事实来源、模型输出验证、错误处理和测试,并可通过 MCP 向 AI Agent 提供检查结果。
主要功能
- 01依据 requirements 和已安装包检查导入
- 02标记不存在的调用及手写事实
- 03追踪模型输出是否经过验证
- 04检测被忽略的错误及缺失或无效测试
- 05支持命令行、pre-commit、GitHub Actions 和 MCP 服务
适用场景
- 01合并前审查 AI 生成的 Python 代码
- 02检查代码中的过时或无来源事实
- 03向 AI Agent 提供可执行的代码审查结果
MCP 相关
Proven 向 MCP 客户端提供 `proven_check`、`proven_explain` 和 `proven_rules` 工具,供 AI Agent 运行检查并了解规则。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 5 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 项目文件夹(其中包含 proven.toml)或单个文件的绝对路径。 |
| files | array | 否 | 可选:仅检查这些文件或文件夹;路径可为绝对路径或相对于项目根目录的路径。 |
详细介绍
Proven
用于评判 AI 编写代码的工具。 语法就是普通的 Python。规则专门针对幻觉。
核心原则:未经证明,一切皆不存在。 如果某个软件包已固定在 requirements 中,它就存在。如果某个函数包含在已安装版本中,它就存在。如果某个事实有来源和日期,它就存在。模型的回答通过检查后,才算真正提供给用户。函数通过测试证明可用,才算可用。
为什么
AI 模型编写的代码多到人们根本读不过来。获胜的语言,是那些编译器能充当审查者的语言:TypeScript 在 2025 年成为 GitHub 上最受欢迎的语言(GitHub Octoverse 2025),GitHub 将此归因于类型语言让 AI 辅助编写的代码更可靠。答案不是发明一种新语言——模型对新语言几乎一无所知。真正有帮助的是模型最熟悉的老语言,再加上一个严格的评判工具。TypeScript 正是以这种方式在 JavaScript 之上发展起来的。
Proven 为 Python 做了同样的事,但它捕捉的是幻觉,而不是类型错误。
六条规则
| 代码 | 规则 | 能捕捉的问题 |
|---|---|---|
| P1 | 导入真实存在 | 虚构的软件包、未固定的版本、未安装的模块 |
| P2 | 调用真实存在 | 并不存在的函数、类、属性和模块 |
| P3 | 不从记忆中获取事实 | 手动写进代码中的官方数据、税率、法律条款编号和 URL;过时的事实 |
| P4 | 模型输出经过验证 | 模型的回答未经检查就发给用户或写入数据库;伪造的检查 |
| P5 | 不吞掉错误 | 裸 except、无声的 except: pass |
| P6 | 函数经过测试证明 | 没有测试的公共函数;什么都没检查的测试 |
每条规则的详细说明:SPEC.md。
效果示例
examples/bad/bot.py 中的代码展示了无人检查时 AI 模型会写出什么——一个面向哈萨克斯坦的法律问答机器人:
import anthropik # a typo
MRP = 3932 # Kazakhstan's monthly index, the 2025 value "from memory"
def handle(phone, question):
raw = llm(question)
answer = f"{raw}\n\nLegal basis: Article 46 of the Labour Code"
try:
json.loadz(answer)
except:
pass
send(phone, answer)
评判工具:
$ python proven.py check examples/bad
Proven 0.2.0 · root: /path/to/proven/examples · python: /usr/bin/python3 3.12.3 · requirements: requirements.txt · packages from: the judge's own
bad/bot.py:4:1 P1 package "anthropik" is not in requirements.txt — it may be invented
bad/bot.py:5:1 P1 version of "requests" is not pinned with == (now: ">=2.31")
bad/bot.py:7:1 P3 "MRP" is a number typed from memory — it needs a dated source
bad/bot.py:9:10 P3 address "adilet.zan.kz" typed by hand — move it to a config or allowed_url_hosts
bad/bot.py:12:1 P6 function "llm" is not called in any test
bad/bot.py:16:5 P4 public function "llm" returns unverified model output — annotate it "-> Unverified" or return verify(...)
bad/bot.py:19:1 P6 function "send" is not called in any test
bad/bot.py:23:1 P6 function "handle" is not called in any test
bad/bot.py:25:14 P3 law article number typed by hand: "Article 46" — take it from the database
bad/bot.py:27:9 P2 module "json" has no name "loadz"
bad/bot.py:28:5 P5 bare except catches everything, even Ctrl+C and program exit
bad/bot.py:30:5 P4 unverified model output goes into "send"
How to fix:
P1 Imports are real — Check the exact package name on PyPI, add a name==version line ...
...
Proven: 12 issue(s) in 1 file(s). Code rejected.
按规则修正后的同一个机器人——examples/good/bot.py:
MRP = Fact(4325, source='Law of the Republic of Kazakhstan "On the Republican Budget '
'for 2026–2028" No. 239-VIII',
date="2026-01-01")
def ask_model(question, llm) -> Unverified:
return unverified(llm(question))
def answer(question, llm, checker, send):
raw = ask_model(question, llm)
send(verify(raw, checker)) # the user only gets what has been verified
$ python proven.py check examples/good
Proven: no issues. Code accepted.
快速开始
Python 3.11+。无依赖——仅使用标准库。
pip install proven-judge # the package is "proven-judge", the command is "proven"
proven init # create proven.toml
proven check # check the project
退出代码:0 表示代码通过,1 表示存在问题。供机器使用时,可指定 --json。
proven rules # list the rules
proven explain P4 # explain a rule
在代码中,使用 from proven_types import Fact, Unverified, unverified, verify,并将 proven-judge==0.2.0 添加到 requirements.txt(P1 规则也适用于 Proven)。
完全无需安装:将 proven.py 和 proven_types.py 复制到项目中,然后运行 python proven.py check。
pre-commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/malikabyl/proven
rev: v0.2.0
hooks:
- id: proven
此钩子会检查整个项目,而不只是有更改的文件:P6 需要查看测试。
GitHub Actions
- uses: actions/checkout@v4
- uses: malikabyl/[email protected]
问题会以注释的形式显示在拉取请求对应代码行上,以及任务摘要中。输入参数:path(要在其中运行的文件夹)、args(传给 proven check 的额外参数)、python(已安装项目依赖的解释器,以便 P1 和 P2 能看到这些依赖;默认值为 python3)。在此 Action 之外,proven check --github 也会生成相同的注释。
MCP 服务
Proven 也是一个 MCP 服务,因此 AI Agent 可以直接调用评判工具:proven_check、proven_explain 和 proven_rules 工具。它不需要额外的软件包。
Claude Code:
claude mcp add proven -- uvx proven-judge mcp --no-installed-check
其他客户端(Claude Desktop、Cursor 等):
{
"mcpServers": {
"proven": {
"command": "uvx",
"args": ["proven-judge", "mcp", "--no-installed-check"]
}
}
}
uvx 会在独立环境中运行服务,其中没有安装你项目的软件包,因此需要使用 --no-installed-check。若也要检查软件包是否已安装(P1),请改为在项目环境中运行服务:pip install proven-judge,然后运行 proven mcp。传给 Agent 的项目路径必须是绝对路径。
与 AI 模型协作的循环
Proven 的工作方式就像 AI 模型的编译器:模型编写代码,审查器指出问题并说明如何修复,模型再进行修复。审查器的消息经过专门编写,可以直接交给模型处理。
Claude Code。 仓库中已有 .claude/settings.json:每次编辑 .py 文件后,审查器都会检查文件;如果发现问题,Claude 就会看到报告并进行修复。将 .claude 文件夹复制到你的项目中。
提示词中的规则。 PROMPT.md 中提供了可用于系统提示词或 CLAUDE.md 的速查表。这样,模型从一开始就会遵循规则,剩余的问题则由审查器发现。
GitHub。 工作流 .github/workflows/proven.yml 会在每次推送和拉取请求时运行审查器和测试。
现有项目
对于旧代码,审查器会一次性发现许多问题。若要避免在一天内修复所有问题:
python proven.py baseline
当前问题会作为旧债务记录到 .proven-baseline.json 中。之后,审查器会跳过这些问题,但会拒绝任何新问题。逐步偿还债务,并重写基线。
使用项目的 Python 运行审查器。 P1 和 P2 会检查已安装的软件包。每份报告的第一行都会说明审查器检查所用的内容:项目根目录、Python、requirements 文件,以及读取过的环境。如果没有 proven.toml,根目录就是最近的、包含 pyproject.toml、requirements.txt 或 .git 的文件夹。如果审查器在自己的环境中运行,它还会读取项目的 .venv(或 venv、env、$VIRTUAL_ENV):其中的软件包会被视为已安装,并通过读取其代码来检查名称,不会导入它们。
完全没有测试的项目只会产生一个 P6 问题,而不是每个函数各产生一个。添加测试之前,设置 disable = ["P6"] 可以让报告更易于阅读。
豁免
最终决定权在人手中。可以针对某一行关闭规则,但必须说明原因:
MRP = 3932 # proven: allow P3: computing an archived 2025 fine
没有说明原因的豁免本身也是一个问题(P0)。注释可以写在同一行或上一行。对于 P5,也可以把注释放在处理程序内部,通常解释就在这里:
except OSError:
pass # proven: allow P5: logging a call must not break the answer to the client
故意不接受普通注释:模型写出 # intentional 和写出 pass 一样容易。俄语关键词同样有效:# proven: разрешить P3: reason。
诚实的局限
审查器能发现编造的内容,但发现不了错误的内容:
- P3 会检查事实是否有来源和近期日期,但不会检查其值是否符合法律。将其与来源进行比较,需要由人或
verify()中的检查来完成。 - P2 会检查模块和类中的名称。对象的方法(
response.jsonn())无法通过静态方式检查,因此需要测试来发现(P6)。 - P2 会导入审查器自身环境中已安装的软件包以检查其内容,这会运行这些软件包的导入代码;项目
.venv中的软件包则只会被读取,不会被导入。使用check_attributes = false可关闭此项检查。 - P4 会根据名称,在文件内及函数间跟踪数据。它会采取谨慎做法:有疑问时,就将数据视为未验证。返回模型输出的公共函数必须用
-> Unverified明确标注。只有在sources中列出了函数名称,才会识别出在其他文件中创建的模型客户端。 - P6 会按名称匹配函数和测试,而不是按模块匹配。
- 逻辑错误但前后一致的内容,任何静态审查器都无法发现。测试和你的最终判断才能发现它们。
目录结构
proven.py the judge (CLI)
proven_types.py Unverified, Verified, verify(), Fact
proven.toml settings (the judge checks itself)
SPEC.md the rules in detail and every setting
CHANGELOG.md what changed in each version
PROMPT.md a cheat sheet for an AI model
examples/bad code with hallucinations
examples/good the same code following the rules
tests/ the judge's tests
pyproject.toml the proven-judge package
action.yml the GitHub Action
server.json the MCP Registry entry
.pre-commit-hooks.yaml the pre-commit hook
.claude/settings.json the hook for Claude Code
.github/workflows/ the check on GitHub and the release to PyPI
发布:在 proven.py 中递增 VERSION,然后创建带有标签 vX.Y.Z 的 GitHub 发布版本。release 工作流会检查标签、VERSION 和 server.json 是否一致,构建软件包,将其发布到 PyPI,然后发布到 MCP Registry。请同时更新 server.json 中的两个版本号和 VERSION。
检查判定器本身:
pip install -r requirements-dev.txt
python proven.py check # the judge accepts itself
python -m pytest
示例中的数值(哈萨克斯坦的 MRP 及其他数值)已于 2026 年 11 月 3 日对照来源核验,仅作说明之用。在实际代码中,请对照哈萨克斯坦官方法律数据库 adilet.zan.kz 核验这些数值。
许可证
MIT,详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。