技术教程 · 阅读约 8 分钟

用 30 行 Python 让 AI Agent 帮你审完整个代码仓库

用 30 行 Python 让 AI Agent 帮你审完整个代码仓库

很多人第一次用 Codex 或 Claude 做代码审查,都踩过同一个坑:把整个文件丢给模型,结果 token 爆了,或者审查结果泛泛而谈,没有实际价值。

真正有用的 AI Code Review,不是"把代码喂进去问有没有问题",而是让模型像有经验的同事一样,逐文件、逐函数地给出具体建议。这篇文章教你搭一个能跑通的最小版本,不依赖任何框架,纯 Python 标准库 + OpenAI SDK,30 行核心逻辑。


为什么直接贴代码给 ChatGPT 效果差

根本原因有三个:

1. 上下文太长:一个中等规模的函数文件就几百行,加上 prompt 很容易超过有效注意力范围

2. 问题太宽泛:模型不知道你最关心什么——安全?性能?还是可维护性?

3. 没有结构化输出:自由文本难以集成进 CI/CD 流程

解决方案:按函数粒度切割 + 结构化 prompt + JSON 输出。


实战代码

下面这段脚本会遍历你指定目录下的所有 .py 文件,用 AST 提取每个函数,然后逐个交给模型审查,最后输出一份 Markdown 报告。


import ast

import os

import json

from pathlib import Path

from openai import OpenAI



client = OpenAI(

    api_key=os.environ.get("API_KEY"),

    base_url="https://api2everything.xyz/v1",  # 国内直连,无需代理

)



def extract_functions(filepath: str) -> list[dict]:

    """从 Python 文件中提取所有函数的源码和名称"""

    source = Path(filepath).read_text(encoding="utf-8")

    tree = ast.parse(source)

    lines = source.splitlines()

    functions = []

    for node in ast.walk(tree):

        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):

            start = node.lineno - 1

            end = node.end_lineno

            functions.append({

                "name": node.name,

                "code": "\n".join(lines[start:end]),

                "file": filepath,

            })

    return functions



def review_function(func: dict) -> dict:

    """让模型审查单个函数,返回结构化结果"""

    prompt = f"""审查以下 Python 函数,从安全性、性能、可读性三个维度给出建议。

用 JSON 格式返回,字段:severity(high/medium/low)、issues(列表)、suggestion(字符串)。

只返回 JSON,不要多余解释。



文件:{func['file']}

函数:{func['name']}



{func['code']}




    response = client.chat.completions.create(

        model="claude-sonnet-4-5",   # 或换成 gpt-4o / deepseek-chat

        messages=[{"role": "user", "content": prompt}],

        response_format={"type": "json_object"},

        temperature=0.2,

    )

    result = json.loads(response.choices[0].message.content)

    result["function"] = func["name"]

    result["file"] = func["file"]

    return result



def review_repo(directory: str) -> None:

    """遍历目录,审查所有 Python 文件"""

    py_files = list(Path(directory).rglob("*.py"))

    all_issues = []



    for filepath in py_files:

        try:

            functions = extract_functions(str(filepath))

            for func in functions:

                print(f"  reviewing {func['file']}::{func['name']} ...")

                result = review_function(func)

                if result.get("issues"):

                    all_issues.append(result)

        except SyntaxError:

            print(f"  skip (syntax error): {filepath}")



    # 输出 Markdown 报告

    print("\n# Code Review Report\n")

    for item in sorted(all_issues, key=lambda x: {"high": 0, "medium": 1, "low": 2}[x["severity"]]):

        print(f"## [{item['severity'].upper()}] `{item['file']}` → `{item['function']}`\n")

        for issue in item["issues"]:

            print(f"- {issue}")

        print(f"\n**建议**:{item['suggestion']}\n")



if __name__ == "__main__":

    import sys

    target = sys.argv[1] if len(sys.argv) > 1 else "."

    review_repo(target)

运行方式:


pip install openai

export API_KEY="your_key_here"

python review.py ./your_project_dir


几个值得注意的细节

函数粒度而非文件粒度:AST 解析保证每次送给模型的 token 量可控,也让结果更精准。一个函数 50 行,比整个文件 500 行审查质量高很多。

response_format: json_object:强制 JSON 输出,避免模型返回 markdown 代码块包裹的 JSON 还要再解析一层。

temperature=0.2:代码审查需要确定性,低温度让建议更一致,减少随机发挥。

模型选择:这个脚本支持直接换模型,claude-sonnet-4-5 对代码理解很强,deepseek-chat 性价比极高,gpt-4o 则在解释类建议上更清晰。改一行 model= 参数就能切换。


进一步扩展的方向

  • 接入 CI/CD:把 all_issues 里 severity == "high" 的数量作为退出码,超过阈值就阻断 merge
  • 增量审查:结合 git diff --name-only 只审查本次改动的文件,节省 token
  • 多语言支持:把 AST 部分换成 tree-sitter,就能支持 JS/TS/Go/Rust

关于 API 费用

上面用的 base_url 是 无量Api 的地址。国内直连,不需要代理,支持 OpenAI / Claude / Gemini / DeepSeek 等 300+ 模型,价格比官方便宜约 65%。

对于这类批量审查场景,token 消耗量不小,用聚合 API 省下来的钱还是很明显的。注册即送 ¥1 余额,余额永久有效,先试用再决定要不要充值。

👉 api2everything.xyz


有问题欢迎评论区留言,特别是遇到大型 monorepo 或者想接 GitHub Actions 的,可以聊聊具体方案。觉得有用的话点个赞,后续会继续更 AI 工具链的实战内容。