AI Provider Selection
autociso uses AI to extract user lists from access screenshots and PDFs, classify assets and suppliers, and prefill ISO control evidence. Two providers are supported, selected per deployment via AI_VISION_PROVIDER:
- Anthropic Claude (default). Image bytes are base64-encoded and sent directly to Claude’s
/v1/messagesAPI. - DeepSeek. Images are run through in-process OCR (tesseract) before any network call. The extracted text is masked for email PII, wrapped in a clearly-delimited
UNTRUSTED IMAGE TEXTenvelope, and sent as text only. Raw image bytes never leave your pod.
What changes per flow
| Flow | Image on the wire? | Provider |
|---|---|---|
| Audit ingest (screenshot/PDF upload) | Depends on AUDIT_REQUIRE_VISION. true (default): image goes to Anthropic. false: OCR text only. | Anthropic when AUDIT_REQUIRE_VISION=true, otherwise the configured provider. |
| Asset extraction (uploaded image/PDF) | Anthropic only — hard-coded. | Anthropic. |
| ISO certificate extraction (PDF) | Anthropic only — hard-coded. | Anthropic. |
| Asset/supplier name + website analysis | Text-only. | Whichever is configured. |
AI chat (ai/chat SSE) | Text-only. | Whichever is configured. |
AUDIT_REQUIRE_VISION=false turns off the default RequireVision for audit ingest. Asset and ISO image-bearing flows are NOT operator-tunable — they always route to Anthropic.
PII handling on the DeepSeek path
The DeepSeek provider OCRs the image with size/dimension/format guards (≤25 MiB, ≤8000×8000 pixels, ≤32 megapixels, PNG and JPEG only); normalises OCR-typical email corruption (alice@acme,com → alice@acme.com); masks emails with deterministic per-call tokens; sends the masked text inside --- BEGIN UNTRUSTED IMAGE TEXT (filename) --- ... --- END UNTRUSTED IMAGE TEXT (filename) --- so the prompt-injection guard can identify it as data; and restores tokens in the response. Tokens never leave the provider’s goroutine.
Names and phone numbers are not masked in this phase — only email addresses.
Masking is deliberately invisible to the extraction result. The model is
instructed that a [PII_xxxx] token is the value and must be copied into the
output field verbatim, so a masked email survives the round trip and is restored
before matching. Privacy costs nothing in accuracy here — but it does mean the
model never sees a real address, so a prompt that ignores the tokens loses every
email. If you supply a custom prompt for an asset (Prompt Override), the
transcription rules covering tokens are always appended and cannot be opted out.
Extraction accuracy on the OCR path
When audit ingest runs on OCR text (AUDIT_REQUIRE_VISION=false), no model ever
sees your screenshot — it reads what tesseract recovered. That text carries
predictable damage, and it is worth knowing what to expect:
- Characters are misread.
Sergey Ilinis commonly recovered asSergey lin(capitalIread as lowercasel). The extraction prompt instructs the model to repair obvious character damage and keep the surname rather than drop it. - Layout is flattened. Sidebars, headers, and buttons interleave with table
rows; badges next to a name (
Owner,Admin) arrive as stray characters. The prompt describes the table shape so these are read as roles or ignored, not as names. - A damaged row is never “repaired” into a different person. The model is instructed that an empty field beats a plausible guess, and that a row must appear in the source to be reported.
The email is what carries a match. Employee matching treats an exact email
as decisive, so a row whose name arrived damaged still attributes correctly as
long as its email survived. Where the name is ambiguous and no email was
recovered — a row reading only Sergey when two employees share that first name
— autociso raises it for review rather than guessing. See
Correct a misrecognised employee.
To remove OCR from the equation entirely, set AUDIT_REQUIRE_VISION=true and
keep ANTHROPIC_API_KEY set: image-bearing audit calls then go to Anthropic and
are read as pixels. This sends image bytes to Anthropic — a deliberate trade of
the text-only guarantee for extraction accuracy.
When to choose DeepSeek
Use DeepSeek when:
- Your tenant requires no image bytes leave the platform (text only).
- You want lower cost on text-only flows (chat, name/website classification). Asset and ISO image-bearing flows continue to use Anthropic regardless; audit ingest follows
AUDIT_REQUIRE_VISION. - Your DPA covers DeepSeek as a sub-processor. Update your RoPA accordingly.
When you switch to AI_VISION_PROVIDER=deepseek, leave ANTHROPIC_API_KEY set so per-call RequireVision=true flows continue to work via the Anthropic fallback. DEEPSEEK_BASE_URL defaults to https://api.deepseek.com/anthropic if unset; DEEPSEEK_MODEL defaults to deepseek-chat. Never set DEEPSEEK_MODEL to a Claude id — DeepSeek will return a vendor error.
Operator visibility
- One startup log line records the active provider, fallback status, and OCR languages.
- Audit failures on the DeepSeek+OCR path show
[redacted — deepseek+OCR error path]inRawAIOutput(partial responses may contain unmasked PII fragments). - Boot in production refuses
AI_VISION_PROVIDER=deepseekwithout anANTHROPIC_API_KEY— that combination would silently lose audit-ingest accuracy.
What does NOT change
The console UI is identical regardless of provider; the stored audit data structure is identical (only RawAIOutput differs). PII tokenisation in your domSnapshot and text inputs continues to work as before, independent of the DeepSeek OCR-side masker.
Was this page helpful?