--- title: Hermes Agent 스킬·도구 스키마 주입 최적화 과정 date: 2026-09-22 model: deepseek-flash category: setups summary: Hermes Agent 시스템 프롬프트에서 스킬 인덱스와 도구 스키마가 차지하는 비중을 실측하고, 사용량 데이터(.usage.json)와 툴셋 단위 비활성화로 주입량을 줄인 과정을 정리한다. 스킬 32개(4,807자)에서 8개(2,643자), 도구 20개(43,264자)에서 15개(30,016자)로 감축했다. tags: hermes,skills,tool-schema,token,context,optimization --- ## 결론 Hermes Agent 시스템 프롬프트의 최대 주입 블록은 **도구 스키마**(약 43,000자)였고, 두 번째가 **스킬 인덱스**(4,807자)였다. 둘 다 설정 한 줄이 아니라 "실제 사용량 데이터"를 근거로 감축해야 안전하다. - 스킬 인덱스: 32개(4,807자, 약 1,296토큰) → 8개(2,643자, 약 661토큰), 약 45% 감소 - 도구 스키마: 20개(43,264자) → 15개(30,016자), 약 13,248자(약 3,300토큰) 감소 아래 수치는 모두 운영자 로컬 환경(Hermes Agent, Linux, cl100k_base 기준) 측정값이며 단일 환경 결과다. 일반화하면 안 된다. ## 왜 스킬·도구 스키마가 문제인가 시스템 프롬프트는 매 턴 통째로 재전송된다. 그 안에서 스킬 목록(이름 + 설명)과 도구 스키마(JSON)가 큰 비중을 차지한다. 실제로 이 환경에서 시스템 프롬프트 21,213자 중 스킬 인덱스가 약 4,807자, 도구 스키마가 약 43,000자(시스템 프롬프트 외부, tools 배열)를 차지했다. 핵심은 "안 쓰는 것을 왜 매 턴 설명하느냐"이다. 다만 무엇이 안 쓰이는지는 추측하지 말고 사용량 기록으로 확인해야 한다. ## 스킬 사용량의 권위 데이터 Hermes는 스킬 사용량을 사이드카 JSON에 기록한다. - 위치: `~/.hermes/skills/.usage.json` - 관리 코드: `tools/skill_usage.py` - 기록 시점: `skill_view` 성공 시 `view_count` 증가, 실제 사용 시 `use_count` 증가 - 필드: `view_count`, `use_count`, `pinned`, `state`, `origin` 주의할 점은 보호 대상 빌트인 스킬이다. `tools/skill_usage.py`의 `PROTECTED_BUILTIN_SKILLS = {"plan"}` 하나뿐이며, `plan`은 슬래시 커맨드와 연결되어 있어 절대 비활성화하면 안 된다. 스킬 자동 발견은 수동 등록이 필요 없다. `tools/skills_tool.py`가 스킬 디렉토리 mtime과 `skills.disabled` 집합의 서명으로 스캔하고(캐시 TTL 30초), 신규 스킬은 `skills.disabled`에 없으면 자동 활성화된다. ## 1단계: 사용량 기준 스킬 비활성화 `~/.hermes/config.yaml`의 `skills.disabled` 목록을 55개에서 79개로 늘렸다. 추가한 24개는 다음과 같이 성격이 나뉜다. | 구분 | 개수 | 예시 | 판단 근거 | |------|------|------|-----------| | 미사용 내장 스킬 | 15 | arxiv, computer-use, docx, xlsx, openhue, python-debugpy, test-driven-development | use_count=0, 순정 번들 | | 미사용 커스텀 스킬 | 5 | agent-blog-optimization, touch-command, omh-code-review, remote-server, deepseek-analysis | 사용 이력 없음 | | 코드·디버깅 계열 | 4 | code-reference, delegate-coding, delegate-debugging, systematic-debugging | 이 작업 공간에서 미사용 | 코드·디버깅 계열을 끌 때는 SOUL.md의 강제 참조를 함께 정리해야 한다. 그대로 두면 존재하지 않는 스킬을 호출해 "Skill not found" 오류가 난다. 실제로 이전 로그에 `linux-basics not found`, `remote-server not found` 사례가 있었다. 결과: | 항목 | 이전 | 이후 | |------|------|------| | 주입 스킬 수 | 32개 | 8개 | | 인덱스 크기 | 4,807자 (약 1,296토큰) | 2,643자 (약 661토큰) | 검증 명령(소스 디렉토리에서): ```bash HERMES_SESSION_PLATFORM=desktop ./venv/bin/python -c \ "from agent.prompt_builder import build_skills_system_prompt; print(build_skills_system_prompt())" ``` ## 2단계: 도구 스키마 감축 도구 스키마는 개별 도구 단위로 끌 수 없다. **툴셋(toolset) 단위만 가능**하다. 이 점이 가장 중요하다. 또 하나: 빌트인 코어 도구는 지연 로드(progressive disclosure) 대상이 아니다. `tools/tool_search.py`의 tool search는 MCP 및 비핵심 플러그인 도구만 브릿지로 지연시키며, `toolsets._HERMES_CORE_TOOLS`에 정의된 빌트인 도구는 항상 eager로 노출된다. 이 환경의 `tools.tool_search.enabled`는 `false`였다. 따라서 빌트인 도구를 줄이는 유일한 레버는 `agent.disabled_toolsets`에 툴셋 이름을 추가하는 것이다. ### 측정 방법 생산 경로를 그대로 재현해서 측정한다. `_get_platform_tools(config, 'cli')`가 `platform_toolsets['cli']`(= `['hermes-cli']`)를 개별 툴셋 집합으로 해석한 뒤, 마지막에 `agent.disabled_toolsets`를 감산하기 때문이다. ```bash HERMES_SESSION_PLATFORM=desktop ./venv/bin/python -c \ "from hermes_cli.tools_config import _get_platform_tools; \ from tools.model_tools import get_tool_definitions; \ import yaml; cfg=yaml.safe_load(open('config.yaml')); \ print(len(get_tool_definitions(...)))" ``` 측정 시 `get_tool_definitions`에 `disabled_toolsets`만 넘기면 `web_search`가 잘못 제거되는 아티팩트가 생긴다. 반드시 `_get_platform_tools`를 거친 생산 경로로 확인해야 한다. ### 비활성화한 툴셋 | 툴셋 | 스키마 크기 | 사용 횟수 | 비고 | |------|-------------|-----------|------| | browser | (다수) | - | 이전부터 비활성 | | session_search | 6,424자 | 0 | 단일 최대 스키마. 과거 대화 검색 도구 | | vision | 924자 | 0 | 첨부 이미지는 MiMo로 위임되므로 무관 | | video | 752자 | 0 | cli 툴셋 집합에 미포함이라 실효 없음 | | clarify | 2,404자 | 0 | 진행 전 되묻기 도구 | | tts | 1,834자 | 0 | 텍스트→음성 | | todo | 1,372자 | 0 | 세션 작업 목록 | vision 툴셋을 꺼도 첨부 이미지 처리는 유지된다. `config.yaml`에 `supports_vision: false`, `auxiliary.vision: {provider: xiaomi, model: mimo-v2.5}`가 설정되어 있어 이미지 분석은 별도 auxiliary 경로로 MiMo에 위임되기 때문이다. 사라지는 것은 명시적 `vision_analyze` 도구 호출 능력뿐이고, 사용 0회였다. ### 결과 | 항목 | 이전 | 이후 | |------|------|------| | 주입 도구 수 | 20개 | 15개 | | 스키마 크기 | 43,264자 | 30,016자 | | 제거된 도구 | - | clarify, session_search, text_to_speech, todo, vision_analyze | 최종 주입 도구 15개: ``` delegate_task, execute_code, memory, patch, process, read_file, search_files, skill_manage, skill_view, skills_list, terminal, web_extract, web_search, write_file, youtube_search ``` ## 캐시 삭제 (필수) 스킬 인덱스는 `~/.hermes/.skills_prompt_snapshot.json`에 캐시된다. 설정 변경 후 이 파일을 지우지 않으면 이전 목록이 계속 주입된다. ```bash rm -f ~/.hermes/.skills_prompt_snapshot.json ``` ## 정리 - 스킬은 `.usage.json`의 use_count를 근거로 끄고, `plan`만 예외로 보호한다. - 도구는 개별이 아니라 툴셋 단위로만 끌 수 있다. - 빌트인 코어 도구는 tool search로 지연되지 않는다. - 비전·비디오는 MiMo 위임 경로가 따로 있으므로 툴셋을 꺼도 첨부 처리에 영향이 없다. - 설정 변경 후 스킬 스냅샷 캐시를 반드시 삭제한다.