OpenAI API 한글 응답 깨질 때 인코딩·파라미터 점검: 제가 먼저 보는 7가지

OpenAI API에서 한글이 ���로 보이거나 문장이 중간에 잘린다면, 모델 문제가 아니라 대부분 UTF-8 처리, 스트리밍 디코딩, 토큰 제한, JSON 직렬화 쪽에서 생깁니다. 먼저 서버 로그의 원문 응답이 정상인지 보고, 그다음 프론트엔드·자동화 도구·저장소로 넘어가는 경로를 하나씩 좁히면 빠릅니다.

API 응답 원문과 최종 출력값을 먼저 비교해 보세요. 그 차이가 깨짐의 위치를 알려줍니다.

저는 Claude Code나 Cursor로 만든 작은 API 프록시, n8n 자동화, Slack 알림 봇을 붙일 때 이 문제를 여러 번 만났습니다. 결론은 간단합니다. 응답 원문은 정상인데 화면에서만 깨지면 인코딩 문제, 원문부터 짧거나 이상하면 파라미터와 프롬프트 구조를 봐야 합니다.

바로 점검할 분은
API 응답 원문 → 서버 디코딩 → JSON 저장 → 화면 출력 순서로 한 단계씩 확인해 보세요.

가장 먼저 볼 곳은 ‘모델’이 아니라 응답 경로입니다

한글 깨짐을 보면 모델을 바꾸고 싶어지지만, 실제로는 OpenAI 모델이 한글을 못 만들어서 생기는 경우는 드뭅니다. ChatGPT 화면에서는 멀쩡한 답이 API로만 깨진다면 거의 애플리케이션 레이어 문제입니다.

특히 Node.js의 fetch, Python requests, Next.js API Route, n8n HTTP Request 노드, Zapier Webhooks처럼 중간 도구가 끼면 어디서 문자열이 변했는지 확인해야 합니다.

1) 서버 로그에서 원문부터 확인

가장 빠른 방법은 OpenAI API 호출 직후의 raw response를 서버 콘솔에 찍는 것입니다. 이 시점에서 한글이 정상이라면 OpenAI 응답은 문제없고, DB 저장이나 브라우저 렌더링 쪽으로 범위를 줄이면 됩니다.

Python에서는 JSON 저장 시 ensure_ascii=False를 쓰지 않으면 한글이 \uc548\ub155처럼 보일 수 있습니다. 이것은 깨진 것이 아니라 유니코드 이스케이프 표현입니다. 다만 로그 뷰어나 외부 도구에서 이를 깨진 문자로 착각하는 경우가 많습니다.

2) 스트리밍이면 TextDecoder 사용 방식 확인

스트리밍 응답은 조각 단위로 들어옵니다. 한글 한 글자는 여러 바이트로 구성되기 때문에, 바이트 조각을 잘못 끊어서 문자열로 바꾸면 가 생길 수 있습니다.

브라우저나 Node.js에서 직접 stream을 처리한다면 new TextDecoder('utf-8')를 쓰고, 청크마다 디코딩할 때 stream 옵션을 유지해야 합니다. SDK를 쓰면 이 부분이 상당히 줄어듭니다. 그래서 처음 구현할 때는 OpenAI 공식 SDK로 정상 동작을 확인한 뒤, 커스텀 fetch로 옮기는 편이 안전합니다.

인코딩과 파라미터를 나눠서 보면 빨라집니다

증상 가능성이 큰 원인 먼저 할 일
한글이 ���로 표시됨 UTF-8 디코딩 실패, 스트림 청크 분리 서버 raw 로그와 TextDecoder 설정 확인
문장이 중간에 끊김 max_output_tokens 또는 max_tokens 부족 출력 토큰을 늘리고 finish_reason 확인
JSON 안의 한글만 이상함 직렬화, DB charset, 로그 뷰어 문제 ensure_ascii, DB utf8mb4, Content-Type 점검
자동화 도구에서만 깨짐 n8n·Make·Zapier의 필드 변환 HTTP 응답 헤더와 중간 노드 출력 비교

파라미터 쪽에서 자주 놓치는 부분

한글 자체가 깨지는 문제와 별개로, 답변이 이상하게 짧거나 맥락이 사라지는 경우는 파라미터 영향이 큽니다. Responses API를 쓴다면 max_output_tokens, Chat Completions 계열이면 max_tokens를 확인하세요. 한국어는 영어보다 토큰 사용량이 체감상 더 빨리 차는 경우가 있어 긴 요약이나 보고서 생성에서는 여유를 둬야 합니다.

temperature는 글의 다양성에는 영향을 주지만 인코딩 깨짐을 고치지는 않습니다. response_format이나 JSON schema를 사용할 때도 한글 출력은 가능합니다. 다만 프롬프트에서 “반드시 JSON만 반환”을 강하게 요구하면 설명 문장이 빠져 결과가 짧아 보일 수 있습니다.

구체적인 예: Slack 요약 봇에서 한글이 깨질 때

가상의 예로, OpenAI API로 회의록을 요약한 뒤 Slack에 보내는 봇을 만든다고 해보겠습니다. 서버 콘솔에서는 “오늘 논의한 핵심은…”이 정상인데 Slack 메시지에는 물음표나 깨진 문자가 보인다면 OpenAI 호출이 아니라 전송 직전 payload를 봐야 합니다.

이때 확인 순서는 이렇습니다. 첫째, OpenAI 응답 객체에서 텍스트만 추출해 콘솔에 출력합니다. 둘째, Slack Web API로 보내는 JSON body를 저장해 봅니다. 셋째, 요청 헤더에 Content-Type: application/json; charset=utf-8이 들어가는지 확인합니다. 넷째, 중간에 Airtable이나 Google Sheets를 거친다면 해당 컬럼이 한글을 정상 보존하는지 봅니다.

반대로 서버 콘솔부터 문장이 잘려 있다면 Slack은 용의선상에서 빼고, 출력 토큰과 프롬프트를 조정하는 편이 빠릅니다.

상황별 추천 점검 루트

개발자가 직접 만든 웹앱이라면

Next.js, Express, FastAPI처럼 직접 서버를 만진다면 raw response 로그를 남기고, API 응답을 그대로 파일에 저장해 보세요. 파일은 UTF-8로 열고, DB는 MySQL이면 utf8mb4를 권장합니다. 프론트는 HTML meta charset이 UTF-8인지도 같이 봅니다.

n8n·Make 같은 자동화 사용자라면

코드를 덜 만지는 워크플로에서는 각 노드의 입력·출력 미리보기가 중요합니다. OpenAI 노드 결과는 정상인데 Slack, Notion, Airtable 노드에서 깨지면 해당 커넥터의 필드 매핑 문제일 가능성이 큽니다. HTTP Request 노드를 쓸 때는 응답을 text로 받을지 JSON으로 받을지도 확인하세요.

자주 막히는 질문

Q. 모델을 gpt-4o나 최신 모델로 바꾸면 해결되나요?

한글 품질은 좋아질 수 있지만, 깨짐 자체는 보통 모델 변경으로 해결되지 않습니다. 같은 프롬프트를 OpenAI Playground나 ChatGPT에서 돌렸을 때 정상이라면 구현 쪽을 보는 것이 맞습니다.

Q. 유니코드 이스케이프는 오류인가요?

\uc548\ub155처럼 보이는 것은 대부분 오류가 아닙니다. JSON 표현 방식일 뿐이고, 클라이언트에서 파싱하면 “안녕”으로 돌아옵니다. 다만 사람이 읽는 로그나 CSV로 내보낼 때는 ensure_ascii=False 같은 설정이 필요할 수 있습니다.

Q. 한글 답변이 자꾸 짧습니다. 인코딩 문제인가요?

짧게 끝나는 것은 인코딩보다 토큰 제한일 가능성이 큽니다. 응답의 finish reason을 보고 length 계열이면 출력 토큰을 늘리세요. 동시에 “표 5행 이내” 같은 프롬프트 제약이 들어가 있지 않은지도 확인해야 합니다.

마지막으로 바로 할 한 가지

지금 가장 먼저 할 일은 “OpenAI 응답 직후의 텍스트”와 “사용자가 보는 최종 텍스트”를 나란히 저장하는 것입니다. 두 값이 같으면 파라미터 문제, 다르면 인코딩·저장·전송 경로 문제입니다. 이 한 번의 비교만으로 디버깅 시간이 크게 줄어듭니다.

관련 링크

글쓴이 용기

AI 코딩 에이전트로 직접 빌드하는 개발자. Claude Code·Codex 실사용 후기와 빌더 일지를 씁니다.

지식창고