Summary
The Suggestions tab shows, for each source concept, OMOP candidates ranked by a combined score. These suggestions come from two places: precomputed scores — syntactic and semantic — computed by Linkr on the server, as a background job; and the proposals of an AI agent, which follows the concept-mapping skill and works live in the project through the MCP server, with no export. Either way, you are the one who creates each mapping.
Why a separate tab
Mapping 1,000 local codes by hand against the 4 million concepts of the OMOP vocabulary is slow. Each algorithm family has its own bias:
- String comparison misses synonyms (“HR” vs “heart rate”).
- Semantic embeddings occasionally confuse close-but-different concepts (“serum creatinine” vs “urine creatinine”).
- An AI agent adds clinical context but is expensive to run over 4 million pairs.
The Suggestions tab combines several methods into a single score and surfaces the per-method details, so you keep the final decision.
Where suggestions come from
Precomputed scores
Syntactic and semantic, for every source concept at once.
Computed by Linkr on the server, from Manage suggestions. Without a backend, a scores file computed elsewhere can be imported. See Precomputing the scores.
AI agent suggestions
A few justified candidates per concept, batch by batch.
Written live into the project by an agent connected to Linkr’s MCP server. Server mode only. See Mapping with an AI agent.
The two complement each other: the agent starts from the precomputed scores, its first source of candidates, and queries the semantic index for the concepts they leave without a target. It never starts a computation itself.
The Suggestions tab in Linkr
| Score | Methods | Vocab | Concept name | Code | Std | |
|---|---|---|---|---|---|---|
92% | 95%88%91% | LOINC | Creatinine [Mass/volume] in Serum or Plasma | 2160-0 | S | |
81% | 83%79%82% | LOINC | Creatinine [Mass/volume] in Blood | 38483-4 | S | |
76% | 80%71%77% | LOINC | Creatinine [Moles/volume] in Serum or Plasma | 14682-9 | S | |
68% | 72%64% | SNOMED | Serum creatinine measurement | 113075003 | S | |
54% | 58%51% | LOINC | Creatinine renal clearance | 2164-2 | S |
Similarity methods
Four method families can feed the candidate ranking. Each attacks the problem from a different angle, and their failure modes don’t overlap — which is why combining them beats any single family.
Syntactic
Compares the label character strings.
Semantic
Compares meaning via biomedical embeddings.
Statistical
Compares the distributions of numerical values.
AI
An LLM re-reads top candidates with the clinical context.
In Linkr, every method is represented next to the combined score by a coloured dot (colours above) followed by its percentage. On hover, a tooltip names the exact algorithm. This helps understand why a score is high: a candidate scoring 92% from the syntactic method alone is likely a textual false friend, while one scoring 80% from semantic + AI is much more solid.
1. Syntactic — compare character strings
We compare label strings as-is, without any understanding of their meaning. Useful because source and OMOP labels often follow different writing conventions: case, spaces or underscores, accents, abbreviations, word order, punctuation. Three algorithms in the catalogue:
- Jaro-Winkler — letter-level proximity with a bonus for shared prefixes. Matches “hemoglobin_a1c” with “Hemoglobin A1c” despite the case and separator differences.
- Token-Sort — splits labels into words, sorts them alphabetically, then compares. Word-order agnostic (“blood pressure systolic” ≈ “systolic blood pressure”).
- N-gram IDF — splits into character n-grams (subsequences of N letters), weights each n-gram by its rarity in the vocabulary. Usagi’s historical method.
hemoglobin_a1c(source label, no accents, no spaces)Hemoglobin A1cA1c hemoglobinHemoglobinGlucoseJaro-Winkler — letter-level proximity, bonus for shared prefix; Token-Sort lets "A1c hemoglobin" match the source despite word-order differences.
Strengths — catches near-literal matches despite writing variants (case, spaces, abbreviations, word order), very fast (milliseconds per pair).
Limits — does not account for synonyms: “creatinine” and “creat” are close, but “heart rate” and “pulse” score zero.
2. Semantic — compare meaning
Each label is encoded as a numerical vector through a sentence-embedding model, then we measure the angle between vectors via cosine similarity. Two labels with close meanings will produce close vectors, even if the words differ.
From label to embedding vector
BioLORD-2023-M projects each label into a 768-dimensional space. Here are 24 dimensions as a heatmap — each cell is one dimension, colour encodes the value.
Heart ratePulseBlood pressureCosine similarity
cos(θ) = (A · B) / (‖A‖ × ‖B‖)Heart ratevsPulseHeart ratevsBlood pressureThe patterns for "Heart rate" and "Pulse" are nearly identical cell by cell → very close vectors. "Blood pressure" has a different pattern → distant vector. The closer the cosine score gets to 1, the closer the meanings.
Default model: BioLORD-2023-M, trained on biomedical text and multilingual (French, English, Spanish, German…).
Configurable alternatives — any Sentence-Transformers compatible BERT model:
- PubMedBERT, SapBERT, ClinicalBERT — biomedical-specialised but English-only.
- all-MiniLM-L6-v2 — general-purpose, English-only, much faster.
- paraphrase-multilingual-MiniLM-L12-v2, LaBSE — general-purpose, multilingual.
Multilingual coverage
If your source labels are in French (or any non-English language), stick with BioLORD-2023-M or switch to an explicitly multilingual model. PubMedBERT, SapBERT, ClinicalBERT and all-MiniLM-L6-v2 will produce poor-quality embeddings on non-English text.
Strengths — catches synonyms (“heart rate” ≈ “pulse”), rephrasings, terminology variants.
Limits — can conflate two close-but-distinct concepts (“serum creatinine” vs “urine creatinine”). Expensive to pre-compute over the ~3.5M standard OMOP concepts: a few hours, once per workspace (GPU recommended).
3. Statistical — compare value distributions
For numerical variables (Measurement only), we compare the statistical distribution of values between source concept and candidates: min, P25, median, P75, max, mean, standard deviation. Two variables taking values in the same range with the same shape are probably the same measurement.
Concretely, we use a statistical test to quantify the gap between the two distributions:
- Kolmogorov-Smirnov test (KS) — maximum gap between cumulative distribution functions. KS = 0 → identical distributions; KS close to 1 → very different distributions.
- Wasserstein distance — “cost” of transporting the mass of one distribution onto the other. More robust than KS when supports are shifted (unit change).
Source concept: serum creatinine (µmol/L)
12,450 measurements, 1,842 patients
LOINC 2160-0 — Creatinine [Mass/volume] in Serum or Plasmaunit: mg/dLLOINC 14682-9 — Creatinine [Moles/volume] in Serum or Plasmaunit: µmol/LLOINC 2951-2 — Sodium [Moles/volume] in Serum or Plasmaunit: mmol/LKolmogorov-Smirnov test: KS close to 0 = identical distributions; KS > 0.5 = very different distributions. Smoothed curves (kernel density estimate) let you compare shape and position without the distributions hiding each other.
Strengths — works even when the label is ambiguous or missing. Very discriminating: hard to confuse creatinine (60–120 µmol/L) with sodium (135–145 mmol/L).
Limits — only applicable to numerical variables with enough values for the distribution to be representative. Sensitive to data-entry artifacts (outliers, mixed units).
Not computed by Linkr yet
Linkr can display and weight statistical scores (statistical/… methods) when an imported scores file contains them, but does not compute them yet. In practice, the AI agent is what compares distributions: it reads each source concept’s distribution in its metadata before choosing a target.
4. Agentic AI — let an LLM reason about it
An LLM driven agentically — it decides which tools to call: reading a source concept and its metadata, searching the OMOP vocabulary, browsing a candidate’s hierarchy — examines the best candidates with all the context available: source label, unit, value distribution, wards where the code is used. It proposes one or more mappings carrying a SKOS equivalence (exactMatch, closeMatch, broadMatch, narrowMatch, relatedMatch) and a comment justifying the choice.
Its proposals show up in the tab as one more method, named ai/<model> after the model that produced them, in the Agentic category. The Mapping with an AI agent page explains how to start it.
TA_systolique_invasiveICCA · M0118 · "Invasive systolic arterial pressure" · 24,380 measurements · median 122 mmHg
SNOMED 251071003 — Invasive systolic arterial pressure91%SNOMED 72313002 — Systolic arterial pressure78%LOINC 8480-6 — Systolic blood pressure74%
The label "TA_systolique_invasive" refers to systolic arterial pressure measured via an arterial catheter (arterial line), not by cuff. SNOMED 251071003 matches this definition exactly — a direct mapping. LOINC 8480-6 is a broader concept (systolic, any method): the target is more general than the source, which is written broadMatch in SKOS. The observed distribution (median 122 mmHg, right tail up to ~180) is consistent with an invasive ICU measurement.
SNOMED 251071003 — Invasive systolic arterial pressureConfidence: 97%skos:exactMatch — The target concept describes precisely the same measurement.LOINC 8480-6 — Systolic blood pressureConfidence: 88%skos:broadMatch — The target is more general (any measurement method), so broader than the invasive source.Strengths — the only method that “understands” clinical semantics (qualifiers, measurement context, nuanced equivalences). Can say “this is not exact, the target is more general” via broadMatch, and says in its comment what differs.
Limits — slow and compute-hungry, risk of hallucinations on rare cases, still requires human validation.
Frugality principle — start with the cheapest method
The methods sit at different resource tiers, roughly grouped as:
- Syntactic and statistical — light CPU, local computations on strings or on values already in memory. Order of magnitude: milliseconds per pair.
- Semantic (BERT / embeddings) — a GPU is recommended for inference and for pre-computing the OMOP vectors. Order of magnitude: minutes to hours depending on hardware, then near-free at query time.
- Agentic AI — calls to the model, several tool round-trips per concept. Order of magnitude: seconds to minutes per concept.
The rule: don’t reach for a higher tier when a lower one suffices.
- Run the syntactic scores first — they are almost free, and already resolve a good share of easy cases.
- The semantic method takes over on unresolved concepts (synonyms, rephrasings, languages).
- The agent works on a chosen scope — a category, the most frequent concepts — and starts from candidates already pre-ranked, never blindly from the 4M OMOP concepts.
It’s at once a question of cost (compute, GPU, and the bill for a remote model), environmental impact and speed: running a 1,000-concept project entirely through the agent takes hours, where the precomputed scores handle the same load in minutes and leave the agent the hard residue.
The combined score
The combined score (left column, green bar) is a weighted average of each method’s score. Default weights are:
| Method | Weight | Role |
|---|---|---|
| Syntactic | ×1 | Catches near-literal matches despite writing variants. |
| Statistical | ×1 | Compares value distributions (creatinine vs sodium). |
| Semantic | ×2 | Picks up synonyms and rephrasings. |
| Agentic AI | ×3 | Justified proposals from an AI agent. |
The Manage suggestions button (top left) opens a dialog with two tabs. The Methods tab has sliders to tune each weight in real time — the table re-sorts automatically; it also shows the number of loaded scores, and lets you Import a file or Delete all. The Compute tab computes the scores — see Precomputing the scores.
In server mode, the Methods in the file section lists every method present — syntactic/jaro-winkler, semantic/biolord, ai/<model>… — each with a bin: Remove the suggestions of a method deletes all its rows from the scores file, keeping the other methods and the mappings. This is how you remove in one go what an agent left.
Manage suggestions
Tune the weight of each method in the combined score.
Method weights
Methods in the file
ai/mistral-small-3.2semantic/biolordsyntactic/jaro-winkler
similarity-scores.parquetSelection and mapping
SNOMED 251071003 — Invasive systolic arterial pressure | 91% | ||
SNOMED 72313002 — Systolic arterial pressure | 78% | ||
LOINC 8480-6 — Systolic blood pressure | 74% |
Candidates already mapped for this source concept are greyed out and not re-selectable.
- Click a row to select it. The action bar at the top then shows the usual mapping buttons (Exact match + SKOS dropdown + comment button).
- Candidates already mapped for this source concept are greyed out and not re-selectable.
- The ⓘ icon at the row end opens the target OMOP concept’s detail (description, synonyms, hierarchy).
The main alignment button “Exact” is pre-filled with the selected suggestion’s SKOS equivalence — the one the agent proposed, for an ai/… row (exactMatch, closeMatch, broadMatch, narrowMatch, relatedMatch). You can accept it in one click, or open the dropdown to pick a different equivalence if you disagree. Linkr never maps on its own from a suggestion: that click is what creates the mapping.
AI agent suggestions
An AI agent can leave its own suggestions in the tab, each with a SKOS equivalence and a comment justifying the choice. The Mapping with an AI agent page explains how to put it to work, what it writes into the project and how to follow its work.
Precomputing the scores
Syntactic and semantic scores give every source concept a ranked list of candidates before any agent looks at it. They are computed in Linkr, on the server: Manage suggestions → Compute tab. The computation runs as a background job; you can close the dialog and keep working.
Server mode only
The computation runs on the Linkr server. In an install without a backend, load a scores file computed elsewhere — see Importing a scores file.
What you need
- The OMOP vocabularies imported in the workspace — see Target concepts. Candidates are taken from their concepts.
- For the syntactic methods: nothing else. They run in the database.
- For the semantic method: an embeddings runtime, a model, and a configuration with a built index. The Models and configurations button of the Compute tab sets it all up.
Models and configurations
The Models and configurations button of the Compute tab opens a dialog with two tabs: Embeddings and models — the embeddings runtime, that is the Python packages that run the models (torch, sentence-transformers, about 2 GB, shared by every workspace of the server), then the models — and Configurations, described below.
Under the list of models, three tiles offer to add one; clicking one opens its form right below:
- BioLORD-2023-M — Proposed by default, the shortest path. Install:
- installs the embeddings runtime if needed;
- downloads BioLORD-2023-M from Hugging Face (about 1 GB, not shipped with Linkr);
- creates a configuration over every standard, valid concept, drugs included.
- Hugging Face — another model of the Hub, named by its owner/name (for instance
cambridgeltl/SapBERT-from-PubMedBERT-fulltext), then Download. Needs the embeddings runtime. - From a folder — the folder of a model downloaded elsewhere, chosen on your computer (it is sent to the server and copied into the workspace) or on the server (read in place). This is how you bring a model into an environment without internet access.
Models and configurations
What the semantic method needs, shared by the projects of this workspace: the runtime, the models, and the configurations with their index.
Embeddings runtime
Models
No model yet.
Installs the embeddings runtime if needed, downloads FremyCompany/BioLORD-2023-M (about 1 GB, not shipped with Linkr) and creates a configuration over every standard concept, drugs included. You then build its index: a few hours for about 3.5 million concepts. A stopped build resumes where it stopped.
InstallYou then build the configuration’s index — the Build button, in the Configurations tab: each target concept is encoded once, and the index then serves every project of the workspace. Count a few hours for about 3.5 million concepts, much less with a GPU (NVIDIA or Apple Silicon). A stopped build resumes where it stopped.
Closing the dialog during an install
Installs, downloads and index builds run on the server. You can close the dialog or switch tabs: when you come back, the progress is where it got to, with its Stop button.
Configurations
A configuration pairs a model with what it encodes. Its scores are written as the semantic/<identifier> method. New creates another one, for instance with another model or over a narrower scope:
| Field | Role |
|---|---|
| Model | One of the models of the Embeddings and models tab — BERT-type (sentence-transformers). |
| Text encoded | What the model reads for each concept: the name alone, or the name with its vocabulary and class, which tells homonyms apart across vocabularies. |
| Standard concepts only, Valid concepts only | Checked by default. |
| Domains, Vocabularies, Concept classes | Empty = all. Classes target drugs at the right level — e.g. Ingredient, Clinical Drug, Branded Drug — without boxes or marketed products. |
| Device | Automatic: the GPU if there is one, the CPU otherwise. |
Models and configurations
What the semantic method needs, shared by the projects of this workspace: the runtime, the models, and the configurations with their index.
Configurations
New- BioLORD-2023-M
semantic/biolordBioLORD-2023-Mstandard · valid · all domains
Index: 38/41 vocabularies, 3,412,905 concepts · 1 out of dateBuild the BioLORD-2023-M index64%StopSNOMED: 248,000/361,284
- BioLORD — drugs
semantic/biolord-drugsBioLORD-2023-Mstandard · valid · Drug
Index: 1/1 vocabularies, 107,753 conceptsRebuild
Edit embedding configuration
Which concepts to encode with which model. Its scores are written as the semantic/<identifier> method.
Name *
Identifier *
Model
Text encoded
Domains
Vocabularies
Concept classes
Device
Batch size
The index is built per vocabulary: each is built, not built, or out of date when the vocabulary was re-imported since — an out-of-date index still answers, Rebuild brings it up to date. Changing a configuration’s model, encoded text or target concepts deletes its index.
Running the computation
In the Compute tab:
Manage suggestions
Tune the weight of each method in the combined score.
Syntactic methods
Semantic method
Models and configurationsTarget concepts
Domains
Vocabularies
Concept classes
Candidates per concept and method
Each method computed replaces its previous scores in this project. The other methods — the AI suggestions in particular — are kept.
- Syntactic methods — Jaro-Winkler, Token-Sort, N-gram IDF. N-gram IDF is slow (about an hour of CPU on the whole vocabulary): narrow the targets.
- Semantic method — one of the configurations with a built index, or none.
- Target concepts — standard, valid, domains, vocabularies, classes. For the semantic method, targets are further limited to what its configuration encoded.
- Candidates per concept and method — how many targets each method keeps for each source concept.
- Only the source concepts these methods have not scored yet — to complete a computation rather than redo it.
Compute starts the job. Each method computed replaces its previous scores in the project; the other methods — an agent’s suggestions in particular — are kept. Pause stops the computation: what is finished is already in the scores, and Resume carries on from the percentage reached. Start over drops the paused computation and starts a new one with the settings shown.
The agent reads the scores, it does not compute them
The concept-mapping skill never starts a computation or an index build: they are jobs of several hours whose scope you choose. It reads the precomputed scores, its first source of candidates, and queries the semantic index for the concepts they leave without a target. So compute them before putting an agent to work.
Importing a scores file
A scores file computed outside Linkr — by another tool, or in an install without a backend — is loaded through Manage suggestions → Methods tab → Import a file (.parquet or .csv). Its rows are added to the project’s scores and replace the existing ones for the same source concept, target and method.
The file holds one score per (source, candidate, method) triple:
similarity-scores.parquet| source_vocabulary_id | source_concept_code | concept_id | method | score | equivalence | comment | created_at |
|---|---|---|---|---|---|---|---|
| ICCA | M0118 | 4353843 | syntactic/jaro-winkler | 0.83 | skos:exactMatch | — | 2026-05-14T09:32:11Z |
| ICCA | M0118 | 4353843 | semantic/biolord | 0.91 | skos:exactMatch | — | 2026-05-14T09:34:02Z |
| ICCA | M0118 | 4353843 | ai/mistral-small-3.2 | 0.97 | skos:exactMatch | Concept dedicated to systolic pressure measured by arterial catheter, like the source; the observed median of 122 mmHg is consistent. | 2026-05-14T09:35:48Z |
| ICCA | M0118 | 3004249 | ai/mistral-small-3.2 | 0.88 | skos:broadMatch | The target is more general: it covers any measurement method and does not keep the invasive nature of the source. | 2026-05-14T09:35:48Z |
Two columns complete the file: concept_set_uid and concept_set_source_repo, filled in when a suggestion was taken from a concept set of a data dictionary.
Going further
- Mapping with an AI agent — putting an agent to work, following and reviewing its suggestions.
- Agents — what an agent can do in Linkr, and how you stay in control.
- MCP server — create your API key and connect LibreChat or OpenCode.
- Evaluation — review and validate mappings, including those created by an agent.