Skip to content

Supply Chain Risk

Suppose you need to identify cascading supplier dependencies: the cases where trouble at a deep-tier supplier ripples all the way up to many downstream products. What makes this different from the fraud example is depth: the risk usually hides several tiers down.

The graph holds entities like Supplier, Component, Product, Facility, and Region, connected by relations such as supplies, depends_on, manufactured_at, and ships_to.

Explore deep dependencies

Because the interesting chains run deep, this is the case that calls for a higher hop_limit:

from arango import ArangoClient
from odin import OdinEngine

db = ArangoClient(hosts="http://localhost:8529").db(
    "supply", username="root", password=""
)
engine = OdinEngine(db, community_id="supply", community_mode="mapping")

result = engine.retrieve(
    seeds=["supplier/critical_vendor"],
    hop_limit=5,          # deep exploration across tiers
    max_paths=100,
)

for p in result["paths"][:10]:
    edges = p["edges"]
    nodes = [edges[0]["u"], *(e["v"] for e in edges)] if edges else []
    print(f"[{p['score']:.2f}]", " -> ".join(str(n) for n in nodes))
# Discovers: a Tier-3 supplier feeds 47 downstream products

The deep walk reveals chains like Tier-3 supplier → component → sub-assembly → product, quantifying how far a single vendor's disruption propagates.


Why deeper hops here

Domain trait Odin setting
Risk is many tiers deep hop_limit=5 (or more)
Chains fan out widely Narrow the beam_width to keep depth affordable
One vendor, many products Seed on the vendor; read node frequencies in the aggregates

See Tuning Retrieval for the depth-vs-breadth trade-off.


Rank the exposure

Use anchors to find the most structurally central suppliers before drilling in:

anchors = engine.find_anchors(seeds=["region/southeast_asia"], topn=20)
for node_id, ppr in anchors[:10]:
    print(f"{ppr:.4f}  {node_id}")   # the load-bearing suppliers in the region

High-PPR suppliers are the ones whose failure would affect the most paths, and the priorities for a resilience review.


Hand off to an agent

if result["triage"]["score"] >= 65:
    risk_agent.reason(
        prompt="Summarize the single-point-of-failure risk in this supply chain.",
        evidence=result["paths"][:10],
    )

Next