An internal AI assistant for the staff of a US managed service provider, delivered inside Microsoft Teams. People ask questions about the company in plain language and the assistant answers from live systems of record rather than from a static knowledge base.
It is a three-tier agent, not a chat model with a knowledge base bolted on. A Teams front door terminates the Azure Bot Service channel and speaks the Bot Framework REST API directly rather than through a connector, with client-credentials token acquisition and proactive replies posted back into the originating conversation. A top-level orchestrator holds the persona and the routing rules and decides which of 12 registered tool workflows can answer. Specialist sub-agents sit under it: a knowledge-base agent over a pgvector store, a PSA search agent that knows the platform's conditions query language, and a service-ticket agent that resolves entities before it queries.
The details that made it survive production. Four deterministic entity resolvers turn model free text into real record ids and are instructed to ask the user to disambiguate rather than pick, which is what removed hallucinated identifiers. Two-stage retrieval pulls 50 candidates by embedding similarity then reranks to 25, with a relevance floor and mandatory citation of the source page. Conversation memory lives in Postgres keyed by the user's Entra object id, so history is per person rather than per channel, and each person can clear their own and nobody else's. The front door fans each incoming activity into two branches, one posting an instant holding phrase and one calling the agent, so a multi-tool query never looks frozen.
One deliberate trade: the orchestrator lists its available tools and has the user pick one before running anything. Conversational fluency given up for predictability, because this agent has live access to production systems. Model resilience is a primary model with a fallback, five retries, and an error branch that returns a readable sentence instead of a stack trace.
126 sessions across 269 days with zero failures. That is a reliability record over the period, not an adoption figure, and it is written that way. No client is named and no client data appears here.
Built with