Skip to content
Back to Blog
August 4, 2026

From \\\"Find Me Cheap Flights\\\" to 3 Perfect Options

What happens in the 2 seconds after you ask our AI for flights? A step-by-step teardown of search, ranking, and personalized curation.

From \\\"Find Me Cheap Flights\\\" to 3 Perfect Options
M

You type "Find me cheap flights to Tokyo in March." Two seconds later, three flight options appear in your chat with prices, airlines, layover times, and a note from the AI explaining why each one made the cut. It feels simple. It is not.

Those two seconds contain a dense sequence of operations: natural language parsing, constraint extraction, flexible date interpretation, API query construction, multi-provider result retrieval, normalization, multi-factor ranking, diversity optimization, and response synthesis with streaming delivery. Each step has its own engineering challenges and each one had to be fast enough to fit inside a conversational latency budget.

Here's the full teardown.

The moment a user speaks: extracting structured intent from messy language

Illustration for this section

"Find me cheap flights to Tokyo in March" is clear enough. But users also say things like "I want to go somewhere warm, maybe Southeast Asia, not too expensive, and I need to be back by the 15th because my daughter has a recital." That is a much harder input to work with.

The first step is intent extraction. The AI model processes the user's message and extracts structured parameters: destination (or destination constraints), date range (specific or flexible), budget signal (explicit number or relative term like "cheap"), number of travelers, preferred airlines, class of service, and any negative constraints ("not too long a layover," "no red-eyes").

The interesting part is handling ambiguity. "Cheap" means different things to different people. For a college student, cheap might mean under $400 round-trip. For a business traveler, cheap might mean under $1,500. We resolve this in two ways: if we have agentic memory for this user, we use their historical booking data to calibrate budget expectations. We know that the last three flights this person booked were between $600 and $900, so "cheap" probably means the lower end of that range. If it's a new user, we use the destination and travel dates to estimate a reasonable range based on typical fares for that route, and ask for confirmation if the range is wide.

Flexible dates like "sometime in March" get expanded into a date range. If the user hasn't specified a preference for start of month vs. end of month, we search across the full range and let the ranking algorithm find the best price-date combinations. "Next weekend" gets anchored to the current date. "Around the 15th" gets expanded to a window of a few days in either direction. "The cheapest day this week" triggers a multi-date search with price as the primary sorting criterion.

Negative constraints are especially interesting because they require understanding intent behind the words. "No red-eyes" means exclude overnight flights. "Not too long a layover" means we need to know what's "too long" for this person. We default to a reasonable range (under 3 hours for experienced travelers, under 4 hours for less experienced ones) and adjust based on any memory we have about this user's layover tolerance.

The output of this step is a structured query object that our search tools can consume. It's clean, typed, and validated. All the ambiguity has been resolved, either by inference or by asking the user a clarifying question. If we're not confident about a parameter, we ask rather than guess. "When you say cheap, are you thinking under $500 or under $800?" is a better experience than presenting results in the wrong price range.

From intent to API call: translating human language into provider queries

Once we have structured search parameters, we need to translate them into provider-compatible API queries. This is a layer of engineering that's invisible to the user but critical to the quality of results.

Different travel data providers have different APIs with different parameter formats, supported features, and quirks. Some providers support flexible date searches natively, returning the best prices across a range of dates in one call. Others require you to make separate requests for each specific date, which means we might need to dispatch seven parallel API calls for a one-week flexible date search.

Some providers support multi-city routing in a single query. Others require separate one-way searches that you stitch together. Some return rich fare class data with baggage and change policies. Others return only the basics.

We abstract over these differences with a normalization layer. The AI agent's search tool constructs a canonical search request with standardized fields. The normalization layer translates that into provider-specific API calls, dispatches them (often in parallel to multiple providers), and assembles the raw results into a uniform format.

The normalization handles the messy reality that travel APIs are not standardized. The same flight from the same airline might look different depending on which provider's API returns it. Different fare classes, different baggage policies, different change fee structures, different ways of expressing layover duration. We normalize all of this so the ranking pipeline has clean, comparable data to work with.

The average flight search on a traditional OTA takes twenty-plus minutes when you count all the browsing, filtering, comparing, and going back to check prices again. Users compare three to five OTA sites before booking, adding even more time. We compress the search itself into seconds and do the filtering for you.

The ranking pipeline: turning 200 results into 3

Supporting diagram

This is where the engineering gets genuinely hard. And it's where we have the strongest opinions.

A raw search might return 100 to 300 flight options. One-stops, two-stops, red-eyes, different airlines, different layover airports, different fare classes, different departure times, different pricing. Dumping all of this on a user and saying "filter as you wish" is the approach every traditional OTA takes. We think that's lazy engineering dressed up as user empowerment. Showing someone 300 options and calling it "choice" is like handing someone an encyclopedia when they asked for a recommendation.

Our ranking pipeline scores every result across five dimensions:

Price score. How does this option compare to the cheapest available? We use a relative score, not an absolute one. An $800 flight when the cheapest is $750 scores differently than an $800 flight when the cheapest is $400. The relative scoring means that on an expensive route where all flights cost over $1,000, a $1,050 flight can still score well on price if the cheapest is $1,020. On a cheap route, the price sensitivity is proportionally higher.

Convenience score. Departure time (early morning flights get penalized unless the user prefers them), layover duration (under 90 minutes is risky for connections at large airports, over 4 hours is tedious), total travel time, number of stops, and layover airport quality. Connecting through a modern, well-organized airport is better than connecting through one known for delays and long walks between terminals.

Comfort score. Aircraft type (wide-body vs. narrow-body for long hauls), seat configuration (3-3-3 is worse than 2-4-2 for aisle access), in-flight amenities (seatback entertainment, WiFi, power outlets), and fare class features (legroom, baggage included, seat selection).

Reliability score. Historical on-time performance for this airline on this route, at this time of day, during this season. A 6 AM departure from an airport that regularly has morning fog gets a lower reliability score. A route known for afternoon thunderstorm delays in summer gets adjusted accordingly. This data comes from publicly available flight performance databases.

Preference match score. This is where agentic memory earns its keep. If we know the user always books Delta, Delta options get a preference boost. If they always pick window seats, we check if window seats are available and factor that in. If they've told us they hate connecting through Miami, any Miami connection gets penalized. If they consistently choose direct flights even when cheaper connections are available, we weight directness heavily.

Each dimension gets a weight, and the weights adapt to the user. Budget travelers get a heavier price weight. Comfort-focused travelers get a heavier comfort weight. Users who haven't expressed strong preferences get balanced weights with a slight tilt toward price, because price sensitivity is the most common default.

85% of travelers say personalization influences their booking decisions. But most search engines personalize with a blunt instrument: sort by price, or sort by duration. We personalize across all five dimensions simultaneously, creating a multi-dimensional score that captures what "best" actually means for each individual user.

Making the three options genuinely different

If all three options were just the three highest-scoring flights, you'd often get three nearly identical options. Same airline, similar times, $20 apart in price. That's useless. It doesn't give the user meaningful choice. It's the same option presented three times with trivial variations.

We enforce a diversity constraint in the final selection step. The three options should span the trade-off space. Typically this means: a budget pick (best price, acceptable on other dimensions), a comfort pick (best experience, higher price), and a balanced pick (strong across all dimensions).

The diversity algorithm works by first selecting the highest overall scorer. Then it penalizes remaining options that are too similar to the selected one. Similarity is measured across all five dimensions: two flights on the same airline with departure times an hour apart are "similar." A Delta direct flight and a budget carrier with a connection are "diverse." Two economy options from different airlines at similar prices are more similar than an economy option and a premium economy option.

After penalizing similar options, we select the next highest scorer. Then penalize again relative to both selected options, and select the third. This process produces three options that genuinely occupy different positions in the trade-off space.

The tuning is important. Too much diversity and you show irrelevant options (a $300 budget flight alongside a $2,000 business class, when the user's history suggests a $500-800 budget). Too little diversity and the three options feel interchangeable. We calibrate the diversity penalty based on the user's demonstrated flexibility. Users who always pick the cheapest option get less diversity (three budget-oriented options with different trade-offs). Users who've shown willingness to pay more for comfort get more diversity in the comfort dimension.

Streaming search progress: the perception trick that isn't a trick

Here's a data point that changed how we think about search: a five-second search that streams progress feels faster than a three-second search hidden behind a spinner. This has been studied in UX research and confirmed by our own metrics.

When the agent kicks off a flight search, we stream status updates to the user in real time. "Searching across airlines..." appears first. Then "Found 180 options, ranking by your preferences..." Then the three options render one at a time with their scoring explanations. Each option appears with a brief note: "Budget pick: lowest price, one stop in LAX" or "Recommended: direct flight, matches your usual preferences."

This progressive disclosure keeps the user engaged and informed. They know the agent is working, they can see progress, and the results arrive with context instead of appearing as a sudden wall of data. The status messages are real, generated from actual pipeline checkpoints, not canned loading text.

The streaming architecture uses unidirectional server streaming (server streaming). The backend generates events as each stage of the pipeline completes, and the frontend renders them incrementally. The total time from user message to complete results display is under two seconds for most searches. The first token of the response appears in under a second. The AI agent responds with streamed content within a couple of seconds, and that two-second budget is carefully allocated across each pipeline stage.

Where traditional search engines fall short

The best flight search engine in the world, by raw capability, is probably the one built by the largest search company. Fast results, broad coverage, good price tracking. But it has no personalization. It doesn't know if you prefer aisle seats or hate red-eyes. It doesn't remember that you searched for the same route last week at a different price point. It can't book. It's a very good search form, and that's all it is.

The next tier down, the major OTAs, add booking capability but at the cost of monetization bias. Results are ranked partly by commission rates, not purely by user benefit. Sponsored placements are mixed into organic results. The user has to navigate this bias while also managing filters and comparisons across hundreds of results.

We have neither of these problems. We don't sell sponsored placements. We don't rank by commission. The ranking algorithm optimizes for one thing: which three flights this specific user would be happiest with. That alignment between the product's incentive and the user's interest is only possible because we built a different business model.

What gets better from here

Two things improve our search quality on different timescales.

On a per-user timescale, agentic memory makes every search better than the last. The more we know about you, the better the three options become. By your fifth or sixth booking, the agent has a detailed model of your preferences that no OTA profile page could capture, because it's learned from behavior and conversation, not entered into form fields. Repeat user experience on traditional OTAs is the same as first time. On Nowah, it improves with every interaction.

On a product timescale, model improvements make intent extraction sharper, ranking more nuanced, and response synthesis more natural. Longer context windows let the agent reason about more complex trip requirements. Better reasoning capabilities let it handle edge cases we currently route to clarification questions.

The direction is clear: the gap between "find me cheap flights" and three perfect options should shrink to near zero. Not because the search is faster (two seconds is already fast), but because the options are more perfectly matched to what you actually want. That's a personalization problem, and it gets better with every conversation.

AI-powered travel recommendations increase conversion by 20 to 35 percent over traditional unpersonalized search. That improvement comes from showing fewer, better options, not more options. The ranking pipeline is the engine of that improvement, and everything in it, from intent extraction to diversity optimization, is designed to turn a vague human desire into three genuinely good choices.


Nowah is an AI travel agent that searches and books real flights and hotels through conversation — no filters, no thirty open tabs. Plan your next trip.

Share this article

Ready to Plan with Nowah?

Bring the idea. Nowah will help turn it into a trip.

Try Nowah