DEV Community

Oleksander
Oleksander

Posted on

Give an AI Agent Your Customer List Without Telling It Who Your Customers Are

Every business that tries AI agents hits the same wall.

The useful questions are about your own data. Which customers owe us more than a month? Who is waiting for a reply? What do people complain about most? To answer, the agent needs your customer list, your invoices, your mail.

And that is exactly what you can't send to a cloud model. Names, e-mails, phone numbers, account numbers: personal data of people who never agreed to it. So you either don't ask, or you paste it in and hope.

I build Aura, a desktop app that gives AI tools memory and data that stay on your computer. I wanted a third option, so I tested one.

How I tested: I wrote down the rules and the pass/fail line of every test before running it, and failed tests are reported as failures. I used public test sets wherever one existed.

The idea: the agent sees tokens, you see names

Before the agent touches a table, Aura makes a local copy where every name, e-mail, phone and account number is replaced by a stable token:

What you have What the agent sees
Olena Petrenko, olena@firm.ua, owes 12,000 name_1, email_1, owes 12,000
"Called Mr Kowalski, he wants the invoice at jan@firma.pl" "Called name_2, he wants the invoice at email_2"

The same person always gets the same token, so the agent can still count, group, join tables and follow a customer across rows. When you ask for the actual list ("send me the debtors"), the result is written to a file on your computer with the real names put back. The agent only learns the file name.

The obvious worry: does the AI get worse at its job when it can't see names?

Does the AI get worse? Barely

I used BIRD, a public benchmark where an AI writes SQL to answer questions about real databases: 179 questions over 4 databases, Google's gemini-3.8-flash writing the queries.

The agent sees Correct answers Names, e-mails, numbers that reached the cloud
The real data 68.2% 849
Tokens instead of names (Aura) 67.6% 0
Only the table structure, no rows 65.9% 0
A small local model, nothing sent 35.2% 0

The gap to full access is 0.6 points, within noise. The same held with a second model (Qwen: 67.0% with tokens vs 64.8% with real data). And the obvious "keep it all local" alternative is far worse: a small model on your own computer got half as many answers right.

Text is the hard part

Tables are the easy case: a "Name" column is a name. Real business data is mostly text: notes, comments, the body of an e-mail. A name can be anywhere, in any language, in any grammatical form.

The standard answer is a small AI model that finds personal data in text. I needed one that runs on an ordinary office PC, so nothing gigabyte-sized. I tested the four lightest multilingual ones I could find on public test sets in 21 languages (court rulings, EU legal text, synthetic finance documents).

None was good enough alone. The best found 69–78% of the people. Roughly one name in four would have gone to the cloud.

What worked was using something the gateway already knows: who the text belongs to. An e-mail has a sender and recipients. A note sits in a customer's row. Those people's names, addresses and numbers are known, so they can be found in the text reliably, in any form ("Kowalskiego" for Kowalski, "Mr Benham" for Stephen Andrew Benham), with no word lists for any language. The model then only has to catch strangers mentioned in passing.

Text People hidden
Finance documents, 7 languages 95%
Court rulings about 95% of people with a name in the text (82% of all mentions; the rest are bare initials like "A." that courts already anonymized)
EU legal text in 21 languages, where most people are not in any record 55%

Then I ran it on 85 real e-mails from my own inbox. Aura replaced every sender and recipient and more than 750 names, addresses, numbers and links inside the messages. Then it checked its own work: it searched the agent's copy for each of the 254 values it had hidden. No full name, address or number was left. Three single words remained (a city, a lone first name).

This check now runs after every upload. It's built into the app, so you don't have to take my word for it.

What it does not do

I want to be precise, because privacy claims are easy to overstate.

  • This is pseudonymization, not anonymity. The agent still sees the content: subjects, amounts, dates, company names. If the content itself identifies someone ("the CEO of our biggest client"), tokens won't hide that.
  • In free text, coverage depends on what you have. It's highest when the people mentioned are in your data, lower for strangers. Single words, like a first name alone or a city, can remain.
  • Names written in another alphabet aren't linked. A Cyrillic record won't match a Latin signature; only the optional model can catch it.

Try it

Aura for Windows is free: aurasdk.dev/desktop. In the Data tab there are two zones:

  • Upload: the agent sees the file as it is. For documents you don't worry about.
  • Safe upload: names, contacts and numbers are replaced with tokens, also inside mail and notes, and the copy is checked.

It takes Excel, CSV, SQLite and mail (.eml, .mbox from Gmail, Thunderbird or Apple Mail). One click connects Claude Code, Claude Desktop, Cursor and other agents. An optional model (about 380 MB, downloaded only if you turn it on) also hides people who are not in your data. Everything runs on your computer.

It's an early version. If you work with customer data and would like an AI on it, I'd really like to hear whether this solves your problem, and what's missing.

Top comments (2)

Collapse
 
omyvnss profile image
Om Yaduvanshi •

the 0.6-point BIRD gap is the number that sells it, but BIRD is SQL over structured tables, where a string is just a string. tokenization is nearly free there. the real cost would show up where string semantics matter: fuzzy matches, misspellings, entity resolution across variant spellings. that's the benchmark i'd want to see next.

Collapse
 
teolex2020 profile image
Oleksander •

You were right, so I ran it. FEBRL (5,000 synthetic person records with typos, swapped and missing fields), same agent loop, gemini-3.8-flash.
Looking someone up by a misspelled name (“Sameul Ryan”, “Isaac Clark” for Clarke):
real data: 98.3%
tokens: 86.7%, an 11.6-point cost, exactly where you expected it
tokens + a local “similar values” tool: 96.7%
The tool compares the real strings on the user’s machine and returns only tokens with a similarity score, so the agent can pick name_14 without ever seeing the name. It only accepts text from the question or a token, so it can’t be used to probe names letter by letter. No real name, address or ID reached the model in either token arm.

One honest gap: finding duplicates scored ~100% even with plain tokens, because FEBRL duplicates share date of birth, postcode and street number, which stay visible. Duplicates that differ only by name, and transliteration (Cyrillic ↔ Latin), are still untested. Those are next.
Thanks, this one is going into the gateway.