AI Learning Hub Roadmap Resources Blog Projects Paths
Beginner 2–3 hours · Python, OpenAI API, Click

Build an AI Code Explainer: Understand Any Code Instantly

· 3 min read · AI Learning Hub

Project Overview

A CLI tool that takes any code snippet or file and explains it in plain English, identifies potential bugs, suggests improvements, and optionally generates docstrings or comments.


Learning Goals

  • Use the OpenAI API for code understanding tasks
  • Build a multi-command CLI with Click
  • Handle different programming languages in prompts
  • Detect language from file extension

Implementation

Step 1: Setup

pip install openai click

Step 2: Code Analysis Functions

# explainer.py
from openai import OpenAI

client = OpenAI()

EXPLAIN_PROMPT = """Explain this {language} code to a developer who hasn't seen it before.
Be clear and concise. Cover: what it does, key logic, and any gotchas.

```{language}
{code}
```"""

BUG_PROMPT = """Review this {language} code for bugs, errors, and potential issues.
List each issue with: (1) description, (2) line/location, (3) how to fix it.
If no bugs found, say so.

```{language}
{code}
```"""

IMPROVE_PROMPT = """Suggest improvements for this {language} code.
Focus on: readability, performance, error handling, best practices.
For each suggestion, show the original and improved version.

```{language}
{code}
```"""

DOCSTRING_PROMPT = """Add docstrings and inline comments to this {language} code.
Return ONLY the commented code, no other text.

```{language}
{code}
```"""


def call_llm(prompt: str) -> str:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=1500,
        temperature=0.2,
    )
    return response.choices[0].message.content


def detect_language(filename: str) -> str:
    ext_map = {
        ".py": "python", ".js": "javascript", ".ts": "typescript",
        ".go": "go", ".rs": "rust", ".java": "java", ".cpp": "cpp",
        ".c": "c", ".rb": "ruby", ".sh": "bash", ".sql": "sql",
        ".html": "html", ".css": "css", ".json": "json",
    }
    import os
    _, ext = os.path.splitext(filename.lower())
    return ext_map.get(ext, "code")


def explain_code(code: str, language: str = "python") -> str:
    return call_llm(EXPLAIN_PROMPT.format(code=code, language=language))

def find_bugs(code: str, language: str = "python") -> str:
    return call_llm(BUG_PROMPT.format(code=code, language=language))

def suggest_improvements(code: str, language: str = "python") -> str:
    return call_llm(IMPROVE_PROMPT.format(code=code, language=language))

def add_docstrings(code: str, language: str = "python") -> str:
    return call_llm(DOCSTRING_PROMPT.format(code=code, language=language))

Step 3: CLI

# main.py
import click
import sys
from pathlib import Path
from explainer import (
    explain_code, find_bugs, suggest_improvements, add_docstrings, detect_language
)

def get_code_and_language(file, code, language):
    if file:
        path = Path(file)
        source_code = path.read_text(encoding="utf-8")
        lang = language or detect_language(file)
    elif code:
        source_code = code
        lang = language or "python"
    else:
        source_code = click.get_text_stream("stdin").read()
        lang = language or "python"
    return source_code, lang

@click.group()
def cli():
    """AI Code Explainer — understand any code instantly."""
    pass

@cli.command()
@click.option("--file", "-f", help="Path to code file")
@click.option("--code", "-c", help="Code snippet as string")
@click.option("--language", "-l", help="Programming language")
def explain(file, code, language):
    """Explain what code does in plain English."""
    source_code, lang = get_code_and_language(file, code, language)
    click.echo(f"\nExplaining {lang} code...\n")
    click.echo(explain_code(source_code, lang))

@cli.command()
@click.option("--file", "-f", help="Path to code file")
@click.option("--code", "-c", help="Code snippet as string")
@click.option("--language", "-l", help="Programming language")
def bugs(file, code, language):
    """Find bugs and potential issues."""
    source_code, lang = get_code_and_language(file, code, language)
    click.echo(f"\nChecking {lang} code for bugs...\n")
    click.echo(find_bugs(source_code, lang))

@cli.command()
@click.option("--file", "-f", help="Path to code file")
@click.option("--code", "-c", help="Code snippet as string")
@click.option("--language", "-l", help="Programming language")
def improve(file, code, language):
    """Suggest code improvements."""
    source_code, lang = get_code_and_language(file, code, language)
    click.echo(f"\nSuggesting improvements for {lang} code...\n")
    click.echo(suggest_improvements(source_code, lang))

@cli.command()
@click.option("--file", "-f", help="Path to code file")
@click.option("--output", "-o", help="Save commented code to file")
@click.option("--language", "-l", help="Programming language")
def document(file, output, language):
    """Add docstrings and comments to code."""
    if not file:
        click.echo("Error: --file required for document command")
        sys.exit(1)
    source_code, lang = get_code_and_language(file, None, language)
    click.echo(f"\nAdding documentation to {lang} code...\n")
    result = add_docstrings(source_code, lang)
    if output:
        Path(output).write_text(result)
        click.echo(f"Documented code saved to {output}")
    else:
        click.echo(result)

if __name__ == "__main__":
    cli()

Step 4: Run

# Explain a file
python main.py explain --file utils.py

# Find bugs in code
python main.py bugs --code "def divide(a, b): return a/b"

# Suggest improvements
python main.py improve --file messy_code.py

# Add documentation
python main.py document --file module.py --output module_documented.py

# Explain from stdin
cat complex_query.sql | python main.py explain --language sql

Extension Ideas

  1. VS Code extension — right-click any selection → "Explain with AI"
  2. GitHub Action — run bug checker on every PR automatically
  3. Complexity scoring — add cyclomatic complexity metrics
  4. Refactor mode — generate a refactored version of the code
  5. Multi-file mode — explain an entire Python module/package

What to Learn Next

← Back to all projects