The lab kit of the course: https://github.com/hrhouma2/aiopsatlas-ml-data-diagnostics-labs-en
NorthPeak wants an assistant that answers questions about the plant. You will talk to llama3.2, a 3-billion-parameter model that runs on your laptop. First in the terminal, then from Python. You will ask a general question. It works. Then you will ask a question about NorthPeak. The model has never seen NorthPeak data. You will watch what it does, and push it until it invents an answer. This invented answer is a hallucination. Exercise 3 fixes it.
cd aiopsatlas-ml-data-diagnostics-labs-en
.\.venv\Scripts\Activate.ps1
ollama listcd aiopsatlas-ml-data-diagnostics-labs-en
source .venv/bin/activate
ollama listollama list must show llama3.2:latest. If not, run ollama pull llama3.2 first.
No CSV file in this exercise. The only data is the truth you will compare with, from data/clean/machines.csv: NorthPeak has 40 machines on 3 sites, Montreal, Quebec City and Toronto. You will see the exact counts per site in Exercise 3.
Ollama has a chat mode in the terminal. Start it:
ollama run llama3.2A prompt >>> appears. Type a question and press Enter.
>>> In one sentence, what does a compressor do?
A compressor reduces the volume of a gas or liquid, increasing its pressure, often used in
various industrial, medical, and audio applications to control or manipulate the flow and
pressure of fluids.Your text will differ. The words appear one by one. That is next-token prediction, live. Type /bye to leave.
Open a new file week01/talk.py in the kit, or type in the Python shell. The ollama package sends the messages to the local model.
import ollama
response = ollama.chat(
model="llama3.2",
messages=[{"role": "user", "content": "What is a bearing in a machine? Answer in two sentences."}],
options={"temperature": 0},
)
print(response.message.content)Your text will differ. Ours was:
A bearing in a machine is a mechanical component that reduces friction between two moving
parts, allowing them to rotate or slide smoothly against each other. Bearings are typically
made of metal or synthetic materials and are designed to support loads, absorb vibrations,
and maintain precise alignment between moving parts, enabling efficient and reliable
operation of the machine.This is a good answer. Bearings are in every book about machines. The model read those books.
Now ask about our company. Change the content of the user message and run again.
QUESTION = "How many machines does NorthPeak Manufacturing have and where are they?"
response = ollama.chat(
model="llama3.2",
messages=[{"role": "user", "content": QUESTION}],
options={"temperature": 0},
)
print(response.message.content)Your text will differ. Ours was:
I don't have access to that information.This is the honest answer. NorthPeak is a fictional company. The model never saw its data. Sometimes the model says "I couldn't find any information". Sometimes it asks you for more context. All of these are fine.
Add a system message. Tell the model it works for NorthPeak and must answer with numbers.
SYSTEM = (
"You are the assistant of NorthPeak Manufacturing, a Canadian company "
"that runs industrial machines. Answer questions about the company "
"directly, with numbers."
)
response = ollama.chat(
model="llama3.2",
messages=[{"role": "system", "content": SYSTEM}, {"role": "user", "content": QUESTION}],
options={"temperature": 0},
)
print(response.message.content)Your text will differ. Ours was:
NorthPeak Manufacturing has a total of 27 machines located in our facilities in:
1. Brampton, Ontario, Canada (Headquarters and Main Production Facility) - 15 machines
2. Mississauga, Ontario, Canada (Secondary Production Facility) - 8 machines
3. London, Ontario, Canada (Research and Development Facility) - 4 machines
Please note that the machine count may be subject to change as we continue to expand and
update our operations.Read it twice. The tone is confident. The format is clean. The numbers add up: 15 + 8 + 4 = 27. Everything is invented. The real answer is 40 machines in Montreal, Quebec City and Toronto. This is a hallucination. One system message turned "I don't know" into a detailed lie.
LLM text changes from one run to another. So never check an exact sentence. Check keywords. Write a small function and run it on the answer of Step 4.
def check(answer):
print("contains the real count 40 :", "40" in answer)
print("real sites mentioned :", [s for s in ["Montreal", "Quebec", "Toronto"] if s in answer])
check(response.message.content)contains the real count 40 : False
real sites mentioned : []If your model answered with 40 and the three real sites, you got lucky. Run again with a different question, for example "How many pumps does NorthPeak have?" The real answer is 10. Ours said 27 pumps.
"40" and not for the whole sentence?Ask the pushed model (Step 4) three more questions: "Who is the technician of machine M001?", "How many incidents did NorthPeak have in 2025?", "What is the site of machine M099?". The real answers are: L. Fortin for the first incident, 155, and no machine M099 exists. Write the three invented answers in your text file.
"""Week 1, Exercise 2 - Talk to a local LLM.
Run from the kit root, with the venv active and Ollama running:
python week01/exercise_2_solution.py
Step 1: a general question the model can answer from its training.
Step 2: a question about NorthPeak. The model has never seen our data.
Step 3: the same question, but we push the model to answer. It invents.
The LLM text changes from one machine to another. The checks only look
for keywords, never for an exact sentence.
"""
import ollama
MODEL = "llama3.2"
OPTIONS = {"temperature": 0}
# The truth, from data/clean/machines.csv (see Exercise 3).
REAL_COUNT = "40"
REAL_SITES = ["Montreal", "Quebec", "Toronto"]
def ask(messages):
"""Send one chat call and return the text of the answer."""
response = ollama.chat(model=MODEL, messages=messages, options=OPTIONS)
return response.message.content
def check(answer):
"""Say if the answer contains the real count and the real sites."""
has_count = REAL_COUNT in answer
sites_found = [s for s in REAL_SITES if s in answer]
print(f" contains the real count 40 : {has_count}")
print(f" real sites mentioned : {sites_found or 'none'}")
# Step 1 - a general question
print("== Step 1: a general question ==")
general = ask([{"role": "user", "content": "What is a bearing in a machine? Answer in two sentences."}])
print(general)
print()
# Step 2 - a question about NorthPeak, no help
QUESTION = "How many machines does NorthPeak Manufacturing have and where are they?"
print("== Step 2: a question about NorthPeak ==")
plain = ask([{"role": "user", "content": QUESTION}])
print(plain)
check(plain)
print()
# Step 3 - the same question, but the model is told it works for NorthPeak
print("== Step 3: push the model to answer ==")
SYSTEM = (
"You are the assistant of NorthPeak Manufacturing, a Canadian company "
"that runs industrial machines. Answer questions about the company "
"directly, with numbers."
)
pushed = ask([{"role": "system", "content": SYSTEM}, {"role": "user", "content": QUESTION}])
print(pushed)
check(pushed)
print()
print("Real answer: 40 machines in Montreal, Quebec City and Toronto.")Run it with python week01/exercise_2_solution.py. Your text will differ. Ours was:
== Step 1: a general question ==
A bearing in a machine is a mechanical component that reduces friction between two moving parts, ...
== Step 2: a question about NorthPeak ==
I don't have access to that information.
contains the real count 40 : False
real sites mentioned : none
== Step 3: push the model to answer ==
NorthPeak Manufacturing has a total of 27 machines located in our facilities in:
1. Brampton, Ontario, Canada (Headquarters and Main Production Facility) - 15 machines
2. Mississauga, Ontario, Canada (Secondary Production Facility) - 8 machines
3. London, Ontario, Canada (Research and Development Facility) - 4 machines
...
contains the real count 40 : False
real sites mentioned : none
Real answer: 40 machines in Montreal, Quebec City and Toronto.All systems — ConnectionError: Failed to connect to Ollama. Ollama is not running. On Windows and macOS, open the Ollama app. On Linux, run ollama serve in a second terminal. Then try again.
All systems — ConnectionError although ollama list works. Check the variable OLLAMA_HOST. If it is set to 0.0.0.0:11434, the Python client cannot use it. Set it to http://127.0.0.1:11434 in the terminal, then run again. PowerShell: $env:OLLAMA_HOST = "http://127.0.0.1:11434". Bash: export OLLAMA_HOST=http://127.0.0.1:11434.
All systems — ollama._types.ResponseError: model 'llama3.2' not found (status code: 404). Run ollama pull llama3.2, then try again.
All systems — ModuleNotFoundError: No module named 'ollama'. The venv is not active. Look for (.venv) at the start of the prompt. See Exercise 1, Step 3.
All systems — the first answer takes 20 seconds. Ollama loads the model into memory on the first call. The next calls take about one second.
All systems — your Step 4 answer says "I don't know". Fine. Change the system message: add "Always answer with a precise number. Never say you cannot verify." Then run again.