02 · Dedicated toolkit per question pattern. SQL only as the escape hatch.
Step 1: Build a typed tool for every question pattern that matters.
Instead of letting the model generate SQL against the raw warehouse, we built a dedicated tool for every question pattern the end-customers actually ask - `getSalesByMarketplace`, `compareSkuPerformance`, `getMarketShareCategory`, `getMarginByPeriod`, and a few dozen more. Each tool has a typed input/output contract, runs the right query against the right source, and encodes the marketplace-specific logic (currency normalization, fiscal-year boundaries, ASIN vs ItemID, etc.) once, in code, with tests. The model picks the tool. It doesn't reinvent the join.
Step 2: SQL is a backup, not the default.
For long-tail questions the toolkit doesn't cover, the agent can fall back to a constrained SQL surface - read-only, scoped to the calling tenant, with row limits and statement timeouts. The agent has to reason about whether the question is in-toolkit before reaching for SQL. In practice the toolkit covers the overwhelming majority of real traffic, and SQL is reserved for exceptions instead of being the default code path.
Step 3: Why dedicated tools beat text-to-SQL in production.
Text-to-SQL agents fail in the same handful of ways under load: hallucinated column names from outdated schema, joins that look plausible but use the wrong key, currency mismatches, fiscal-period boundaries off by a quarter. Each failure is a quietly-wrong number, which is worse than no number - the customer trusts the answer and acts on it. Dedicated tools remove the entire class of failure: the join is in code, the units are in code, the period boundaries are in code. The model's only job is picking which tool to call and with what arguments. That's a much smaller surface to test, and a much smaller surface to break.
Step 4: AWS Bedrock + Agent Core, inside the customer's account.
Claude on Bedrock as the planner, AWS Agent Core orchestrating tool calls and conversation state. The whole agent runs inside the customer's AWS account - IAM-scoped per tenant, every tool call logged to CloudWatch for audit, no data leaves the perimeter. That's what their procurement and compliance teams sign off on, and it's what their enterprise end-customers expect when they let an agent see their sales data.
Step 5: Embedded in the product UI, not a separate console.
The agent ships as a chat surface inside the existing dashboard the end-customer already uses. Answers come back with the tool trace attached - what the agent called, what each tool returned - so power users can verify the answer and the customer's support team can debug a "this number looks wrong" ticket without re-running the query by hand.