
The idea
Want to build a clinical assistant that actually remembers each patient? Here is how
Think about a really good family doctor in a small town. You walk in and before you say a word she already knows you are allergic to penicillin, that you switched off the statin last spring because it gave you muscle pain, and that your mother had the same heart thing.
She does not flip through a thick folder while you sit there. She just knows, because she has carried your story forward visit after visit. The penicillin allergy from three years ago is as present in her head as the cough you came in with today. Nothing about you got lost between appointments.
That quiet carried memory is exactly what a chatbot does not have. Each visit, it starts from zero. It transcribes, it summarises, and then it forgets, so the next time the patient walks in the assistant has no idea what was said in April.
Korely is that carried memory. You ship the assistant, we carry the patient story forward.
How you build it
Eight steps, and the last one is the part you skip
- Pick your framework and model
You probably already have Claude Code or Cursor to write the agent, and an LLM you trust for the clinical reasoning. That part you keep. We do not touch the model.
- Define the safety frame first
Decide what the assistant is allowed to say, where it must defer to a clinician, and how it hands off. Memory does not replace judgement, it feeds it.
- Give every patient their own private space
With Korely you set a
user_idper patient, so one patient allergies, medications, and preferences stay out of another patient answers when every read passes that id. For a hard wall, give the assistant a key confined to its patients. - Write down what matters as the visit happens
When the patient mentions a penicillin allergy, a medication change, or that they prefer telehealth over coming in, the agent calls
korely.add()scoped to that patient. It saves the fact, not a transcript. - Read it back at the start of the next visit
Before the agent answers anything, it calls
korely.get_context()for that patient and gets back the facts true right now first (current meds, known allergies, stated preferences), then the matching notes, with no generative model on the read path. - Let the timeline correct itself
When the patient says they stopped a drug, the agent writes the new fact and our two-stage contradiction step retires the old one, keeping it on the record as superseded so nothing is silently erased.
- Wire up the regulated bits you would dread building
EU-hosted storage (with the Europe region for EU processing), an audit log of every read and write, and one call to erase everything about a patient when they ask. These come with the memory layer, not as a six-month side project.
- Here is where you stop building
You do not stand up a bi-temporal, graph-backed retrieval system, tune it, run contradiction resolution, and pass a data-residency review on your own. Korely is that whole memory infrastructure, ready, starting at 19 euro a month + VAT. You ship the assistant, we carry the memory.
The shape of it
One patient, two visits, the story carried in between
Visit 1, April
The visit gets written down
- Patient states a penicillin allergy and a medication
- Agent calls add() scoped to this patient
Korely memory
Bi-temporal store, EU-hosted
- Typed facts in the patient isolated space
- A stopped drug is marked superseded, kept on the timeline
- Audit log on every read and write
Visit 2, three months later
The agent shows up informed
- Calls get_context() before it answers
- Gets current allergies and meds
How Korely fits
The hard part nobody wants to build, already built
What Korely saves you is the part nobody actually wants to build: a bi-temporal, graph-backed agentic-memory layer that is safe to point at patient data. Building it yourself means a vector store plus typed fact extraction plus contradiction logic plus an entity graph plus a valid-from and valid-until timeline on every fact, then wrapping all of it in EU-hosted storage, audit logging, and a clean delete path.
That is months of specialist work and an ongoing maintenance tax, and in healthcare it is also the part a reviewer will scrutinise hardest. We already did it. The memory is Postgres-only, hosted in the EU, with no generative model sitting on the read path. Retrieval is a pgvector search plus a lookup of the typed facts, all in Postgres, so the few facts that matter surface ahead of three visits of small talk.
And it stays small. The context block comes back under a token budget you set, 800 tokens by default, with the facts that match the question placed ahead of the raw memories, so a recorded allergy is not buried under three visits of small talk.
For regulated teams that require on-prem deployment, the Self-hosted plan runs the same engine on your own servers. Talk to us at info@korely.ai.
Show me the code
Two calls, one isolated patient space, one-call erase
import hashlib
import os
from korely_memory import Korely
# EU-hosted memory API: memories and facts are stored in the EU.
korely = Korely(api_key=os.environ["KORELY_API_KEY"])
# One memory per patient, never the raw id
patient = hashlib.sha256(b"PAT-2026-04812").hexdigest()[:32]
# ── April: the patient mentions an allergy and a medication ─────
korely.add(
"Allergic to penicillin. On lisinopril 10mg for blood pressure. "
"Prefers telehealth over coming in.",
user_id=patient,
# your own label, stored on the memory and filterable in search; not part of the audit log
metadata={"lawful_basis": "vital-interest"},
)
# ── Three months later: read back what is true NOW ─────────────
context = korely.get_context(
"current allergies and medications",
user_id=patient,
)
# context.context → the facts true now first: penicillin allergy, lisinopril 10mg
# no generative model on the read path.
# ── Right to be forgotten: erase everything in one call ────────
korely.delete_all(user_id=patient)
The same memory is reachable from any agent: Claude Code, Cursor,
LangGraph, n8n, or a plain HTTP client against the REST API. Scope
each patient with a different
user_id
and their facts stay in their own room.
When the facts change
The assistant answers about the right drug, not the loudest one
A patient was put on lisinopril for blood pressure two years ago. Last spring it started giving her a dry cough that would not quit, so her doctor swapped her to losartan and the lisinopril was stopped. Today she opens the patient assistant and asks whether her current blood pressure medication is safe to take with the new cold remedy she just bought.
A plain chatbot, or a naive recent-history window, will happily reach back and answer about lisinopril, because that is the drug it saw mentioned the most across her record. Korely answers from what is true now. The agent reads her facts, sees that lisinopril is marked superseded with an effective-until date and losartan is the current medication, and reasons about losartan.
The old fact is not deleted, it stays on the patient's timeline
with its dates (get_facts with
include_invalidated), so a clinician can later see
exactly when the switch happened. Time-aware memory is the whole reason the assistant talks
about the right drug instead of the loudest one.
korely.add(
"On lisinopril 10mg for blood pressure.",
user_id=patient,
timestamp="2024-03-01",
)
# Last spring: dry cough, doctor switches the drug
korely.add(
"Stopped lisinopril (dry cough). Now on losartan 50mg.",
user_id=patient,
timestamp="2026-04-10",
)
ctx = korely.get_context("current blood pressure medication", user_id=patient)
# once extraction has run, ctx.context lists under Known facts what is true now: losartan 50mg; the lisinopril fact is closed
# Full history stays walkable:
korely.get_facts(user_id=patient, include_invalidated=True)
# each Fact has valid_from and invalid_at Frequently asked
Healthcare deployment, common questions
Is this safe to point at patient data, and where does it live?
The memory lives in a managed store hosted in the EU, Postgres with vector and graph indexes. To extract facts, the text of each memory you write, with the patient's identifier, up to ten of that patient's earlier memories, the earlier facts it is compared with, and the phrase of any relation that patient has not used before, with a value, goes to the language model of your project's region: Google's Gemini API (United States and other countries where Google has facilities) by default, or a model on Scaleway in Paris if you choose the EU region, and then no memory text reaches Google. Searches and context queries run no language model. Every read and write is recorded in an audit log so you can show who or what touched a patient record and when. You do not host or harden any of it yourself. We are honest that Korely is the memory layer, not a certified medical device, so you keep your own clinical safety frame and human oversight on top of it.
How do you keep one patient's data from leaking into another patient's answers?
Every patient gets their own user_id. A read that passes it returns only that patient's memories and facts. For a hard wall, give the assistant a key confined to its patients (create_key(..., users=[...])), and a call can then never reach another patient, so allergies, medications, and preferences stay where they belong.
A patient asks us to delete everything. How hard is that?
It is one call. You delete by that patient user_id and every memory, every fact, and the full timeline for that patient is erased from the store. It is built for the right-to-be-forgotten case from day one, not bolted on later, which is exactly what a data-protection review will ask you about.
How does it handle a medication or diagnosis that changes over time?
Facts are time-aware. When a patient stops a drug or a preference changes, the agent writes the new fact and our two-stage contradiction step retires the old one, keeping it on the record as superseded with its effective dates instead of silently overwriting it. So the assistant answers from what is true now, and a clinician can still retrace the history. Each fact also keeps when the assistant learned it, so a reviewer can ask what the assistant knew at the time of a visit.
Will adding memory slow the assistant down in front of a patient?
No. No generative model sits on the read path: a recall is one embedding call for the query plus a database lookup. The agent reads the patient current allergies and medications before it answers, and the patient does not feel a pause.
Do I have to rebuild my agent to use this?
No. You keep the framework and the model you already have, whether that is Claude Code, Cursor, LangGraph, or a plain HTTP client. You add two calls, korely.add() when something worth remembering happens and korely.get_context() before the agent answers. The memory infrastructure is the only part you are handing over, and it starts at 19 euro a month + VAT with a free tier to try it.
Wire memory into one patient flow today
The free tier lets you build memory into one patient flow today, and pricing starts at 19 euro a month + VAT when you outgrow it. Before you send health data, sign our data processing agreement (write to privacy@korely.ai); it covers every Cloud account. Need it on your own servers? That is the Self-hosted plan. For a custom retention agreement, write to info@korely.ai.
Looking for a different shape? See the other nine use cases →