Asking the portfolio a question#
A Customer Success team watching a portfolio of accounts wants to ask a question and get back the accounts that need attention, why they're slipping and a plan it can act on. So I built a console where the operator asks in plain English and an AI agent does the analysis. The operator still makes every decision.
The data is invented: a portfolio of B2B SaaS accounts with health scores, adoption, engagement and support signals, and no real customers. The dashboard itself is standard. The command bar is the part I wanted to build.

What the agent does#
Type "which accounts are at churn risk and why?" and a multi-step agent:
- works through the portfolio with tools: filter by health or metric, compare an account to its industry peers, pull a full record, read portfolio-wide stats
- streams a trace of each step while it runs
- highlights the matching cards on the dashboard
- drafts a recovery plan you can approve or edit, based on that account's alerts
Every action is a tool call#
The agent's effects on the interface, highlighting cards and drafting the plan, arrive as typed tool calls instead of text the client has to parse out of prose. Reading data and changing the UI go through the same mechanism, which keeps the trace accurate and the interface predictable when the model improvises.
The agent never acts on its own. It drafts the plan, and the operator approves or edits it. An LLM loop that acts by itself in front of a customer can do real damage, so this one drafts and never executes.
Limits#
The agent has a step cap, an output cap, an input limit and a timeout, so a runaway loop can't run up a bill or hang the page. Errors come back as a short plain message, never a stack trace. With no API key configured, the command bar hides and the dashboard still works.
It's built with Next.js and React, Tailwind for the design system and the Vercel AI SDK running a multi-step Claude tool loop on a Node route. It runs on mock data with no backend and is deployed on Vercel.