从零搭建 AI 代码审查服务:一份前端也能看懂的 Python 学习笔记

一份写给前端开发者的 Python 小项目实战指南

  1. # 实战:搭建 AI Code Review 自动化流水线
  2. # GitLab-Runner + AI 代码审查服务 + 远程大模型 全套部署运维实战

缘起:为什么我要写这份笔记?

前几天,我搭了一套 AI 代码审查服务,用 Python + Flask 写了大概 200 行代码,实现了:当 GitLab 收到 MR 时,自动调用 AI 分析代码 diff,然后把审查意见贴回 MR 评论区

团队里几个前端同事看了都很好奇:"我不会 Python,这个能学会吗?" 我就想,干脆写一份零基础也能看懂的学习笔记,把我踩过的坑、理解的过程都记录下来。


一、这个服务到底干了什么事?

你先别管代码,我们先理清楚它想解决什么问题

  • 每次有人提 MR,都要人工 review,很慢,而且有些低级错误(比如忘记处理空值、变量命名不规范)反复出现。
  • 我们希望让 AI 先帮忙扫一遍,把明显的错误挑出来,人工只需要看复杂逻辑。

所以这个服务的流程就是:

  1. GitLab CI 触发一个任务 →
  2. 调用这个 Python 服务(传过去项目名、MR 编号)→
  3. Python 服务从 GitLab 拉取这次 MR 的代码变更(diff)→
  4. 把 diff 发给大模型(比如 GPT-4)→
  5. 大模型按我们的规范返回审查意见 →
  6. 服务再把这些意见通过 GitLab API 贴到 MR 评论区。

你可以把它想象成:一个会看代码的 AI 同事,24 小时在线,随叫随到


二、这个项目用了哪些技术?(尽量让前端看懂)

技术 作用 类比(前端视角)
Python 3 后端语言 类似 Node.js
Flask Web 框架 类似 Express
OpenAI SDK 调用大模型 类似调用第三方 API
requests 发 HTTP 请求 类似 axios
python-dotenv 读取 .env 配置 类似 dotenv
git 命令 克隆规范文件仓库 就是 git clone

所以即使你不会 Python,只要你会写 JavaScript,理解这些概念都不难------只是语法不同罢了。


三、手把手运行起来(Mac / Linux)

1. 安装 Python(如果没有)

Mac 用户(一般电脑自带):

bash 复制代码
brew install python3

验证:

bash 复制代码
python3 --version   # 应该显示 3.9 以上

2. 下载代码

把上面那份 app.py 保存到一个文件夹里,比如 ~/ai-review-service/

同时创建一个 requirements.txt,内容如下:

复制代码
flask
openai
python-dotenv
requests

3. 安装依赖

bash 复制代码
cd ~/ai-review-service
pip3 install -r requirements.txt

如果提示 pip3 找不到,试试 pip。或者用 python3 -m pip install ...

4. 配置环境变量(创建 .env 文件)

在相同目录下新建 .env 文件,内容如下(把尖括号里的换成你自己的):

env 复制代码
OPENAI_API_KEY=sk-xxxxxxxxxxxxxx
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
GITLAB_TOKEN=glpat-xxxxxxxxxxxx
GITLAB_URL=https://gitlab.com
REVIEW_SPEC_PATH=./specs/frontend-code-review.md
AUTO_SYNC_SPEC=true
SKILLS_REPO_URL=https://gitlab.com/your-team/skills.git

各字段含义我后面会详细解释。

5. 启动服务

bash 复制代码
python3 app.py

看到类似下面的输出就成功了:

bash 复制代码
🚀 AI Review 服务启动中...
📡 服务地址: http://localhost:5001
🔑 测试令牌: test-token-123
📝 审查接口: POST /api/review

四、配置文件 .env 详解(小白必看)

变量 含义 从哪里获取
OPENAI_API_KEY 调用 OpenAI(或兼容接口)的密钥 在 OpenAI 官网或阿里云 DashScope 申请
OPENAI_BASE_URL API 地址 默认是 OpenAI 官方,如果国内用通义千问就改成阿里云地址
OPENAI_MODEL 使用的模型名 比如 gpt-4o-miniqwen3.7-max
GITLAB_TOKEN GitLab 个人访问令牌 GitLab → Settings → Access Tokens,勾选 apiread_api 权限
GITLAB_URL 你的 GitLab 服务器地址 公司内部的 GitLab 地址,比如 https://gitlab.your-company.com
REVIEW_SPEC_PATH 代码审查规范文件存放路径 可以默认,会在启动时从 skills 仓库下载
AUTO_SYNC_SPEC 是否自动同步规范 truefalse,建议 true
SKILLS_REPO_URL 存放审查规范的 Git 仓库地址 你自己建一个仓库,里面放 frontend-code-review/SKILL.md

特别注意

  • GITLAB_TOKEN 必须有 api 权限,否则无法在 MR 下发评论。
  • 如果只是测试,可以先不配置 GITLAB_TOKEN,服务会返回"无法获取 diff"的提示,但不会报错。

五、代码逐段解析(不要求你懂 Python,但知道它在干嘛)

我会把 app.py 拆成几个核心功能,用大白话解释。

1. 导入依赖和读取配置

python 复制代码
from flask import Flask, request, jsonify
import os
import subprocess
# ... 其他导入
load_dotenv()   # 自动读取 .env 文件
  • Flask 就像 Express 的 app 对象,用来定义路由。
  • load_dotenv() 让你能在代码里用 os.getenv('OPENAI_API_KEY') 拿到配置。

2. 同步审查规范文件

python 复制代码
def sync_specs_from_git():
    # 用 git clone 拉取一个仓库,然后把里面的 SKILL.md 复制到本地

为什么需要这个?

团队代码规范可能会更新。我们把它单独放在一个 Git 仓库里,服务启动时自动拉取最新版。这样不用改代码,只改规范文件,AI 就会按新规则审查。

对前端的类比 :就像你 npm install 一个依赖包,只不过这里 git clone 了一个文档。

3. 从 GitLab 获取 MR 的 diff

python 复制代码
def get_mr_diff(project_path, mr_iid):
    # 调用 GitLab API: GET /projects/:id/merge_requests/:iid/changes
    # 返回一个包含代码增删内容的字符串

核心逻辑

  • project_path 类似 group/project
  • mr_iid 是 MR 的编号(比如 !123 中的 123)。
  • requests 库发 GET 请求,带上 PRIVATE-TOKEN 头。
  • 解析返回的 JSON,提取 changes 数组中的 diff 字段。

如果失败怎么办? 代码里做了详细的错误提示,比如 401 告诉你 token 权限不够,403 告诉你没权限访问项目。

4. 调用 AI 进行审查

python 复制代码
def get_real_ai_review(mr_info, code_diff):
    # 1. 加载团队规范文件内容
    # 2. 拼接一个超长的 prompt(提示词)
    # 3. 调用 OpenAI API
    # 4. 解析返回的 JSON

这是最核心的函数。它做的事情可以理解为:给 AI 下指令

指令内容大致是:

你是一位审查专家。下面是 MR 的代码变更,请按以下规范检查:...... 输出格式必须是 JSON,每个问题要标明文件、行号、优先级、分类。

AI 返回的 JSON 结构类似:

json 复制代码
{
  "score": 75,
  "suggestions": [
    {"type": "error", "file": "src/App.vue", "line": 12, "message": "空指针风险,建议加 ?."}
  ]
}

前端同学注意:这个 prompt 就是你的"需求文档",你想让 AI 怎么审查,完全可以通过修改 prompt 来控制。甚至你可以把 ESLint 规则翻译成自然语言写进去。

5. 定义 HTTP 接口(路由)

python 复制代码
@app.route('/api/review', methods=['POST'])
def review_code():
    # 1. 验证 Authorization 头里的 Bearer token
    # 2. 解析请求 body(JSON)
    # 3. 调用 get_mr_diff 拉取代码
    # 4. 调用 get_real_ai_review
    # 5. 返回结果
  • @app.route 类似 Express 的 app.post()
  • 函数名随便起,但里面逻辑一定要清晰。
  • 返回的 JSON 会通过 jsonify 自动转成响应。

6. 健康检查与测试接口

python 复制代码
@app.route('/health')
def health_check():
    return {"status": "ok", ...}

作用:让你确认服务是否还活着,以及配置是否正确(比如检查 API Key 是否存在)。

还有一个 /test/gitlab 接口,可以手动测试 GitLab token 是否有效。


六、如何在 GitLab CI 里调用这个服务?

在你的前端项目根目录,修改 .gitlab-ci.yml,添加一个 job:

yaml 复制代码
ai-review:
  stage: review
  tags:
    - mac-runner          # 如果你用本地 runner
  script:
    - |
      curl -X POST http://localhost:5001/api/review \
        -H "Authorization: Bearer test-token-123" \
        -H "Content-Type: application/json" \
        -d "{
            \"project\": \"$CI_PROJECT_PATH\",
            \"mr_iid\": $CI_MERGE_REQUEST_IID,
            \"source_branch\": \"$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME\",
            \"target_branch\": \"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME\"
          }"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  • $CI_PROJECT_PATH 等变量是 GitLab CI 自带的,不用你手动填。
  • test-token-123 是服务里硬编码的测试 token,你可以改成更安全的随机字符串。

如果你不想用本地 runner ,也可以把这个服务部署到一台有公网 IP 的服务器上,然后把 http://localhost:5001 换成对应的 IP。


七、踩坑记录(我摔过的地方)

1. Token 权限不足 → 401

  • 错误:获取 MR 变更失败: 401
  • 原因:GitLab Token 只给了 read_user,没给 api
  • 解决:重新生成 Token,权限勾选 api(或至少 read_api + write_repository)。

2. 本地服务跑在 5001,GitLab Runner 却访问不通

  • 错误:curl: (7) Failed to connect to localhost port 5001
  • 原因:Runner 如果是 Docker 模式,localhost 指向容器内部,不是你的 Mac。
  • 解决:要么用 host.docker.internal(Mac),要么改用 shell executor(我上面用的就是 shell)。

3. Python 依赖安装失败

  • 错误:No module named 'flask'
  • 原因:你可能用了系统自带的 Python 2.7,或者忘记激活虚拟环境。
  • 解决:用 python3 -m pip install,或者先 python3 -m venv venv 创建虚拟环境。

4. AI 返回的 JSON 解析失败

  • 现象:服务日志提示 JSON 解析失败,MR 里出现 raw_response。
  • 原因:大模型偶尔会返回带解释文字的 JSON,或者 JSON 不完整。
  • 解决:代码里已经做了"尝试提取 ```json 代码块"的逻辑,如果还失败,可以让模型 temperature 更低(比如 0.1)。

八、扩展想法(你可以自己加的功能)

  • 支持更多 Git 平台:比如 GitHub、Gitee,原理一样,只是 API 地址和 Token 不同。
  • 支持本地模型:用 Ollama 跑一个开源的 CodeLlama,不用花 API 钱。
  • 增量审查:只审查变更的部分,而不是全量 diff,提高速度。
  • 自动修复:让 AI 不仅发现问题,还生成一个修复 patch,用户点一下就能应用。

九、最后想说的话

之前作为一个前端,我一开始也觉得 Python 很陌生。但实际写下来发现,Flask 比 Express 还简单 :不需要配置中间件,不需要处理路由参数解析,甚至不需要 async/await(默认就是同步,很适合这种小工具)。

而且这种"小 AI 服务"的写法非常固定:

接收请求 → 调第三方 API → 加工数据 → 返回 JSON

你只要会写 JavaScript,换成 Python 只是字典和列表的语法区别。

希望这份笔记能让你有信心去改一改上面的代码,甚至自己写一个。如果你在尝试中遇到问题,欢迎在评论区留言(或者提 issue),我会把新的踩坑经历补充进来。

最后再啰嗦一句:代码不重要,解决问题的方法才重要。这个服务虽然只有 200 行,但它让团队的代码规范真正落地了,这才是最有价值的部分。

相关推荐
lichenyang4531 小时前
JSAPI、NAPI、Biz、Imp:ASCF Demo 如何真正调用系统能力和 C++ 能力
前端
lichenyang4532 小时前
IPC、JSVM、UIThread、libuv:ASCF 架构图里最容易混的几个词
前端
用户059540174462 小时前
Redis记忆存储故障恢复测试踩坑实录:手动测试让我漏掉了2个一致性Bug
前端·css
用户2136610035722 小时前
Vue2脚手架工程化与Axios集成
前端·vue.js
我不是外星人2 小时前
我把 Claude Code 搬到网页!自研高颜值 Web 交互工作台
前端·ai编程·claude
mixuecoding2 小时前
零成本搭建全球科技热点情报站:12 个平台,6 小时,0 元
前端
用户059540174462 小时前
用了3年Mock,才发现Redis记忆存储的测试一直漏掉了60%的边界场景
前端·css
石小石Orz2 小时前
AI具身交互:实现一个会说话的3D虚拟伴侣
前端·人工智能·后端
Muen3 小时前
iOS设计模式-外观Facade
前端