Xirai — Medical system with AI
A medical system with computer vision: reads radiographs, dental panoramic X-rays and skin lesions with YOLO, and handles the clinic's WhatsApp 24/7 to book and follow up.
- Python
- FastAPI
- YOLOv8
- OpenCV
- Gemini
- Docker
- Laravel
- PHP
- Livewire
- MySQL
- Stripe
- WhatsApp API
Constraints
- An assisted diagnosis cannot invent findings that are not in the image.
- Most queries arrive when the clinic is closed. Whoever answers first gets the appointment.
- The data is clinical. Medical logic cannot be mixed with administration.
- Hardware was not guaranteed, so inference has to run on CPU and use a GPU if there is one.
- Model weights change often; rebuilding the container for every version is unworkable.
The problem
A medical system that reads the studies
The part almost nobody builds: computer vision applied to real medical images. Xirai analyses studies with trained detection models —not a language model guessing over a photo— and returns localised findings.
Three modalities, the same engine:
- Dental panoramics YOLO detects every tooth and numbers it with FDI notation. The diagnosis is written on top of that detection.
- Chest radiograph Detection over chest plates with the same contract and the same deployment scheme.
- Skin lesions Dermatology. The youngest of the three services.
Local detection with computer vision · generative writing
How it analyses a study
- 01 The image comes in A dental panoramic, a chest plate or a lesion photo, through the same endpoint.
- 02 YOLO detects and localises The trained model finds the structures and numbers them. In dental, every tooth gets its FDI number. This is deterministic: the same image gives the same result.
- 03 The diagnosis is written The language model works on the detections, not on the image. No detection, no finding to write.
The full chain: from pixels to a traceable finding
That separation is what makes the system auditable. When a finding is wrong, you can tell whether detection or writing failed — because they are two distinct stages with two distinct outputs. Ask the same model for everything and there is no way to know where it broke.
What runs underneath
The three services are independent containers with the same contract: same health endpoint, same response format. A new client integrates without learning anything new, and one service can be replaced without touching the others.
Two decisions you only appreciate once you have deployed it:
Hardware was not guaranteed. Inference runs on CPU by default and uses a GPU if the host has one. The GPU reservation in the deployment exists but is commented out with the instruction to uncomment it when the host offers one, instead of demanding it just to boot.
Weights are mounted, not baked in. Updating a model is swapping a read-only file and restarting, with no image rebuild. With three services and models that change often, baking them in would have turned every iteration into a full build. And if the trained model is missing, the service starts with the generic one leaving an unmistakable warning in the log: starting silently with the wrong model produces bad diagnoses with nobody noticing.
And on top of that, the patient
The detection model does not answer WhatsApp. For that there is a conversational agent trained on the clinic’s operation, working while the clinic is closed — which is when most queries arrive.
Evening query → availability, prices → appointment with the study included
The price was not invented: it was in the clinic’s knowledge base. And had they asked for something not there, the agent escalates instead of improvising.
The panel the owner sees
- Conversations Full, searchable history of every thread with your patients.
- Appointments Booked by the agent, confirmed, with a reminder.
- Leads Captured contacts with their intent and interest level.
- Configuration Editable answers, hours and flows with no code.
What the clinic owner sees, not the engineer
Who it is for
- Dental clinics Booking, quotes, panoramics and treatment follow-up.
- Medical practices Assessments, hours, preparation, insurance and follow-up.
- Radiology and diagnostics Assisted reading of studies with localised findings.
- Dermatology and aesthetics Lesion analysis, packages, costs and initial guidance.
Plans
- Essential $2,490 MXN / month Up to 300 conversations a month. Automates the first line of attention.
- Most popular Professional $4,990 MXN / month Up to 1,000 conversations. Per-conversation memory, lead capture and human escalation.
- Enterprise $9,990 MXN / month Unlimited agents and conversations, multichannel, integrations and a support SLA under 2 hours.
About the team
Xirai is mine: it was born inside Alean. The architecture, the data model, the domain rules, the code zones and the inference pipeline design are my design; the implementation goes through pull-request review against working branches.
Decisions
- 01
Detection is deterministic, writing is generative
The vision model detects and numbers the teeth using FDI notation; the language model writes the diagnosis from THAT detection, not from the image. A general model is not asked to do a specialist's job: the deterministic part stays local, auditable and cheap, and the generative part is used only to write.
RejectedSending the X-ray to a vision language model and asking for the whole diagnosis. It gives plausible answers with no traceability, and when the finding is wrong there is no way to tell whether detection or writing failed.
- 02
Starting with the generic model is allowed; doing it silently is not
If the trained model is missing, the service starts with the generic weights and leaves an unmistakable warning in the log. Refusing to start without custom weights makes the service unusable in development; starting silently with the wrong model produces bad diagnoses with nobody noticing. The third option is the one that was rejected.
- 03
Weights are mounted, not baked in
The models live in a read-only volume, so updating a weight is swapping a file and restarting, with no image rebuild. With three services and models that change often, baking them in would have turned every iteration into a full build.
- 04
The three services share the same HTTP contract
Dental, radiology and skin are three separate containers with the same health endpoint and the same response format. A new client integrates without learning anything new, and one service can be replaced without touching the others.
- 05
The agent receives context, not access
On the conversational side, the agent does not query the database on its own: it receives an already-assembled context —services, hours, prices, brand voice and the thread— and answers with that. If something is not in its knowledge base, it escalates instead of improvising. That is the difference between a trained assistant and one that hallucinates prices.
- 06
Code zones have different permissions inside the same repo
The repository declares three explicit zones: a safe one where you can work freely; a careful one where models only accept new relationships; and a forbidden one without review —clinical logic, the endpoints the automation consumes, and the external workflows—. PR review alone does not distinguish "I added a relationship" from "I changed clinical logic", so the distinction lives in the repository.
Outcome
- Three medical image inference services —dental panoramics, chest and skin— with computer-vision detection behind a uniform HTTP contract.
- Local dental detection with FDI numbering, and a diagnosis written by a language model on top of that detection.
- A WhatsApp agent that answers, books, qualifies and escalates with full patient context.
- Three commercial plans with defined volume and scope, from attention up to multichannel with a support SLA.
- A panel where the clinic sees conversations, appointments, leads and studies with no technical knowledge.