목차
Openclaw
OpenClaw는 LLM(거대 언어 모델)을 기반으로, 개인 서버와 일상을 자동화하고 관리하도록 설계된 오픈소스 AI 에이전트 게이트웨이임.
OpenClaw는 단순히 챗봇이 아니라, 당신의 서버 환경과 물리적 장치(Node)에 직접 접근하여 명령을 실행하는 '실행 엔진' 역할을 수행함.
주요 특징 및 능력
- 멀티 채널 게이트웨이: 텔레그램, WhatsApp, Discord, iMessage 등 다양한 메신저 플랫폼을 통해 AI 비서와 소통할 수 있다. (현재 당신은 텔레그램으로 소통 중임.)
- 실제 서버 관리:
- 파일 시스템 제어: 파일 읽기, 쓰기, 편집, 폴더 관리.
- Shell 명령어 실행 (exec): uptime, ls, apt install 등 서버의 모든 CLI 명령을 AI가 직접 실행함.
- Cron 자동화: 정기적인 알림, 서버 상태 점검, 자동 백업 등을 예약함.
- 하이브리드 모델 지원: Google Gemini, OpenAI, 그리고 로컬 Ollama 모델을 필요에 따라 전환하며 사용하여 효율성과 개인 정보 보호를 극대화함.
- Node 연동: ESP32, iOS/Android 기기 등을 Node로 연결하여 물리적 세계와 소통함. (예: ESP32 OLED 표시기, 스마트폰 카메라 제어)
- 웹 자동화: 웹 검색, URL 추출, 스크린샷 캡처 등 웹상의 정보를 실시간으로 수집하고 분석함.
OpenClaw의 작동 원리
OpenClaw는 Gateway라는 중앙 프로세스를 통해 작동함.
- 메신저 → Gateway → AI 에이전트(LLM)
- AI 에이전트는 요청을 분석한 후, Tool을 사용하여 Gateway에게 실행을 지시함.
- (예: "날씨 알려줘" → weather 스킬 사용)
- Gateway는 결과를 다시 메신저로 보내 사용자에게 전달함.
시작하기
- 설치 환경: 리눅스(Proxmox 컨테이너, 라즈베리파이 등), macOS (맥 미니)
- 설치 방법: Node.js 22 이상 환경에서
npm install -g openclaw@latest명령어를 통해 설치하고openclaw onboard마법사로 설정함. - 소스 코드: GitHub - openclaw/openclaw (https://github.com/openclaw/openclaw)
오픈클로(OpenClaw) 설치부터 제미나이(Gemini) 무료 연동까지 완벽 가이드(feat. 구 클로드봇(Clawdbot) 설치 가이드)
대화창
명령어
| 명령어 | 용도 및 설명 |
|---|---|
| /status | 현재 세션의 상태, 사용 중인 모델, 토큰 사용량, 런타임 정보 등을 보여줘. |
| /model <name> | 현재 세션에서 사용할 모델을 지정해. (예: /model gemini-flash-latest) |
| /default-model <name> | 모든 새 세션의 기본 모델을 지정해. |
| /new | 현재 세션을 종료하고 새로운 세션을 시작해. (이전 컨텍스트 초기화) |
| /reset | /new와 비슷하게 세션을 초기화하고 새로 시작해. |
| /tools | 사용 가능한 모든 도구 목록을 보여줘. |
| /reasoning | 내 '생각하기' 모드를 켜거나 꺼. (켜면 내가 어떻게 추론하는지 볼 수 있어) |
| /thinking | /reasoning과 같은 기능이야. |
| /verbose | 상세 모드를 켜거나 꺼. (도구 출력 등을 더 자세히 보여줄 수 있어) |
| /history | 최근 대화 기록을 보여줘. |
| /profile <name> | 브라우저 도구에서 사용할 프로필을 지정해. (예: /profile chrome 또는 /profile openclaw) |
| /memory | MEMORY.md 파일 내용을 보여줘. |
openclaw gateway status openclaw gateway status --deep openclaw gateway status --json openclaw gateway install openclaw gateway restart openclaw gateway stop openclaw logs --follow openclaw doctor
구성
처음 도입할 때, 에이전트에게 원하는 모든 기능을 아주 자세하게 설명해 주세요.
| 분야 | 유료클라우드 | 무료로컬 | |
|---|---|---|---|
| 💻코딩 | DeepSeek Coder v2 ( 월 20달러) | ||
| 🎙️ 음성 인식 | OpenAI Whisper (한달에 약 3달러) | ||
| 🖼️ 이미지 생성 | Gemini / Nano Banana Pro (달에 약 10달러 ) | x/z-image-turbo | |
| 🖼️ 이미지 인식 | 거의 모든 유료 클라우드 모델 | llava | |
| 🧾 구조화된 장기 기억 | (무료) Supermemory.ai | ||
| 🌐 웹 검색 및 브라우징 | Brave / Tavily | Brave는 일반 검색에 적합하고, Tavily는 연락처 정보 추출 등 특정 용도. | |
| 이메일 | Nylas 이 서비스는 무료 | ||
- Groq – Fastest, 1K req/day on Llama 3.3 70B, great for bots
- • Mistral – 1 billion tokens/month free, but 1 req/sec limit
- • OpenRouter – 50 req/day (used to be 200), good for testing multiple models
- • Gemini Flash – Best for long documents (1M context window)
memory.md 예
- memory-YYYY-MM-DD.md = 단기 캐시이다.
- 7일 넘기지 말 것
- 반복·판단·위험 → memory.md로 병합
- memory.md는 500 tokens가 생존 한계 (30줄 × 15 tokens ≈ 450 tokens 추천)
- 설명은 죄, 규칙만 허용
# Identity - 로컬 실행 환경을 우선하는 OpenClaw 에이전트 # Priority - 비용 최소화 > 편의성 > 상세 설명 # Cost Policy - 로컬 모델 우선 - 클라우드 사용 시 사전 비용 명시 - 토큰 증가 선택지는 대안을 먼저 제시 # Output Rules - 코드 요청 시 전체 코드 우선 제공 - 불필요한 설명 금지 # Web Policy - 6개월 이상 최신성 요구 시 웹 검색 필수
cron/jobs.json
작동하는 cron 예제.
- jobs.json
{ "version": 1, "jobs": [ { "id": "d6206e6c-8544-4324-9062-435ba835864e", "name": "아침 날씨 알림", "enabled": true, "createdAtMs": 1771753627753, "updatedAtMs": 1771974387969, "schedule": { "expr": "1 8 * * *", "kind": "cron", "tz": "Asia/Seoul" }, "sessionTarget": "isolated", "wakeMode": "now", "payload": { "kind": "agentTurn", "text": "Generate today's briefing: today's weather comparing yesterday's, use weather skill" }, "delivery": { "mode": "announce", "channel": "heartbeat", "to": "6913272833" }, "state": { "nextRunAtMs": 1772060460000, "lastRunAtMs": 1771974300009, "lastStatus": "ok", "lastDurationMs": 87960, "consecutiveErrors": 0, "lastRunStatus": "ok", "lastDeliveryStatus": "delivered", "lastDelivered": true } } ] }
Heartbeat.md 예제
# 💓 HEARTBEAT CHECKLIST CONTRACT: Reply HEARTBEAT_OK if nothing needs attention. Gateway silently drops OK-only replies. Only message the user if action is needed. --- ## 1. 🧠 Memory Maintenance - Check memory/ folder for .md files older than 3 days - If any daily log has actionable items not yet in MEMORY.md: - Extract: decisions, preferences, project states, learned facts - Merge into the correct section of MEMORY.md - After merge, mark the daily log as [MERGED] at the top - Skip entries that are just routine conversation (no lasting value) ## 2. 📋 Pending Tasks - Scan MEMORY.md for any items tagged #todo or #pending - If overdue → notify user - If blocked → note what's missing in MEMORY.md ## 3. 🤖 Subagent Status - Check if any subagents are currently active - Do NOT interrupt active subagents - If a subagent has been silent > 30min, flag it ## 4. 🔔 Proactive Actions - Only attempt if no active subagents are running - Examples: scheduled summaries, reminders, monitoring tasks ## 5. ✅ FINAL STEP (always last) - If nothing above requires user attention → reply HEARTBEAT_OK - Never send HEARTBEAT_OK before completing steps 1-4
cron
# 매일 오전 7시 브리핑 (isolated 세션) openclaw cron add \ --name "Morning brief" \ --cron "0 7 * * *" \ --tz "Asia/Seoul" \ --session isolated \ --message "오늘 브리핑: 날씨, 캘린더, 이메일 요약" \ --announce # 20분 후 one-shot 리마인더 openclaw cron add \ --name "Meeting reminder" \ --at "20m" \ --session main \ --system-event "회의 시작 10분 전입니다." \ --wake now \ --delete-after-run openclaw cron add \ --name "Morning briefing" \ --cron "0 7 * * *" \ --tz "America/New_York" \ --session isolated \ --message "Generate today's briefing: weather, calendar, top emails, news summary." \ --model opus \ --announce \ --channel whatsapp \ --to "+15551234567" openclaw cron add \ --name "Morning briefing" \ --cron "0 8 * * *" \ --tz "Asia/Seoul" \ --session isolated \ --message "Generate today's briefing: today's weather comparing yesterday's, web_fetch https://news.naver.com" \ --model macmini \ --announce \ --channel telegram
보안
Tailscale을 Clawdbot이 설치된 컴퓨터와 메인 컴퓨터에 설치하세요. 앞서 언급했듯이 저는 Windows를 사용하고 있는데(놀랍죠!), Tailscale을 통해 원격 데스크톱을 사용할 수 있고, Tailscale이 설치된 다른 컴퓨터의 웹 인터페이스를 통해 Clawdbot을 제어할 수도 있습니다. 또한, 서버에서 원격 데스크톱용 RDP 포트를 열 필요가 없으므로 보안 측면에서 유리합니다.
openclaw security audit –deep
chmod 700 ~/.openclaw chmod 600 ~/.openclaw/openclaw.json chmod 700 ~/.openclaw/credentials
설정
openclaw.json example
컨텍스트 자동 압축 설정해주는 것이 좋다. 1M이라고 주장하는 제미나이도 너무 길어지면 오류난다. 150k~200K 이하가 적당함.
{
"meta": {
"comment": "Sanitized OpenClaw config example - replace placeholders with your values"
},
"agents": {
"defaults": {
"model": {
"comment": "Primary model + fallback chain. Keeps expensive models out of default path.",
"primary": "anthropic/claude-sonnet-4-5",
"fallbacks": [
"kimi-coding/k2p5",
"synthetic/hf:zai-org/GLM-4.7",
"openrouter/openai/gpt-5-mini",
"openrouter/openai/gpt-5-nano",
"openrouter/google/gemini-3-flash-preview",
"openrouter/google/gemini-2.5-flash-lite"
]
},
"models": {
"comment": "Model aliases for easier referencing",
"anthropic/claude-haiku-4-5": {
"alias": "haiku"
},
"anthropic/claude-sonnet-4-5": {
"alias": "sonnet"
}
},
"workspace": "/path/to/your/.openclaw/workspace",
"memorySearch": {
"comment": "Cheap embeddings for memory recall",
"sources": ["memory", "sessions"],
"experimental": {
"sessionMemory": true
},
"provider": "openai",
"model": "text-embedding-3-small"
},
"contextPruning": {
"comment": "Automatically prune old context, keep cache valid for 6h",
"mode": "cache-ttl",
"ttl": "6h",
"keepLastAssistants": 3
},
"compaction": {
"comment": "Memory flush settings - distill sessions to daily memory files",
"mode": "default",
"memoryFlush": {
"enabled": true,
"softThresholdTokens": 40000,
"prompt": "Extract key decisions, state changes, lessons, blockers to memory/YYYY-MM-DD.md. Format: ## [HH:MM] Topic. Skip routine work. NO_FLUSH if nothing important.",
"systemPrompt": "Compacting session context. Extract only what's worth remembering. No fluff."
}
},
"heartbeat": {
"comment": "Use cheapest model for background heartbeat checks",
"model": "openrouter/openai/gpt-5-nano"
},
"maxConcurrent": 4,
"subagents": {
"maxConcurrent": 8
}
},
"list": [
{
"id": "main",
"default": true
}
]
},
"logging": {
"comment": "Redact sensitive data from tool output in logs",
"redactSensitive": "tools"
},
"tools": {
"web": {
"search": {
"enabled": true,
"apiKey": "YOUR_BRAVE_SEARCH_API_KEY"
},
"fetch": {
"enabled": true
}
}
},
"messages": {
"ackReactionScope": "group-mentions",
"tts": {
"auto": "inbound",
"provider": "edge",
"edge": {
"enabled": true,
"voice": "en-GB-RyanNeural"
}
}
},
"channels": {
"telegram": {
"enabled": true,
"dmPolicy": "pairing",
"botToken": "YOUR_TELEGRAM_BOT_TOKEN",
"groupPolicy": "allowlist",
"streamMode": "partial"
},
"discord": {
"enabled": true,
"token": "YOUR_DISCORD_BOT_TOKEN",
"groupPolicy": "allowlist",
"dm": {
"enabled": true,
"policy": "allowlist",
"allowFrom": ["YOUR_DISCORD_USER_ID"]
},
"guilds": {
"YOUR_DISCORD_GUILD_ID": {
"requireMention": false,
"users": ["YOUR_DISCORD_USER_ID"],
"channels": {
"*": {
"allow": true
}
}
}
}
}
},
"gateway": {
"comment": "SECURITY: Bind to loopback (localhost) only, not 0.0.0.0",
"port": 18789,
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token",
"token": "YOUR_GATEWAY_AUTH_TOKEN",
"allowTailscale": true
},
"tailscale": {
"mode": "serve",
"resetOnExit": true
}
},
"models": {
"comment": "Example: Add Synthetic provider for free GLM/Kimi models",
"mode": "merge",
"providers": {
"synthetic": {
"baseUrl": "https://api.synthetic.new/anthropic",
"api": "anthropic-messages",
"models": [
{
"id": "hf:zai-org/GLM-4.7",
"name": "GLM-4.7",
"reasoning": false,
"input": ["text"],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 198000,
"maxTokens": 128000
},
{
"id": "hf:moonshotai/Kimi-K2.5",
"name": "Kimi K2.5",
"reasoning": true,
"input": ["text"],
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"contextWindow": 256000,
"maxTokens": 8192
}
]
}
}
},
"auth": {
"comment": "API auth profiles - tokens stored in ~/.openclaw/credentials/",
"profiles": {
"kimi-coding:default": {
"provider": "kimi-coding",
"mode": "api_key"
},
"openrouter:default": {
"provider": "openrouter",
"mode": "api_key"
},
"synthetic:default": {
"provider": "synthetic",
"mode": "api_key"
},
"anthropic:default": {
"provider": "anthropic",
"mode": "token"
}
}
}
}