跳到正文
DEV Community· ADK BBX·· 3 小時前AI 評分52

Aoandon 提供 Lafcadio Hearn 五篇怪談的 JLPT N5 至 N1 日文改寫

Aoandon: Hearn's ghost stories in Japanese, retold at five JLPT levels

AI 導讀

作者開發 Aoandon,使用 Gemma 4 31B 將 Lafcadio Hearn 的 5 篇怪談改寫至 JLPT N5 至 N1 五個級別,共 53 個場景、265 個版本。用戶可逐幕閲讀、答題並熄滅蠟燭,點選詞語查看讀音和意思,再匯出為 Anki 卡組。原文一按即可查看;網站採 MIT 授權,毋須帳戶、追蹤、後端或 API key,進度和詞語保存在瀏覽器。

正文

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

In Edo Japan, friends sometimes spent a night telling a hundred ghost stories. It was called hyakumonogatari. A hundred wicks burned inside a lantern covered with blue paper, in a room away from the guests. After each story, the teller walked to that room and put out one flame. The legend says that when the last flame goes out, the spirit of the blue lantern appears. Her name is Aoandon, 青行灯.

The Japanese ghost stories most people outside Japan know come from Lafcadio Hearn. Hearn never properly learned Japanese. His wife, Koizumi Setsu, found the old stories and told them to him in her own words, and his book Kwaidan grew out of those tellings. (NHK's 2025 morning drama, Bakebake, is based on the two of them.)

I live in Japan and my Japanese is around N2. The Japanese translations of Hearn's stories are free on Aozora Bunko, so I opened one. This is how 貉 (Mujina) begins:

東京の、赤坂への道に紀国坂という坂道がある

That part is fine. The next sentence is 「何故それが紀伊の国の坂と呼ばれているのか、それは私の知らない事である。」 and it gets heavier from there. It is Meiji-era Japanese, more than a hundred years old.

So I built the thing Hearn had: someone who tells you the story in words you can follow. Except the someone is an open model, and it can tell it five different ways.

What I Built

Aoandon is a candlelit reading room for Japanese learners. It has five of Hearn's ghost stories, from the Japanese translations on Aozora Bunko:

  • 貉 (Mujina), the faceless woman by the moat
  • 茶碗の中 (In a Cup of Tea), a face that appears in the tea
  • 雪女 (Yuki-Onna), the snow woman
  • ろくろ首 (Rokuro-Kubi), heads that leave their bodies at night
  • 耳無芳一の話 (Mimi-Nashi-Hoichi), the blind biwa player and the ghosts of the Heike

Gemma 4 retold every scene of every story at all five JLPT levels, N5 to N1. That is 53 scenes and 265 retellings.

You pick your level and a story. You read one scene on washi paper, answer one question about it, and then hold a button (or blow into your microphone) to put out a candle. The room gets a little darker each time. Any word you tap shows its reading and meaning, and it "follows you home": it becomes a small blue ghost flame that circles the lantern, and you can export all of them as an Anki deck. When the hundredth candle goes out, Aoandon arrives.

A few things I cared about:

  • Every kanji above your level has furigana, and the original Meiji text is always one tap away. The app never pretends the retelling is the original.
  • Vertical text on a wide screen, like a real Japanese book, and horizontal on a phone.
  • No account, no tracking. Your progress and your words stay in your browser.
  • A demo night that starts at the 99th candle, so you can see the ending in one scene.

Here is the first line of 貉 at three of the five levels:

  • N5: とうきょうにさかがあります。紀伊国坂です。
  • N3: 東京のあかさかへの道に、紀伊国坂というさかがあります。
  • N1: 東京の赤坂へ向かう道に紀伊国坂という坂があるが、その理由は私にはわからない。

N5 is almost all kana and very short. N1 is close to the original's register.

Demo

Live site: https://aoandon.onrender.com

Demo night (starts at candle 99): https://aoandon.onrender.com/?night=demo#/shelf

Demo video (34 seconds, sound on). It was made with HyperFrames, an open-source tool that turns HTML into video, from screen recordings of the live site. The narration is ElevenLabs text-to-speech and the music was made with Eleven Music.

When you arrive, the title comes up like ink on paper and the hundred candles catch one after another:

The Aoandon room: the title fades in and a hundred candles light up on both sides of the five level seals

Choosing a story and a level:

Five ghost stories as hanging scrolls, with five level seals from N5 to N1

Reading in vertical text, with furigana only where your level needs it:

The reader: a washi sheet with vertical Japanese text, an illustration and a candle for each scene

Tap a word and it follows you home. Then answer the question and hold the button to blow out the candle for that scene:

Tapping 紀伊国坂 shows its reading and meaning, then the right answer is chosen and the scene's candle goes out

The hundredth candle. This is the demo night, so only one candle is left:

The last candle goes out, the room goes dark and Aoandon, the spirit of the blue lantern, appears

Code

GitHub logo adkbbx / aoandon

A hundred ghost stories by candlelight for Japanese learners: real Meiji-era kaidan retold at your JLPT level by Gemma 4.

Aoandon 青行灯

A hundred ghost stories by candlelight, for Japanese learners.

Live: https://aoandon.onrender.com · Demo night (starts at candle 99): https://aoandon.onrender.com/?night=demo#/shelf

Five of Lafcadio Hearn's ghost stories, in the Japanese translations on Aozora Bunko, retold by Gemma 4 at five JLPT levels from N5 to N1. Read a scene, answer one question and blow out a candle. Words you tap follow you home as blue ghost flames and export to Anki. When the hundredth candle goes out, 青行灯, the spirit of the blue lantern, arrives.

Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 4: Ghost in the Machine.

How the levels work

Every level follows its own cumulative JLPT kanji list: 79 kanji for N5, 245 for N4, 612 for N3, 979 for N2 and 2,211 for N1. A word whose kanji are above the level is written in kana; a word whose kanji are allowed is written in…

How I Built It

The pipeline

  1. Fetch the stories. A script downloads the five tales from Aozora Bunko, converts them from Shift_JIS, keeps Aozora's own furigana, and splits each story into scenes of a few paragraphs. 53 scenes in total.
  2. Retell each scene. Gemma 4 (31B, open weights) gets the original scene and a prompt that starts: "You are Koizumi Setsu. You are retelling a Japanese ghost story aloud to a foreign friend who is learning Japanese at JLPT N4." The rules change with the level: sentence length, grammar, and which kanji are allowed. It also writes one question about the scene.
  3. Check it. A checker splits the Japanese into words (kuromoji) and compares every word with open JLPT vocabulary lists, and every kanji with an open JLPT kanji list.
  4. Send it back. Sentences that break the rules go back to the model with the exact words to fix. Up to three rounds.
  5. Check the meaning. A second call compares the retelling with the original and lists numbers, people or events that changed. Those sentences get one more rewrite.

The stories are generated once and saved as plain files. The website just shows them, so it is a free static site and needs no API key.

Three versions, and the one that failed my own test

This part is the real story of the week.

Version 1 measured words only. The checker reported things like "97% of the words are N4 words", and I believed it. Then I read it. It was too hard, and I am N2. When I measured it properly, about a quarter of every retelling was kanji, at every level, including N5. Across the five stories there were about 3,800 kanji above the reader's level, and around 60% of them had no furigana, because the app only added furigana to hard words, not hard kanji. 驚く counted as an easy word even though the kanji is not easy. There was also a sneaky bug: a word could pass because its reading matched an easy word. 僧 (monk) passed as そう. 復讐 (revenge) passed as 復習 (review).

Version 2 forced hard kanji into kana. That fixed the furigana problem and broke something else. N3 ended up with the fewest kanji of all levels, 5% against 7% for N5. Kana-only text is actually harder for an N3 reader, because kanji show you where words begin. I told it the levels were backwards, and they were.

Version 3 follows the JLPT kanji list. Each level may only use kanji from its own list, counting everything below it: 79 kanji for N5, 245 for N4, 612 for N3, 979 for N2 and 2,211 for N1. A word whose kanji are above the level is written in kana. A word whose kanji are allowed must be written in kanji. Then every scene is checked so that each level is harder than the one before. These are the averages now:

Level Kanji in the text Average sentence Different kanji used Kanji outside the level's list
N5 9% 12 characters 47 0
N4 15% 17 characters 150 0
N3 22% 28 characters 369 0
N2 26% 34 characters 551 0
N1 31% 38 characters 903 0

(Names in the stories, like 芳一, are the only exception. They keep their kanji and always show furigana.)

The small model on my laptop

I wanted all of this to run on my laptop with Gemma 4 E2B through Ollama. It did not work. On the very first scene it got stuck and wrote 「むかしの」 more than fifty times in a row. The scenes it did finish had broken Japanese, like 「さびしいでした」. So the stories you read were written by the 31B model on DigitalOcean, and the small model stays a local experiment. The evidence for the current stories records 1,870 model calls, including all the rewrites.

The meaning check

The vocabulary checker cannot tell if a sentence is true. In the first version, 貉 said the old merchant saw the mujina thirty years ago. In Hearn, he died about thirty years ago. The meaning check caught that kind of thing: wrong numbers, wrong people, invented events. The N1 version now reads 「約30年前に死んだ年をとった商人」, which is what the original says.

The room

The front end is React and Vite. The hundred candles are one canvas so phones can handle them. The flames flicker on their own timing, the room darkens as candles go out, and the blue lantern grows brighter as the room gets darker. The images (the room, the lantern, the five story illustrations and Aoandon herself) were generated with gpt-image-2 in one woodblock-print style, and none of them contain text.

The room also has sound, made with ElevenLabs sound effects. When you tap, you hear wind against the paper screens and bell crickets outside. A candle catches when you arrive, a breath puts each one out, a glass furin chime rings when a word follows you home, and a distant temple bell sounds when the last candle goes out. Nothing is loud and nothing jumps out at you.

I planned and reviewed the project with Claude Code, and OpenAI Codex wrote most of the code from written briefs. I checked the Japanese myself.

Why Does Open Innovation Matter?

These stories have been free for a long time. Hearn wrote them, translators put them into Japanese, and volunteers at Aozora Bunko typed them up so anyone can read them. A tool for reading them should not be locked inside a service that might disappear. Aoandon is MIT licensed, the stories are saved as plain files, and the site needs no backend, no API key and no account.

Open weights mattered in a practical way too. I could run the same family of models on my laptop and on DigitalOcean, compare them honestly, and see exactly where the small one failed. I could change the prompt, the checker and the rules as many times as I needed (and I needed to, three times) without asking anyone.

And the project stands on open data made by people who did it for free: Jonathan Waller's JLPT lists, the open Anki decks built from them, an MIT-licensed list of kanji levels, and the Aozora Bunko volunteers. Without that, there is no way to say what "N4" even means.

The Spirit of It

The real test was not a number. The checker said the first version was 97% N4. I read it and said what I actually thought: this is not N5, N4 or N3, it is too difficult, and I am N2. That is the moment I stopped trusting the score and started measuring kanji.

The second test came a few hours later, when I noticed the fix had turned the levels upside down and N3 now looked easier than N5. So I set one rule the whole project had to follow: look at the JLPT kanji list and update the stories to match it. Everything in the table above comes from that rule.

The last test was the same as the first: I read it again, at my own level. This time my whole reaction was four words: feels like N2 now. The checker can tell me there are no kanji outside the list. Only reading it could tell me that.

What it can't do (yet)

  • The checker measures words and kanji, not truth. The meaning check still flags about a hundred sentences across 265 retellings, some of them false alarms. That is why the original is always one tap away.
  • Kanji share goes up from N5 to N1 in all 53 scenes, and sentence length in 50 of them. The share of harder words goes up on average (23%, 33%, 41%, 51%, 55%), but in about half the scenes two neighbouring levels swap by a few points.
  • The JLPT has not published official word or kanji lists since 2010, so every list, including the ones I used, is an approximation.
  • Some word meanings are written by the model, and they are marked as such.
  • "Retell again" only works on your own machine, with your own model.

Prize Categories

  • Best Use of Gemma: Gemma 4 31B wrote every retelling, every question and every meaning check. Gemma 4 E2B was tested locally, and the post shows where it failed.
  • Best Use of DigitalOcean: every retelling was generated on DigitalOcean's serverless inference with gemma-4-31B-it.
  • Best Use of Render: the site is a Render static site that redeploys from GitHub on every push.
  • Best Use of ElevenLabs: every sound in the room was generated with ElevenLabs sound effects: the night ambience with wind on the shoji and bell crickets, the candles catching and going out, the glass wind chime when a word follows you, and the temple bell when Aoandon arrives. In the demo video, the narration is ElevenLabs text-to-speech (Eleven v3) and the score is Eleven Music.

Credits

Stories by Lafcadio Hearn (小泉八雲), Japanese translations by 戸川明三 and 田部隆次, from Aozora Bunko. JLPT vocabulary from open-anki-jlpt-decks (MIT), based on Jonathan Waller's lists at tanos.co.uk. Kanji levels from kanji-data (MIT). Fonts: Shippori Mincho B1, Yuji Syuku and Zen Kaku Gothic New (OFL).

This is the final challenge of Hacktoberfest. I had so much fun this year and hope to be back again next year! Thank you.

來源:DEV Community · dev.to