
Matter intake, conflict checks and entity resolution
New enquiries reach a law firm as emails, web forms and phone notes typed up by reception. Before anyone opens a matter, someone has to work out who every party is and whether the firm has acted for or against any of them. In most firms a person does this by reading the enquiry, typing names into the practice-management system’s conflict search and scanning the results. It is slow work, and how good the search is depends on how well that person guesses the ways a name might have been recorded.
This post is part of our Practical AI for Law Firms series. It sets out how we would build an intake pipeline that turns unstructured enquiries into structured party data and resolves those parties against the firm’s records. Plain matching rules do most of the work. A language model helps with the cases the rules can’t settle, and a person clears every potential conflict before a matter opens.
Why manual conflict searches miss things
A conflict search is only as good as the names you search for, and the same party can sit in a practice-management system several ways. “Harbour Fresh Foods Pty Ltd” might have been entered as “Harbour Fresh Foods Pty. Limited”, or as “Harbour Fresh” under a trading name, or under a former company name. Individuals show up as “Jonathan Smith” on one matter and “Jon Smith” on another.
Related entities make it harder. The other side in a lease dispute may be a subsidiary of a company the firm acts for, or its director may be a current client in a separate matter. Trusts are the hardest case. A trust is not a legal person, so the party is the trustee, and an enquiry that names “the Kellett Family Trust” may correspond to a record for “Kellett Nominees Pty Ltd ATF Kellett Family Trust”. A free-text search on “Kellett” either misses the record or returns hundreds of hits that nobody reads closely.
The pipeline
This is the architecture we use as a starting point:
- Capture: enquiries from the intake mailbox and web forms land in a queue, with the original text stored unchanged.
- Extraction: an LLM converts the enquiry into a fixed JSON schema of parties, roles and matter details.
- Normalisation and matching: deterministic code cleans each name and matches it against an index of every party in the practice-management system, open and closed matters alike.
- LLM review of the grey zone: candidates the rules score as uncertain get a written assessment from the model.
- Conflict queue: a person reviews every candidate and records a decision.
- Write-back: the matter opens in the practice-management system only after every candidate has a recorded decision.
Extraction with evidence
The extraction step asks the model for structured output against a schema and nothing else. Every party must carry the text it came from, so the reviewer can check the model’s reading against the enquiry.
{
"matter_type": "commercial lease dispute",
"parties": [
{
"name": "Harbour Fresh Foods Pty Ltd",
"entity_type": "company",
"role": "prospective_client",
"acn": null,
"evidence": "I'm a director of Harbour Fresh Foods Pty Ltd"
},
{
"name": "Kellett Nominees Pty Ltd ATF Kellett Family Trust",
"entity_type": "trustee_company",
"role": "other_side",
"acn": null,
"evidence": "our landlord, Kellett Nominees as trustee for the Kellett Family Trust"
}
]
}
Missing fields stay null. The prompt tells the model never to supply an ABN or ACN that isn’t in the text, and code checks any number it does return against the published check-digit algorithms. A party whose role the model can’t determine goes to the reviewer with that role marked unknown, because an unclear role is still a party that needs a conflict search.
Deterministic matching first
Most of the matching is ordinary string and identifier work, and it should be. Rules are cheap, they give the same answer every time, and a reviewer or auditor can see why a match was made.
SUFFIXES = {
"proprietary limited": "pty ltd",
"pty limited": "pty ltd",
"limited": "ltd",
}
def normalise(name: str) -> str:
n = name.lower().replace("&", " and ")
n = re.sub(r"[^\w\s]", " ", n)
n = re.sub(r"\s+", " ", n).strip()
n = re.sub(r"^the ", "", n)
for long_form, short_form in SUFFIXES.items():
n = re.sub(rf"\b{long_form}$", short_form, n)
return n
def split_trustee(name: str):
m = re.match(r"(.+?)\s+(?:atf|as trustee for)\s+(.+)", name, re.I)
return (m.group(1), m.group(2)) if m else (name, None)
The matcher runs in order of strength. An ABN or ACN match is near certain. An exact match on normalised names comes next, then token and phonetic similarity with a nickname table for given names. Trustee names are split from the trust name and both are searched. Where the firm has an ABN for a party, a lookup against the Australian Business Register adds the registered name and trading names to the search terms. Once a party matches, the matcher expands one hop through the relationships the practice-management system already holds, such as directors, trustees and parent companies.
Each candidate comes out with a score and a plain reason (“ACN match”, “normalised name exact”, “name similarity 0.91, same suburb”). Thresholds are set low on purpose. A false positive costs a reviewer a few seconds, while a missed conflict can cost the firm a client or worse. Nothing is ever cleared automatically, and that includes a search that returns no hits.
Where the LLM helps
The rules leave a tail of middling candidates, where a reviewer has to think about whether “Harbour Fresh” on a 2019 matter is the same business as the enquirer. For these, the model gets the extracted party, the candidate record and its surrounding context (addresses, matter descriptions, linked parties). It returns a structured verdict of likely same, likely related, unlikely or can’t tell, with a short explanation.
The model can also propose extra search terms, such as a likely trading name or the individual behind a sole-trader business name. Those terms go back through the deterministic matcher, so every hit still carries a rule-based reason.
The model’s permissions are narrow by design. It can add candidates, reorder the queue and attach notes. It cannot remove a candidate from the reviewer’s list or mark anything as cleared. In the review screen its notes are labelled as model output, kept separate from the matcher’s reasons.
Enquiry text is confidential and often sensitive, so the model should run in an Australian region under terms that exclude training on your data. Logs should be retained according to the firm’s existing records policy rather than the vendor’s default.
A person clears every potential conflict
The review screen shows the original enquiry, the extracted parties with their evidence, and every candidate for each party with its reasons. The reviewer records one of three outcomes per candidate (no conflict, conflict, or refer to a partner), and the system stores who made each decision and when. The matter cannot open in the practice-management system until every candidate has a recorded decision, and the firm’s obligations under the Australian Solicitors’ Conduct Rules stay with the people making those calls.
Reviewer decisions feed back into the system, with care. A confirmed non-match is stored so the next search shows that pair pre-annotated (“cleared by J. Nguyen, March 2026, different ABN”). It still appears on the list, because circumstances change and a pair that was unrelated last year may not be now.
Costs and limits
Integration is most of the work. The matcher needs a current, complete index of every party across every matter, closed ones included, and practice-management data that goes back years is usually messy, with duplicate contacts, inconsistent entity types and free-text notes holding the relationships. A party added this morning has to be searchable this afternoon, so the index needs frequent incremental syncs from the source system. This is the kind of sync job we built Centazio, our open-source data integration platform, to handle. Model calls are a small running cost next to the integration build and the reviewer time the process still needs.
The system knows only what the firm has recorded. Conflicts held in people’s heads, such as a lateral hire’s former clients, stay invisible until someone enters them. Trust beneficiaries and ultimate owners are often unknown at intake, and no amount of matching will find a relationship nobody has captured.
Before switching over, run the pipeline in shadow mode alongside the existing manual process. Any conflict the manual search found and the pipeline missed is a defect to fix before go-live. Replaying a few months of past enquiries through it first gives you a test set and a realistic picture of reviewer workload.
Starting small
A sensible first project is extraction plus deterministic matching, running in shadow mode against your practice-management data, with the review screen built but not yet controlling matter opening. That shows quickly how clean your party data is and how many grey-zone candidates you actually get, which tells you whether the LLM review step is worth adding.
PicNet builds production AI systems for Australian organisations. If intake and conflict checking is taking up your team’s time, talk to us about what a first project could look like.