Ever searched the web only to find useless AI-generated content? You're not alone. Lately, Google Search feels broken, AI assistants give erratic recommendations, users avoid chatbots where possible, and even the tools meant to make life easier are causing burnout. AI fatigue is real — and growing.
But while frustration with AI is understandable, it shouldn’t overshadow the real value it can bring. For every product bogged down by unnecessary AI features, there are many that could be transformed by the right application.
Let’s take a look at a real-world example: a 2021 project I worked on, which could have been radically transformed with today's GenAI.
The ConceiveAbilities Project
As we recently marked the fifth anniversary of COVID, I found myself thinking about a project I worked on for ConceiveAbilities, a Chicago-based egg donation and surrogacy agency, at the beginning of 2021. At that time, IVF clinics in the USA were starting to gradually reopen after the initial wave of COVID restrictions.
Many couples and individuals, who had to halt their treatments, were confused and uncertain about the current status of clinic openings. Nazca Fuentes, the CEO of ConceiveAbilities, sought to reduce some of this uncertainty by providing timely and accurate information about the availability of IVF clinics.
The solution Nazca envisioned included a website that collects the information from clinics and couples (community crowdsourcing via a survey) and displays it upon verification. The website required a user-friendly CMS for non-technical staff, and needed to go live as soon as possible.
The website launched within a few days and proved useful to many. The concept was, however, not self-sufficient. The ConceiveAbilities crew needed to check the information and keep tabs on its accuracy as time passed.
Looking back at this project, it was an ideal candidate for AI — if only we had the ease of using GenAI at the time. Instead of crowdsourcing, an AI agent could scrape clinics' websites, look up their opening info, and make a decision on the clinic’s status. Today, building an AI-driven solution would be not just possible, but straightforward.
GenAI Is the Perfect Fit for Simple Problems
Before jumping into implementing GenAI, it's important to reflect on whether it's indeed the right tool for the given challenge.
Let’s start with what GenAI is not the best at. GenAI is not a reliable therapist, doctor, or legal expert, nor is it the best coding assistant (as Pierce Edmiston points out). What these areas of expertise have in common is that they often go beyond words — law depends on abstract interpretation and societal context, coding relies on the broader software ecosystem, and medicine and psychology require an understanding of the complexities of the body and mind.
GenAI is most efficient and correct when it can tackle simple problems where understanding the meaning of the written context is the key challenge. There is no formal definition of a simple concept, but Andrew Ng describes it as “something that takes you less than a second of mental thought or maybe just a very small number of seconds of mental thought to come up with a conclusion”. Given GenAI’s strength in processing language, the ConceiveAbilities project seemed like a perfect fit for a quick implementation of an LLM-powered AI agent.
First, it would save plenty of time. The manual process of finding the opening hours information and making sure they are up to date was very time intensive, while for GenAI it would be a matter of seconds. Secondly, because the problem was straightforward — extract written information from IVF clinics’ websites and determine their open status based solely on that content. It required no additional model training or retrieval-augmented generation (RAG) other than providing the websites’ text.
Finding the Right Problem to Test My Hypothesis
Once the idea of replacing the manual collection of data with GenAI was determined, I wanted to try out the solution. However, with the pandemic being over and clinics operating as usual, I couldn’t directly test it. So instead I came up with a similar use case. I have a four-year-old child whom I’m teaching to ski. There are several ski stations within a 45-minute drive from my home in Kraków, Poland. Whenever I plan a day trip, I have to check each station’s website to see if the baby lift (aka conveyor belt or magic carpet) is operational — especially during the shoulder season when conditions fluctuate daily.
Multiple websites to check? Changing conditions? Sounds like a familiar challenge!
The Implementation
To keep this challenge similar to the ConceiveAbilities project, I chose a solution that would be ready in the shortest possible time. The implementation was done in Python and consisted of: 1) a website scraper, 2) a prompt builder, 3) a call to a chatbot (I’ve decided to use OpenAI), and 4) a UI builder.
The Website Scraper
For the MVP, I used BeautifulSoup to scrape only the main page.
class Website:
def __init__(self, url):
self.url = url
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
self.text = soup.body.get_text(separator="\n", strip=True)
In the next interactions, I'd find all the links on the website by recursively running soup.find_all('a', href=True) and then potentially ask the AI agent to filter out links that are unlikely to contain opening hours information. I'd also implement code to scrape the content of iframes to ensure I don't miss anything.
The Prompt Builder
Writing the correct prompt proved to be the most difficult task. The AI agents using LLMs have a tendency to hallucinate responses. There are a number of strategies on how to avoid them but having limited time, I focused on testing prompts and refining them to reach a 100% correct response rate.
My prompt consisted of two messages — one with user role and one with developer role (also known as a system role, see more about the different type of prompts).
def messages_for(website):
return [
{"role": "developer", "content": system_prompt},
{"role": "user", "content": user_prompt_for(website)}
]
The user message simply informs the AI agent that it's looking at a website with a particular URL and pasted its content, scraped in the previous step.
def user_prompt_for(website):
user_prompt = f"You are looking at a website {website.url}"
user_prompt += "\nThe contents of this website is as follows:"
user_prompt += website.text
return user_prompt
Writing the developer message posed a larger challenge because it needed to remain precise and include all relevant factors in making the decision.
I started with giving the model a persona in order to achieve the necessary precision and attain non-hallucinatory responses.
system_prompt = "You are a helpful and precise assistant "
system_prompt += "that provides clear and accurate answers."
system_prompt += "Always prioritize being truthful and nuanced."
When I started interacting with chatbots, I thought that the persona was a bit unnecessary and in all honesty— a tad cringy. But it proved very useful and I discovered using personas is recommended by OpenAI. When I took out the parts about precision — “ (...) precise (...) that provides clear and accurate answers. Always prioritize being truthful and nuanced.” and “If you are not absolutely certain about the status, use 'Unknown'” (used in a prompt below)— I got a wrong status for one of the stations!
After implementing the persona, I proceeded to describe the task:
system_prompt += "You will be given the text from Polish websites "
system_prompt += "and will respond in English."
system_prompt += "Your task is to take the contents of the website and "
system_prompt += "determine if a baby lift is open today."
Then I tackled the language differences. As the websites are in Polish, I made sure that the model didn’t mix up the baby lift with other types of lifts:
system_prompt += "The baby lift is called taśma or wyciąg taśmowy in Polish."
system_prompt += "Do not mix up the baby lift with other types of lifts "
system_prompt += "such as t-bars (in Polish orczyk, wyciąg orczykowy, "
system_prompt += "wyciąg linowy), chairlifts (krzesełko, krzesełkowy) or others."
Lastly, I described the requirements for the response
system_prompt += "Respond in 2 sentences. "
system_prompt =+ "The first sentence should be 1 word long and be Open, Closed, or Unknown."
system_prompt += "Use 'Open' if the baby lift is open. "
system_prompt += "Use 'Closed' if the baby lift is closed. "
system_prompt += "Use 'Unknown' if the baby lift's status is not known. "
system_prompt += "If you are not absolutely certain about the status, use 'Unknown'."
system_prompt += "The second sentence should briefly explain your decision and include opening hours if possible."
A Call to a Chatbot
In the next step, I made the call to the OpenAI chatbot.
def is_the_baby_lift_open(url):
website = Website(url)
response = openai.chat.completions.create(
model = "gpt-4o-mini",
messages = messages_for(website),
temperature = 0.2
)
return [url, *response.choices[0].message.content.split(".")]
links = [
"https://www.podstolice-ski.pl/",
"https://www.siepraw-ski.pl/",
"https://szklanagora.pl/",
"https://www.laskowa-ski.pl/",
"https://zima.sportarenamyslenice.pl/",
"https://www.narty.pl/malopolskie/rabka/polczakowka"
]
responses = [is_the_baby_lift_open(link) for link in links]
In this call, I've experimented with passing a temperature ranging from 0.2 to 0.9. As explained by OpenAI, higher values like 0.8 will make the output more random which is good for diverse, creative content, while lower values like 0.2 will make it more focused and deterministic, better for analytical, precise use cases.
In my case, changing the temperature had no effect on the response. This is because, for tasks that are inherently simple, well-defined, and have only one reasonable outcome, varying the temperature is unlikely to make a noticeable difference.
A UI Builder
Lastly, as I assumed that the client is on the clock, I used another AI tool called Gradio to build the UI for my results. Tada! A visual representation of the agent’s responses!

import gradio as gradio
colors = {"Open": "#2E8B57", "Closed": "#FF6347", "Unknown": "#D3D3D3"}
def create_display(texts):
with gradio.Blocks() as display:
with gradio.Row():
for text in texts:
color = colors.get(text[1], "#D3D3D3")
with gr.Column():
gr.Markdown(
f"""
<div style="background-color: {color}; padding: 20px; border-radius: 10px; text-align: center; width: 400px;">
<h1>{text[1]}</h1>
<p>{text[0]}</p>
<p>{text[2]}</p>
</div>
""",
elem_id=f"status_{text[1]}"
)
return display
demo = create_display(responses)
demo.launch()
Conclusion
By revisiting this 2021 8th Light project through the lens of GenAI, I identified how a simple, targeted AI agent could have made the product self-sufficient, reducing manual effort and improving accuracy. Although AI isn’t the answer to every problem, applying it to the right use cases — especially those rooted in simple language processing — can lead to powerful, practical solutions.
As AI continues to evolve, the key is not just adopting it for the sake of innovation but ensuring it genuinely enhances workflows and user experiences. For ConceiveAbilities, it could have saved many hours of manual work without negatively affecting the speed of delivery while simultaneously ensuring the accuracy of data as time passed.
Interested in seeing if AI is the right solution to address your business challenge? Learn more about how we can help you explore AI solutions.