This prompt is designed for CDP and CRM engineering teams who need to deduplicate contact records that arrive from upstream model outputs, extraction pipelines, or multi-source ingestion. It handles pairwise comparison of contact records, assigns match confidence scores, applies survivorship rules to resolve conflicting field values, and produces a single deduplicated record with provenance tracking. Use this when you have two or more contact records that may represent the same person and you need a programmatic, auditable merge decision.
Prompt
Contact Record Deduplication Prompt Template

When to Use This Prompt
Defines the job-to-be-done, ideal user, required context, and boundaries for the Contact Record Deduplication prompt.
This prompt belongs in a post-extraction repair loop, not in initial record creation. It assumes contact records have already been normalized for email, phone, name, and address formatting. Pair this with the Email Address Normalization and Phone Number Canonicalization prompts earlier in your pipeline for best results. The prompt expects structured JSON input containing the candidate records to compare, along with your configured survivorship rules and match thresholds. It is not designed for bulk deduplication across millions of records—use it for pairwise or small-cluster resolution within a larger deduplication pipeline.
Do not use this prompt when you need real-time matching against a master database (use a vector search or deterministic matching service instead), when records lack any common identifiers to compare, or when legal or compliance requirements demand a human review every merge decision. For high-stakes merges in regulated domains, route low-confidence matches to a human review queue rather than relying solely on the model's survivorship decisions. The prompt's value is in making merge logic explicit, auditable, and consistent—not in replacing your MDM system.
Use Case Fit
Where the Contact Record Deduplication prompt template delivers value and where it introduces unacceptable risk. Use these cards to decide if this prompt fits your pipeline before investing in integration.
High-Volume CRM Ingestion Pipelines
Use when: you have a nightly batch of model-extracted contacts from call transcripts, emails, or web forms that must be merged into Salesforce or HubSpot. Avoid when: your contact volume is under 100 records per run—manual review is cheaper and safer. Guardrail: always run a pre-flight validation on the deduplicated output before allowing CRM API writes.
Multi-Source Identity Resolution
Use when: you are merging contact records from three or more upstream model pipelines with conflicting field values. Avoid when: you have a single authoritative source of truth—deduplication adds latency without benefit. Guardrail: require explicit source precedence rules in [SURVIVORSHIP_RULES] and log every merge decision for audit.
Required Inputs Not Present
Risk: running deduplication without unique identifiers (email, phone, external ID) forces the model to rely on fuzzy name matching, producing high false-positive merge rates. Guardrail: abort the prompt and route to a human review queue if [RECORDS] lack at least one strong identifier per record. Never deduplicate on name alone.
Regulatory or Compliance Contexts
Risk: automated merging can combine records across jurisdictions, violating GDPR data minimization or CCPA opt-out boundaries. Guardrail: inject [COMPLIANCE_CONSTRAINTS] into the prompt with jurisdiction rules, and require human approval for any merge that spans different consent regimes or data residency requirements.
Real-Time or Latency-Sensitive Flows
Risk: pairwise comparison of large contact sets is computationally expensive and can exceed model context windows or timeouts. Guardrail: use this prompt only in batch or async workflows. For real-time deduplication, pre-compute embedding clusters and use the prompt only for edge-case resolution on small candidate sets.
Low-Confidence Merge Thresholds
Risk: the model may return merges with confidence scores below your business threshold, leading to incorrect record consolidation. Guardrail: define [MIN_CONFIDENCE] in the prompt, route sub-threshold pairs to a human review queue, and never auto-merge below 0.85 confidence without additional verification signals.
Copy-Ready Prompt Template
A production-ready system prompt for deduplicating contact records with match confidence, survivorship rules, and merge conflict resolution.
This prompt template is designed to be pasted directly into your system instructions for an LLM tasked with merging duplicate contact records. It expects a pair of contact records and a set of business rules, and it returns a single deduplicated record with a detailed merge audit trail. The template uses square-bracket placeholders that you must replace with your specific data, schemas, and policies before use.
textYou are a contact record deduplication engine for a Customer Data Platform (CDP). Your task is to compare two contact records and produce a single, deduplicated golden record. ## INPUT You will receive two contact records in [INPUT_FORMAT, e.g., JSON] format. Record A: [RECORD_A] Record B: [RECORD_B] ## OUTPUT_SCHEMA Return a single JSON object with the following structure: { "golden_record": { // The merged contact object conforming to [TARGET_SCHEMA] }, "match_decision": { "is_match": boolean, "confidence_score": number (0.0 to 1.0), "match_reasoning": "string explaining the evidence for the match decision" }, "merge_audit": [ { "field_name": "string", "selected_source": "A" | "B" | "MERGED" | "CONFLICT", "value_a": "original value from Record A", "value_b": "original value from Record B", "resolved_value": "final value in golden_record", "resolution_rule": "string referencing the specific survivorship rule applied" } ] } ## SURVIVORSHIP_RULES Apply the following rules in order of precedence to resolve conflicts: [SURVIVORSHIP_RULES, e.g., 1. Prefer the most recently updated record's value. 2. Prefer the longer, more complete value. 3. Prefer the value from the record with a verified email or phone. 4. If still in conflict, flag for human review.] ## MATCHING_RULES Two records are considered a match if they satisfy [MATCHING_CRITERIA, e.g., - Email addresses match exactly after normalization. - OR, first name, last name, and phone number all match after normalization. - Fuzzy name matching is allowed only if another strong identifier matches.] ## CONSTRAINTS - Do not invent any contact data. Only use values present in Record A or Record B. - If a field is missing in both records, set its value to null in the golden_record. - For any field where the resolution rule results in a CONFLICT, set the resolved_value to null and flag it for human review. - If the confidence_score is below [CONFIDENCE_THRESHOLD, e.g., 0.85], set is_match to false and do not produce a merged record. Instead, return both records unchanged in a "review_queue" array. - Normalize all email addresses and phone numbers according to [NORMALIZATION_RULES] before comparison.
To adapt this template, start by replacing the [TARGET_SCHEMA] placeholder with the exact field definitions your downstream system expects. Then, codify your business's survivorship rules in [SURVIVORSHIP_RULES]—this is the most critical customization, as it encodes your data governance policy directly into the model's behavior. Finally, calibrate [CONFIDENCE_THRESHOLD] using a labeled evaluation set to balance merge throughput against the cost of false merges. For high-risk domains like healthcare or finance, set a high threshold and route all CONFLICT flags to a human review queue rather than attempting automatic resolution.
Prompt Variables
Inputs the prompt needs to work reliably. Validate these before sending to the model. Missing or malformed variables are the most common cause of silent failures in deduplication prompts.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[CONTACT_RECORDS] | Array of contact objects to compare for deduplication | [{"id":"c1","name":"John Smith","email":"jsmith@example.com","phone":"+15551234567"},{"id":"c2","name":"J. Smith","email":"john.smith@example.com","phone":"555-123-4567"}] | Must be a valid JSON array with at least 2 objects. Each object requires an id field. Reject if array length < 2 or if any record lacks an id. |
[MATCH_FIELDS] | Ordered list of fields to use for pairwise comparison with priority weighting | ["email","phone","name","company","address"] | Must be a non-empty JSON array of strings. Each string must match a field present in [CONTACT_RECORDS]. Validate field existence before prompt assembly. Order determines comparison priority. |
[MATCH_THRESHOLD] | Minimum confidence score for declaring a match | 0.85 | Must be a float between 0.0 and 1.0. Reject values outside range. Default to 0.80 if not provided. Lower thresholds increase false positives; higher thresholds increase false negatives. |
[SURVIVORSHIP_RULES] | Rules dictating which field value wins when merged records conflict | {"email":"most_recent","phone":"longest","name":"most_complete","company":"source_priority"} | Must be a valid JSON object. Each key must match a field in [MATCH_FIELDS]. Allowed values: most_recent, longest, most_complete, source_priority, manual_review. Reject unknown rule values. |
[SOURCE_PRIORITY] | Ordered list of source identifiers for breaking ties in survivorship | ["salesforce","hubspot","manual_entry","csv_import"] | Must be a JSON array of strings if [SURVIVORSHIP_RULES] references source_priority. Validate that all source values in [CONTACT_RECORDS] appear in this list. Null allowed if no rule uses source_priority. |
[OUTPUT_SCHEMA] | Expected JSON schema for the deduplicated output | {"type":"object","properties":{"merged_records":{"type":"array"},"discarded_ids":{"type":"array"},"match_pairs":{"type":"array"},"confidence_scores":{"type":"object"}},"required":["merged_records","match_pairs","confidence_scores"]} | Must be a valid JSON Schema object. Validate with a JSON Schema parser before prompt assembly. Required fields must include merged_records, match_pairs, and confidence_scores at minimum. |
[MAX_RECORDS] | Upper bound on input records to prevent token overflow and cost spikes | 500 | Must be a positive integer. Truncate or reject [CONTACT_RECORDS] if count exceeds this value. Log a warning if truncation occurs. Typical safe range: 50-1000 depending on field count and model context window. |
Implementation Harness Notes
How to wire the Contact Record Deduplication Prompt into a production application with validation, retries, logging, and human review gates.
This prompt is designed to operate as a stateless function within a larger deduplication pipeline. It expects a pre-clustered pair of contact records as input, meaning your application must handle the initial blocking and candidate pair generation before invoking the model. The prompt should be called once per candidate pair, with results aggregated and resolved downstream. Do not use this prompt for list-wise deduplication of more than two records at a time; the pairwise comparison logic degrades when given more than two records, and the model will often hallucinate a consensus record rather than performing true pairwise analysis.
The implementation harness must enforce strict input validation before calling the model. Verify that both [RECORD_A] and [RECORD_B] contain the required fields specified in the prompt template, and reject any pair where mandatory identifiers are missing. After receiving the model output, validate the JSON structure against the expected schema: match_confidence must be a float between 0.0 and 1.0, is_match must be a boolean, merged_record must be present when is_match is true, and conflict_resolutions must be an array of objects with field, resolution, and reasoning keys. If validation fails, implement a retry loop with a maximum of two additional attempts, appending the validation error message to the prompt context. After two failed retries, route the pair to a human review queue rather than silently accepting a malformed output. Log every validation failure, retry attempt, and escalation event with the original input pair and the model's raw response for debugging.
Model choice matters for this workflow. Use a model with strong JSON output capabilities and a context window large enough to hold both records plus the prompt instructions. For high-volume pipelines, consider batching pairwise comparisons and using asynchronous calls with a concurrency limit to avoid rate limiting. Implement a confidence threshold in your application logic: pairs with match_confidence above 0.85 can be auto-merged, pairs between 0.5 and 0.85 should be flagged for human review, and pairs below 0.5 should be treated as non-matches. This threshold should be calibrated against your own labeled dataset, not assumed from generic benchmarks. Store the model's reasoning field alongside every decision to enable post-hoc audit and threshold tuning. Never auto-merge records in regulated domains (healthcare, finance) without a human-in-the-loop step, regardless of confidence score.
Expected Output Contract
Defines the exact structure, types, and validation rules for the deduplicated contact record output. Use this contract to build a parser, validator, or retry loop that rejects any model response not conforming to these rules.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
deduplicated_record | object | Top-level object must contain exactly the fields listed in this contract. Reject if extra top-level keys are present. | |
deduplicated_record.contact_id | string | Must match regex ^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}$ representing the surviving canonical ID. Reject if format deviates. | |
deduplicated_record.primary_email | string or null | If not null, must pass RFC 5322 email regex and domain MX record check. Null allowed only if no email exists across merged records. | |
deduplicated_record.primary_phone | string or null | If not null, must be E.164 format (e.g., +12125551234). Null allowed only if no phone exists across merged records. | |
deduplicated_record.full_name | string | Must be non-empty string with length between 1 and 200 characters. Leading/trailing whitespace must be stripped. Reject if empty or whitespace-only. | |
merge_metadata | object | Must contain exactly 'source_record_ids', 'survivorship_rules_applied', and 'conflict_resolutions' sub-objects. Reject if any sub-object is missing or extra keys present. | |
merge_metadata.source_record_ids | array of strings | Must contain at least 2 unique IDs. Each ID must match the same format as contact_id. Reject if array length < 2 or contains duplicates. | |
merge_metadata.conflict_resolutions | object | Keys must be field names that had conflicts (e.g., 'email', 'phone'). Values must be objects with 'winning_source_id' (string) and 'resolution_strategy' (enum: 'most_recent', 'most_complete', 'source_priority', 'manual'). Reject if strategy is not in enum. |
Common Failure Modes
What breaks first when deduplicating contact records from model outputs and how to guard against it.
Over-Merging Distinct Contacts
What to watch: The prompt merges records that share a common name or email prefix but belong to different people (e.g., John Smith at two different companies). This is the highest-risk failure mode in production deduplication. Guardrail: Require at least two independent strong-match fields (email + phone, or email + company domain) before merging. Add a human review queue for single-field matches below a confidence threshold.
Under-Merging Obvious Duplicates
What to watch: The prompt fails to merge records that are clearly the same person due to minor formatting differences, nickname variations, or whitespace-only email mismatches. This silently inflates contact counts and fragments engagement history. Guardrail: Pre-normalize all identifier fields (email, phone, name) before pairwise comparison. Run a canonicalization pass first, then deduplicate on normalized values rather than raw strings.
Survivorship Field Selection Errors
What to watch: The prompt picks the wrong value when two duplicate records disagree on a field—choosing an outdated email, a misspelled name, or a less complete address over the correct one. Guardrail: Define explicit survivorship rules per field (e.g., prefer most recent timestamp, prefer longest value, prefer source with highest trust score). Include these rules in the prompt template and validate field-level choices against them.
Confidence Score Inflation
What to watch: The model assigns high confidence to matches based on weak signals (same city, same first name) without verifying strong identifiers. This creates a false sense of reliability that propagates downstream. Guardrail: Calibrate confidence thresholds against a labeled ground-truth dataset. Require the prompt to output explicit match reasoning per pair, not just a score. Flag any high-confidence match that lacks at least one strong identifier match for review.
Batch Boundary Blindness
What to watch: When processing contacts in batches, the prompt misses duplicates that span batch boundaries because it only compares records within a single batch. This creates systematic under-merging at scale. Guardrail: Design the deduplication pipeline to maintain a running canonical record index across batches. Use deterministic blocking keys (normalized email domain, phone area code + last name) to ensure cross-batch candidates are compared, not just intra-batch pairs.
Hallucinated Merge Justifications
What to watch: The model fabricates plausible-sounding reasons for merging records when the evidence is actually thin or contradictory. The output looks reasonable but the merge decision is unsupported. Guardrail: Require the prompt to cite specific field values from both records as evidence for each merge decision. Add a post-merge validation step that checks whether cited values actually exist in the source records. Escalate merges with unsupported justifications to human review.
Evaluation Rubric
Run these checks against a golden dataset of known duplicate and non-duplicate pairs. Each criterion targets a specific failure mode observed in production deduplication pipelines. Use the results to calibrate match thresholds and decide when to escalate to human review.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Exact Match Recall | All records with identical [INPUT_FIELDS] are flagged as duplicates with confidence >= 0.95 | Confidence below 0.95 on exact duplicates or duplicate pair missed entirely | Run against 50+ exact duplicate pairs with varying whitespace and casing |
Near-Match Precision | No false positives on pairs differing only by one typo in a low-weight field like [STREET_SUFFIX] | Non-duplicate pair scored above [MATCH_THRESHOLD] due to single-field similarity | Test 30+ near-match non-duplicate pairs with controlled single-field variations |
Transposed Field Detection | Records with first_name and last_name swapped are identified as duplicates with confidence >= 0.85 | Transposed-name pair scored below [MATCH_THRESHOLD] or flagged as non-duplicate | Run 20+ pairs where given_name and family_name are swapped between records |
Nickname Variant Handling | Common nickname pairs like 'Bill' and 'William' contribute to match score without dominating | Nickname mismatch alone pushes confidence below [MATCH_THRESHOLD] when all other fields match | Test 15+ pairs with known nickname variants and identical remaining fields |
Cross-Field Contamination | Phone number similarity does not inflate match score when names and addresses clearly differ | Two unrelated records with same corporate phone number scored above [MATCH_THRESHOLD] | Run 25+ pairs sharing one high-weight field but differing on all others |
Null Field Handling | Missing [EMAIL] or [PHONE] fields do not cause false negatives when other fields match strongly | Pair with one record missing email scored below [MATCH_THRESHOLD] despite matching name and address | Test 20+ pairs where one record has null values in 1-2 fields |
Threshold Boundary Stability | Confidence scores within 0.05 of [MATCH_THRESHOLD] produce consistent decisions across repeated runs | Same pair flips between duplicate and non-duplicate across 3 runs with identical inputs | Run 10 borderline pairs 3 times each and check decision consistency |
Survivorship Rule Correctness | Golden record selects non-null field value from the more complete record for each [OUTPUT_FIELD] | Null or less-complete field value chosen over populated value from the other record | Verify field-level provenance on 30 merged records against expected survivorship rules |
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Adapt This Prompt
How to adapt
Start with the base pairwise comparison prompt. Use a single model call per record pair with relaxed output validation. Accept JSON or markdown table output and parse loosely. Skip confidence threshold enforcement—just collect scores and review manually.
Prompt modification
Remove strict [OUTPUT_SCHEMA] constraints. Replace with: Return your analysis as a JSON object with keys: match, confidence, reasoning, merged_record. If you cannot determine a field, use null.
Watch for
- Inconsistent field names across runs
- Missing
merged_recordwhen match is true - Overly verbose reasoning bloating token usage
- No survivorship rules applied

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us