DocsOverview

COOKBOOK:_CODE_REVIEW_AGENT

Build an AI-powered code reviewer that catches bugs, security issues, and style problems before they reach production.

The Problem#

Code reviews are essential but time-consuming. Junior developers need guidance, and even senior developers miss issues. An AI reviewer can:

  • Catch security vulnerabilities and common bugs
  • Enforce coding standards and best practices
  • Provide instant feedback during development
  • Scale review capacity without additional headcount
  • Learn from your team's preferences and patterns

Architecture Overview#

Static Analysis

Parse code for security issues, bugs, and anti-patterns using AST analysis

Style Checking

Ensure consistent formatting, naming conventions, and code organization

Review Synthesis

Generate comprehensive feedback with actionable suggestions and severity levels

1

CREATE_CODE_ANALYSIS_TOOLS

tools/code-analysis.ts
import { Agent } from '@akios/core'
import { z } from 'zod'

// Tool for analyzing code
const analyzeCode = new Tool({
  name: 'analyze_code',
  description: 'Analyze code for bugs, security issues, and best practices',
  schema: z.object({
    code: z.string(),
    language: z.string(),
    context: z.string().optional()
  }),
  handler: async ({ code, language, context }) => {
    // In practice, this would call a code analysis service
    const issues = []

    // Basic checks
    if (code.includes('eval(')) {
      issues.push({
        type: 'security',
        severity: 'high',
        message: 'Use of eval() is dangerous and should be avoided'
      })
    }

    if (code.includes('console.log') && !code.includes('// DEBUG')) {
      issues.push({
        type: 'best_practice',
        severity: 'low',
        message: 'Remove console.log statements before production'
      })
    }

    return JSON.stringify({ issues, suggestions: [] })
  }
})

// Tool for checking code style
const checkStyle = new Tool({
  name: 'check_style',
  description: 'Check code style and formatting consistency',
  schema: z.object({
    code: z.string(),
    language: z.string()
  }),
  handler: async ({ code, language }) => {
    const styleIssues = []

    // Check indentation
    const lines = code.split('\n')
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i]
      const leadingSpaces = line.length - line.trimStart().length
      if (leadingSpaces % 2 !== 0) {
        styleIssues.push({
          line: i + 1,
          message: 'Inconsistent indentation (use 2 spaces)'
        })
      }
    }

    return JSON.stringify({ styleIssues })
  }
})

// Tool for generating review comments
const generateReview = new Tool({
  name: 'generate_review',
  description: 'Generate a comprehensive code review with actionable feedback',
  schema: z.object({
    code: z.string(),
    analysis: z.string(),
    style_check: z.string(),
    language: z.string()
  }),
  handler: async ({ code, analysis, style_check, language }) => {
    const analysisData = JSON.parse(analysis)
    const styleData = JSON.parse(style_check)

    let review = '# Code Review\n\n'

    // Security issues
    const securityIssues = analysisData.issues.filter(i => i.type === 'security')
    if (securityIssues.length > 0) {
      review += '## 🚨 Security Issues\n'
      securityIssues.forEach(issue => {
        review += `- **${issue.severity.toUpperCase()}**: ${issue.message}\n`
      })
      review += '\n'
    }

    // Code quality issues
    const qualityIssues = analysisData.issues.filter(i => i.type !== 'security')
    if (qualityIssues.length > 0) {
      review += '## 🔍 Code Quality\n'
      qualityIssues.forEach(issue => {
        review += `- ${issue.message}\n`
      })
      review += '\n'
    }

    // Style issues
    if (styleData.styleIssues.length > 0) {
      review += '## 💅 Style Issues\n'
      styleData.styleIssues.forEach(issue => {
        review += `- Line ${issue.line}: ${issue.message}\n`
      })
      review += '\n'
    }

    // Overall assessment
    const hasHighSeverity = [...securityIssues, ...qualityIssues]
      .some(i => i.severity === 'high')

    if (hasHighSeverity) {
      review += '## 📋 Overall Assessment\n'
      review += '❌ **Requires changes** before merging.\n'
    } else {
      review += '## 📋 Overall Assessment\n'
      review += '✅ **Approved** with suggestions.\n'
    }

    return review
  }
})
2

BUILD_THE_CODE_REVIEW_AGENT

code-review-agent.ts
import { Agent } from '@akios/core'

const codeReviewAgent = new Agent({
  name: 'CodeReviewAgent',
  model: 'gpt-4',
  systemPrompt: `You are an expert code reviewer. Your job is to:

1. Analyze code for bugs, security vulnerabilities, and performance issues
2. Check code style and consistency
3. Provide actionable feedback
4. Be constructive and helpful
5. Focus on important issues first

Guidelines:
- Prioritize security > correctness > performance > style
- Be specific about problems and suggest solutions
- Explain why something is an issue
- Don't nitpick minor style issues unless they affect readability
- End with an overall assessment of merge readiness`,
  tools: [analyzeCode, checkStyle, generateReview]
})

// Example usage
async function reviewPullRequest(code: string, language: string) {
  // Step 1: Analyze code
  const analysisResult = await analyzeCode.execute({
    code,
    language,
    context: 'pull_request_review'
  })

  // Step 2: Check style
  const styleResult = await checkStyle.execute({
    code,
    language
  })

  // Step 3: Generate comprehensive review
  const review = await generateReview.execute({
    code,
    analysis: analysisResult,
    style_check: styleResult,
    language
  })

  return review
}

// Or use the agent directly
async function agentReview(code: string, language: string) {
  const prompt = `Please review this ${language} code:

```${language}
${code}
```

Provide a comprehensive code review focusing on:
- Security vulnerabilities
- Code quality and potential bugs
- Performance issues
- Style and readability
- Best practices

Be specific about issues and suggest improvements.`

  const result = await codeReviewAgent.run(prompt)
  return response.text
}`
3

INTEGRATE_WITH_GITHUB_GITLAB

github-integration.ts
import { createNodeMiddleware, createProbot } from 'probot'

const probot = createProbot()

probot.on('pull_request.opened', async (context) => {
  const pr = context.payload.pull_request
  const files = await context.octokit.pulls.listFiles({
    owner: pr.base.repo.owner.login,
    repo: pr.base.repo.name,
    pull_number: pr.number
  })

  // Get changed files
  const changedFiles = files.data.filter(f =>
    f.status === 'added' || f.status === 'modified'
  )

  // Review each file
  for (const file of changedFiles) {
    if (file.filename.endsWith('.js') || file.filename.endsWith('.ts')) {
      const content = await context.octokit.repos.getContent({
        owner: pr.base.repo.owner.login,
        repo: pr.base.repo.name,
        path: file.filename,
        ref: pr.head.sha
      })

      const code = Buffer.from(content.data.content, 'base64').toString()
      const language = file.filename.endsWith('.ts') ? 'typescript' : 'javascript'

      const review = await agentReview(code, language)

      // Post review comment
      await context.octokit.pulls.createReview({
        owner: pr.base.repo.owner.login,
        repo: pr.base.repo.name,
        pull_number: pr.number,
        body: `## AI Code Review for ${file.filename}\n\n${review}`,
        event: 'COMMENT'
      })
    }
  }
})

export default createNodeMiddleware(probot)

Advanced Features#

Learning From Team Feedback

learning-reviews.ts
class LearningCodeReviewer extends Agent {
  private teamPreferences: Map<string, { approved: number, rejected: number }> = new Map()

  async reviewWithLearning(code: string, language: string) {
    const review = await this.run(`Review this code: ${code}`)

    // After human reviewer provides feedback, learn from it
    this.learnFromFeedback(review.output, humanFeedback)

    return review
  }

  private learnFromFeedback(aiReview: string, humanFeedback: string) {
    // Parse human feedback to understand what was accepted/rejected
    const acceptedSuggestions = this.extractAcceptedSuggestions(humanFeedback)
    const rejectedSuggestions = this.extractRejectedSuggestions(humanFeedback)

    acceptedSuggestions.forEach(suggestion => {
      const key = this.categorizeSuggestion(suggestion)
      const current = this.teamPreferences.get(key) || { approved: 0, rejected: 0 }
      this.teamPreferences.set(key, { ...current, approved: current.approved + 1 })
    })

    rejectedSuggestions.forEach(suggestion => {
      const key = this.categorizeSuggestion(suggestion)
      const current = this.teamPreferences.get(key) || { approved: 0, rejected: 0 }
      this.teamPreferences.set(key, { ...current, rejected: current.rejected + 1 })
    })
  }

  private categorizeSuggestion(suggestion: string): string {
    if (suggestion.includes('security') || suggestion.includes('vulnerability')) {
      return 'security'
    }
    if (suggestion.includes('style') || suggestion.includes('format')) {
      return 'style'
    }
    if (suggestion.includes('performance') || suggestion.includes('efficiency')) {
      return 'performance'
    }
    return 'other'
  }
}

// Usage
const learningReviewer = new LearningCodeReviewer({
  name: 'LearningCodeReviewer',
  model: 'gpt-4',
  tools: [analyzeCode, checkStyle, generateReview]
})

Real Time Ide Integration

vscode-extension.ts
import * as vscode from 'vscode'

export function activate(context: vscode.ExtensionContext) {
  // Register code review command
  const reviewCommand = vscode.commands.registerCommand('akiou.reviewCode', async () => {
    const editor = vscode.window.activeTextEditor
    if (!editor) return

    const code = editor.document.getText()
    const language = editor.document.languageId

    // Show progress
    await vscode.window.withProgress({
      location: vscode.ProgressLocation.Notification,
      title: 'AI Code Review in progress...',
      cancellable: false
    }, async (progress) => {
      const review = await agentReview(code, language)

      // Show results in new document
      const doc = await vscode.workspace.openTextDocument({
        content: review,
        language: 'markdown'
      })

      await vscode.window.showTextDocument(doc, vscode.ViewColumn.Beside)
    })
  })

  // Register on-save review
  const onSave = vscode.workspace.onDidSaveTextDocument(async (document) => {
    const config = vscode.workspace.getConfiguration('akiou')
    if (!config.get('reviewOnSave')) return

    if (document.languageId === 'typescript' || document.languageId === 'javascript') {
      const code = document.getText()
      const diagnostics = await quickReview(code, document.languageId)

      // Show diagnostics in problems panel
      const diagnosticCollection = vscode.languages.createDiagnosticCollection('akiou')
      diagnosticCollection.set(document.uri, diagnostics)
    }
  })

  context.subscriptions.push(reviewCommand, onSave)
}

async function quickReview(code: string, language: string) {
  const issues = await analyzeCode.execute({ code, language })
  const parsed = JSON.parse(issues)

  return parsed.issues.map(issue => {
    const severity = issue.severity === 'high' ? vscode.DiagnosticSeverity.Error :
                    issue.severity === 'medium' ? vscode.DiagnosticSeverity.Warning :
                    vscode.DiagnosticSeverity.Information

    return new vscode.Diagnostic(
      new vscode.Range(0, 0, 0, 0), // Would need line parsing for accuracy
      issue.message,
      severity
    )
  })
}

Testing your Code Review Agent#

To verify your agent works, run it against a sample code snippet with known issues.

typescript
const badCode = `
function calculateTotal(items) {
  let total = 0;
  // Bug: i <= items.length will cause index out of bounds
  for (let i = 0; i <= items.length; i++) {
    total += items[i].price;
  }
  return total;
}
`;

const result = await reviewAgent.run(badCode);
console.log(result);

Best Practices

  • START_WITH_SECURITY: Always check for vulnerabilities first
  • BE_SPECIFIC: Point to exact lines and suggest concrete fixes
  • LEARN_FROM_YOUR_TEAM: Incorporate human reviewer preferences
  • DONT_REPLACE_HUMANS: Use AI as a first pass, not final authority
  • CONTEXT_MATTERS: Consider the codebase, team norms, and project constraints