DEV Community

shashank ms
shashank ms

Posted on

LLM Models for Tasks with High-Explainability Requirements

When you are automating security reviews, a simple yes or no output is not enough. Engineers need cited line numbers, explicit data flows, and remediation steps they can act on. In this tutorial, I will walk you through building a diff auditor that uses an LLM to return structured, explainable findings via the Oxlo.ai API.

What you'll need

Step 1: Configure the Oxlo.ai client

I use the OpenAI SDK as a drop-in client because Oxlo.ai exposes a fully compatible endpoint. Since Oxlo.ai charges per request rather than per token, I can pass in large system prompts and full diffs without watching metered input costs climb. That predictability matters when you are shipping an internal tool that processes heavy pull requests.

from openai import OpenAI

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

Step 2: Define the audit rubric and system prompt

Explainability breaks down when the model is vague. I lock the behavior down with a strict system prompt that requires line-level citations, explicit variables, and concrete remediations. The prompt also forces JSON mode output so downstream tools can parse findings reliably.

import json

SYSTEM_PROMPT = """You are a security code auditor. Analyze the provided git diff and produce structured findings.

Rules:
1. Only flag issues directly observable in the diff.
2. For each finding, provide:
   - category: one of [injection, secrets, auth, logic, none]
   - severity: one of [critical, high, medium, low, info]
   - line_reference: exact line numbers or hunk headers from the diff
   - explanation: 2 to 3 sentences describing the risk. Name the specific variable, function, or input source.
   - remediation: a concrete code snippet or config change that fixes the issue.
3. If no issues are found, return an empty findings array and explain why the diff is clean in the summary.
4. Respond ONLY with valid JSON. Do not wrap the output in markdown fences.

Requested JSON schema:
{
  "summary": "string",
  "findings": [
    {
      "category": "string",
      "severity": "string",
      "line_reference": "string",
      "explanation": "string",
      "remediation": "string"
    }
  ]
}
"""

Step 3: Build the audit function with JSON mode

I wrap the call in a small function that injects the diff as a user message and enables JSON mode via the response_format parameter. I keep temperature low to reduce creative hallucinations in the citations.

def audit_diff(diff_text: str, model: str = "llama-3.3-70b") -> dict:
    user_message = f"Audit the following diff:\n\n

```diff\n{diff_text}\n```

"

    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )

    raw_content = response.choices[0].message.content
    return json.loads(raw_content)

Step 4: Validate citations against the diff

To keep the model honest, I add a lightweight validator that checks whether the cited line_reference strings actually appear in the original diff. If a citation is missing, I flag it as a hallucination and either retry or surface a warning.

def validate_findings(result: dict, diff_text: str) -> dict:
    for finding in result.get("findings", []):
        ref = finding.get("line_reference", "")
        if ref and ref not in diff_text:
            finding["citation_valid"] = False
            finding["note"] = "Line reference not found in original diff, which indicates a possible hallucination."
        else:
            finding["citation_valid"] = True
    return result

Run it

Here is a small synthetic diff containing a clear SQL injection vector. I pass it through the auditor and print the validated results.

SAMPLE_DIFF = """diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -14,6 +14,9 @@ def get_user():
     user_id = request.args.get("id")
-    query = "SELECT * FROM users WHERE id = %s" % user_id
+    query = f"SELECT * FROM users WHERE id = {user_id}"
     cursor.execute(query)
     return cursor.fetchone()
"""

if __name__ == "__main__":
    findings = audit_diff(SAMPLE_DIFF)
    validated = validate_findings(findings, SAMPLE_DIFF)
    print(json.dumps(validated, indent=2))

Example output:

{
  "summary": "The diff introduces a string-formatted SQL query that directly interpolates user input, creating a clear SQL injection vulnerability.",
  "findings": [
    {
      "category": "injection",
      "severity": "critical",
      "line_reference": "+    query = f\"SELECT * FROM users WHERE id = {user_id}\"",
      "explanation": "The user_id variable comes from request.args.get, which is untrusted user input. Formatting this directly into the SQL string allows attackers to manipulate the query structure.",
      "remediation": "Use parameterized queries: cursor.execute(\"SELECT * FROM users WHERE id = %s\", (user_id,))",
      "citation_valid": true
    }
  ]
}

Next steps

Pipe the JSON output into a GitHub Action or GitLab CI job so every pull request gets an automated, cited security review. If you start processing large monorepo diffs, consider switching to qwen-3-32b or deepseek-v3.2 on Oxlo.ai to handle longer context windows without increasing your per-request cost. For pricing details, see https://oxlo.ai/pricing.

Top comments (0)