
【#2】Hermes Agent 해독하기
요약
Hermes Agent의 핵심인 코어 대화 루프(conversation loop)의 동작 원리를 분석합니다. 사용자 메시지 한 번의 왕복 과정에서 발생하는 API 호출, 툴 실행, 상태 관리 및 다양한 API 형식(OpenAI, Anthropic 등)의 통합 방식을 다룹니다.
핵심 포인트
- Hermes의 핵심은 툴 호출이 반복되는 while 루프 구조임
- 상태 오염 방지를 위해 메시지 정본과 송신용 복사본을 분리함
- 실패 유형(JSON 오류, Truncation 등)에 따른 차별화된 회복 전략 적용
- 다양한 LLM API 형식을 하나의 공통 루프로 흡수하여 프로바이더 차이 극복
연재 「Hermes Agent 해독하기」 제2회.
연재 「Hermes Agent 해독하기」 총 10회
- [제1회 전체상과 읽는 법]
[제2회 코어 대화 루프] (본 기사) - [제3회 상태 관리와 컴팩션 (Compaction)]
- [제4회 기억 아키텍처와 인격]
- [제5회 툴 시스템 (Tool System)]
- [제6회 멀티 에이전트 병렬]
- [제7회 Kanban 영속 태스크 보드]
- [제8회 접속층과 인터페이스 총람]
- [제9회 확장 운용]
- [제10회 보안과 안전 운용]
에이전트의 거동을 이해하는 최단 경로는, 사용자가 메시지를 1개 보내고 나서 1개의 응답이 돌아올 때까지——이 1턴을 코드에 따라 처음부터 끝까지 추적하는 것이다. Hermes의 경우, 그 본체는 agent/conversation_loop.py이다. 4,836행에 달하는 거물이지만, 골격은 놀라울 정도로 솔직한 while 루프에 담겨 있다.
1턴은 다음 5단계로 흐른다.
입력을 받고, 시스템 프롬프트 (System Prompt)를 구성하여 메인 루프에 진입한다. 루프는 툴 호출 (Tool Call)이 계속되는 한 돌아가며, 탈출하면 상태를 SQLite에 영속화하고 반환값을 돌려준다. 중요한 것은, 툴 호출이 1턴 안에서 여러 번 반복된다는 점이다. 사용자 입장에서 보는 '1왕복'의 내부에서 API 호출 → 툴 실행 → 다시 API 호출……이 여러 번 일어난다.
루프 1회전은 다음 순서로 진행된다.
- API 호출— 현재 메시지 열을 모델에 전달
- 응답 분석— 텍스트와 툴 호출을 분리
- 툴 검증— 툴 이름 및 인자 (Argument)의 타당성 체크
- 툴 실행— 검증을 통과한 것을 실행
- 압축— 컨텍스트 (Context)가 임계치를 넘으면 컴팩션 (Compaction) (제3회)
- 탈출 판정— 툴 호출이 없으면 루프를 탈출
설계상의 요점이 하나 있다. messages가 정본 (Source of Truth)이며, API 호출은 그 복사본에 대해 수행한다. 왜일까? API에 전달하기 직전에는 고아가 된 툴 결과의 제거이나 스텁화 (Stubbing) (제3회 §4), 컨텍스트 주입과 같은 일시적인 가공이 들어간다. 이를 정본에 직접 적용하면 상태가 오염된다. 그래서 "정본은 건드리지 않고, 송신용 복사본을 매번 만들어 가공한다". 소박하지만, 상태 관리의 견고함을 지탱하는 판단이다.
LLM의 출력은 불안정하다. Hermes는 실패 유형별로 4가지 회복책을 가진다.
| 실패 | 대처 |
|---|---|
| 부적절한 JSON | 최대 3회 재시도 |
| ... | |
| "어쨌든 전부 재시도"하는 것이 아니라, 실패의 성질에 따라 수단을 바꾸는 것이 포인트다. JSON 깨짐이나 툴 이름 오기입은 "다시 말하면 고쳐지는" 종류이므로 재시도한다. Truncation은 "중간까지는 올바르기" 때문에 버리지 않고 부분 채택한다. 빈 응답은 재촉 → 모델 교체와 같이 단계적으로 대응한다. |
Hermes는 3가지 API 형식를 내부에서 흡수한다.
anthropic_messages— Anthropic Messages API 형식openai— OpenAI Chat Completions 형식codex_responses— OpenAI Responses 형식
호출 측의 루프는 공통이며, 이 층이 프로바이더(Provider) 차이를 흡수한다. Thinking 계열 모델의 reasoning (사고 과정) 처리도 여기에 포함된다——reasoning 블록을 다음 턴으로 인계할지 버릴지는 모델과 API 형식에 따라 분기된다. OpenAI SDK 호환을 "축"이라 부르면서도, 실제로는 여러 형식을 병행시키고 있는 것이다.
다음 회차는 루프 안에서 슬쩍 호출되었던 "압축"과, 그 토대가 되는 상태 스토어——hermes_state.py (SQLite + FTS5)와 agent/context_compressor.py를 파헤친다.
대응 맵 장: §2 / 행 번호는 hermes update 시 어긋날 수 있음
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기