Hun-Bot

Japanese Speaking App for JLPT & Business Conversation Practice, Part 1

jlpt business japanese app devlog

Japanese Speaking App for JLPT & Business Conversation Practice, Part 1

I have been studying Japanese for about seven months since last June. I did not like the Japanese conversation practice apps on the market or the apps shown in YouTube ads, so I wanted to build one myself and see what technical limitations make it hard to build a good study app.

The conditions I consider necessary for a good Japanese speaking practice app are:

  1. It should support practice across many situations, from daily conversation to business conversation, and it should allow natural use of polite language, respectful language, and humble language. The target level is above JLPT N1.
  2. Users should be able to improve conversation ability by speaking with AI through voice-based real-time interaction.
  3. It should provide feedback based on what the user said, helping them improve mistakes.
  4. It should support interview practice by asking and evaluating various questions about the user’s major, portfolio, and resume. It should always assume the worst-case scenario, and every question should include follow-up questions that encourage deeper answers.
  5. Strong security should ensure that user personal information and conversation contents are not leaked outside.

With these thoughts in mind, I used Gemini Deep Research to organize the necessary technologies and the development direction.


Initial Tech Stack Selection

CategoryTechnologyReason
LanguagePython 3.11+Richest AI/ML library ecosystem.
OrchestrationLangGraphOptimized for agent workflows where cycles and state management are essential. Suitable for complex conversation flow control, not just simple chains.
LLM (Text)CyberAgentLM3-22B-Chat (GGUF) or Llama-3-Elyza-JP-8BStrong Japanese-specific performance and can be run locally or through low-cost APIs.
TTS (Audio)Style-Bert-VITS2Open-source model that expresses Japanese intonation and emotions such as joy, anger, and embarrassment most naturally.
RAG & SearchQdrant (Vector DB) + SudachiPy (Tokenizer)Supports hybrid search and uses a tokenizer optimized for Japanese morphological analysis.
UI/UXChainlitFast and efficient for conversational AI prototyping, and good for visualizing the chain-of-thought-style process.

For real-time conversation, the most important part, I thought Chainlit alone would not be enough. So I considered which real-time communication framework to use.

FeatureChainlitGradioLiveKit
Main useChat-style LLM appsML model demo/servingReal-time A/V infrastructure
Communication protocolWebSocketWebSocket / HTTPWebRTC (UDP/TCP)
LatencyMedium (500ms-1s)Medium (500ms-1s)Very low (<200ms)
Audio processingFile/chunk transferStream generatorRTP media stream
Barge-inDifficult, custom neededPossible but complexNative support
State managementPersistent chat sessionsState object passingReal-time room state
ScalabilityEasy vertical scalingEasy containerizationCloud/edge distributed processing

Based on this table, real-time audio communication and barge-in are essential, so I selected LiveKit as the main communication framework. I plan to build the frontend and backend with a LiveKit + [ ] combination.

Real-Time Voice Conversation

To achieve the behavior I want, the whole pipeline of speech recognition (STT), large language model (LLM), and speech synthesis (TTS) needs to be optimized as a streaming structure. I know streaming is a fairly difficult area to implement, so I will probably build it gradually and refine the direction as I go.

General Voice Conversation Flow (Non-Streaming)

StepComponentDescription
1VAD DelayTime spent waiting for silence to determine whether the user has finished speaking
2Audio UploadSend audio data to the cloud
3ASR ProcessingConvert the full audio into text
4LLM InferenceWait for the full answer text to be generated
5TTS SynthesisConvert the full text into audio
6Audio Download & BufferingPrepare playback

Problem: Each step is processed sequentially, so total latency accumulates and the system becomes unsuitable for real-time conversation.

Streaming Architecture (Real-Time)

StepTechnologyDescription
1Transport (WebRTC)Audio is split into 20ms frames and arrives at the server, LiveKit Agent, in real time
2Server-side VAD (Silero VAD)Analyze the audio frame stream in real time and detect speech start/end
3Streaming STT (ReazonSpeech v2)Push audio frames into the STT engine as soon as speech is detected and generate interim text results
4Speculative LLM ProcessingAdvanced optimization where the LLM prepares or starts generating tokens based only on interim STT results
5Streaming LLMThe LLM streams tokens instead of outputting the complete sentence at once
6Streaming TTS (Style-Bert-VITS2)Start audio synthesis immediately when text accumulates by punctuation or semantic unit
7PlaybackThe first synthesized audio chunk is immediately sent to the user through a WebRTC track

Benefit: Parallel processing and incremental result delivery minimize latency and enable natural real-time conversation.

Data Collection

Naturally, I first needed to collect data for business conversation and Japanese-specific language forms such as polite, respectful, and humble speech. The data to collect is below.

BSD (Business Scene Dialogue) Dataset: ryo0634/bsd_ja_en

  • Downloaded from Hugging Face
  • JSON-form dialogue data
  • Classified by situation, such as telephone, meeting, apology, and speaker relationship, such as superior-subordinate or client
  • Business manners documents: Collected from sites such as business-mail.jp
  • Honorific/grammar correction data: TMU Evaluation Corpus or KeiCO corpus

KeiCO Corpus

Source: GitHub - Liumx2020/KeiCO-corpus
Paper: Liu et al. (2022) - “Construction and Validation of a Japanese Honorific Corpus”

Scale: 10,007 sentences (5 annotations per sentence)
Annotations:
   - Honorific level (4 levels)
   - Respectful language (尊敬語/sonkeigo) classification
   - Humble language (謙譲語/kenjougo) classification
   - Polite language (丁寧語/teineigo) classification
   - Activity field

Honorific Level System (Level 1-4)

LevelNameUse caseMarker examples
1Highest respectFormal speeches, polite businessございます, 申し上げます, いたします
2General respectBusiness conversation, official documentsます, ございます
3Medium honorificEveryday respectます, です
4Casual respectClose relationships

Detecting Honorific Errors and Giving Feedback

I want to show feedback on screen as text in the following form. Alternatively, the feedback could also be spoken by voice.

# User's incorrect expression
user_utterance = "すみません。"  # Level 4 (casual)

# Classification learned from KeiCO data
correct_level = 1  # Business requires the highest respect
correct_form = "失礼いたします。"

# Generate feedback
feedback = "Your expression 'すみません' is Level 4. " \
           "In business situations, you should use the Level 1 expression '失礼いたします'."

Data Classification and Structuring

BSD Data Classification Schema

Scenario
├── Telephone
│   ├── Customer service
│   ├── Order confirmation
│   └── Problem solving
├── Meeting
│   ├── Business negotiation
│   ├── Project review
│   └── Result reporting
├── Apology
│   ├── Acknowledging a mistake
│   ├── Offering compensation
│   └── Restoring trust
└── Other
    ├── Email conversation
    └── Business card exchange

Speaker Relationship
├── Superior-Subordinate → Level 2 or higher required
├── Peers → Level 2-3
├── Business Partner → Level 1-2
├── New Customer → Level 1 recommended
└── Existing Customer → Level 2-3

Preprocessing and Morphological Segmentation

Why is morphological segmentation necessary?

Japanese does not use spaces, so it must be split into meaningful units. I need a tool specialized for Japanese that can perform morphological analysis and divide text by semantic units.

The tool that can classify text into meaningful units is SudachiPy, a fairly large Japanese morphological analyzer.

SudachiPy: https://pypi.org/project/SudachiPy/

WAP Tokushima Laboratory of AI and NLP: https://nlp.worksap.co.jp/

Embedding Generation

According to what I found, the model below is considered well suited for Japanese sentence embeddings. I will try it first, and if performance is not satisfactory, I will try other models.

Model selection: cl-nagoya/ruri-large (Japanese-specialized)

from sentence_transformers import SentenceTransformer

# Japanese-specialized model
model = SentenceTransformer('cl-nagoya/ruri-large')

# Convert text into 384-dimensional vectors
texts = [
    "会議でのビジネス敬語",
    "電話での丁寧な表現",
    "謝罪の文化"
]

embeddings = model.encode(texts)  # shape: (3, 384)

print(f"Embedding generation complete: {embeddings.shape}")

Building a Qdrant Vector DB

Qdrant is an open-source database optimized for vector search. It can efficiently store and retrieve large-scale embedding data. This option may also be replaced if a better vector DB is found.

Hybrid Search Implementation (Optional)

I plan to use a combination of vector search + BM25 keyword search. What is BM25? See https://www.geeksforgeeks.org/nlp/what-is-bm25-best-matching-25-algorithm/. In short, it is an algorithm that improves keyword-based search accuracy by considering term frequency and inverse document frequency.

I am not sure whether this is truly necessary. First I will implement vector search without BM25, and if performance is not satisfactory, I will add BM25 later.

References

Japanese Speaking App 1 / 1
이전 편 없음
다음 편 없음

Table of Contents

댓글