feat: добавлена фуригана для японского во все промпты AI

Теперь во всех промптах для японского языка обязательно добавляется
фуригана к кандзи в формате: 漢字(かんじ)

Обновлены методы:
- generate_mini_story
- generate_thematic_words
- extract_words_from_text
- generate_words_of_day_batch
- generate_level_test
- generate_grammar_exercise
- generate_task_sentences_batch
- start_conversation / continue_conversation (уже было)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-10 14:08:37 +03:00
parent 1d29055f69
commit b74ea2170c

View File

@@ -633,6 +633,13 @@ class AIService:
if not tasks_description: if not tasks_description:
return [] return []
# Инструкция для фуриганы в японском
furigana_instruction = ""
if learning_lang == "ja":
furigana_instruction = """
- ОБЯЗАТЕЛЬНО: добавляй фуригану к кандзи в формате: 漢字(かんじ)
- Пример: 私(わたし)は毎日(まいにち)___を読(よ)みます。"""
prompt = f"""Создай предложения на языке {learning_lang} для следующих заданий: prompt = f"""Создай предложения на языке {learning_lang} для следующих заданий:
{chr(10).join(tasks_description)} {chr(10).join(tasks_description)}
@@ -652,7 +659,7 @@ class AIService:
- Для fill_blank: замени целевое слово на ___, укажи answer - Для fill_blank: замени целевое слово на ___, укажи answer
- Для sentence_translate: просто предложение со словом, answer не нужен - Для sentence_translate: просто предложение со словом, answer не нужен
- Предложения должны быть простыми (5-10 слов) - Предложения должны быть простыми (5-10 слов)
- Контекст должен подсказывать правильное слово - Контекст должен подсказывать правильное слово{furigana_instruction}
- Верни результаты В ТОМ ЖЕ ПОРЯДКЕ что и задания""" - Верни результаты В ТОМ ЖЕ ПОРЯДКЕ что и задания"""
try: try:
@@ -740,6 +747,13 @@ class AIService:
Эти слова пользователь уже знает. ОБЯЗАТЕЛЬНО выбери ДРУГИЕ слова!""" Эти слова пользователь уже знает. ОБЯЗАТЕЛЬНО выбери ДРУГИЕ слова!"""
# Инструкция для фуриганы в японском
furigana_instruction = ""
if learning_lang == "ja":
furigana_instruction = """
- ОБЯЗАТЕЛЬНО: в примерах добавляй фуригану к кандзи в формате: 漢字(かんじ)
- Пример: 私(わたし)は毎日(まいにち)本(ほん)を読(よ)みます。"""
prompt = f"""Создай подборку из {count} слов на языке {learning_lang} по теме "{theme}" для уровня {level}. Переводы дай на {translation_lang}. prompt = f"""Создай подборку из {count} слов на языке {learning_lang} по теме "{theme}" для уровня {level}. Переводы дай на {translation_lang}.
{exclude_instruction} {exclude_instruction}
Верни ответ в формате JSON: Верни ответ в формате JSON:
@@ -749,7 +763,7 @@ class AIService:
{{ {{
"word": "слово на {learning_lang}", "word": "слово на {learning_lang}",
"translation": "перевод на {translation_lang}", "translation": "перевод на {translation_lang}",
"transcription": "транскрипция в IPA (если применимо)", "transcription": "транскрипция в IPA (для английского) или хирагана (для японского)",
"example": "пример использования на {learning_lang}", "example": "пример использования на {learning_lang}",
"example_translation": "перевод примера на {translation_lang}" "example_translation": "перевод примера на {translation_lang}"
}} }}
@@ -760,7 +774,7 @@ class AIService:
- Полезными и часто используемыми - Полезными и часто используемыми
- Соответствовать уровню {level} - Соответствовать уровню {level}
- Связаны с темой "{theme}" - Связаны с темой "{theme}"
- Разнообразными (существительные, глаголы, прилагательные)""" - Разнообразными (существительные, глаголы, прилагательные){furigana_instruction}"""
try: try:
logger.info(f"[AI Request] generate_thematic_words: theme='{theme}', level='{level}', count={count}, learn='{learning_lang}', to='{translation_lang}'") logger.info(f"[AI Request] generate_thematic_words: theme='{theme}', level='{level}', count={count}, learn='{learning_lang}', to='{translation_lang}'")
@@ -809,6 +823,13 @@ class AIService:
Returns: Returns:
Список словарей с информацией о словах Список словарей с информацией о словах
""" """
# Инструкция для фуриганы в японском
furigana_instruction = ""
if learning_lang == "ja":
furigana_instruction = """
- ОБЯЗАТЕЛЬНО: в context добавляй фуригану к кандзи в формате: 漢字(かんじ)
- Для transcription используй хирагану"""
prompt = f"""Проанализируй следующий текст на языке {learning_lang} и извлеки из него до {max_words} самых полезных слов для изучения на уровне {level}. Переводы дай на {translation_lang}. prompt = f"""Проанализируй следующий текст на языке {learning_lang} и извлеки из него до {max_words} самых полезных слов для изучения на уровне {level}. Переводы дай на {translation_lang}.
Текст: Текст:
@@ -820,7 +841,7 @@ class AIService:
{{ {{
"word": "слово на {learning_lang} (в базовой форме)", "word": "слово на {learning_lang} (в базовой форме)",
"translation": "перевод на {translation_lang}", "translation": "перевод на {translation_lang}",
"transcription": "транскрипция в IPA (если применимо)", "transcription": "транскрипция в IPA (для английского) или хирагана (для японского)",
"context": "предложение из текста на {learning_lang}, где используется это слово" "context": "предложение из текста на {learning_lang}, где используется это слово"
}} }}
] ]
@@ -831,7 +852,7 @@ class AIService:
- Слова должны быть интересны для уровня {level} - Слова должны быть интересны для уровня {level}
- Не включай простейшие слова (a, the, is, и т.д.) - Не включай простейшие слова (a, the, is, и т.д.)
- Слова должны быть в базовой форме (инфинитив для глаголов, ед.число для существительных) - Слова должны быть в базовой форме (инфинитив для глаголов, ед.число для существительных)
- Разнообразие: существительные, глаголы, прилагательные, устойчивые выражения""" - Разнообразие: существительные, глаголы, прилагательные, устойчивые выражения{furigana_instruction}"""
try: try:
text_preview = text[:100] + "..." if len(text) > 100 else text text_preview = text[:100] + "..." if len(text) > 100 else text
@@ -1045,6 +1066,7 @@ User: {user_message}
Список из 7 вопросов разной сложности Список из 7 вопросов разной сложности
""" """
# Определяем систему уровней и язык для промпта # Определяем систему уровней и язык для промпта
furigana_instruction = ""
if learning_language == "ja": if learning_language == "ja":
level_system = "JLPT (N5-N1)" level_system = "JLPT (N5-N1)"
language_name = "японского" language_name = "японского"
@@ -1053,6 +1075,9 @@ User: {user_message}
- Вопросы 5-6: уровень N2 (продвинутый) - Вопросы 5-6: уровень N2 (продвинутый)
- Вопрос 7: уровень N1 (профессиональный)""" - Вопрос 7: уровень N1 (профессиональный)"""
level_example = "N5" level_example = "N5"
furigana_instruction = """
- ОБЯЗАТЕЛЬНО: добавляй фуригану к кандзи в формате: 漢字(かんじ)
- Пример: 私(わたし)は毎日(まいにち)学校(がっこう)に行(い)きます。"""
else: else:
level_system = "CEFR (A1-C2)" level_system = "CEFR (A1-C2)"
lang_names = {"en": "английского", "es": "испанского", "de": "немецкого", "fr": "французского"} lang_names = {"en": "английского", "es": "испанского", "de": "немецкого", "fr": "французского"}
@@ -1082,7 +1107,7 @@ User: {user_message}
{levels_req} {levels_req}
- Каждый вопрос с 4 вариантами ответа - Каждый вопрос с 4 вариантами ответа
- correct - индекс правильного ответа (0-3) - correct - индекс правильного ответа (0-3)
- Вопросы на грамматику, лексику и понимание""" - Вопросы на грамматику, лексику и понимание{furigana_instruction}"""
try: try:
logger.info(f"[AI Request] generate_level_test: generating 7 questions for {learning_language}") logger.info(f"[AI Request] generate_level_test: generating 7 questions for {learning_language}")
@@ -1258,8 +1283,12 @@ User: {user_message}
Returns: Returns:
Список упражнений Список упражнений
""" """
furigana_instruction = ""
if learning_lang == "ja": if learning_lang == "ja":
language_name = "японском" language_name = "японском"
furigana_instruction = """
- ОБЯЗАТЕЛЬНО: добавляй фуригану к кандзи в формате: 漢字(かんじ)
- Пример: 私(わたし)は毎日(まいにち)___に行(い)きます。"""
else: else:
language_name = "английском" language_name = "английском"
@@ -1288,7 +1317,7 @@ User: {user_message}
- ВАЖНО: translation должен быть ПОЛНЫМ переводом готового предложения (без пропусков), чтобы ученик понимал смысл - ВАЖНО: translation должен быть ПОЛНЫМ переводом готового предложения (без пропусков), чтобы ученик понимал смысл
- Подсказка должна направлять к ответу, но не содержать его - Подсказка должна направлять к ответу, но не содержать его
- Объяснение должно быть понятным для уровня {level} - Объяснение должно быть понятным для уровня {level}
- Сложность должна соответствовать уровню {level}""" - Сложность должна соответствовать уровню {level}{furigana_instruction}"""
try: try:
logger.info(f"[AI Request] generate_grammar_exercise: topic='{topic_name}', level='{level}'") logger.info(f"[AI Request] generate_grammar_exercise: topic='{topic_name}', level='{level}'")
@@ -1408,13 +1437,20 @@ User: {user_message}
levels_str = ", ".join(levels) levels_str = ", ".join(levels)
# Инструкция для фуриганы в японском
furigana_instruction = ""
if language == "ja":
furigana_instruction = """
- ОБЯЗАТЕЛЬНО: в примерах (sentence) добавляй фуригану к кандзи в формате: 漢字(かんじ)
- Пример: 私(わたし)は毎日(まいにち)本(ほん)を読(よ)みます。"""
prompt = f"""Сгенерируй "слово дня" для изучающих {language_name} язык на каждом из уровней: {levels_str}. prompt = f"""Сгенерируй "слово дня" для изучающих {language_name} язык на каждом из уровней: {levels_str}.
Требования для каждого слова: Требования для каждого слова:
- Слово должно быть полезным и интересным - Слово должно быть полезным и интересным
- Строго соответствовать указанному уровню сложности - Строго соответствовать указанному уровню сложности
- Желательно с интересной этимологией или фактом - Желательно с интересной этимологией или фактом
- Все слова должны быть РАЗНЫМИ{excluded_info} - Все слова должны быть РАЗНЫМИ{furigana_instruction}{excluded_info}
Верни JSON объект, где ключи - уровни ({levels_str}): Верни JSON объект, где ключи - уровни ({levels_str}):
{{ {{
@@ -1526,6 +1562,14 @@ User: {user_message}
}}''') }}''')
questions_json = ",\n".join(questions_examples) questions_json = ",\n".join(questions_examples)
# Специальные инструкции для японского языка
japanese_instructions = ""
if learning_lang == "ja":
japanese_instructions = """
- ОБЯЗАТЕЛЬНО: Для КАЖДОГО кандзи добавляй фуригану в формате: 漢字(かんじ)
- Пример: 私(わたし)は毎日(まいにち)学校(がっこう)に行(い)きます。
- Это критически важно для изучающих японский!"""
prompt = f"""Создай {genre_desc} на {language_name} языке для уровня {level}. prompt = f"""Создай {genre_desc} на {language_name} языке для уровня {level}.
Требования: Требования:
@@ -1533,7 +1577,7 @@ User: {user_message}
- Используй лексику и грамматику подходящую для уровня {level} - Используй лексику и грамматику подходящую для уровня {level}
- История должна быть интересной и законченной - История должна быть интересной и законченной
- Выдели 5-8 ключевых слов которые могут быть новыми для изучающего - Выдели 5-8 ключевых слов которые могут быть новыми для изучающего
- Добавь полный перевод текста на {translation_name} язык - Добавь полный перевод текста на {translation_name} язык{japanese_instructions}
Верни JSON: Верни JSON:
{{ {{