Skip to main content

German Spelling Alphabet

From Spelling Tool to Research Paper in an Afternoon

2 sessions41 prompts2h 32m human3h 25m AI
linguisticssimulated-annealingphoneticsALINE algorithmreact
View Live Project →
Project screenshot
Human: 2h 32m (43%)AI: 3h 25m (57%)

The Setup​

Brian lives in Germany. Most people know the NATO phonetic alphabet -- Alpha, Bravo, Charlie, Delta -- for spelling things clearly over the phone. Germany has its own equivalent, the Buchstabiertafel (A wie Anton, B wie Berta, C wie Cäsar), but it's not in Brian's head and he can never find a simple resource for it online.

He used Claude to research the domain first, discovering that Germany actually has two versions: the Traditional alphabet and the newer DIN 5009 standard. That shared understanding of the domain was the foundation before any code was written.

The goal: a simple React app where you type text and get back the spelling alphabet words ("bob" -> "Berta, Otto, Berta").

Part One: The Basic Tool​

Building the Tool — ~30 minutes | Scaffold, refinements, done

One prompt to scaffold: Claude generated a full Vite + React app with both Traditional and DIN 5009 alphabet data, ran npm install, started the dev server, and verified it in Puppeteer -- all from a single prompt.

Rapid stacked refinements followed (messages 2-8, ~30 minutes). Brian caught a culturally specific error immediately -- "zwei should be zwo" (Germans say "zwo" to avoid confusion with "drei"). He swapped a checkbox toggle for a split dropdown showing DIN vs. Traditional, added text-to-speech with a German voice fallback chain (de-DE -> de-AT -> de-CH -> any de-*), fixed eszett rendering ("SS should be ß" and "Instead of SS wie Eszett, just say Eszett"), separated letters and numbers into sub-groups in the reference table, and made letters clickable to speak ("A wie Anton"). Nearly every message stacked 2-5 directives at once.

Message 9: he commits everything. Working tool, done. But then...

Part Two: Phonetics & Computational Linguistics​

Session 1 (continued): The Research Pivot — Feb 5 | ~3.5 hours | ALINE algorithm, heatmaps, optimization planning

The Pivot​

Session
A single sentence transforms the project's trajectory
>I wanted to call this a 'research project' but I don't know how to do that. Right now it's just a nice tool, what opportunities are there?
>Oh, I wonder, can we detect similarity / confusion between the pairs? maybe a 2x2 heatmap?
#Also plants a seed: 'I also think we can invent our own that is better but that's a phase 3 thing. Keep it in the hat for now.'

Challenging the Methodology​

Claude suggested Levenshtein distance on IPA transcriptions. Brian pushed back.

Session
Knowing when something doesn't feel right
>I am not convinced Levenshtein is enough because some phenomes will be similar. I'm also not sure Levenshtein is a good methodology (I just don't understand the case for it, sounds arbitrary, not linguistic-thinking, is it?).
#Demands actual research: 'Any research on this topic?'
#Claude searches, finds the ALINE algorithm (Kondrak 2002) -- articulatory feature vectors with salience weights, published in computational linguistics
>ok let's do that.

He didn't know the right answer but he knew the proposed one didn't feel right. That instinct led to ALINE, which is the real thing.

ALINE Implementation​

Full ALINE algorithm in JavaScript, IPA transcriptions for all words, interactive heatmap with hover tooltips, confusable pairs list -- all built and committed. Refinements followed: triangular heatmap (removed duplicate A:B / B:A pairs), side-by-side comparison of Traditional vs. DIN 5009, top 10 most confusable and top 10 most distinct pairs, color scale fix (0% distinctiveness = red, 100% = green), four German-labeled interpretation levels (Sehr ähnlich through Sehr unterscheidbar).

Both existing alphabets -- Traditional and DIN 5009 -- scored an identical 78.4% distinctiveness. That was genuinely surprising: two completely different naming conventions, developed decades apart, landed on the exact same phonetic performance.

The Optimization Leap​

"I want to have an algo find the best word mapping using all german words" -- Phase 3 arrived within hours of being on the mental backlog.

Downloaded ipa-dict (350K+ German word pronunciations), German cities list. Filtered to ~61K candidates by length (3-10 chars), syllable count (max 3, preference for 1-2), and excluded inflected forms. Brian's intuition on filtering: "I wonder if we can avoid compound words? German is full of those and an algo not aware of this could be an issue." Used Claude's plan mode to design the full optimization script architecture before writing a line of code.

Session 2: Optimization and Research Paper — Feb 5-6 | 2 hours | 13 prompts | Simulated annealing, quality loop, paper writeup

Building the Optimizer​

Brian provided the implementation plan and said go. Claude built the full simulated annealing optimizer, ran it, generated results, and built a three-way comparison UI between Traditional, DIN 5009, and the algorithmically optimal alphabet.

The Delegated Quality Loop​

Results came back with "Aab" and "Uds" as optimal words. Brian: "are those all real words? I never heard of Aab or Uds."

Session
Designing a process, then handing judgment to Claude
>Yeah let's use a feedback loop here. You will maintain a filter file. Run the script, and anything that looks weird gets filtered. Run it until you are satisfied the words are not strange.
#Claude runs 13+ iterations: obscure surnames, genitives, technical terms, regional words, foreign words all caught and excluded. Created a block/allow list with 198 uncommon German words filtered out.
#Brian's only intervention during the loop: a single 'continue' when the context window needed it

Final result: 81.98% distinctiveness on the algorithmically optimal alphabet vs. 78.44% on DIN 5009 and 78.36% on the Traditional standard. Without the word-quality filtering, the algorithm reached 87.1% -- but with words like Aab, Ith, and Enquete that nobody would use in practice. The 5.1 percentage point cost of constraining to recognizable words (Aal, Ball, Chef, Igel, Milch, Wald) is the price of practical usability.

Research Paper + Polish​

"Write a mini section at the end that is like a research paper... abstract, method, findings... nothing too complex, but explain it." Also: "the methodology needs to describe how I used Claude Opus 4.6 to remove words that didn't meet specific standards."

Session
Genuine self-assessment after hours of building
>cool, now let's sit back and review. is this interesting at all? is something missing? something wrong? Who cares about this?

Final details: excluded words displayed as comma-separated list with a summary of why ("annoying, in the Ausgeschlossene Worter section you just kind of dump the file to jsx. Don't do that."), computed unfiltered optimization score for comparison, made DIN the default, meta tags, OG image via Puppeteer screenshot, removed footer, added TTS to the optimal alphabet text field.

What This Shows​

Research-First, Not Code-First

Brian did the domain research with Claude before writing any code, building a shared understanding of the DIN and Traditional alphabets. The most consequential messages aren't instructions -- they're Brian thinking out loud. "I wanted to call this a research project but I don't know how to do that" created the entire second half of the project. "I also think we can invent our own that is better" planted the optimization seed.

Using Claude to Explore Better Techniques

Brian didn't know what the right algorithm was, but he knew Levenshtein "sounds arbitrary, not linguistic-thinking." He used Claude to explore alternatives, learn about phonetic distance methods he'd never encountered, and weigh trade-offs between approaches. They looked at several methods before landing on ALINE (Kondrak 2002). The instinct that something doesn't feel right, combined with Claude's ability to search and summarize research, is what gets you from a naive first attempt to the real thing.

The Human as Quality Gate

Brian designed the word-filtering loop and delegated judgment to Claude. It took Claude 13 iterations to reach an optimal set -- filtering obscure surnames, genitives, technical terms, and foreign words along the way. Brian's only intervention was a single "continue" when the context window needed it. The human defines the standard; the AI does the reps.