[세컨드브레인 개발기] 11. OpenClaw 를 버리고 Hermes 로 간 이유
[세컨드브레인 개발기] 11. OpenClaw 를 버리고 Hermes 로 간 이유
브레인에 MCP를 달고, 에이전트가 창고에 쓰는 손을 얻었습니다. 그런데 그 이야기에는 전제가 하나 숨어 있어요. 창고를 쓰는 쪽, 즉 에이전트가 제대로 서 있어야 한다는 전제입니다.
3부가 묻는 것은 창고를 쓰는 쪽이 누구인가인데, 그 쪽을 통째로 갈아탄 일이 이 편의 중심입니다. MCP가 붙은 뒤로 얼마 지나지 않아, 에이전트 플랫폼을 OpenClaw에서 Hermes로 바꿨습니다. 이유는 하나, 남의 버그였어요. 지난 편에서 예고한 그 도구들의 이야기는 다음 편에서 풀기로 하고, 이 편은 그 도구들이 달려 있던 플랫폼의 이야기입니다. 하나씩 보겠습니다.
게이트웨이와 페어링

그때까지 에이전트 플랫폼으로 쓰던 것은 OpenClaw였습니다. 게이트웨이가 중심에 있고, 그 주위에 디바이스들이 웹소켓으로 붙는 구조예요. Slack 브리지도 그 게이트웨이 위에 얹혀서, 슬랙의 메시지를 에이전트로 흘려보냈습니다. 연구실의 대화는 슬랙에서 오가니, 그 자리에서 창고에 물어볼 수 있게 하려는 것이었죠. 내 짐작이지만, 그 목적이 브리지를 들인 이유였을 것입니다.
디바이스는 하나하나 페어링으로 등록됩니다. 진단 명령을 돌려보면, 등록된 디바이스가 다섯 대였어요. 맥의 CLI 하나, 리눅스의 CLI 하나, 윈도우와 맥의 웹채팅 각 하나, 그리고 맥북 하나가 노드와 운영자 역할을 겸했습니다. 토큰마다 역할과 scopes가 붙고, 운영자에게는 관리와 승인과 페어링 권한이 주어졌습니다. 페어링이라는 절차가 이 플랫폼의 일상이었어요.

유월 초의 진단 기록을 보면, 이 플랫폼은 이미 그때부터 삐걱거리고 있었습니다. 진단은 게이트웨이가 안 돌고 있다고 말하면서, 같은 화면의 아래쪽에서는 게이트웨이가 돌고 있다고 말했습니다. 같은 진단 안에서 서로 모순된 보고가 나온 것이죠.
게이트웨이 같은 서비스도 두 개가 잡혔는데, 하나는 게이트웨이 이름의 등록 서비스였고, 다른 하나는 또 다른 이름의 것이었습니다. 문서는 이렇게 적고 있었어요. 한 기계에는 게이트웨이를 하나만 두라고. 두 개가 같은 자격증명을 두고 충돌할 수 있다는 뜻이었습니다.
진단은 또, 메모리 검색이 켜져 있는데 임베딩 제공자가 없어서 의미검색이 동작하지 않을 것이라는 경고도 함께 내놓았습니다. 게이트웨이는 버전 관리자에 들어 있는 Node로 돌고 있었는데, 문서는 그 버전이 올라가면 게이트웨이가 깨질 수 있다고 경고했어요. 기능이 요구사항을 채운 것은 열네 개였고, 요구사항이 빠진 것은 서른셋이었습니다.
플러그인은 여섯 개가 올라와 있고 서른 개가 꺼져 있었는데, 오류는 하나도 없었습니다. 그런데 오류가 없다는 말이 잘 돌아간다는 말은 아니었어요. 켜져 있는 것과 동작하는 것이 다르다는 그 문장은, 이 시리즈가 나중에 온몸으로 겪을 주제를 이미 예고하고 있었습니다.
pairing required
문제는 그 페어링에서 났습니다. 어느 날 Slack 브리지가 연결을 거부하기 시작했어요. 이유는 한 줄, pairing required. 게이트웨이 쪽에서 보면, 이 디바이스는 아직 페어링이 안 된 것처럼 보였습니다. 등록된 디바이스 목록에는 분명히 다섯 대가 있고, 그중 슬랙과 통하는 쪽의 토큰도 살아 있는데도, 연결만 하면 페어링이 필요하다고 되돌아왔죠.
그때부터가 삽질이었습니다. 로컬에서 승인을 눌러도 소용없었고, 토큰을 다시 받아도 소용없었습니다. 진단 명령도, 게이트웨이 재시작도, 전부 무효였어요. 꺼져 있는 기기가 같은 슬랙 자격증명을 점유해 충돌했다는 사실도 이 무렵의 기록에 남아 있는데, 그 충돌이 어떻게 해서 페어링 오류까지 이어졌는지는 기록에 없어서, 여기서는 충돌이 있었다는 사실만 남겨두고 메커니즘은 짐작으로 채우지 않습니다.
이 버그의 안쪽이 왜 그랬는지도 모릅니다. 고쳐야 할 대상이 남의 코드였고, 그 코드는 내가 열어볼 수 있는 구석이 마땅치 않았어요. 시도해 볼 수 있는 것은 다 해봤고, 그 시도들이 전부 무효였다는 것만 기록에 남아 있습니다.

남의 코드의 버그는, 내 코드의 버그와 다릅니다. 내 코드는 열어서 고칠 수 있지만, 남의 코드는 그 안쪽을 모른 채 시도만 반복하게 됩니다.
플랫폼을 붙들고 있던 마지막 시도도 그 무렵에 있었습니다. 칠월 초의 기록에는, OpenClaw 위에서 로컬 vLLM을 붙이느라 타임아웃과 재시도 사이를 오간 흔적이 남아 있어요. 한 번 타임아웃이 나면 그 제공자는 일정 시간 요청을 거부하는 상태로 들어가고, 재시도 없이 게이트웨이를 통째로 재시작해야 풀립니다. 추론 설정을 낮추고, 요청 타임아웃을 늘리고, 그렇게 한 바퀴를 다 돌아도 뭔가가 매번 어딘가에서 걸렸습니다. 도구 하나를 붙이는 일이 이렇게 험하면, 플랫폼 자체가 문제라는 생각이 들 수밖에 없었어요.
구조로 회피하는 쪽으로
교체를 검토한 것은 그 무렵입니다. 다른 플랫폼이 궁금해서가 아니라, 이 버그가 이 플랫폼의 구조에서 나온 것인지가 궁금했어요. Hermes를 들여다보니, 페어링이라는 개념 자체가 없었습니다. 디바이스를 등록하고 토큰을 승인하는 단계가 아예 없어요. 인증의 설계가 다르니, 페어링 버그가 설계상 생길 자리가 없습니다.
이 대목이 이 편의 핵심입니다. 똑같은 버그를 만났을 때, 패치로 고치는 것과 설계로 회피하는 것은 다릅니다. 패치는 그 버그가 또 나오면 다시 고치면 되지만, 설계로 회피하면 그 버그가 설계상 존재하지 않으므로 다시 만날 일 자체가 없어요.
OpenClaw의 페어링 버그는 고칠 수 없었고, Hermes에는 고칠 페어링 버그가 애초에 없었습니다. 고칠 수 없는 버그를 만났을 때 우회로를 찾는 대신, 구조가 다른 쪽으로 옮기는 선택, 그것이 이 전환의 내용이었습니다.
전환은 그렇게 순식간에 끝났습니다. 칠월 첫째 주의 기록에는 OpenClaw 위에서 로컬 vLLM을 붙이느라 애쓰던 흔적이 남아 있고, 그다음 주의 기록에는 Hermes가 원격 서버의 모델을 메인으로 물고 있습니다. 그 사이 어느 날 플랫폼이 바뀌었던 것이죠. 정확한 날짜는 기록에 없어서, 이 둘 사이였다는 것만 남겨둡니다. 브레인의 MCP도 브레인 쪽 코드가 표준이라 그대로 살아남았고, 창고를 쓰는 손은 플랫폼이 바뀌어도 같은 모양으로 붙어 있었습니다.
조용히 거부하는 기본값
Hermes로 옮기고 나서도 삽질이 하나 더 있었습니다. Slack 브리지가 메시지를 받고도 대답하지 않았어요. 연결이 안 된 것처럼 보였습니다. 그런데 이상한 점은, 메시지에 입력 표시가 떠 있다는 것이었습니다. 받기는 하는데, 대답만 안 하는 상태였죠. 연결 문제라면 입력 표시조차 안 떠야 하는데, 입력 표시가 뜨니까 어딘가에서 요청이 받아지고 있다는 뜻이었습니다.
원인은 설정의 기본값이었습니다. Hermes의 보안 기본값은, 허용 목록(allowlist)이 비어 있으면 외부에서 온 요청을 전부 거부합니다. 거부인데, 조용히 거부예요. 메시지는 받고, 입력 표시는 치고, 그다음이 없습니다. 오류도 로그도 남기지 않으니, 네트워크 쪽을 먼저 의심하게 됩니다.
연결을 확인하고, 재시작하고, 그러고도 대답이 없어서 이번에는 설정을 열어보았고, 그제서야 허용 목록이 비어 있다는 것을 발견했는데, 거부가 조용해서 오류 로그가 없었으니 원인을 찾는 데 그만큼 시간이 걸렸습니다. 허용 목록에 채널을 넣으니 그제서야 대답이 돌아왔어요.
죽었는지 살았는지 알 수 없는 채로 조용히 거부당하는 상태, 그것이 이 삽질에서 제일 고약한 부분이었습니다. 차라리 큰 소리로 거절해 주는 편이 나았죠.
결론 대신
돌아보면, 이 전환에서 가장 시간이 아깝지 않았던 결정은 버그를 고치려는 시도를 그만둔 것이었습니다. 로컬 승인, 토큰 재발급, 진단, 재시작, 그 모두가 무효였고, 무효임을 확인하는 데 쓴 시간이 플랫폼을 통째로 바꾸는 시간보다 길었어요.
이 전환의 전후로 남아 있는 기록은 진단 출력과 세션 기록 몇 개뿐이라, 시도한 순서나 그날의 심경 같은 것은 기록이 남긴 것만 썼습니다. 기억은 기록이 아니어서, 이 편에서는 기억만으로 채운 자리에 짐작이라는 말을 붙였습니다.

고칠 수 없는 남의 버그를 만났을 때, 우회가 아니라 교체가 답인 경우가 있습니다. 이 편의 결론은 그것 하나입니다.
브리지는 Hermes 위에서 다시 살아났고, 그다음 문제는 다른 곳에서 나타났습니다. 대답이 오는 데 걸리는 시간이었어요. 받아들이고 나서야 보인 것이지만, 플랫폼을 바꾸는 일은 그 자체로 끝이 아니라, 그 위에서 문제가 어디서 나는지가 달라지는 일이었습니다. 그 이야기는 다음 편에서 풀겠습니다.