sgkstudio.
엔지니어링

사내 챗봇 응답 속도, 최대 292초 지연을 구조에서 고쳤다

사내 챗봇 응답 속도가 최대 292초까지 늘어진 원인은 요청을 처리하는 구조에 있었습니다. 자연어 요청마다 누적 대화를 다시 읽고, 승인·수정 명령은 주기 작업으로 넘기던 구조를 명령 즉시 처리와 상시 대기 워커로 바꾸자 접수 표시는 3.0~5.2초, 명령 완료는 3.4초가 됐습니다. 주기 작업과 처리 기록을 공유해 중복 발송 0건도 확인했습니다.

2026-10-31대상: 한 투자자문사의 사내 메신저 업무 비서 응답 구조 재설계(2026년)개선 전: 응답 최대 292초개선 후: 접수 표시 3.0~5.2초, 명령 완료 3.4초, 중복 발송 0건측정 구간: 요청 시점부터 접수 표시까지, 명령 처리 완료까지로 나눠 기록무너진 전제: 모든 요청을 같은 방식으로 처리해도 된다, 승인·수정 명령은 주기 작업이 처리해도 충분하다남는 한계: 표본 크기와 자연어 요청의 최종 완료 시간은 기록에 없고, 전후 측정 구간이 완전히 같지 않음

무엇이 문제였나: 사내 챗봇 답이 최대 292초 늦었다

사내 메신저에 붙인 업무 비서의 응답이 최대 292초까지 늘어졌습니다. 5분에 가까운 시간입니다. 사내 챗봇 응답 속도는 사용 편의만의 문제가 아닙니다. 이 비서는 묻는 말에 답만 하는 도구가 아니라 승인과 수정 명령을 받아 실제 업무를 진행시키는 도구였기 때문입니다.

질문 하나가 늦는 일과 승인 하나가 늦는 일은 무게가 다릅니다. 승인을 눌렀는데 아무 반응이 없으면 보낸 사람은 처리가 됐는지 안 됐는지 알 수 없습니다. 이 불확실성은 메신저 안에서 끝나지 않고 그 승인에 걸린 다음 업무까지 함께 붙잡습니다.

이 비서는 혼자 떨어진 도구도 아니었습니다. 같은 회사에서 환급 처리, 전자결재, 복합기 스캔 문서 정리까지 자동화를 넓혀 가던 중이었고, 2026년 10월 23일 기준으로 회사 업무 자동화는 시스템 41개, 작업일 121일 규모였습니다. 자동화가 늘수록 사람이 개입하는 지점은 승인으로 모입니다. 사람이 말을 거는 창구가 느리면 뒤에 붙은 자동화가 아무리 빨라도 전체 일은 그 창구의 속도로 흐릅니다.

품질을 다루는 우리 규칙에 이런 문장이 있습니다. “안 보는 QA는 없는 QA와 같다.” 챗봇에도 그대로 옮길 수 있습니다. 답이 늦어 아무도 안 쓰게 된 비서는 만들어 두지 않은 비서와 다르지 않습니다. 사내 도구는 강제로 쓰게 할 수 없는 경우가 많아서, 응답 속도가 곧 사용 여부를 가르는 조건이 될 수 있습니다.

그래서 이 글의 질문은 하나입니다. 사내 챗봇이 느릴 때 어디부터 봐야 할까요? 답을 먼저 적으면, 느린 호출 하나를 찾는 일보다 요청이 어떤 경로로 지나가는지 그리는 일이 앞섰습니다.

처음 잰 숫자는 무엇이었나: 최대 292초 하나

개선 전 기록에 남은 숫자는 응답 최대 292초 하나입니다. 평균이나 중앙값은 남아 있지 않습니다. 이 글은 없는 숫자를 채우지 않고, 있는 숫자가 말할 수 있는 범위만 적습니다.

최대값 하나로도 알 수 있는 사실은 있습니다. 어떤 요청은 약 5분을 기다렸다는 사실입니다. 반대로 알 수 없는 사실도 있습니다. 모든 요청이 그만큼 느렸는지, 몇 건 중 몇 건이 그랬는지입니다. 최대값은 최악의 경험을 보여 주지만 보통의 경험은 보여 주지 않습니다.

그래도 이 숫자를 지우지 않고 첫 숫자로 남겨 둡니다. 개선 전 값을 하나도 적지 않으면 뒤에 나오는 개선 후 값은 비교할 대상을 잃습니다. 부족한 기준선이라도 왜 부족한지 함께 적어 두면 읽는 사람이 직접 판단할 수 있습니다.

개선 후 기록은 시간을 둘로 나눠 남겼습니다. 사람이 체감하는 기다림에는 두 구간이 섞여 있기 때문입니다. 요청이 들어온 뒤 “받았다”는 표시가 뜰 때까지의 구간과, 요청한 일이 실제로 끝날 때까지의 구간입니다.

이 글에서 쓰는 시간 지표
지표시작끝무엇을 말하나
접수 표시요청 수신“받았다”는 표시요청이 사라지지 않았다는 신호
명령 완료승인·수정 명령 수신명령 처리 끝결정이 실제로 반영됐다는 신호
응답 최대값(개선 전)요청 수신응답최악의 기다림

개선 전 값은 응답 최대 292초만 기록에 있고, 개선 후 값은 접수 표시와 명령 완료로 나눠 기록했다.

구간을 나누면 판정 기준을 앞에 적기 쉬워집니다. 우리 품질 규칙은 기준을 “WHEN 견적 폼을 제출하면, 시스템은 3초 내 확인 화면을 보여야 한다”처럼 기계가 읽을 수 있는 문장으로 적으라고 정합니다. 이 문장은 다른 화면의 예시지만 생각은 같습니다. 빠르다는 말을 쓰려면 어디서 어디까지 몇 초인지부터 정해야 합니다.

세운 가설: 모든 요청을 같은 방식으로 처리해도 될까?

먼저 밝혀 둘 점이 있습니다. 당시 어떤 순서로 무엇을 의심했는지는 기록에 없습니다. 남은 기록은 고치기 전 구조와 고친 뒤 구조입니다. 그래서 여기서는 고치기 전 구조가 말없이 깔고 있던 전제를 가설로 꺼내 적습니다. 처음부터 답을 알았던 것처럼 쓰지 않으려는 선택입니다.

고치기 전 구조에는 전제가 두 개 있었습니다.

  • 가설 1: 요청마다 누적 대화를 읽어야 맥락을 놓치지 않는다. 그러니 모든 자연어 요청을 같은 방식으로 처리해도 된다.
  • 가설 2: 승인·수정 명령은 주기 작업이 넘겨받아 처리해도 충분하다. 어차피 곧 처리되기 때문이다.

둘 다 처음 만들 때는 합리적인 선택입니다. 누적 대화를 전부 읽으면 맥락을 놓칠 위험이 줄어듭니다. 주기 작업에 맡기면 프로그램 하나로 쌓인 일을 몰아서 처리할 수 있어 구조가 단순합니다. 그래서 초기 구조로는 자연스럽습니다. 문제는 이 전제들이 시간이 지나도 그대로 남아 있다는 점이었습니다.

초기 구조를 탓할 이유도 없습니다. 우리 품질 규칙은 검수 투자를 제품의 생존 증거에 비례시키라고 적습니다. 방금 나온 제품은 가장 가벼운 검사만 받고, 방문이나 문의 같은 실제 신호가 나타나면 다음 단계로 올립니다. 승격은 신호가 먼저이지 의욕이 먼저가 아니라는 규칙입니다. 구조도 비슷합니다. 아무도 쓰지 않는 챗봇에 상시 대기 워커를 붙이는 일은 낭비에 가깝고, 사람들이 쓰기 시작해 대화가 쌓인 뒤에야 이 전제들을 다시 볼 이유가 생깁니다.

가설이 틀린 지점은 어디였나

가설 1은 요청의 종류를 가리지 않는다는 점에서 틀렸습니다. 대화는 쓸수록 쌓입니다. 요청마다 누적 대화를 다시 읽는 구조에서는 읽을 양이 사용 기간에 따라 함께 늘어납니다. 맥락을 지키려던 장치가 오래 쓸수록 느려지는 장치로 바뀝니다. 잘 쓰이는 비서일수록 대화가 많이 쌓이므로 많이 쓰는 쪽이 더 불리해집니다.

가설 2는 “곧”이라는 말에서 틀렸습니다. 주기 작업은 다음 차례가 올 때까지 기다리는 구조입니다. 이 기다림은 LLM이 아무리 빨라도 줄지 않습니다. 호출 속도와 상관없는 시간이기 때문입니다. 승인을 보낸 사람 입장에서는 이 시간차가 그대로 무반응으로 보입니다.

두 가설이 틀린 자리를 합치면 한 가지 사실이 남습니다. 느린 이유가 하나가 아니었습니다. 느린 호출 하나를 찾아 고치는 방식으로는 둘 중 하나밖에 건드리지 못합니다. 읽는 양을 줄여도 명령은 주기를 기다리고, 주기를 고쳐도 자연어 요청은 누적 대화를 읽습니다.

읽는 시간과 기다리는 시간은 다른 시간이다. 한쪽을 고쳐도 다른 쪽은 그대로 남는다.

진짜 원인: 처리 경로 둘이 각자 다른 이유로 느렸다

원인은 두 구조였습니다. 첫째는 자연어 요청마다 누적 대화를 다시 읽던 구조입니다. 둘째는 승인·수정 명령이 주기 작업으로 넘어가 시간차가 벌어지던 구조입니다. 첫째는 일을 하는 데 드는 시간이고, 둘째는 일을 시작하기 전까지 기다리는 시간입니다.

개선 전 구조 흐름도. 자연어 요청은 누적 대화를 다시 읽은 뒤 LLM이 처리하고, 승인·수정 명령은 주기 작업 차례를 기다린 뒤 처리돼 응답이 최대 292초까지 늘어진다
자연어 요청은 읽느라 늦고, 명령은 차례를 기다리느라 늦었다

성격이 다른 두 요청을 한 방식에 태운 점이 핵심이었습니다. 자연어 요청은 무엇을 원하는지 해석해야 하지만, 승인과 수정은 무엇을 해야 하는지가 이미 정해진 명령입니다. 뜻을 풀 일이 적은 요청까지 같은 처리 흐름에 들어가 있었던 셈입니다.

요청 종류별로 본 처리 성격
요청해석이 필요한가개선 전 처리늦어진 이유
자연어 요청필요함요청마다 누적 대화를 다시 읽음읽는 양이 쌓일수록 늘어남
승인 명령할 일이 정해져 있음주기 작업으로 넘어감다음 차례까지 시간차
수정 명령할 일이 정해져 있음주기 작업으로 넘어감다음 차례까지 시간차

개선 전 구조 기록을 요청 종류별로 다시 나눈 표다.

두 시간을 구분하면 고치는 방법도 갈립니다. 일하는 시간은 읽는 양과 처리 방식을 바꿔야 줄어듭니다. 기다리는 시간은 일을 잘하게 만들어서는 줄지 않고, 일이 언제 시작되는지를 바꿔야 줄어듭니다. 그래서 명령에는 주기 작업에서 빼내는 조치가, 자연어 요청에는 대기 중인 워커가 받는 조치가 각각 필요했습니다. 원인이 둘이면 조치도 둘입니다.

여기서 “LLM이 느려서”라는 설명은 절반도 맞지 않습니다. 설령 호출 시간이 줄어도 주기 작업의 시간차는 남습니다. 호출 시간을 따로 잰 값도 기록에 없습니다. 그래서 이 글은 LLM 호출이 얼마를 차지했는지 말하지 않습니다. 말할 수 있는 범위는 구조를 바꾸자 숫자가 달라졌다는 데까지입니다.

조치: 명령은 즉시 처리하고 LLM 워커는 상시 대기시켰다

조치는 세 가지였습니다. 명령을 주기 작업에서 빼내고, 자연어 요청을 상시 대기 워커로 옮기고, 두 경로가 주기 작업과 같은 처리 기록을 쓰게 했습니다.

  • 명령 즉시 처리: 승인·수정 명령은 주기를 기다리지 않고 들어오는 대로 처리한다.
  • 상시 대기 LLM 워커: 자연어 요청은 대기 중인 워커가 바로 받는다. 요청이 올 때마다 누적 대화를 다시 읽던 구조를 버렸다.
  • 처리 기록 공유: 즉시 처리와 주기 작업이 같은 처리 기록을 보고, 이미 처리한 일을 다시 보내지 않는다.
개선 후 구조 흐름도. 승인·수정 명령은 즉시 처리로, 자연어 요청은 상시 대기 LLM 워커로 가고, 즉시 처리와 워커와 주기 작업이 모두 같은 처리 기록을 공유해 중복 발송 0건을 확인했다
빠른 경로를 새로 내면서 주기 작업과 같은 처리 기록을 보게 했다

세 번째 조치가 없으면 앞의 두 조치는 새 사고를 부릅니다. 빠른 경로를 새로 내면 같은 일을 처리할 수 있는 주체가 둘이 됩니다. 즉시 처리가 보낸 건을 주기 작업이 다시 집어 보내면 받는 사람은 같은 내용을 두 번 받습니다. 속도를 얻고 신뢰를 잃는 교환입니다. 그래서 주기 작업을 없애지 않고 같은 처리 기록을 함께 보게 했습니다.

중복 발송을 막는 기준은 부정형으로 적을 수 있습니다. 품질 규칙에서 빌려 온 방식입니다. “이 답이 맞는가”는 기계가 판단하기 어렵지만, “어떤 경우에도 이건 아니다”는 기계가 검사할 수 있습니다. 규칙은 이것을 불변식이라고 부릅니다. 메신저 비서에 옮기면 “같은 건은 어떤 경로로 들어와도 두 번 나가지 않는다”가 됩니다. 이 문장은 명세가 없어도 돌고, 경로가 하나 더 늘어도 그대로 쓸 수 있습니다.

경로를 나눈 구조는 또 다른 규칙과도 맞습니다. “작성은 LLM, 실행은 결정론”입니다. LLM은 사람 말을 해석하는 자리에 두고, 정해진 일을 정해진 대로 처리하는 자리는 같은 입력에 같은 결과를 내는 코드가 맡습니다. 이렇게 하면 빠르고 싸고 결과가 흔들리지 않습니다. 이 메신저 비서에서는 해석이 필요한 요청과 이미 정해진 명령을 두 경로로 나눠, 각 자리에 맞는 처리를 두었습니다.

회사의 다른 자동화에도 같은 원칙이 보입니다. 네 자동화를 나란히 놓으면 공통점이 보입니다. 사람이 해야 할 일만 남기고, 기계가 조용히 어긋날 자리에는 되돌릴 장치를 둡니다.

표. 환급 처리는 승인과 지급 실행만 사람이 맡고 회귀 테스트로 어긋남을 막는다. 전자결재는 실제 브라우저 세션 연결로 정기 업무 4종을 운영한다. 스캔 문서는 건당 판독 10초에 신뢰도 낮으면 이름을 바꾸지 않는다. 메신저 비서는 처리 기록을 공유해 중복 발송 0건을 확인했다
네 자동화 모두 빠르게 하는 장치와 어긋남을 막는 장치를 함께 뒀다

환급 처리는 요청 메일 수신부터 케이스 정규화, 전자결재 기안 작성과 제출, 승인 상태 폴링, 처리 대장 기록, 문서번호 동기화까지 하나로 이었습니다. 사람에게는 승인과 지급 실행만 남겼습니다. 돈이 나가는 결정은 끝까지 사람이 쥔다는 뜻입니다. 파서와 정규화, 대장 기록에는 회귀 테스트를 붙여 케이스 형식이 바뀌어도 조용히 어긋나지 않게 했습니다. 사람 손을 어디에 남길지 정한 비슷한 사례는 컴플라이언스 자동화 기록에 따로 적었습니다.

조용히 어긋난다는 표현이 중요합니다. 메일 형식이 조금 바뀌어 파서가 다른 값을 읽어도 프로그램은 오류를 내지 않고 끝날 수 있습니다. 그러면 틀린 값이 처리 대장까지 그대로 내려갑니다. 눈에 보이는 실패보다 이런 실패가 늦게 발견됩니다. 회귀 테스트는 고친 자리가 다시 깨지지 않게 하는 장치이면서, 입력 형식이 달라졌을 때 조용히 지나가지 않게 하는 장치입니다.

그룹웨어 전자결재는 지출결의서 작성, 결재선 지정, 참조 문서 첨부, 보관을 자동화하고 사내 정기 업무 4종을 스케줄로 돌립니다. 여기서는 실제 브라우저 세션에 CDP(크롬을 프로그램으로 조종하는 연결 방식)로 붙어 헤드리스 자동화의 불안정성을 없앴습니다.

복합기 스캔 문서는 앞 2장을 이미지로 렌더해 LLM Vision으로 문서 종류와 상대방을 판독하고, 날짜·문서 종류·상대방 형식으로 파일명을 바꿉니다. 건당 판독은 10초입니다. 판독 신뢰도가 낮은 문서는 이름을 바꾸지 않고 원본명을 기록해 되돌릴 수 있게 했습니다. 스캔 문서 속 문구가 판독 모델의 지시로 쓰이지 않도록 입력을 데이터로 격리한 점도 같은 생각입니다.

이 자동화가 바꾼 것은 찾는 방식입니다. 예전에는 폴더를 열어봐야 내용을 알 수 있었지만, 이제는 파일명만으로 식별합니다. 메신저 비서와 스캔 파이프라인은 하는 일이 전혀 다른데 설계 질문은 같았습니다. 기계가 틀릴 수 있는 자리에서 어떻게 멈추고, 어떻게 되돌릴 것인가입니다. 빠른 처리와 안전한 멈춤은 둘 중 하나를 고르는 문제가 아니었습니다.

재측정 결과: 접수 표시 3.0~5.2초, 명령 완료 3.4초

다시 잰 결과, 접수 표시는 3.0~5.2초, 명령 완료는 3.4초였습니다. 개선 전 기록인 응답 최대 292초와 나란히 놓으면 차이가 크지만, 세 값은 같은 구간이 아닙니다. 개선율 하나로 합치지 않고 절대값 그대로 둡니다.

막대 그래프. 개선 전 응답 최대 292초, 개선 후 접수 표시 최대 5.2초, 개선 후 명령 완료 3.4초
개선 전 값은 응답 최대값이고, 개선 후 값은 구간을 나눠 잰 값이다

숫자에서 눈여겨볼 자리는 명령 완료 3.4초가 접수 표시 범위인 3.0~5.2초 안에 들어간다는 점입니다. 승인이나 수정 명령은 접수 표시에 걸리는 시간과 비슷한 시간에 끝납니다. 명령을 보낸 사람이 처리 여부를 궁금해할 틈이 크게 줄어듭니다.

접수 표시가 하나의 값이 아니라 3.0~5.2초의 범위로 남은 점도 그대로 적어 둡니다. 범위의 폭을 어떻게 읽을지는 조심해야 합니다. 화면 검수에서 겪은 일이 참고가 됩니다. 처음 고정 임계값을 0.2%로 잡았는데, 실제 노이즈가 0.160%로 0.04%p 차이밖에 나지 않아 아슬아슬했습니다. 그래서 노이즈 바닥을 자동으로 재는 기능을 추가했습니다. 오탐 한 번이 인프라의 신뢰를 끝낸다고 봤기 때문입니다. 시간 측정도 같습니다. 평소 흔들리는 폭을 모르면 다음 측정값이 나빠진 건지 평소 범위인지 가릴 수 없습니다.

중복 발송은 0건을 확인했습니다. 경로를 늘리는 변경에서 가장 먼저 따져야 할 부작용이 여기이므로, 속도 숫자만큼 중요한 숫자입니다. 다만 이 0건은 확인한 범위에서 걸린 건이 없다는 뜻입니다. 우리 품질 규칙은 “통과를 정답의 증거로 읽지 않는다”고 적어 둡니다. 통과는 검사한 항목 중 걸린 게 없다는 말일 뿐이기 때문입니다. 이 원칙의 배경은 QA 자동화 글에 있습니다.

전후 비교
지표개선 전개선 후
응답최대 292초구간을 나눠 측정
접수 표시기록 없음3.0~5.2초
명령 완료기록 없음3.4초
중복 발송기록 없음0건 확인

개선 전 값이 없는 칸은 비워 두지 않고 기록 없음으로 적었다.

남는 한계: 아직 모르는 숫자는 무엇인가

이 개선은 끝난 이야기가 아닙니다. 모르는 숫자가 여럿 남아 있습니다.

  • 표본 크기가 기록에 없습니다. 3.0~5.2초가 몇 건에서 나온 범위인지 이 글로는 말할 수 없습니다.
  • 개선 전과 후의 구간이 완전히 같지 않습니다. 292초는 응답 최대값이고, 개선 후 값은 접수 표시와 명령 완료입니다.
  • 자연어 요청의 최종 완료 시간이 없습니다. 접수 표시는 일이 끝났다는 신호가 아니라 받았다는 신호입니다.
  • LLM 호출 자체가 차지한 시간을 따로 재지 않았습니다.
  • 3초 안에 들어오지는 못했습니다. 접수 표시의 가장 빠른 값이 3.0초이고 가장 느린 값은 5.2초입니다.

가장 큰 한계는 세 번째입니다. 접수 표시가 빨라지면 사람은 덜 불안하지만 일 자체가 빨라졌다는 뜻은 아닙니다. 빠르게 보이는 일과 빠르게 끝나는 일은 다릅니다. 다음에 다시 잰다면 자연어 요청의 완료 시간과 표본 크기부터 남겨야 합니다.

상시 대기 방식에도 따져 볼 자리가 있습니다. 워커는 요청이 없어도 켜져 있어야 합니다. 그 유지 비용을 응답 속도와 맞바꾼 셈인데, 이 비용을 잰 숫자는 기록에 없습니다. 도입을 검토한다면 대기 비용도 함께 재야 판단할 수 있습니다.

측정 범위를 정직하게 적는 일도 이 글이 지키려는 원칙입니다. 접근성 검사를 다룬 규칙에는 “기계로 57%만 잡힌다”는 문장과 함께 “못 하는 것을 한다고 하지 않는다”는 조항이 있습니다. 속도 개선 글도 같습니다. 재지 않은 구간은 빨라졌다고 쓰지 않습니다.

  • 요청을 종류별로 나눴는가: 해석이 필요한 요청과 이미 정해진 명령을 구분한다.
  • 시간을 구간별로 재는가: 받았다는 표시와 일이 끝난 시점을 따로 기록한다.
  • 기다리는 시간을 찾았는가: 주기 작업이나 대기열이 만드는 시간차는 모델을 바꿔도 줄지 않는다.
  • 같은 일을 두 번 하지 않는가: 경로를 늘렸다면 처리 기록을 공유한다.
  • 사람이 남을 자리를 정했는가: 승인과 지급처럼 되돌리기 어려운 일은 사람이 맡는다.
  • 재측정 계획이 있는가: 표본 크기와 평소 흔들리는 폭까지 함께 남긴다.

사내 챗봇이 느릴 때 시도해 볼 순서는 위 목록과 같습니다. 핵심은 느린 곳 하나를 찾기 전에 요청이 지나는 경로부터 그리는 일입니다. 사내 업무 자동화나 챗봇 구조를 검토 중이라면 상담에서 현재 구조를 들려주셔도 좋습니다.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.