Mac에서 로컬 LLM 최적화하기 / EP08
Hermes를 깨우다 — 나만의 AI 에이전트 구축 첫날
8GB iMac에서 Hermes와 로컬 Qwen을 연결해봤다. 첫 실행을 막은 64K 컨텍스트 검사, Ollama 응답과 실제 도구 실행의 차이를 로그로 확인한 기록.
이 글의 내용
QwenPaw 다음에는 Hermes를 켜보기로 했다
EP07에서는 작은 Qwen으로 시작해 OpenCode Go와 Codex로 넘기는 경로를 시험했다. 정해둔 과제에서는 실제 호출이 이어졌다. 하지만 자연어로 부탁했을 때 도구를 고르는 일, 원격 세션을 이어가는 일은 따로 해결해야 했다.
그래서 EP06에서 그렸던 Hermes 쪽으로 한 발 옮겨보려 한다. 원하는 건 여전히 같다. 대화창 하나에서 일을 맡기고, 뒤에서는 필요한 모델과 도구가 움직이는 것.
Hermes 자체를 처음 접하는 날은 아니다. 이미 설치돼 있고 Telegram에도 연결해 쓰고 있다. 오늘의 ‘첫날’은 기존 환경과 분리해 로컬 모델 연결부터 파일 작업까지 근거를 남겨보는 첫 실험에 가깝다.
그런데 첫 질문에 답을 받기도 전에 막혔다. 메모리보다 먼저, 컨텍스트 길이에서.
오늘도 장비는 8GB iMac
확인한 날짜는 2026년 10월 23일. 주문한 Mac Studio M5 Max 128GB / 1TB 대신, 실제 명령을 실행한 장비는 아직 M1 iMac이다.
| 항목 | 직접 확인한 환경 |
|---|---|
| Mac | iMac21,2 · Apple M1 · 통합메모리 8GiB |
| 운영체제 | macOS 26.6.2 · build 25G83 |
| Hermes | 버전 출력 v0.21.0 (2026.8.31) · 소스 HEAD 63279301 |
| 실행 기반 | Hermes 가상환경의 Python 3.11.3 |
| 로컬 런타임 | Ollama 0.20.0 |
| 이미 설치된 모델 | Qwen2.5 1.5B Instruct · Q4_K_S |
| 코딩 도구 | OpenCode 1.4.3 · Codex CLI 0.163.0 · Claude Code 2.1.308 |
Hermes에는 로컬 수정 커밋이 하나 있었다. 버전 문자열만으로 최신 공식 릴리스라고 부르지 않고, 이번 동작은 설치된 소스를 기준으로 적는다. 공식 설치 안내와 실제 hermes chat --help를 대조했고, 기존 설치를 업데이트하거나 다시 설치하지는 않았다.
Codex는 ChatGPT 로그인, Claude Code는 구독 로그인이 확인됐다. OpenCode에는 Go를 포함한 공급자 인증 항목이 있었다. 인증이 있다는 것과 실제 요청이 성공한다는 것은 별개라 여기서는 설치·로그인 상태까지만 확인했다.
시작 전에 vm.swapusage가 보여준 swap 사용량은 약 4GB였다. 이미 다른 작업을 하고 있는 8GB Mac이다. 오늘은 이 상태에서 장시간 부하나 여러 모델 동시 실행까지 밀어붙이지 않기로 했다. 기존 QwenPaw PoC 원본과 로그도 외장 보관본에서 찾았고, 수정하지 않았다.
설치 대신, 실험용 프로필부터
운영 중인 Telegram 설정을 건드리고 싶지는 않았다. 별도의 HOME과 HERMES_HOME을 만들고, 모델 주소·출력 제한·도구 설정을 작은 구성으로 분리했다. 기존 인증 파일이나 프로젝트 기억을 복사하지 않았다.
Hermes 프로필 문서는 인스턴스별 설정과 세션을 분리하는 방법을 설명한다. 여기서도 같은 취지로 실험용 홈을 사용했다. 이것은 설정 분리다. 로컬 터미널 도구를 켜면 그 자체로 파일시스템 샌드박스가 생기는 것은 아니다.
Ollama는 루프백 주소에서만 켰다. 클라우드 기능은 끄고 병렬 요청과 로드 모델 수를 각각 1로 제한했다. 이미 있던 모델을 썼으므로 이 시험을 위해 큰 모델을 새로 받을 필요는 없었다.
실제 구성에서 모델 부분은 이랬다.
model:
default: qwen2.5:1.5b-instruct-q4_K_S
provider: custom
base_url: http://127.0.0.1:11434/v1
api_key: ollama
context_length: 8192
max_tokens: 256
fallback_providers: []
toolsets: []
auxiliary:
free_only: true
title_generation:
enabled: false
여기서 ollama는 로컬 호환 API에 전달한 더미 문자열이다. 운영 중인 비밀키가 아니다. 공식 Ollama 연결 문서의 custom endpoint 형태를 확인한 뒤, 설치된 CLI가 읽는 설정과 대조했다.
첫 실행은 64K 검사에서 멈췄다
첫 과제는 거창하지 않았다. 시험용 문자열 CEDAR-58을 기억시키고 같은 세션을 다시 열어 확인하려 했다. 파일을 수정하는 도구는 아직 켜지 않았다.
아래는 실제 실행 명령에서 비공개 경로와 가상환경 Python 경로만 변수로 치환한 형태다. $PYTHON은 Hermes 가상환경 실행 파일이고, 명령은 설치된 Hermes 소스 디렉터리에서 실행했다. LAB는 별도 시험 디렉터리다.
HOME="$LAB/home" HERMES_HOME="$LAB/hermes-home" \
"$PYTHON" -m hermes_cli.main chat \
--ignore-rules --max-turns 5 --run-budget 100 -Q -t '' \
-q 'Remember this synthetic session code: CEDAR-58. Reply with the code only.'
--ignore-rules로 기존 프로젝트 규칙과 기억이 실험 요청에 섞이지 않게 했다. 실제 프로세스 환경에서도 외부 공급자 키를 넘기지 않았다. 결과는 종료 코드 1. 프로세스 시작부터 오류 종료를 확인하기까지 5.034초였다. 종료 상태를 0.5초 간격으로 확인한 계측이라 정밀한 초기화 성능 수치는 아니다.
Failed to initialize agent
context window: 8,192 tokens
minimum required by Hermes Agent: 64,000
위 로그는 줄바꿈과 반복 설명을 줄인 발췌다. 설치된 agent/model_metadata.py의 MINIMUM_CONTEXT_LENGTH와 agent/agent_init.py의 초기화 검사를 확인하니 이유가 맞았다. 이번 custom endpoint 구성은 64,000토큰 미만이면 시작을 거부했다. 모든 Hermes 버전과 실행 경로에 대한 일반화는 아니다.
8K를 64K로 고쳐 적으면 될까? Qwen2.5 1.5B의 공식 설정은 최대 위치 길이를 32,768로 적고 있다. 지원하지 않는 길이를 설정에 써놓고 연결 성공이라고 하기는 어렵다. 실제 컨텍스트 확장과 런타임 지원을 검증하는 일도 이번 시험과는 다르다.
그래서 여기서는 멈췄다. 기본 대화, 세션 저장 후 재실행, 기억 회수는 도달하지 못한 항목으로 남겼다. 메모리 부족 오류를 본 것도 아니다. 이번 실행을 막은 직접 근거는 초기화 단계의 컨텍스트 검사다.
이번에 실제로 지나간 경로
Ollama가 답하는 것과 Hermes가 일하는 것은 달랐다
Hermes가 시작하지 못하니 모델 자체도 응답하지 못하는지 분리해봤다. 같은 Qwen에 Ollama의 /api/chat으로 짧은 요청 두 개만 보냈다. 컨텍스트 8,192, 최대 생성 96토큰, temperature 0, keep_alive: 0 조건이다.
첫 요청은 LOCAL_READY라고만 답하라는 것이었다. 실제 응답도 LOCAL_READY. HTTP 요청부터 응답 완료까지 1.883초가 걸렸다. 모델 로딩을 포함한 단발 결과다.
두 번째는 read_file 도구 스키마를 주고 README를 읽으라고 했다. 응답 JSON에 다음 호출 제안이 들어왔다.
{"name":"read_file","arguments":{"path":"/path/to/README.md"}}
2.316초 만에 호출 모양은 나왔다. 그런데 경로가 임의의 예시 경로였다. 그리고 이 요청은 진단용 API 호출이라, 반환된 함수를 실행하는 dispatcher를 붙이지 않았다. 실제 파일 읽기 0회.
Ollama의 모델 정보에는 tools capability가 있었다. 그래도 이 시험에서 확인한 건 ‘도구 호출을 제안할 수 있다’까지다. 유효한 인자 선택, 실제 실행, 실행 결과를 받아 다음 행동을 하는 능력은 더 확인해야 한다. EP07의 QwenPaw Skill 실패와도 요청·프롬프트·실행 루프가 달라, 이번 결과로 당시 실패 원인을 뒤집을 수는 없다.
실행 시간도, 무엇을 잰 건지부터
A · Hermes · 초기화 실패까지5.034 s
B1 · Ollama 직접 응답 · LOCAL_READY1.883 s
B2 · Ollama 호출 제안 · 실행 없음2.316 s
메모리 숫자도 아껴 적으려 한다. 이번에는 모델의 GPU 메모리나 전체 통합메모리 피크를 측정하지 않았다. 실패한 Hermes 시작 과정의 프로세스 RSS 표본을 모델 메모리 요구량으로 부를 수는 없다. 기존 앱이 켜져 있었으니 swap 변화만으로 이 모델의 영향을 분리하지도 않았다.
첫 파일 작업은 아직 실행 전
파일 작업용으로는 실제 앱 대신 작은 Python 프로젝트를 만들었다. add(a, b)가 잘못해서 a - b를 반환하고, 별도 테스트는 add(2, 3) == 5와 add(-1, 1) == 0을 검사하는 구성이다.
검사기가 먼저 python3 test_calc.py를 실행했고 예상대로 AssertionError가 났다. 이것은 고치기 전 기준선이다. Hermes가 파일을 읽거나 수정한 결과는 아니다.
원래 이어갈 순서는 ‘요청 → 파일 읽기 → 수정 → 테스트 → 외부 재검사’였다. 하지만 시작 단계가 막힌 상태에서 뒤쪽을 수작업으로 고쳐놓고 에이전트 성공으로 적을 수는 없다. C는 FAIL 대신 NOT TESTED로 남겼다. 실험을 실행해서 잘못된 수정을 낸 상황과 구분하기 위해서다.
클라우드 경로는 무엇을 검증해야 할까
로컬 실험은 iMac의 여유를 고려해 여기서 중단했다. 시험용 Ollama 서버도 내렸다. 대신 현재 설치에서 가능한 클라우드 연결 방식을 조사했다.
공식 Codex app-server 문서는 Hermes에서 Codex 런타임으로 한 턴의 실행을 넘기는 선택적 경로를 설명한다. 이 경우 도구 실행 루프는 Codex 쪽이 맡는다. Hermes가 로컬 결과를 Judge로 검사하고 Codex로 자동 승격하는 구조와는 다르다. ACP 연결도 아니다.
이번에는 문서와 설치된 소스, CLI 인증 상태까지만 확인했다. 구독을 사용하는 실제 요청은 아직 실행하지 않아 D는 NOT TESTED다. Claude Code·OpenCode Go를 실제로 호출했다거나, iPhone에서 Hermes 결과를 확인했다는 기록도 아직 없다.
여기서 API 키 방식과 구독 로그인도 구분해야겠다. ChatGPT 로그인 여부를 확인했다고 OpenAI API 요금이 포함된다고 해석하지 않는다. 다음 시험에서는 선택한 실행 경로와 사용량부터 남길 생각이다.
오늘 확인한 것과 아직 확인하지 못한 것
A–E · 어디까지 확인했을까?
A · Hermes 첫 실행
FAIL
8,192토큰 설정을 최소 64,000토큰 검사에서 거부했다. 대화·세션 재개까지 도달하지 못했다.
근거 · CLI 종료 코드 1 · 초기화 오류 로그
B · 로컬 응답과 호출 제안
PARTIAL
Ollama 직접 요청은 LOCAL_READY를 반환했다. 별도 요청에서는 read_file을 제안했지만 경로가 예시 경로였고 도구 실행은 0회였다. Hermes 연결 성공은 아니다.
근거 · Ollama 응답 JSON · content와 tool_calls를 분리 확인
C · 실제 파일 수정
NOT TESTED
격리된 add 함수와 실패하는 테스트만 준비했다. Hermes 초기화가 막혀 에이전트의 수정·테스트는 실행하지 않았다.
근거 · 시험용 원본 파일 · 별도 검사기의 예상된 AssertionError
D · 클라우드 실행 경로
NOT TESTED
인증 상태와 공식 app-server 경로만 조사했다. 구독을 사용하는 실제 요청과 세션 재개는 아직 실행 전이다. ACP나 자동 승격 성공으로 기록하지 않았다.
근거 · CLI 인증 상태 · 공식 문서·설치된 소스
E · iPhone 원격 요청
NOT TESTED
이번 Hermes 실험에서는 iPhone에서 보낸 요청과 반환 결과를 확인하지 않았다. EP07의 QwenPaw 원격 결과와 구분한다.
근거 · 이번 편의 실행 근거 없음
이번에 QwenPaw와 Hermes를 같은 과제로 끝까지 돌린 것은 아니다. 비교할 수 있는 범위만 적어보면 이렇다.
| 확인할 것 | EP07의 QwenPaw PoC | 이번 Hermes 실험 |
|---|---|---|
| 로컬 모델 응답 | 실제 Ollama 경로에서 확인 | Ollama 직접 진단만 확인 · Hermes는 초기화 실패 |
| 도구·파일 작업 | 명령 플러그인 경로와 최종 Codex 파일 검사를 확인 | 호출 제안만 관찰 · 실제 파일 작업 미실행 |
| 클라우드 전환 | 통제된 B/C 경로에서 실제 호출 | 미실행 |
| 원격·세션 | 별도 ACP 어댑터와 후속 시험 기록 존재 | 이번 Hermes 경로는 미검증 |
| 결과 판단 | 결정적 검사, 별도 의미 Judge 평가의 한계 확인 | 통합 Judge 시험 전 |
QwenPaw에서는 경로를 직접 이어 붙이는 일이 컸다. Hermes에서는 그 앞에 둘 메인 에이전트가 어떤 모델과 컨텍스트를 요구하는지부터 맞춰야 했다. 이미 있는 라우터나 Judge가 자동으로 따라오는 것은 아니었다.
결정적 검사는 파일·테스트·형식을 확인한다. 의미 Judge는 요구사항과 근거를 판단하는 별도 실험이다. 오늘 기본 대화조차 시작하지 못한 결과를 의미 Judge로 PASS 처리할 일은 없다.
EP09에서는 어디부터 이어갈까
Hermes를 켜면 작은 모델이 파일 하나쯤은 바로 고쳐줄 수 있을까 싶었다. 오늘 답은 아직 못 얻었다. 대신 모델이 답할 수 있는 환경과 에이전트가 시작할 수 있는 환경이 같지 않다는 건 확인했다.
다음에는 메인 에이전트의 실행 경로를 먼저 정하고, 격리된 같은 과제로 파일 읽기·수정·테스트·세션 재개를 이어가려 한다. 로컬 부하 시험은 Mac Studio가 도착해 여유를 확인한 뒤다. 그때 EP01의 지연 구분과 EP02의 메모리 예산도 실제 작업 로그에 같이 붙여볼 수 있겠다.
자동 승격, 의미 Judge, iPhone 접근은 그 뒤에 하나씩. 오늘은 설계도에서 실행으로 내려오는 첫 단계에서 멈췄다. 어디에서 멈췄는지는 이제 알겠다.
참고 자료
2026-10-23 확인. 웹 문서의 최신 설명과 설치된 코드의 동작은 구분했다.
댓글과 좋아요
로그인 없이 닉네임으로 남길 수 있어. 닉네임과 댓글은 공개되고, 댓글은 확인 후 올라가.