用 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 余额,余额永久有效,先试用再决定要不要充值。
有问题欢迎评论区留言,特别是遇到大型 monorepo 或者想接 GitHub Actions 的,可以聊聊具体方案。觉得有用的话点个赞,后续会继续更 AI 工具链的实战内容。