지난 편에서, 플랫폼을 Hermes 로 갈아타고 브리지가 다시 살아났다고 했다. 살아나기는 했는데, 그다음 문제가 바로 그 자리에서 기다리고 있었다. 대답이 오는 데 걸리는 시간이었다. 슬랙에 질문을 던지면, 입력 표시는 뜨는데 대답이 오기까지 꼬박 3분이 걸렸다. 죽어 있는 것도 아니고, 살아 있는 것도 아니고, 그 중간 어딘가에서 하염없이 기다리는 상태였다. 지난 편에서도 썼지만, 플랫폼을 바꾸는 일은 그 자체로 끝이 아니라 그 위에서 문제가 어디서 나는지가 달라지는 일이다. 이번에는 그 문제가 통로가 아니라 시간이었다. 이 편은 그 3분을 세 번에 걸쳐 고친 이야기다. 같은 증상을, 세 번, 서로 다른 이유로. 하나씩 겹을 벗겨보자.
첫 번째 겹 — 모델이 느리다
그 무렵 Hermes 의 브레인은 edgexpert 라는 이 박스에 설치한 27B 모델이었다. 하필 그 모델을 고른 데는 사정이 있었다. 그 전까지 브레인은 pro6000 이라는 공유 서버의 DeepSeek 을 쓰고 있었는데, 그 서버는 통제 밖에 있었다. 누군가 재시작을 하면 내 서비스가 같이 죽고, 기록에 따르면 컨텍스트를 256K 로 올리면 툴콜 요청 시 커널이 크래시까지 냈다. 그래서 안정성을 위해 아예 이 박스 안으로 옮겼고, 그 자리에 앉힌 것이 이 27B 였다. 즉, 불안정한 원격에서 안정적인 로컬로 옮기자, 이번에는 속도가 문제로 드러난 셈이다. 이 시리즈에서 플랫폼을 바꾸는 일이 끝이 아니라, 그 위에서 문제가 어디서 나는지가 달라지는 일이라는 말이, 그대로 이 자리에서 반복됐다.
27B 라는 이름이 말해주듯 이 모델은 dense 라서, 토큰 하나를 만들 때 270억 개의 파라미터를 전부 읽어야 했다. 그 무렵 기록에는 모델이 초당 8 토큰을 만들었다고 남아 있다. 8 토큰이 어느 정도냐면, 사람이 천천히 읽는 속도보다 느린 수준이다. 질문 하나에 대답을 두세 문장만 써도 그 생성만으로 몇 십 초가 지나간다.

그래서 브레인에 뭔가를 물어보면, 검색은 순식간인데 대답 생성에서 시간이 통째로 소모됐다. 기록에 남은 수치로는 쿼리 하나가 134초였다. 슬랙 쪽에서 보면 2분이 넘게 입력 표시만 깜빡이고 있는 셈이라, 대화를 주고받는 도구로서는 이미 한계를 넘은 상태였다. 슬랙은 느린 응답을 기다려 주는 도구가 아니다. 사람이 기다리는 시간이 길어지면 그 자리에서 대화가 끊기고, 나중에는 아예 물어보지 않게 된다. 브리지가 살아 있는 것과 브리지가 쓸모 있는 것은 다른 문제였다. 이 27B 가 왜 하필 그렇게 느렸는지는, 모델의 문제라기보다 그것을 올린 기계가 초당 얼마를 읽어낼 수 있느냐의 문제라, 여기서는 접어두고 첫 번째 겹이 모델이었다는 사실만 남겨둔다. 속도가 문제인 건 알았지만, 이때는 아직 이게 겹의 전부라고 생각하고 있었다.
두 번째 겹 — 길을 막은 정책
모델이 느리니 모델을 의심하는 게 순서였다. 그런데 이상한 점이 하나 있었다. 같은 브레인을 두고, 어떤 질문은 2분이 걸리고 어떤 질문은 아주 짧게 끝나는 것이었다. 모델이 느리다면 모든 질문이 비슷하게 느려야 하는데, 그러지 않았다. 느린 질문과 빠른 질문의 차이가 무엇인지 들여다보니, 느린 쪽이 공통적으로 브레인 웹의 특정 경로를 거치고 있었다. 게이트웨이가 띄운 MCP 프로세스에는 외부 접근을 제한하는 정책이 강제되는데, 그 정책이 경로마다 다르게 적용되고 있었다. MCP 프로세스는 에이전트가 도구를 쓰기 위해 게이트웨이가 자식으로 띄우는 것이어서, 그 프로세스가 나가는 통신은 전부 그 정책의 지배를 받는다. API 쪽 경로는 통과가 되는데, 위키 문서를 읽는 경로는 20초 동안 기다렸다가 타임아웃이 나고, 재시도가 세 번 반복되면서 1분이 넘게 끌렸다. 재시도까지 포함하면 이 경로 하나가 60초 이상을 그냥 태우는 셈이었다.
그런데 여기서 이 삽질을 가장 길게 만든 함정이 하나 있었다. 그 경로를 셸에서, 그것도 컨테이너 안에서 직접 테스트해 보면 0.01초 만에 응답이 돌아왔다. 즉, 직접 만져보면 아무 문제가 없어 보인다. 정책은 게이트웨이가 띄운 프로세스에만 강제되니까, 셸에서 실행한 테스트는 그 정책을 우회한 채 아주 빠른 길로 통과해 버린 것이다. 테스트가 성공하니 코드는 문제없다고 생각하고, 정책 쪽을 의심할 생각을 못 했다. 죽은 원인은 정책인데, 증거는 전부 정책이 없는 경로에서 나오고 있었던 셈이다.

이 대목이 이 편에서 가장 아깝지 않은 교훈이다. 테스트한 경로와 실제 실행 경로가 다르면, 측정은 거짓말을 한다. 테스트가 실제와 같은 길을 타는지부터 확인하지 않으면, 아무리 정밀하게 측정해도 그 숫자는 그 문제의 숫자가 아니다. 그리고 거부가 아니라 지연이라는 점이 또 문제를 어렵게 만들었다. 지난 편의 허용 목록은 거부였는데, 거부는 오류가 남아서 흔적을 찾을 수 있었다. 이번 지연은 오류도 로그도 없이 시간만 조용히 흘려보냈다. 그 경로를 정책 예외에 넣자, 그 60초는 사라졌다.
세 번째 겹 — 에이전트가 LLM 을 또 돌렸다
두 겹을 벗기고 나니 이제 남은 것은 모델의 생성 속도뿐이었다. 그런데 그래도 이상했다. 같은 질문을 두고도 응답 시간이 들쭉날쭉했다. 50초일 때도 있고, 100초가 넘을 때도 있었다. 모델 속도라면 일정해야 하는데, 편차가 너무 컸다. 그 편차가 곧 세 번째 원인이 있었다는 증거였다.
원인은 에이전트가 쓰는 도구 안에 있었다. 에이전트가 브레인에 질문하는 도구를 부르면, 그 도구는 검색만 하는 게 아니라 그 자리에서 또 한 번 LLM 생성을 돌리고 있었다. 브레인 웹의 답변 기능이, 검색 결과를 받아서 그걸 다시 LLM 으로 종합해 대답까지 만들어 주는 구조였던 것이다. 코드를 열어보면 그 구조가 그대로 드러나는데, 검색 함수를 부르고 나서 그 결과를 다시 대화 모델에 넣어 답을 짓는 흐름이었다. 다시 말해, 에이전트가 브레인에 물어보면 같은 vLLM 위에서 에이전트 자신의 턴과 브레인 웹의 생성 턴이 동시에 경합을 벌였다. 하나의 모델이 두 주인의 요청을 번갈아 처리하다 보니, 둘 다 늘어지고 응답 시간은 그때그때 달라졌다.

웹을 검색해서 답하는 도구는 더 심했다. 그 도구는 검색과 생성을 여러 단계로 반복하는 구조라서, 검색이 느린 게 아니라 검색 결과를 또 한 번 LLM 으로 돌려 답을 짓는 과정이 통째로 시간이었고, 기록에 남은 수치로는 136초가 걸렸다. 세 번째 겹이 이 편의 결론에 해당한다. 같은 LLM 을 쓰는 에이전트에게, LLM 을 또 돌리는 도구를 주지 마라. 검색 도구는 검색만 하고, 받은 결과를 종합해 대답을 만드는 일은 에이전트 자신의 턴에서 하게 하면 된다. 도구에서 답까지 만들어 주는 것이 편해 보이지만, 그 편의가 두 배의 생성 비용으로 돌아온다. 에이전트 입장에서는 도구가 검색만 해 주는지, 답까지 만들어 주는지가 그렇게 다르지 않아 보이는데, 그 한 글자의 차이가 모델 하나를 통째로 추가로 돌리는 차이다. 그렇게 검색 전용 도구로 바꾼 뒤로, 응답은 3분에서 15초에서 30초 사이로 내려왔다.
돌아보면
세 겹을 벗기고 나서 보니, 처음의 진단은 겉만 맞고 있었다. 느린 것은 사실이었지만, 그 느림의 원인은 모델 하나가 아니라 모델과 정책과 도구 설계가 겹쳐서 만든 것이었다. 그리고 세 겹의 성격은 각각 달랐다. 모델은 하드웨어의 물리적 한계였고, 정책은 보안 기본값의 부작용이었고, 도구는 설계 선택이었다. 같은 증상을 보고도 원인이 셋이나 되니, 하나를 고치면 조금 나아지고, 또 하나를 고치면 또 조금 나아지는 식으로 진행됐다. 어느 한 시점에서도 전체 그림이 보이지 않았던 것이다.
기록을 돌아보면, 이 3분이 사라지는 데 걸린 시간은 길지 않았다. 길었던 것은 원인을 찾는 시간이었다. 모델을 탓하고, 설정을 뒤지고, 테스트를 반복하면서, 그 사이에 두 번째와 세 번째 겹이 숨어 있었다. 지금 보면 당연해 보이는 것들인데, 그때는 하나씩 겹을 벗기기 전에는 보이지 않았다. 그리고 이 겹들이 전부 동시에 존재했기 때문에, 어느 하나만 고쳐서는 증상이 사라지지 않았다. 셋이 합쳐져 3분이었고, 셋을 각각 벗겨야 15초가 남았다. 이 이야기가 남에게 쓸모가 있으려면, 결론만 남기지 말고 겹을 벗기는 순서도 남겨야 한다. 그 순서가 곧 같은 삽질을 두 번 하지 않는 방법이다.
이 시리즈의 3부는 에이전트가 창고를 쓰는 이야기였다. 브리지가 살아나고, 대답이 빨라지고 나니, 이제 남은 질문은 하나였다. 이 에이전트에게 일을 얼마나 맡길 수 있을까. 그 질문을 실측으로 답한 이야기는 다음 편에서 풀어야겠다.
'공부 > 인공지능' 카테고리의 다른 글
| OpenClaw 를 버리고 Hermes 로 간 이유 (0) | 2026.08.12 |
|---|---|
| 브레인에 MCP 를 달다 (읽기 → 쓰기) (0) | 2026.08.12 |
| 매주 월요일 아침, 논문이 온다. (0) | 2026.08.11 |
| 단체 메일은 조용히. (0) | 2026.08.06 |
| 전사가 깨진 이유. (0) | 2026.08.05 |