Interview Evidence is a local web app that transcribes interview audio with the RTZR Batch STT API and runs google/embeddinggemma-300m locally to retrieve candidate responses that are semantically related to a review criterion. Reviewers can verify each result against its transcript context and source audio.
Search results are suggestions for human review. The app does not evaluate or score candidates.
Interview Evidence helps interviewers quickly find candidate responses related to a specific evaluation criterion and review the transcript context and source audio as evidence for their assessment.
After an interview, locating evidence for a specific evaluation criterion in a long recording can be time-consuming. Interviewers need to find relevant responses and review their surrounding context before making an assessment. Keyword search may miss answers expressed in different words, while a transcript alone cannot convey the candidate's tone and delivery.
Interview Evidence combines speaker-aware transcription, semantic retrieval, transcript context, and source-audio playback to help interviewers find relevant responses and assess candidates based on supporting evidence.
- Speaker-aware transcription of two-person interviews through the RTZR Batch STT API
- Semantic retrieval of up to three candidate responses related to an evaluation criterion
- Review of each answer with its transcript and preceding conversational context
- Source-audio playback from the start of the selected answer to three seconds after it ends
- Structured JSON export of the evaluation criterion and timestamped answer evidence for documentation and follow-up review
Experience the functionality of this project by watching the demo video:
Watch the Demo
This project was developed and tested on macOS with Python 3.13.13.
All Python dependencies are pinned in requirements.txt.
Before you begin, make sure you have:
- An RTZR Developers application with its
RTZR_CLIENT_IDandRTZR_CLIENT_SECRET - A Hugging Face account with access to
google/embeddinggemma-300mafter accepting Google's usage license - A Hugging Face access token, configured as
HF_TOKEN, with permission to download the model
git clone https://github.com/logicallaw/interview-evidence.git
cd interview-evidenceThe following commands were tested on macOS:
python -m venv .venv
source .venv/bin/activatepython -m pip install -r requirements.txtCopy the example environment file:
cp .env.example .envAdd your credentials to .env:
RTZR_CLIENT_ID=
RTZR_CLIENT_SECRET=
HF_TOKEN=Do not commit the completed .env file.
google/embeddinggemma-300m is a gated model. Before running the preparation script, sign in to Hugging Face and accept the model's usage terms:
https://huggingface.co/google/embeddinggemma-300m
Then download and verify the model:
python scripts/prepare_model.pyThis step is optional for running the app but recommended for verifying the installation:
python -m pytestThe default test suite does not require RTZR credentials, a Hugging Face token, or external API access.
python -m streamlit run app.pyStreamlit will display the local URL in the terminal after the app starts.
The repository includes a synthetic two-person interview recording:
public/audio/interview-sample.wav
The recording is approximately 9 minutes and 11 seconds long. It was created for demonstration purposes and contains no real interview data.
To verify the complete workflow:
-
Upload
public/audio/interview-sample.wav. -
Start the RTZR transcription.
-
Review the representative utterances for both speakers.
-
Select the speaker who represents the candidate.
-
Because the sample interview is in Korean, enter the following evaluation criterion:
λμ μ νλκ° μ€μ μ΄μ μ±λ₯μΌλ‘ μ΄μ΄μ§μ§ μμμ λ μμΈμ μ΄λ»κ² λΆμνκ³ κ°μ νλκ°? -
Review a result with
μ΄ κ΅¬κ° λ£κΈ°(Listen to this segment) orμ μ¬ λ¬Έλ§₯ 보기(View transcript context). -
Download the results with
νμ¬ κ²μ κ²°κ³Ό λ΄λ €λ°κΈ°(Download current search results).
Interview audio file (WAV)
β Obtain an RTZR access token
β Submit the audio for transcription and wait for completion
β Review the speaker-labeled transcript and identify which speaker is the candidate
β Group the candidate's consecutive utterances into answer segments
β Enter an evaluation criterion
β Compare the criterion with the candidate's answers
β Present up to three answers closest in meaning to the criterion
β Review the selected answer with its transcript context and source audio
β Export the criterion, answers, and timestamps as structured JSON for follow-up review
The app obtains an RTZR access token, submits the WAV file to the Batch STT API, and polls the transcription job at a default interval of five seconds until it is completed. The resulting utterances are labeled by speaker so that the reviewer can identify which speaker is the candidate.
The candidate's consecutive utterances are grouped into answer segments. When the reviewer enters an evaluation criterion, the locally running google/embeddinggemma-300m model compares its meaning with the candidate's answers and returns up to three responses with the highest cosine similarity.
Each result can be reviewed with its transcript context and source audio. Audio playback starts at the beginning of the selected answer and continues until three seconds after it ends. The current criterion and timestamped answer evidence can then be exported as structured JSON for documentation and follow-up review.
interview-evidence/
βββ app.py # Streamlit UI and workflow orchestration
βββ scripts/
β βββ prepare_model.py # Downloads and verifies EmbeddingGemma
βββ src/
β βββ __init__.py
β βββ exporters.py # Builds the structured JSON export
β βββ rtzr_client.py # Handles RTZR authentication and transcription jobs
β βββ segments.py # Builds answer segments and playback boundaries
β βββ semantic_search.py # Embeds text and retrieves the Top-K answers
βββ tests/
β βββ __init__.py
β βββ conftest.py # Shared pytest fixtures
β βββ fixtures/
β β βββ rtzr_completed.json # Synthetic completed transcription response
β βββ test_exporters.py
β βββ test_integration.py
β βββ test_rtzr_client.py
β βββ test_segments.py
β βββ test_semantic_search.py
βββ public/
β βββ audio/
β βββ interview-sample.wav # Synthetic two-person interview audio
βββ docs/
β βββ ADR.md # Architecture decision records
β βββ ARCHITECTURE.md # System structure and data flow
β βββ PRD.md # Product scope and requirements
β βββ UI_GUIDE.md # UI states, copy, and visual guidelines
βββ .github/
β βββ ISSUE_TEMPLATE/ # Issue templates (bug, chore, docs, feature, fix)
β βββ pull_request_template.md # Pull request template
βββ .env.example # Environment variable template
βββ .gitignore
βββ requirements.txt # Pinned Python dependencies
βββ README.md- The app processes one WAV file at a time.
- It is designed for interviews with exactly two detected speakers, and the reviewer must identify which speaker is the candidate.
- Only one evaluation criterion can be searched at a time.
- The app returns up to three results without applying an absolute relevance threshold, so each result should be reviewed in context.
The public/audio/interview-sample.wav file was generated with NAVER CLOVA Dubbing from an original script written by logicallaw.
The recording is synthetic and does not contain real interview data. An audible attribution notice for NAVER CLOVA Dubbing is included at the beginning of the file.
This project was developed with reference to the following official documentation and examples:
- RTZR Authentication Guide β access-token authentication
- RTZR Batch STT API β file upload, transcription polling, response fields, and STT options
- RTZR Rate Limit β concurrency-limit handling and exponential backoff
- EmbeddingGemma Model Overview β model characteristics and usage requirements
- EmbeddingGemma with Sentence Transformers β model loading and retrieval query/document prompts
- RTZR Automatic Chapters Tutorial β conceptual reference during early exploration; the final project implements evaluation-criterion-based answer retrieval rather than automatic chapter segmentation
| Name | Role |
|---|---|
| Kim Jun-Ho (logicallaw) | Full-stack AI engineer |
- Fork the repository and clone it locally.
- Set up your development environment by following the π Quick Start section.
- Create an issue for your change. Pick a template from
.github/ISSUE_TEMPLATE/that matches the type of work. - Create a branch from main:
<type>/#<issue-number>-<slug>(e.g.fix/#16-playback) - Follow the commit message format:
<type>(#<issue>/<scope>): description(e.g.fix(#16/segments): remove pre-playback offset) - Run
python -m pytestand make sure all tests pass. - Open a PR using
.github/pull_request_template.mdand includeCloses #Nin the body.
For questions or support:
- Open a GitHub issue
- Email: logicallawbio@gmail.com
- GitHub: logicallaw