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],
)