跳到正文
DEV Community· Kuntal Gorai·· 3 小時前AI 評分54

MedPort:在手提電腦本機讀取化驗報告的私隱醫療檔案工具

MedPort: a private medical portfolio that reads your lab reports on your own laptop

AI 導讀

作者以 MIT 授權開發 MedPort,讓本機開放權重模型讀取化驗報告和出院摘要,整理成供醫生查閲的個人醫療檔案。工具支援 PDF、掃描件和手機相片,會把提取的數值與原頁文字核對,並要求用戶逐項確認。資料留在本機,無需帳戶、雲端或 API key,亦可離線使用。

正文

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Every time someone in my family sees a new doctor, the same thing happens: a plastic bag of lab reports from three different labs, a phone gallery full of blurry PDFs, and a doctor flipping through pages trying to find last year's HbA1c.

MedPort turns that pile into one clean page. You drop in lab reports and discharge summaries, and a small open-weight model running on your own laptop reads them into a portfolio a doctor can scan in thirty seconds: allergies, conditions, current medications, out-of-range results, and trend charts that line up the same test across different labs and years.

Your reports never leave your machine. There is no account, no cloud, and no API key.

Who would pay for it:

  • Caregivers of elderly parents juggling reports from several hospitals. This is the sharpest pain, and a one-time fee or about ₹299 / $5 a month is an easy yes for them.
  • People with chronic conditions (diabetes, thyroid, kidney) who track the same labs for years.
  • People moving cities or countries who need one coherent history to hand to a new doctor.
  • Later, small clinics that want intake summaries without sending patient data to a cloud API.

What it does:

  • Reads PDFs, scans and phone photos, rebuilding table rows so values land in the right place.
  • Extracts only what is printed (lab values, diagnoses, medications, allergies) and never interprets or gives advice.
  • Checks itself: every value the model returns is matched against the page text and dropped if it isn't there.
  • Lines up results across labs: "SGPT", "ALT (SGPT)" and "Alanine transaminase" all become one trend line.
  • Lets you review each value next to the original before it counts. Anything you haven't checked is marked "unreviewed".
  • Shares the portfolio as a printable PDF, a passphrase-locked file that opens in any browser, or a QR code a doctor scans on the same Wi-Fi.
  • Goes with you to the hospital: a phone companion app keeps a PIN-encrypted copy that works with no laptop and no internet.

Demo

Everything below uses fictional reports generated by samples/make_samples.py, read by gemma4:e2b on a CPU-only laptop.

1. Upload, and the model reads each report in the background. The review screen puts the original next to what was extracted, so you confirm every value before it counts.

Review screen: the original report next to the extracted values

2. The portfolio a doctor reads in thirty seconds: allergies, conditions, medications, out-of-range results, and trends across labs.

The portfolio page

Lab results lined up across different labs and dates

3. Share it as a PDF, a passphrase-locked file, or a QR code on the same Wi-Fi.

QR share card

4. At the hospital, on the phone, with no laptop and no internet.

The phone app showing the portfolio offline
Out-of-range results on the phone
Send to doctor from the phone

Code

MedPort

A private medical portfolio that runs on your own computer. Drop in lab reports and discharge summaries; a local open-weight model reads them into a one-page summary you can hand to any doctor allergies, conditions, current medications, out-of-range results, and trend charts across labs and years Your reports never leave your machine.

Install (Windows)

  1. Download MedPort-windows.zip from the latest release, unzip it, and double-click MedPort.exe. Your browser opens MedPort; keep the black window open while you use it. (Not code-signed yet: if SmartScreen appears, choose More info -> Run anyway.)
  2. Optional but recommended: install Ollama and run ollama pull qwen2.5:3b, so a local open model reads your reports. MedPort shows these steps on first run.

Your data stays in %USERPROFILE%\.medport. Nothing is uploaded anywhere.

Run it from source

pip install -r requirements.txt
# 1. Install Ollama (https://ollama.com) and pull a small open model
ollama pull qwen2.5:3b          

…

MIT licensed. There is a Windows download (unzip, double-click MedPort.exe, and it opens in your browser), or run from source with pip install -r requirements.txt and python -m medport.

How I Built It

The open pieces doing the work:

Piece What it does in MedPort
Ollama Local inference server. MedPort talks to it over localhost only.
Gemma 4 (gemma4:e2b), thinking off The extractor I run day to day on my laptop.
Qwen2.5 3B / Qwen2.5-VL 3B Default text model, and the vision model used as OCR for photos and scans.
PyMuPDF Pulls text from PDFs and rebuilds table rows from word positions.
FastAPI + Jinja + SQLite The app itself, all on the user's machine.

The pipeline:

  1. Read. PyMuPDF extracts text. Pages with no text layer (scans, photos) go to the local vision model.
  2. Extract. Each page goes to the model with a JSON schema through Ollama's structured output at temperature 0. The prompt asks only for what is printed on the page.
  3. Ground. Small models occasionally invent a value. Every number and name the model returns is checked against the page text, and anything not found is dropped. A rule parser also runs, and rows it finds that the model skipped are added back.
  4. Normalize. A lookup table maps about 40 common tests to one name and a LOINC code, so results from different labs share a trend line. Out-of-range flags come from each report's own reference range.
  5. Review, then share. The user confirms values against the original before anything is shown as reviewed.

Making it fast on a normal laptop. My laptop is an i5 with 16 GB of RAM and no GPU. Gemma 4 and Qwen3 are "thinking" models, and switching thinking off made extraction about 3x faster on CPU with no loss on this narrow task. Long reports are sent in chunks, reading runs in the background with a live "page 2 of 5" status, and there is a per-page timeout and a per-report time budget. If a page runs out of time, the rule parser takes over, so a report never just hangs.

It still works with no model at all. With Ollama off, the rule parser handles common lab layouts, and pressing Read again later reruns the model.

The phone companion. At a hospital, you have your phone, not your laptop. Running py -m medport --lan serves a small installable web app to the phone over home Wi-Fi. Phones only allow offline apps and in-browser encryption over HTTPS, so MedPort creates its own tiny certificate authority, restricted with X.509 name constraints to private addresses, which means it can't be used to impersonate any public website. The phone pairs with a one-time code and keeps an AES-256-GCM copy encrypted with a key derived from your PIN (PBKDF2, 310k rounds). From the phone you can show the portfolio, print it, or Send to doctor, which builds a passphrase-locked file on the phone itself and opens the share sheet for WhatsApp or email.

One real-world bug worth mentioning. The first real report I tried (from an Indian hospital lab) wrapped long test names inside table cells, which put the value on its own line, and both the model and the parser lost the row. Fixing that, with an anonymised copy kept as a test fixture, mattered more than any prompt tweak.

Why Does Open Innovation Matter?

For MedPort, open models aren't a cost optimisation. They are the only way the product can exist.

  • Privacy is the product. Health records are the data people least want on someone else's server. With a closed API, "your reports stay private" is a policy promise from a company you have never met. With a local open-weight model, it is a fact you can check by turning off Wi-Fi. The whole demo runs offline.
  • It works where the problem is. Hospital Wi-Fi is bad, and you can't ask a patient to sign up for a cloud service in a waiting room. The laptop reads reports with no internet, and the phone shows them with no internet.
  • Zero cost per report. A caregiver might upload 50 reports in the first week. With a paid API, every report costs me money, so I would need a subscription just to cover inference. Locally the marginal cost is zero, so a one-time price works and the business is viable at ₹299.
  • Swap models with one setting. MEDPORT_MODEL switches between Gemma 4, Qwen2.5, Llama 3.2 or MedGemma. When a better small model comes out, users get it with ollama pull, and nobody can deprecate the model out from under them.
  • Room to fine-tune. Every correction a user makes on the review screen is a labelled example. The extraction task is narrow enough that a 1 to 3B model fine-tuned on those corrections (with consent, on-device) should beat a general-purpose giant, which a closed API would never let me ship to the user's own laptop.
  • No lock-in. No API key to leak, no pricing change or account ban that can break someone's medical history.

Where closed would have won: a frontier API reads messy scans more accurately out of the box, and I wouldn't have spent time on a grounding check. But the grounding check plus a review screen turned out to be the right design anyway. Even a perfect model shouldn't put a lab value in front of a doctor without the patient confirming it.

Prize Categories

  • Gemma: MedPort runs Google's open-weight Gemma 4 (gemma4:e2b) locally through Ollama as its day-to-day extraction model on a CPU-only laptop.

來源:DEV Community · dev.to