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.
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.
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.
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.
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.
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 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);
Everyone exposed, up to three hops out
One recursive path collects every entity that is exposed to the fund, then a plain filter finds the netting sets facing them.
LET $hit = entity:halvorsen_fund .{1..3+collect}(<-exposed_to<-entity); SELECT id, counterparty.name AS cp, mtm FROM netting_set WHERE counterparty IN $hit;
Remember why the limit is what it is
Memory is a table in the same database, so the graph result goes straight into the query. No lookup service, no second round trip.
SELECT entity.name, at, note, limit_before, limit_after FROM review WHERE entity IN $hit ORDER BY at DESC;
Draft the alert and keep the evidence
The agent writes the text. The database records what the text was based on, in the same transaction.
BEGIN; LET $a = CREATE alert SET body = $draft; RELATE $a->based_on->$hit; RELATE $a->based_on->$netting_sets; RELATE $a->based_on->$reviews; COMMIT;
SELECT out.entity.name AS entity, out.note AS memory, out.source AS source FROM based_on WHERE in = $alert AND meta::tb(out) = 'review';
trace_id. Open it to see which hits, by which path, informed the draft; each memory carries its own source and quote span.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.
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;
An alert that shows its working
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.
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.
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
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
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.
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.
Your agents can read the news. Now let them see what it hits.
Explore more
- What is agent memory?The six categories of agent memory, what each one stores, and where it sits in an AI stack.
- Financial services ontologyEight source systems land in one SurrealDB graph, with the SurrealQL behind every entity and relation.
- Company brainOne pricing decision is followed through ingest, per-person permissions and time.