เนื้อหาในบทความนี้
1 บทนำ: Code Review ด้วย AI คืออะไร?
AI-powered Code Review คือการใช้ Artificial Intelligence โดยเฉพาะ Large Language Models (LLMs) เพื่อวิเคราะห์ ตรวจสอบ และให้ feedback บน source code อัตโนมัติ โดยไม่ต้องให้มนุษย์ review ทุกบรรทัด
ปัญหาของ Manual Code Review
- ใช้เวลามาก: Reviewer ต้องใช้เวลาหลายชั่วโมงสำหรับ PR ขนาดใหญ่
- ขาดความสม่ำเสมอ: แต่ละ reviewer มีมาตรฐานและ focus ต่างกัน
- พลาด security bugs: คน review อาจพลาด issues ที่ subtle หรือซับซ้อน
- Bottleneck: Review ช้าทำให้ deployment ล่าช้า
วิวัฒนาการของ Code Review
Manual Review
คน review code ทุกบรรทัดด้วยตัวเอง
AI Review (Cloud)
GitHub Copilot, GitLab Duo - ส่ง code ไป cloud
Local LLM + CI/CD
Ollama + GitLab CI - Private, fast, local
ทำไม Local LLM (Ollama) เป็นทางเลือกที่น่าสนใจในปี 2024-2026?
- Privacy & Security: Code ไม่ถูกส่งไปที่ cloud เหมาะสำหรับ banking, government, fintech
- Speed: Local inference เร็วกว่า เพราะไม่ต้องออก internet
- Cost: ไม่มีค่า API call per token, เหมาะสำหรับ large codebases
- Customization: เลือก model ที่เหมาะสม (CodeLlama, Llama 3, Mistral)
2 แหล่งข้อมูลหลักจาก US Tech Sources
บทความนี้รวบรวมข้อมูลจากแหล่งข้อมูลแหล่งน่าเชื่อถือจากสหรัฐอเมริกา ปี 2024-2025 ดังนี้:
Ollama - Local LLM Runtime
Ollama คือ framework สำหรับ run LLMs แบบ local บน macOS, Linux, Windows รองรับหลาย models (Llama 3, Mistral, CodeLlama)
https://ollama.aiGitLab CI/CD Pipeline Automation
GitLab CI มี pipeline orchestration ที่ powerful สามารถใช้ Docker containers เพื่อ run custom tools
GitLab CI DocumentationGitHub Copilot & AI Code Review
GitHub Copilot, GitLab Duo ใช้ LLMs (GPT-4, Claude) สำหรับ code review และ PR suggestions
GitHub CopilotLLMs for Code Review Research
Research จาก papers: "LLMs for Automated Code Review", "CodeT5", "CodeBERT" - การใช้ models พิเศษสำหรับ code
Note: แหล่งข้อมูลทั้งหมดเป็น US-based tech sources ที่ได้รับการตรวจสอบและเชื่อถือได้
3 การประยุกต์ใช้ในประเทศไทย
E-commerce Companies
บริษัท E-commerceใช้ AI code review สำหรับ Laravel/PHP projects ลดเวลา review และค้นหา security issues
Use Case
SQL Injection detection, Authentication bugs, Laravel best practices
Government Systems
หน่วยงานราชการLocal LLM เหมาะสำหรับ government เพราะ data security, ไม่ต้องส่ง code ไป cloud
Use Case
Compliance checks, Security review, Data protection compliance
Fintech Companies
บริษัท Financial TechAI review ก่อน merge production ลดความเสี่ยงของ financial transaction bugs
Use Case
Input validation, Race condition detection, Security patterns
Thai Startups
สตาร์ทอัพไทยลดรอบการ review และให้ developers focus บน features มากกว่า manual review
Use Case
Speed up development, Reduce review backlog, Quality assurance
4 สิ่งที่ต้องเตรียม
Software Requirements
-
GitLab.com หรือ GitLab Self-Hosted (with CI/CD enabled)
ต้องเปิดใช้ GitLab Runner
-
Docker และ Docker Compose
สำหรับ build containers
-
Ollama (Local LLM runtime)
ดูวิธีติดตั้งใน Section 5
-
Python 3.9+ สำหรับ script automation
pip install ollama requests
Hardware Requirements
Minimum (LLM 7B)
- RAM: 8GB
- Storage: 20GB (free space)
- OS: macOS, Linux, Windows
- CPU: Multi-core (4+ cores recommended)
Recommended (LLM 13B+)
- RAM: 16GB+
- GPU: NVIDIA GPU (optional, faster inference)
- OS: Linux (best for production)
- CPU: 8+ cores
LLM Models ที่รองรับ (ติดตั้งผ่าน Ollama)
CodeLlama 7B
สาย coding เฉพาะทาง
ollama pull codellama:7b
Llama 3 8B
General purpose, powerful
ollama pull llama3:8b
Mistral 7B
Fast, efficient, good quality
ollama pull mistral:7b
5 ขั้นตอนที่ 1: ติดตั้ง Ollama
Ollama คือ tool สำหรับ run LLMs แบบ local ง่ายและรวดเร็ว รองรับ macOS, Linux, Windows
1 ติดตั้ง Ollama
# macOS (Apple Silicon or Intel)
curl -fsSL https://ollama.ai/install.sh | sh
# Linux (Ubuntu, Debian, etc.)
curl -fsSL https://ollama.ai/install.sh | sh
# Windows (PowerShell as Administrator)
winget install Ollama.Ollama
# หรือ download จาก https://ollama.ai/download
Tip: หลังจากติดตั้ง คุณสามารถเปิด Ollama app แล้ว run ผ่าน command line
2 ติดตั้ง LLM Model
เลือก model ที่เหมาะสำหรับ code review:
# ติดตั้ง CodeLlama 7B (เหมาะสำหรับ coding)
ollama pull codellama:7b
# หรือ Llama 3 8B (General purpose, powerful)
ollama pull llama3:8b
# หรือ Mistral 7B (Fast และ efficient)
ollama pull mistral:7b
Recommendation: เริ่มด้วย codellama:7b สำหรับ code review
3 ทดสอบ Ollama
ทดสอบว่า Ollama และ model ทำงานได้:
# รัน model เพื่อ review code
ollama run codellama:7b "Review this PHP code for security issues:
<?php
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = $db->query($query);
?>"
Expected Output:
Based on the PHP code provided, I've identified several security issues:
1. SQL Injection Vulnerability:
The code constructs a SQL query by directly concatenating user input ($_GET['id']) into the query string. This is a classic SQL injection vulnerability.
Fix:
Use prepared statements with PDO:
```php
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
```
4 ตรวจสอบ Ollama Server
Ollama จะเริ่ม server ที่ http://localhost:11434 โดยอัตโนมัติ หลังจากติดตั้ง
# ทดสอบ Ollama API
curl http://localhost:11434/api/generate -d '{
"model": "codellama:7b",
"prompt": "Hello"
}'
Success: ถ้าได้ response แสดงว่า Ollama server ทำงานได้ถูกต้อง
6 ขั้นตอนที่ 2: สร้าง GitLab CI Pipeline สำหรับ Code Review
สถาปัตยกรรม AI Code Review
เมื่อ developer push code, GitLab CI จะ:
- Trigger Pipeline - เมื่อ MR ถูกสร้างหรือ code ถูก push
- Run Docker Container - GitLab Runner จะ spin up Docker container พร้อม Python script
- Fetch Code - Script จะ fetch code จาก GitLab API
- Send to Ollama - Script ส่ง code ไปให้ Ollama review
- Parse Response - Script แปลง AI response เป็น format ที่ GitLab รองรับ
- Post Comments - Script โพสต์ comments บน MR
.gitlab-ci.yml Configuration
stages:
- code-review
# AI Code Review Stage
ai-code-review:
stage: code-review
image: python:3.11
services:
- docker:dind # Docker-in-Docker
variables:
OLLAMA_BASE_URL: "http://host.docker.internal:11434" # หรือ host.docker.internal
script:
# Install dependencies
- pip install ollama requests
# Run code review script
- python scripts/code_review.py
artifacts:
reports:
codequality: gl-code-quality-report.json # GitLab Code Quality report
only:
- merge_requests # Run ก็ต่อเมื่อมี MR เท่านั้น
allow_failure: true # ไม่ให้ fail ถ้า AI review ไม่สำเร็จ
Important: host.docker.internal ใช้สำหรับเชื่อมต่อจาก Docker container ไป host machine (ที่ Ollama รันอยู่)
ติดตั้ง GitLab Runner (ถ้าจำเป็น)
ถ้าใช้ GitLab.com จะมี shared runners ให้ใช้ แต่ถ้าต้องการ control เอง:
# Register GitLab Runner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get install gitlab-runner
# Register runner
sudo gitlab-runner register
# ใส่ GitLab instance URL และ registration token
Note: สำหรับ GitLab.com สามารถใช้ shared runners ได้เลย โดยไม่ต้องติดตั้ง runner เอง
7 ขั้นตอนที่ 3: Python Script สำหรับ AI Code Review
Python script นี้จะทำงานใน GitLab CI, fetch code จาก GitLab API, ส่งให้ Ollama review, และโพสต์ comments บน MR
scripts/code_review.py
#!/usr/bin/env python3
"""
AI Code Review Script for GitLab CI/CD
Uses Ollama Local LLM to review code changes
"""
import os
import json
import requests
from urllib.parse import urljoin
# Configuration
OLLAMA_BASE_URL = os.getenv('OLLAMA_BASE_URL', 'http://host.docker.internal:11434')
OLLAMA_MODEL = os.getenv('OLLAMA_MODEL', 'codellama:7b')
# GitLab Configuration
GITLAB_TOKEN = os.getenv('GITLAB_TOKEN') # จาก CI/CD Variables
GITLAB_API_URL = os.getenv('CI_API_V4_URL', 'https://gitlab.com/api/v4')
PROJECT_ID = os.getenv('CI_PROJECT_ID')
MR_IID = os.getenv('CI_MERGE_REQUEST_IID')
MR_SOURCE_BRANCH = os.getenv('CI_MERGE_REQUEST_SOURCE_BRANCH')
def get_merge_request_diff():
"""Get code diff from merge request"""
url = f"{GITLAB_API_URL}/projects/{PROJECT_ID}/merge_requests/{MR_IID}/diff"
headers = {'PRIVATE-TOKEN': GITLAB_TOKEN}
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
def send_to_ollama(code_diff, file_path):
"""Send code diff to Ollama for review"""
url = urljoin(OLLAMA_BASE_URL, '/api/generate')
# Build prompt for code review
prompt = f"""Review this code diff for security issues, bugs, and best practices:
File: {file_path}
Diff:
{code_diff}
Focus on:
1. Security vulnerabilities (SQL injection, XSS, etc.)
2. Code quality issues
3. Best practices
4. Potential bugs
Provide your response in JSON format:
{{
"issues": [
{{
"severity": "high|medium|low",
"line": line_number,
"message": "Description of the issue",
"suggestion": "Suggested fix"
}}
],
"summary": "Overall assessment"
}}"""
payload = {
"model": OLLAMA_MODEL,
"prompt": prompt,
"stream": False,
"format": "json" # Try to get JSON response
}
try:
response = requests.post(url, json=payload, timeout=60)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error calling Ollama: {e}")
return None
def parse_ai_response(response):
"""Parse AI response into structured format"""
if not response or 'response' not in response:
return []
ai_output = response['response']
# Try to parse JSON from AI response
try:
# AI might output JSON directly or wrapped in text
start = ai_output.find('{')
end = ai_output.rfind('}') + 1
if start != -1 and end > start:
json_str = ai_output[start:end]
parsed = json.loads(json_str)
return parsed.get('issues', [])
except json.JSONDecodeError:
pass
# Fallback: parse manually
issues = []
lines = ai_output.split('\n')
for line in lines:
if 'security' in line.lower() or 'vulnerability' in line.lower():
issues.append({
'severity': 'high',
'line': 'unknown',
'message': line.strip(),
'suggestion': ''
})
return issues
def post_merge_request_comment(issues):
"""Post code review comments to merge request"""
if not issues:
print("No issues found by AI review.")
return
url = f"{GITLAB_API_URL}/projects/{PROJECT_ID}/merge_requests/{MR_IID}/notes"
headers = {'PRIVATE-TOKEN': GITLAB_TOKEN}
# Build comment body
comment = "## 🔍 AI Code Review Results\n\n"
severity_emoji = {
'high': '🔴',
'medium': '🟡',
'low': '🟢'
}
for issue in issues:
severity = issue.get('severity', 'medium')
emoji = severity_emoji.get(severity, '⚪')
message = issue.get('message', 'No message')
line = issue.get('line', 'N/A')
suggestion = issue.get('suggestion', '')
comment += f"{emoji} **{severity.upper()}** (Line {line}): {message}\n"
if suggestion:
comment += f" 💡 *Suggestion:* {suggestion}\n"
comment += "\n"
comment += "\n---\n"
comment += "*Powered by Ollama (Local LLM)*"
payload = {'body': comment}
try:
response = requests.post(url, headers=headers, data=payload)
response.raise_for_status()
print("Code review comment posted successfully!")
except requests.exceptions.RequestException as e:
print(f"Error posting comment: {e}")
def generate_code_quality_report(issues):
"""Generate GitLab Code Quality report"""
report = []
for issue in issues:
report_item = {
"type": issue.get('severity', 'medium'),
"check_name": "AI Code Review",
"description": issue.get('message', 'No message'),
"content": issue.get('suggestion', ''),
"severity": issue.get('severity', 'medium'),
"location": {
"path": issue.get('file_path', 'unknown'),
"lines": {
"begin": int(issue.get('line', 0))
}
}
}
report.append(report_item)
# Save report
with open('gl-code-quality-report.json', 'w') as f:
json.dump(report, f, indent=2)
print(f"Generated code quality report with {len(issues)} issues")
def main():
print("Starting AI Code Review...")
print(f"Ollama URL: {OLLAMA_BASE_URL}")
print(f"Model: {OLLAMA_MODEL}")
# Get merge request diff
diffs = get_merge_request_diff()
print(f"Found {len(diffs)} changed files")
all_issues = []
# Review each changed file
for diff in diffs:
file_path = diff.get('new_path', 'unknown')
diff_text = diff.get('diff', '')
if not diff_text:
continue
print(f"Reviewing {file_path}...")
# Send to Ollama
ai_response = send_to_ollama(diff_text, file_path)
# Parse AI response
issues = parse_ai_response(ai_response)
# Add file path to issues
for issue in issues:
issue['file_path'] = file_path
all_issues.extend(issues)
# Post comments to MR
if all_issues:
print(f"Found {len(all_issues)} issues total")
post_merge_request_comment(all_issues)
generate_code_quality_report(all_issues)
else:
print("No issues found!")
print("AI Code Review completed!")
if __name__ == '__main__':
main()
การตั้งค่า Environment Variables ใน GitLab CI
- •
OLLAMA_BASE_URL- URL ของ Ollama server - •
OLLAMA_MODEL- Model ที่ต้องการใช้ (codellama:7b) - •
GITLAB_TOKEN- GitLab Personal Access Token (with api scope)
สร้าง GitLab Personal Access Token
- 1 ไปที่ Settings > Access Tokens ใน GitLab
- 2 คลิก Add new token
-
3
เลือก scopes:
api(เป็นอย่างน้อย) - 4 Copy token และเพิ่มเป็น CI/CD Variable ใน project
8 ตัวอย่าง PHP
ตัวอย่าง PHP code พร้อมการ review จาก AI และแนวทางการแก้ไข:
ตัวอย่าง 1: SQL Injection Vulnerability
❌ Code ที่มีปัญหา
<?php
function getUserData($userId) {
$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
// ❌ SQL Injection vulnerability!
$query = "SELECT * FROM users WHERE id = " . $userId;
$result = $db->query($query);
return $result->fetchAll(PDO::FETCH_ASSOC);
}
// Usage
$userId = $_GET['id']; // User input
$userData = getUserData($userId);
print_r($userData);
?>
✅ Code ที่แก้ไขแล้ว
<?php
function getUserData(PDO $db, $userId) {
try {
// ✅ Use prepared statements
$stmt = $db->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam(':id', $userId, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("Database error: " . $e->getMessage());
return false;
}
}
// Usage
$db = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$userId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($userId === false) {
die("Invalid user ID");
}
$userData = getUserData($db, $userId);
print_r($userData);
?>
AI Code Review Feedback
🔴 HIGH SEVERITY: SQL Injection vulnerability detected.
The code constructs SQL query by directly concatenating user input ($userId). Attacker can inject malicious SQL.
💡 Suggestion:
- Use PDO prepared statements with parameterized queries
- Validate input type (ensure $userId is integer)
- Add error handling with try-catch
ตัวอย่าง 2: Missing Input Validation & XSS
❌ Code ที่มีปัญหา
<?php
// Process user registration
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];
// ❌ No validation!
// ❌ No XSS protection!
if (strlen($password) < 6) {
echo "Password too short";
exit;
}
// Save to database
$query = "INSERT INTO users (name, email, password) VALUES (?, ?, ?)";
$stmt = $db->prepare($query);
$stmt->execute([$name, $email, password_hash($password, PASSWORD_DEFAULT)]);
// ❌ XSS vulnerability when displaying
echo "Welcome, " . $name . "!";
?>
✅ Code ที่แก้ไขแล้ว
<?php
// ✅ Validate and sanitize input
function validateInput($data) {
return htmlspecialchars(strip_tags(trim($data)), ENT_QUOTES, 'UTF-8');
}
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
// Process user registration
$name = validateInput($_POST['name']);
$email = validateEmail($_POST['email']);
$password = $_POST['password'];
// ✅ Enhanced validation
if (empty($name) || empty($email) || empty($password)) {
throw new InvalidArgumentException("All fields are required");
}
if (strlen($password) < 8) {
throw new InvalidArgumentException("Password must be at least 8 characters");
}
if ($email === false) {
throw new InvalidArgumentException("Invalid email address");
}
// Save to database
$stmt = $db->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)");
$stmt->execute([$name, $email, password_hash($password, PASSWORD_DEFAULT)]);
// ✅ XSS protected output
echo "Welcome, " . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . "!";
?>
AI Code Review Feedback
🟡 MEDIUM SEVERITY: Missing input validation.
User inputs ($_POST) are not validated or sanitized, leading to potential security issues.
🔴 HIGH SEVERITY: XSS vulnerability.
Echoing user input ($name) directly to HTML allows attackers to inject malicious scripts.
💡 Suggestions:
- Validate email format with filter_var()
- Sanitize HTML output with htmlspecialchars()
- Use prepared statements for database (already done)
- Implement proper error handling
ตัวอย่าง 3: Laravel Best Practices
❌ Anti-Pattern
// routes/web.php
Route::get('/users', function () {
// ❌ Business logic in route
$users = DB::table('users')
->where('active', true)
->orderBy('created_at', 'desc')
->get();
return response()->json($users);
});
// app/Http/Controllers/UserController.php
class UserController extends Controller {
// ❌ No type hints
public function store(Request $request) {
$data = $request->all();
// ❌ Mass assignment vulnerability
$user = User::create($data);
return response()->json($user, 201);
}
}
✅ Best Practice
// routes/web.php
Route::apiResource('users', UserController::class);
// app/Http/Controllers/UserController.php
class UserController extends Controller {
// ✅ Type hints
public function index(ShowUsersRequest $request): JsonResponse {
$users = User::active()
->latest()
->paginate($request->get('per_page', 15));
return UserResource::collection($users);
}
// ✅ Form Request validation
public function store(StoreUserRequest $request): JsonResponse {
$validated = $request->validated();
// ✅ Safe mass assignment
$user = User::create($validated);
return new UserResource($user);
}
}
AI Code Review Feedback
🟡 LOW SEVERITY: Business logic in routes.
Routes should be thin. Move database queries to Controllers or Services.
🟡 MEDIUM SEVERITY: Mass assignment vulnerability.
Using $request->all() without validation can expose sensitive fields.
💡 Suggestions:
- Use Form Request classes for validation (StoreUserRequest)
- Define $fillable or $guarded in User model
- Use API Resources for JSON response formatting
- Add type hints for better IDE support
9 ตัวอย่าง Node.js
ตัวอย่าง Node.js code พร้อมการ review จาก AI และแนวทางการแก้ไข:
ตัวอย่าง 1: Express.js Security Issues
❌ Code ที่มีปัญหา
const express = require('express');
const app = express();
const db = require('./db');
// ❌ No helmet security headers
app.use(express.json());
app.get('/api/users/:id', async (req, res) => {
const userId = req.params.id;
// ❌ SQL Injection!
const query = `SELECT * FROM users WHERE id = ${userId}`;
const result = await db.query(query);
// ❌ No error handling
res.json(result.rows);
});
app.post('/api/users', async (req, res) => {
const { name, email } = req.body;
// ❌ No input validation
const query = `INSERT INTO users (name, email) VALUES ('${name}', '${email}')`;
await db.query(query);
res.status(201).json({ message: 'Created' });
});
app.listen(3000);
✅ Code ที่แก้ไขแล้ว
const express = require('express');
const helmet = require('helmet');
const { body, param, validationResult } = require('express-validator');
const app = express();
const db = require('./db');
// ✅ Security headers
app.use(helmet());
app.use(express.json());
app.get('/api/users/:id',
[param('id').isInt()],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const userId = parseInt(req.params.id, 10);
try {
// ✅ Parameterized query
const result = await db.query(
'SELECT id, name, email FROM users WHERE id = $1',
[userId]
);
if (result.rows.length === 0) {
return res.status(404).json({ error: 'User not found' });
}
res.json(result.rows[0]);
} catch (error) {
console.error('Database error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
);
app.post('/api/users',
[
body('name').trim().notEmpty(),
body('email').isEmail().normalizeEmail()
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, email } = req.body;
try {
const result = await db.query(
'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
[name, email]
);
res.status(201).json(result.rows[0]);
} catch (error) {
console.error('Database error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
);
app.listen(3000, () => console.log('Server running'));
AI Code Review Feedback
🔴 HIGH SEVERITY: SQL Injection vulnerabilities.
Both GET and POST routes construct SQL queries with user input concatenation.
🟡 MEDIUM SEVERITY: Missing security headers.
No Helmet middleware or CORS configuration, exposing to various attacks.
💡 Suggestions:
- Use parameterized queries ($1, $2) with pg or mysql2
- Add Helmet middleware for security headers
- Implement input validation with express-validator
- Add proper error handling with try-catch
- Consider using an ORM like Sequelize or TypeORM
ตัวอย่าง 2: TypeScript Best Practices
❌ Anti-Pattern
// ❌ No types
async function getUserData(id) {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return data;
}
// ❌ Callback hell
function processUsers(users, callback) {
const results = [];
users.forEach(user => {
getUserData(user.id).then(data => {
results.push(data);
if (results.length === users.length) {
callback(results);
}
});
});
}
// ❌ No error handling
processUsers(userList, data => {
console.log(data);
});
✅ Best Practice
// ✅ Type definitions
interface User {
id: number;
name: string;
email: string;
}
async function getUserData(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data: User = await response.json();
return data;
}
// ✅ Async/await with Promise.all
async function processUsers(users: User[]): Promise<User[]> {
try {
const userPromises = users.map(user =>
getUserData(user.id)
);
const results = await Promise.all(userPromises);
return results;
} catch (error) {
console.error('Error processing users:', error);
throw error; // Re-throw for caller to handle
}
}
// ✅ Proper error handling
(async () => {
try {
const processedUsers = await processUsers(userList);
console.log('Processed:', processedUsers);
} catch (error) {
console.error('Failed:', error);
// Show error to user
}
})();
AI Code Review Feedback
🟡 LOW SEVERITY: Missing TypeScript types.
Without type definitions, code is harder to maintain and prone to runtime errors.
🟡 MEDIUM SEVERITY: Callback hell pattern.
Using nested callbacks instead of async/await or Promises makes code hard to read and error-prone.
🔴 HIGH SEVERITY: No error handling.
Async operations without try-catch or .catch() will silently fail.
💡 Suggestions:
- Define TypeScript interfaces for all data structures
- Use async/await instead of callbacks
- Use Promise.all() for parallel async operations
- Add proper error handling with try-catch
- Consider using a logging library like winston or pino
10 Advanced Features
Multi-File Review
Review หลายไฟล์พร้อมกัน และสรุป issues ระหว่างไฟล์:
# Review multiple files
issues = []
for file in changed_files:
issues += review_file(file)
# Track cross-file issues
summary = analyze_cross_file_relationships(issues)
Custom Review Rules
กำหนด custom rules สำหรับ PHP/Node.js standards:
# Custom PHP rules
rules = [
"PSR-12 coding standards",
"Laravel best practices",
"Company-specific patterns"
]
# Custom Node.js rules
rules = [
"TypeScript strict mode",
"ESLint configuration",
"Security guidelines"
]
Performance Optimization
ปรับปรุง performance:
- • Cache LLM responses (Redis/File)
- • Batch processing (parallel reviews)
- • Use smaller models for quick checks
- • Limit review to changed files only
Additional Integrations
เชื่อมต่อกับ tools อื่น:
- • SonarQube (static analysis)
- • Slack/Discord (notifications)
- • Jira (bug tracking)
- • GitHub/GitLab (PR integration)
11 Troubleshooting
ปัญหา: Ollama connection timeout
Docker container ไม่สามารถเชื่อมต่อกับ Ollama server ได้
Solution:
- • ใช้
host.docker.internalแทนlocalhost - • ตรวจสอบว่า Ollama server กำลังรันอยู่:
ollama list - • Restart Ollama server:
ollama serve
ปัญหา: LLM out of memory
Model 13B+ ใช้ memory เยอะเกินไป
Solution:
- • ใช้ model เล็กกว่า:
codellama:7bแทนcodellama:13b - • เพิ่ม RAM หรือใช้ GPU
- • ตั้งค่า Ollama ให้ใช้ memory น้อยลง
ปัญหา: GitLab CI resource limits
Pipeline timeout หรือ out of memory
Solution:
- • ตั้งค่า timeout:
timeout: 5mใน .gitlab-ci.yml - • ใช้ self-hosted runner พร้อม resource เพิ่ม
- • Split review หลาย stages
ปัญหา: AI response quality poor
AI ให้ feedback ที่ไม่เป็นประโยชน์หรือเข้าใจผิด
Solution:
- • Tune prompt เพื่อให้เฉพาะเจาะจงมากขึ้น
- • ใช้ model ที่เหมาะสม:
codellama:7bสำหรับ code - • เพิ่ม context เช่น language, framework version
- • Fine-tune model สำหรับ codebase ของคุณ
12 สรุปและขั้นตอนถัดไป
สรุปสิ่งที่ได้เรียนรู้
ข้อดีของ Ollama + GitLab CI
- ✅ Privacy: Code ไม่ถูกส่งไป cloud
- ✅ Speed: Local inference เร็วกว่า
- ✅ Cost: ไม่มี API costs
- ✅ Customization: เลือก model ได้
สิ่งที่ได้เรียนรู้
- ✅ ติดตั้งและตั้งค่า Ollama
- ✅ สร้าง GitLab CI Pipeline
- ✅ เขียน Python script สำหรับ AI review
- ✅ Apply กับ PHP และ Node.js
เมื่อไหร่ควรใช้ AI vs Manual Code Review
🤖 ใช้ AI Review เมื่อ:
- • PR ขนาดเล็กถึงกลาง (< 500 lines)
- • ตรวจสอบ security issues ทั่วไป
- • ตรวจสอบ best practices ของ language
- • เพิ่มความสม่ำเสมอ
👥 ใช้ Manual Review เมื่อ:
- • PR ขนาดใหญ่หรือ complex
- • Architecture หรือ design decisions
- • Business logic ที่ซับซ้อน
- • Performance considerations
ข้อจำกัดของ AI Code Review
- Quality depends on model: CodeLlama 7B อาจไม่ถูกต้องสำหรับ complex code
- Resource usage: LLMs ใช้ memory และ CPU เยอะ
- False positives: AI อาจแจ้งว่าเป็น issue แต่จริงๆ ไม่ใช่
- No context awareness: AI ไม่เข้าใจ codebase ของคุณทั้งหมด
ขั้นตอนถัดไป (Next Steps)
ทดลองกับ Production Code
Apply AI review กับ MRs จริงใน project ของคุณ
ปรับแต่ง Prompts
Tune prompts ให้เฉพาะเจาะจงกับ codebase ของคุณ
Monitor Performance
ติดตาม review time, quality, และ developer feedback
Learn AI/ML for DevOps
ศึกษา fundamentals ของ LLMs และ integration patterns