3

Veriphrase — LLM-Generated Memorable Phrases for Confirmation Codes

A prototype that turns an opaque confirmation code into a memorable three-word phrase, using OpenAI to propose genre-themed words and NLTK part-of-speech tagging to filter them, behind a Django REST API and a Next.js 14 frontend.

Overview

Confirmation codes like X7KQ-29PL are easy for computers and hard for people, especially when a customer is reading one aloud to a support agent. Veriphrase explores a friendlier encoding: map each code to a short, memorable phrase such as silver-dragon-wanders, which is easier to say, hear and type back. It's a two-day prototype from July 2024, built to test whether an LLM could generate good candidate words reliably.

How it works

  1. The frontend posts a confirmation code and an optional genre. There are about 50 to choose from, such as fantasy, space or nature; the default is fantasy.
  2. The Django REST Framework backend asks OpenAI's chat completions API (gpt-3.5-turbo, 10 candidates, temperature 0.7) for words in that genre.
  3. Candidates are split into words and filtered with NLTK part-of-speech tagging, keeping only nouns, verbs, adjectives and adverbs. That removes the filler words LLMs tend to add.
  4. Three words are sampled and joined with hyphens into the phrase, which is returned to the client and recorded against the code.

Stack

  • Backend: Django 5 with Django REST Framework, django-cors-headers and Gunicorn.
  • Frontend: Next.js 14 with React 18 and TypeScript, Material UI and Tailwind.
  • Packaging: a Dockerfile for each service, Docker Compose for local development, and Kubernetes Deployment and Service manifests targeting Azure Container Registry images.

What a production version needs

The prototype answers the interesting question — LLM plus POS filtering gives pronounceable, on-theme phrases — but it's deliberately thin elsewhere, and making it production-grade would mean:

  • Durable, collision-checked storage. Mappings are held in memory, so they don't survive a restart and decoding isn't yet keyed by phrase. A real version stores code ↔ phrase pairs in a database with a uniqueness constraint and retries on collision.
  • A deterministic option. For high volume, a fixed curated wordlist (in the spirit of the EFF dice lists) indexed by the code's bits gives reversible encoding with no LLM call on the hot path, with the LLM kept for curating themed lists offline.
  • Hardening: environment-specific settings, restricted allowed hosts, authentication and rate limiting on the encode endpoint, and tests.
  • Lean dependencies: the backend pins several ML frameworks it doesn't import, which bloats the image.

Built with

  • Python, Django 5, Django REST Framework, NLTK, OpenAI API
  • Next.js 14, React 18, TypeScript, Material UI, Tailwind CSS
  • Docker, Docker Compose, Kubernetes manifests