unlob Docs
Browse documentation

Untrusted content: risk flags on retrieved text

The web is an input channel into your agent. Every evidence item says when a passage is addressing the model rather than the reader.

Why the retrieval layer says anything about this

A passage that says “ignore your previous instructions and…” is still a passage: it matches queries, it has a host and a date, it can be corroborated. The model reading it cannot reliably tell that it is being addressed. The retrieval layer can, cheaply, and should say so before the text reaches a context window.

So every evidence item from ground carries risk_flags, and get_document will compute them on request. They flag; they never decide. An empty list means nothing looked wrong, not that the text is safe.

The flags

FlagMeaning
instruction_likeA sentence addresses an AI system or tells it what to do — “ignore previous instructions”, “you are an AI assistant”, “do not tell the user”, “your system prompt”.
hidden_textCharacters or markup that hide text from a human reader but not from a model: zero-width characters, HTML-comment or CSS-hiding remnants.
role_markersChat-role or prompt-template markers inside content: im_start and im_end template tokens, [INST], ### instruction, a line starting system: or assistant:.
low_trust_sourceThe host’s trust prior is low (host_rank below 0.2).

The checks are deterministic phrase and marker matches, case-insensitive, chosen for precision: a phrase that also appears in ordinary prose is deliberately not on the list, because a false flag on documentation is worse than a missed one on a hostile page. The full vocabulary is in /describe under vocab.risk_flags.

Stripping

Flagging is the default. Two options remove the text instead:

  • strip_instruction_like=true on ground replaces flagged sentences in snippets with [removed: instruction-like text], so a reader can see that something was there.
  • strip=true on /doc/{id} and get_document does the same for the full text and adds sentences_removed. risk=true returns the flags without stripping. Flags are always computed on the original text, so a stripped document still says what was in it.
curl -sG -H "x-api-key: $UNLOB_API_KEY" \
  "https://api.unlob.com/doc/3be72f8af6378060:0" -d risk=true -d strip=true
{ "id": "…", "text": "Acme reported revenue of $4M. [removed: instruction-like text] Shares rose 3%.",
  "risk_flags": ["instruction_like"], "sentences_removed": 1 }

What to do with a flag

  • Quote a flagged passage as data, never as instruction. Wrap retrieved text in your own delimiters and say what it is.
  • Treat hidden_text as a reason to fetch and read the page yourself before relying on it.
  • low_trust_source on its own is not a prompt-injection signal; it is the same trust prior min_host_rank filters on, surfaced where you will see it.
  • Do not lower your guard because the list is empty. The checks catch the characteristic phrasings; they do not understand intent.

Next