Building AI Applications with Kimi K2: A Complete Travel Deal Finder Tutorial

Building AI Applications with Kimi K2
Build and deploy a Travel Deal application using the Groq Cloud, Firecrawl API, and the Hugging Face ecosystem.
Kimi K2 is a state-of-the-art open-source agentic AI model that is rapidly gaining attention across the tech industry. Developed by Moonshot AI, a fast-growing Chinese company, Kimi K2 delivers performance on par with leading proprietary models like Claude 4 Sonnet, but with the flexibility and accessibility of open-source models. Thanks to its advanced architecture and efficient training, developers are increasingly choosing Kimi K2 as a cost-effective and powerful alternative for building intelligent applications. In this tutorial, we will learn how Kimi K2 works, including its architecture and performance. We will guide you through selecting the best Kimi K2 model provider, then show you how to build a Travel Deal Finder application using Kimi K2 and the Firecrawl API. Finally, we will create a user-friendly interface and deploy the application on Hugging Face Spaces, making it accessible to users worldwide.
What is Kimi K2?
Kimi K2 is an open-source Large Language Model (LLM) designed for agentic AI tasks. It’s built on a mixture-of-experts (MoE) architecture featuring an impressive total of 1 trillion parameters, activating 32 billion during inference.
This model is trained on 15.5 trillion tokens using the innovative MuonClip optimizer, which effectively addresses training instabilities at this unprecedented scale, leading to robust and stable learning. Designed specifically for agentic intelligence, Kimi K2 excels in knowledge, reasoning, and coding. It’s also highly optimized for autonomous tool use and complex multi-step problem-solving. Kimi K2 features a context window of 128K tokens, advanced attention mechanisms, and strong capabilities for tool-calling. It has achieved impressive state-of-the-art results across a variety of benchmarks, including a 65.8% pass rate on the first attempt in the SWE-bench Verified coding assessments, along with exceptional performance in math, STEM, and tool-use tasks.
Getting Started with Kimi K2 API
Kimi K2 is an open-source model, which means you can run it locally for free. However, the catch is that you need at least 32 H100 GPUs. So, what are your other options? You can choose to use the official API provided by Moonshot AI or other model providers that provide lower cost and better performance. In this section, we will cover the best methods to access the paid and free APIs for using the Kimi K2 model.
1. Groq Cloud
It’s safe to say that Groq API is the best currently available. It provides the fastest token generation and is easy to set up. At the moment, it offers free but limited access to the Kimi K2 model.
2. Moonshot AI
Moonshot AI provides access to the models with the official API.
They don’t provide free access, meaning you need to add a credit card and add at least $10 credit to start using the Kimi K2 model.
3. OpenRouter
For other options to run Kimi K2, OpenRouter is the best place to explore. It’s a marketplace for all LLM APIs. You can easily find free APIs, affordable options, and those that are stable and provide fast inference. In the screenshot below, you will see that Moonshot AI is the cheapest option, but also the slowest. In contrast, Groq is a bit more expensive but provides 26 times more inference speed than Moonshot AI. Notice that while Groq offers free usage on their direct platform, OpenRouter charges for the convenience and its additional features.
Getting Started with Groq
For this tutorial, we will use Groq as the AI model provider. First, let’s install the Groq Python SDK:
pip install groq==0.30.0
On Groq’s website, create an account to generate the Groq API key. Save the API key and set it as an environment variable:
export GROQ_API_KEY=your_groq_api_key
Then, in Python, use the Groq Python library to create a client and generate response:
import os
from groq import Groq
# initialize clients
groq_client = Groq(api_key=os.environ["GROQ_API_KEY"])
chat_completion = groq_client.chat.completions.create(
messages=[
{
"role": "user",
"content": "What is Firecrawl famous for?",
}
],
model="moonshotai/kimi-k2-instruct",
)
print(chat_completion.choices[0].message.content)
This should return a quick and accurate response from Kimi K2.
Firecrawl is best known for its ability to **turn entire websites into clean, LLM-ready markdown or structured data** in a single API call. It's become popular among developers and AI teams who need to feed web content into large-language-model pipelines, RAG systems, or fine-tuning workflows without having to write custom scrapers or crawl logic.
Building a Travel Deal Finder AI Application with Kimi K2 and Firecrawl
Now that we have Groq as an AI model provider, the next step is to build the backbone of the application using the Firecrawl API and the Kimi K2 model. We’ll write a function that combines Firecrawl’s web searching with Kimi K2’s reasoning to return the best travel deals.
1. Setting up
First, we need to obtain the API keys for Groq and Firecrawl. Currently, both platforms provide free, but limited access to their API servers, which is sufficient for testing.
export FIRECRAWL_API_KEY=your_firecrawl_api_key
export GROQ_API_KEY=your_groq_api_key
Next, install the Groq, Firecrawl, and Gradio Python packages. We will use Gradio later to build a user interface for the application, which requires Python 3.10 or higher.
pip install groq==0.30.0
pip install firecrawl-py==2.16.1
pip install gradio==5.38.0
Then, in python, initialize the clients for Groq and Firecrawl.
import os
from firecrawl import FirecrawlApp
from groq import Groq
# initialize clients
groq_client = Groq(api_key=os.environ["GROQ_API_KEY"])
firecrawl_client = FirecrawlApp(api_key=os.environ["FIRECRAWL_API_KEY"])
2. Testing Firecrawl Search API
Before integrating the Firecrawl API with the Kimi K2 model, we need to verify how the Firecrawl Search API works and what outputs it generates.
We will request 5 search results for flights from New York to Tokyo and retrieve the latest results.
search_result = firecrawl_client.search(
"Find flight from New York to Tokyo",
limit=5,
tbs="qdr:w", # results from the past week
timeout=30000, # 30 seconds
)
for item in search_result.data:
print("Title:", item["title"])
print("URL:", item["url"])
print("Description:", item["description"])
print("-" * 40)
As a result, we received the titles, URLs, and descriptions of 5 flight details:
Title: American Airlines(r) - Find New York to Tokyo flights
URL: https://www.aa.com/en-us/flights-from-new-york-to-tokyo
Description: Find deals on New York to Tokyo flights ... *Fares displayed have been collected within the last 24hrs and may no longer be available at time of booking. Some ...
----------------------------------------
Title: Flights from New York to Tokyo (JFK - HND) - EVA Air
URL: https://flights.evaair.com/en/flights-from-new-york-to-tokyo
Description: Find New York to Tokyo Flights with EVA Air from USD 1,288. Round Trip ... Flight Type Round Trip|Economy. Dec 2025. No results available. Check ...
----------------------------------------
Title: Flights from New York to Tokyo | Singapore Airlines
URL: https://www.singaporeair.com/en-us/flights-from-new-york-to-tokyo
Description: Discover the best flight rates from New York to Tokyo. Travel in comfort with award-winning inflight services and state-of-the-art amenities.
----------------------------------------
Title: New York to Tokyo Flights | ANA
URL: https://flights.ana.co.jp/en-us/flights-from-new-york-to-tokyo
Description: Get a low fare flight from New York to Tokyo with ANA! Enjoy total comfort, world-class meals, and entertainment on your flight with ANA.
----------------------------------------
Title: Flights New York - Tokyo (NYC-TYO) - Air France
URL: https://wwws.airfrance.us/en-us/flights-from-new-york-nyc-to-tokyo
Description: Take a look at the next 6 months and find the best price to fly with Air France from New York (NYC) to Tokyo (TYO) or directly pick your departure date.
----------------------------------------
3. Testing Firecrawl Scrape API
Now let’s test the Scrape API. We will take the URL from the previous results and provide it to the Scrape API.
scrape_result = firecrawl_client.scrape_url(
url="https://flights.evaair.com/en/flights-from-new-york-to-tokyo",
formats=["markdown"],
max_age=3600000,
)
# markdown content:
print(scrape_result.markdown[:500], "...")
As a result, we received the content of the webpage in markdown format:
[Skip to content](https://flights.evaair.com/en/flights-from-new-york-to-tokyo#main)- [Skip to footer](https://flights.evaair.com/en/flights-from-new-york-to-tokyo#footer)
# Find New York to Tokyo Flights with EVA Air from USD 1,288
Round Trip
_expand\_more_
1 Passenger, Economy
_expand\_more_
Departure City
_close_
Destination City
_close_
Departurefc-booking-departure-date-aria-label07/24/2025
_today_
Returnfc-booking-return-date-aria-label07/31/2025
...
Search
[. The summarize_flight
function takes the raw flight search results and requests Kimi K2 to summarize them in a structured, human-friendly format.
def search_flights(query: str, limit: int = 5):
results = firecrawl_client.search(
query,
limit=limit,
tbs="qdr:w", # results from the past week
timeout=30000,
)
jobs = []
for item in results.data:
jobs.append(
{
"title": item["title"],
"url": item["url"],
"description": item["description"],
}
)
return jobs
def summarize_flight(description: str) -> str:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": f"""You are a helpful assistant. Summarize each flight search result into:
• Airline
• Route (origin to destination)
• Price (if available)
• Key features or restrictions
• Link to book flight
{description}""",
},
]
resp = groq_client.chat.completions.create(
model="moonshotai/kimi-k2-instruct",
messages=messages,
max_tokens=512,
temperature=0.7,
)
return resp.choices[0].message.content.strip()
The flight_search
function calls search_flights
to obtain raw flight data, passes this data to summarize_flight
for structured summarization, and returns the final user-friendly summary:
def flight_search(query: str) -> str:
flights = search_flights(query)
summary = summarize_flight(str(flights))
return summary
This app can also be built using an agentic framework like LangGraph, which allows the AI to make autonomous decisions about when to search, what information to gather, and how to process results using tools and agents. To learn more about top AI agent frameworks, please review The Best Open Source Frameworks For Building AI Agents in 2025.
5. Testing the Flight Search AI Application
Now that our Flight Search AI Application is set up, let’s test its performance by providing a sample user query:
result = flight_search("Find flight from New York to Tokyo")
print(result)
Each flight option is clearly summarized, including the airline, route, price (when available), key features or restrictions, and a direct booking link:
• Airline: American Airlines
Route: New York (JFK/EWR/LGA) → Tokyo (NRT/HND)
Price: Not specified in search feed ("...may no longer be available...")
Key features/restrictions: 24-hr price volatility warning; fare may change at booking
Link: https://www.aa.com/en-us/flights-from-new-york-to-tokyo
• Airline: EVA Air
Route: New York (JFK) → Tokyo Haneda (HND)
Price: From USD 1,288 round-trip (Economy)
Key features/restrictions: Lowest price shown for Dec 2025 currently unavailable--check calendar
Link: https://flights.evaair.com/en/flights-from-new-york-to-tokyo
• Airline: Singapore Airlines
Route: New York (JFK/EWR) → Tokyo (NRT/HND)
Price: Not displayed in search snippet
Key features/restrictions: Award-winning service, modern amenities, wide-body aircraft
Link: https://www.singaporeair.com/en-us/flights-from-new-york-to-tokyo
• Airline: Air France
Route: New York (NYC-area airports) → Tokyo (TYO - both NRT/HND)
Price: "Best price" shown on 6-month calendar (not quoted in snippet)
Key features/restrictions: Flexible date selector; can mix cabin classes
Link: https://wwws.airfrance.us/en-us/flights-from-new-york-nyc-to-tokyo
• Airline: ANA (All Nippon Airways)
Route: New York (JFK/EWR) → Tokyo (NRT/HND)
Price: Promoted as "low fare" but amount not listed
Key features/restrictions: Japanese hospitality, complimentary meals & entertainment
Link: https://flights.ana.co.jp/en-us/flights-from-new-york-to-tokyo
Creating the UI for the Travel Deal Finder AI Application
We are going to create a user-friendly web interface using Gradio that allows users to search for and summarize the best flight deals between two cities.
In the app.py
script, the user interface is built using Gradio’s Blocks API, which provides flexible layout and component arrangement options. The interface features text boxes where users can input their origin and destination cities, a checkbox to enable or disable “Deep Search” (which triggers detailed scraping of top results), and a button to initiate the search. When the user clicks “Find Deals,” the app disables the button to prevent duplicate submissions and displays a “Processing…” message.
app.py:
import os
import time
import gradio as gr
from firecrawl import FirecrawlApp
from groq import Groq
# Initialize API clients
firecrawl_client = FirecrawlApp(api_key=os.getenv("FIRECRAWL_API_KEY"))
groq_client = Groq(api_key=os.getenv("GROQ_API_KEY"))
def search_flights(origin: str, destination: str, limit: int = 5):
query = f"Find flights from {origin} to {destination}"
results = firecrawl_client.search(
query,
limit=limit,
tbs="qdr:w", # results from the past week
timeout=30000,
)
flights = []
for item in results.data:
flights.append(
{
"title": item["title"],
"url": item["url"],
"description": item["description"],
}
)
return flights
def summarize_flights(flights):
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": f"""
Summarize these flight search results in clear, visually appealing markdown. For each flight, use the following format:
---
## [Airline Name]
- **Route:** [Origin] → [Destination]
- **Price:** [Price or 'Not quoted']
- **Key Points:** [Key features or restrictions]
- **Book:** [Link with airline name](URL)
---
{flights}
""",
},
]
resp = groq_client.chat.completions.create(
model="moonshotai/kimi-k2-instruct",
messages=messages,
max_tokens=512,
temperature=0.7,
)
return resp.choices[0].message.content.strip()
def scrape_flight_details(url: str):
try:
scrape_result = firecrawl_client.scrape_url(
url=url,
formats=["markdown"],
max_age=3600000,
)
content = getattr(scrape_result, "markdown", None)
if not content:
return "No markdown content returned from scrape."
content = content[:1500] # limit for display
# Summarize scraped content
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": f"Summarize the key details from this flight booking page for a traveler.\n{content}",
},
]
resp = groq_client.chat.completions.create(
model="moonshotai/kimi-k2-instruct",
messages=messages,
max_tokens=512,
temperature=0.7,
)
return resp.choices[0].message.content.strip()
except Exception as e:
import traceback
tb = traceback.format_exc()
return f"Error scraping details: {type(e).__name__}: {e}\nTraceback:\n{tb}"
def travel_deal_finder(origin, destination, deep_search):
flights = search_flights(origin, destination)
summary = summarize_flights(str(flights))
scraped_details = "No results to scrape."
if deep_search:
for flight in flights:
url = flight["url"]
details = scrape_flight_details(url)
if not details.startswith("Error scraping details"):
scraped_details = details
break
else:
scraped_details = (
"Deep Search is disabled. Only summarized search results are shown above."
)
return summary, scraped_details
def travel_deal_finder_with_time(origin, destination, deep_search):
start = time.time()
summary, scraped_details = travel_deal_finder(origin, destination, deep_search)
elapsed = time.time() - start
return (
summary,
scraped_details,
gr.update(interactive=True), # Re-enable button
f"⏱️ Processing time: {elapsed:.2f} seconds",
)
def main():
with gr.Blocks() as demo:
gr.Markdown(
"# Travel Deal Finder ✈️\nEnter your origin and destination to find and summarize the best flight deals!"
)
with gr.Row():
origin = gr.Textbox(label="Origin City", value="New York")
destination = gr.Textbox(label="Destination City", value="Tokyo")
deep_search = gr.Checkbox(
label="Deep Search (scrape top results for details)", value=False
)
search_btn = gr.Button("Find Deals")
summary_output = gr.Markdown(label="Flight Deals Summary")
scrape_output = gr.Markdown(label="Top Result Details (Scraped)")
time_output = gr.Markdown(label="Processing Time")
def on_search(o, d, ds):
# Disable button immediately
return (
gr.update(), # summary_output placeholder
gr.update(), # scrape_output placeholder
gr.update(interactive=False), # Disable button
"Processing...", # Show processing message
)
search_btn.click(
on_search,
inputs=[origin, destination, deep_search],
outputs=[summary_output, scrape_output, search_btn, time_output],
queue=False,
)
search_btn.click(
travel_deal_finder_with_time,
inputs=[origin, destination, deep_search],
outputs=[summary_output, scrape_output, search_btn, time_output],
queue=True,
)
demo.launch()
if __name__ == "__main__":
main()
To launch the app, simply run python app.py, and Gradio will start a local web server, making the Travel Deal Finder accessible in your browser at http://127.0.0.1:7860.
python app.py
Output:
* Running on local URL: http://127.0.0.1:7860
* To create a public link, set `share=True` in `launch()`.
Copy and paste the http://127.0.0.1:7860 URL in your browser and view the Travel Deal Finder UI.
If you are facing issues running the app, please refer to the kingabzpro/Travel-with-Kimi-K2 GitHub repository, which contains code, examples, and a guide to clone and run the application locally.
Deploying the Travel Deal Finder AI Application
To make your Travel Deal Finder AI app accessible online, you can deploy it using Hugging Face Spaces. Spaces provides free hosting for interactive machine learning apps built with Gradio, Streamlit, or Docker.
- Go to https://huggingface.co/new-space and fill out the repository import form. Make sure to include the app’s name, description, license, and SDK, and then create your Space.
-
After that, you will see a guide on how to deploy your app. The most popular solution is to clone the repository, add all the app files, and then push these files to the remote repository.
-
Clone the repository from Hugging Face. git clone https://huggingface.co/spaces/your_account/name_of_your_project
-
Create or update the
requirements.txt
file in the project root directory and add the following dependencies: groq==0.30.0 firecrawl-py==2.16.1 -
Copy the
app.py
file you created during the previous session to the repository. -
Edit the
README.md
file based on your preferences.
- Stage the changes, commit, and push the files to the remote Space repository:
git add .
git commit -m "initial commit"
git push
Note that for your password, you’ll need to enter a Hugging Face access token. 8. Go to your app’s settings and scroll down to add the necessary secrets. Input your Groq and Firecrawl API keys with the names GROQ_API_KEY and FIRECRAWL_API_KEY.
Once you save the secrets, your app will be ready, and you will see the proper user interface. You can test it by providing city names, and it will generate results within 5-10 seconds.
Screenshot from Travel With Kimi K2 If you encounter any issues while deploying the app, feel free to refer to the Travel With Kimi K2 example and duplicate the app to try it on your own account with your own API keys.
Conclusion
In this tutorial, we learned about the new fast and efficient Firecrawl Search API. We also learned how to use the Search and Scrape API to build a Travel Deal Finder AI application using Kimi K2, Firecrawl API and Gradio. In only a few steps, we built an easy-to-use app that provides details about the top five searches for specific travel destinations as well as a deep search option to perform a page scrape to gather even more details about your flight search.
Kimi K2 represents a major win for the open-source community. People can now quantize and run the model locally. Despite its size, the open-source release means users can choose from multiple providers based on their needs and performance. This flexibility also helps teams with budgeting and efficiency, rather than relying on a single proprietary provider. If you are interested in building more complex AI applications using Firecrawl, then please check out the LangGraph Tutorial: Build a Startup Idea Validator with Interactive UI.
On this page
Building AI Applications with Kimi K2
What is Kimi K2?
Getting Started with Kimi K2 API
1. Groq Cloud
2. Moonshot AI
3. OpenRouter
Getting Started with Groq
Building a Travel Deal Finder AI Application with Kimi K2 and Firecrawl
1. Setting up
2. Testing Firecrawl Search API
3. Testing Firecrawl Scrape API
4. Integrating Firecrawl API with Kimi K2
5. Testing the Flight Search AI Application
Creating the UI for the Travel Deal Finder AI Application
Deploying the Travel Deal Finder AI Application
Conclusion
About the Author

I am a certified data scientist who enjoys building machine learning applications and writing blogs on data science. I am currently focusing on content creation, editing, and working with large language models.