AboutProjectsServicesContact
Back to Projects

BizComp Intelligence

AI-Powered Conversational Agent for Belgian Company Analysis

Overview

BizComp Intelligence is the AI layer built on top of the Bizcomp data platform. It introduces a conversational agent that lets users explore Belgian company data through natural language. Instead of navigating dashboards manually, users ask questions like 'Show me the financials of Colruyt' or 'Compare Delhaize and Carrefour' and the system autonomously classifies intent, resolves entities, orchestrates tool calls, and composes a rich dashboard response — all in real time via streaming.

Agent Architecture

The agent follows a multi-stage pipeline: an LLM-powered intent classifier determines what the user wants, an entity resolver maps company names to official enterprise numbers, a query planner selects which tools to invoke, and a fallback loop executes tool calls with retry logic. Finally, a layout composer assembles the response into a structured dashboard with summary text, widgets, and suggested follow-up actions. The entire pipeline supports abort propagation, request budgets, and optimistic session concurrency.

1
User Query
Natural language input
2
Intent Classifier
LLM-powered, 12 intent types
3
Entity Resolver
BCE lookup, speculative parallel
4
Query Planner
Tool selection & orchestration
5
Tool Executor
Parallel calls with retry & abort
6
Layout Composer
Dashboard assembly + suggestions
7
Streaming Response
SSE to client
Each stage supports abort propagation & request budget enforcement

Core Capabilities

  • Natural language queries with intent classification across 12 intent types including financials, risk analysis, company overview, sector analysis, and multi-company comparison
  • Multi-tool orchestration with parallel execution — the agent can invoke get_company_card, get_financials, get_risk_flags, search_companies, and more in a single turn
  • Real-time streaming responses via Server-Sent Events, delivering partial results as each pipeline stage completes
  • Deterministic dashboard composition for standard intents, bypassing the LLM composer for speed when the intent is unambiguous
  • Session persistence with optimistic concurrency on PostgreSQL — concurrent requests to the same session are safely merged without last-write-wins
  • Anonymous access protections: IP-based rate limiting, per-client concurrency caps, message quotas, and load shedding based on LLM queue depth
  • Multi-language support (French, Dutch, English) with locale-aware suggested actions and localized dashboard content
  • Interactive widgets: financial trend charts with toggle legends, company comparison dashboards, risk flag panels, map views, and timeline visualizations

Technology Stack

Next.js 16TypeScriptFastifyGoogle Gemini AIPostgreSQLGoogle Cloud SQLDockerTailwind CSSServer-Sent EventsRecharts

Technical Challenges & Solutions

Reliable Intent Classification & Entity Resolution

User queries are ambiguous — 'Colruyt finances' could mean a financial dashboard or a deep dive. I built a classifier that maps queries to one of 12 structured intents, with follow-up normalization that carries forward context from previous turns. Entity resolution handles partial company names, resolves them against the Crossroads Bank for Enterprises, and supports speculative parallel resolution alongside classification to cut latency.

Streaming Pipeline with Abort Safety

Each query passes through 5+ async stages (classify, resolve, plan, execute tools, compose). I implemented request budgets with abort propagation so that if a user navigates away or the request times out, every in-flight LLM call and database query is cleanly cancelled. Failed turns are rolled back from the session to prevent corrupted conversation state.

Optimistic Session Concurrency

Multiple browser tabs or rapid follow-up queries can hit the same session simultaneously. I added a version column to session state with optimistic concurrency control — on conflict, the system reloads the latest session, reapplies the current request's turns, and retries up to 3 times, avoiding the classic last-write-wins problem.

LLM Rate Limiting & Queue Management

With multiple LLM calls per request (classifier, composer, fallback loop), hitting Gemini API rate limits is inevitable. I built a shared LLM queue with configurable minimum delays, per-model routing, and queue-depth-based load shedding that rejects new requests before they even reach the LLM when the system is saturated.

Amar Fettis | Full Stack Web Developer based in Liège