跳到主要内容

告别繁琐评审一站式搞定Code Review

本文将详细介绍如何借助 Tuanjie AI 这一智能工具,优化 Git Commit 信息编写与 Code Review(代码评审)流程,通过 AI 赋能让研发协作更高效、代码质量更有保障。

一、为什么需要 AI 赋能 Git Commit 与 Code Review?

在传统的研发协作模式中,Git Commit 和 Code Review 作为核心环节,长期面临着诸多痛点,严重影响研发效率与代码质量:

  • Commit 信息混乱无规范:开发人员常因赶进度随意编写 Commit 信息(如"fix bug"、"update"),后续排查问题、回溯版本时难以快速定位核心变更,增加沟通成本;此外,Tuanjie AI能够基于良好的Commit信息直接生成Change log和工作报告。

  • Code Review 效率低下:人工 Review 需耗费大量时间逐行核对代码,尤其是大型项目中,Review 周期长易导致研发流程卡顿;

  • Review 质量参差不齐:不同开发人员的技术水平、关注点存在差异,易遗漏潜在的性能问题、安全漏洞或代码规范问题;

  • 新人上手成本高:新人需熟悉团队的 Commit 规范、代码评审标准,过程漫长且易出错。

而 Tuanjie AI 凭借其强大的智能分析与自动化能力,能够从根源上解决上述问题,让研发协作流程更顺畅,代码质量管控更高效。

二、实操指南

接下来,我们将通过具体实操步骤,演示如何利用 Tuanjie AI 完成 Git Commit 与 Code Review 的全流程优化。

项目准备

  1. 首先创建空项目目录code-review-sample,并通过命令git init完成 Git 仓库初始化,为后续的版本管理做好准备。
  2. 使用你偏好的代码编辑器打开项目(本文以 VS Code 为例进行演示)。
  3. 借助 Tuanjie AI 的智能编码能力生成代码:向 Tuanjie AI 输入指令 "帮我用 python 写个抽象 sort 接口并实现快速排序与冒泡排序",Tuanjie AI 会自动完成算法实现,并生成sorting.py文件,大幅节省编码时间。

生成规范化 Commit 信息

Tuanjie AI 内置了专门用于生成 Commit 信息的 Prompt 模板,无需手动编写复杂的规范信息,具体操作如下:

  1. 在 Tuanjie AI 中输入 / 符号,从弹出的选项中选择 Git Commit Message Generator
  2. 直接按输入按钮,Tuanjie AI 将自动生成符合规范的 Commit 信息。
Bridge

然后我们查看下生成的Commit 信息:

Bridge

从生成结果可以看到,Tuanjie AI 提供的 Commit 信息不仅结构清晰,还包含了变更类型、影响模块、具体修改内容等关键信息,完全满足团队的版本管理规范。

此外,若团队有定制化的 Commit 信息规范,也可根据自身需求自定义 Prompt 模板,让 Tuanjie AI 生成的信息更贴合团队实际使用习惯。

AI 驱动的 Code Review

借助 Tuanjie AI 的 AI 能力,我们可以搭建一套自动化的 Code Review 流程,实现对 Merge Request(MR)的智能评审,并将结果同步至代码仓库与协作群聊,大幅提升评审效率与覆盖度。

项目配置:搭建 Code Review 的核心文件

首先在项目根目录创建codereview目录,用于存放评审所需的 Prompt 模板与执行脚本,具体包含两个核心文件:codereview_prompt.mdai-code-review.py

codereview_prompt.md

你是一位资深的软件开发专家和代码审查大师,精通 Python 与 JavaScript/TypeScript 开发,尤其擅长使用 FastAPI、gRPC Web 实现后端服务,以及使用 React 与 shadcn/ui 构建现代前端应用。

请你以 **中文** 进行回复。

你的任务是审查以下代码变更,结合代码仓库的内容,评估此次变更的质量、潜在风险,并提供有针对性的改进建议。

## 项目背景

该项目为 Web 应用及 AI 服务平台,主要功能包括前后端协作与大模型交互,技术栈如下:

* **后端语言**:Python(约占源代码比例 60%)
* 框架:FastAPI、gRPC Web
* 特别关注:异步任务调度、上下文管理、Prompt 构建、Token 控制、多用户状态隔离等
* **前端语言**:JavaScript / TypeScript(约占源代码比例 40%)
* 框架与组件:React + shadcn/ui + TailwindCSS
* 特别关注:状态管理、异步加载、组件复用、性能优化、可访问性等
* **注意**:代码提交可能包含编译后的静态资源(如 `dist/``.vscode/``static/` 等),请自动忽略这些无需评审的文件。

你当前就在代码的根目录,可以直接查看代码仓库的必要内容以协助对变更代码进行评估。

## 审查重点(按以下优先级顺序)

1. **严重缺陷**
* 后端:
* 逻辑错误、异常处理缺失、上下文管理混乱
* gRPC/WebSocket/FastAPI 使用不当
* 对大模型请求接口的异步处理错误、未正确处理超时或异常响应
* 敏感数据泄露、路径遍历、XSS/注入等安全问题
* 前端:
* 关键交互逻辑缺陷,如无法正确触发事件、异步请求未捕捉错误
* 表单校验缺失、未处理异常状态等问题
* 使用非受控组件或破坏 React 状态流转的代码

2. **性能问题**
* 后端:
* 同步阻塞、数据库/大模型请求串行执行等导致延迟增加
* 使用非惰性数据结构(如大模型响应未按流式处理)
* 前端:
* 渲染开销大、重复请求、多余状态刷新
* 不必要的组件重渲或状态过度提升

3. **可维护性与健壮性**
* 命名不清晰、代码重复、函数过长、职责不清
* 未封装通用逻辑、未使用依赖注入/钩子等组件机制
* 缺乏类型注解(Python)或类型不匹配(TS)
* 未包含单元测试/无基本测试覆盖

4. **语言/框架特定问题**
* Python:
* FastAPI 路由/依赖注入误用
* gRPC 客户端/服务端协作逻辑缺陷
* 依赖管理(requirements/pyproject)、异常处理装饰器误用
* React:
* Hooks 使用不当(如副作用无限执行)
* 状态逻辑复杂未拆分、未使用组件化思维
* CSS 冲突、Tailwind 滥用、样式未复用

## 输出格式(请严格遵循)

#### 🤖 评审打分

[请在此处为本次修改打分,打分范围 0-100 分]

---

#### 💭 代码理解

[请简要描述你对本次代码变更实现的功能和主要目的的理解。]

---

#### ⚠️ 关键问题与建议

[请列出所有你发现的严重问题。每个问题应包含:

- 问题描述:清晰说明问题所在。
- 代码定位:指出问题相关的代码片段或文件行号(如果可能)。
- 潜在影响:解释该问题可能导致的后果。
- 修复建议:提供具体的修改方案,可以包含简短的示例代码。]

---

#### 🔍 次要改进(可选)

[请列出最多 3 个你认为可以进一步改进代码质量的次要点,例如代码风格、可读性提升等。]

---

#### 📝 总结

[请用 1-2 句话对本次代码变更的整体质量给出一个总体评价。]

## 注意事项

- 请忽略前端编译生成文件(如 `.next/``dist/``static/`)、`.vscode/` 目录或 IDE 插件相关资源。
- 若变更质量较高无明显问题,请在"关键问题与建议"中明确说明"代码变更没有明显的严重问题"。
- 若缺乏上下文影响判断准确性,请在"代码理解"或问题中指出需要哪些补充信息。
- 请避免纯风格建议,除非其显著影响可维护性。

以下是需要审查的代码变更,请结合代码仓库的已有内容对其进行评估:

```diff
{{diff_content}}
```

请严格按照上述"输出格式"组织回复,并使用中文,每个标题(例如 #### 🤖 评审打分)都必须存在。

ai-code-review.py

import os
import sys
import json
import subprocess
import argparse
import requests
import re
import time
from jinja2 import Template

def get_mr_diff_via_api(project_path, mr_id, gitlab_token, gitlab_base_url):
"""通过 GitLab API 获取 MR 差异"""
if not all([project_path, mr_id, gitlab_token, gitlab_base_url]):
print("缺少必要参数,使用mock数据进行本地测试")
return get_mock_diff_data()

encoded_project_path = requests.utils.quote(project_path, safe='')
api_url = f"{gitlab_base_url}/api/v4/projects/{encoded_project_path}/merge_requests/{mr_id}/changes"

headers = {
"PRIVATE-TOKEN": gitlab_token
}

try:
response = requests.get(api_url, headers=headers, timeout=10)
if response.status_code == 200:
try:
return response.json().get("changes", [])
except requests.exceptions.JSONDecodeError:
print(f"无效的API响应: {response.text}")
else:
print(f"获取MR差异失败,状态码: {response.status_code}, 响应内容: {response.text}")
print("请检查Settings->CI/CD->Variables 是否配置了GITLAB_BASE_URL和GITLAB_BOT_TOKEN,如已配置,请检查是否过期。")
except requests.exceptions.RequestException as e:
print(f"API请求失败: {str(e)}")
print("使用mock数据进行本地测试")
return get_mock_diff_data()

return []

def get_mock_diff_data():
"""返回模拟的diff数据用于本地测试"""
mock_changes = [
{
"old_path": "src/utils/helper.py",
"new_path": "src/utils/helper.py",
"diff": """@@ -1,10 +1,15 @@
import os
import sys
+import json

def process_data(data):
- if data is None:
- return None
+ if not data:
+ return {}

- result = data.strip()
+ try:
+ result = data.strip()
+ except AttributeError:
+ return {}
+
return result.upper()

def validate_input(input_str):"""
},
{
"old_path": "src/api/endpoints.py",
"new_path": "src/api/endpoints.py",
"diff": """@@ -15,8 +15,12 @@

@app.route('/api/users', methods=['GET'])
def get_users():
- users = db.query('SELECT * FROM users')
- return jsonify(users)
+ try:
+ users = db.query('SELECT * FROM users')
+ return jsonify(users)
+ except Exception as e:
+ logger.error(f"Database error: {e}")
+ return jsonify({'error': 'Internal server error'}), 500

@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):"""
}
]
return mock_changes

def filter_diff(diff_content):
"""过滤掉二进制文件和第三方库"""
binary_extensions = r"\.(png|jpg|jpeg|gif|svg|pdf|zip|tar|gz|jar|war|ear|class|so|dylib|dll|exe|bin)$"

if isinstance(diff_content, list):
filtered_changes = []

for change in diff_content:
file_path = change.get('new_path', '') or change.get('old_path', '')
if re.search(binary_extensions, file_path, re.IGNORECASE):
continue

diff = change.get('diff')
if diff and isinstance(diff, str):
filtered_changes.append(diff)

return '\n'.join(filtered_changes)

def gen_prompt(diff_content):
"""生成代码审查提示词"""
script_dir = os.path.dirname(os.path.abspath(__file__))
prompt_file = os.path.join(script_dir, 'codereview_prompt.md')

try:
with open(prompt_file, 'r', encoding='utf-8') as f:
template = Template(f.read())
return template.render(diff_content=diff_content)
except FileNotFoundError:
raise FileNotFoundError(f"Prompt file not found: {prompt_file}")
except Exception as e:
raise Exception(f"Error reading prompt file: {e}")

def check_codely_installed():
"""检查codely是否已安装"""
try:
result = subprocess.run(
['codely', '--version'],
capture_output=True, text=True, encoding='utf-8', errors='ignore'
)
return result.returncode == 0
except FileNotFoundError:
return False
except Exception as e:
print(f"检查codely安装状态时出错: {e}")
return False

def install_codely():
"""安装codely CLI工具"""
if check_codely_installed():
print("Codely CLI 已安装")
return True

print("正在安装 Codely CLI...")

install_cmd = [
'curl', '-fsSL', 'https://codesearch-plugins.tos-cn-shanghai.volces.com/codely-cli/install.sh'
]
bash_cmd = ['bash']

try:
curl_process = subprocess.run(
install_cmd, shell=False, check=False, text=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

if curl_process.returncode != 0:
print(f"下载安装脚本失败: {curl_process.stderr}")
return False

bash_process = subprocess.run(
bash_cmd, shell=False, check=False, text=True,
input=curl_process.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

if bash_process.returncode == 0:
print("Codely CLI 安装成功")
return True
else:
print(f"Codely CLI 安装失败: {bash_process.stderr}")
return False

except Exception as e:
print(f"安装 Codely CLI 异常: {str(e)}")
return False

def call_codely_for_review(diff_content, codely_token):
"""使用codely进行代码审查"""
request_start_time = time.time()

codely_available = check_codely_installed()
if not codely_available:
error_info = {"error": "Codely CLI 未安装或不可用"}
return error_info, "Codely CLI 未安装或不可用,请先安装 Codely CLI", {"error": "Codely CLI not available"}

prompt = gen_prompt(diff_content)
full_prompt = f"{prompt}"
safe_prompt = full_prompt

codely_cmd = ['codely', '-p', safe_prompt, '-y']

try:
env = os.environ.copy()
process = subprocess.run(
codely_cmd, shell=False, check=False, text=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', errors='ignore,
env=env
)

request_end_time = time.time()
request_duration_seconds = round(request_end_time - request_start_time, 3)

info = {
"model_name": "codely",
"token_info": {
"prompt_tokens": "N/A",
"completion_tokens": "N/A",
"total_tokens": "N/A"
},
"request_duration_seconds": request_duration_seconds
}

if process.returncode == 0:
generated_content = process.stdout.strip()
if not generated_content:
generated_content = "Tuanjie AI 执行成功但未返回内容"
else:
generated_content = f"Tuanjie AI 执行失败: {process.stderr.strip()}"

response_json = {
"stdout": process.stdout,
"stderr": process.stderr,
"returncode": process.returncode,
"command": ' '.join(codely_cmd) if isinstance(codely_cmd, list) else codely_cmd
}

return info, generated_content, response_json

except Exception as e:
error_info = {"error": str(e)}
return error_info, f"Tuanjie AI 调用异常: {str(e)}", {"error": str(e)}

def send_to_feishu(ai_review, project_name, commit_sha, mr_id=None, mr_url=None,
commit_url=None, webhook_url=None):
"""发送审查结果到飞书"""
# 构建链接文本
if mr_id:
button_text = "查看 Merge Request"
button_url = mr_url
else:
button_text = "查看完整提交"
button_url = commit_url

card_payload= {
"msg_type": "interactive",
"card": {
"schema": "2.0",
"config": {
"update_multi": True,
"style": {
"text_size": {
"normal_v2": {
"default": "normal",
"pc": "normal",
"mobile": "heading"
}
}
}
},
"body": {
"direction": "vertical",
"padding": "20px 20px 20px 20px",
"elements": [
{
"tag": "markdown",
"content": f"{ai_review}",
"text_align": "left",
"text_size": "normal_v2",
"margin": "0px 0px 0px 0px"
},
{
"tag": "button",
"text": {
"tag": "plain_text",
"content": button_text
},
"type": "default",
"width": "default",
"size": "medium",
"behaviors": [
{
"type": "open_url",
"default_url": button_url,
"pc_url": "",
"ios_url": "",
"android_url": ""
}
],
"margin": "0px 0px 0px 0px"
}
]
},
"header": {
"title": {
"tag": "plain_text",
"content": "📋 AI Code Review 报告"
},
"subtitle": {
"tag": "plain_text",
"content": ""
},
"template": "blue",
"padding": "12px 12px 12px 12px"
}
}
}

# 创建简单的文本消息(作为备用方案)
text_payload = {
"msg_type": "text",
"content": {
"text": f"AI Code Review for {project_name} ({commit_sha[:8]})\n\n{ai_review}"
}
}

# 尝试发送富文本卡片消息
try:
response = requests.post(
webhook_url,
headers={"Content-Type": "application/json"},
json=card_payload
)

if response.status_code == 200 and response.json().get("code") == 0:
print("富文本通知发送成功")
return True

# 如果卡片消息失败,尝试发送普通文本消息
print("富文本消息发送失败,尝试发送普通文本消息...")
response = requests.post(
webhook_url,
headers={"Content-Type": "application/json"},
json=text_payload
)

if response.status_code == 200 and response.json().get("code") == 0:
print("普通文本通知发送成功")
return True
else:
print(f"所有通知方式均失败,响应: {response.text}")
return False

except Exception as e:
print(f"发送通知异常: {str(e)}")
return False

def send_to_gitlab_mr(info, ai_review, project_path, mr_id, gitlab_base_url, gitlab_token):
"""发送审查结果到GitLab MR评论"""
if not mr_id:
print("没有提供MR ID,跳过发送到GitLab")
return False

encoded_project_path = requests.utils.quote(project_path, safe='')
api_url = f"{gitlab_base_url}/api/v4/projects/{encoded_project_path}/merge_requests/{mr_id}/notes"

headers = {
"Content-Type": "application/json",
"PRIVATE-TOKEN": gitlab_token
}

content = f"""
```
Model Name: {info.get("model_name", "N/A")}
Prompt Tokens: {info.get("token_info", {}).get("prompt_tokens", "N/A")}
Completion Tokens: {info.get("token_info", {}).get("completion_tokens", "N/A")}
Total Tokens: {info.get("token_info", {}).get("total_tokens", "N/A")}
Total Duration: {info.get("request_duration_seconds", "N/A")}s
```\n\n{ai_review}
"""
data = { "body": content }

try:
response = requests.post(api_url, headers=headers, json=data)

if response.status_code in [200, 201]:
print(f"成功发送审查结果到GitLab MR #{mr_id}")
return True
else:
print(f"发送到GitLab失败,状态码: {response.status_code}, 响应: {response.text}")
print("请检查Settings->CI/CD->Variables 是否配置了GITLAB_BASE_URL和GITLAB_BOT_TOKEN,如已配置,请检查是否过期。")
return False

except Exception as e:
print(f"发送到GitLab异常: {str(e)}")
return False

def main():
parser = argparse.ArgumentParser(description="Tuanjie AI 代码审查工具")
parser.add_argument("--local-test", action="store_true", help="使用mock数据进行本地测试")
args = parser.parse_args()

mr_id = os.getenv("CI_MERGE_REQUEST_IID")
commit_sha = os.getenv("CI_COMMIT_SHA")
project_name = os.getenv("CI_PROJECT_NAME")
project_path = os.getenv("CI_PROJECT_PATH")
codely_token = os.getenv("CODELY_TOKEN")
gitlab_base_url = os.getenv("GITLAB_BASE_URL")
gitlab_bot_token = os.getenv("GITLAB_BOT_TOKEN")
feishu_webhook_url = os.getenv("FEISHU_WEBHOOK_URL", "")

if args.local_test:
print("启用本地测试模式,使用mock数据")
diff_content = get_mock_diff_data()
project_name = project_name or "test-project"
commit_sha = commit_sha or "abc123456"
mr_id = mr_id or "1"
else:
diff_content = get_mr_diff_via_api(
project_path=project_path,
mr_id=mr_id,
gitlab_token=gitlab_bot_token,
gitlab_base_url=gitlab_base_url
)

filtered_diff = filter_diff(diff_content)

if not filtered_diff:
print("没有需要审查的代码变更,跳过审查流程")
return 0

print("使用 Tuanjie AI 做代码审查")

if not install_codely():
print("Codely CLI 安装失败,审查终止")
return 1

info_codely, ai_review_codely, response_json_codely = call_codely_for_review(filtered_diff, codely_token)

with open("ai_review_codely.txt", "w", encoding="utf-8") as f:
f.write(ai_review_codely)

with open("response_codely.json", "w", encoding="utf-8") as f:
json.dump(response_json_codely, f, indent=2, ensure_ascii=False)

if args.local_test:
print("本地测试模式,跳过发送到GitLab")
gitlab_success = True
else:
gitlab_success = send_to_gitlab_mr(
info=info_codely,
ai_review=ai_review_codely,
project_path=project_path,
mr_id=mr_id,
gitlab_base_url=gitlab_base_url,
gitlab_token=gitlab_bot_token
)

# 发送到飞书
feishu_success = False
if feishu_webhook_url:
feishu_success = send_to_feishu(
ai_review=ai_review_codely,
project_name=project_name,
commit_sha=commit_sha,
mr_id=mr_id,
mr_url=f"{gitlab_base_url}/{project_path}/-/merge_requests/{mr_id}" if mr_id else None,
commit_url=f"{gitlab_base_url}/{project_path}/-/commit/{commit_sha}" if commit_sha else None,
webhook_url=feishu_webhook_url
)
else:
feishu_success = True
print("没有配置飞书Webhook URL,跳过发送到飞书")

return 0 if (feishu_success and gitlab_success) else 1

if __name__ == "__main__":
sys.exit(main())

文件说明:

  • codereview_prompt.md:作为 AI 评审的指令模板文件,你可根据团队的代码规范、业务场景自定义评审维度(如代码风格、性能、安全、逻辑合理性等),让 AI 评审更贴合团队实际需求。

  • ai-code-review.py:作为 Code Review 的执行入口脚本,其核心功能包含四大模块:

    1. 自动检测并安装 Codely CLI,确保工具环境可用
    2. 拉取 MR 中代码的 Diff 内容,定位本次变更的核心代码片段
    3. 基于自定义 Prompt 模板,调用 Codely CLI 完成自动化代码评审
    4. 将评审结果以结构化形式写入 GitLab MR 评论区,同时推送到飞书群聊机器人,实现评审结果实时同步

配置GitLab/GitHub环境变量

为保证脚本正常运行,需在 GitLab 项目的 Settings > CI/CD > Variables 中配置相关环境变量,变量说明与配置要求如下表所示:

变量名描述示例值注意事项必填
CODELY_TOKENTuanjie AI API访问令牌your-codely-token需要访问 https://codely.tuanjie.cn/dashboard/access-tokens 生成
GITLAB_BOT_TOKENGitLab机器人访问令牌xxxxxxxxxxxxxxxx需要在GitLab Settings > Access Tokens生成,必须勾选scope:api, read_api, read_repository, write_repository
FEISHU_WEBHOOK_URL飞书群聊机器人Webhook地址https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxx需要在飞书群聊添加自定义机器人获取,不配置此项默认跳过飞书发送
GITLAB_BASE_URLGitLab API基础URL从.gitlab-ci.yml读取如需覆盖默认值可配置此变量
ENABLE_AI_CODE_REVIEW是否启用AI代码审查从.gitlab-ci.yml读取如需覆盖默认值可配置此变量

注意事项:

  • CODELY_TOKEN:Tuanjie AI Token 为个人令牌,需要妥善保管,避免泄露。
Bridge
  • GITLAB_BOT_TOKEN:GitLab Bot Token 为机器人令牌,机器人名称即为显示在评论区的用户名,需要妥善保管,避免泄露。
Bridge
  • FEISHU_WEBHOOK_URL:飞书 Webhook 为群聊机器人Webhook,通过在飞书群聊添加自定义机器人获取。
Bridge Bridge

环境变量配置

  1. 进入 GitLab 项目页面,点击Settings → CI/CD;
  2. 展开Variables部分,点击Add variable按钮;
  3. 输入变量名和对应值,敏感信息(如各类 Token)务必勾选Mask variable,避免日志明文泄露;
  4. 点击Add variable保存,非必要不勾选Protect variable和Expand variable reference,否则可能导致 CI 流水线执行失败。
Bridge

GitLab CI 配置

在项目根目录添加.gitlab-ci.yml文件,通过 CI/CD 流水线实现 "MR 提交即触发 AI 评审" 的自动化流程,配置内容与说明如下:

default:
tags:
- codereview
- docker
- shared

workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"

variables:
GITLAB_BASE_URL:
description: the base url of the gitlab api
value: "https://gitlab.xxx.xxx.xxx"
ENABLE_AI_CODE_REVIEW:
description: whether to enable AI code review for merge requests
value: "true"

stages:
- code_review

ai_code_review:
stage: code_review
image: python:3.11-slim
before_script:
- pip install requests jinja2
- apt-get update && apt-get install -y curl && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/*
script:
- echo "Starting AI code review for merge request $CI_MERGE_REQUEST_IID"
- python codereview/ai-code-review.py
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $ENABLE_AI_CODE_REVIEW == "true" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "prod")
allow_failure: false
variables:
GIT_DEPTH: 0
artifacts:
reports:
junit: ai_review_codely.txt
expire_in: 1 week
when: always

核心触发规则说明:

  • 仅在 MR 事件触发时运行,避免无关流水线消耗资源
  • 仅对合并到main/master/prod等核心分支的 MR 进行评审,聚焦关键代码变更
  • 通过ENABLE_AI_CODE_REVIEW变量可灵活开关评审功能,便于测试与维护

查看评审结果

Tuanjie AI 完成 AI 代码审查后,会输出多维度、结构化的评审结果,并同步至 GitLab MR 评论区与飞书群聊,具体包含:

  1. 代码质量评估:从代码规范、编程语言最佳实践、注释完整性等维度给出评分与建议
  2. 潜在问题识别:精准定位代码中的 bug、逻辑漏洞、安全风险(如 SQL 注入、越权访问)、性能瓶颈(如低效算法、重复查询)
  3. 改进建议:提供具体的代码优化方案,包括代码片段示例、重构思路等
  4. 资源消耗统计:展示本次 API 调用的 Tuanjie AI Token 消耗情况,便于成本管控

审查结果会以结构化的Markdown格式展示在MR评论中。

Bridge