feat: GLM 응답에서 assistant 텍스트 추출 로직 개선 및 관련 경고 메시지 추가
- GLM 응답의 content가 비어있을 경우 reasoning_content를 대신 사용하도록 로직 개선 - 새로운 메서드 _extract_glm_assistant_text 추가하여 assistant 텍스트 추출을 명확히 함 - 관련 단위 테스트 추가 및 README.md에 변경 사항 반영
This commit is contained in:
@@ -312,19 +312,15 @@ class AIPlanner:
|
||||
|
||||
t_json0 = time.perf_counter()
|
||||
data = json.loads(raw_text)
|
||||
content = data["choices"][0]["message"]["content"].strip()
|
||||
if not content:
|
||||
# content가 비어있으면 이후 JSON 파서가 원인 파악이 어렵다.
|
||||
# GLM_DEBUG=1에서 raw 응답 일부를 함께 보여준다.
|
||||
if _glm_debug_enabled():
|
||||
finish_reason = data.get("choices", [{}])[0].get("finish_reason")
|
||||
print(
|
||||
"[경고] GLM 응답 content 비어있음 | "
|
||||
f"finish_reason={finish_reason!r} | "
|
||||
f"raw_preview={raw_text[:600]!r}"
|
||||
)
|
||||
else:
|
||||
print("[경고] GLM 응답 content가 비어있습니다. (GLM_DEBUG=1 시 raw_preview 출력)")
|
||||
content = self._extract_glm_assistant_text(data).strip()
|
||||
if not content and _glm_debug_enabled():
|
||||
# content가 비어있으면 아래 파서에서 원인 추적이 어려워지므로 raw 일부를 남긴다.
|
||||
finish_reason = data.get("choices", [{}])[0].get("finish_reason")
|
||||
print(
|
||||
"[경고] GLM 응답 assistant text 비어있음 | "
|
||||
f"finish_reason={finish_reason!r} | "
|
||||
f"raw_preview={raw_text[:600]!r}"
|
||||
)
|
||||
t_json_done = time.perf_counter()
|
||||
|
||||
dt_total = time.perf_counter() - t_total0
|
||||
@@ -354,6 +350,35 @@ class AIPlanner:
|
||||
f"GLM API HTTP {e.code}: {body[:1200]}"
|
||||
) from e
|
||||
|
||||
@staticmethod
|
||||
def _extract_glm_assistant_text(data: dict) -> str:
|
||||
"""
|
||||
GLM 응답에서 사용자가 기대하는 assistant 텍스트를 뽑는다.
|
||||
|
||||
관찰 케이스:
|
||||
- finish_reason='length' 인데 message.content가 ''로 오고,
|
||||
message.reasoning_content에 실제 출력(JSON)이 포함되는 패턴이 있다.
|
||||
"""
|
||||
choices = data.get("choices") if isinstance(data, dict) else None
|
||||
if not choices or not isinstance(choices, list):
|
||||
return ""
|
||||
choice0 = choices[0] if choices else {}
|
||||
if not isinstance(choice0, dict):
|
||||
return ""
|
||||
msg = choice0.get("message", {})
|
||||
if not isinstance(msg, dict):
|
||||
return ""
|
||||
|
||||
content = msg.get("content") or ""
|
||||
if isinstance(content, str) and content.strip():
|
||||
return content
|
||||
|
||||
reasoning = msg.get("reasoning_content") or ""
|
||||
if isinstance(reasoning, str):
|
||||
return reasoning
|
||||
|
||||
return ""
|
||||
|
||||
def _parse_json(self, raw: str) -> dict:
|
||||
text = raw.strip()
|
||||
if "<think>" in text:
|
||||
|
||||
Reference in New Issue
Block a user