Agent-as-a-Service
Set up a local maintenance assessment agent with FastAPI and Ollama.
Component
Minimum version
Notes
1
# Open PowerShell as a standard user (no elevation required)
cd $env:USERPROFILE
mkdir LLM-PDI-Integration\agent-maintenance
cd LLM-PDI-Integration\agent-maintenance
mkdir agent
mkdir data
mkdir scriptssudo mkdir -p /opt/agent-maintenance
sudo chown $USER /opt/agent-maintenance
cd /opt/agent-maintenance
mkdir -p agent data scripts2
cd $env:USERPROFILE\LLM-PDI-Integration\agent-maintenance
python -m venv agent-venv
.\agent-venv\Scripts\Activate.ps1
# If you see a script execution error, run this once:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Install dependencies
pip install fastapi uvicorn httpx pydantic
# Verify
python -c "import fastapi, uvicorn, httpx, pydantic; print('OK')"cd $env:USERPROFILE\LLM-PDI-Integration\agent-maintenance
.\agent-venv\Scripts\Activate.ps1cd /opt/agent-maintenance
python3 -m venv agent-venv
source agent-venv/bin/activate
pip install fastapi uvicorn httpx pydantic
# Verify
python -c "import fastapi, uvicorn, httpx, pydantic; print('OK')"cd /opt/agent-maintenance
source agent-venv/bin/activate3
import os
import sqlite3
os.makedirs("data", exist_ok=True)
con = sqlite3.connect("data/asset_history.db")
con.execute("""CREATE TABLE IF NOT EXISTS asset_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
asset_id TEXT NOT NULL,
logged_at TEXT NOT NULL,
log_text TEXT NOT NULL
)""")
history = [
("PUMP-017", "2025-09-12", "slight rumble on startup, clears after 2 minutes"),
("PUMP-017", "2025-11-03", "intermittent vibration under load, bearing checked ok"),
("PUMP-017", "2026-01-18", "bearing replaced, work order WO-4412"),
("COMP-004", "2025-10-05", "temperature running slightly high 82C, within tolerance"),
("COMP-004", "2025-12-14", "cooling fan filter cleaned, temperature normal"),
("COMP-004", "2026-02-28", "temperature normal, no issues"),
("VALVE-022", "2025-08-20", "valve serviced, seals replaced"),
("VALVE-022", "2026-01-09", "operating normally, no issues")
]
con.executemany(
"INSERT INTO asset_history (asset_id, logged_at, log_text) VALUES (?, ?, ?)",
history
)
con.commit()
con.close()
print("History database created.")cd $env:USERPROFILE\LLM-PDI-Integration\agent-maintenance
python scripts\create_db.pypython3 - << 'EOF'
import os
import sqlite3
os.makedirs("data", exist_ok=True)
con = sqlite3.connect("data/asset_history.db")
con.execute("""CREATE TABLE IF NOT EXISTS asset_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
asset_id TEXT NOT NULL,
logged_at TEXT NOT NULL,
log_text TEXT NOT NULL
)""")
history = [
("PUMP-017", "2025-09-12", "slight rumble on startup, clears after 2 minutes"),
("PUMP-017", "2025-11-03", "intermittent vibration under load, bearing checked ok"),
("PUMP-017", "2026-01-18", "bearing replaced, work order WO-4412"),
("COMP-004", "2025-10-05", "temperature running slightly high 82C, within tolerance"),
("COMP-004", "2025-12-14", "cooling fan filter cleaned, temperature normal"),
("COMP-004", "2026-02-28", "temperature normal, no issues"),
("VALVE-022", "2025-08-20", "valve serviced, seals replaced"),
("VALVE-022", "2026-01-09", "operating normally, no issues"),
]
con.executemany(
"INSERT INTO asset_history (asset_id, logged_at, log_text) VALUES (?, ?, ?)",
history
)
con.commit()
con.close()
print("History database created.")
EOF4
import sqlite3, os
os.makedirs("data", exist_ok=True)
con = sqlite3.connect("data/maintenance_log.db")
# maintenance_log: one row per engineer observation
con.execute('''CREATE TABLE IF NOT EXISTS maintenance_log (
log_id TEXT PRIMARY KEY,
asset_id TEXT NOT NULL,
logged_at TEXT NOT NULL,
engineer TEXT NOT NULL,
log_text TEXT NOT NULL,
processed INTEGER NOT NULL DEFAULT 0)''')
# assessed_log: populated by the PDI transformation
con.execute('''CREATE TABLE IF NOT EXISTS assessed_log (
log_id TEXT PRIMARY KEY,
asset_id TEXT NOT NULL,
logged_at TEXT,
log_text TEXT,
priority TEXT,
fault_type TEXT,
pattern TEXT,
assessment TEXT,
confidence INTEGER,
parse_error TEXT DEFAULT 'N',
response_time_ms INTEGER,
assessed_at TEXT DEFAULT (datetime('now')))''')
# Five sample log entries across four assets
log_entries = [
("L-1001","PUMP-017","2026-04-07 08:14:00","J.Walsh",
"Rougher than usual on startup, louder than before the January maintenance. Vibration settling after ~3 minutes.", 0),
("L-1002","COMP-004","2026-04-07 09:02:00","S.Okafor",
"High temperature alarm triggered at 09:00. Reading: 94C. Limit is 85C. No prior warnings this shift.", 0),
("L-1003","FAN-011","2026-04-07 10:31:00","T.Marsh",
"Fan running normally. Slight hum noted but within normal range. No action.", 0),
("L-1004","PUMP-017","2026-04-07 11:45:00","J.Walsh",
"Vibration increased since this morning. Getting worse through the shift.", 0),
("L-1005","VALVE-022","2026-04-07 13:10:00","R.Nkosi",
"Valve sticking on close. Takes 3-4 attempts. Never seen this before.", 0),
]
con.executemany(
"INSERT OR IGNORE INTO maintenance_log (log_id,asset_id,logged_at,engineer,log_text,processed) VALUES (?,?,?,?,?,?)",
log_entries)
con.commit()
con.close()
print("maintenance_log.db created:", len(log_entries), "entries.")cd $env:USERPROFILE\LLM-PDI-Integration\agent-maintenance
python scripts\create_maintenance_db.pypython3 - << 'EOF'
import sqlite3, os
os.makedirs("data", exist_ok=True)
con = sqlite3.connect("data/maintenance_log.db")
# maintenance_log: one row per engineer observation
con.execute('''CREATE TABLE IF NOT EXISTS maintenance_log (
log_id TEXT PRIMARY KEY,
asset_id TEXT NOT NULL,
logged_at TEXT NOT NULL,
engineer TEXT NOT NULL,
log_text TEXT NOT NULL,
processed INTEGER NOT NULL DEFAULT 0)''')
# assessed_log: populated by the PDI transformation
con.execute('''CREATE TABLE IF NOT EXISTS assessed_log (
log_id TEXT PRIMARY KEY,
asset_id TEXT NOT NULL,
logged_at TEXT,
log_text TEXT,
priority TEXT,
fault_type TEXT,
pattern TEXT,
assessment TEXT,
confidence INTEGER,
parse_error TEXT DEFAULT 'N',
response_time_ms INTEGER,
assessed_at TEXT DEFAULT (datetime('now')))''')
# Five sample log entries across four assets
log_entries = [
("L-1001","PUMP-017","2026-04-07 08:14:00","J.Walsh",
"Rougher than usual on startup, louder than before the January maintenance. Vibration settling after ~3 minutes.", 0),
("L-1002","COMP-004","2026-04-07 09:02:00","S.Okafor",
"High temperature alarm triggered at 09:00. Reading: 94C. Limit is 85C. No prior warnings this shift.", 0),
("L-1003","FAN-011","2026-04-07 10:31:00","T.Marsh",
"Fan running normally. Slight hum noted but within normal range. No action.", 0),
("L-1004","PUMP-017","2026-04-07 11:45:00","J.Walsh",
"Vibration increased since this morning. Getting worse through the shift.", 0),
("L-1005","VALVE-022","2026-04-07 13:10:00","R.Nkosi",
"Valve sticking on close. Takes 3-4 attempts. Never seen this before.", 0),
]
con.executemany(
"INSERT OR IGNORE INTO maintenance_log (log_id,asset_id,logged_at,engineer,log_text,processed) VALUES (?,?,?,?,?,?)",
log_entries)
con.commit(); con.close()
print("maintenance_log.db created:", len(log_entries), "entries.")
EOF5
ollama pull llama3.1:8bollama serveollama list6
$env:AGENT_MODEL_NAME = "llama3.1:8b"
$env:AGENT_TEMPERATURE = "0.1"
$env:AGENT_TIMEOUT = "120"export AGENT_MODEL_NAME="llama3.1:8b"
export AGENT_TEMPERATURE="0.1"
export AGENT_TIMEOUT="120"7
cd $env:USERPROFILE\LLM-PDI-Integration\agent-maintenance
.\agent-venv\scripts\Activate.ps1# Keep this terminal open
uvicorn agent.agent:app --host 0.0.0.0 --port 8000cd /opt/agent-maintenance
source agent-venv/bin/activate# Keep this terminal open
uvicorn agent.agent:app --host 0.0.0.0 --port 8000Expected output:
INFO: Started server process [xxxxx]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
...8
Test-Path .\data\asset_history.db
curl.exe http://localhost:11434
curl.exe http://localhost:8000/docstest -f data/asset_history.db && echo "Database OK"
curl http://localhost:11434
curl http://localhost:8000/docs9
Symptom
Resolution
Last updated
Was this helpful?
