ai newsMi., 28. Okt.
EilmeldungWe Built an Open-Source Skill to Improve Coding-Agent Prompts — Now Live in ChatGPT and the MCP Registry

An AI assistant for your own website: chat, voice calls and appointments, hosted on my own Mac

It started with a telephone. For a small business I had built an AI receptionist that answers calls, answers questions and suggests appointments. Speech recognition (Parakeet), the voice (a cloned Qwen3-TTS model) and the brain (Claude through Claude Code) all run on my Mac, not in a cloud speech s

dev.toMittwoch 21:47 · 28.10.5 Min. Lesezeit
Bild: dev.to

Posted on Oct 28 • Originally published at daniele-michelin.com

It started with a telephone. For a small business I had built an AI receptionist that answers calls, answers questions and suggests appointments. Speech recognition (Parakeet), the voice (a cloned Qwen3-TTS model) and the brain (Claude through Claude Code) all run on my Mac, not in a cloud speech service. At some point the obvious question came up: why not use the same technique for myself, on this website?

I did not want an intrusive chat pop-up. I wanted something discreet: a small round icon at the bottom right of every page, in the language of the page (DE, EN, IT). One click opens a window with an animated portrait of me that breathes, blinks and moves its mouth when it speaks. The assistant answers questions about me and the content of the site, and if you like you can call it right in the browser. It says from the start that it is an AI, and it does not make things up: what is not on the site it does not know, and then it points to the contact form.

Browser (widget) │ wss://daniele-michelin.com/assistent/ws ▼ nginx on the server ──► my Mac at home ├─ speech recognition + voice (local) └─ brain (Claude through Claude Code) ▲ └── settings: the Mac pulls them from the website every minute (token) Enter fullscreen mode Exit fullscreen mode The browser never talks to my Mac directly. It talks to my own domain and nginx forwards the connection:

location = /assistent/ws { proxy_pass http://MY-MAC:5070/ospite/ws $is_args$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } Enter fullscreen mode Exit fullscreen mode That keeps the page's content security policy strict ( connect-src 'self' ) and no visitor ever sees my home address.

All settings live in a protected admin page on the website: widget, tone, knowledge, voice, limits, appointments, mail. The Mac pulls them every minute with a token. I did not want a channel through which the website can change something on my computer; the Mac asks, never the other way round.

A Mac at home is not a data centre. If it is off or busy, the widget switches to plain text chat that the website answers by itself. There is deliberately no AI model and no third party behind it: the answers are written from the public content of the site and chosen by keywords. That is less flexible, but honest and nothing leaves the server. I add my own question-and-answer pairs in the admin.

The assistant can arrange a conversation with me. Free times come from my opening hours, minus appointments already booked and the entries in my Nextcloud calendar (via CalDAV; read-only for “busy”, and booked appointments are written there). There is also an ICS feed to subscribe to and confirmation e-mails. Messages for me work exactly like the contact form: same recipient, same mail design, same sending.

This is where I found a bug that kept me thinking. In a test the assistant said “appointment confirmed” although nothing had been booked: the model had not triggered the action and still found the right words. Since then the system decides, not the model. A booking waits in a pending state, the system speaks the summary itself, and only after an explicit “yes” is anything booked. The system also reports the outcome: “done”, “that slot has just been taken” or an error. Never leave it to a language model to say whether an action worked.

The content of conversations is not stored; the logs hold at most the time and the length of a message. Audio never leaves my Mac. The recognised text goes to the language model (Claude) today, which is the price for the quality. A visitor's IP address lives only in memory, for a daily limit. Appointment data (name, e-mail, topic, time) sits in a non-public file and is deleted automatically 90 days after the appointment. On the privacy page the section about the assistant only appears when the feature is switched on, and the paragraphs on appointments and messages only when those are active.

For that reason the public repository contains only my own code: the widget, the PHP endpoints and the admin page, the nginx configuration, the engine logic (guest limits, the system-owned booking flow) and a small text-only reference engine with a pluggable brain that is a local Ollama by default. The voice pipeline itself (recognition and cloned voice) is not included; the protocol it speaks is documented, so any speech stack can be attached. It is under the MIT licence, with English documentation, screenshots, an architecture diagram and a one-command demo: github.com/Mikweb2025-design/ai-site-assistant.

Today the recognised text goes to Claude. My goal is that nothing leaves the Mac any more: a language model that runs only locally. Honest status: in my earlier tests small local models were too slow and too weak for a conversation at phone speed. Now I want to try newer small models on Apple Silicon (MLX) and make the brain swappable behind an OpenAI-compatible interface. That is why an Ollama / OpenAI-compatible option is on the repository's roadmap. If I find a model that answers fast enough and sticks to the facts, I will write about it.

I already ran a first round with the reference engine and the real text of this site as knowledge. A 2-billion-parameter model answered in 2 to 6 seconds once warm, got a German question right and correctly refused an off-topic one. The 4B and 12B models I had installed took more than 30 seconds per answer with the long prompt, far too slow. So the direction is clear: smaller prompts (only the relevant chunk of knowledge instead of the whole page), streaming sentence by sentence, and a tiny classifier in front for greetings. The numbers and the script to repeat them on your own machine are in the repository ( docs/roadmap.md ).

Originally published at daniele-michelin.com. More guides, free checks (SPF, TLS, headers) and an error-message lexicon: daniele-michelin.com/en/.

Quelle: dev.to (dev.to). Original öffnen