项目成果演示:

1. 方案摘要
本方案旨在解决手动代码审查(Code Review)耗时耗力、标准不一的问题。通过利用 GitLab 自带的 CI/CD 功能,在开发者创建合并请求(Merge Request, MR)时自动触发一个流水线任务。该任务会提取 MR 中的代码变更,调用 Google Gemini Pro 模型的 API 进行分析,并将 AI 生成的审查意见以评论的形式自动发布回 MR 页面,从而为人工审查提供有价值的参考,提升代码质量和团队效率。
1.1 核心目标
- 自动化:MR 创建或更新时,自动触发代码审查,无需人工干预。
- 智能化:利用大语言模型的代码理解能力,发现潜在的 Bug、性能问题、不规范写法和安全漏洞。
- 效率化:AI 优先进行第一轮审查,帮助人类审查者快速抓住重点,缩短整体审查周期。
- 低成本:方案初期采用 Google 提供的免费 API 配额,无需支付额外费用即可验证其价值。
1.2 技术选型
- 代码托管与CI/CD:GitLab
- AI 模型服务:Google Gemini API (使用 gemini-1.5-flash-latest 模型,兼具速度与性能,且有慷慨的免费额度)
- 需要确保gitlab的服务器能访问到google的服务
- 执行环境:GitLab Runner 上的 Docker 环境 (使用官方 python:3.9-slim 镜像)
- 核心脚本:Python 3
1.3 方案架构与流程
- 开发者提交代码到特性分支,并向主分支发起一个 Merge Request。
- GitLab 收到 MR 事件,根据 .gitlab-ci.yml 的配置,触发 CI/CD 流水线。
- GitLab Runner 启动一个名为 ai_code_review 的 Job。
- Job 内部执行 Python 脚本,脚本通过 GitLab API 获取该 MR 的代码变更(Diff)。
- 脚本将代码变更与预设的 Prompt(指令)结合,向 Google Gemini API 发起请求。
- Gemini API 返回分析结果(审查意见)。
- 脚本接收结果,并再次调用 GitLab API,将审查意见作为一条 Comment 发布到原始 MR 中。
- 开发者和审查者在 MR 页面直接看到 AI 的反馈。
2. 实施步骤
阶段一:准备工作
1. 获取 Google Gemini API 密钥:
- 访问 Google AI Studio。
- 使用 Google 账号登录。
- 点击 "Get API key" -> "Create API key in new project"。
- 立即复制并妥善保管生成的 API 密钥。
2. 获取 GitLab Access Token:
- 登录 GitLab 账号。
- 进入 右上角头像 -> Preferences -> Access Tokens。
- Token name: ai_code_reviewer (或任何其他名字)。
- Expiration date: 建议设置一个有效期。
- Select scopes: 勾选 api 权限。api 权限已包含读取仓库和写入评论所需的所有权限。
- 点击 "Create personal access token"。
- 立即复制并妥善保管生成的 Token。
阶段二:GitLab 项目配置
进入需要集成此功能的 GitLab 项目:
- 导航到 Settings -> CI/CD。
- 展开 Variables 部分。
- 点击 "Add variable" 添加以下两个变量,用于安全地存储密钥:
- Key: GEMINI_API_KEY
- Value: [粘贴从 Google AI Studio 获取的 API 密钥]
- Flags: 勾选 Protect variable 和 Mask variable。
- Key: GITLAB_ACCESS_TOKEN
- Value: [粘贴从 GitLab 创建的 Access Token]
- Flags: 勾选 Protect variable 和 Mask variable。
阶段三:创建核心脚本和CI配置文件
在的项目代码库的根目录下,创建以下两个文件:
- 审查脚本: ai_review.py
python
import os
import requests
import json
# --- 1. 从 CI/CD 环境变量中获取配置 ---
GITLAB_API_URL = os.environ.get("CI_API_V4_URL")
PROJECT_ID = os.environ.get("CI_PROJECT_ID")
MR_IID = os.environ.get("CI_MERGE_REQUEST_IID")
GITLAB_TOKEN = os.environ.get("GITLAB_ACCESS_TOKEN")
# 修改为 DeepSeek 的 API Key
DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY")
def check_env_vars():
"""检查所有必要的环境变量是否存在"""
if not all([GITLAB_API_URL, PROJECT_ID, MR_IID, GITLAB_TOKEN, DEEPSEEK_API_KEY]):
print("Error: Missing one or more required environment variables.")
exit(1)
# --- 2. 与 GitLab API 交互 (无变动) ---
def get_mr_changes():
url = f"{GITLAB_API_URL}/projects/{PROJECT_ID}/merge_requests/{MR_IID}/changes"
headers = {"PRIVATE-TOKEN": GITLAB_TOKEN}
try:
response = requests.get(url, headers=headers, timeout=20)
response.raise_for_status()
changes = response.json().get('changes', [])
return "\n".join([change['diff'] for change in changes])
except requests.exceptions.RequestException as e:
print(f"Error fetching MR changes from GitLab: {e}")
return None
def post_review_to_gitlab(comment):
url = f"{GITLAB_API_URL}/projects/{PROJECT_ID}/merge_requests/{MR_IID}/notes"
headers = {"PRIVATE-TOKEN": GITLAB_TOKEN}
body = f"🤖 **AI Code Review (DeepSeek)** 报告:\n\n---\n\n{comment}"
data = {"body": body}
try:
response = requests.post(url, headers=headers, data=data, timeout=20)
response.raise_for_status()
print("Successfully posted AI review comment to GitLab MR.")
except requests.exceptions.RequestException as e:
print(f"Error posting comment to GitLab: {e}")
# --- 3. 调用 DeepSeek API 进行审查 (核心替换部分) ---
def call_deepseek_api(code_diff):
"""调用 DeepSeek API 对代码 diff 进行审查"""
api_url = "https://api.deepseek.com/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {DEEPSEEK_API_KEY}"
}
# Prompt 保持不变,但可以针对 Coder 模型进行微调
prompt = f"""
你是一名世界级的软件工程师和代码审查专家,对代码质量有近乎完美的苛刻要求。请严格、细致地审查以下代码变更(diff格式)。
你的任务是:
1. **识别潜在的 Bug**:比如空指针、逻辑错误、边界条件问题。
2. **发现性能问题**:比如不必要的循环、低效的算法。
3. **检查代码风格和可读性**:是否遵循通用编码规范,命名是否清晰,注释是否必要。
4. **识别安全漏洞**:比如 SQL 注入、跨站脚本等。
5. **提出具体的改进建议**:对于每一个发现的问题,请提供清晰的解释,并给出"修改前"和"修改后"的代码片段对比,以便开发者能直接采纳你的建议。
请以清晰的 Markdown 格式返回你的审查意见。如果发现多个问题,请用列表形式呈现。
如果代码质量很高,没有发现任何问题,请回复 "代码质量非常高,未发现明显问题。LGTM! 👍"。
以下是需要审查的代码变更:
```diff
{code_diff}
```
"""
payload = {
"model": "deepseek-coder", # 使用 DeepSeek 的代码专用模型
"messages": [
{"role": "user", "content": prompt}
],
"temperature": 0.1, # 让输出更稳定、严谨
"max_tokens": 4096,
"stream": False
}
try:
response = requests.post(api_url, headers=headers, data=json.dumps(payload), timeout=60) # 延长超时时间
response.raise_for_status()
result = response.json()
review_content = result['choices'][0]['message']['content']
return review_content
except requests.exceptions.RequestException as e:
detailed_error_message = f"**错误: 请求 DeepSeek API 失败。**\n\n**详情:**\n```\n{str(e)}\n```"
print(f"Error calling DeepSeek API: {e}")
return detailed_error_message
except (KeyError, IndexError) as e:
detailed_error_message = f"**错误: 解析 DeepSeek API 响应失败。**\n\n**详情:**\n```\n{str(e)}\n```\n**原始响应:**\n```\n{response.text}\n```"
print(f"Error parsing DeepSeek response: {e}")
return detailed_error_message
# --- 4. 主执行逻辑 (调用新函数) ---
if __name__ == "__main__":
check_env_vars()
print("Starting AI Code Review process with DeepSeek...")
diff_content = get_mr_changes()
if not diff_content or not diff_content.strip():
print("No code changes found in this MR. Exiting.")
exit(0)
print("Fetching review from DeepSeek AI...")
review_result = call_deepseek_api(diff_content) # 调用新的函数
if review_result:
post_review_to_gitlab(review_result)
else:
post_review_to_gitlab("从 DeepSeek AI 未获取到有效的审查结果。")
exit(1)
- CI/CD 配置文件: .gitlab-ci.yml
yaml
stages:
- review
.python-base:
image: python:3.9-slim
before_script:
# 使用阿里云的镜像源在线安装依赖
- pip install -i https://mirrors.aliyun.com/pypi/simple/ requests
ai_code_review:
extends: .python-base
stage: review
script:
- python ai_review.py
rules:
# ------------------- 核心修正部分 -------------------
# 将 CI_PIPILINE_SOURCE 修正为 CI_PIPELINE_SOURCE
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
阶段四:部署与测试
- 将 ai_review.py 和 .gitlab-ci.yml 这两个文件提交到的项目代码库的主分支。
- 从主分支创建一个新的特性分支,例如 feature/test-code-review。
- 在该分支上做一些代码修改。可以故意写一些有小问题的代码,比如:
- 一个永远不会退出的循环。
- 一个变量命名为 data1,data2。
- 硬编码的密钥或密码。
-
提交并推送的特性分支。
-
在 GitLab UI 上,为这个分支创建一个新的 Merge Request。
-
创建 MR 后,GitLab 会自动启动一个新的流水线。
-
可以点击 MR 页面的 "Pipelines" 标签页,查看 ai_code_review job 的运行状态和日志。
-
几分钟后,刷新 MR 页面,在 "Overview" 页面的评论区看到一个来自的账户(因为用了你的 Token)、由 AI 生成的代码审查报告。
-
进阶与优化
- Prompt 优化:
ai_review.py
脚本中的prompt
是整个系统的核心。可以根据团队的技术栈(如 Java, Go, Frontend)和编码规范,对 Prompt 进行深度定制,以获得更精准的审查结果。 - 触发控制: 如果不希望每次提交都触发,可以修改 .gitlab-ci.yml 的 rules。例如,只在 MR 添加了特定标签(如 ai-review)时才运行。
- 成本管理: 当决定从免费额度转向付费后,为了控制成本,可以进一步限制 diff 的大小,或者只对指向 main/master 分支的 MR 进行审查。
- 通知: 可以或其他通知工具,在 AI 审查脚本执行失败时发送警报。