Guaranteed 15% off your current AI inference bill for team spending up to $20000 / month.

Book a call →
Back to Blogs
Engineering

Building a Corporate Training Tool with LLM

We are going to build a corporate training CLI tool that reads internal documentation, quizzes employees, and adapts its difficulty based on their answers. It...

Building a Corporate Training Tool with LLM

We are going to build a corporate training CLI tool that reads internal documentation, quizzes employees, and adapts its difficulty based on their answers. It replaces static slide decks with an interactive session that gives instant feedback. The tool is aimed at engineering and HR teams who need to onboard employees or roll out new policies without scheduling live sessions. We will use two different Oxlo.ai models, one to generate questions and another to evaluate answers, which shows how easy it is to route tasks to the best model for the job. The entire system runs against Oxlo.ai's flat per-request API, so feeding it a 10-page policy document does not inflate the cost.

What you'll need

  • Python 3.10 or newer.
  • The OpenAI SDK. Install it with pip install openai.
  • An Oxlo.ai API key from https://portal.oxlo.ai. Create a free account if you have not already.
  • A sample training document. For this walkthrough, I created handbook.txt containing a short security policy. You can use any plain text file.

I chose Oxlo.ai for this project because its request-based pricing removes the token-counting anxiety that usually comes with long-context tutoring. You can pass the full handbook into every request and still pay the same flat rate. There are no cold starts on popular models, so the first question fires immediately. See https://oxlo.ai/pricing for plan details.

Step 1: Project setup and document loading

First, we initialize the Oxlo.ai client and load the training material into memory. I read the file as a single string because the simplest version of this tool keeps everything in context. In production you might chunk large documents, but for team handbooks under twenty pages, stuffing the full text works fine. Because Oxlo.ai charges per request rather than per token, we can pass the full document into every call without worrying about input length or hidden context fees.

import os
from openai import OpenAI

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

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

handbook = load_document("handbook.txt")
print(f"Loaded {len(handbook)} characters of training material.")

Step 2: Define the tutor system prompt

The system prompt tells the model it is a patient corporate tutor. It must ground every question and correction in the provided document, never hallucinate policies, and adjust its tone for clarity. I use a {{DOCUMENT}} placeholder so the same prompt template can be reused for different departments. I also explicitly tell the model to track difficulty and score, which turns the LLM into a lightweight state machine without needing external logic.

SYSTEM_PROMPT = """You are a corporate training tutor. Your job is to help employees learn from the provided company handbook.

Rules:
1. Base every question, answer, and explanation strictly on the DOCUMENT provided by the user.
2. If the employee answers incorrectly, explain why using direct quotes or clear paraphrases from the DOCUMENT.
3. Keep explanations under three sentences.
4. After two consecutive correct answers, increase the question difficulty slightly.
5. Never introduce policies that are not in the DOCUMENT.
6. Track the employee's score mentally and report it at the end of the session.

DOCUMENT:
{{DOCUMENT}}
"""

Step 3: Generate the first question

We call Oxlo.ai with the handbook injected into the system prompt. I use Qwen 3 32B because it handles structured instruction following well and starts agentic workflows cleanly. It is particularly good at staying on rails when you give it explicit rules, which matters when you need compliance-heavy questions that do not drift from source material.

def start_session(document: str) -> str:
    prompt = SYSTEM_PROMPT.replace("{{DOCUMENT}}", document)
    
    response = client.chat.completions.create(
        model="qwen-3-32b",
        messages=[
            {"role": "system", "content": prompt},
            {"role": "user", "content": "Generate the first quiz question based on the DOCUMENT."},
        ],
    )
    return response.choices[0].message.content

first_question = start_session(handbook)
print(first_question)

Step 4: Evaluate the employee's answer

Next, we send the employee's reply back to the model. I switch to Kimi K2.6 here because its advanced reasoning is useful for judging whether an approximate answer captures the intent of the policy, not just keyword matching. This prevents the tutor from marking someone wrong just because they used different wording. Routing evaluation to a stronger reasoning model while using a faster model for generation is a common pattern on Oxlo.ai because every request costs the same flat amount.

def evaluate_answer(document: str, history: list, user_answer: str) -> str:
    prompt = SYSTEM_PROMPT.replace("{{DOCUMENT}}", document)
    
    messages = [{"role": "system", "content": prompt}]
    messages.extend(history)
    messages.append({"role": "user", "content": f"EMPLOYEE ANSWER: {user_answer}\n\nEvaluate the answer. If correct, confirm and ask the next question. If incorrect, explain and ask a simpler follow-up."})
    
    response = client.chat.completions.create(
        model="kimi-k2.6",
        messages=messages,
    )
    return response.choices[0].message.content

# Example usage
history = [
    {"role": "assistant", "content": first_question},
]
user_input = "We should report security incidents within 24 hours."
feedback = evaluate_answer(handbook, history, user_input)
print(feedback)

Step 5: Build the interactive session loop

We wire the generator and evaluator into a loop that keeps running until the employee types 'exit' or reaches five correct answers. Each turn appends to a history list so the model remembers where we are. Keeping the full history in a single flat list makes debugging easy, and because Oxlo.ai does not charge by the token, growing the transcript does not increase the per-request cost. The loop is intentionally simple so you can swap the CLI input for a web framework later.

def run_training_session(document: str):
    history = []
    prompt = SYSTEM_PROMPT.replace("{{DOCUMENT}}", document)
    
    response = client.chat.completions.create(
        model="qwen-3-32b",
        messages=[
            {"role": "system", "content": prompt},
            {"role": "user", "content": "Generate the first quiz question based on the DOCUMENT."},
        ],
    )
    assistant_msg = response.choices[0].message.content
    history.append({"role": "assistant", "content": assistant_msg})
    print(f"Tutor: {assistant_msg}\n")
    
    correct_count = 0
    while correct_count < 5:
        user_answer = input("Your answer (or 'exit'): ").strip()
        if user_answer.lower() == "exit":
            break
        
        history.append({"role": "user", "content": user_answer})
        
        messages = [{"role": "system", "content": prompt}]
        messages.extend(history)
        messages.append({"role": "user", "content": "Evaluate the answer above. Confirm if correct and ask the next question, or explain the mistake and provide a simpler follow-up."})
        
        response = client.chat.completions.create(
            model="kimi-k2.6",
            messages=messages,
        )
        assistant_msg = response.choices[0].message.content
        history.append({"role": "assistant", "content": assistant_msg})
        print(f"\nTutor: {assistant_msg}\n")
        
        if "correct" in assistant_msg.lower():
            correct_count += 1
    
    print(f"Session complete. You answered {correct_count} questions correctly.")

Step 6: Log sessions for managers

HR teams need visibility into completion rates and common mistakes. We append each completed session to a JSONL file. Because Oxlo.ai's pricing is flat per request, adding this logging step does not change the inference cost. You can stream the JSONL file into any analytics pipeline or ingest it into a BI tool to see which policies confuse people most often.

import json
from datetime import datetime

def log_session(employee_id: str, history: list, score: int):
    entry = {
        "employee_id": employee_id,
        "timestamp": datetime.utcnow().isoformat(),
        "score": score,
        "transcript": history,
    }
    with open("training_log.jsonl", "a", encoding="utf-8") as f:
        f.write(json.dumps(entry) + "\n")

Run it

Save the full script as tutor.py, place a file named handbook.txt in the same folder, export your Oxlo.ai key, and run python tutor.py. I recommend starting with a short document so you can watch the difficulty adaptation in real time.

import os
import json
from datetime import datetime
from openai import OpenAI

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

SYSTEM_PROMPT = """You are a corporate training tutor. Your job is to help employees learn from the provided company handbook.

Rules:
1. Base every question, answer, and explanation strictly on the DOCUMENT provided by the user.
2. If the employee answers incorrectly, explain why using direct quotes or clear paraphrases from the DOCUMENT.
3. Keep explanations under three sentences.
4. After two consecutive correct answers, increase the question difficulty slightly.
5. Never introduce policies that are not in the DOCUMENT.
6. Track the employee's score mentally and report it at the end of the session.

DOCUMENT:
{{DOCUMENT}}
"""

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

def log_session(employee_id: str, history: list, score: int):
    entry = {
        "employee_id": employee_id,
        "timestamp": datetime.utcnow().isoformat(),
        "score": score,
        "transcript": history,
    }
    with open("training_log.jsonl", "a", encoding="utf-8") as f:
        f.write(json.dumps(entry) + "\n")

def run_training_session(document: str, employee_id: str):
    history = []
    prompt = SYSTEM_PROMPT.replace("{{DOCUMENT}}", document)
    
    response = client.chat.completions.create(
        model="qwen-3-32b",
        messages=[
            {"role": "system", "content": prompt},
            {"role": "user", "content": "Generate the first quiz question based on the DOCUMENT."},
        ],
    )
    assistant_msg = response.choices[0].message.content
    history.append({"role": "assistant", "content": assistant_msg})
    print(f"Tutor: {assistant_msg}\n")
    
    correct_count = 0
    while correct_count < 5:
        user_answer = input("Your answer (or 'exit'): ").strip()
        if user_answer.lower() == "exit":
            break
        
        history.append({"role": "user", "content": user_answer})
        
        messages = [{"role": "system", "content": prompt}]
        messages.extend(history)
        messages.append({"role": "user", "content": "Evaluate the answer above. Confirm if correct and ask the next question, or explain the mistake and provide a simpler follow-up."})
        
        response = client.chat.completions.create(
            model="kimi-k2.6",
            messages=messages,
        )
        assistant_msg = response.choices[0].message.content
        history.append({"role": "assistant", "content": assistant_msg})
        print(f"\nTutor: {assistant_msg}\n")
        
        if "correct" in assistant_msg.lower():
            correct_count += 1
    
    print(f"Session complete. Score: {correct_count}/5")
    log_session(employee_id, history, correct_count)

if __name__ == "__main__":
    handbook = load_document("handbook.txt")
    run_training_session(handbook, employee_id="dev-042")

Here is what a short session looks like in practice:

$ export OXLO_API_KEY="your_key_here"
$ python tutor.py
Loaded 3842 characters of training material.
Tutor: Welcome to security training. Question 1: According to the handbook, within how many hours must a critical security incident be reported to the SOC team?

Your answer (or 'exit'): 48 hours

Tutor: That is incorrect. The handbook states that critical incidents must be reported within 24 hours. Here is a simpler follow-up: What is the first step you should take immediately after discovering a potential data breach?

Your answer (or 'exit'): Disconnect the affected system and notify my manager.

Tutor: Correct. The handbook lists "isolate the system" and "notify your direct manager" as the first two steps. Question 2: Which encryption standard is required for all customer data at rest?

Next steps

Two concrete upgrades you can ship next.

First, replace the in-memory document with a vector store. Use Oxlo.ai's embeddings endpoint with bge-large to chunk and retrieve only relevant sections. This lets you scale to hundreds of policy documents without hitting context limits.

Second, expose the loop as a Slack bot or web API. Because Oxlo.ai has no cold starts on popular models, the bot responds instantly even after idle periods, and the flat per-request pricing means you know the exact cost of each training session upfront. You could also add vision support by letting employees upload screenshots of errors and ask the tutor to interpret them using a model like Gemma 3 27B or Kimi VL A3B.

Ready to build with Oxlo.ai?

Get started building high-performance AI inference applications today.

Get started
Ox Assistant
Online
OxBot
OxBot

Hi there! Try our cost calculator to see what you'd save with Oxlo.ai.