feat: AIPlanner의 GLM 응답 처리 로직 개선
- content가 비어있거나 JSON 형태가 아닐 경우 reasoning_content를 우선 사용하도록 로직 개선 - JSON 유사성을 판단하는 헬퍼 함수 추가 및 기존 동작 유지 - 관련 단위 테스트 추가 및 README.md에 변경 사항 반영
This commit is contained in:
@@ -370,14 +370,35 @@ class AIPlanner:
|
||||
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 ""
|
||||
if not isinstance(content, str):
|
||||
content = ""
|
||||
if not isinstance(reasoning, str):
|
||||
reasoning = ""
|
||||
|
||||
# Heuristic:
|
||||
# - 모델이 "JSON만 반환"을 어기면 content에 분석/설명 텍스트가 들어올 수 있음.
|
||||
# - 그 경우 reasoning_content 쪽에 실제 JSON이 들어있는 패턴을 우선 복구한다.
|
||||
def looks_like_json(s: str) -> bool:
|
||||
if not s:
|
||||
return False
|
||||
if '"actions"' in s or '"current_goal"' in s:
|
||||
return True
|
||||
# 최소 토큰 기반 (finish_reason=length에서 특히 reasoning에 JSON이 들어오는 케이스)
|
||||
return ("{" in s) or ("[" in s)
|
||||
|
||||
content_stripped = content.strip()
|
||||
reasoning_stripped = reasoning.strip()
|
||||
|
||||
if looks_like_json(content_stripped):
|
||||
return content_stripped
|
||||
if looks_like_json(reasoning_stripped):
|
||||
return reasoning_stripped
|
||||
# 둘 다 JSON처럼 보이지 않더라도, content가 있으면 먼저 반환(기존 동작 유지)
|
||||
if content_stripped:
|
||||
return content_stripped
|
||||
return reasoning_stripped
|
||||
|
||||
def _parse_json(self, raw: str) -> dict:
|
||||
text = raw.strip()
|
||||
|
||||
Reference in New Issue
Block a user