Hear Stuut chase cash! The agent doing $200M / mo in AI collections wants to chat.

Give Stuut a Ring

Building Ask Stuut: Your AI AR Analyst

Emma Teng
Head of AI
Table of contents

See Stuut in action

Get a personalized demo of Stuut and see how it can help with AR automation.

Get started

The Governed Stack

If you've logged into Stuut recently, you've probably noticed a new face in the top-left corner of the dashboard — our logo, bouncing left and right, waiting to say hi. That's Ask Stuut, your AI analyst that answers questions about your accounts receivable in plain English:

  • What's our DSO trend this quarter?
  • Which customers are driving it up?
  • How much cash did we collect last month?

Chatbots that answer questions about your data are easy to demo and hard to trust. The failure mode is well known: hand a language model raw database access, and it will confidently join the wrong tables, mix currencies, double-count partial payments, and return a number that looks plausible. For a finance product, plausible-but-wrong is worse than no answer at all.

So we built a governed data platform, and put a tightly-scoped agent on top of it. This post walks through the four layers that make that work.

Layer 1: Ingestion

Ask Stuut never touches the operational database. Change data capture streams every table from our application database into a dedicated analytics warehouse in near real time, landing in a raw schema that preserves the source shape (including soft-delete markers, which we filter at the next layer).

This separation matters for more than performance isolation. The raw layer is an immutable, replayable record — every downstream transformation can be rebuilt from scratch, and analytical queries can never degrade the app your collections team is working in.

Layer 2: Governed transformation

Raw production tables are the right shape for running the application, but the wrong surface for analytics — answering a domain question like "was this invoice collected by Stuut?" involves complex joins, business logic that lives in application code, and transformations you don't want re-derived (differently) in every query. A version-controlled transformation pipeline rebuilds the raw data into analytics-ready tables through three layers: staging (clean, rename, type-cast), intermediate (business logic), and marts (wide, query-ready fact and dimension tables).

This is where the hard semantics get resolved once, in reviewed and tested code, instead of at query time by a language model. A few examples:

  • Currency. Every monetary column comes in three flavors: the entity's own currency, a USD conversion, and an org-display-currency conversion — each converted at the FX timestamp that matches the accounting question (billing time for balances, payment time for cash collected).
  • Grain. "Cash collected in March" and "invoices paid in March" are different questions. We maintain separate facts at invoice grain and payment-event grain so partial payments land in the period the cash actually arrived.
  • Attribution. Whether an invoice was touched by Stuut outreach, and whether a task was resolved by automation, are encoded as tested flags that mirror the application's own rules.

The pipeline ships with data tests — including reconciliation tests that assert warehouse numbers match what the application itself reports — and every mart carries a row access policy that filters reads to a single organization. More on why that's load-bearing below.

Layer 3: Semantic views

Between the marts and the agent sits a semantic layer: warehouse-native objects that declare, in DDL, exactly which tables an agent may query, which columns are dimensions, which are metrics (with their aggregation functions), and, most critically, a natural-language description of every one of them.

We maintain multiple semantic views, one per product domain:

  • Collections
  • Cash App
  • Disputes
  • Deductions

Each is defined in the same repository as the transformation models and deployed by the same pipeline, so a change to a mart and the semantic view that exposes it ship atomically. The semantic layer is the single source of truth for governed metrics, there is no second definition of "DSO" hiding in a dashboard somewhere.

This is the layer that makes text-to-SQL reliable. The agent doesn't explore a database; it selects from a curated menu of described metrics and dimensions whose grain and aggregation rules are fixed ahead of time.

We also have a library of verified queries covering common analytical questions with the correct SQL for each, which has improved answer accuracy, response time, and token efficiency.

Layer 4: The analytical agent

Ask Stuut isn't a single model trying to know everything about AR — it's one agent orchestrating a team of domain experts, all running inside the warehouse's managed agent harness:

  • Each of the semantic views gets its own text-to-SQL analyst, so the agent has multiple tools, each an expert in one domain.
  • A declarative specification tells it how to use them. Routing rules send each question to the right analyst: "what's our current AR?" goes to the invoice analyst, "what did we collect last month?" to the collections analyst. When a question spans domains, synthesis rules have the agent call each tool independently and combine the results on a shared key.
  • The orchestration layer also encodes metric selection guidance (like which grain gives period-accurate cash figures), domain terminology, and response formatting

Two implementation choices we'd recommend to anyone building something similar:

  • The agent spec lives in version control. The full specification — tool descriptions, orchestration instructions, response rules — is code in the same repository as the data models, and a post-run hook redeploys it after every pipeline run. Prompt changes get code review, history, and automatic deployment, and the agent can never drift out of sync with the semantic views underneath it.
  • Tenant isolation is enforced below the agent, not by it. When a user sends a message, our API binds their organization ID as an immutable session variable on the agent run, and the row access policy on every mart filters accordingly. The agent is instructed never to filter by organization — but even a fully jailbroken agent couldn't read another tenant's rows, because isolation lives in the database engine, not the prompt.

Layer 5: Applications

A thin streaming API in our backend fronts the agent: it authenticates the user, translates the agent's event stream into our dashboard's chat protocol, persists conversations, and handles the unglamorous edges — timeouts, disconnects, retries — so a deploy never eats an answer mid-stream.

We created multiple REST Agent API to serve multiple use cases:

  • Ask Stuut: the customer-facing chat you see in the top-left of Stuut’s product UI, which also suggests follow-up prompts based on where the conversation has gone.
  • Our internal Slack: HAL, our internal bot, routes every analytical question it receives to this same agent. (HAL deserves a blog post of its own — stay tuned!)
  • Snowflake’s native chat interface: a third way for the Stuut team to ask analytical questions —  backed by an internal agent variant that can analyze metrics at scale with comprehensive charting and table outputs.

Observability

Every agent run is traced end to end: general application telemetry on one platform, and LLM-specific traces — token usage, latency, per-tool calls, prompt and response inspection — forwarded to a dedicated eval platform. Each response carries a request_id tying our logs to the runtime's usage history, and in-product thumbs up/down feedback is persisted alongside the conversation. Together, traces and feedback give us the raw material for evals — real questions with known-good answers that we can score routing and accuracy against as the agent evolves.

Looking ahead

We're not stopping at data pulls. Today Ask Stuut is deliberately read-only — it reports, you decide. The next chapters push further up the value chain: root-cause analysis ("why did DSO jump?", not just "it jumped"), actionable recommendations grounded in your own data, and eventually taking action — drafting the outreach, adjusting the workflow — once you approve it. Each step will get the same treatment as the rebuild itself: guardrails first, capability second.

We also want your best questions to compound. Soon you'll be able to save prompts, charts, and tables as reusable artifacts — so the analysis you built last month is one click away, not one conversation away.

The takeaway

The interesting engineering in Ask Stuut isn't the chat window — it's everything underneath it. The agent is reliable because it's the last layer of a governed stack: tested transformations resolve the hard semantics, semantic views constrain what can be queried, database-level policies enforce tenancy, and version control governs every prompt and metric definition.

Bounce on the logo and ask it something — and if it gets anything wrong, that thumbs-down button goes straight into our eval set.

If you're a Stuut customer, reach out to your account team to get a demo of Ask Stuut. If you're not yet working with us, this is a good reason to start a conversation.

[Book a walkthrough →]

Emma Teng

Head of AI

Emma is Head of AI at Stuut, where she leads the Data & AI team building next-generation AR automation and analytics. With 10+ years of AI experience, she's passionate about scalable AI infrastructure and creating product experiences that are as enjoyable as they are powerful.

Frequently asked questions  about DSO

Is a higher or lower DSO better?
Lower is better because it means cash reaches your account faster. A DSO of 35 days is better than 55 days if your payment terms are the same.
Does DSO include current AR?
Yes. DSO reflects the total dollar amount you're owed from outstanding invoices, including invoices that aren't yet due.
How does bad debt affect DSO?
Writing off bad debt reduces your AR balance, which artificially lowers DSO even though no cash was collected. Ensure your AR figure is net of bad debt reserves for accurate measurement.
Should I calculate DSO monthly or annually?
Both. Annual DSO tracks long-term trends, while monthly DSO helps you spot process problems quickly and take corrective action before they compound.
What's the difference between DSO and CEI?
DSO measures collection speed in days. CEI measures collection quality as a percentage. A company can have low DSO but poor CEI if they're writing off accounts aggressively.
Can I reduce DSO without upsetting customers?
Yes. Proactive communication before due dates, helpful reminders, and fast dispute resolution improve customer experience while accelerating payment.

Related posts

Setup time to learn more