TL;DR
Parallel specialist agents all read the same text, so they all report it. Deduplicating across agents is not tidying — it is what decides whether the output is usable, and it is a different problem from deduplicating messages.
How do you stop eleven agents reporting the same clause eleven times?
You filter the output, and you do it before a human ever sees it.
That sounds like housekeeping. It is not. In a multi-agent system, deduplication is the difference between an output somebody uses and an output somebody abandons — and the moment you run specialists in parallel, you have signed up for it.
For the engineering lead whose fan-out works and whose output nobody reads. 7 minute read.
Eleven specialists, one paragraph
A contract-review pipeline routes each chunk of text to domain analysts — warranty, indemnity, termination, data protection and so on. Several of them can be selected for the same chunk, and when a chunk scores as broadly relevant, all of them are.
Now consider a limitation-of-liability clause. It caps damages, which is the warranty analyst's territory. It carves out indemnities, which is IP's. It survives termination, which is termination's. It references insurance minimums, which is insurance's.
Four specialists read that paragraph. Four specialists report it. Each is correct. Each is doing precisely the job it was given.
The duplication is not a bug in any agent. It is a property of the architecture. Fan-out means overlapping coverage, and overlapping coverage means the same text surfaces repeatedly. A system that does not plan for this produces a findings list where the same clause appears four times with four slightly different justifications, and the reader concludes the tool does not know what it is doing.
The filter that does the work
The pipeline applies deduplicate_cross_analyst before anything reaches the interface: the same text found by different analysts collapses into one finding.
Note where it sits. Not inside an agent, not in the router — after analysis, across all of it. It has to be there, because no individual analyst can know that another analyst already reported the clause. Each one sees a chunk and its own remit. Only the layer above them can see the overlap.
That placement is the design lesson, and it generalises past contract review: anything that fans out needs a converging step that knows what all the branches produced. If your architecture has no such layer, duplication has nowhere to be resolved and it becomes the user's problem.
Content deduplication is not message deduplication
This is worth separating carefully, because the words are the same and the problems are not.
Message deduplication is an infrastructure concern. A standard queue delivers at least once, so the same message can arrive twice, and the fix is idempotency — our sibling article on queue topology describes exactly this, using conditional database updates keyed on the chunk and agent identity so a duplicate delivery short-circuits.
Content deduplication is a product concern. Every message was delivered exactly once. Every agent ran exactly once. Eleven distinct, correct, non-duplicated executions produced findings that point at the same sentence. No amount of idempotency helps, because nothing was repeated.
- Cause — Message dedup: At-least-once delivery · Content dedup: Overlapping agent coverage
- Fixed by — Message dedup: Idempotent writes keyed on identity · Content dedup: A convergence step comparing outputs
- Symptom if missed — Message dedup: Double-counted work, corrupted state · Content dedup: An unreadable findings list
- Lives in — Message dedup: The queue consumer · Content dedup: Above all the agents
Teams that have solved the first one often assume they have solved the second. They have not. They are different layers, they fail differently, and only one of them is visible to the person reading the report.
The other three filters, and why each exists
Deduplication does not travel alone. Three more filters run before output:
Low-risk findings are dropped. Not because they are wrong, but because a list that includes everything ranks nothing. If a reviewer has to skim forty low-risk notes to find three high-risk ones, the ranking has been outsourced to them.
A minimum extract length applies. Below a certain size, a fragment cannot carry enough context for a human to judge it, and a finding a reader cannot evaluate is worse than no finding — it costs attention and returns nothing.
Headings and contents-page patterns are excluded. A table of contents contains every dangerous word in the document — indemnity, termination, liability — with none of the substance. It is precisely the text most likely to score highly and least likely to matter.
All four filters are answering one question: what does this person have time to read? That is a product question, and it is being answered in the pipeline rather than in the interface, which is the right place for it — the interface cannot un-generate a finding.
The interface makes it worse, not better
There is a reason this cannot be deferred to the front end, and it is specific to how the findings are presented.
The output is not a list beside the document. It is highlighting inside the document itself — the contract the lawyer already had open, with risky clauses marked in place.
Overlapping findings on one paragraph are not four rows in a table. They are four highlights on the same sentence. A list can at least be scrolled past; a document with layered, competing annotations on one clause is actively harder to read than an unannotated one. The tool has made the lawyer's primary artefact worse.
That inverts where the convergence layer belongs. With a side panel you could argue for merging at render time. With in-place annotation, by the time the finding reaches the interface it is already a mark on the page — so the merge has to happen before, in the pipeline, where the analyst outputs still exist as data. Chapter 9 covers what else that delivery choice forces.
Where it breaks
Every filter is a bet, and each of these can be wrong.
Deduplication can collapse a genuine second finding. Two analysts reporting the same clause for genuinely different reasons — a cap that is too low and a carve-out that swallows it — is two findings about one sentence. Collapse them and the reader gets one. The safe behaviour is to merge the locations and keep both justifications, and any dedup that keeps only the first result is discarding analysis that was paid for.
Low-risk filtering hides trend information. One low-risk finding is noise. Thirty low-risk findings in the same category is a pattern about that counterparty, and it is invisible once each one is individually dropped.
Heading exclusion is pattern-matching, and contracts are inconsistent. A clause title that reads like a heading is a heading to a filter.
The honest framing: filtering trades recall for usability, deliberately. That trade is correct at this scale — but it is a trade, it should be configurable, and the person configuring it should know what it costs. A filter presented as neutral cleanup is a filter nobody audits.
What we would build, and the check for Monday
How we build it. Make the convergence layer explicit and inspectable rather than implicit. Merge on location, keep every justification, record which analysts contributed, and keep the filtered set retrievable so a reviewer can ask what was suppressed. A finding that was dropped should be recoverable, not deleted — the pipeline's confidence in a filter should never exceed the reviewer's ability to check it.
Status, stated plainly. This is a system we built. It runs, it is demonstrable on a call, and it has zero delivered engagements. We build these on request, against your documents. No number here describes anyone's business but our own.
The check worth running, and it needs nothing from us. Take one output from your own multi-agent system and count distinct source locations against total findings. If findings substantially exceed locations, your users are reading the same thing several times and quietly deciding the tool is noisy. Then ask the harder question: how many findings were suppressed, and can anyone tell you?
About Cognilium Cognilium is an AI engineering company — agent systems, retrieval, knowledge graphs, voice AI and the production plumbing that makes them survive contact with real workloads. https://cognilium.ai · https://www.linkedin.com/company/37180269/
Want to know what your fan-out is producing that nobody reads? Book a 15-minute call — we will walk the convergence layer with you, on your output if you bring it. No deck.
Sources
This article draws on our own build. The infrastructure-side counterpart — idempotent handling of at-least-once delivery — is covered in our published piece on mixing FIFO and standard queues in an agent pipeline.
Share this article
The review pipeline these articles describe — extraction, category routing, parallel scoring and human escalation — as an engagement.
