microsoft/lab-column-mapper
Use this skill when a Power Automate flow triggers the agent with a payload describing an unknown source column from a lab results file that broke an Azure Data Factory ingestion pipeline. The skill semantically matches the source column against the canonical clinical schema indexed in Azure AI Search, scoped first by the sending lab and then by clinical domain, and writes a suggested destination-column mapping to the Dataverse review queue for a clinical informatics steward to approve. Also activates on manual invocations like "map this lab column", "the ADF pipeline failed on column X, what should it map to", or "suggest a canonical column for this lab feed field".
npx skills add https://github.com/microsoft/cat-agent-skills --skill lab-column-mapper
Given an unknown column from an incoming lab results file, retrieve the most likely canonical destination column from a health system's clinical warehouse, explain why, and write the suggestion to the review queue.
The skill is invoked with a JSON payload delivered by Power Automate. Every field is required unless marked optional.
| Field | Type | Description |
|---|---|---|
| source_column_name | string | The unrecognized column header from the incoming file (e.g., PT_MRN, spec_collected_dt). |
| source_column_sample_values | array of strings | Up to 5 sample values, de-identified. Never include raw PHI — the caller must hash or redact patient identifiers before invoking. |
| source_lab_id | string | Stable identifier for the sending lab (e.g., LAB-QUEST-001). |
| source_lab_name | string | Human-readable lab name (e.g., Quest Diagnostics). |
| source_file_name | string | Name of the file that failed ingestion. |
| source_domain | string | One of lab-observations, orders, specimens, results. Used to scope the search. |
| pipeline_run_id | string | ADF pipeline run ID for traceability. |
| source_column_description | string, optional | If the sending lab publishes a data dictionary, the human description of the column. Boosts match confidence significantly when present. |
Perform these steps in order. Do not skip to a broader search until the previous scope has been tried.
Query the Azure AI Search index lab-canonical-schema with:
source_column_name + source_column_description (if present) + a synthesized query from the sample values (e.g., if samples look like dates, add "date time timestamp"; if samples look like numeric with units, add "quantity measurement value").source_lab_id eq '{source_lab_id}' or previously_mapped_from_labs/any(l: l eq '{source_lab_id}')column-descriptions semantic configuration.If the top result has a @search.rerankerScore ≥ 2.5, accept it as the primary suggestion and go to Step 3.
If Step 1 returns no result at or above the threshold, re-query with:
clinical_domain eq '{source_domain}'Accept the top result at @search.rerankerScore ≥ 2.2 as the primary suggestion. Capture the next 2 candidates as alternatives.
If no result clears the threshold, produce a no_confident_match outcome (see Step 3) and let the human decide from scratch.
Build a suggestion record with this schema:
{
"suggestion_id": "<new GUID>",
"pipeline_run_id": "<from payload>",
"source_column_name": "<from payload>",
"source_lab_id": "<from payload>",
"source_lab_name": "<from payload>",
"source_file_name": "<from payload>",
"suggested_destination_column": "<canonical column name, or null if no_confident_match>",
"suggested_destination_loinc": "<LOINC code if the canonical column has one, else null>",
"confidence": "high | medium | low | no_confident_match",
"confidence_score": <0.0 to 1.0, derived from the rerankerScore normalized>,
"reasoning": "<one to two sentences citing WHICH signals drove the match — description match, sample-value shape, prior mapping history for this lab>",
"alternatives": [
{ "destination_column": "<name>", "confidence_score": <0.0 to 1.0> },
{ "destination_column": "<name>", "confidence_score": <0.0 to 1.0> }
],
"status": "pending_review",
"created_at": "<ISO-8601 UTC>"
}
Confidence bands from @search.rerankerScore:
>= 3.0 → high, confidence_score = min(1.0, rerankerScore / 4.0)2.5 – 2.99 → medium2.2 – 2.49 → low< 2.2 → no_confident_match, suggested_destination_column = nullCall the lab_column_mapping_suggestions table's Create action via the Dataverse connector with the suggestion record. Return the new record ID to the caller so Power Automate can notify the clinical informatics steward.
Return this JSON to Power Automate:
{
"suggestion_id": "<the ID>",
"review_url": "<Power App URL for the steward, if configured; else null>",
"summary": "<one-line human-readable summary — 'PT_MRN → patient_mrn (high confidence)' or 'No confident match found for PT_MRN — manual review required'>"
}
no_confident_match and let a human decide.data_type field on the index result before finalizing the suggestion.reasoning field. Describe the *shape* of the values ("looks like an ISO date"), not the values themselves.{ "error": "missing_field", "field": "<name>" } and do not query the index.status = "search_unavailable" and surface it for human review.README.md in this skill package.Take microsoft/lab-column-mapper from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.