Written in the operator-handbook style of the Ops Docs collective (title, last-updated line, short prose, tables, a quick-checks block, no secrets). Ready to paste into the collective, or to publish once writing to Nextcloud is permitted — that call was blocked by my permission layer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
121 lines
5.3 KiB
Markdown
121 lines
5.3 KiB
Markdown
# Ped AI And Milvus
|
|
|
|
Last updated: 2026-09-11
|
|
|
|
What Ped-AI is, which Milvus is which, and where each kind of data lives. Written
|
|
for the operator handbook, so it says where things are rather than how they are
|
|
coded.
|
|
|
|
## What Ped-AI is
|
|
|
|
A clinical documentation assistant. Two halves:
|
|
|
|
- **Workspace** — encounter notes, dictation, SOAP, well and sick visits, ED,
|
|
hospital course, calculators, Learning Hub. Each generates text with an LLM
|
|
through the LiteLLM gateway.
|
|
- **Clinical Assistant** — a chat that answers only from an indexed medical
|
|
library, with numbered citations back to the source documents.
|
|
|
|
It runs as one container, `pediatric-ai-scribe`, on `127.0.0.1:3552` behind
|
|
Caddy. Postgres and Redis are its own; everything else it talks to belongs to
|
|
another stack.
|
|
|
|
## The two Milvus servers
|
|
|
|
They are easy to confuse, and both listen on 19530. Connecting to the wrong one
|
|
succeeds at the network level and then fails authentication, because each has
|
|
its own users — so a mistake here looks like a password problem.
|
|
|
|
| Which | Container | Database | Collection | Holds |
|
|
|---|---|---|---|---|
|
|
| **Clinical** | `nextcloud-mcp-server-milvus-1` | `default` | `mcp_bge_m3_1024` | The medical library Ped-AI answers from. ~1.8M chunks. |
|
|
| **Personal assistant** | `personal-assistant-storage-milvus-basic-milvus-1` | `basic` | `personal_assistant_bge_m3_1024` | Your Nextcloud mail, notes, tables and files. |
|
|
|
|
Both embed with **bge-m3** at 1024 dimensions, which is what the collection names
|
|
now say. Neither is reachable from the internet: the personal one publishes no
|
|
ports at all, the clinical one is bound to `127.0.0.1`.
|
|
|
|
Repositories, renamed 2026-09-11 to match what they hold:
|
|
|
|
- `personal-assistant-storage-milvus` — was `ped-ai-storage`
|
|
- `clinical-storage-milvus` — was `nextcloud-mcp-server`, and runs no MCP server,
|
|
only etcd, MinIO and Milvus
|
|
|
|
Container and volume prefixes still read `ped-ai-storage_*` on anything not yet
|
|
migrated; the project name is pinned deliberately, because changing it makes
|
|
Compose create empty volumes instead of finding the existing ones.
|
|
|
|
## How Milvus stores its data
|
|
|
|
Milvus keeps **segment files in MinIO**, not on a local disk, and its metadata in
|
|
etcd. That matters: `COMMON_STORAGETYPE=local` writes segments relative to the
|
|
working directory, so recreating the container destroys them while etcd still
|
|
references them, and the collection then hangs at `Loading` forever. Each Milvus
|
|
has its own MinIO and its own etcd container.
|
|
|
|
Access is per-database and per-collection. Renaming a collection revokes its
|
|
grants, because a grant names the collection — after any rename, re-run the
|
|
bootstrap that provisions the roles.
|
|
|
|
## Where each kind of data lives
|
|
|
|
| Data | Where |
|
|
|---|---|
|
|
| Accounts, notes, encounters, Learning Hub content and quizzes | Postgres (`pedscribe`) |
|
|
| Learning Hub semantic search | `learning_content.embedding`, pgvector |
|
|
| Generated images | MinIO bucket `generated-images` |
|
|
| Voice recordings, kept 24 hours | MinIO bucket `audio-backups` |
|
|
| Medical library chunks | Clinical Milvus |
|
|
| Nextcloud mail, notes, tables, files | Personal assistant Milvus |
|
|
|
|
Quizzes are ordinary relational tables and use no vectors at all.
|
|
|
|
## How a question is answered
|
|
|
|
1. The browser posts to `/api/clinical-assistant/chat/stream`.
|
|
2. Ped-AI calls the MCP tool `clinical_semantic_search` on `mcp-server-mcp-1`.
|
|
3. That searches the clinical Milvus and returns passages with scores.
|
|
4. Ped-AI sends those passages to the chat model as the only permitted source.
|
|
5. The answer streams back with numbered citations; the Sources panel shows the
|
|
passages behind them.
|
|
|
|
If retrieval returns nothing, the assistant says so rather than answering from
|
|
the model's own knowledge.
|
|
|
|
## Recordings
|
|
|
|
Every recording is kept for 24 hours, whether or not its transcription
|
|
succeeded, gzipped and encrypted before storage. A recording holds a screen wake
|
|
lock while it runs, survives moving around the app, and is saved with the module
|
|
it came from if the session ends. Recordings can be downloaded from
|
|
Settings → Audio backups.
|
|
|
|
Transcription is a gateway model — currently `mistral-voxtral-mini-transcribe`.
|
|
The browser's own speech recognition is a separate, off-by-default setting; it
|
|
sends audio to the browser vendor and is not HIPAA-compliant.
|
|
|
|
## Indexing
|
|
|
|
| Index | Written by | Source |
|
|
|---|---|---|
|
|
| Clinical | `mcp-server-mcp-indexer-1` | The medical library. Text extraction via `unstructured`, PyMuPDF4LLM and Tesseract. |
|
|
| Personal assistant | `personal-assistant-storage-milvus-basic-indexer-1` | Nextcloud. Mail first, then notes, deck, tables, calendar, todos, collectives, cookbook, talk, contacts, and files. PDF text via PyMuPDF4LLM. |
|
|
|
|
The folder the personal indexer walks is `BASIC_INDEXING_DOCUMENTS_FOLDER`. It
|
|
takes one folder or several separated by commas, each walked recursively:
|
|
|
|
```
|
|
BASIC_INDEXING_DOCUMENTS_FOLDER=Personal assistant,Clinical Notes
|
|
```
|
|
|
|
A complete listing is the authority for deletion, so moving that setting to a
|
|
different folder removes the chunks of everything no longer under an indexed
|
|
root.
|
|
|
|
## Quick checks
|
|
|
|
```bash
|
|
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3552/api/health
|
|
docker ps --format '{{.Names}} {{.Status}}' | grep -E 'pediatric-ai-scribe|milvus|indexer'
|
|
docker logs --since 10m personal-assistant-storage-milvus-basic-indexer-1 | grep -c Indexed
|
|
```
|