fix: deterministic weather → one clean Korean sentence (no 'Celsius')
getWeather now returns only the Korean sentence (지금 <곳> 날씨는 <상태>, 기온 N도 (체감 M도)입니다) with no English/°C source. A deterministic weather path in the engine returns it verbatim, bypassing the 7B which was rephrasing into multiple sentences and leaking 'Celsius'.
This commit is contained in:
@@ -889,6 +889,37 @@ def _maybe_deterministic_site_search(text: str, db, cfg, language) -> Optional[s
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
_WEATHER_INTENT_WORDS = (
|
||||||
|
"날씨", "기온", "더워", "더운", "추워", "추운", "비 와", "비와", "비 올",
|
||||||
|
"눈 와", "눈와", "weather", "temperature", "forecast",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _maybe_deterministic_weather(text: str, db, cfg, language) -> Optional[str]:
|
||||||
|
"""Run getWeather directly and return its concise Korean sentence, bypassing
|
||||||
|
the chat model. The 7B otherwise re-synthesises the weather into multiple
|
||||||
|
sentences and leaks units ("25도 Celsius"); the tool already formats one
|
||||||
|
clean Korean sentence, so for a plain weather ask we just return it.
|
||||||
|
Fail-open: any problem returns None and the normal flow continues.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
low = (text or "").lower()
|
||||||
|
if not any(w in low for w in _WEATHER_INTENT_WORDS):
|
||||||
|
return None
|
||||||
|
from ..tools.registry import run_tool_with_retries
|
||||||
|
res = run_tool_with_retries(
|
||||||
|
db=db, cfg=cfg, tool_name="getWeather", tool_args={},
|
||||||
|
system_prompt="", original_prompt="", redacted_text=redact(text),
|
||||||
|
max_retries=1, language=language,
|
||||||
|
)
|
||||||
|
if res and getattr(res, "success", False) and res.reply_text:
|
||||||
|
debug_log("deterministic weather executed", "tools")
|
||||||
|
return res.reply_text
|
||||||
|
except Exception as e: # noqa: BLE001
|
||||||
|
debug_log(f"deterministic weather failed (fail-open): {e}", "tools")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
|
def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
|
||||||
text: str, dialogue_memory: "DialogueMemory",
|
text: str, dialogue_memory: "DialogueMemory",
|
||||||
language: Optional[str] = None) -> Optional[str]:
|
language: Optional[str] = None) -> Optional[str]:
|
||||||
@@ -920,6 +951,13 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
|
|||||||
if _site_search_reply is not None:
|
if _site_search_reply is not None:
|
||||||
return _site_search_reply
|
return _site_search_reply
|
||||||
|
|
||||||
|
# Step 0.6: Deterministic weather — return getWeather's concise Korean
|
||||||
|
# sentence directly so the chat model can't rephrase it into multiple
|
||||||
|
# sentences or leak units.
|
||||||
|
_weather_reply = _maybe_deterministic_weather(text, db, cfg, language)
|
||||||
|
if _weather_reply is not None:
|
||||||
|
return _weather_reply
|
||||||
|
|
||||||
# Step 2: Check for recent dialogue context
|
# Step 2: Check for recent dialogue context
|
||||||
recent_messages = []
|
recent_messages = []
|
||||||
is_new_conversation = True
|
is_new_conversation = True
|
||||||
|
|||||||
@@ -440,17 +440,11 @@ class WeatherTool(Tool):
|
|||||||
_ko_parts.append(_t)
|
_ko_parts.append(_t)
|
||||||
ko_sentence = ", ".join(_ko_parts) + "입니다."
|
ko_sentence = ", ".join(_ko_parts) + "입니다."
|
||||||
|
|
||||||
# Build response text — concise current conditions (Korean sentence
|
# The reply is the clean Korean sentence ONLY — no English/°C source
|
||||||
# first so the model echoes it; English detail kept for any follow-up
|
# for the model to echo ("25도 Celsius"), no forecast firehose to
|
||||||
# reasoning but the forecast firehose is dropped to curb rambling).
|
# ramble over. The deterministic weather path in the engine returns
|
||||||
lines = [
|
# this verbatim; on the LLM path the model just echoes one sentence.
|
||||||
f"한국어로 정확히 이 한 문장만 답하세요: {ko_sentence}",
|
lines = [ko_sentence]
|
||||||
f"(참고 데이터 — 답변에 추가하지 말 것: {location_display}, {weather_desc}, "
|
|
||||||
f"{temp_c}°C feels {feels_like_c}°C, humidity {humidity}%, wind {wind_speed}km/h)",
|
|
||||||
]
|
|
||||||
# Forecast (hourly / 7-day) is intentionally omitted from the default
|
|
||||||
# voice reply to keep it to one spoken sentence; current conditions
|
|
||||||
# are what "날씨 알려줘" asks for.
|
|
||||||
|
|
||||||
reply_text = "\n".join(lines)
|
reply_text = "\n".join(lines)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user