We recently built a demo showing how multiple AI agents can work together to plan travel itineraries.
The system takes user preferences and returns a complete travel package with flights, accommodations, and activities.
Implementation
The system uses two specialized agents:
- A primary travel agent that coordinates the planning process and interfaces with travel APIs
- An analyzer agent that validates and formats the data
Here's how we implemented the primary travel agent:
1import { anthropic } from "@ai-sdk/anthropic";
2
3export const travelAgent = new Agent({
4 name: "travelAgent",
5 instructions: `You are an expert travel agent responsible for finding a flight, hotel, and three attractions for a user. You will be given a set of user preferences along with some tools and you will need to find the best options for them. Be as concise as possible with your response.`,
6 model: anthropic("claude-3-5-sonnet-20241022"),
7 tools: {
8 searchFlights,
9 searchHotels,
10 searchAttractions,
11 searchAirbnbLocation,
12 searchAirbnb,
13 },
14});
The agent receives structured input including:
- Departure and arrival locations
- Trip goals and interests
- Flight preferences and priorities
- Accommodation type and price range
- Travel dates
Here's the prompt that guides the agent's decision-making:
1const message = `
2 You are a travel agent and have been given the following information about a customer's trip requirements.
3
4 - Find the best flight option for the customer (use departureLocation and arrivalLocation)
5 - Find the best accommodation option (use arrivalCityId)
6 - Find three activities based on their interests (use arrivalAttractionId)
7 - Find the best return flight option
8 - For Airbnb stays, search location then listings (use searchAirbnbLocation then searchAirbnb)
9
10 Notes:
11 - Include layover information when present
12 - Add images for hotels and accommodations
13 - flightPriority ranges 0-100 (0: prioritize price, 100: prioritize convenience)
14 - Use complete timestamps for departure/arrival times
15 - Return complete flight objects
16 - Only call relevant accommodation search based on user preference
17
18 Trip Requirements:
19 Departure: ${formObject.departureLocation}
20 Arrival: ${formObject.arrivalLocation}
21 Goals: ${formObject.tripGoals}
22 ...
23`;
The analyzer agent then validates and formats the data:
1import { anthropic } from "@ai-sdk/anthropic";
2
3export const travelAnalyzer = new Agent({
4 name: "travel-analyzer",
5 instructions:
6 "You are an expert travel agent responsible for finding a flight, hotel, and three attractions for a user. You will be given a set of user preferences along with some data to find the best options for them.",
7 model: anthropic("claude-3-5-sonnet-20240620"),
8});
This agent also gets a fairly detailed prompt:
1const messageToAnalyze = `
2 You are a travel agent analyzing research results.
3
4 Format the response according to the output schema for the travel planner.
5
6 For hotel ratings:
7 - Extract numeric rating from description/accessibilityLabel
8 - Rating format: "X.X out of 5 stars" or "X out of 5 stars"
9 - Use only first number (before "out of")
10 - Rating must be ≤ 5
11 - Include layover details in flight legs
12 - Replace <UNKNOWN> values with empty strings
13
14 ${JSON.stringify(data)}
15`;
Type Safety
The system uses TypeScript and Zod schemas throughout:
1const FlightSearchSchema = z.object({
2 budget: z.number(),
3 departure: z.string(),
4 destination: z.string(),
5 dates: z.object({
6 start: z.date(),
7 end: z.date(),
8 }),
9});
This ensures data consistency between agents and external APIs.
The code is available on GitHub, and you can try it at mastra-eight.vercel.app.