Most of the time, the bot returns useful answers, as long as the content on the site can cover the query. You're not confined to asking in German either - other languages work too, with the bot replying in the same language.
Wondering what sort of questions you can ask? Here are a few examples:
- Wieviele Einwohner hat Zürich? (How many inhabitants does Zurich have?)
- Wer ist die Stadtpräsidentin? (Who is the mayor of the city?)
- Wann sind die Badis offen in 2023? (When are the public swimming areas open in 2023?)
- Wann sind Schulferien in 2023? (When are the school holidays in 2023?)
- Ich brauche einen neuen Pass, was kann ich tun? (I need a new passport, what can I do?)
- Was ist das höchste Gebäude von Zürich? (What is the tallest building in Zurich?)
- Wie entsorge ich Pneus? (How do I dispose of tires?)
- Was macht Zürich für den Klimaschutz? (What is Zurich doing for climate protection?)
- Wo lebte Alfred Einstein in Zürich? (Where did Alfred Einstein live in Zurich?)
- Wie werde ich Feuerwehrmann/Frau? (How do I become a firefighter?)
- Ist der Strom in Zürich atomfrei? (Is the electricity in Zurich nuclear-free?)
- Wo kann ich ein Velo mieten? (Where can I rent a bicycle?)
And, of course, there are many more questions you can pose.
The bot isn't infallible, so we strongly advise verifying your answers with the provided official pages if accuracy is essential.
The Tech Stuff: How ZüriCityGPT came to be
Inspired by a blog post from Supabase shared in our AI Slack channels, here's a look at what we did:
Getting and indexing the content:
- For the backend, we used NestJS.
- The frontend is a very simple react app, which sends the question to the backend and displays the result.
- We set up a database using PostgreSQL and the pgvector extension.
- We responsibly crawled the entire website using SimpleCrawler and input the data into the database.
- We extracted the relevant content with Cheerio and inserted it into the database.
- We then sent these text snippets to OpenAI's embedding APIs and stored the received embeddings in the database.
Querying the content:
- Upon receiving a question, we send it to OpenAI’s embedding API to obtain an embedding vector.
- We use this vector to search the database, extracting text snippets and URLs.
- A prompt is created, including the snippets until the maximum token limit is reached.
- These tokens are sent to OpenAI’s createChatCompletion API and the result is streamed back to the browser with Server Sent Events.
- All related links found in our database are also returned for reference and proper sources.
We've made some tweaks for improvement later. We now only use the first few content snippets for the prompt, filling the end with links and title only. This gives some more context to ChatGPT, but apparently not as good as the whole content. Initially, we tried sending only links, but this didn't always give satisfactory results and even led to "hallucinated" answers, since gpt-3.5 doesn't actually resolve all those links.
Remember, this tool is not affiliated with the City of Zurich and serves mainly as a proof of concept.
However, we're excited about the potential of this technology in enhancing public information access, and we hope you enjoy exploring Zurich with ZüriCityGPT!