ai newsDi., 27. Okt.
EilmeldungAnthropic Says It Will Revolutionize Biology—Some Day

Datei-Uploads im KI-Chat: Sicherheit statt Paperclip-Optik

Beim Einbau von Dateianhängen in FodyChat lag die eigentliche Herausforderung nicht am KI-Modell, sondern an Fragen zu Zugriff, Übertragung und Schutz der Dateien. Die Lösung kombiniert wenige Buttons, presigned URLs und einen Malware-Scanner.

dev.toDienstag 15:18 · 27.10.DE4 Min. Lesezeit
Bild: dev.to

Posted on Oct 27 • Originally published at chat.fodylabs.com

Most "AI chat" widgets do one thing: you type, it answers. Attachments are an afterthought — a paperclip that dumps a file somewhere and shows a thumbnail.

When we added files to FodyChat, the interesting problems turned out to be almost nothing to do with the AI. They were about who the file is for, where it lives, and how big it is allowed to be.

A file upload usually means one of two very different things:

These want different limits, different failures, and different UI. So under the "+" we put two items: Extract text from a file and Upload a file. The first drops extracted text into the input box for review before sending. The second attaches the file to the next message as a removable chip.

Here's a mistake we almost made: when a guest uploads a screenshot, we made the AI read it. But the AI isn't usually the one who needs it. In a support chat, a screenshot means "here is what I see" — and the person who needs to understand it is the operator on Telegram, Slack, or email, not the bot.

So we invert the emphasis: vision transcription (OCR + a short description) is delivered to the receiving side. A guest's file reaches the operator with the file itself and its transcription. An operator's file reaches the guest as a card and an explanatory snippet of its text. The AI reading the image is a paid-tier extra, not the point.

By default, files go into our R2 bucket. But "your files are in our bucket" is a non-starter for some customers — data-residency, compliance, or just "we want to own it." So storage is a small pluggable interface — put, get, delete — with two implementations: R2, and any S3-compatible bucket the customer brings.

That seam paid off twice. First, it gave us lifecycle hooks: afterPut / afterDelete can POST to a customer webhook, so they can chain OCR, virus scanning, or indexing into their own pipeline. Second, it opened the door to the large-file problem below.

Our per-plan limits were generous — up to "unlimited." But an embeddable widget runs on Cloudflare Workers, and Workers has hard ceilings: a 100 MB request body and 128 MB of memory on the free plan. Read a 100 MB file, base64 it for the scanner, and you've blown the memory budget. "Unlimited" was a lie told by our own pricing table.

Malware is the part nobody wants to think about, but a support chat receives arbitrary files that a human operator will open on their own machine. Full antivirus engines don't fit in a serverless worker — ClamAV's signatures alone are hundreds of megabytes. With zero customers and unknown demand, we did what's free:

That's not enterprise-grade antivirus. It's the right 80% for free: stop the obvious abuse, and leave a clean seam for a real scanner when a customer actually asks for one.

None of this matters without retention. Orphaned uploads (never sent) expire in 24 hours; attached files expire per-plan; a tenant leaving cascades to its files. A file's life ends the way it should: with its deletion.

And deletion is where everyone has the same scar. You send a message in one messenger, instantly regret it, hit "delete" — and only later learn the app deleted it for you, while everyone else still sees it. The mistake is treating "delete" as one action, when it is really two: remove the reference, and remove the thing itself.

Files have the same trap. Delete the database row and the bytes are still in the bucket — the chat says "gone," the storage says "still here." So FodyChat deletes both, every time: the bytes leave storage and the row leaves the database, on message deletion, on retention expiry, and when a tenant leaves. A deleted file is actually deleted.

If the storage is yours — a BYO S3 bucket or your own self-hosted stack — the files live in your bucket, not ours. The originals stay with you; we don't keep a separate copy or take custody of them, and you stay in control of your own storage.

The result is a chat widget where files work the way files actually work in support: sent, received, read, scanned, and eventually deleted — with the storage and the limits under the customer's control, not ours.

Originaltitel: Files in an embeddable AI chat: two buttons, a presigned URL, and a malware scannerQuelle: dev.to (dev.to). Original öffnen