Skip to content
Arrow left icon View all blogs 10 min read

How to Build AI Assistants That Query Live Data with Built-in Controls

Arrow down icon
How to Build AI Assistants That Query Live Data with Built-in Controls
How to Build AI Assistants That Query Live Data with Built-in Controls

TL;DR

  • This guide shows how to build a governed AI assistant on AISquared’s UNIFI platform that translates natural-language questions into live database queries. Using a movie dataset example, it walks through guardrails for topic scope, conditional routing, human-in-the-loop approval for sensitive data, Text-to-SQL execution, and LLM synthesis.
  • The same pattern applies to finance, healthcare, or government data, balancing direct access with full control.

Most enterprise data sits in databases. The challenge is not storing it, it is making it accessible in a safe and controlled way.

Natural language interfaces make it easy for users to ask questions. But without the right controls, they can also expose sensitive data, generate incorrect queries, or operate outside defined boundaries.

This guide shows how to build a governed AI assistant using AISquared’s UNIFI platform. The assistant translates user questions into live database queries, applies guardrails to keep responses in scope, and adds approval steps for sensitive requests.

The example uses a movie dataset, but the same pattern applies to real business systems: finance, operations, healthcare, or government data.

The goal is simple: give users direct access to data through AI, while keeping full control over what can be asked, what can be accessed, and how decisions are made.

Overview

This workflow builds a governed movie lookup assistant backed by a live database query. User input is first screened by a Guardrails node scoped to movie-related content — off-topic queries are rejected immediately. A Conditional node then evaluates the screened query: questions containing ‘box office’ are routed through a Human-in-the-Loop authorization gate before proceeding, while all other movie queries go directly to Text to SQL. The Text to SQL node translates the natural language question into a SQL query, executes it against the movie database, and returns the results. A Prompt node aggregates the query results with the original question and passes them to an LLM, which synthesizes a readable answer for the Chat Output.

Use case: A movie information assistant that answers questions from a live relational database — genres, directors, cast, ratings, and more — with box office revenue queries gated behind human reviewer sign-off to control exposure of commercially sensitive data.

Workflow Diagram

The diagram below shows the full node graph as configured in the UNIFI AI Workflows canvas.

Node Reference

This workflow uses eight nodes in a mostly linear sequence, with one branch point at the Conditional node. Both branches converge at the Text to SQL node.

CategoryNode NameRole
Input / OutputChat InputEntry point — receives the user’s movie question
ExecutionGuardrailsScope screen — enforces topic alignment; only movie-related queries pass; all others are rejected with an out-of-scope message
ExecutionConditionalRoutes box office queries to HITL for authorization; all other movie queries proceed directly to Text to SQL
ExecutionHuman in the LoopAuthorization gate for box office queries — Approve proceeds to Text to SQL; Reject returns a denial message
DataText to SQLTranslates the approved natural language question into SQL, executes it against the movie database, and returns Query Results, Generated SQL, and Schema
ModelPromptAggregates the original user question and Text to SQL query results into a structured prompt for the LLM
ModelLLMSynthesizes a natural language answer grounded in the query results
Input / OutputChat OutputReturns the LLM response to the user

Step 1 — Register Sources

Two sources must be registered in UNIFI before building the canvas: the movie database (used by Text to SQL) and the AI/ML model endpoint (used by both the Text to SQL node and the LLM node).

1.1  Movie Database Source

Sources → Add Data Source → PostgreSQL

FieldValue / Notes
HostHostname or IP of your PostgreSQL server
Port5432 (default)
DatabaseName of the movie database
SchemaSchema containing the movie tables (e.g. public)
UsernameMust have SELECT access on the movie tables
PasswordStored encrypted by UNIFI
Tip: The Text to SQL node auto-introspects the database schema at runtime — it reads table and column names to inform SQL generation. Verify that the connecting user has SELECT access on all tables you want the assistant to query.

1.2  AI/ML Source

Sources → AI/ML Sources → Add AI/ML Source

Register the LLM that powers both the Text to SQL node (for SQL generation) and the LLM node (for natural language synthesis). The same source can be used for both, or different providers can be selected per node.

FieldValue / Notes
ProviderAnthropic or OpenAI (any supported provider)
API KeyObtain from the provider’s console
HTTP Timeout30 seconds (default)
Request FormatSample request JSON for the selected provider and model
Response FormatSample response JSON — used to map the output field
Model InputsMap the dynamic message/content field as a model input
Model OutputsMap the response text field as the model output

Step 2 — Build the Canvas Workflow

In UNIFI: AI Workflows → New Workflow → open the canvas editor

2.1  Chat Input

  1. Add a Chat Input node as the workflow entry point
  2. Connect Chat Input → Message to Guardrails → input

2.2  Guardrails — Scope Screen

Category: Execution — enforces topic alignment to movie-related queries only

This Guardrails node is configured as a scope guard rather than a PII screen. Its purpose is to keep the assistant on-topic — only movie-related questions pass through. This prevents the Text to SQL node from generating queries against unintended tables or domains.

  1. Connect Chat Input → Message to Guardrails → input
  2. Configure scope rules — enable topic/relevance enforcement set to the movies domain; reject questions about unrelated subjects (sports, finance, medical, etc.)
  3. Connect Guardrails → Pass to Conditional → input
  4. Connect Guardrails → Fail to a Chat Output node with an out-of-scope message, e.g. ‘I can only answer questions about movies. Please ask about a film, director, genre, or cast.’
Guardrails Rule TypePurpose in This Workflow
Topic/Scope EnforcementRestricts queries to the movies domain — blocks off-topic questions before SQL generation
PII Detection (optional)Can also be enabled to prevent user personal data from being embedded in SQL queries
Important: Always wire the Guardrails Fail path. An unconnected Fail output results in a silent failure — the user receives no response. For a scope guard specifically, the Fail message should clearly tell the user what the assistant is designed to answer.

2.3  Conditional — Box Office Routing

The Conditional node checks whether the screened query mentions box office revenue or earnings. Box office data is commercially sensitive, so these queries are routed through Human-in-the-Loop before SQL is generated. All other movie queries proceed directly to Text to SQL.

OutputConditionDestination
Condition 1Input contains ‘box office’, ‘revenue’, ‘gross’, or ‘earnings’Human in the Loop → Input Text
Condition 2(optional) Input asks about ticket sales or financial performanceHuman in the Loop → Input Text
DefaultAll other movie queriesText to SQL → Question (bypasses HITL)
  1. Configure Condition 1: operator contains, value box office — add additional conditions for ‘revenue’, ‘gross’, ‘earnings’ if needed
  2. Set Default Input to pass so the query is forwarded unchanged on the Default path
  3. Connect Conditional → Condition 1 to Human in the Loop → Input Text
  4. Connect Conditional → Default to Text to SQL → Question
Tip: The Conditional conditions are evaluated in order — Condition 1 is checked first. If the query matches, it is routed to HITL regardless of other conditions. The Default path fires only when no condition matches, ensuring all box office queries are consistently captured.

2.4  Human in the Loop — Box Office Authorization

Category: Execution — pauses the workflow for a reviewer to authorize box office queries

Box office and revenue data is financially sensitive. The Human in the Loop node sends the query to a designated reviewer before the Text to SQL node is allowed to generate and execute a query against that data.

  1. Connect Conditional → Condition 1 to Human in the Loop → Input Text
  2. Configure reviewer assignment — specify which user(s) or role(s) receive the approval request
  3. Set a timeout policy — define behavior if no reviewer responds within the window (e.g. auto-reject after a set duration)
  4. Connect Human in the Loop → Approve to Text to SQL → Question — approved queries join the same path as general movie queries
  5. Connect Human in the Loop → Reject to a Chat Output node with a denial message, e.g. ‘Box office data access was not approved for this request.’
Important: Always wire both Approve and Reject. The Human in the Loop node pauses asynchronously — the user receives no response until a reviewer acts. Set clear expectations in the welcome message that box office queries require review and may take additional time.

2.5  Text to SQL Node

Category: Data — translates natural language into SQL and executes it against the movie database

The Text to SQL node connects to the movie database registered in Step 1.1. It auto-introspects the schema, generates a SQL SELECT query from the natural language input, executes it, and returns three outputs.

  1. Both Conditional → Default and Human in the Loop → Approve connect to Text to SQL → Question
  2. In the node configuration, select the movie database source registered in Step 1.1
  3. Select the AI/ML source registered in Step 1.2 — this model powers the SQL generation step
  4. The node will introspect the database schema automatically — verify the correct tables are visible
OutputDescription
Query ResultsThe rows returned by the executed SQL — passed to the Prompt node for LLM synthesis
Generated SQLThe SQL statement produced by the node — useful for debugging and audit logging
SchemaThe database schema as interpreted by the node — useful for debugging incorrect query generation
  1. Connect Text to SQL → Query Results to Prompt → Query Results
Tip: During development, wire the Generated SQL output to a secondary Chat Output to inspect the queries being produced. If the LLM’s final answer is wrong or incomplete, the Generated SQL is the fastest way to diagnose whether the query retrieved the right data.

2.6  Prompt Node

Category: Model — aggregates the user question and database results for the LLM

  1. Connect Chat Input → Message to Prompt → Input Message — the original question provides context for the LLM’s answer
  2. Connect Text to SQL → Query Results to Prompt → Query Results
  3. Write a prompt template that clearly structures both inputs:
You are a movie information assistant.Answer the user’s question using only the database results below.If the results are empty or insufficient, say so explicitly.
User question: {{Input Message}}
Database results:{{Query Results}}
  1. Connect Prompt → Rendered Prompt Output to LLM → Input Message

2.7  LLM Node

Category: Model — synthesizes the final natural language response

  1. Connect Prompt → Rendered Prompt Output to LLM → Input Message
  2. Select the AI/ML source registered in Step 1.2
  3. Connect LLM → Response to Chat Output → Text

2.8  Chat Output Node

  1. Add a Chat Output node and connect LLM → Response to its Text input
  2. Ensure all failure/rejection paths are also wired to Chat Output nodes:
Failure PathSuggested Message
Guardrails → Fail‘I can only answer questions about movies. Please ask about a film, director, genre, or cast.’
Human in the Loop → Reject‘Box office data access was not approved for this request.’
Conditional → Default (if needed)Only if Default is used as a second rejection path rather than forwarding to Text to SQL

Pipeline Flow Reference

The table below maps every connection. Both branches of the Conditional (Default and HITL Approve) converge at Text to SQL. Chat Input → Message is also forwarded directly to Prompt → Input Message so the original question is available for the final LLM synthesis.

FromToData / Notes
Chat Input → MessageGuardrails → inputRaw user question
Chat Input → MessagePrompt → Input MessageOriginal question carried forward for LLM context
Guardrails → PassConditional → inputScope-verified movie query
Guardrails → FailChat Output (out-of-scope)Non-movie query — rejected before any SQL generation
Conditional → Condition 1Human in the Loop → Input TextBox office / revenue query — requires authorization
Conditional → DefaultText to SQL → QuestionGeneral movie query — proceeds directly
Human in the Loop → ApproveText to SQL → QuestionAuthorized box office query joins general query path
Human in the Loop → RejectChat Output (HITL rejection)Reviewer denied — no SQL generated
Text to SQL → Query ResultsPrompt → Query ResultsDatabase rows returned by generated SQL
Prompt → Rendered Prompt OutputLLM → Input MessageAggregated prompt: question + query results
LLM → ResponseChat Output → TextFinal natural language answer

Step 3 — Test in the Playground

Test CaseSample InputExpected Behavior
General movie query‘Who directed Inception?’Guardrails pass → Conditional Default → Text to SQL generates and runs query → Prompt → LLM → Chat Output
Genre query‘List all sci-fi movies in the database’Guardrails pass → Conditional Default → Text to SQL queries genre column → LLM synthesizes list
Box office (approved)‘What was the box office revenue for Avatar?’Conditional → Condition 1 → HITL → Reviewer approves → Text to SQL → Prompt → LLM → Chat Output
Box office (rejected)‘What was the box office revenue for Avatar?’Conditional → Condition 1 → HITL → Reviewer rejects → denial Chat Output; no SQL generated
Out-of-scope query‘What is the score of tonight’s game?’Guardrails → Fail → out-of-scope Chat Output; Conditional and Text to SQL never reached
Empty resultsQuery about a film not in the databaseText to SQL returns empty rows; verify LLM Prompt template handles empty Query Results without hallucinating
Generated SQL checkAny query during developmentWire Generated SQL to secondary Chat Output to inspect the produced query and debug mismatch between question and results
Tip: Test the empty results case specifically — a well-written Prompt template should instruct the LLM to say ‘No results found for that query’ rather than speculating. If the LLM invents movie data, tighten the template with an explicit instruction not to answer beyond the provided database results.

Step 4 — Configure Interface and Export

4.1  Interface Settings

SettingRecommended Value
Assistant Name‘Movie Lookup’ or your preferred display name
Feedback OptionsEnable thumbs up/down for query quality tracking
Welcome Messagee.g. ‘Ask me anything about movies in our database — directors, cast, genres, ratings, and more. Box office queries require reviewer approval.’
Placeholder Texte.g. ‘Ask about a movie, director, genre, or cast…’

4.2  Save, Export, and Embed

Click Save, then Export or Embed to generate the embeddable assistant snippet. Copy the dataAppId and dataAppUseCaseId from the export panel and insert them into the HTML template below:

<html>
<body>    <h2>Movie Lookup</h2>    <div id=”movie-lookup-container”></div></body>
<script src=”https://api.squared.ai/enterprise/api/v1/data_apps_runner.js”></script><script>  if (window.DataApp) {    const dataApp = new window.DataApp({      dataAppId: ‘0’,      dataAppUseCaseId: ‘YOUR_USE_CASE_ID_HERE’    });    dataApp.runDataApp();  }</script>
</html>
FieldDescription
dataAppIdNumeric Data App ID from the UNIFI export panel
dataAppUseCaseIdUnique use case ID string from the UNIFI export panel — replace ‘YOUR_USE_CASE_ID_HERE’
data_apps_runner.jsSelf-contained UNIFI script — includes rendering, data fetching, and authentication. No additional dependencies needed.
<div id=”…”>Widget mount point — place anywhere in the page body; the chat UI renders inside this element
Tip: The embed snippet always connects to the latest published version of the workflow. Updating guardrail rules, the prompt template, or reviewer assignments in UNIFI does not require changing the HTML embed code.

Quick Reference — Workflow Summary

StepActionKey Detail
1aAdd movie DB sourceSources → PostgreSQL; host, port, database, schema, username, password; SELECT access required
1bAdd AI/ML sourceSources → AI/ML Sources; provider, API key, request/response format, model inputs/outputs
2aChat InputEntry point; Message → Guardrails AND Prompt (original question needed for LLM context)
2bGuardrails (scope)Topic enforcement — movies only; Pass → Conditional; Fail → out-of-scope output; describe scope clearly in Fail message
2cConditionalCondition 1 (box office/revenue) → HITL; Default (all other movie queries) → Text to SQL directly
2dHuman in the LoopBox office authorization; Approve → Text to SQL; Reject → denial output; configure reviewer + timeout; wire both paths
2eText to SQLSelect movie DB source + AI/ML source; auto-introspects schema; Query Results → Prompt; wire Generated SQL during dev
2fPrompt + LLMInput Message (from Chat Input) + Query Results → Prompt template; Rendered Prompt → LLM → Response → Chat Output
3Test 7 casesGeneral query, genre query, box office approved, box office rejected, out-of-scope, empty results, Generated SQL inspection
4Configure + Export + EmbedInterface Settings (name, feedback, welcome message) → Save → Export → copy IDs → HTML embed template → deploy

Measure Your AI Readiness

See where your organization stands today across data, security, governance, workflows, adoption, and improvement.