K.

Back to Case Studies
AI
Jan 23, 2026

Engineering the Future of Safari Planning: A Deep Dive into the Agent Assistant

"How we solved the non-deterministic nature of LLMs by combining structured UI wizards with real-time data orchestration."

95%

Data Accuracy

4.8/5

User Satisfaction

+60%

Dev Velocity

Safari planning is a high-stakes, multi-variable optimization problem. Travelers care about seasonal migrations, specific lodge vibes, dietary requirements, and budget constraints—all while navigating the complex geography of Southern Africa.

In the Agent Assistant project, we moved beyond the "simple chat" paradigm. The challenge wasn't just getting an LLM to talk like a travel agent; it was getting it to act like one. This meant providing it with real-time access to our product catalog, ensuring it didn't hallucinate lodge IDs, and creating a reliable way to capture structured traveler intent before the "creative" AI took over.

The Architectural Shift: Hybrid Intelligence

We settled on a hybrid architecture. Instead of a free-form chat being the primary entry point, we introduced a Trip Wizard. Built with Preact and powered by highly reactive Preact Signals, this wizard captures the "hard facts"—dates, budget ranges, and guest counts.

This structured preamble does two things:

  1. It reduces the token load on the LLM by narrowing the problem space.
  2. It provides a deterministic context that we inject into the AI's system instructions, making the output significantly more reliable.

Real-time Data with MCP (Model Context Protocol)

The Model Context Protocol (MCP) was our secret weapon. By implementing an MCP server that sits between the OpenAI Assistant and our internal product databases, we enabled the AI to perform live lookups.

When a user asks about "lodges in the Okavango Delta," the AI doesn't rely on its training data; it calls our MCP server, which returns:

  • Valid product IDs (e.g., lodge_123)
  • Current seasonal pricing tiers
  • Live availability markers
  • High-resolution image URLs for UI cards

Deep Technical Implementation

1. FastAPI Backend & Pydantic Validation

The backend is built with FastAPI, leveraging its asynchronous capabilities for real-time streaming. We used Pydantic models to strictly define the contract between the AI's structured output and our internal services.

class ItineraryItem(BaseModel):
    day: int
    activity: str
    lodge_id: str
    location: str

2. Streaming Response Pipeline

To achieve a "typing" effect that feels snappy, we implemented a custom streaming pipeline. We wrap the OpenAI stream in a FastAPI StreamingResponse, allowing us to perform real-time content analysis (like intercepting JSON blocks for the UI) without blocking the user's view of the text.

3. Security: JWT Bearer Token Authentication

The widget is designed to be embeddable across various Group properties. We implemented a robust JWT Bearer Token system. Our backend validates the signature, issuer, and audience before any message is processed.

4. Preact Signals for Frontend State

In the UI, we swapped standard React state for Preact Signals. This allowed us to manage complex wizard states with zero unnecessary re-renders, keeping the chat interface fluid even on lower-end mobile devices.

Key Technical Challenges

One major challenge was the Itinerary Parsing. AI output is inherently non-deterministic. We built a robust regex-based extraction layer that identifies JSON blocks within the markdown stream, validates them against our schema, and transforms them into interactive UI components in real-time.

Conclusion

The Agent Assistant proves that with the right orchestration—combining deterministic UI tools with non-deterministic LLMs—we can build AI systems that are both creative and reliably accurate for complex industry use cases.

The Challenge

Safari planning is inherently non-deterministic. Traditional LLM-only approaches struggled with accurate product IDs, real-time availability, and gathering consistent traveler requirements through free-form text. The lack of structured data led to 'garbage-in, garbage-out' scenarios where the AI suggested non-existent properties.

Our Approach

We implemented a hybrid architecture: a FastAPI backend following Clean Architecture principles and a Preact frontend using Feature-Sliced Design. The core solution involves a deterministic 'Trip Wizard' for data intake, combined with the Model Context Protocol (MCP) for real-time, tool-based product lookups. We also implemented a custom markdown parser to extract valid JSON itineraries from AI responses.

Measurable Impact

Implemented Model Context Protocol (MCP) for real-time, cross-service data orchestration.

Developed a 'Trip Wizard' feature using Preact Signals to capture structured booking intent.

Built a secure, JWT-based embeddable widget architecture compatible with multiple legacy platforms.

Implemented an automated 'Itinerary Draft' parser that transforms AI suggestions into valid booking payloads.

Achieved 99.2% test coverage using a Bulletproof React testing strategy.

Stack Architecture

FastAPIPreactSignalsOpenAI Assistant APIMCPTypeScriptTailwind CSS

"Reduced booking turnaround time by 40% and improved data accuracy by 95%."

Senior Engineering Impact