Field Log · Entry
OpenClaw 구축 후 최적화: 20봇을 1 workflow로 줄인 기록 (6/7)
이번 글의 결론
- 저는 약 20개 bot을 먼저 만들었지만, 안정된 workflow는 하나도 없었습니다.
- 병목은 model이 아니라 scope·context·tool·state·verification이 bot마다 달랐던 데 있었습니다.
- OpenClaw의 Skill은 같은 출력을 보장하는 program이 아니라 절차와 검증을 반복 가능하게 만드는 지침입니다.
- 최적화는 bot을 늘리는 일이 아니라 한 workflow의 성공률·사람 교정·비용·지연·권한 위반을 측정하는 일에서 시작했습니다.
- Multi-agent는 역할 이름을 늘리는 기능이 아니라 agent별 workspace·auth·session·sandbox와 merge 책임을 분리하는 운영 설계입니다.
앞 글에서는 Docker Gateway와 Slack Socket Mode를 한 agent에 연결했습니다. 이번 글은 제가 그 원칙을 거꾸로 배웠던 기록입니다.
이 글은 2026년 5월의 실험을 바탕으로 썼고, 2026년 7월 21일 OpenClaw 2026.7.1 문서 기준으로 구조 설명을 고쳤습니다. 당시 config 손상 경험을 현재 version에서도 그대로 재현되는 제품 결함처럼 일반화하지 않습니다.
1. 처음에는 Slack에 팀을 만들고 싶었다
제가 원한 장면은 단순했습니다.
Slack에서 @commander에게 요청
→ backend bot 구현
→ frontend bot 화면 작업
→ QA bot 검증
→ commander가 결과를 합쳐 보고
iCME(영어 학습), 360me(MBTI 인식차), calculate_math(커리큘럼 viewer), coin(트레이딩 report) 네 project에 commander·backend·frontend·QA·design·research 역할을 붙였습니다. 숫자는 금방 약 20개가 됐습니다.
Slack sidebar에서 여러 thread가 동시에 움직이는 모습은 강력했습니다. 하지만 한 주가 지나자 “활동 중인 bot이 많은가?”와 “완료된 일이 많은가?”가 전혀 다른 지표라는 사실이 드러났습니다.
2. 현재 OpenClaw를 정확히 정의한다
당시 저는 OpenClaw를 “Slack에서 여러 Claude Code를 호출하는 orchestrator”처럼 이해했습니다. 현재 Agent runtime 문서는 더 정확한 구조를 보여 줍니다.
OpenClaw Gateway
channel · auth · routing · session · delivery
Embedded Agent runtime
model · prompt · tool loop
Per-agent state
workspace · auth profile · session store
Optional external harness
Claude Code · Codex · OpenCode 등과 연결 가능
즉, 외부 coding harness는 선택 가능한 실행 방식이지 OpenClaw의 정의가 아닙니다. 이 차이를 모르고 “role bot 이름만 만들면 각자 개발자가 된다”고 생각한 것이 첫 번째 착각이었습니다.
3. 실제로 무너진 세 자리
3.1 Config 변경이 잦고 복구 기준이 없었다
2026년 5월 실험 폴더에는 openclaw.json.clobbered.* backup이 19개 남았고, 가장 심한 날에는 하루 5개가 생겼습니다. bot·binding·workspace를 계속 추가하면서 누가 어느 기준 version을 편집하는지 통제하지 않았습니다.
문제는 backup 개수만이 아니었습니다.
- 변경 전
doctor또는 schema validation을 하지 않음 - config diff review 없음
- last-known-good version 없음
- 여러 session에서 동시에 routing을 수정
- 복구 후 Slack route smoke test 없음
현재 OpenClaw에는 openclaw config patch --dry-run, read-only openclaw doctor --lint, Gateway를 통한 state writer 등 당시보다 안전한 경로가 있습니다. 그래도 운영 config를 version·review·smoke test 없이 바꾸면 같은 종류의 혼란은 남습니다.
3.2 Bot 사이에 작업 맥락이 흐르지 않았다
개발 bot이 만든 code를 QA bot이 자동으로 이해할 것이라 생각했습니다. 그러나 서로 다른 agent는 각각 workspace와 session을 가질 수 있습니다. 공유 artifact와 handoff contract가 없으면 다음이 전달되지 않습니다.
왜 이 방식을 골랐는가
어떤 test가 이미 실패했는가
어떤 파일을 의도적으로 건드리지 않았는가
완료를 무엇으로 판정하는가
사람 한 명의 머릿속에 있던 implicit context를 bot 수만큼 자동 복제할 수는 없습니다.
3.3 같은 요청이 매번 새 작업이 됐다
“주식 뉴스 정리해줘”라고만 쓰면 어떤 날은 표, 어떤 날은 긴 서술, 어떤 날은 출처 없는 요약이 나왔습니다. 입력 source, 시간 범위, 중복 제거, section, citation, 실패 조건을 정하지 않았기 때문입니다.
LLM이 비결정적이라는 사실보다 더 큰 문제는 제가 task contract를 쓰지 않았다는 것이었습니다.
4. 원인을 다섯 축으로 다시 분류했다
| 축 | 당시 상태 | 결과 |
|---|---|---|
| Scope | 한 bot에 개발·QA·research 혼합 | 완료 기준이 계속 바뀜 |
| Context | 얇은 AGENTS.md, 비어 있는 handoff | bot마다 다른 가정 |
| Tool | broad shell·file 권한 | 불필요한 행동과 승인 증가 |
| State | Memory·artifact·session 책임 불명 | 다음 실행이 이전 결정을 못 찾음 |
| Verification | output format·test·review 없음 | “완료했다”는 말만 남음 |
처음에는 model을 바꾸거나 prompt를 더 길게 쓰려고 했습니다. 하지만 이 표에서 model은 첫 원인이 아니었습니다.
5. 전환: 한 project와 한 workflow만 남겼다
세 결정을 동시에 내렸습니다.
Project를 하나로 줄였다
iCME·360me·calculate_math automation을 잠시 내리고 coin report만 남겼습니다. 여러 domain을 동시에 안정화하면 실패 taxonomy가 섞입니다.
Agent를 하나로 줄였다
commander·research·writer·QA를 일단 하나의 agent session으로 합쳤습니다. 역할 분리의 이점보다 handoff 손실이 더 큰 단계였기 때문입니다.
Workflow를 하나로 줄였다
첫 대상은 “매일 아침 관심 종목 뉴스 brief”였습니다.
input:
tickers: fixed watchlist
window: previous 24 hours
sources: approved source list
process:
- collect
- canonicalize URL
- deduplicate event
- separate fact from interpretation
output:
- ticker
- event
- why_it_matters
- source_url
- published_at
failure:
- source unavailable => report gap
- timestamp unknown => exclude
- no material event => say none
“news를 잘 정리한다”가 아니라 입력·절차·출력·실패를 고정했습니다.
6. Skill은 출력을 결정하지 않고 절차를 고정한다
기존에는 Skill을 “같은 입력이면 같은 출력이 나오는 결정적 절차”라고 표현했습니다. 정확하지 않았습니다. SKILL.md도 결국 LLM이 읽는 instruction이므로 model·source·시간에 따라 결과는 달라질 수 있습니다.
더 정확한 설명은 이것입니다.
Skill은 반복 작업에서 어떤 순서로 무엇을 확인하고, 어떤 형식과 검증을 통과해야 하는지를 versioning하는 절차 계약이다.
진짜 deterministic해야 하는 단계는 code로 내립니다.
URL normalize code
timestamp parse code
duplicate hash code
schema validation code
event importance agent judgment
why it matters agent judgment
conflict summary agent judgment
OpenClaw Skill에는 둘의 경계를 적습니다.
---
name: daily-stock-brief
description: Build a cited 24-hour brief for the configured watchlist
---
# Daily Stock Brief
## Procedure
1. Read the configured watchlist.
2. Collect only approved sources from the previous 24 hours.
3. Run `{baseDir}/scripts/normalize.py` for URL and time normalization.
4. Group articles that describe the same event.
5. Write one row per event using the template.
## Stop conditions
- Do not infer a publication time.
- Do not invent an event when no approved source is available.
## Verification
- Every event has at least one source URL and timestamp.
- Facts and interpretation appear in separate fields.
- The output passes `{baseDir}/scripts/validate.py`.
이제 OpenClaw는 자유롭게 report 형식을 발명하는 bot이 아니라, 정해진 procedure와 validator를 호출하는 agent가 됩니다.
7. Memory와 artifact를 분리했다
MEMORY.md에 매일 뉴스와 긴 report를 넣지 않았습니다.
| Data | 위치 |
|---|---|
| watchlist와 사용자 선호 | USER.md 또는 config |
| source 신뢰 규칙 | AGENTS.md·Skill reference |
| 오늘 실행 log | memory/YYYY-MM-DD.md |
| 장기 교정 | MEMORY.md |
| raw article·중간 JSON | 날짜별 artifact directory |
| 최종 report | 별도 output directory·DB |
Memory는 database 대체물이 아닙니다. 매 run의 raw data는 artifact로 보존하고, “이 source는 timestamp가 local time이라 parser X를 쓴다”처럼 다음 task에 필요한 짧은 교정만 Memory 또는 Skill patch 후보로 올립니다.
현재 OpenClaw는 agent가 reusable work를 발견했을 때 Skill을 바로 덮어쓰지 않고 proposal로 보낼 수 있는 Skill Workshop도 제공합니다. 변경은 다음처럼 검토합니다.
openclaw skills workshop list
openclaw skills workshop inspect <proposal-id>
openclaw skills workshop apply <proposal-id>
8. “잘된다”를 숫자로 바꿨다
7일 동안 같은 workflow를 실행해 다음을 기록합니다.
task success
required field가 모두 있고 validator 통과
evidence coverage
source URL과 timestamp가 있는 event 비율
human correction
사람이 수정한 row·field 수
cost per accepted brief
재시도 포함 token/API 비용
latency
schedule 시작부터 Slack delivery까지
policy violations
범위 밖 tool call·blocked command·비허용 source
예시 release gate:
seven_day_gate:
accepted_briefs: 7/7
validator_pass: 100%
unsupported_event: 0
human_field_corrections: <= 2/day
unauthorized_tool_calls: 0
delivery_failures: 0
목표값은 업무 중요도에 맞게 정합니다. 핵심은 Slack message 수나 agent 활동량을 성과로 세지 않는 것입니다.
9. Cron은 validator를 통과한 workflow만 실행한다
OpenClaw에서 schedule할 때 main session과 isolated session을 구분하고, 결과 delivery target을 명시합니다. 정확한 command와 payload field는 빠르게 바뀌므로 Scheduled tasks 문서의 현재 예제를 기준으로 만듭니다.
운영 원칙:
schedule trigger
→ fresh or named session
→ one versioned Skill
→ deterministic normalizer
→ schema validator
→ failure alert or Slack delivery
→ task/run history
Agent reasoning이 필요 없는 health check는 LLM에 맡기지 않습니다. shell·monitoring system이 threshold를 판단하고 이상이 있을 때만 agent 또는 Slack을 깨웁니다.
10. Multi-agent는 언제 다시 붙이는가
한 agent의 queue에서 서로 독립적인 작업이 실제로 기다릴 때만 분리합니다.
예를 들어 수집과 editorial review가 동시에 오래 걸린다면 두 agent를 고려할 수 있습니다. 그때도 역할 이름보다 isolation contract를 먼저 씁니다.
collector:
workspace: workspace-collector
tools: [web, read, write-artifact]
cannot: [publish, message-user]
output: normalized-events.json
editor:
workspace: workspace-editor
tools: [read-artifact, write-report]
cannot: [web, shell, publish]
input: normalized-events.json
output: validated-brief.md
publisher:
trigger: validator-pass
tools: [message-send]
cannot: [web, shell, edit-artifact]
Multi-agent routing 문서에 따르면 각 agent는 별도 workspace, auth profile, session store를 가져야 하고 agentDir을 공유하면 안 됩니다. Workspace만 나눠도 hard sandbox는 생기지 않으므로 per-agent sandbox와 tool policy도 함께 설정합니다.
병렬화 checklist:
- 각 agent 입력과 산출물이 file/schema로 정의됨
- 같은 file을 동시에 쓰지 않음
- agent별 workspace와 state가 분리됨
- child output을 누가 검증·merge하는지 명확함
- 실패한 child를 전체 재실행하지 않아도 됨
- VPS CPU·RAM·provider rate limit budget이 있음
11. 운영 명령을 습관으로 만든다
openclaw status --deep
openclaw status --usage
openclaw health --verbose
openclaw channels status --probe
openclaw tasks audit
openclaw doctor --lint --all
openclaw logs --follow
특히 Health 문서가 설명하듯 session row가 있다는 사실은 channel socket이 살아 있다는 뜻이 아닙니다. channels status --probe와 deep health로 live connectivity를 확인합니다.
주간 review에서는 다음 네 log를 함께 봅니다.
agent trajectory
validator result
Gateway delivery/task history
사람 correction diff
최종 답변만 보면 어떤 tool 선택에서 실패가 시작됐는지 알 수 없습니다.
12. 제가 다시 시작한다면
첫 2주는 이렇게 씁니다.
1주차
Day 1 한 project·한 agent·읽기 전용 task
Day 2 입력/출력 schema와 validator
Day 3 Skill v0.1
Day 4 실패 fixture 10개
Day 5 permission·sandbox negative test
Day 6 shadow schedule
Day 7 사람 correction review
2주차
Day 8 가장 큰 실패 원인 하나 수정
Day 9 10-case regression
Day 10 real source variation test
Day 11 cost·latency budget
Day 12 delivery·restart test
Day 13 Skill v1.0 review
Day 14 production schedule
두 번째 agent는 이 14일을 통과한 뒤에도 독립 queue가 쌓일 때만 추가합니다.
FAQ
OpenClaw로 개발 자동화는 안 되는가
됩니다. OpenClaw는 내장 runtime과 외부 coding harness, worktree, sandbox, sub-agent를 지원합니다. 제가 개발·QA를 잠시 뺀 것은 당시 제 repository context와 test·review loop가 준비되지 않았기 때문입니다. 제품의 절대적 한계가 아니라 제 배포의 성숙도에 맞춘 scope 축소였습니다.
Bot은 몇 개가 적당한가
고정 숫자는 없습니다. 한 agent의 queue에 독립 작업이 쌓이고, 분리 후 handoff 비용보다 병렬 이익이 크다는 측정이 있을 때 하나 늘립니다. 그 전에는 1개가 적당합니다.
Skill을 쓰면 항상 같은 결과가 나오는가
아닙니다. Skill은 절차·도구·검증을 고정하지만 LLM 판단과 외부 data는 달라질 수 있습니다. 동일성이 필요한 단계는 script와 schema validator로 구현합니다.
대부분의 개인 작업은 coding CLI로 충분하지 않은가
대화형 coding만 한다면 그럴 수 있습니다. OpenClaw의 가치가 커지는 지점은 항상 켜진 Gateway, 여러 channel, schedule, delivery, agent별 routing이 필요할 때입니다. 도구 이름이 아니라 workload shape로 선택합니다.
마무리
제가 원했던 “딸깍”은 bot 수에서 나오지 않았습니다.
작은 scope
명시적 context
최소 tool
분리된 state
자동 validator
관측 가능한 run
이 여섯 가지가 준비된 한 workflow가, 준비되지 않은 20개 bot보다 훨씬 많은 일을 끝냈습니다.
마지막 글에서는 이 원리를 개인 agent에서 3,500명 규모 engineering 조직으로 확장합니다. Block은 repository·업무 도구·review·cloud workspace·company world model까지 바꿨지만, Stage 5 직후 자동화와 구조조정의 관계라는 더 어려운 질문을 마주했습니다.
참고 자료
Reader questions
읽으며 남긴 질문
글을 읽으며 붙잡아 둔 질문입니다. 다시 살펴보거나, 보내지 않은 질문을 한 번에 블로그 주인에게 전달할 수 있습니다.