OpenAI 함수콜링으로 유저 요청을 툴 호출로 라우팅하는 걸 만들고 있어요. 90%는 잘 되는데, 열 번에 한 번쯤 tool_calls의 arguments 문자열을 json.loads 하면 Unterminated string 이나 Expecting ',' delimiter 같은 에러가 납니다.
스트리밍으로 받고 있어서 delta로 오는 arguments 조각을 문자열로 계속 이어 붙인 다음, 매 청크마다 파싱을 시도하는 구조입니다. 대략 이런 식이에요.
buf += delta.tool_calls[0].function.arguments
try:
args = json.loads(buf) # 여기서 가끔 터짐
except Exception:
pass실패한 걸 로그로 찍어보면 {"query": "서울 날씨 이렇게 문자열이 중간에 뚝 끊긴 상태예요. 모델이 이상한 JSON을 뱉는 건지, 제 파싱 로직이 문제인지 헷갈립니다. 인자 스키마는 필드 두어 개짜리로 단순한데도 이러네요.
댓글 2
제대로 하려면 조각은 그냥 이어 붙이기만 하고, 파싱은 그 tool call이 끝났을 때 딱 한 번만 하세요. 스트림에서 해당 tool_use 블록이 종료되는 시점(스트리밍 종료 이벤트, finish_reason)이 왔을 때 완성된 buffer를 한 번 파싱하면 됩니다. 중간에 except pass로 삼키니까 진짜 문제는 안 보이고 성공한 것만 우연히 잡히던 거고요.
그리고 스트리밍이 굳이 필요 없으면 스트리밍 없이 받으면 SDK가 이미 파싱된 input 객체를 통째로 줍니다. 직렬화된 문자열을 손으로 파싱할 필요 자체가 없어요.
추가로 인자가 진짜로 잘려 오는 케이스도 있는데, 그건 max_tokens에 걸려서 출력이 중간에 끊긴 경우예요. stop_reason 혹은 finish_reason이 length/max_tokens인지 꼭 확인하세요. 이건 파싱으로 못 살리고 max_tokens를 올려야 합니다.