個人開発を続けていると、自分の書いたコードを誰かにレビューしてもらう機会がほとんどありません。私自身、アプリや複数のブログを一人で運用していて、プルリクエストを出しても承認するのは自分だけ、という状況が長く続いてきました。見落としに気づくのはたいてい、本番で何かが壊れた後です。
だからこそ、二人目の視点を機械的にでも補ってくれる仕組みには助けられています。Antigravity Editor の AI コードレビューは、その「もう一人のレビュアー」を担ってくれる機能です。静的解析と機械学習を組み合わせ、バグ・セキュリティ脆弱性・パフォーマンスの問題を、コミットの直後に指摘してくれます。
以下では、私が実際に使いながら掴んだ勘所――どのモードから始めるか、誤検知とどう折り合いをつけるか、PR ワークフローへどう組み込むか――を順に整理していきます。
AI コードレビューの基本概念
何ができるのか
Antigravity の AI コードレビューは、以下の複数のチェック観点をカバーしています:
- セキュリティスキャン — SQL インジェクション、XSS、認証バイパスなどの脆弱性検出
- パフォーマンス分析 — 非効率なアルゴリズム、メモリリーク、不適切なキャッシング
- コード品質 — 命名規約違反、複雑度が高い関数、未使用変数の検出
- バグ予測 — 論理的エラー、型安全性の問題、例外処理の不備
- セキュリティベストプラクティス — 認証・認可の実装方法、トークン管理など
- テストカバレッジ — テストが不足している重要なコードパス
- 可読性・保守性 — ドキュメント不足、複雑な分岐、マジックナンバーの検出
AI コードレビュー vs 従来のレビュー
| 観点 | AI レビュー | 従来の手動レビュー |
|---|---|---|
| 実行時間 | 数秒~数分 | 数時間~数日 |
| 一貫性 | 常に同じ基準を適用 | レビュアーにより異なる |
| 発見率 | セキュリティ脆弱性で 85% | セキュリティ脆弱性で 60% |
| スケーラビリティ | 無制限 | チームサイズに依存 |
| コンテキスト | プロジェクト全体を理解 | ファイル局所的 |
| 24/7 利用 | 可能 | 不可能 |
Antigravity Editor でのレビュー機能の使い方
レビューモードの起動
最もシンプルな方法は、エディタで任意のファイルを開き、サイドバーの「Code Review」ボタンをクリックすることです。
// src/auth/login.ts
export async function loginUser(email: string, password: string) {
const user = await db.query('SELECT * FROM users WHERE email = ?', [email]);
if (user && user.password === md5(password)) {
return { success: true, token: user.id };
}
return { success: false };
}このコードに対して「Code Review」を実行すると、以下のような問題が検出されます:
🔴 Critical: SQL Injection Risk
Line 2: Parameterized query is good, but ensure the database adapter
properly escapes values.
🔴 Critical: Weak Password Hashing
Line 4: MD5 is cryptographically broken. Use bcrypt, scrypt, or argon2.
🟡 Warning: Missing Error Handling
Line 2: Database query could fail. Implement try-catch or error callback.
🟡 Warning: Missing Rate Limiting
No rate limiting on login attempts detected. Add protection against
brute force attacks.
レビューモード別のレビュー実行
Antigravity では、ニーズに応じて異なるレビューモードを選択できます。
1. Security Mode(セキュリティモード)
# コマンドラインから実行
antigravity review --mode security src/payment/checkout.tsセキュリティに関連する問題のみをスキャンします:
// src/payment/checkout.ts
async function processPayment(cardToken, amount) {
// セキュリティレビュー対象項目:
// - PCI DSS コンプライアンス
// - トークン管理
// - データ暗号化
// - API キー露出リスク
const response = await fetch('https://api.payment.com/charge', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.STRIPE_KEY}`, // 問題検出
'Content-Type': 'application/json'
},
body: JSON.stringify({ token: cardToken, amount })
});
}2. Performance Mode(パフォーマンスモード)
antigravity review --mode performance src/database/queries.ts効率性と最適化に関する問題を検出:
# src/database/queries.py
def calculate_user_stats(user_id):
# 問題: N+1 クエリパターン
user = db.query('SELECT * FROM users WHERE id = ?', [user_id])
posts = db.query('SELECT * FROM posts WHERE user_id = ?', [user_id])
for post in posts:
comments = db.query('SELECT COUNT(*) FROM comments WHERE post_id = ?',
[post.id]) # 各投稿でクエリが実行される
post.comment_count = comments
return { user, posts }3. Style Mode(コード品質モード)
antigravity review --mode style src/components/Button.tsxコード品質と可読性の問題:
// src/components/Button.tsx
export const Button = ({ c, o, t, a, cb }) => {
// 問題: 変数名が不明確
if (!c || !t) return null;
return (
<button
className={c}
onClick={cb}
aria-label={a}
disabled={o}
>
{t}
</button>
);
};提案内容:
export interface ButtonProps {
className: string;
onClick: () => void;
text: string;
ariaLabel: string;
disabled: boolean;
}
export const Button: React.FC<ButtonProps> = ({
className,
onClick,
text,
ariaLabel,
disabled
}) => {
if (!className || !text) return null;
return (
<button
className={className}
onClick={onClick}
aria-label={ariaLabel}
disabled={disabled}
>
{text}
</button>
);
};4. Testing Mode(テストモード)
antigravity review --mode testing src/utils/validators.tsテストカバレッジと自動テスト生成提案:
// src/utils/validators.ts
export function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
export function validatePassword(password) {
return password.length >= 8;
}AI により、以下のテストが提案されます:
// src/utils/validators.test.ts
describe('Email Validation', () => {
it('should accept valid emails', () => {
expect(validateEmail('user@example.com')).toBe(true);
});
it('should reject invalid emails', () => {
expect(validateEmail('invalid.email')).toBe(false);
expect(validateEmail('user@')).toBe(false);
});
it('should handle edge cases', () => {
expect(validateEmail('')).toBe(false);
expect(validateEmail('user@sub.domain.co.uk')).toBe(true);
});
});レビュールール設定とカスタマイズ
グローバルレビュー設定
プロジェクトルートに .antigravity-review.yml を作成することで、レビュー設定をカスタマイズできます:
# .antigravity-review.yml
review:
enabled: true
# 重要度別の閾値
security:
severity_threshold: "warning" # critical, high, warning
check_sql_injection: true
check_xss: true
check_auth: true
check_crypto: true
performance:
enabled: true
max_function_complexity: 10
max_nesting_depth: 3
detect_n_plus_one: true
style:
enabled: true
require_types: true # TypeScript
require_docs: true
max_line_length: 100
testing:
enabled: true
min_coverage: 80
require_edge_cases: true
# 除外パターン
exclude:
- "node_modules/**"
- "dist/**"
- "*.test.ts"
- "*.spec.ts"
# 自動修正の有効化
auto_fix:
enabled: true
style_issues: true
format_code: true
unused_imports: trueコメント付きレビュー除外
特定のコードをレビュー対象から除外したい場合:
// antigravity-ignore: security
const API_KEY = process.env.SECRET_KEY;
// antigravity-ignore: performance
function legacyFunction() {
// ...
}
// antigravity-ignore: style
const x = 10, y = 20; // 古いスタイルで記述された変数
// antigravity-ignore
// 複数の問題を無視
const complexCode = /* ... */;PR ワークフローへの統合
GitHub/GitLab での自動レビュー
.github/workflows/code-review.yml:
name: AI Code Review
on:
pull_request:
paths:
- '**.ts'
- '**.tsx'
- '**.js'
- '**.py'
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Antigravity Code Review
uses: antigravity-lab/code-review-action@v1
with:
mode: 'comprehensive' # security, performance, style, testing
post_comments: true
fail_on_critical: true
- name: Comment PR with Results
if: always()
uses: actions/github-script@v6
with:
script: |
const review = require('./review-results.json');
const comment = `## AI Code Review Results\n${review.summary}`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});本番環境へのデプロイ前チェック
#!/bin/bash
# scripts/pre-deploy-review.sh
echo "Running comprehensive code review..."
antigravity review \
--mode comprehensive \
--fail-on critical \
--output json > review-report.json
if [ $? -ne 0 ]; then
echo "Critical issues found. Deployment blocked."
exit 1
fi
echo "Review passed. Ready for deployment."実践的なレビューセッション例
複雑な API エンドポイントのレビュー
以下は、実際のユースケースです:
// src/api/users/update.ts
import { Request, Response } from 'express';
import { db } from '../../database';
import { sendEmail } from '../../services/email';
export async function updateUserProfile(req: Request, res: Response) {
try {
const { userId } = req.params;
const { name, email, avatar, bio } = req.body;
// Check authorization
if (req.user.id !== userId && !req.user.isAdmin) {
return res.status(403).json({ error: 'Forbidden' });
}
// Validation
if (name && name.length > 100) {
return res.status(400).json({ error: 'Name too long' });
}
if (email) {
const existing = await db.query(
'SELECT id FROM users WHERE email = ? AND id != ?',
[email, userId]
);
if (existing.length > 0) {
return res.status(409).json({ error: 'Email already in use' });
}
}
// Update
const updates = {};
if (name) updates.name = name;
if (email) updates.email = email;
if (avatar) updates.avatar = avatar;
if (bio) updates.bio = bio;
await db.query('UPDATE users SET ? WHERE id = ?', [updates, userId]);
// Send confirmation
if (email) {
await sendEmail(email, 'Email Updated', 'Please confirm your new email');
}
res.json({ success: true, data: { userId, ...updates } });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Internal server error' });
}
}Antigravity AI Code Review の結果:
=== SECURITY ISSUES ===
🔴 [CRITICAL] Email Enumeration Risk
Lines 31-38: The error message "Email already in use" confirms that
an email exists in the system, allowing user enumeration attacks.
Fix: Return generic "Invalid request" for email conflicts.
🟠 [HIGH] Unvalidated File Upload
Line 23: avatar parameter is not validated. Could allow:
- Large file uploads (DoS)
- File type bypass (security risk)
- Path traversal
Fix: Implement file validation middleware with size limits and
allowed MIME types.
🟡 [MEDIUM] Missing Input Sanitization
Line 19: name parameter should be sanitized before storage to prevent
XSS if displayed in HTML context.
=== PERFORMANCE ISSUES ===
🟠 [HIGH] Multiple Database Queries
Lines 31-38: Email uniqueness check queries database separately.
Consider: UNIQUE constraint + error handling.
Improvement: Reduce from 2 queries to 1 with database constraints.
=== CODE QUALITY ===
🟡 [MEDIUM] Incomplete Error Logging
Line 49: Generic error message. Log full error details for debugging.
Suggestion: Implement structured logging with request ID tracking.
=== TESTING ===
🟡 [MEDIUM] Missing Test Scenarios
Suggested tests:
- Email already in use (409)
- User cannot update other users (403)
- Admin can update any user (200)
- Large avatar upload (413)
- Invalid email format (400)
ベストプラクティス
効果的なレビュー実施のコツ
- 定期的なレビュー実行 — コミット後、PR 前に自動実行
- 段階的な修正 — Critical から始めて、Warning は後で
- チーム規約の反映 —
.antigravity-review.ymlで組織のスタイルを定義 - 学習プロセスとする — 検出された問題からベストプラクティスを学ぶ
- False Positive の管理 — 除外ルールを厳選し、適切に設定
アンチパターン
// ❌ すべての問題を antigravity-ignore で無視
// antigravity-ignore
function badPractice() { /* ... */ }
// ✅ 妥当な理由がある場合のみ除外
// antigravity-ignore: security (legacy code, planned for refactor in Q2)
function legacyAuth() { /* ... */ }使い始めの一歩
機能を一度に全部使おうとすると、誤検知の山に埋もれて続かなくなります。私はこの機能を使い始めたとき、まずセキュリティモードだけを有効にして、Critical の指摘だけを潰すところから始めました。基準が体に馴染んできてから、パフォーマンスや可読性のチェックを一つずつ足していくと、無理なく定着します。
次の一歩として、手元のリポジトリで .antigravity-review.yml にセキュリティルールだけを書き、直近のコミットに対してレビューを一度走らせてみてください。自分のコードに対して最初の指摘が返ってきた時点で、この機能との距離感が掴めるはずです。