DEV Community

shashank ms
shashank ms

Posted on

Using LLM for Code Analysis: A Comprehensive Guide

We are going to build a small Python CLI that reads a source file and returns a structured review covering bugs, security risks, style issues, and refactoring opportunities. It is useful for pre-commit checks or for getting a second opinion on legacy code without pulling in a full static-analysis toolchain.

What you'll need

  • Python 3.10 or newer
  • An Oxlo.ai API key from https://portal.oxlo.ai
  • The OpenAI SDK installed with pip install openai

I will use llama-3.3-70b because it handles code reasoning well, but you can swap in qwen-3-32b, kimi-k2.6, or deepseek-v3.2 without changing any other code.

Step 1: Verify the connection

Before we analyze anything, we need to confirm that the OpenAI SDK can talk to Oxlo.ai. I keep my key in an environment variable so it does not end up in shell history.

from openai import OpenAI
import os

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ["OXLO_API_KEY"],
)

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Say 'Connection OK'"}],
)

print(response.choices[0].message.content)

Run the script. If you see Connection OK, the client is pointing at Oxlo.ai and we are ready to move on.

Step 2: Read the source file

The tool needs to ingest an arbitrary code file. This helper reads the file and returns the raw text. Because Oxlo.ai charges a flat rate per request, you can pass large files in a single call without the cost scaling with token count. That makes it a natural fit for long-context code analysis. You can see the exact request pricing at https://oxlo.ai/pricing.

def read_code_file(path: str) -> str:
    with open(path, "r", encoding="utf-8") as f:
        return f.read()

Step 3: Define the system prompt

We want deterministic, structured output. The system prompt below forces the model to return JSON only, with four categories of findings. Feel free to edit the severity levels or add categories like performance.

SYSTEM_PROMPT = """You are a senior staff engineer performing code review.
Analyze the provided source code and return a JSON object with exactly these keys:
- "bugs": list of objects with "line", "severity", and "description"
- "security": list of objects with "line", "severity", and "description"
- "style": list of objects with "line", "severity", and "description"
- "refactoring": list of objects with "description" and "suggestion"
Be concise. If a category has no findings, return an empty list.
Return only valid JSON, no markdown fences."""

Step 4: Build the analyzer

Now we wire the file contents to the model. I set temperature low to keep the output focused. The helper strips any accidental markdown fences and parses the result into a Python dict.

import json

def analyze_code(code: str) -> dict:
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": f"Analyze this Python file:\n\n{code}"},
        ],
        temperature=0.2,
    )

    raw = response.choices[0].message.content.strip()

    # Guard against markdown wrapping
    if raw.startswith("

```"):
        raw = raw.split("\n", 1)[1].rsplit("```

", 1)[0].strip()

    return json.loads(raw)

Step 5: Wrap it in a CLI

Finally, we add a small argument parser so we can run this against any file from the terminal.

import argparse

def main():
    parser = argparse.ArgumentParser(description="LLM code analyzer via Oxlo.ai")
    parser.add_argument("file", help="Path to source file")
    args = parser.parse_args()

    code = read_code_file(args.file)
    findings = analyze_code(code)

    for category in ["bugs", "security", "style", "refactoring"]:
        items = findings.get(category, [])
        print(f"\n== {category.upper()} ({len(items)}) ==")
        for item in items:
            line = item.get("line", "-")
            text = item.get("description") or item.get("suggestion", "")
            print(f"  Line {line}: {text}")

if __name__ == "__main__":
    main()

Run it

Create a deliberately rough test file named sample.py:

import os

def process_user_data(user_id, data):
    password = "hardcoded_secret_123"
    os.system("rm -rf /tmp/" + user_id)
    if data:
        return data[0]
    return None

class config:
    debug = True

Then run the analyzer:

export OXLO_API_KEY="YOUR_OXLO_API_KEY"
python analyzer.py sample.py

You should see output similar to this:

== BUGS (1) ==
  Line 7: Possible IndexError if data is an empty sequence after truthiness check passes.

== SECURITY (2) ==
  Line 5: Hardcoded credential detected.
  Line 6: Command injection risk via unsanitized user input passed to os.system.

== STYLE (2) ==
  Line 10: Class name 'config' should use CapWords convention.
  Line 11: Module-level variable 'debug' inside class does not follow expected constants style.

== REFACTORING (2) ==
  Line -: Use subprocess.run with a list of arguments instead of os.system.
  Line -: Remove hardcoded secrets and load from environment variables or a secrets manager.

Next steps

To scale this up, point the script at an entire directory with pathlib and accumulate findings into a single JSON report. Alternatively, hook the analyzer into a GitHub Action so every pull request gets an automated Oxlo.ai-powered review comment.

Top comments (0)