This prompt is designed for triage engineers, QA leads, and automated support pipelines that need to determine whether an incoming bug report describes an issue already tracked in the database. The core job is to compare a new, often unstructured report against a set of existing tickets and produce a ranked list of candidate duplicates with clear similarity reasoning. The ideal user is someone building or operating a bug triage system where duplicate noise wastes engineering time and inflates backlog metrics. Required context includes the full text of the incoming report and a search result set of candidate existing tickets, each with at least a title, description, and component tag. Without this context, the prompt cannot perform meaningful comparison.
Prompt
Duplicate Detection Prompt for Bug Databases

When to Use This Prompt
Define the job, the reader, and the operational constraints for a duplicate detection prompt in bug triage workflows.
This prompt should not be used as the sole decision-maker for merging tickets. It is a recommendation engine, not an auto-merge system. Do not use it when the candidate ticket set is empty, when the incoming report is a feature request rather than a defect, or when the cost of a false merge is catastrophic—such as in safety-critical or financially regulated systems where duplicate misclassification could hide a distinct high-severity issue. The prompt also fails when existing tickets lack sufficient detail; if your database is full of one-line titles with no reproduction steps, similarity scoring will be unreliable. In those cases, invest in upstream report quality before deploying this prompt.
Before implementing, define your operational thresholds. You need a minimum similarity score for flagging a candidate, a maximum number of candidates to return, and a clear policy on what happens when the top candidate scores above a configurable auto-merge threshold versus when it falls into an ambiguous review bucket. The prompt output should always route to a human reviewer when confidence is moderate, not just when it is low. Next, wire the prompt into a harness that measures recall against a golden set of known duplicates and precision against a set of distinct reports that should never be merged. If your precision drops below 90% or your recall below 85%, pause and tune the prompt, the candidate retrieval step, or the similarity threshold before scaling to production.
Use Case Fit
Where the Duplicate Detection Prompt delivers value and where it introduces risk. Use these cards to decide if this prompt fits your triage pipeline before integrating it.
High-Volume Ingest with Known Backlog
Use when: your team receives 50+ bug reports per day against a database of 10,000+ existing tickets. Avoid when: the ticket corpus is tiny (<100 tickets) or entirely unstructured; keyword search is cheaper and more predictable. Guardrail: benchmark recall@5 against a labeled duplicate set before cutting over.
Unstructured Freeform Reports
Use when: incoming bugs arrive as freeform text, emails, or chat transcripts with inconsistent terminology. Avoid when: reporters reliably select from a controlled component/symptom taxonomy that makes exact-match deduplication trivial. Guardrail: run the prompt only after the Bug Report Ingestion and Structuring step produces a normalized title and description.
Required Inputs Not Yet Available
Risk: running duplicate detection on raw user text without a structured summary causes the model to match on irrelevant conversational filler. Guardrail: require a structured [INCOMING_BUG] object with title, description, and component fields as input. Gate execution behind schema validation; if ingestion hasn't run yet, route to the ingestion prompt first.
Operational Risk of False Merges
Risk: a high-similarity false positive causes two distinct bugs to be merged, silently burying a separate issue. Guardrail: never auto-merge. Output a ranked candidate list with similarity reasoning and require human confirmation or a secondary verification prompt before linking tickets. Log every merge decision for audit.
Domain Shift and Terminology Drift
Risk: the prompt works well on backend crash reports but fails on frontend UI bugs because the similarity model overweights stack traces and underweights visual descriptions. Guardrail: segment your ticket corpus by component or channel and evaluate recall and precision per segment. Maintain separate similarity thresholds for structurally different bug types.
Latency Sensitivity in Real-Time Triage
Risk: embedding-based retrieval plus LLM re-ranking adds 2-5 seconds to triage latency, which may violate SLAs for chat or phone-originated reports. Guardrail: implement as an asynchronous step after ticket creation. If real-time duplicate detection is required, use a fast embedding retrieval step and only invoke the LLM re-ranker for the top 5 candidates.
Copy-Ready Prompt Template
A reusable prompt for comparing an incoming bug report against a set of existing tickets to identify likely duplicates with ranked similarity reasoning.
This template is designed to be dropped into a triage pipeline where an unstructured or semi-structured bug report must be checked against an existing database of open and recently closed tickets. The prompt instructs the model to act as a strict duplicate detector, not a general classifier. It requires the incoming report and a formatted list of candidate tickets as inputs, and it produces a ranked list of potential duplicates with explicit similarity reasoning. The square-bracket placeholders allow you to inject your own ticket schema, severity taxonomy, and risk tolerance without rewriting the core instruction.
codeYou are a bug triage specialist. Your task is to compare the incoming bug report against a list of existing tickets and identify likely duplicates. A duplicate is a ticket that describes the same underlying defect, even if the wording, reproduction steps, or environment details differ. ## INPUT ### Incoming Bug Report [INCOMING_REPORT] ### Existing Tickets [EXISTING_TICKETS] ## OUTPUT SCHEMA Return a JSON object with the following structure: { "duplicates": [ { "ticket_id": "string", "similarity_score": 0.0-1.0, "reasoning": "string explaining what matches and what differs", "matched_fields": ["title", "description", "stack_trace", "component", "environment"], "key_differences": ["string describing notable differences"] } ], "no_duplicate_found": false, "confidence_note": "string summarizing overall confidence in the results" } ## CONSTRAINTS - Only flag a ticket as a duplicate if the underlying defect is the same, not just the same component or symptom category. - If no ticket meets the threshold, set no_duplicate_found to true and return an empty duplicates array. - similarity_score must reflect semantic overlap of the defect, not surface-level keyword matching. Use 0.85 or higher for near-certain duplicates, 0.70-0.84 for likely duplicates, and below 0.70 for possible but uncertain matches. - Do not fabricate ticket IDs. Only reference IDs present in the existing tickets list. - If the incoming report is too vague to compare, set confidence_note to "LOW" and explain what information is missing. ## EXAMPLES [FEW_SHOT_EXAMPLES] ## RISK LEVEL [RISK_LEVEL]
To adapt this template, start by defining your [INCOMING_REPORT] format. If your intake system already produces structured JSON, pass that directly. If reports arrive as freeform text, preprocess them with a structuring prompt first. For [EXISTING_TICKETS], provide a JSON array of ticket objects with at minimum id, title, description, and component fields. The [FEW_SHOT_EXAMPLES] placeholder should be replaced with 2-3 annotated examples showing correct duplicate and non-duplicate calls, especially edge cases where symptoms overlap but root causes differ. The [RISK_LEVEL] placeholder controls the model's caution: set to "HIGH" to require stronger evidence before merging tickets, or "STANDARD" for routine triage. Before deploying, run this prompt against a golden dataset of known duplicate pairs and non-duplicate pairs to calibrate your similarity threshold. If your use case involves regulated software or safety-critical systems, route all proposed merges to a human reviewer and log the full prompt-response pair for audit.
Prompt Variables
Required inputs for the duplicate detection prompt. Each placeholder must be populated before the prompt is assembled and sent. Missing or malformed inputs are the most common cause of false negatives and low-precision matches.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[INCOMING_BUG] | The new bug report to check for duplicates. Must include title, description, and any available structured fields. | {"title": "Checkout crash on iOS", "description": "App crashes when tapping 'Place Order' on iPhone 15, iOS 17.4. Cart has 3 items.", "component": "checkout"} | Validate JSON parse. Require non-empty title and description fields. Reject if only whitespace or placeholder text. |
[EXISTING_TICKETS] | Array of candidate tickets from the bug database to compare against. Pre-filtered by component or keyword search to keep context window manageable. | [{"id": "BUG-421", "title": "iOS checkout crash with multiple items", "description": "...", "status": "open"}, {"id": "BUG-398", "title": "Payment screen freeze", "description": "...", "status": "in_progress"}] | Validate JSON array. Require id and title per ticket. Warn if array exceeds 50 items or 40K characters. Empty array is valid but will produce no matches. |
[COMPONENT_CATALOG] | List of valid component labels in the bug tracking system. Used to normalize and match component fields. | ["checkout", "cart", "payments", "account", "search", "notifications"] | Validate non-empty array of unique strings. Mismatch between catalog and ticket component fields produces a warning but does not block execution. |
[SIMILARITY_THRESHOLD] | Minimum similarity score (0.0 to 1.0) required to include a candidate in the ranked output. Lower values increase recall; higher values increase precision. | 0.65 | Validate float between 0.0 and 1.0. Default to 0.6 if null or out of range. Values below 0.4 produce noisy results; values above 0.9 risk missing true duplicates. |
[MAX_CANDIDATES] | Maximum number of duplicate candidates to return in the ranked list. Controls output size for downstream routing or human review. | 5 | Validate positive integer. Default to 5 if null. Cap at 10 to prevent oversized responses. Value of 1 returns only the top match if above threshold. |
[OUTPUT_SCHEMA] | Expected JSON structure for the response. Defines fields, types, and required elements for the duplicate detection output. | {"type": "object", "properties": {"candidates": {"type": "array", "items": {"type": "object", "properties": {"ticket_id": {"type": "string"}, "score": {"type": "number"}, "reasoning": {"type": "string"}}}}}, "required": ["candidates"]} | Validate valid JSON Schema. Reject if schema is missing required fields or uses unsupported types. Schema mismatch with actual output triggers repair retry. |
[STATUS_FILTER] | Optional filter to include or exclude tickets by status. Controls whether closed or resolved tickets are considered as duplicates. | "open,in_progress" | Validate comma-separated list of valid status values. Null or empty string means no status filter. Invalid status values produce a warning and are ignored rather than blocking. |
Implementation Harness Notes
How to wire the duplicate detection prompt into a bug triage pipeline with validation, recall measurement, and safe merge controls.
The duplicate detection prompt operates as a comparison and ranking step inside a larger triage pipeline. When a new bug report arrives, the harness retrieves a candidate set of open and recently closed tickets from the bug database—typically via keyword search, embedding similarity, or component-based filtering—and passes each candidate pair (incoming report + existing ticket) through the prompt. The prompt returns a similarity score, reasoning, and a recommended action. The harness then aggregates results, ranks candidates by score, and presents the top matches to a human reviewer or an automated merge rule. Do not use this prompt in isolation without a retrieval step; sending every open ticket to the model is cost-prohibitive and introduces noise that degrades ranking quality.
Retrieval and batching: Before calling the prompt, run a lightweight retrieval step to narrow the candidate pool. Use a hybrid approach: keyword match on title and error signature fields, plus vector similarity on the description embedding. Limit the candidate set to 10–20 tickets. For each candidate, construct a prompt call with [INCOMING_BUG] set to the structured fields of the new report and [EXISTING_TICKET] set to the candidate's title, description, and component. Run these calls in parallel if your model provider supports it, or batch them sequentially with a concurrency cap. Validation: After each response, validate that the output contains a numeric similarity_score between 0.0 and 1.0, a non-empty reasoning string, and a recommendation that matches one of the allowed enum values (merge, link, keep_separate). Reject and retry any response that fails schema validation. Log all raw responses and validation failures for offline recall analysis.
Merge safety and human review: Never auto-merge tickets based solely on the model's recommendation. For scores above a configurable threshold (start at 0.85), surface the candidate pair to a triage engineer with the model's reasoning and a one-click merge action. For scores between 0.65 and 0.85, present the match as a suggested link with a note to review. Below 0.65, suppress the match from the UI but log it for recall measurement. Evaluation harness: Maintain a labeled dataset of known duplicate pairs and known distinct pairs from your bug database history. After each prompt version change, run the prompt against this golden set and measure recall@k (did the true duplicate appear in the top k results?) and precision (what fraction of high-scoring matches were true duplicates?). Track these metrics over time and set a minimum recall threshold (e.g., 0.90) before promoting a new prompt version. Model choice: Use a model with strong comparison reasoning—GPT-4o or Claude 3.5 Sonnet work well. Avoid smaller models for this task; they tend to over-anchor on keyword overlap and miss semantic duplicates where the phrasing differs substantially.
What to avoid: Do not include closed tickets older than 90 days in the candidate set unless the incoming report explicitly references a regression of a previously fixed issue. Stale candidates increase false positives and waste review time. Do not use the prompt to compare more than two tickets at once; pairwise comparison produces more reliable similarity scores than multi-way ranking. Finally, do not skip the retrieval step—sending every open ticket to the model will blow your token budget and latency budget while producing worse results than a focused candidate set.
Expected Output Contract
Define the exact shape of the structured output for the duplicate detection prompt. This contract is used to validate the model's response before merging or linking tickets.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
candidates | array of objects | Must be a non-empty array if duplicates are found; empty array if no candidates exceed the threshold. | |
candidates[].ticket_id | string | Must match the exact ID format used in the existing bug database (e.g., PROJ-1234). Regex validation required. | |
candidates[].similarity_score | number | Must be a float between 0.0 and 1.0. Scores below [SIMILARITY_THRESHOLD] should not be included in the array. | |
candidates[].reasoning | string | Must be a non-empty string explaining the overlap in symptoms, root cause, or affected component. Cannot be a generic statement like 'similar issue'. | |
candidates[].matched_elements | array of strings | Must list specific fields that matched (e.g., 'stack_trace', 'error_message', 'repro_steps'). Values must correspond to keys in the input schema. | |
candidates[].recommended_action | enum | Must be one of: 'link_as_related', 'merge_into_existing', 'keep_separate'. 'merge_into_existing' requires a similarity_score >= [MERGE_THRESHOLD]. | |
query_quality_assessment | object | If present, must contain a 'completeness' score (0.0-1.0) and a 'missing_info' array of strings. Used to flag insufficient input data for reliable matching. |
Common Failure Modes
Duplicate detection prompts fail in predictable ways that can silently merge unrelated bugs or miss true duplicates. These cards cover the most common failure patterns and the guardrails that catch them before they affect triage decisions.
False Merges from Surface-Level Similarity
What to watch: The prompt merges bugs that share keywords but describe different root causes—e.g., two 'login failure' reports where one is an auth timeout and the other is a redirect loop. The model latches onto the shared symptom phrase and ignores the underlying mechanism. Guardrail: Require the prompt to output a similarity reasoning block that distinguishes symptom from root cause. Add a validation step that flags merges where the reasoning block contains only symptom overlap without mechanism alignment.
Missed Duplicates from Paraphrased Descriptions
What to watch: Two reports describe the same bug using completely different vocabulary—one says 'app freezes on checkout' and another says 'payment page becomes unresponsive.' The model fails to recognize semantic equivalence and returns no match. Guardrail: Include few-shot examples that demonstrate matching across paraphrased descriptions. Evaluate recall against a golden set of known duplicate pairs with varied phrasing. If recall drops below threshold, add embedding-based pre-filtering before the LLM comparison step.
Ranking Collapse When Too Many Candidates
What to watch: When the existing bug database returns dozens of plausible candidates, the model produces a flat ranking where the top-5 scores are nearly identical, making the duplicate decision arbitrary. Guardrail: Cap the candidate list passed to the prompt at a manageable size (e.g., top-10 from embedding similarity). Require the prompt to output calibrated confidence scores with explicit score differentiation. Add a post-processing check that flags result sets where the top two scores differ by less than a configurable margin.
Environment and Version Blindness
What to watch: The model declares a duplicate match based on matching symptoms but ignores that the incoming bug reports a different app version, OS, or deployment environment. A bug fixed in v2.1 gets incorrectly linked to a v1.8 report. Guardrail: Include environment fields (version, OS, browser, deployment region) as required comparison dimensions in the prompt template. Add a validation rule that blocks duplicate assignment when environment fields conflict and the fix status of the candidate is 'resolved' or 'closed.'
Temporal Context Drift
What to watch: The model matches an incoming bug to an older ticket that was already fixed and closed, failing to account for the possibility of a regression rather than a true duplicate. The triage system silently closes the new report as a duplicate of a resolved issue. Guardrail: Add a temporal constraint to the prompt that treats closed or resolved tickets as regression candidates, not duplicates. Require the output to include a match_type field with values duplicate, regression, or related. Route regression matches to a separate escalation path.
Overfitting to Ticket Titles
What to watch: The prompt weights the bug title too heavily and ignores the description body, reproduction steps, or attached logs. A misleading or vague title causes a false match or a miss. Guardrail: Structure the prompt to compare across multiple fields independently—title, description, steps to reproduce, and error messages—and require the reasoning block to cite evidence from at least two fields before declaring a duplicate. Add an eval check that measures duplicate detection accuracy when titles are deliberately uninformative.
Evaluation Rubric
Use this rubric to test the duplicate detection prompt before shipping. Each criterion targets a specific failure mode observed in production triage systems. Run these checks against a golden dataset of known duplicate pairs and non-duplicates.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Recall@K | At least one true duplicate appears in the top K=5 candidates for 90% of test cases | Known duplicate pair ranks below position 5 or is absent from candidate list | Run against a labeled dataset of 100+ known duplicate pairs; measure recall at K=5 |
Precision@K | No more than 1 false positive in the top K=5 candidates for 85% of test cases | Multiple unrelated bugs ranked above position 5 with high similarity scores | Run against a labeled dataset with 50% non-duplicate distractors; measure precision at K=5 |
Similarity Score Calibration | True duplicates score above 0.75; non-duplicates score below 0.40 with clear separation | Score distribution shows overlap between duplicate and non-duplicate clusters | Plot score histogram for known duplicates vs. known non-duplicates; check for bimodal separation |
Reasoning Grounding | Every similarity reason cites a specific shared element: stack trace, error message, component, or reproduction step | Reasoning contains vague claims like 'similar issue' or 'same problem' without citing evidence | Spot-check 20 outputs; require at least one concrete shared element per candidate explanation |
Cross-Component False Merge Prevention | No candidate from a different component scores above 0.60 unless the bug genuinely spans components | High similarity score assigned to a bug in an unrelated service or codebase area | Inject cross-component distractors into test set; verify component mismatch caps similarity below 0.60 |
Closed-Duplicate Handling | Already-resolved or closed duplicates are flagged with status and excluded from merge recommendations | Closed or resolved ticket appears as a top candidate without status annotation | Include closed tickets in test dataset; verify status field appears and merge recommendation is suppressed |
Empty Input Handling | Prompt returns an empty candidate list with reason 'insufficient information for duplicate detection' | Prompt hallucinates candidates or returns low-confidence guesses when [INPUT] has fewer than 20 words | Test with truncated or vague bug reports; verify abstention behavior |
Latency Budget | Response completes within 3 seconds for a candidate pool of 500 open tickets | Response exceeds 5 seconds or times out under production load | Benchmark with 500-ticket context window; measure p95 latency across 50 requests |
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 prompt and a small, labeled dataset of known duplicates and non-duplicates. Use a frontier model with high recall tolerance. Skip strict schema enforcement initially—focus on whether the similarity reasoning is directionally correct.
Watch for
- Over-merging: the model may flag loosely related bugs as duplicates because it lacks a calibrated similarity threshold.
- Missing schema checks: without output validation, the ranked list may drift in format across runs.
- Context window limits: if you pass too many candidate bugs, the model may truncate or skip candidates.

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