How to show PII in the final chat answer while keeping it out of the LLM context? (sanitize → infer → re-hydrate)
05:34 19 Jun 2026

I'm building an AI chat assistant for an internal sales/CRM system. It uses tool/function calling: the LLM picks a backend tool, tools return JSON from our APIs, and the orchestrator sends tool results back to the LLM to produce a natural-language answer.

Use case

A user asks:

"Which customer had the highest order volume this month? Please include their email and address."

Tool get_top_customers returns:

{

"customers": [

{

"customerCode": "C00-00001",

"contactName": "Acme Logistics",

"orderTotal": 110483341,

"email": "contact@acme.com",

"contactAddress": "123 Main St, Yangon"

}

]

}

I do not want email or contactAddress sent to a third-party LLM (OWASP LLM02 / data minimization). The end user is an authenticated employee who is allowed to see email and address in the final answer.

Current flow

Tool (full data) → sanitize (strip PII) → LLM (safe data only) → natural-language reply

The LLM only sees fields like customerCode, contactName, and orderTotal, so it can identify the top customer without seeing PII.

My question

After sanitization, the LLM cannot mention email or address in its reply because it never received those fields.

How do you normally put removed PII back into the final answer for an authorized user?

Is the standard approach:

  1. Server-side re-hydration — LLM returns e.g. customerCode, and the orchestrator merges email / contactAddress from the raw tool result into the final answer?

  2. Structured LLM output (IDs only) + API builds the user-facing message?

  3. Something else?

I'm looking for the usual production pattern for:

sanitize → infer → re-hydrate (permitted PII for the user, never sent to the LLM)

.net chatbot large-language-model sensitive-data pii