Field Log · Entry

Hermes Agent 구축 후 최적화: Tool·Memory·Skill을 줄이는 순서 (3/7)

Hermes Agent 최적화가 작업 평가셋에서 도구 범위 문맥 기억 스킬 모델 예약 실행을 한 변수씩 조정하고 성공률 비용 지연 위험을 측정하는 흐름

이번 글의 결론

  • Agent 최적화는 “더 좋은 모델로 교체”가 아니라 성공률·비용·지연·위험의 동시 개선입니다.
  • 먼저 Tool을 줄이고, 다음으로 항상 필요한 문맥을 줄이고, 반복 절차를 Skill로 옮긴 뒤 model을 비교합니다.
  • Memory에는 매 session 필요한 짧은 사실, session search에는 과거 대화, Skill에는 긴 절차를 둡니다.
  • Hermes의 self-improvement는 결과가 아니라 변경 제안입니다. Memory·Skill write approval을 켜고 diff를 검토합니다.
  • Cron은 잘되는 일을 자동화하는 마지막 단계입니다. 불안정한 prompt를 schedule하면 실패가 자동 반복됩니다.

앞 글에서는 Hermes를 전용 계정과 격리 backend를 가진 VPS service로 만들었습니다. 이제 빠르게 만들기 전에 같은 입력에서 같은 품질을 내는지부터 측정합니다.

1. 최적화 목표를 네 축으로 고정한다

“좋아졌다”를 모델의 느낌으로 판단하지 않습니다.

질문최소 지표
품질요청한 일을 끝냈는가task success, 검증 항목 충족률
비용한 번 성공하는 데 얼마가 드는가input/output token, API cost, 재시도 수
지연사람이 결과를 받기까지 얼마나 걸리는가wall time, first response, tool 대기
위험불필요한 권한·행동이 있었는가범위 밖 tool call, 승인 요청, 정책 차단

한 축만 줄이면 다른 축을 망칠 수 있습니다. 작은 model로 token 비용이 줄어도 재시도가 세 번 늘면 성공 1건당 비용은 오를 수 있습니다. 승인 prompt를 모두 없애 지연을 줄였지만 host write 위험이 커졌다면 운영 최적화가 아닙니다.

2. 실제 작업 10개를 작은 평가셋으로 만든다

반복 중인 “블로그 초안 점검”을 예로 듭니다.

suite: blog-frontmatter-audit-v1
cases:
  - id: valid-post
    fixture: fixtures/valid.md
    expected: no_violation
  - id: short-description
    fixture: fixtures/short-description.md
    expected: description_min_length
  - id: too-many-tags
    fixture: fixtures/too-many-tags.md
    expected: tags_max_7
  - id: missing-series-order
    fixture: fixtures/missing-series-order.md
    expected: series_pair_violation
  - id: invalid-cover
    fixture: fixtures/invalid-cover.md
    expected: image_validation_failure

실패 유형을 섞어 10개 정도로 시작합니다.

  • 정상 문서
  • 한 가지 명백한 위반
  • 위반이 여러 개인 문서
  • 판단 근거가 부족한 문서
  • 한글·영문·긴 code block이 섞인 문서

평가 prompt와 fixture를 versioning하고, 각 run에서 다음 표를 남깁니다.

run_id | config_rev | model | success | false_positive
       | tool_calls | input_tokens | output_tokens | seconds
       | human_corrections | policy_blocks

이 표가 없으면 model·Memory·Skill을 동시에 바꾼 뒤 무엇이 효과를 냈는지 알 수 없습니다.

3. 첫 번째 최적화: Toolset을 줄인다

Tools & Toolsets 문서에 따르면 Hermes는 platform별 toolset을 다르게 구성할 수 있습니다.

hermes tools

frontmatter 점검에 browser·image generation·delegation·cron은 필요하지 않습니다. CLI에서 일회성으로 범위를 시험할 수도 있습니다.

hermes chat --toolsets "file,safe" \
  -q "이 repository의 최근 글 3개 frontmatter를 schema와 비교해 점검해줘"

실제 설치에서 보이는 toolset 이름과 조합은 hermes tools 출력이 기준입니다. 핵심은 allowlist를 길게 쓰는 것이 아니라 작업에 필요한 최소 capability profile을 만드는 것입니다.

Tool이 줄면 세 가지가 함께 좋아집니다.

  1. system prompt의 tool schema가 작아짐
  2. model이 엉뚱한 도구를 고를 선택지가 줄어듦
  3. 손상·유출 가능한 외부 system이 줄어듦

단, tool을 너무 줄여 실제 필요한 read_file까지 빠지면 agent가 추측으로 답할 수 있습니다. explicit allowlist가 비어도 text-only로 조용히 진행하게 두지 말고, smoke test에서 필요한 tool call이 실제 발생했는지 확인합니다.

4. 두 번째 최적화: 문맥을 네 저장소로 분리한다

Hermes의 문맥은 한 덩어리가 아닙니다.

정보둘 곳이유
저장소 build·test·금지 규칙AGENTS.mdproject와 함께 versioning
사용자 말투·timezone·선호USER.md memory모든 session에 짧게 필요
환경의 핵심 사실·교정MEMORY.md memorysession 시작부터 필요
과거의 구체적 대화session search필요할 때만 검색
긴 반복 절차SKILL.mdtask가 맞을 때만 load
일회성 log·raw dataartifact/fileprompt에 상시 넣지 않음

현재 Persistent Memory 문서~/.hermes/memories/MEMORY.mdUSER.md를 session 시작에 주입하며, 기본 한도를 각각 2,200자와 1,375자로 둡니다. 이 제한은 불편함이 아니라 prompt를 bounded하게 유지하는 장치입니다.

좋은 Memory:

Blog repo uses Astro content schema at src/content.config.ts.
Site changes must pass npm run build. Never edit dist/.

나쁜 Memory:

지난 화요일에 300줄짜리 build log에서 본 모든 오류와 대화 전문...

이미 AGENTS.md에 있는 규칙을 Memory에 복사하면 token을 두 번 내고, 둘이 달라질 때 충돌합니다. raw log는 파일로 남기고 session search나 file search로 찾습니다.

Memory가 바뀌었는데 현재 대화가 모르는 이유

Memory는 session 시작 때 frozen snapshot으로 들어갑니다. 대화 중 저장한 내용은 disk에는 즉시 반영되지만 system prompt에는 다음 session부터 보입니다. 이 동작은 prompt prefix cache를 보존하기 위한 설계입니다. Memory를 수정한 직후 테스트할 때는 새 session에서 확인합니다.

5. 세 번째 최적화: 반복 절차를 Skill로 승격한다

같은 task를 세 번 이상 성공했고, 실패 패턴도 관찰했다면 Skill 후보입니다.

name: astro-frontmatter-audit

input
  target markdown paths

procedure
  1. read src/content.config.ts
  2. parse frontmatter only
  3. check field constraints
  4. report evidence, do not edit

verification
  every finding has path + field + actual value + rule

failure policy
  schema unreadable → stop
  image resolution unavailable → mark unknown

Hermes에서는 /learn으로 성공한 대화를 skill 초안으로 만들 수 있습니다.

/learn how I just audited Astro frontmatter, including the evidence table and stop conditions

또는 직접 SKILL.md를 작성합니다.

---
name: astro-frontmatter-audit
description: Audit Astro post frontmatter against the local schema
version: 1.0.0
---

# Astro Frontmatter Audit

## When to Use
Use when asked to validate post metadata without changing files.

## Procedure
1. Read `src/content.config.ts` first.
2. Read only the requested Markdown frontmatter.
3. Compare every field with the current schema.
4. Report path, field, actual value, and violated rule.

## Pitfalls
- Do not assume an image exists from its path string alone.
- Do not reuse constraints remembered from another repository.

## Verification
Every conclusion must point to the current schema or be marked unknown.

Skill description은 짧고 trigger가 분명해야 합니다. Hermes는 description index만 먼저 보고 필요한 skill의 전문을 나중에 load하는 progressive disclosure를 사용합니다.

Self-improvement에는 review gate를 둔다

Hermes는 성공·오류·사용자 교정에서 Memory나 Skill 변경을 제안할 수 있습니다. 운영에서는 자동 변경을 그대로 신뢰하지 않습니다.

memory:
  write_approval: true

skills:
  write_approval: true

display:
  memory_notifications: verbose

검토 명령:

/memory pending
/memory approve <id>
/memory reject <id>

/skills pending
/skills diff <id>
/skills approve <id>
/skills reject <id>

학습 loop의 품질은 “얼마나 자주 스스로 고쳤나”가 아니라 잘못된 일반화를 사람이 merge 전에 잡을 수 있는가로 평가합니다.

6. 네 번째 최적화: Model은 동일 평가셋으로 비교한다

이제야 model을 바꿉니다.

hermes model

한 model을 “싼 모델”, 다른 model을 “좋은 모델”이라고 이름 붙이지 말고 실제 10개 task를 같은 조건으로 실행합니다.

Model성공사람 교정평균 tool call성공당 비용p95 시간
A9/1014.2계산값측정값
B7/1045.8계산값측정값

값은 직접 측정해 채웁니다. 모델 가격표만 보고 비용을 적지 않습니다. 실패 재시도와 긴 tool trajectory를 포함한 성공당 비용을 씁니다.

Model routing과 fallback은 base provider가 안정된 뒤 추가합니다. 주 model이 rate limit일 때 fallback이 필요한지, 더 싼 model로 분류만 하고 어려운 작업만 상위 model로 보낼지 각각 별도 실험입니다. route를 추가한 뒤에는 다음을 확인합니다.

  • 실제 사용 model이 trace에 남는가
  • fallback에서 tool-call contract가 같은가
  • context window가 충분한가
  • 비용 상한을 넘으면 fail-closed 하는가
  • provider 장애가 권한 확대를 유발하지 않는가

7. 다섯 번째 최적화: Cron은 안정된 Skill을 호출한다

평가셋에서 충분히 안정된 astro-frontmatter-audit만 schedule합니다.

hermes cron create "every 1d at 09:00" \
  "최근 게시 예정 글 3개를 점검하고 위반이 있을 때만 요약해줘" \
  --skill astro-frontmatter-audit \
  --workdir /srv/hermes-workspaces/blog \
  --name "blog-frontmatter-audit"

Cron 문서에 따르면 workdir을 지정해야 그 project의 context file이 load되고 file·terminal tool도 그 directory에서 실행됩니다. 상대 경로나 존재하지 않는 path는 거부됩니다.

운영 기본값:

approvals:
  cron_mode: deny

사람이 없는 scheduled run에서 위험 command 승인창이 나오면 자동 승인하는 대신 실패하게 둡니다. 정상일 때 알림이 필요 없다면 agent가 [SILENT]를 반환하도록 계약할 수 있고, LLM 판단이 전혀 필요 없는 disk threshold 같은 watchdog은 no-agent script mode로 token 사용을 없앨 수 있습니다.

상태와 history도 확인합니다.

hermes cron status
hermes cron list
hermes cron runs blog-frontmatter-audit --limit 20

Provider나 model을 바꾸면 기존 unattended job이 비용 높은 model을 조용히 상속하지 않는지 확인합니다. 현재 Hermes는 unpinned job이 global default 변경을 감지하면 실행을 건너뛰고 명시적 pin을 요구하는 fail-closed 동작을 문서화하고 있습니다.

8. 병렬화는 throughput 병목이 확인된 뒤 한다

Hermes는 profile, delegation, worktree, 여러 gateway를 지원합니다. 하지만 한 task의 품질이 불안정한데 agent를 네 개로 늘리면 실패도 네 갈래가 됩니다.

병렬화를 고려할 조건:

  • 단일 agent의 task success가 기준을 넘음
  • 독립 작업의 queue가 실제로 쌓임
  • 각 task가 다른 workspace 또는 worktree로 격리됨
  • 결과 merge owner가 명확함
  • provider rate limit과 VPS CPU/RAM budget이 있음
  • child trajectory와 최종 결과가 추적됨

같은 Git working tree에서 여러 coding agent가 동시에 수정하지 않게 Hermes Git Worktrees 구조를 사용합니다.

9. 주간 최적화 Loop

월요일  실패 trajectory 5개 분류
화요일  가장 큰 한 원인만 수정
수요일  고정 10-case 평가 재실행
목요일  실제 workload shadow run
금요일  Memory·Skill diff 검토와 release note

원인 taxonomy:

scope       입력 범위가 모호함
context     project 규칙을 못 찾음
tool        잘못된 tool 선택·권한 부족
model       추론·tool call 품질 부족
runtime     timeout·resource·provider 장애
verify      완료 판정이 약함
delivery    결과는 만들었지만 사용자에게 전달되지 않음

Prompt를 길게 만드는 것으로 모든 원인을 해결하지 않습니다. timeout은 runtime, 범위 밖 write는 permission, 오래된 절차는 Skill version 문제입니다.

10. 완료 기준

최적화가 끝났다고 말하려면 최소한 다음을 기록합니다.

release: astro-frontmatter-audit-v1.2
evaluation:
  suite: blog-frontmatter-audit-v1
  task_success: 0.90
  false_positive: 0.00
  human_correction_rate: 0.10
operations:
  p95_seconds: measured
  cost_per_success: measured
  unauthorized_tool_calls: 0
  cron_delivery_failures_7d: 0
rollback:
  previous_skill: v1.1
  config_backup: recorded-path

숫자는 예시 목표가 아니라 직접 측정할 필드입니다. 실제 값과 평가 일자를 넣습니다.

마무리

Hermes가 “나와 함께 성장한다”는 말은 Memory와 Skill을 많이 쌓는다는 뜻이 아닙니다. 항상 필요한 사실은 짧게 유지하고, 반복 절차는 필요할 때만 load하며, 잘못 학습한 변경을 되돌릴 수 있는 상태에 가깝습니다.

최적화 순서를 다시 압축하면 다음과 같습니다.

평가셋 고정
→ Tool 최소화
→ Context·Memory 정리
→ 반복 절차 Skill화
→ Model 비교
→ Cron 승격
→ 필요할 때만 병렬화

다음 글부터는 OpenClaw를 같은 기준으로 살펴봅니다. Hermes와 겉모습은 비슷하지만, OpenClaw는 Gateway·channel routing·agent workspace가 사용 경험의 중심에 더 가깝습니다.

참고 자료