Counterparty risk agent demo
A downgrade, three entities away

Your agents can read the news. Can they see what it hits?

Can your agent see that a downgrade three entities away hits four of your netting sets, and remember why you raised that limit last quarter? That needs graph and memory in the same place.

downgraded hop 1 hop 2 hop 3 Halvorsen Fund III Meridian Bank Nordkap Logistics Calder Trading Vantage Metals Ostrava Freight NS-1042 · 42.0 NS-2210 · 18.5 NS-3307 · 7.2 NS-4415 · 11.0 Halvorsen Marine same name, other entity Aurelia Energy Corvid Bank NS-5001 · 25.0 not reached
5 entities · 4 netting sets · 78.7m MTM
The use case

A supplier or fund is downgraded. What does the desk need to know in the next ten minutes?

The news is public. The exposure is yours: spread across counterparties, guarantees, funding lines, and netting sets, and shaped by decisions your team made in earlier reviews. An agent that only reads the headline cannot answer for any of that.

Which entity?

The headline says "Halvorsen credit fund"

Your books hold a credit fund and a marine supplier with the same family name. Keyword search alone picks the supplier.

Who is exposed?

Direct is easy. Indirect is the risk.

A bank lent to the fund, a trading house sits behind the bank, a freight firm behind that. The exposure is a path, not a row.

What did we decide?

The limit has a history

Calder's limit went from 15m to 25m in July because of daily collateral. The risk team needs that reason next to the alert, not in a folder.

3hops from headline to the furthest counterparty
5entities exposed, directly or indirectly
4netting sets touched, 78.7m MTM
2past reviews that explain today's limits
How the agent works it

From headline to alert in four queries

Each step is a query against the same database. These are the queries and results from the demo, run on SurrealDB 3.3.4.

Which Halvorsen?

Full-text search finds both entities and ranks the supplier first. Fusing it with a vector search on the headline puts the fund on top.

Full-text alone, then hybrid
-- full-text only: 1. Halvorsen Marine Supply (1.01)  2. Halvorsen Credit Opps III (0.77)
SELECT id, id.name AS name
FROM search::rrf([
  (SELECT id, search::score(0) AS score
   FROM entity WHERE name @0,OR@ 'Halvorsen'),
  (SELECT id, vector::distance::knn() AS distance
   FROM entity WHERE embedding <|3, 40|> $vec)
], 3, 60);
Full-textHalvorsen Marine Supply ranks first1.01
HybridHalvorsen Credit Opportunities Fund III ranks firstrrf #1
The schema

Five tables carry all four jobs

The entity table holds the record, the full-text index, and the vector index. Relations are edges you can walk. Memory and alerts are ordinary tables.

schema.surql
DEFINE TABLE entity SCHEMAFULL;
DEFINE FIELD name      ON entity TYPE string;
DEFINE FIELD rating    ON entity TYPE string;
DEFINE FIELD embedding ON entity TYPE array<float>;
DEFINE INDEX entity_ft  ON entity FIELDS name
  FULLTEXT ANALYZER an BM25;
DEFINE INDEX entity_vec ON entity FIELDS embedding
  HNSW DIMENSION 4 DIST COSINE;

DEFINE TABLE exposed_to TYPE RELATION IN entity OUT entity;

DEFINE TABLE netting_set SCHEMAFULL;
DEFINE FIELD counterparty ON netting_set TYPE record<entity>;
DEFINE FIELD mtm ON netting_set TYPE number;

DEFINE TABLE review SCHEMAFULL;
DEFINE FIELD entity ON review TYPE record<entity>;
DEFINE FIELD at     ON review TYPE datetime;
DEFINE FIELD note   ON review TYPE string;

DEFINE TABLE alert SCHEMAFULL;
DEFINE TABLE based_on TYPE RELATION IN alert;
entitySupplier, fund, or bank. Document, full-text index, and vector index in one record.
exposed_toThe edge the agent walks. "A is exposed to B."
netting_setWhat the desk actually cares about, linked to a counterparty.
reviewThe agent's memory of past limit decisions and why.
alert, based_onThe output, and the edges that make it auditable.
What the risk team receives

An alert that shows its working

Draft alert for the risk team

A rating agency cut Halvorsen Credit Opportunities Fund III to BB+. Four netting sets are exposed, 78.7m MTM in total, and the furthest link is three hops out (Ostrava Freight).

Calder's limit was raised in July against daily CSA collateral. Check that it still holds. Meridian was already on the watchlist for funding concentration in credit funds. Alert text is hand-written for this demo. In production the agent drafts it from the query results.

11records it is based on
Entities · 5
nordkapmeridianvantagecalderostrava
Netting sets · 4
ns_1042ns_2210ns_3307ns_4415
Prior reviews · 2
r1 · Calderr2 · Meridian

Ask "why did this alert say that?" and the answer is a walk along based_on edges, not a log search. Each memory names its source, and the alert's trace_id opens the retrieval trace behind it.

Why SurrealDB

One system, not four stitched together

You can build this agent on a vector database, a search index, a graph database, and Postgres. The queries above then become four services, three sync jobs, and a lot of glue code owned by whoever is on call.

The usual stackFour stores and the glue between them

Vector DB
Full-text index
Graph DB
Postgres
ETLsync jobagent-side joins

Four copies of each entity, four permission models, and a lineage story you assemble from four sets of logs after a regulator asks.

SurrealDBOne database, one record per entity

Single engine
Hybrid search
Graph traversal
Relational records
Agent memory

The fund's record, its vector, its text index, and its edges live together. The agent asks one system, in one query language, inside one transaction.

No joins in the agent

Match, traverse, and recall chain through variables like $hit. The agent never merges result sets from different services.

Nothing to drift

There is one copy of each entity. A relationship added at 09:00 is visible to the traversal at 09:01, with no sync job in between.

Auditable by construction

The alert, its sources, and the decisions behind it are linked records written in one transaction. One permission model covers all of them.

Less to run

One thing to secure, back up, monitor, and upgrade. For a regulated team, that is fewer systems to evidence.

What this demo does and does not show

Entities are fictional, embeddings are four-dimension toys, and the alert text is written by hand. The queries and their results are real, run against SurrealDB 3.3.4. Production use needs a real embedding model, your own data model, and your own controls review.

Graph and memory, in the same place

Your agents can read the news. Now let them see what it hits.

Explore more