How to Add an AI Agent to Your SaaS App (The ISV Playbook)
You have a case management app with 1,000 customers. Here's how to give every one of them an AI assistant without building an ML team.
Amodal TeamApril 2, 202620 min read
The scenario
You're the CTO of CaseFlow, a B2B case management SaaS. You have 1,000 paying customers. Each customer is a tenant in your app: their own cases, contacts, workflows, SLAs. Your app manages support tickets, escalations, resolution tracking, and customer communication.
Your board asks: "Where's our AI story?" Your customers ask: "Can the app just tell me what to focus on today?" Your PM says: "Every competitor is adding an AI chat panel."
The constraint
You need to ship AI features fast. But you can't: hire an ML team (6 months to fill, $2M/yr), fine-tune models per customer (1,000 tenants), or build the infrastructure (context management, guardrails, observability). Your engineering team is already fully committed to the core product.
This tutorial shows you how to embed Amodal into CaseFlow so every customer gets an AI assistant that understands their cases, follows their workflows, and respects their data boundaries. Every command is real. Every file is shown.
What you're building
Chat panel
A chat widget embedded in CaseFlow's UI. Your customers ask questions about their cases in natural language. The agent answers using their data.
Multi-tenant isolation
1,000 customers, each with their own data. Customer A's cases never leak to Customer B. Field-level access control. Per-tenant knowledge.
White-label
End users see "CaseFlow AI." They never see Amodal. The chat widget uses your branding, your colors, your domain.
Part 1
Build the agent config
Your developer writes the agent definition once. Every customer gets it.
1
Initialize the project
terminal
$ mkdir caseflow-amodal && cd caseflow-amodal
$ npx amodal init
✓ Project initialized
2
Connect your own API
This is the key difference from the internal-agent tutorial. You're not connecting to Salesforce. You're connecting to your own API. CaseFlow has a REST API that your customers already use. The agent will call the same API.
There's no CaseFlow package in the Amodal registry (it's your proprietary API). So you write the connection files by hand:
connections/caseflow/spec.json
{
"source": "https://api.caseflow.io/openapi.json",
"format": "openapi",
"auth": {
"type": "bearer",
"token": "env:CASEFLOW_API_TOKEN"
}
}
connections/caseflow/surface.md
# Surface: CaseFlow API
### GET /cases
List cases for the authenticated tenant. Supports filters:
status (open|in_progress|resolved|closed), priority (p1-p4),
The agent can read cases, contacts, SLAs, and metrics. It can add comments (with user confirmation) and update cases (with explicit review). It can never retrieve phone numbers. Email addresses are restricted to admin and manager roles. These restrictions are enforced by the runtime before the LLM ever sees the data. Not a prompt instruction. A hard policy.
connections/caseflow/entities.md
# Entities: CaseFlow
### Case
A support case submitted by a customer. Has a lifecycle:
A person associated with a case. Can be the submitter,
the assigned agent, or an escalation contact.
### SLA
Service level agreement tracking per case. Tracks target
resolution time, time elapsed, breach risk percentage.
connections/caseflow/rules.md
# Rules: CaseFlow API
- Always check SLA status before recommending actions.
A case approaching SLA breach takes priority over everything.
- Never close a case without verifying the submitter confirmed
resolution. Check the comments for a confirmation message.
- P1 cases older than 2 hours without an update are escalation
candidates. Flag them, don't escalate automatically.
- The /metrics/summary endpoint is expensive. Cache the result
and reuse within the same session. Don't call it per-case.
Five files. No code. The agent now knows your API: what endpoints exist, what the data means, what it's allowed to do, and the rules for using it responsibly.
3
Write the case triage skill
The skill tells the agent how to think about case management. This is your domain expertise encoded as markdown:
skills/case-triage/SKILL.md
# Skill: Case Triage
## Trigger
Activate when the user asks about case status, priorities,
workload, SLA risk, or "what should I focus on."
## Methodology
1. Check SLA breaches first. Any case approaching breach
(>80% of target time elapsed) is the top priority.
2. Then check P1 cases without recent updates (>2 hours).
3. Then check cases with pending customer responses (>24 hours).
4. Then check unassigned cases.
5. Present as a prioritized list with reasoning for each.
## Output format
- Lead with the count: "X cases need attention."
- For each case: case ID, title, priority, SLA status, why
it's flagged, and a recommended action.
- Keep it scannable. Agents are busy.
## What NOT to do
- Never fabricate case details. If the API returns an error,
say so.
- Never auto-close or auto-escalate. Recommend, don't act.
- Never expose contact PII unless the user's role allows it.
1. CASE-4521 (P1) "Production outage for Acme Corp" — SLA at 92% of target, 23 minutes remaining. No update in 3 hours. Action: escalate to tier 2 immediately.
2. CASE-4518 (P2) "Data export failing" — assigned to Mike but no response in 6 hours. SLA at 71%. Action: check if Mike is available or reassign.
3. CASE-4515 (P3) "Dashboard loading slowly" — customer responded 28 hours ago, no agent follow-up. Action: respond to customer.
4. CASE-4523 (P3) "Feature request: bulk import" — unassigned for 2 days. Action: assign to backlog or triage.
The agent queried your API live, applied the triage methodology from the skill, checked SLA status, and produced a prioritized list with specific actions. All from the markdown you wrote.
Part 2
Make it multi-tenant
One agent definition, 1,000 isolated instances.
5
The multi-tenant architecture
In the internal-agent model (Sales Ops tutorial), there's one tenant with one set of credentials. In the ISV model, each of your customers is a tenant. The agent definition is the same. The data is different. The credentials are different.
YOUR AGENT CONFIG (one definition)
connections/caseflow/ (your API surface, access rules, entities)
skills/case-triage/ (your triage methodology)
.amodal/config.json (model settings, user context endpoint)
amodal deploy ↓ (one snapshot)
AMODAL PLATFORM (1,000 tenants)
Acme Corp
own creds, own KB, own sessions
GlobalTech
own creds, own KB, own sessions
... 998 more
own creds, own KB, own sessions
↓ each tenant gets
Isolated data
Own knowledge
Own sessions
The key insight
You deploy one snapshot. The platform creates a tenant for each of your customers. Each tenant has its own API credentials (hitting your API as that customer), its own knowledge base (that learns from that customer's usage), and its own session history. Customer A's data never leaks to Customer B. The runtime enforces this at the tenant level, not through prompting.
6
Configure per-tenant credentials
Each of your customers has their own API token in your system. When CaseFlow provisions a customer for the AI feature, you create a tenant in Amodal and set the credentials:
your backend — provisioning a new customer's AI agent
// Your API's existing auth handles data isolation.
You already solved multi-tenancy
Your API already scopes data by auth token. If Customer A's token calls GET /cases, it only sees Customer A's cases. The agent uses the same token. Data isolation is your existing API auth, not a new system. Amodal just stores the token per tenant and injects it into API calls.
7
Add the user context endpoint
The agent needs to know who is chatting. When a support agent at Acme Corp opens the chat panel, the agent should know their name, role, and permissions. Add a user context endpoint to your API:
Now when Sarah opens the chat, the agent calls your user context endpoint first. It knows her name, role, team, and what she's allowed to do. The conversation is personalized from the first message.
Part 3
Embed the chat widget
Your customers see "CaseFlow AI," not Amodal.
8
Add the React widget to your app
terminal
$ npm install @amodalai/react
your React app — CaseDashboard.tsx
import { AmodalChat } from '@amodalai/react';
export const CaseDashboard = () => {
const user = useCurrentUser();
return (
<div className="dashboard">
<CaseList />
<CaseDetail />
<AmodalChat
projectId="caseflow-amodal"
tenantId={user.tenantId}
userId={user.id}
token={user.amodalSessionToken}
theme={{
primaryColor: '#6366f1',
name: 'CaseFlow AI',
position: 'right',
}}
/>
</div>
);
};
That's it. 10 lines. The widget renders a chat panel inside your app. It connects to the Amodal runtime via SSE (server-sent events). The user sees "CaseFlow AI" with your brand color. They don't see Amodal.
CaseFlow — Case Dashboard (with embedded AI chat)
Open Cases (47)
CASE-4521 P1 Production outage — Acme Corp
CASE-4518 P2 Data export failing — GlobalTech
CASE-4515 P3 Dashboard slow — StartupCo
CASE-4523 P3 Feature request — MegaCorp
CASE-4521 Detail
Status: Open · Priority: P1 · SLA: 23 min remaining
Assigned: Sarah Chen · Escalation: Mike → VP Support
CaseFlow AI
What should I focus on right now?
4 cases need attention:
1. CASE-4521 (P1) — SLA breach in 23 min, escalate now
2. CASE-4518 (P2) — no response in 6hr
...
Ask CaseFlow AI...
Your customers see a native chat panel. It feels like it was always part of CaseFlow.
Part 4
What your customers experience
Two of your 1,000 customers. Same agent, different data, different knowledge.
9
Acme Corp's support agent uses the chat
Sarah at Acme Corp opens her CaseFlow dashboard and types:
CaseFlow — Acme Corp tenant — Sarah Chen (Support Agent)
S
Sarah Chen · Support Agent
Summarize the Acme Corp situation for the 4pm executive check-in.
C
Queried: /cases, /sla, /metrics/summary for Acme Corp tenant
Acme Corp Support Summary
Active cases: 47 open, 12 in progress, 8 resolved pending close
SLA risk: CASE-4521 (P1, production outage) is 23 minutes from breach. Currently assigned to Sarah. Recommend immediate escalation to tier 2.
Aging: 3 cases older than 48 hours without update (CASE-4502, 4508, 4511). All P3, none approaching SLA.
Metrics: 94% SLA compliance this month (target: 95%). Average resolution: 6.2 hours (down from 7.8 last month).
Recommended talking points: the P1 outage, the SLA compliance gap, and the resolution time improvement.
10
GlobalTech's manager gets a different view
Meanwhile, David at GlobalTech (a different CaseFlow customer) asks the same agent the same question. He gets completely different data:
CaseFlow — GlobalTech tenant — David Park (Manager)
D
David Park · Manager
What should my team focus on today?
C
Queried: /cases, /sla, /metrics/summary for GlobalTech tenant
GlobalTech Team Priorities
Active cases: 23 open, 5 in progress
SLA status: All green. No cases approaching breach.
Attention: CASE-GT-891 (P2, "Integration sync failing") has been bounced between 3 agents in 48 hours. Needs a single owner.
Workload: Lisa has 8 open cases (team avg: 4). Recommend redistributing 2-3 to Mike who has capacity.
Data isolation
Same agent. Same skill. Same methodology. Completely different data. Sarah sees Acme Corp's 47 cases. David sees GlobalTech's 23 cases. Neither can see the other's data. The isolation happens at the API level (different API token per tenant) and the platform level (separate session history, separate knowledge base, separate credentials).
Part 5
Per-tenant learning
After 50 sessions, each customer's agent is smarter — for them.
11
The knowledge flywheel, per tenant
After a month of use, the agent learns patterns specific to each customer:
Acme Corp's agent learned
"P1 cases from the billing team resolve 2x faster when escalated directly to tier 2 (skip tier 1)."
"Cases mentioning 'SSO' are always auth-related, not feature requests. Route to the identity team."
"The Acme Corp SLA clock pauses on weekends. Don't count Saturday/Sunday in breach calculations."
GlobalTech's agent learned
"GlobalTech's integration cases always involve the same 3 API endpoints. Check /sync/status first."
"David prefers bullet-point summaries, not paragraphs. Keep responses under 5 lines."
"GlobalTech's SLA is 24/7, no weekend pause. Different from most customers."
Each customer's knowledge base is isolated. Acme Corp's learned patterns don't leak to GlobalTech. But both benefit from the same underlying skill improvements when you update the deal-triage methodology (which applies to all tenants).
Two levels of learning
Application-level knowledge (your skill updates, API doc improvements) applies to all 1,000 customers. Tenant-level knowledge (each customer's patterns, preferences, baselines) is isolated per customer. The skill gets smarter for everyone. The knowledge gets smarter for each customer specifically.
Part 6
The CaseFlow admin experience
You shipped an AI feature. Now you need to operate it across 1,000 customers.
12
Cost monitoring across all tenants
Your CFO asks: "What does the AI feature cost us?" Open the admin UI:
Admin UI → Costs → All Tenants (CaseFlow product team view)
$847
Total this month
1,000
Active tenants
$0.85
Avg per tenant/mo
14,200
Total sessions
Cost by skill
case-triage
$466
case-summary
$212
ad-hoc queries
$169
Top 5 tenants by usage
• Acme Corp — $12.40 (340 sessions)
• GlobalTech — $8.20 (210 sessions)
• MegaCorp — $6.80 (178 sessions)
• StartupCo — $5.10 (142 sessions)
• DataFlow — $4.90 (131 sessions)
Model Arena suggestion:Switch case-summary from Sonnet to Haiku. Estimated savings: $127/mo. Eval score unchanged (94% → 93%).
$847/month across 1,000 tenants. $0.85 per customer per month. If you charge $10/mo for the AI feature, that's 91% gross margin. The Model Arena suggests saving $127/mo by switching one skill to a cheaper model with no quality loss.
13
Product intel from user conversations
The admin UI aggregates what your customers are asking. This is product intelligence gold:
Admin UI → Session Analytics → Common Questions
Most common question patterns (last 30 days)
1.
"What's the status of case X?"
3,420
↑ 12%
2.
"What should I focus on today?"
2,810
→ flat
3.
"Summarize this case for an executive"
1,950
↑ 34%
4.
"Why is this SLA about to breach?"
1,240
→ flat
5.
"Can you draft a response to the customer?"
980
NEW
6.
"Show me cases assigned to [person]"
870
↓ 8%
7.
"What are the trends in case volume?"
640
↑ 22%
Emerging requests (agent couldn't answer well)
⚠"Can you draft a response to the customer?" — 980 attempts, 42% ended with user rephrasing. The agent can read cases but doesn't have a draft-response skill. Consider building one.
⚠"What are the trends in case volume?" — 640 attempts. Agent queries /metrics/summary but users want week-over-week charts. Consider adding a trend analysis skill or a chart widget.
Product roadmap from AI conversations
Your customers are literally telling you what features to build next. "Draft a response" is the #5 request — that's a write skill you can ship in a day. "Case volume trends" is #7 — that's a chart widget or a new API endpoint. This is live product discovery, not a survey.
14
Skill quality and eval scores
Is the agent actually answering correctly? The eval dashboard tracks quality per skill across all tenants:
Admin UI → Evals → case-triage
94%
Overall accuracy
97%
SLA breach detection
88%
Priority ordering
Accuracy trend (last 8 weeks)
Week 1 (84%)Week 4 (91%)Week 8 (94%)
Regression alert
Priority ordering dropped from 91% to 88% after skill update on March 15 (commit a3f8d2e: "Updated SLA thresholds"). The change broadened P2 criteria, causing some P3 cases to get over-prioritized.
Accuracy improves from 84% in week 1 to 94% in week 8 as the agent learns and the skill gets refined. When a regression happens (priority ordering drops after a skill edit), the eval dashboard catches it, links to the commit, and offers a one-click rollback.
15
Skill improvement suggestions
The platform aggregates patterns across all tenants and suggests skill improvements:
Admin UI → Skill Insights → case-triage
Suggested improvement · High confidence
"Add a check for cases that have been reopened >2 times."
Across 1,000 tenants, cases reopened 3+ times have a 4x longer resolution time. 68 tenants have at least one such case this month. The skill currently doesn't flag reopened cases.
Suggested improvement · Medium confidence
"Distinguish between SLA breach risk and actual breach."
32% of users follow up on "approaching SLA breach" flags to ask "has it actually breached?" The skill should separate "at risk (80%+)" from "breached (100%)."
New skill opportunity
"Customer response drafting"
980 attempts last month to draft customer responses. Currently handled ad-hoc by the agent. A dedicated skill with templates, tone guidelines, and auto-include of case context would improve quality from ~60% user acceptance to an estimated ~85%.
The product flywheel
The platform watches how 1,000 customers use the agent and surfaces patterns you couldn't see from any single tenant. Reopened cases are a pain point across 68 tenants. SLA messaging is confusing 32% of users. And 980 people are trying to draft responses with a skill that doesn't exist yet. Each insight is a product improvement you can ship in hours (it's just markdown). Your AI feature gets better every week, driven by real usage data across your entire customer base.
16
The ops dashboard: everything at a glance
Admin UI → Overview → CaseFlow AI
1,000
Tenants active
482
Sessions today
2.8s
Avg response
$28.40
Cost today
94%
Eval score
Skills
case-triage 94%
case-summary 91%
response-draft (new, no eval yet)
Deployments
deploy-a3f8d2e ● Live
deploy-b1c4e7f 3hr ago
deploy-c9d2f1a yesterday
Action items
2 skill suggestions pending
1 regression alert (priority ordering)
1 model swap recommendation
Tenant usage heatmap (last 7 days)
... (showing 50 of 1,000)
No sessions
Low
Medium
High
One screen. 1,000 tenants. You see health, costs, quality, deployments, and action items. The heatmap shows which tenants are actually using the AI feature (adoption tracking). The action items tell you exactly what to do next: apply the skill suggestions, investigate the regression, accept the model swap to save $127/month.
What you shipped
1
agent definition
1,000
isolated tenants
10
lines of React
0
ML engineers hired
You wrote
What it does
5 connection files
API surface, access rules, entities, best practices for your CaseFlow API
1 skill file
Case triage methodology: SLA priority, aging checks, assignment audit
1 config file
Model selection, user context endpoint
10 lines of React
@amodalai/react chat widget, white-labeled as "CaseFlow AI"
1 API endpoint
User context (name, role, permissions) — your API serves this
Your board gets their AI story. Your customers get a chat interface that actually understands their cases. Your engineering team spent a week, not a year. And the system gets smarter for each customer individually, every day.
The ISV advantage
This is the B2B2B play. You sell CaseFlow. Amodal makes CaseFlow smarter. Your customers never see Amodal. They see "CaseFlow AI" getting better at their specific workflow every week. That's your competitive moat, not ours.
Amodal is an open-source agent runtime with multi-tenant support for ISVs.