πŸ’³ Introducing Flexible Pay|
    Back to the Series
    Agentic AI Systems 18 min read Issue 14

    How We Built a Governed Conversational Analytics Multi-Agent System

    A simple chat interface on the surface. Behind it: metric governance, SQL generation, three layers of validation, data-quality gates, analytical routing, machine learning, evaluation, and human oversight.

    TA
    Tobe Awo
    Data Techcon Technical Series Β· AI Engineering & Technical AI Governance

    The first multi-agent system I built was at Google. At first glance, the product looked simple. A user opened a chat interface and asked a business question.

    They could ask:

    • β†’What was revenue last month?
    • β†’Why did paid subscriptions decline?
    • β†’Which customer segments contributed most to growth?
    • β†’Which customers are likely to churn?
    • β†’What will revenue be next quarter?
    • β†’Can you build a churn prediction model?

    The user did not need to upload a dataset, write SQL, identify a table, or select a machine-learning algorithm. The system was expected to determine what data was required, retrieve it from BigQuery, validate it, analyze it, and return an understandable answer.

    But behind that simple interface was a complex, governed analytics workflow.

    This was not just an exploratory data analysis tool. It was a conversational analytics and machine-learning system that combined natural-language understanding, metric governance, SQL generation, query validation, data-quality controls, analytical execution, machine learning, evaluation, and human oversight.

    The problem

    The Core Problem

    Business users often know the question they want answered, but they do not always know:

    • β†’which table contains the data;
    • β†’how the metric is officially defined;
    • β†’which joins are approved;
    • β†’what filters must be applied;
    • β†’which comparison period is appropriate;
    • β†’whether the request requires descriptive analytics, diagnostic analysis, forecasting, or machine learning.

    For example, a user may ask:

    Why did paid subscriptions decline last month?

    That question sounds straightforward, but the system must resolve several details before producing an answer.

    Ambiguity the system must resolve
    β†’What qualifies as a paid subscription?
    β†’Should trials be excluded?
    β†’Does β€œlast month” mean calendar month or the most recent 30 days?
    β†’Should subscriptions be measured using account IDs, subscription IDs, or successful payment transactions?
    β†’Should the comparison be month over month or year over year?
    β†’Which dimensions should be evaluated to explain the decline?

    A general-purpose language model could make assumptions about these questions. In an enterprise analytics environment, however, assumptions can produce incorrect business decisions.

    The system therefore needed governance before generation.

    Architecture

    The End-to-End Workflow

    The final architecture followed this general flow:

    User question
    ↓
    Authentication and authorization
    ↓
    Intake and intent classification
    ↓
    Metric and semantic-layer retrieval
    ↓
    SQL generation
    ↓
    SQL validation
    ↓
    BigQuery dry run
    ↓
    Query execution
    ↓
    Returned-data validation
    ↓
    Intent-based analytical routing
    β”œβ”€β”€ Descriptive analytics
    β”œβ”€β”€ Diagnostic analytics
    β”œβ”€β”€ Exploratory data analysis
    β”œβ”€β”€ Forecasting
    └── Machine learning
    ↓
    Answer generation
    ↓
    Evaluation, monitoring and human review

    Each stage had a clearly defined responsibility.

    That separation became especially important after the first version exposed weaknesses in answer quality, hallucination, query reliability, and latency.

    Design decision

    Intake Agent Versus Orchestrator

    One of the most important design decisions was separating the intake agent from the orchestrator. They were not the same component.

    Interpretation Β· 01
    The Intake Agent

    The intake agent interpreted the user’s request. For a question such as β€œWhy did paid subscriptions decline last month?” the intake agent extracted:

    • β†’user intent;
    • β†’primary metric;
    • β†’requested date range;
    • β†’comparison period;
    • β†’dimensions;
    • β†’filters;
    • β†’business context;
    • β†’potential ambiguity;
    • β†’requested output type.

    It also classified the task. Examples included:

    • β†’β€œWhat was revenue last month?” β€” descriptive analytics
    • β†’β€œWhy did revenue decline?” β€” diagnostic analytics
    • β†’β€œWhich customers are likely to churn?” β€” predictive machine learning
    • β†’β€œWhat will revenue be next quarter?” β€” forecasting
    • β†’β€œBuild a churn model.” β€” supervised model-development workflow

    The output of the intake agent was structured rather than conversational. For example:

    {
      "intent": "diagnostic_analysis",
      "metric": "paid_subscriptions",
      "date_range": {
        "current_period": "previous_calendar_month",
        "comparison_period": "month_before_previous"
      },
      "dimensions": [
        "country",
        "acquisition_channel",
        "subscription_plan"
      ],
      "filters": [],
      "requires_clarification": false
    }

    The intake agent did not decide every downstream action. It understood and structured the request.

    Control plane Β· 02
    The Orchestrator

    The orchestrator managed workflow execution. Its responsibilities included:

    • β†’deciding which component ran next;
    • β†’passing approved state between stages;
    • β†’checking whether validation succeeded;
    • β†’triggering retries;
    • β†’stopping invalid workflows;
    • β†’requesting user clarification;
    • β†’enforcing human-review requirements;
    • β†’preventing agents from bypassing controls.

    We implemented the orchestrator primarily as deterministic workflow logic rather than as a completely autonomous AI agent. The AI could classify the request and recommend an analytical route. The application decided whether that route was permitted.

    For example:

    If the metric definition cannot be found: stop and request clarification If SQL validation fails: return the query for one controlled revision If the BigQuery dry run exceeds the cost threshold: request a narrower query or approval If returned data fails quality validation: stop analysis and revise the query If the request involves model deployment: require human review

    This distinction mattered because a free-thinking supervisor agent could skip steps, repeat work, create unnecessary model calls, or route a request directly into analysis before the data had been validated.

    The orchestrator acted as the control plane.

    Governance

    Metric Governance and the Semantic Layer

    Before generating SQL, the system retrieved approved business definitions. The language model was not allowed to invent the meaning of a metric.

    For example, the approved definition of paid subscriptions could include:

    Count distinct subscription IDs where subscription status is active, trial status is false, and payment status is paid.
    The semantic layer stored information such as
    • β†’official metric name;
    • β†’metric description;
    • β†’approved calculation;
    • β†’required filters;
    • β†’source tables;
    • β†’approved joins;
    • β†’time-column definitions;
    • β†’dimension mappings;
    • β†’data owner;
    • β†’data freshness expectations;
    • β†’access restrictions.

    A structured metric definition drove SQL generation directly. For example, the generated query could look like this:

    SELECT
      DATE_TRUNC(subscription_date, MONTH) AS subscription_month,
      country,
      acquisition_channel,
      COUNT(DISTINCT subscription_id) AS paid_subscriptions
    FROM `project.analytics.fact_subscriptions`
    WHERE subscription_status = 'active'
      AND is_trial = FALSE
      AND payment_status = 'paid'
      AND subscription_date BETWEEN @start_date AND @end_date
    GROUP BY 1, 2, 3
    ORDER BY 1, 2, 3;

    The SQL generation agent did not have permission to execute the query directly.

    This was intentional.

    The component creating the query was not allowed to be the only component deciding whether the query was correct or safe.

    Validation

    Three-Layer SQL Validation

    We validated SQL using three complementary approaches:

    1. deterministic validation scripts;
    2. LLM-based semantic validation;
    3. human evaluation.

    Each layer caught a different class of failure.

    Rules in code Β· 01
    Deterministic SQL Validation

    Deterministic scripts checked rules that could be enforced reliably in code. These checks included:

    • β†’valid SQL syntax;
    • β†’allowed statement types;
    • β†’approved datasets and tables;
    • β†’prohibited operations;
    • β†’presence of date filters;
    • β†’required metric filters;
    • β†’approved join paths;
    • β†’restricted columns;
    • β†’use of query parameters;
    • β†’row-level access requirements;
    • β†’prohibition of SELECT *;
    • β†’query-size limits;
    • β†’estimated bytes processed;
    • β†’timeout and cost thresholds.

    The system also performed a BigQuery dry run before execution. The dry run helped estimate query cost and identify query errors without processing the full dataset.

    Deterministic validation was appropriate for controls that should not depend on probabilistic reasoning. For example, an LLM should not be responsible for deciding whether a DELETE, UPDATE, or unapproved table reference is permitted. Those rules belong in code.

    Semantic alignment Β· 02
    LLM-Based Semantic Validation

    A query can be syntactically valid and still answer the wrong question. The LLM validation layer examined whether the generated SQL matched:

    • β†’the user’s intent;
    • β†’the approved metric definition;
    • β†’the requested date range;
    • β†’the comparison period;
    • β†’the expected dimensions;
    • β†’the analytical granularity.

    For example, the LLM validator could detect that:

    • β†’the query calculated total subscriptions rather than paid subscriptions;
    • β†’trials were not excluded;
    • β†’the date comparison used 30 days rather than calendar months;
    • β†’the query grouped by country but omitted acquisition channel;
    • β†’the query answered β€œwhat changed” but not β€œwhy it changed.”

    The LLM validator returned a structured decision:

    {
      "status": "failed",
      "issues": [
        {
          "type": "metric_mismatch",
          "description": "The query does not exclude trial subscriptions."
        },
        {
          "type": "date_mismatch",
          "description": "The query uses rolling 30-day periods instead of calendar months."
        }
      ],
      "approved_for_execution": false
    }
    Human in the loop Β· 03
    Human Validation

    Human reviewers evaluated SQL and answers against known business questions and expected results. The review process included:

    • β†’predefined test questions;
    • β†’approved reference queries;
    • β†’known metric outputs;
    • β†’edge cases;
    • β†’ambiguous requests;
    • β†’complex joins;
    • β†’incomplete data scenarios;
    • β†’questions that should trigger clarification.

    Human review was especially important during early development because it exposed failure patterns that automated evaluations did not yet capture. For example, a response could contain technically correct SQL but still be misleading because the analytical interpretation overstated causality.

    Human evaluation helped us assess the full user experience, not just SQL correctness.

    Execution

    Query Execution and Data Retrieval

    After the SQL passed validation, the application executed the query through a controlled BigQuery service account.

    The execution layer applied:

    • β†’scoped credentials;
    • β†’read-only permissions;
    • β†’dataset allowlists;
    • β†’timeouts;
    • β†’scan limits;
    • β†’row limits;
    • β†’logging;
    • β†’query identifiers;
    • β†’user-level access checks.

    Agents did not receive unrestricted warehouse credentials. They interacted with approved tools such as:

    get_metric_definition()
    get_table_schema()
    validate_sql()
    estimate_query_cost()
    execute_bigquery_query()

    This tool-based design reduced risk and made each action auditable.

    Data quality

    Returned-Data Validation

    Successful query execution did not mean the data was ready for analysis.

    The returned dataset was validated before entering the EDA or modeling workflow.

    The data-validation layer checked
    • β†’whether any rows were returned;
    • β†’required columns;
    • β†’expected data types;
    • β†’date coverage;
    • β†’freshness;
    • β†’missing values;
    • β†’duplicate keys;
    • β†’impossible values;
    • β†’volume anomalies;
    • β†’join duplication;
    • β†’metric reconciliation;
    • β†’granularity;
    • β†’class balance;
    • β†’target availability;
    • β†’potential data leakage.

    For example:

    {
      "status": "passed_with_warnings",
      "row_count": 1864,
      "date_coverage": {
        "minimum": "2026-05-01",
        "maximum": "2026-06-30"
      },
      "warnings": [
        "Acquisition channel is missing for 4.8% of rows.",
        "One regional source is 18 hours behind the expected refresh time."
      ],
      "blocking_issues": [],
      "approved_for_analysis": true
    }

    This stage addressed an important reality:

    A query can be valid while the returned data is still incomplete, stale, duplicated, or inappropriate for modeling.

    Routing

    Routing Into Analytics, EDA or Machine Learning

    Once the dataset passed validation, the orchestrator routed it based on the original request.

    Descriptive Analytics

    What was revenue last month?

    The system calculated:

    • β†’totals;
    • β†’averages;
    • β†’counts;
    • β†’rates;
    • β†’trends;
    • β†’period-over-period changes.
    Diagnostic Analytics

    Why did subscriptions decline?

    The system examined:

    • β†’segment contributions;
    • β†’country-level changes;
    • β†’acquisition-channel changes;
    • β†’plan-level changes;
    • β†’shifts in customer mix;
    • β†’statistically significant deviations;
    • β†’correlated business drivers.
    The system was careful not to present correlation as confirmed causation.
    Exploratory Data Analysis

    For an EDA request, the workflow evaluated:

    • β†’distributions;
    • β†’missingness;
    • β†’duplicates;
    • β†’outliers;
    • β†’correlations;
    • β†’cardinality;
    • β†’target relationships;
    • β†’temporal patterns;
    • β†’class imbalance;
    • β†’potential leakage.
    Forecasting

    For forecasting requests, the system validated:

    • β†’time granularity;
    • β†’historical coverage;
    • β†’missing periods;
    • β†’seasonality;
    • β†’trend stability;
    • β†’external-event considerations.
    It then routed the dataset into approved forecasting functions and compared candidate approaches.
    Machine Learning

    For supervised machine-learning requests, the workflow included:

    • β†’target validation;
    • β†’leakage checks;
    • β†’train-validation-test splitting;
    • β†’preprocessing;
    • β†’baseline creation;
    • β†’candidate model training;
    • β†’cross-validation;
    • β†’error analysis;
    • β†’explainability;
    • β†’model recommendation.
    The LLM helped determine which analysis was appropriate and explained the findings. Deterministic Python code performed the statistical calculations, preprocessing, training, and evaluation.
    Lessons

    What Went Wrong in V1

    Our first version demonstrated the potential of the system, but it also revealed several weaknesses. Only about 60% of answers consistently met our internal quality bar.

    The most common issues included:

    • β†’hallucinated metric definitions;
    • β†’incorrect table selection;
    • β†’invalid or incomplete SQL;
    • β†’missing filters;
    • β†’incorrect date interpretation;
    • β†’unsupported causal claims;
    • β†’analysis based on incomplete data;
    • β†’repeated agent calls;
    • β†’long response times;
    • β†’inconsistent answer formatting.

    The initial architecture gave too much freedom to the model. Some agents received overly broad prompts. Some responsibilities overlapped. Agents occasionally reinterpreted decisions that had already been made upstream. In some cases, the system generated SQL, executed it, and interpreted the results without enough independent validation between stages.

    We also learned that adding more agents could increase latency without improving quality. Every additional agent introduced:

    • β†’another model call;
    • β†’another prompt;
    • β†’additional state;
    • β†’more potential failure points;
    • β†’more opportunities for conflicting conclusions.

    The goal therefore became controlled specialization, not maximum agent count.

    Improvements

    How We Improved Answer Quality

    We introduced several changes.

    Change 01
    Structured Inputs and Outputs

    Agents stopped passing long unstructured narratives to one another. Instead, they exchanged typed objects containing:

    • β†’intent;
    • β†’metric;
    • β†’dimensions;
    • β†’filters;
    • β†’date range;
    • β†’query;
    • β†’validation status;
    • β†’warnings;
    • β†’data profile;
    • β†’analytical result.
    Change 02
    Deterministic Orchestration

    The orchestrator enforced allowed workflow transitions. Agents could no longer bypass validation stages. The workflow knew exactly what should happen when:

    • β†’a metric was unavailable;
    • β†’SQL validation failed;
    • β†’a query exceeded the cost limit;
    • β†’data was incomplete;
    • β†’user clarification was required;
    • β†’human review was mandatory.
    Change 03
    Metric Grounding

    Metric definitions were retrieved from approved sources instead of being generated from model memory. This reduced inconsistent calculations and hallucinated business logic.

    Change 04
    Independent SQL Validation

    We separated SQL generation from SQL approval. Deterministic scripts handled security and rule-based checks. An LLM handled semantic alignment. Human evaluators reviewed representative queries and answers.

    Change 05
    Data-Quality Gates

    Returned data had to meet defined quality requirements before analysis could proceed. This prevented polished explanations from being generated from incomplete or unreliable data.

    Change 06
    Evaluation Datasets

    We created representative evaluation sets containing:

    • β†’straightforward questions;
    • β†’ambiguous questions;
    • β†’questions requiring clarification;
    • β†’complex metric calculations;
    • β†’multi-table joins;
    • β†’edge cases;
    • β†’unsupported requests;
    • β†’machine-learning requests.
    Change 07
    Reduced Unnecessary Agent Calls

    We removed agents that did not provide meaningful independent value. Some tasks were converted into deterministic functions. Some tasks were performed in parallel. Others were skipped when the required result was already available in the shared state.

    Change 08
    Controlled Retries

    The system did not retry indefinitely. For example, a failed SQL query could receive one or two controlled revisions. After that, the workflow stopped or requested human intervention. This reduced latency and prevented expensive retry loops.

    Structured state reduced interpretation drift between agents.

    Results

    Results

    60%
    V1 answer quality against internal criteria
    85%
    Post-governance answer quality
    ↓
    Materially reduced hallucinations

    After introducing stronger governance, validation, routing, and evaluation, answer quality improved from approximately 60% to roughly 85% against our internal quality criteria. We also materially reduced hallucinations.

    Latency improved because the system made fewer unnecessary model calls, reused structured context, and moved deterministic work out of the LLM layer. The exact architecture was less important than the principle behind it: AI handled interpretation, planning, and explanation. Deterministic software handled access, policy enforcement, validation, execution, and workflow control. Humans remained responsible for evaluating critical outputs and approving high-impact use cases.

    Trade-offs

    Key Trade-Offs

    More Agents Versus Fewer Agents
    More agents can provide
    • β†’specialization;
    • β†’clearer ownership;
    • β†’better traceability;
    • β†’easier testing;
    • β†’better fault isolation.
    But they also create
    • β†’higher cost;
    • β†’greater latency;
    • β†’more state-management complexity;
    • β†’more failure points;
    • β†’more conflicting outputs.

    We learned not to create an agent for every small task. A component should become an agent only when it requires distinct reasoning, context, tools, or evaluation.

    AI Orchestration Versus Deterministic Orchestration

    An AI supervisor can support flexible routing. However, fully autonomous routing is harder to test and govern. We chose a hybrid design. AI interpreted the user’s request. Deterministic code enforced the permitted workflow.

    LLM Validation Versus Rule-Based Validation
    LLMs are useful for semantic questions
    • β†’Does this SQL answer the user’s question?
    • β†’Does the query align with the approved metric definition?
    • β†’Is the explanation supported by the result?
    Deterministic scripts are better for enforceable controls
    • β†’Is the query read-only?
    • β†’Does it reference an approved table?
    • β†’Is a date filter present?
    • β†’Does the query exceed the scan limit?
    • β†’Is a restricted column included?

    The strongest system used both.

    Accuracy Versus Latency

    Additional validation improved reliability but added processing time. We reduced the impact by:

    • β†’running independent checks in parallel;
    • β†’caching metric definitions and schemas;
    • β†’using smaller models for classification;
    • β†’limiting query revisions;
    • β†’avoiding repeated context;
    • β†’moving calculations into BigQuery and Python.
    Automation Versus Human Oversight

    The system automated a significant portion of analytics work. It did not eliminate human responsibility. Human review remained important for:

    • β†’metric-definition changes;
    • β†’high-impact business decisions;
    • β†’sensitive data use;
    • β†’model-deployment approval;
    • β†’causal interpretation;
    • β†’new analytical workflows;
    • β†’evaluation of unexpected outputs.
    Takeaway

    The Broader Lesson

    A multi-agent system is not simply several prompts connected together.

    A production system requires:

    • β†’clear responsibilities;
    • β†’governed context;
    • β†’typed state;
    • β†’deterministic orchestration;
    • β†’restricted tools;
    • β†’independent validation;
    • β†’data-quality gates;
    • β†’evaluation datasets;
    • β†’observability;
    • β†’human oversight.

    The most important architecture decision was not how many agents we used. It was deciding which responsibilities belonged to AI and which belonged to traditional software.

    The AI layer was best used for
    • β†’understanding intent;
    • β†’resolving language;
    • β†’planning analysis;
    • β†’interpreting results;
    • β†’explaining findings.
    The deterministic layer was best used for
    • β†’authentication;
    • β†’authorization;
    • β†’SQL policy enforcement;
    • β†’query execution;
    • β†’data validation;
    • β†’cost controls;
    • β†’state transitions;
    • β†’audit logging.

    That separation helped move the system from an impressive prototype to a more reliable analytics product.

    And that remains one of my biggest lessons from building multi-agent systems:

    The intelligence does not come only from the model. It comes from the architecture surrounding the model.


    About the Author. Tobe Awosanya is a Technical Founder and AI Product & Governance Leader working across AI engineering, agentic systems, AI evaluation, and technical AI governance. Her work focuses on translating AI product and governance requirements into practical system, control, and implementation decisions for teams building and adopting AI systems.

    Considering Building a Multi-Agent System?

    Multi-agent systems can look impressive in a demo and still fail in production because of weak orchestration, poor validation, unnecessary agent complexity, rising model costs, latency, and hallucinated outputs.

    Through Data Techcon AI Advisory, I help founders and teams design practical multi-agent architectures that are easier to govern, evaluate, and scale.

    An advisory session can help you
    • β†’determine whether your use case actually needs multiple agents;
    • β†’define the right agent responsibilities and workflow;
    • β†’separate AI reasoning from deterministic application logic;
    • β†’design validation, guardrails, evaluation, and human-review controls;
    • β†’choose the appropriate models, tools, data architecture, and orchestration framework;
    • β†’identify cost, latency, security, and reliability risks before development begins.

    Whether you are validating an early idea, reviewing an existing architecture, or preparing to move a prototype into production, you can book an advisory session to get expert guidance tailored to your product and use case.

    Book an Advisory Session

    πŸͺ We value your privacy

    We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies. Read our Privacy Policy to learn more.