- Random Forest Model as Baseline
- Closed source LLMs
- grok-4
- grok-3-mini (partially in the Prototype Application)
- gpt-5-2025-08-07 (partially in the Prototype Application)
- gpt-5-mini-2025-08-07 (partially in the Prototype Application)
- Open source LLMs
- Apertus-8B (only in Jupyter Notebook)
- Apertus-70B (only in Jupyter Notebook)
Instructions to prepare your .env file and how the prototype can be started and used.
Create the .env file as followed in the path/prototype directory:
HUGGINFACE_TOKEN=[Your Token]
OPENAI_API_KEY=[Your Token]
XAI_API_KEY=[Your Token]
BK_API_VORLAGE=[API endpoint provided by the Swiss Federal Chancellary]
BK_API_ERLAEUTERUNGEN=[API endpoint provided by the Swiss Federal Chancellary]
MODEL_CONFIG=[{"provider": "OpenAI", "models": ["gpt-5", "gpt-5-mini"]}, {"provider": "xAI", "models": ["grok-4", "grok-3-mini"]}]
BK_API_VORLAGE and BK_API_ERLAEUTERUNGEN are not public and can be requested by email.
Feel free to amend MODEL_CONFIG to your need or add future models. gpt-5-nano is not used due to the TPM limit of 200 000 token (as of 20.09.2025), see API Documentation for more details.
Run prototype/app.py and open http://127.0.0.1:10002 in browser. Multilanguage and one LLM is implemented. For demonstration and performance purposes, all necessary metadata is stored in prototype/static/votes.json. If you want to run the app from scratch you need to create a .env file in prototype/agents/ and add your own API keys and necessary GET endpoints to import voting data.
HUGGINFACE_TOKEN=[YOUR_SECRET]
OPENAI_API_KEY=[YOUR_SECRET]
XAI_API_KEY=[YOUR_SECRET]
PUBLICAI_API_KEY=[YOUR_SECRET]
BK_API_VORLAGE=[URL]
BK_API_ERLAEUTERUNGEN=[BASE_URL]/{vote_id}/{file_name}
MODEL_CONFIG=[
{"provider": "OpenAI", "models": ["gpt-5", "gpt-5-mini", "gpt-5-nano"]},
{"provider": "xAI", "models": ["grok-4", "grok-3-mini"]},
{"provider": "PublicAI", "models": ["swiss-ai/apertus-70b-instruct", "swiss-ai/apertus-8b-instruct"]}
]
The test mode can be set in app.py by initialize_data(TESTMODE=True). This limits the number of votes to 1 to 5 elements, instead of loading and processing all 380 popular votes, which are currently available.
Let's configure the app with docker as followed:
- Container name:
christoph-zweifel-thesis - App name:
smart-voting-booklet-app
To start the docker container run the following commands:
Build the app
docker build -t smart-voting-booklet-app .
Start the Docker container with the app
docker run -d -p 10002:10002 --name christoph-zweifel-thesis smart-voting-booklet-app
Start the Docker container on thesis.zweifel.cz
docker run -d --name christoph-zweifel-thesis -p 127.0.0.1:10002:10002 -e GUNICORN_CMD_ARGS="--bind 0.0.0.0:10002 --workers=2 --threads=2 --timeout=60 --access-logfile - --error-logfile - --forwarded-allow-ips=*" smart-voting-booklet-app:latest
To check if things are running smoothly or debug:
docker ps
docker logs christoph-zweifel-thesis
To stop and remove both the container and the built app:
docker stop christoph-zweifel-thesis
docker rm christoph-zweifel-thesis
docker rmi smart-voting-booklet-app
The Federal Chancellery (Bundeskanzlei) kindly provided two endpoints to fetch data about past Popular Votes and their respective information (Erläuterungen).
The module swissparlpy is used to fetch information about parlamentary votes to enrich the data in the protopye.
All .txt files in data/srfArena have been accessed by
Digital Democracy Lab, a Swiss
organization concerned with X. In April 2019, they have published a study how much gender, individuals and
political parties are represented in Switzerland best known debating shown. The same dataset, contained of transcribed
and annotated subtitles of the debates could be used for argumentation mining and later be assessed for the degree of
polarization, populism or other properties of the statement.