Ask Herald anything
Chat answers three shapes of question about your product: factual (what the data says), diagnostic (why a number moved), and exploratory (what patterns exist). Every answer cites the data Herald used and the SQL or code it ran.
Every chat is scoped to a single Product. Your questions, Herald’s answers, and the queries behind them all live inside that Product’s Durable Object — nothing leaves the tenant. The briefing is the hero; chat is what you use every day.
Three shapes of question
Section titled “Three shapes of question”Factual
Section titled “Factual”“How many users signed up from the Twitter campaign last week?”
Herald classifies the question, generates SQL against your Durable Object’s rollups, runs it in a Dynamic Worker sandbox with a read-only view of your data, and returns the answer with an inline chart. No SQL knowledge required on your end.
Diagnostic
Section titled “Diagnostic”“Why did signups drop on Monday?”
Herald pulls relevant slices — daily signups, source breakdown, deploy history if you’ve connected it — correlates them, and returns a one-paragraph explanation with the supporting evidence. This is where larger models (Opus routed through AI Gateway) earn their keep.
Exploratory
Section titled “Exploratory”“Who are my 10 most at-risk users and why?”
Herald writes a scoring function, runs it on your data in the sandbox, and returns a ranked list with reasoning. The sandboxed code never touches your main tenant state — only a read-only SQL view.
How the SQL runs
Section titled “How the SQL runs”Every chat answer is generated by code Herald wrote, then executed in an isolated Dynamic Worker with:
- Read-only access to a SQL view of your Product’s Facet DB
- No network — can’t call out to anything
- No extra bindings — no KV, no R2, no Vectorize
- 5-second CPU budget — a hung query gets killed
Every answer shows a How did you get that? disclosure with the SQL Herald ran. Click it any time you don’t trust a number.
Semantic annotations
Section titled “Semantic annotations”The single biggest lever for chat accuracy. As you chat, Herald accumulates the business rules you tell it:
- “A qualified trial is a user with 3+ events in week 1.”
- “Our power-user threshold is 40+ sessions/month.”
- “MRR excludes internal accounts ending
@helpkit.com.”
These live in your Product’s semantics table and are injected into every agent prompt. They’re collected conversationally — no YAML to write. Review them any time under Settings → Semantics.
Accuracy improves with use. Week 1 of chat is the worst it will ever be.
What chat will not do today
Section titled “What chat will not do today”- Write data. Chat is read-only. Herald never modifies your Stripe account, Intercom conversations, or source systems.
- Cross Products. One Product per conversation. Cross-Product queries are structurally impossible — tenant isolation is non-negotiable.
- Guess without asking. If Herald can’t tell which event represents “signup” —
user_signed_up,account_created,trial_started— it asks. That answer becomes a semantic annotation.
Watch out for
Section titled “Watch out for”Text-to-SQL is 85-95% accurate on standard queries and falls off a cliff on complex analytics (deep window functions, recursive CTEs). If an answer smells wrong:
- Open the How did you get that? disclosure.
- Read the SQL.
- Reply with the correction — Herald retries with your note as context, and stores the correction as a semantic annotation for next time.
Every natural-language-to-SQL pair is logged to Herald’s evaluation corpus so we can improve the generator over time. No row results are stored — only the question and the query.