[프로젝트] OpenClaw 컴포넌트 적용기: Skill·Tool·Hook·Session

이 글은 2026년 3–7월 진행한 서버형 Bixby 에이전트 PoC에서 확인한 설계 판단을 공개 가능한 수준으로 일반화한 기록이다. 내부 시스템명, endpoint, 인증 정보와 비공개 protocol은 제외했다. OpenClaw 자체의 현재 구조는 아키텍처 리서치 글에서 먼저 정리했다.

PoC의 질문은 단순했다.

디바이스 assistant가 가진 여러 기능을 서버형 LLM agent에서 호출하면서도, capability 선택·도구 실행·후속 대화와 예약 실행을 하나의 흐름으로 연결할 수 있을까?

구현하면서 확인한 답은 “가능하지만 모든 것을 하나의 prompt나 하나의 tool에 넣어서는 안 된다”였다. OpenClaw의 Skill, Tool, Hook, Session과 Automation을 각자 맞는 경계에 배치해야 했다.

적용한 컴포넌트 한눈에 보기

해결할 문제 사용한 OpenClaw 구성요소 PoC에서 맡긴 책임
기능별 capability와 제약 설명 Workspace + Skill Agent 선택 기준, query 작성 규칙, positive/negative scope
외부 기능 실행 Custom Tool Plugin typed input, 요청 전송, 응답을 model-visible event로 변환
공통 보정과 관측 Plugin Hook 예약 tool metadata 보정, tool latency·결과 logging
대화 연속성 Session context 사용자·서비스·conversation routing, 후속 turn 연결
확인·선택 후속 대화 Tool schema + 이전 turn reference 이전 실행을 이어가는 명시적 reference 전달
예약·조건부 실행 Cron/Automation 실행 시점, session target과 결과 delivery 연결
서버 실행 Gateway + Docker Compose 장시간 실행되는 runtime과 workspace/Skill mount
사용자 요청
  → Gateway / Session
  → Agent가 관련 Skill 확인
  → target Agent와 실행 query 결정
  → custom Tool 호출
  → 외부 기능 실행
  → event filtering / normalization
  → model이 결과 또는 후속 질문 생성

1. 하나의 Tool과 여러 Skill을 조합했다

처음 고민은 기능마다 tool을 따로 노출할지, 하나의 integration tool 뒤에서 target capability를 선택할지였다.

PoC에서는 하나의 custom tool에 자연어 query와 optional target Agent를 전달하고, 각 Agent의 capability 정의는 Skill로 분리했다. 예를 들어 검색, 메시지, 일정과 디바이스 제어는 같은 실행 입구를 사용하지만 서로 다른 Skill이 범위와 query 작성 규칙을 제공했다.

이 선택의 장점은 다음과 같았다.

  • model에 노출하는 tool schema 수를 제한할 수 있다.
  • 외부 기능 서비스와의 연결·인증·응답 처리를 한곳에 모을 수 있다.
  • capability 변화는 Skill 정의를 교체해 빠르게 반영할 수 있다.

반면 단점도 분명했다.

  • 하나의 tool 이름만으로는 실제 action 종류가 잘 드러나지 않는다.
  • routing 정확도가 Skill retrieval과 prompt adherence에 의존한다.
  • target Agent와 query가 논리적으로 맞는지 별도 검증이 필요하다.

따라서 이 구조에서 Skill은 참고 문서가 아니라 tool call 전의 capability contract였다. Agent가 임의로 target을 먼저 고른 뒤 정당화하지 않도록, 관련 Skill을 읽고 scope를 확인한 다음 query를 재작성하는 순서를 workspace instruction에 넣었다.

현재 OpenClaw 문서도 Tool은 typed action, Skill은 기존 capability를 사용하는 instruction이라고 구분한다. (Tools, Skills, Plugins 구분, Skills)

2. Custom Tool은 외부 응답을 그대로 반환하지 않았다

외부 실행 결과는 여러 event가 줄 단위로 섞여 들어왔다. 이를 그대로 model에게 넘기면 다음 문제가 생긴다.

  • 중간 진행 event와 최종 결과의 경계가 흐려진다.
  • 큰 URL이나 image payload가 context와 log를 불필요하게 차지한다.
  • 일부 malformed event가 전체 응답 parsing을 실패시킬 수 있다.
  • model이 필요로 하지 않는 field까지 prompt surface에 노출된다.

그래서 Tool boundary에서 allowlist 기반 event filtering과 type별 mapping을 수행했다. 입력·출력 event는 필요한 field만 남겼고, URL과 image data는 placeholder로 바꿨다. 한 event가 깨져도 나머지 결과는 유지하도록 line 단위 parsing 실패를 격리하고, 누락된 event 수를 warning으로 남겼다.

이 경험에서 얻은 원칙은 다음과 같다.

Tool output은 backend response dump가 아니라 model이 다음 판단을 내리기 위한 최소 계약이어야 한다.

이는 보안뿐 아니라 agent 품질 문제다. Context에 불필요한 payload가 많아질수록 중요한 function result와 사용자 확인 prompt가 묻힌다.

3. Plugin Hook은 횡단 관심사에 사용했다

Tool 구현 안에 모든 정책을 넣으면 다른 tool과 공통으로 적용할 수 없다. PoC에서는 typed plugin hook을 두 용도로 사용했다.

Tool 실행 전: 예약 작업에 실행 문맥 보강

예약 tool이 호출될 때 현재 agent와 session 정보를 job metadata에 연결하고, 결과를 돌려보낼 delivery target을 구성했다. Model이 이 운영 정보를 매번 정확히 작성하기를 기대하지 않고 before_tool_call 경계에서 deterministic하게 보정했다.

Tool 실행 후: 공통 관측 정보 기록

after_tool_call에서 tool 이름, latency, parameter와 결과 summary를 기록했다. 로그 폭증을 막기 위해 문자열 길이를 제한하고, 오류는 정상 결과와 구분했다.

Plugin hooks 공식 문서before_tool_callafter_tool_call을 포함해 agent·tool·message lifecycle을 관찰하거나 변경하는 typed handler를 제공한다. 여기서 중요한 것은 Hook과 durable event processing을 혼동하지 않는 것이다. Callback logging은 가능하지만, 반드시 한 번 처리되어야 하는 business event라면 별도 queue와 persistence가 필요하다.

4. Session context와 business turn reference를 분리했다

멀티턴에는 서로 다른 두 연속성이 있었다.

  1. Agent session continuity: 어느 사용자·서비스·conversation의 history를 이어갈 것인가?
  2. 외부 실행 continuity: 직전 실행의 확인 질문이나 값 선택에 답하는 것인가?

첫 번째는 OpenClaw session context에서 routing identity를 읽어 요청에 연결했다. 두 번째는 Tool schema에 optional reference field를 두고, 이전 결과의 request reference를 다음 호출에 명시적으로 전달했다.

예를 들어 첫 실행이 “이 항목으로 진행할까요?” 또는 “여러 후보 중 무엇을 선택할까요?”를 반환하면, 다음 사용자 답변을 새 요청으로 보내지 않고 이전 turn을 가리키게 했다. 동시에 model이 사용자가 말하지 않은 “예”, “전송” 같은 확인을 임의로 만들어내지 않도록 Tool description과 workspace rule에 제한을 넣었다.

이 분리가 중요한 이유는 chat history만으로는 외부 workflow의 continuation을 보장할 수 없기 때문이다. Session은 대화 문맥을 유지하지만, 외부 시스템이 요구하는 turn identifier까지 자동으로 추론해 주지는 않는다.

Session management도 session을 단순 transcript가 아니라 inbound source, isolation과 background routing을 결정하는 경계로 다룬다.

5. 조건부 요청은 Automation과 상태를 함께 설계했다

“비가 오면 알려줘”처럼 조건이 있는 요청은 한 번의 예약 실행으로 끝나지 않는다. 일정 간격으로 조건을 확인하고, 직전 상태와 비교하며, 조건이 만족됐을 때만 전달해야 한다.

PoC에서는 Cron job이 현재 session과 delivery 정보를 유지하도록 hook에서 metadata를 보강하고, workspace 상태 파일에 직전 실행 결과를 기록하는 규칙을 실험했다.

여기서 구분해야 할 것은 다음 두 책임이다.

  • Scheduler: 언제 깨울지, 실패·timeout과 delivery를 어떻게 기록할지
  • Agent: 깨어난 뒤 무엇을 확인하고 어떤 tool을 호출할지

현재 OpenClaw Automations 문서는 scheduler가 Gateway 안에서 job과 run history를 보존한다고 설명한다. PoC 당시의 파일 기반 상태는 빠른 실험에는 유효했지만, production이라면 job state의 source of truth와 idempotency를 더 명확히 분리해야 한다.

6. Workspace와 Skill을 container에 주입했다

OpenClaw runtime은 Docker Compose로 실행하고 workspace와 Skill 디렉터리를 container에 mount했다. 후속 서버 구성에서는 Skill·tool·subagent 정의 디렉터리를 read-only volume으로 주입해 runtime과 definition 배포를 분리했다.

이 방식은 image를 매번 다시 만들지 않고 definition을 교체할 수 있다는 장점이 있다. Read-only mount를 적용하면 runtime이 배포된 정의를 임의로 수정하지 못하게 할 수도 있다. 하지만 host mount는 deployment artifact의 version을 자동으로 설명해 주지 않는다.

재현성을 높이려면 다음 정보가 함께 남아야 한다.

  • container image version
  • workspace/Skill bundle revision
  • OpenClaw config revision
  • model/provider 설정
  • 실행한 test case와 결과 artifact

Skill은 코드보다 쉽게 바뀌기 때문에 오히려 versioning이 더 중요하다.

7. PoC에서 확인한 한계

Prompt 기반 routing은 hard guarantee가 아니다

Skill을 먼저 읽으라는 instruction을 줘도 model이 항상 같은 경로를 따르지는 않는다. Capability 선택은 tool call, read trajectory와 최종 function result를 함께 평가해야 했다.

단일 integration tool은 관측 단위를 흐릴 수 있다

Tool 이름은 하나인데 내부 target과 function은 많다. Metric을 tool name만으로 집계하면 어떤 capability가 실패했는지 보이지 않는다. Target Agent, function event와 session을 구조화된 field로 남겨야 한다.

응답 filtering은 품질과 정보 손실의 trade-off다

Noise를 줄이면 model 판단이 쉬워지지만, 지나치게 aggressive한 filter는 selection이나 error recovery에 필요한 event까지 제거한다. 실제로 selection 관련 output을 제외했다가 후속 처리가 깨져 다시 포함하는 조정이 필요했다.

PoC deployment와 production hardening은 다르다

Docker로 실행된다는 사실만으로 production-ready가 되지는 않는다. Multi-tenant session isolation, secret management, retry와 idempotency, timeout, audit log, rate limit과 rollback이 별도 과제로 남는다.

현재 API와 PoC 시점 API는 다르다

PoC는 2026년 3–7월 당시의 extension API와 manifest 형식을 사용했다. 현재 Plugin 개발 문서는 package metadata, capability contract와 compatibility version을 더 명시적으로 요구한다.

따라서 이 글은 현재 버전에 그대로 복사할 code recipe가 아니다. Skill, Tool, Hook과 Session을 어떤 책임 경계로 사용했는지 설명하는 design record에 가깝다. 실제 구현을 시작할 때는 현재 manifest와 Plugin SDK 문서를 기준으로 다시 맞춰야 한다.

지금 다시 설계한다면

OpenClaw의 현재 문서와 PoC 경험을 함께 놓고 보면 다음 순서로 설계할 것이다.

  1. Capability마다 Tool, Skill, Plugin 중 어느 경계가 맞는지 먼저 분류한다.
  2. 외부 action은 좁은 typed schema와 최소 output contract로 만든다.
  3. Routing rule은 Skill로 두되 trajectory evaluation으로 실제 준수 여부를 측정한다.
  4. Tool policy에서 불필요한 capability를 제거하고 prompt instruction과 권한 제어를 분리한다.
  5. Session identity와 외부 workflow reference를 별도 field로 모델링한다.
  6. Hook은 보정·관측에 사용하고 durable processing은 queue로 분리한다.
  7. Image, Skill, config와 model revision을 하나의 실행 artifact에 기록한다.

OpenClaw를 적용하면서 가장 유용했던 점은 완성된 agent를 바로 얻었다는 사실이 아니다. 판단은 Skill, 행동은 Tool, runtime 개입은 Hook, 연속성은 Session이라는 경계가 이미 존재해 실험의 책임을 나눌 수 있었다는 점이었다.

관련 글: OpenClaw 아키텍처 리서치 · 재현 가능한 LLM 에이전트 평가 파이프라인

참고 자료

Categories:

Updated: