Tutorial: Customer support flow
Build a flow that classifies an inbound customer message, retrieves relevant knowledge-base docs, generates a response, and routes low-confidence responses to a human reviewer.
The shape#
Steps#
1. Start from the example#
In the toolbar, click Catalog… → Examples tab → Customer Support → Open. A pre-built flow is loaded with a fresh id. Use this as the base; below is what each node is for.
2. Inspect the API Entry#
out_amount port (yes, an example field) wires into the classifier. The entry's config is {method: POST, path: /}. Invocations look like POST .../invoke with {"input": {"message": "..."}}.
3. Configure the classifier#
node_classify is a Flexible Prompt. Its config:
- Goal:
Classify the customer's intent and urgency. Return JSON with intent, urgency, confidence, and entities. - Output schema:jsonc
{ "intent": "enum[question, complaint, request, feedback]", "urgency": "enum[low, medium, high]", "confidence": "float", "entities": "map<string, string>" } - Model role:
fast(cheap classification model from the registry).
4. KB retrieval#
node_kb_search is a Tool Plugin call:
- Plugin:
scaidrive - Method:
search - Args:jsonc
{ "path": "/knowledge/support/", "query": "{{message.text}}" }
The compiler auto-adds scaidrive to the flow's plugin list. The result is bound to a variable for the next step to reference.
5. Generate the response#
node_respond is a Guarded Prompt:
- Goal:
Generate a response grounded in the retrieved docs. Cite sources. - Guard:
kb_results.length > 0— don't hallucinate when there are no docs. - Validate:
result.citations.length > 0— refuse responses without citations. - Model role:
primary(the smart model).
6. Branch on confidence#
node_decision is a Decision node, style if:
- Subject hint:
confidence(optional, fills in placeholder text on the branch conditions). - Two outgoing conditional edges:
confidence > 0.7→ respond directly (sequential edge to wherever you want the response handed back).else(typically a sequential fallthrough) →node_review(HITL Review).
7. The HITL Review#
node_review is an HITL Review node. The fields you set:
- Scope: leave blank — inherits
supportfrom the flow's ScaiQueue topology. - Queue:
review. - Sections (via the Form Builder):
- Context section showing the original customer message + intent classification.
- Input section with the AI-generated response (editable).
- Decision section with
approve,reject,edit_and_approveoptions.
8. Flow-level config#
Confirm in the Flow properties panel:
- Models: two roles —
primary(smart) andfast(cheap). Picker reads from your tenant's ScaiGrid catalog. - ScaiQueue:jsonc
{ "scope": "support", "queues": [ { "slug": "review", "purpose": "review", "consumer_mode": "fifo" } ] } - Plugins:
scaidrive(auto-added by the compiler).
9. Deploy#
Click Deploy. Two things happen:
- The pre-deploy provisioning step ensures the
supportscope +reviewqueue exist in ScaiQueue (idempotent). - ScaiGrid creates the Core.
10. Test#
1 2 3 4 | |
For a low-confidence response, the invocation will pause at the HITL Review. Check the Live Runs panel: a "Pending breakpoints" bar shows the paused execution. Resolve via the ScaiQueue review UI (or POST /v1/scaicore/checkpoints/{id}/resolve).
What you learned#
- Plugins integrate via
tool_plugin— pure ScaiCore plugin_call, no special node kind per integration. - The
Guarded Promptpattern ofguard+validatemakes the response step refuse-rather-than-guess. - HITL Review compiles to a single
@checkpointwithhitl_target— no correlation thread, no daemon. - ScaiQueue topology declared once on the flow; per-node
scopeinherits.
Next#
- Expense approval with HITL — adds ScaiBunker for sandboxed policy checks.
- Multi-model flow — fast vs. smart model selection in depth.