Peer and transaction recommendation agents
Peers and precedent transactions are the two lists at the centre of any valuation, and analysts assembled both by hand across three licensed databases. Two systems now generate a ranked shortlist for each, with a written reason per candidate. The analyst still decides what enters the model, and that decision is the label the system learns from.
The problem
Peers and precedent transactions are the two lists at the centre of any valuation, and analysts built both by hand across three licensed databases.
The result depended on who was doing it and how long they had, and nothing recorded what had been considered and rejected.
The solution
Similar text is not the same as comparable business. Two companies can describe themselves almost identically and be useless as comparables, because one is a brand owner with pricing power and the other a contract manufacturer. Cosine similarity scores the words.
Which makes the embedding step the weakest link, and the four stages around it load-bearing: hard filters in SQL, a maintained list of known non-comparables, heuristic scoring on size, margin and growth, and the language model last.
It re-ranks a pool that is already filtered and already scored, and writes the reason a reviewer reads. It is never asked to produce a company name, so it cannot invent one.
Components
Hard filters
Geography, SIC code and industry group cut the database to a relevant pool in SQL, before any model runs. Embedding the whole universe on every valuation would cost more and rank no better.
Embedding match
Company and deal descriptions, enriched in Snowflake, are embedded with an open-source text model and compared against the filtered pool by cosine similarity.
Negative gating
A maintained list removes candidates that pass the filters and are still clearly wrong: subsidiaries of the same group, companies in regulatory run-off. Some wrong answers are wrong for reasons no similarity score will catch.
Heuristic scoring
Size, margin and growth proximity produce the initial ranking. This is where comparability actually lives, and it is arithmetic rather than a model.
LLM re-ranking
The only generative step, and the last one. It re-orders a pool that is already filtered and already scored, and writes the short reason a reviewer reads before accepting a candidate.
MCP server
Every platform GraphQL operation is wrapped as a typed tool so an agent can call it directly. The analyst's token is passed through, so the platform's own authorization rules apply unchanged.
Analyst review
Accept, reject or replace, per candidate. Nothing enters the valuation model without an explicit human decision, and that decision is the label the system learns from.
Evaluation
Peer sets from closed valuations are ground truth: for a given target, this is the set a qualified person was willing to sign. Ranking against it answers how often the correct peer appears in the top twenty.
Tech stack
Data
ML and embeddings
LLM re-ranking
MCP server
Product screens
Recreated from the platform interface. All company and deal data is synthetic.
Results
Before
Hours, and inconsistentPeers and transactions were assembled by hand across three licensed databases. The result depended on who was doing it and how long they had, and nothing recorded what had been rejected.
After
Shortlist in secondsRanked candidates, each with a written reason and a path back to the source record. The analyst still decides what enters the valuation model.
No baseline of manual analyst selections was captured before launch, so I will not claim a time saving. Acceptance rate is what the system is judged on instead, and capturing that baseline first is what I would insist on next time.