AI Agent System for Automated Travel Itinerary Generation

aimpoint_digital · Consulting · 2024 · source Agentic: yes · promotional bias: med · source-backed · extracted with prompt 0.5.2 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Travel itinerary planning

Aimpoint Digital needed itineraries that avoid stale LLM knowledge and hallucinated places while reducing hours of manual trip research.

Constraints:

Architecture

Aimpoint’s travel agent takes a traveler profile and runs a compound RAG architecture on Databricks: the query is embedded and sent in parallel to places, restaurants, and events retrievers over Databricks AI Search indexes fed by Delta tables and change data feed updates. Retrieved candidates are synthesized by open-source LLMs on Provisioned Throughput Endpoints with guardrails. Evaluation uses MLflow metrics, LLM-as-judge rubrics, and DSPy prompt optimization to improve itinerary quality and format.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  traveler-profile-input["traveler-profile-input"]
  embedding-model["embedding-model"]
  places-rag["places-rag"]
  restaurants-rag["restaurants-rag"]
  events-rag["events-rag"]
  ai-search-indexes["ai-search-indexes"]
  delta-tables["delta-tables"]
  synthesis-llm["synthesis-llm"]
  guardrails["guardrails"]
  llm-judge-and-dspy["llm-judge-and-dspy"]
  itinerary-output["itinerary-output"]
  traveler-profile-input --> embedding-model
  embedding-model --> places-rag
  embedding-model --> restaurants-rag
  embedding-model --> events-rag
  delta-tables --> ai-search-indexes
  ai-search-indexes --> places-rag
  ai-search-indexes --> restaurants-rag
  ai-search-indexes --> events-rag
  places-rag --> synthesis-llm
  restaurants-rag --> synthesis-llm
  events-rag --> synthesis-llm
  synthesis-llm --> guardrails
  synthesis-llm --> itinerary-output
  itinerary-output --> llm-judge-and-dspy
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
traveler-profile-input Captures city, country, dates, purpose, companions, and budget for personalization. embedding-model
embedding-model Converts user-query/profile inputs into vectors for retrieval. traveler-profile-input, places-rag, restaurants-rag, events-rag
places-rag Retrieves destination attractions and places of interest that match the traveler profile. embedding-model, ai-search-indexes, synthesis-llm
restaurants-rag Retrieves restaurant recommendations for daily meals. embedding-model, ai-search-indexes, synthesis-llm
events-rag Retrieves events aligned with destination and traveler preferences. embedding-model, ai-search-indexes, synthesis-llm
ai-search-indexes Databricks vector indexes over current travel data; fed by Delta tables and updated automatically from raw data changes. delta-tables, places-rag, restaurants-rag, events-rag
delta-tables Stores raw and derived travel data and uses Delta Change Data Feed to update search indexes. ai-search-indexes
synthesis-llm Combines retrieved places, restaurants, and events into the final itinerary. places-rag, restaurants-rag, events-rag, guardrails, itinerary-output
guardrails Databricks Provisioned Throughput endpoint guardrails that constrain misuse of the agent system. synthesis-llm
llm-judge-and-dspy Evaluates itinerary professionalism and optimizes prompts against custom metrics and ground-truth examples. itinerary-output
itinerary-output The generated, personalized travel itinerary. synthesis-llm, llm-judge-and-dspy

Data flow

A user provides destination, dates, purpose, companions, and budget. The system converts that profile into embeddings, retrieves matching places, restaurants, and events through three parallel RAG paths, chooses the number of items based on trip length, and then sends the retrieved recommendations to an LLM that writes a cohesive itinerary under Databricks guardrails. Evaluation and prompt optimization run around that pipeline using LLM-as-judge metrics and DSPy.

3 supporting quotes
“Inputs generated from the user query are passed through the embedding model and used to retrieve the places, restaurants and events that closely align with the traveler profile.”article, stated
“Three simultaneous calls are made to the different RAGs in parallel to gather recommendations.”article, stated
“Once the RAGs have retrieved places, restaurants, and events, we use an LLM to combine the recommendations into a cohesive itinerary.”article, stated

Why this architecture

The architecture exists because standalone LLMs have stale training data and hallucination risk, while travel planning needs current restaurants, events, opening hours, and preference fit. Parallel RAGs let the system retrieve category-specific recommendations, and the final LLM only synthesizes grounded candidates. Evaluation and DSPy are wrapped around the pipeline because prompt changes can have unintended output effects.

3 supporting quotes
“Standalone GenAI tools like ChatGPT can generate travel itineraries. Still, the itineraries can be misleading or incorrect because they are based on LLMs that lack up-to-date information.”article, stated
“To generate itineraries with places, restaurants and events, our architecture consisted of three RAGs configured in parallel.”article, stated
“We observed that minor changes to the prompt can sometimes have significant, unintended consequences in the output. To mitigate this, we used a state-of-the-art package called”article, stated

Models used: DBRX Instruct · Meta-Llama-3.1-405b-Instruct · LLM-as-a-Judge · DSPy

Scale

Alternatives considered (roads not taken)

Standalone ChatGPT-style itinerary generation

Rejected because: A standalone LLM can recommend stale, closed, or hallucinated venues because it lacks current travel data.

“An LLM last trained in December 2023 is unlikely to be aware of a restaurant that closed in July 2024 and may incorrectly recommend it to a traveler. Most LLMs are not trained or fine-tuned with recent data and suffer from this “recency issue.””article, stated

A single places-only RAG

Rejected because: An itinerary also needs restaurants and destination events, so the team composed separate RAG paths for each category.

“An itinerary is seldom complete with just places of interest; travelers may seek information on restaurants and events happening at their destination. To solve this problem, we combined multiple RAGs in our architecture”article, stated

Patterns

rag-retrieval (retrieval)

The system uses updated vector databases to ground itineraries in recent place, restaurant, and event information.

“RAGs overcome the recency issue by maintaining regularly updated databases containing the latest information.”article, stated

multi-agent-orchestration (retrieval)

Three RAG components run in parallel for places, restaurants, and events.

“To generate itineraries with places, restaurants and events, our architecture consisted of three RAGs configured in parallel.”article, stated

Tradeoffs

How many retrieval systems to compose.

Chose parallel specialized RAGs over one monolithic travel retriever.

Rationale: Separate indexes match places, restaurants, and events but increase orchestration complexity.

“An itinerary is seldom complete with just places of interest; travelers may seek information on restaurants and events happening at their destination.”article, implied

How to improve itinerary prompt quality without manual prompt tinkering alone.

Chose Use DSPy with an LLM-as-judge and custom metric over ground-truth data. over Relying on manual prompt edits after observing bad generated itineraries..

Rationale: The source says prompt changes can cause unintended consequences, so the team used DSPy with judge-based scoring and a custom metric to optimize outputs.

“We observed that minor changes to the prompt can sometimes have significant, unintended consequences in the output. To mitigate this, we used a state-of-the-art package called”article, stated
“DSPy uses an LLM-as-a-judge in conjunction with a custom-defined metric to evaluate responses based on a ground truth dataset.”article, stated

Gotchas (what bit them)

Standalone LLM itineraries can recommend stale or closed places.

Root cause: Base models lack fresh local data and may hallucinate activities.

Resolution: Use nightly updated RAG indexes and retrieve current destination data before generation.

“An LLM last trained in December 2023 is unlikely to be aware of a restaurant that closed in July 2024 and may incorrectly recommend it to a traveler.”article, stated

Evaluation

Aimpoint used DSPy prompt optimization and LLM-as-a-judge automated evaluation.

Metrics: ~30 second itinerary generation · stakeholder feedback

“ks Provisioned Throughput Endpoints with guardrails, employs DSPy for prompt optimization, and uses LLM-as-a-Judge for automated evaluation.”summary, stated

Outcomes

Databricks platform case; technical but promotional.

“research/#:~:text=Expedia%20Group's%20Path%20to%20Purchase,45%20days%20prior%20to%20booking.), travelers spend over 5 hours researching and planning trips.”article, implied