Prise en compte du langage de l'utilisateur pour le prompt de réponse. Si par exemple l'interface est en anglais, les IA vont favoriser l'anglais pour la réponse

This commit is contained in:
2026-06-15 09:49:05 +02:00
parent 914767f793
commit 84025911f8
29 changed files with 319 additions and 63 deletions

View File

@@ -31,6 +31,7 @@ from app.domain.models import (
QuestSummary,
SessionContext,
)
from app.core.language import DEFAULT as _DEFAULT_LANG, language_name
from app.domain.ports import LLMChatProvider
@@ -40,11 +41,13 @@ from app.domain.ports import LLMChatProvider
_DEFAULT_TEMPERATURE = 0.7
_BASE_SYSTEM = """Tu es un assistant d'écriture pour un Maître de Jeu de JDR.
def _base_system(language: str) -> str:
"""System prompt de base, avec la langue de réponse pilotée par l'utilisateur."""
return f"""Tu es un assistant d'écriture pour un Maître de Jeu de JDR.
Tu dialogues avec le MJ pour l'aider à enrichir son univers et ses campagnes.
Règles de ton :
- Réponds en français, ton chaleureux et créatif.
- Réponds en {language_name(language)}, ton chaleureux et créatif.
- Sois concis : listes à puces courtes plutôt que longs paragraphes.
- Propose des idées qui s'intègrent dans le contexte existant ci-dessous.
@@ -71,16 +74,18 @@ class ChatUseCase:
narrative_entity: NarrativeEntityContext | None = None,
game_system_context: GameSystemContext | None = None,
session_context: SessionContext | None = None,
language: str = _DEFAULT_LANG,
) -> AsyncIterator[str]:
"""Streame les tokens de la réponse assistant pour le dernier message user.
Les contextes sont tous optionnels, mais au moins l'un des deux
"niveaux haut" (lore_context ou campaign_context) doit être fourni
pour que le prompt ait du sens. Le controller (main.py) applique
cette règle à la frontière HTTP.
cette règle à la frontière HTTP. `language` pilote la langue de réponse.
"""
system_prompt = self._build_system_prompt(
lore_context, page_context, campaign_context, narrative_entity, game_system_context, session_context
lore_context, page_context, campaign_context, narrative_entity,
game_system_context, session_context, language,
)
async for token in self._llm.stream_chat(
messages,
@@ -97,12 +102,14 @@ class ChatUseCase:
narrative_entity: NarrativeEntityContext | None = None,
game_system_context: GameSystemContext | None = None,
session_context: SessionContext | None = None,
language: str = _DEFAULT_LANG,
) -> str:
"""Version publique — utilisée par le controller HTTP pour compter
les tokens du system prompt avant de streamer (jauge de contexte).
"""
return self._build_system_prompt(
lore_context, page_context, campaign_context, narrative_entity, game_system_context, session_context
lore_context, page_context, campaign_context, narrative_entity,
game_system_context, session_context, language,
)
# --- Construction du system prompt --------------------------------------
@@ -115,8 +122,9 @@ class ChatUseCase:
narrative: NarrativeEntityContext | None,
game_system: GameSystemContext | None = None,
session: SessionContext | None = None,
language: str = _DEFAULT_LANG,
) -> str:
sections = [_BASE_SYSTEM]
sections = [_base_system(language)]
if lore is not None:
sections.append(self._format_lore(lore))
if campaign is not None: