Inspect the detection engine and tune its workers
Check that the PII model is loaded, probe it on sample text, and change how many workers each ML detection service runs.
- Version: 0.4
- Role: admin_user
- Type: task
ML Engine reports whether the PII detection model is loaded and lets you run a piece of text through it to see exactly what it returns. Worker counts for the ML services are changed on a second screen, Settings → ML Tuning.
What do I need?
- Licence
- Any
- Role
admin_user
Prerequisites
- The appliance runs with CID_ENABLE_LAB=true. On a licensed build the ML Engine page does not exist.
- The ml-detector service is running and reachable from the gateway.
- For worker tuning: you are the superadmin, and the host updater daemon is running to apply the restart.
Danger
ML Engine sits in the lab-only Testing group, hidden on every licensed build. Settings → ML Tuning is not lab-gated but is superadmin-only, and saving there restarts ML services.
/assets/screenshots/ml-engine@0.4.pngCheck the model is loaded
Open the page
Select Testing → ML Engine.
The Detection engine tile shows the active engine, the loaded models, and the note polled every 30s.
Read the status
Confirm the model under Models reports as loaded.
The gateway derives this from the detection service's own health endpoint. When the service does not answer, the tile is replaced by Engine status unavailable — the detection service is not responding.
Re-poll after a restart
Select Refresh status.
The tile re-reads the health endpoint immediately instead of waiting for the next poll.
Warning
The PII pipeline runs a single engine — the fine-tuned ONNX NER model. Shadow mode, Startup engine and Comparisons run on this tile are constants the gateway fills in, not measurements: shadow mode is always off and the comparison count is always zero. The engine-switching surface was removed when the second engine left the pipeline; the tile and the panel below keep the word "compare".
Probe the detector on your own text
Paste the text
In Compare engines, enter the text in Input text.
The field accepts 1 to 50000 characters.
Set the language and threshold
Set Language to Auto detect, English, Turkish or German, and Confidence
threshold between 0 and 1.
The default threshold on this panel is 0.5.
Run it
Select Compare engines.
The results appear below: the detected language with its confidence, the entities the model returned, the entity count and the processing time.
Note
This panel calls the detection service directly. It does not apply your filter rules, the tenant and group overrides, or the validation stage — so an entity listed here is not proof that a real message would be masked. Use Filter testing for that.
Change how many workers a service runs
Open the tuning screen
Select Settings → ML Tuning.
ML Worker Tuning lists one field per tunable service. A non-superadmin sees Access Denied and Only the superadmin can tune ML worker settings.
Set the worker counts
Set a value between 1 and 8 for the services you want to change.
Each field shows its compose service name and the note default {n} · range 1–8. Each worker
is a separate process holding its own copy of the model, so a worker costs linearly more RAM
and CPU.
Apply
Select Save & apply.
Only the services whose value changed are restarted; the rest are untouched and no image is rebuilt. The new count is live once the service finishes restarting.
The gateway never touches Docker itself. Saving writes the value to the configuration store and
drops a reconfigure-ml intent into the host updater daemon's spool; the daemon renders the new
value into the live environment file and recreates the affected services. On a plain development
box with no daemon running, the intent simply sits in the spool and nothing restarts — recreate the
services by hand.
Tunable services
| Service | Compose service | Default workers |
|---|---|---|
| Toxicity (HAP Guard) | hap-guard-v2 | 2 |
| Prompt injection / jailbreak | attack-guard | 2 |
| PII NER | ml-detector | 2 |
Only genuine neural-model services are tunable, because each worker duplicates a heavy model. The language detector and the prompt compressor hold no such model, so their worker counts are fixed in the compose file.
Where detection thresholds actually live
Warning
There is no HAP_THRESHOLD, JAILBREAK_THRESHOLD or PII_CONFIDENCE_THRESHOLD environment variable — nothing in the gateway reads one. Documentation and compose comments that name them are wrong, and setting one changes nothing.
| Threshold | Where it lives | How to change it |
|---|---|---|
| Toxicity, per label | cid-hap-guard-v2/thresholds.json, baked into the service image | Edit the file and rebuild that image |
| Prompt injection and jailbreak | cid-attack-guard/thresholds.json, baked into the service image | Edit the file and rebuild that image |
| ML PII confidence | A fixed 0.6 sent by the gateway's detection client on every call | Not configurable at runtime |
| Validation pass mark | A fixed 0.6 in the guardrails constants | Not configurable at runtime |
Each threshold file gives a label three levels — a block level, a flag level and a log-only level — so the toxicity service carries thirteen independent triples, one per category, rather than one global number. The confidence threshold on the Compare engines panel above applies to that probe only and changes nothing for real traffic.
The per-label values and the entity types each detector produces are in the generated entity type reference; what the pipeline then does with a detection is decided by the rules on Security filters, not by these files.
Verify
- Detection engine reports the model as loaded, and Refresh status does not flip it to unavailable.
- A probe with an obvious entity — an email address in the sample text — returns at least one entity and a processing time.
- After Save & apply, the affected service reports healthy again and the new worker count is in effect. The response carries the queued restart's request id, and the daemon's status for that id says whether the recreate succeeded.
Note
Neither screen writes an event-log row. A worker change is recorded in the configuration store and in the gateway's own log — naming who made it — but there is no event type for it, so it does not appear in Event logs.
If it fails
- The page is missing, or every request returns 404 — the build is not a lab build.
CID_ENABLE_LABis nottrue. - Engine status unavailable — the detection service is not responding. — the gateway cannot reach the detection service. Check the container's health before reading anything into detection results.
- Failed to get engine status with a 503 — the same condition, surfaced by the API rather than the tile.
- Failed to compare engines with a 400 — the probe was rejected. The message carries the detection service's own text; an empty or over-long input is the common cause.
- Access Denied … Only the superadmin can tune ML worker settings. — the tuning screen is superadmin-only, and the backend refuses the save as well as the screen.
- Save & apply succeeds but nothing restarts — no host updater daemon is running to consume the spooled intent. Recreate the services by hand on a development box.
- Services fail to start after raising the worker counts — each worker holds its own copy of the model. Lower the counts to fit the host's memory.
Next steps
- Filter testing — measure the pipeline end to end rather than one detector.
- Security filters — decide what happens to what the detector finds.
- All detections — see the detector's output on real traffic.
Last updated on