41 KiB
Pewnie — poniżej masz dwie gotowe, “produkcyjne” wersje SKILL.md dopasowane pod OpenClaw runtime:
- LLM‑only (bez narzędzi)
- Tool‑first (narzędzia jako domyślny silnik, LLM tylko do planu/formatowania)
Dodatkowo dorzucam gating (load-time), slash-command, oraz przykładowe wpisy do ~/.openclaw/openclaw.json + rekomendowane polityki narzędzi (tools.profile/allow/deny). Wszystko zgodne z tym, jak OpenClaw ładuje i filtruje skille. [docs.openclaw.ai], [docs.openclaw.ai], [docs.openclaw.ai]
0) Kontekst OpenClaw (ważne, bo wpływa na projekt)
- Skill w OpenClaw to katalog z plikiem
SKILL.md(YAML frontmatter + instrukcje w Markdown). [docs.openclaw.ai], [docs.openclaw.ai] - Skille są ładowane m.in. z
<workspace>/skillsoraz~/.openclaw/skills; a gdy nazwy się pokrywają, workspace wygrywa nad lokalnym i bundlowanym. [docs.openclaw.ai] - OpenClaw potrafi filtrować skille przy ładowaniu na podstawie
metadata.openclaw.requires(np. wymagane binarki/env/config). [docs.openclaw.ai] - Frontmatter ma ograniczenia: parser wspiera jednolinijkowe klucze, a
metadatapowinno być jednolinijkowym JSON. [docs.openclaw.ai] - Dostępność i bezpieczeństwo narzędzi kontrolujesz w
openclaw.jsonprzeztools.profile,tools.allow,tools.denyi grupygroup:*. [docs.openclaw.ai]
1) Struktura katalogu (dla obu wariantów)
Minimalnie:
<workspace>/skills/my-custom-skill-llm-only/SKILL.md
<workspace>/skills/my-custom-skill-tool-first/SKILL.md
OpenClaw odkryje te katalogi i zindeksuje SKILL.md (po restarcie gateway albo “refresh skills”). [docs.openclaw.ai], [docs.openclaw.ai]
2) Wersja A — LLM‑only (zero narzędzi, maksymalna przewidywalność)
Kiedy to ma sens?
- gdy chcesz czystą logikę/pisanie/transformację tekstu
- gdy chcesz zero side‑effectów i brak ryzyka tool‑abuse
- gdy wolisz “prompt jako skill” + ustandaryzowany output
SKILL.md (LLM‑only)
---
name: my-custom-skill-llm-only
description: Deterministic LLM-only skill. No tools. Produces structured output for [topic].
user-invocable: true
disable-model-invocation: false
metadata: {"openclaw":{"emoji":"🧠","os":["darwin","linux","win32"],"always":true}}
---
# My Custom Skill (LLM-only)
## Purpose (single responsibility)
Zamień nieuporządkowaną prośbę użytkownika na **ustrukturyzowaną odpowiedź** dla: **[topic]**.
## Hard rules (MUST)
- **NIE używaj żadnych narzędzi** (read/write/exec/web_* / browser / nodes / cron).
- Jeśli brakuje danych: **zadaj maksymalnie 3 pytania doprecyzowujące**.
- Brak zgadywania faktów. Brak “dopowiadania” danych wejściowych.
- Zachowaj deterministyczny format wyjścia (poniżej).
## When to use
Użyj tylko gdy:
- użytkownik chce: analizę/plan/porównanie/rewriting/checklistę/specyfikację dla **[topic]**
Nie używaj gdy:
- potrzebne jest pobranie danych z pliku/WWW/systemu albo jakiekolwiek działanie w środowisku.
## Output format (strict)
Zwróć odpowiedź zawsze w tym układzie:
### TL;DR
- ...
### Inputs (what I used)
- ...
### Result
- ...
### Assumptions
- ...
### Next actions (max 5)
1. ...
2. ...
## Quality checklist (internal)
- Czy output ma TL;DR + Inputs + Result + Assumptions + Next actions?
- Czy nie ma w nim “narzędzi” ani sugestii wykonania poleceń?
- Czy nie ma halucynacji faktów?
Dlaczego te pola?
user-invocable/disable-model-invocationto opcjonalne klucze frontmatter (OpenClaw) — przydatne do ekspozycji jako slash command albo ukrycia przed automatycznym doborem. [docs.openclaw.ai]metadatajako jednolinijkowy JSON ialways/ossą zgodne z mechanizmem gatingu. [docs.openclaw.ai]
Zalecana polityka narzędzi (żeby LLM‑only był naprawdę “no-tools”)
W ~/.openclaw/openclaw.json ustaw np. profil minimalny (albo jawne deny):
{
"tools": {
"profile": "minimal",
"deny": ["group:fs", "group:runtime", "group:web", "group:ui", "group:nodes", "group:automation"]
}
}
tools.profilei grupygroup:*są wspierane i opisane w dokumentacji narzędzi. [docs.openclaw.ai]
Jeśli chcesz, możesz to ograniczyć per-agent (np. tylko dla “writer” agenta), ale powyższe jest najprostsze.
3) Wersja B — Tool‑first (narzędzia domyślnie, LLM tylko do planu + interpretacji)
Kiedy to ma sens?
- gdy skill ma pobierać dane (pliki/WWW), uruchamiać komendy, zapisywać artefakty
- gdy chcesz przewidywalny pipeline: preflight → gather → execute → output
- gdy chcesz mniej halucynacji, bo fakty biorą się z tool outputów
SKILL.md (Tool‑first)
Uwaga: nazwy narzędzi i grupy są zgodne z listą OpenClaw tools (np.
read,write,exec,web_fetch,web_search). [docs.openclaw.ai], [docs.openclaw.ai]
---
name: my-custom-skill-tool-first
description: Tool-first skill for [topic]. Fetches/reads inputs, executes deterministic steps, writes auditable artifacts.
user-invocable: true
metadata: {"openclaw":{"emoji":"🛠️","requires":{"config":["tools.web.fetch.enabled"],"env":["MY_SKILL_API_KEY"],"bins":["jq"]},"primaryEnv":"MY_SKILL_API_KEY"}}
---
# My Custom Skill (Tool-first)
## Purpose (single responsibility)
Wykonaj workflow dla **[topic]** w sposób audytowalny:
1) zbierz dane → 2) przetwórz → 3) zapisz wynik.
## Load-time gates (runtime safety)
Ten skill ma być aktywny tylko gdy:
- `MY_SKILL_API_KEY` jest dostępny (env lub skills.entries.*.apiKey),
- `tools.web.fetch.enabled` jest włączone,
- binarka `jq` istnieje na PATH.
(Jeśli w sandboxie — binarka musi istnieć także w kontenerze.)
## Tools allowed (prefer)
- `read` / `write` (artefakty)
- `web_fetch` (zawartość stron)
- `web_search` (tylko jeśli user nie podał URL)
- `exec` (tylko deterministyczne polecenia, bez wstrzykiwania parametrów od usera)
## Guardrails (MUST)
- Nie uruchamiaj `exec` z argumentami sklejanymi z surowego inputu użytkownika (ryzyko injection).
- Zanim użyjesz narzędzi: wykonaj Pre-flight.
- Zawsze zapisuj artefakty w `{baseDir}/runs/<timestamp>/...` (bezpieczny scope).
- Jeśli jakikolwiek krok nie ma danych → przerwij i poproś o doprecyzowanie.
---
## Execution (deterministic)
### Step 0 — Pre-flight (fail-fast)
1. Waliduj input (topic, opcje).
2. Sprawdź dostępność narzędzi wymaganych w `requires`.
3. Ustaw `runId = YYYYMMDD-HHMMSS` i katalog:
`{baseDir}/runs/{runId}/`
### Step 1 — Gather (minimum necessary)
- Jeśli user podał URL → `web_fetch(url=...)`
- Jeśli nie podał URL → `web_search(query=...)` → wybierz 1–3 wyniki → `web_fetch(...)`
- Jeśli user podał plik ścieżką → `read(path=...)`
Zapisz:
- `{baseDir}/runs/{runId}/inputs.json`
- `{baseDir}/runs/{runId}/sources.md`
### Step 2 — Transform (tool-first)
- Preferuj deterministyczne przetwarzanie:
- proste ekstrakcje i walidacje przez `exec` (np. `jq`) tylko na danych z własnych plików w katalogu run.
- LLM używaj tylko do:
- ułożenia planu
- formatowania końcowego raportu
Zapisz:
- `{baseDir}/runs/{runId}/result.raw`
### Step 3 — Output (auditable)
Wygeneruj raport w Markdown:
- `{baseDir}/runs/{runId}/report.md`
Raport MA zawierać:
- TL;DR
- Źródła (linki/fragmenty)
- Kroki wykonania (logicznie, bez sekretów)
- Artefakty (ścieżki)
Na końcu zwróć użytkownikowi:
- krótką odpowiedź + link/ścieżkę do report.md
Dlaczego takie metadata.openclaw.requires?
requires.bins/env/configto dokładnie ten mechanizm, którym OpenClaw filtruje skille przy ładowaniu. [docs.openclaw.ai]primaryEnvwiąże się z wygodnymskills.entries.<name>.apiKeyw configu. [docs.openclaw.ai]{baseDir}to wspierany placeholder do referencji folderu skilla. [docs.openclaw.ai]
Zalecana konfiguracja skills.entries (openclaw.json)
{
"skills": {
"entries": {
"my-custom-skill-tool-first": {
"enabled": true,
"apiKey": { "source": "env", "provider": "default", "id": "MY_SKILL_API_KEY" },
"env": {
"MY_SKILL_API_KEY": "REDACTED"
},
"config": {
"maxRetries": 2,
"maxSources": 3
}
}
}
}
}
skills.entries.*.env,skills.entries.*.apiKeyiskills.entries.*.configsą wspierane jako override per-skill. [docs.openclaw.ai]
Zalecana polityka narzędzi dla Tool‑first (żeby działał i był bezpieczny)
{
"tools": {
"profile": "coding",
"allow": ["group:fs", "group:web", "group:runtime"],
"deny": ["browser", "canvas", "nodes", "cron"]
}
}
- Profile (
coding) i grupy (group:fs,group:web,group:runtime) są częścią mechanizmu policy w OpenClaw. [docs.openclaw.ai] web_fetchiweb_searchto wbudowane web narzędzia (bez JS; do JS‑heavy stron jestbrowser). [docs.openclaw.ai], [docs.openclaw.ai]
4) Bonus: “hybryda” sterowana komendą (szybki slash → tool dispatch)
Jeśli chcesz, żeby komenda omijała model i wywoływała bezpośrednio narzędzie (np. do “/my-skill fetch …”), możesz użyć command-dispatch: tool + command-tool.
To jest super do operacji typu “zrób X jednym tool‑call”. [docs.openclaw.ai]
5) Dwa krótkie wybory architektoniczne (żebyś nie wpadł w typowe pułapki)
LLM‑only
✅ przewidywalne, zero side‑effectów, tanie w utrzymaniu
❌ nie pobierze danych z zewnątrz, nie zapisze plików (chyba że pozwolisz narzędzia)
Tool‑first
✅ minimalizuje halucynacje, audytowalne artefakty, pipeline “jak w produkcji”
❌ wymaga dobrych guardrails i policy (szczególnie dla exec) [docs.openclaw.ai]
Pytanie, które pozwoli mi dopiąć to “na gotowo” (bez długiej wymiany)
Jaki jest konkretny cel Twojego skilla w praktyce?
Daj 1 zdanie w stylu:
- “Zbiera dane z URL + robi raport”
- “Czyta logi / pliki i generuje podsumowanie”
- “Uruchamia komendy diagnostyczne (DB/Splunk/SQL) i zapisuje wynik”
…i wtedy dopasuję Ci:
- dokładne
requires.configpod Twoje narzędzia, - strukturę artefaktów,
- i bezpieczne allowlisty dla
exec(jeśli w ogóle ma być).
Jasne — poniżej masz wersję hybrydową SKILL.md dla OpenClaw, która łączy:
- tryb “agentowy” (LLM + tool‑first) w normalnej rozmowie
- tryb “komendowy” (/… → direct tool dispatch) dla deterministycznych akcji ze slash command
To jest zgodne z tym, jak OpenClaw ładuje skille z katalogu z SKILL.md (YAML frontmatter + Markdown) i jak działa gating (metadata.openclaw.requires) oraz obsługa slash commands (user-invocable, command-dispatch, command-tool, command-arg-mode). [docs.openclaw.ai], [docs.openclaw.ai], [moely.ai]
Uwaga praktyczna: Direct tool dispatch wymaga, żeby wskazany tool akceptował parametry przekazywane przez dispatcher (
{ command, commandName, skillName }). OpenClaw opisuje to wprost.
Jeśli Twoja instalacja ma ściśle walidowane schematy narzędzi i wywali się na “nadmiarowych polach”, daję też wariant “bez bypassu” (slash dalej wybiera skill, ale przez LLM) w sekcji Plan B. [docs.openclaw.ai], [moely.ai]
✅ 1) Hybrydowy SKILL.md (Tool‑first + Slash direct-dispatch)
Wklej jako:
<workspace>/skills/my-custom-skill-hybrid/SKILL.md
(Workspace ma najwyższy priorytet ładowania względem ~/.openclaw/skills i bundli). [docs.openclaw.ai], [docs.openclaw.ai]
---
name: my-custom-skill-hybrid
description: Hybrid skill: tool-first in chat, optional deterministic slash dispatch (bypass model) for quick actions.
user-invocable: true
disable-model-invocation: false
command-dispatch: tool
command-tool: exec
command-arg-mode: raw
metadata: {"openclaw":{"emoji":"🧩","os":["darwin","linux","win32"],"requires":{"config":["tools.exec.enabled"],"bins":["jq"]}}}
---
# My Custom Skill (HYBRID)
Ten skill ma **dwa tryby pracy**:
## Mode A — Chat / Agent mode (default)
Gdy użytkownik opisuje problem normalnie, skill działa **tool-first**:
- zbierz dane (read/web_fetch/web_search)
- przetwórz deterministycznie (preferuj narzędzia)
- dopiero na końcu użyj LLM do formatowania raportu
## Mode B — Slash / Deterministic mode (bypass model)
Gdy użytkownik użyje komendy slash dla tego skilla, OpenClaw ma **ominiąć model**
i wywołać wskazane narzędzie bezpośrednio (command-dispatch: tool).
W tym trybie parametr `args` trafia jako `command` do toola.
> Komenda jest przekazywana jako:
> { command: "<raw args>", commandName: "<slash>", skillName: "<skill>" }.
---
## Safety & Guardrails (MANDATORY)
- Nigdy nie wykonuj poleceń destrukcyjnych (rm -rf, format, wipe, itp.).
- Nie uruchamiaj poleceń z sekretami w treści.
- Jeśli w Mode A potrzebujesz `exec`, to:
- używaj allowlisty komend,
- nie sklejaj argumentów z “surowego” inputu użytkownika.
- Artefakty zapisuj wyłącznie w `{baseDir}/runs/<runId>/`.
---
## When to Use
Użyj, gdy użytkownik chce:
- zebrać dane z pliku/URL i zrobić raport / analizę dla [topic]
- albo wykonać szybkie, deterministyczne akcje komendą (Mode B)
Nie używaj, gdy:
- zadanie wymaga browser logowania/JS-heavy — wtedy preferuj browser tool (poza tym skillem).
---
## Execution (Mode A — tool-first)
### Step 0: Pre-flight
1) Ustal `runId = YYYYMMDD-HHMMSS`.
2) Sprawdź, czy masz minimalne dane wejściowe (topic / źródło / zakres).
3) Jeśli braki → max 3 pytania doprecyzowujące.
### Step 1: Gather
- Jeśli user podał plik → `read`
- Jeśli podał URL → `web_fetch`
- Jeśli nie podał źródła → `web_search` (max 3 wyniki) → `web_fetch`
Zapisz:
- `{baseDir}/runs/{runId}/inputs.json`
- `{baseDir}/runs/{runId}/sources.md`
### Step 2: Transform
- Preferuj narzędzia i deterministykę.
- Jeśli musisz, użyj `exec` tylko dla bezpiecznych transformacji na plikach z katalogu run.
- LLM wyłącznie do: streszczenia, formatowania, wyjaśnienia.
Zapisz:
- `{baseDir}/runs/{runId}/result.raw`
### Step 3: Output
Wygeneruj `{baseDir}/runs/{runId}/report.md` zawierający:
- TL;DR
- Źródła i cytowane fragmenty
- Kroki wykonania (bez sekretów)
- Artefakty (ścieżki)
---
## Slash usage (Mode B — bypass model)
### /my-custom-skill-hybrid <raw>
Przykłady (bezpieczne, read-only):
- `/my-custom-skill-hybrid echo "hello"`
- `/my-custom-skill-hybrid jq --version`
Zasady:
- traktuj to jako tryb “operator executes a command”
- jeśli komenda wygląda na destrukcyjną → przerwij i poproś o potwierdzenie poza trybem bypass
Dlaczego to jest “OpenClaw‑native”?
- Skill jako katalog z
SKILL.md+ frontmatter jest standardem OpenClaw. [docs.openclaw.ai], [docs.openclaw.ai] metadata.openclaw.requires(bins/config/os) to mechanizm load‑time gating. [docs.openclaw.ai], [moely.ai]user-invocable,command-dispatch: tool,command-tool,command-arg-modeto oficjalnie opisane pola dla komend i bypassu. [docs.openclaw.ai], [moely.ai]execjest narzędziem do uruchamiania komend, kontrolowanym politykami narzędzi. [docs.openclaw.ai]
✅ 2) Konfiguracja openclaw.json (narzędzia + skill entry)
a) Bezpieczna polityka narzędzi (dla hybrydy)
Poniżej ustawiasz profil i allow/deny (OpenClaw wspiera tools.profile, tools.allow, tools.deny i grupy). [docs.openclaw.ai]
{
"tools": {
"profile": "coding",
"allow": ["group:fs", "group:web", "group:runtime"],
"deny": ["browser", "canvas", "nodes", "cron"]
},
"skills": {
"entries": {
"my-custom-skill-hybrid": {
"enabled": true,
"config": {
"maxSources": 3,
"maxRetries": 2
}
}
}
}
}
🔧 Plan B (jeśli direct-dispatch nie działa w Twojej instalacji)
W części wdrożeń bywa, że komendy skillowe (w tym command-dispatch: tool) nie odpalają się jak trzeba zależnie od wersji/konfiguracji (widziano przypadek zależności od aliasów modeli). [github.com]
Wtedy zrób hybrydę bez bypassu:
- Usuń z frontmatter:
command-dispatch,command-tool,command-arg-mode
- Zostaw
user-invocable: true - A w treści skilla dodaj regułę:
- “Jeśli użytkownik wywoła skill ze slash command i poda argumenty, traktuj je jako ‘tryb komendowy’, ale nadal przejdź przez Pre-flight i guardrails.”
To nadal daje dwa tryby, tylko Mode B idzie przez LLM (mniej deterministycznie, ale bardziej kompatybilnie). [docs.openclaw.ai], [docs.openclaw.ai]
Następny krok (żeby to było “idealnie pod Ciebie”)
W tej chwili hybryda ma Mode B ustawiony na exec (bo to najprostszy “tool dispatch”).
Powiedz mi w 1 zdaniu: co Mode B ma robić w Twoim realnym use-case? [docs.openclaw.ai], [docs.openclaw.ai]
Przykłady:
- “/skill diag” → zebrać statusy i zapisać report
- “/skill fetch ” → pobrać stronę i znormalizować do markdown
- “/skill sqlcheck” → odpalić kilka read-only poleceń diagnostycznych
A ja dopasuję:
- bezpieczną allowlistę komend (albo całkiem wyeliminuję
exec), - parametry “raw args” i format,
- oraz gating (
requires.config/env/bins) pod Twoje runtime. [docs.openclaw.ai], [docs.openclaw.ai]
Pewnie — pokażę Ci jak wygląda rozbicie na “skill (orchestrator) + sub‑skille” w OpenClaw oraz dorzucę allowlistę komend (dla exec) tak, żeby dało się to utrzymać i nie otworzyć sobie drzwi na command‑injection. [docs.openclaw.ai], [blog.laozhang.ai], [deepwiki.com]
Ważna uwaga o architekturze w OpenClaw: “sub‑skille” to po prostu osobne skille (oddzielne katalogi z
SKILL.md), które agent wybiera zależnie od intencji. Orchestrator nie “wywołuje” ich jak funkcji w kodzie, ale kieruje agentem (instrukcjami) żeby użył właściwego sub-skilla dla danego kroku. OpenClaw ładuje i filtruje skille (gating), a potem wstrzykuje ich opis do promptu, na podstawie którego model decyduje, którego użyć. [docs.openclaw.ai], [deepwiki.com]
1) Jak to będzie wyglądać — struktura katalogów (suite: skill + sub‑skille)
Skille w OpenClaw to katalog + SKILL.md; najlepiej trzymać to w <workspace>/skills, bo ma najwyższy priorytet nad ~/.openclaw/skills i bundlami. [deepwiki.com], [docs.openclaw.ai]
Przykładowa “paczka” (suite):
<workspace>/skills/
my-suite-orchestrator/
SKILL.md
my-suite-gather-web/
SKILL.md
my-suite-gather-files/
SKILL.md
my-suite-transform/
SKILL.md
my-suite-report/
SKILL.md
my-suite-quickfetch/ # opcjonalny "hybrydowy" slash bypass (bezpieczny)
SKILL.md
- orchestrator: routuje do sub-skilli + trzyma wspólne guardrails i spójny format artefaktów. [docs.openclaw.ai]
- gather-*: izolują pobieranie danych (WWW / pliki). [blog.laozhang.ai], [deepwiki.com]
- transform: deterministyczne przetwarzanie + allowlista
exec. [blog.laozhang.ai] - report: format i finalny raport. [docs.openclaw.ai]
- quickfetch: jeśli chcesz prawdziwy “hybrydowy” bypass bez ryzyka (dispatch do
web_fetch, a nie doexec).web_fetchjest z natury “bezpieczniejszy” niżexec, bo nie uruchamia poleceń, tylko pobiera URL i ekstrahuje treść. [blog.laozhang.ai], [deepwiki.com]
2) Skill #1 — Orchestrator (główny “suite skill”)
Cel: jeden skill, który:
- wybiera odpowiedni sub-skill,
- pilnuje spójnej struktury
runs/<runId>/, - pilnuje zasad bezpieczeństwa i “kiedy exec jest w ogóle dozwolony”. [blog.laozhang.ai], [docs.openclaw.ai]
<workspace>/skills/my-suite-orchestrator/SKILL.md
---
name: my-suite-orchestrator
description: Orchestrates the suite: routes to sub-skills, enforces guardrails, and produces auditable outputs.
user-invocable: true
metadata: {"openclaw":{"emoji":"🧭","always":true}}
---
# My Suite — Orchestrator
## Responsibility (single)
Zarządzaj wykonaniem zadania: wybierz właściwy sub-skill, utrzymaj porządek artefaktów i guardrails.
## Routing rules (deterministic)
- Jeśli źródło to URL / WWW → użyj **my-suite-gather-web**
- Jeśli źródło to plik/ścieżka → użyj **my-suite-gather-files**
- Jeśli trzeba przetworzyć/oczyścić dane → użyj **my-suite-transform**
- Jeśli trzeba złożyć wynik w raport → użyj **my-suite-report**
## Global guardrails (MUST)
- Preferuj narzędzia “read-only” i web tools (web_fetch/web_search) nad exec.
- `exec` tylko gdy:
1) to konieczne,
2) pasuje do allowlisty z my-suite-transform,
3) dotyczy wyłącznie plików w `{baseDir}/runs/<runId>/`.
- Artefakty zapisuj w `{baseDir}/runs/<runId>/...`
- Jeśli brakuje danych → max 3 pytania doprecyzowujące, potem stop.
## Output contract
Zawsze zwróć:
- TL;DR
- Co było wejściem
- Co powstało (artefakty i ścieżki)
- Następne kroki
Dlaczego tak? Orchestrator wykorzystuje fakt, że OpenClaw “podaje” modelowi listę dostępnych skilli i narzędzi, więc routing robimy instrukcjami (deterministycznie). [docs.openclaw.ai], [blog.laozhang.ai]
3) Sub-skill: Gather Web (web_search + web_fetch)
<workspace>/skills/my-suite-gather-web/SKILL.md
---
name: my-suite-gather-web
description: Fetches sources from the web. Uses web_search when needed, then web_fetch for extraction.
user-invocable: false
metadata: {"openclaw":{"emoji":"🌐","requires":{"config":["tools.web.fetch.enabled"]}}}
---
# Gather Web
## When to use
- Użytkownik podał URL lub trzeba znaleźć źródła w WWW.
## Steps
1) Jeśli jest URL → `web_fetch(url=..., extractMode="markdown")`
2) Jeśli brak URL → `web_search(query=..., count=3)` → wybierz 1–3 wyniki → `web_fetch(...)`
## Artifacts
Zapisz do:
- `{baseDir}/runs/<runId>/sources.md` (linki + krótkie ekstrakty)
- `{baseDir}/runs/<runId>/inputs.json` (metadane wejścia)
web_search i web_fetch są oficjalnymi web toolami w OpenClaw (wyszukiwanie + fetch bez JS). [deepwiki.com], [blog.laozhang.ai]
4) Sub-skill: Gather Files (read)
<workspace>/skills/my-suite-gather-files/SKILL.md
---
name: my-suite-gather-files
description: Loads input from local files safely and stores normalized copies in the run folder.
user-invocable: false
metadata: {"openclaw":{"emoji":"📁","requires":{"config":["group:fs"]}}}
---
# Gather Files
## When to use
- Użytkownik wskazuje plik/ścieżkę lub potrzebujesz odczytać artefakt z wcześniejszego run.
## Steps
1) Użyj `read(path=...)` na wejściu.
2) Skopiuj/znormalizuj treść do `{baseDir}/runs/<runId>/input.txt` (bez modyfikowania oryginału).
## Artifacts
- `{baseDir}/runs/<runId>/input.txt`
- `{baseDir}/runs/<runId>/inputs.json`
Narzędzia plikowe (read/write/edit/...) są grupowane i kontrolowane politykami tooli w OpenClaw (group:fs). [blog.laozhang.ai]
5) Sub-skill: Transform (TU dodajemy allowlistę komend)
To jest miejsce, gdzie robisz “bezpieczny runtime” dla exec. exec w OpenClaw to narzędzie do uruchamiania komend w workspace (z parametrami m.in. command, timeout, security). [blog.laozhang.ai]
<workspace>/skills/my-suite-transform/SKILL.md
---
name: my-suite-transform
description: Deterministic transformations with a strict command allowlist (exec is optional and constrained).
user-invocable: false
metadata: {"openclaw":{"emoji":"🧪","requires":{"config":["group:runtime"],"bins":["jq"]}}}
---
# Transform (Allowlisted exec)
## Golden rule
Preferuj transformacje bez `exec`. Jeśli `exec` jest potrzebny → tylko allowlista poniżej.
## Command allowlist (STRICT)
Dozwolone są WYŁĄCZNIE te komendy (dokładne wzorce):
1) `jq --version`
2) `jq -c . <INPUT >OUTPUT`
3) `jq -r . <INPUT >OUTPUT`
4) `head -n <N> <INPUT`
5) `tail -n <N> <INPUT`
6) `wc -l <INPUT`
7) `grep -n "<literal>" <INPUT`
8) `sed -n '<start>,<end>p' <INPUT`
### Constraints (MUST)
- `<INPUT>` i `<OUTPUT>` MUSZĄ być ścieżkami pod `{baseDir}/runs/<runId>/`
- `<N>` to liczba 1..500
- `"<literal>"` nie może zawierać znaków: `; | & $ \` ( ) { }`
- Zakaz: `rm`, `mv`, `cp` poza run, `curl`, `wget`, `ssh`, `sudo`, `chmod`, `chown`, `dd`, `mkfs`, `> /dev/*` itd.
## Execution steps
1) Waliduj, czy polecenie pasuje do allowlisty i constraintów.
2) Jeśli nie pasuje → przerwij i zaproponuj alternatywę bez exec.
3) Jeśli pasuje → uruchom `exec` tylko na plikach w katalogu run.
4) Wynik zapisz do:
- `{baseDir}/runs/<runId>/transform.log`
- `{baseDir}/runs/<runId>/<output files>`
## Why this exists
Zapobiega command injection i ogranicza skutki błędów do sandboxowego katalogu run.
Dlaczego allowlista w SKILL.md ma sens?
Bo w OpenClaw to model wybiera i parametryzuje tool‑call (np. exec(command=...)), a Ty chcesz mu zawęzić przestrzeń decyzji do znanych, bezpiecznych wzorców. Narzędzie exec jest potężne, więc guardrails muszą być twarde. [blog.laozhang.ai]
6) Sub-skill: Report (formatowanie i final)
<workspace>/skills/my-suite-report/SKILL.md
---
name: my-suite-report
description: Produces the final report.md from gathered/transformed artifacts. No exec.
user-invocable: false
metadata: {"openclaw":{"emoji":"📝","always":true}}
---
# Report
## Inputs
- `{baseDir}/runs/<runId>/sources.md` i/lub `input.txt`
- `{baseDir}/runs/<runId>/result.raw` (jeśli istnieje)
- `transform.log` (opcjonalnie)
## Output
Zapisz:
- `{baseDir}/runs/<runId>/report.md`
Format report.md:
- TL;DR
- Evidence (źródła, linki, fragmenty)
- Steps taken (bez sekretów)
- Artifacts (ścieżki)
- Next actions (max 5)
7) Hybryda: “quick” slash bypass (bezpieczny) — opcjonalnie 📦
Jeśli nadal chcesz “hybrydę” w sensie slash command → direct tool dispatch, to nie dispatchuj do exec (bo omijasz model, więc omijasz allowlistę!). Zamiast tego zrób osobny “quickfetch” dispatchujący do web_fetch. Mechanizm command-dispatch: tool + command-tool jest wspierany. [docs.openclaw.ai]
<workspace>/skills/my-suite-quickfetch/SKILL.md
---
name: my-suite-quickfetch
description: Slash-safe quick fetch: bypass model and run web_fetch directly on provided URL.
user-invocable: true
command-dispatch: tool
command-tool: web_fetch
command-arg-mode: raw
metadata: {"openclaw":{"emoji":"⚡","requires":{"config":["tools.web.fetch.enabled"]}}}
---
# QuickFetch (slash)
Usage:
- `/my-suite-quickfetch https://example.com`
Notes:
- This bypasses the model and dispatches to web_fetch.
- Provide a single URL as the raw args string.
web_fetch jest narzędziem do pobrania i ekstrakcji treści (bez JS), więc jako bypass jest dużo mniej ryzykowne niż exec. [deepwiki.com], [blog.laozhang.ai]
8) Konfiguracja narzędzi (tools policy) — minimalny “safe” zestaw
OpenClaw pozwala ustawić bazową politykę przez tools.profile oraz tools.allow/deny i grupy (group:fs, group:web, group:runtime). [blog.laozhang.ai]
Przykład “suite-friendly” (umożliwia pliki+web+exec, ale blokuje UI/nodes/cron):
{
"tools": {
"profile": "coding",
"allow": ["group:fs", "group:web", "group:runtime"],
"deny": ["browser", "canvas", "nodes", "cron"]
}
}
9) Co dostajesz dzięki takiemu rozbiciu?
✅ Mniej halucynacji (gather i transform to narzędzia, a nie “zgadywanie”).
✅ Mniejszy prompt per skill (sub‑skille są węższe i prostsze).
✅ Łatwiejszy audyt (artefakty w jednym run folderze).
✅ Bezpieczniejsze exec dzięki allowliście + constraintom na ścieżki.
✅ “Hybryda”: szybki slash do bezpiecznego toola (web_fetch) + pełny agentowy pipeline w rozmowie. [blog.laozhang.ai], [deepwiki.com] [docs.openclaw.ai] [docs.openclaw.ai], [blog.laozhang.ai] [blog.laozhang.ai] [deepwiki.com], [blog.laozhang.ai]
Szybkie doprecyzowanie (jedno zdanie wystarczy)
Chcesz allowlistę komend pod jakie realne zadania? (np. parsowanie JSON logów, wyciąganie fragmentów tekstu, walidacja plików, itd.)
Jeśli powiesz “do czego”, dopasuję allowlistę tak, żeby:
- była minimalna (im mniej, tym lepiej),
- nie była “zbyt ogólna” (np. nie dam
python -cbo to prawie jak pełny shell), - i żeby nie blokowała Twojego flow.
Poniżej masz praktyczne ograniczenia i “pułapki” używania exec w OpenClaw – czyli co realnie ogranicza to narzędzie, jak działa w sandboxie/na hoście, jakie ma limity i jakie mechanizmy bezpieczeństwa wpływają na to, czy komenda w ogóle się wykona. Wszystko w oparciu o oficjalny opis narzędzi OpenClaw. [blog.laozhang.ai]
1) exec działa w określonym “kontekście uruchomienia” (workspace / sandbox / node)
- Domyślnie
execuruchamia komendy w workspace (w praktyce: w katalogu roboczym sesji/agenta). [blog.laozhang.ai] execma parametrhost, który determinuje gdzie wykonać polecenie:sandbox | gateway | node. [blog.laozhang.ai]- W trybie sandbox (kontener) to, co działa na hoście, nie musi działać w sandboxie (brak binarek, brak sieci, inny filesystem). OpenClaw wprost zaznacza, że przy sandboxie binarki wymagane przez skill muszą istnieć również w kontenerze, a instalacje w kontenerze wymagają m.in. egressu sieci, zapisywalnego FS i uprawnień (root). [docs.openclaw.ai], [blog.laozhang.ai]
Wniosek: jeśli Twoja komenda “działa u Ciebie w terminalu”, to nadal może nie działać w sandboxie agenta (inne środowisko). [blog.laozhang.ai], [docs.openclaw.ai]
2) Narzędzie może być całkowicie niedostępne przez polityki narzędzi (tools.profile/allow/deny)
- OpenClaw ma globalne polityki narzędzi:
tools.profile,tools.allow,tools.deny(deny wygrywa) i wspiera grupy typugroup:runtime(gdzie jest m.in.exec). [blog.laozhang.ai] - Jeśli
exec(albogroup:runtime) jest zablokowany w polityce, to model nie dostanie schematu narzędzia, a więc nie będzie mógł go wywołać. [blog.laozhang.ai]
Wniosek: “skill mówi żeby użyć exec” ≠ “agent może użyć exec”. O tym decyduje policy. [blog.laozhang.ai]
3) exec ma wbudowane limity czasu i tryby pracy (sync vs background)
- Kluczowe parametry
execto m.in.:yieldMs(domyślnie 10000),background,timeout(sekundy; domyślnie 1800),pty,host,security,ask. [blog.laozhang.ai] - Jeśli proces przekroczy
yieldMs, OpenClaw może go zabackgroundować i zwrócić statusrunningzsessionId. [blog.laozhang.ai] - Do obsługi procesów w tle służy narzędzie
process(list/poll/log/write/kill/clear/remove). [blog.laozhang.ai] - Jeżeli
processjest zablokowane, OpenClaw zaznacza, żeexecdziała wtedy synchronicznie i ignorujeyieldMs/background(czyli tracisz wygodny mechanizm long‑running jobów). [blog.laozhang.ai]
Wniosek: długie komendy bez process mogą “nie mieć gdzie żyć” – albo będą ucinane/timeoutowane, albo zablokują przebieg. [blog.laozhang.ai]
4) Ograniczenia bezpieczeństwa: security + “exec approvals” + ask
OpenClaw przewiduje kilka warstw kontroli:
execma parametrsecurity(np.deny | allowlist | full) i parametrask(off | on-miss | always) do sterowania zgodami/warunkami uruchomienia. [blog.laozhang.ai]- Dodatkowo, OpenClaw ma osobny mechanizm “Exec approvals” (zatwierdzanie/ograniczanie uruchamiania komend) – dokumentacja
execodwołuje się do tego wprost. [blog.laozhang.ai] - W praktyce oznacza to, że nawet jeśli agent potrafi złożyć komendę, może zostać zatrzymany przez politykę “approval/allowlist” (zależnie od konfiguracji). [blog.laozhang.ai]
Wniosek: w produkcyjnych setupach exec często jest “supervised”: albo wymaga potwierdzeń, albo działa tylko na allowliście, albo jest wyłączony. [blog.laozhang.ai]
5) elevated (uruchomienie na hoście) ma dodatkowe bramki
elevatedto alias zachowania “uruchom na gateway host z pełnymi uprawnieniami”, ale działa sensownie głównie wtedy, gdy sesja jest sandboxowana (w przeciwnym razie bywa no‑op). [blog.laozhang.ai]- Jest to dodatkowo “gated” przez
tools.elevatedi ewentualne override per-agent – oba muszą pozwalać. [blog.laozhang.ai]
Wniosek: jeśli liczysz na “wyjście z sandboxa” przez elevated, to musisz to mieć jawnie włączone; w wielu środowiskach będzie to celowo zablokowane. [blog.laozhang.ai]
6) exec nie daje prawdziwego TTY bez pty: true (a i tak bywa ograniczone)
- Dokumentacja wskazuje: “Need a real TTY? Set
pty: true.” [blog.laozhang.ai] - To rozwiązuje część problemów z programami interaktywnymi, ale w praktyce nadal możesz wpadać na ograniczenia sandboxa / braku urządzeń / braku UI. [blog.laozhang.ai]
Wniosek: exec nie jest idealne do narzędzi wymagających pełnej interakcji terminalowej, jeśli środowisko nie jest do tego przygotowane. [blog.laozhang.ai]
7) exec może być “ucinane” przez loop‑detection (gdy agent zapętla tool‑calls)
- OpenClaw ma mechanizm loop‑detection, który może ostrzegać/blokować powtarzalne wywołania narzędzi bez postępu (można włączyć i konfigurować progi). [blog.laozhang.ai]
Wniosek: jeśli agent wpada w pętlę exec → poll → exec → poll, system może to wykryć i zablokować. [blog.laozhang.ai]
8) Kluczowe “praktyczne” ograniczenie: ryzyko injection i brak automatycznej sanityzacji
To nie jest pojedyncza flaga, tylko fakt wynikający z charakteru exec:
execuruchamia shell commands, więc jeśli sklejasz komendę z surowego inputu usera, otwierasz się na injection. Dokumentacja narzędzi podkreśla, żeexecto narzędzie w grupie “runtime” i wymaga świadomej polityki bezpieczeństwa (deny/allowlist/approvals). [blog.laozhang.ai]- W docs “Creating Skills” jest ostrzeżenie: jeśli skill używa “bash/exec”, trzeba uważać na arbitrary command injection z niezaufanego inputu. [deepwiki.com]
Wniosek: najtwardszym ograniczeniem “w praktyce” jest to, że w dobrym projekcie exec musi być ograniczone allowlistą + kontrolą parametrów. [deepwiki.com], [blog.laozhang.ai]
Rekomendacja (krótko, produkcyjnie)
Jeśli chcesz używać exec w skillach “na serio”, to zwykle wygląda to tak:
tools.profile+tools.allow/denyogranicza dostęp doexectylko tam, gdzie naprawdę trzeba. [blog.laozhang.ai]- Skill ma allowlistę komend + walidację argumentów + ograniczenie ścieżek do run‑folderu. (To jest najlepsza praktyka wynikająca z ryzyk
execi ostrzeżeń dot. injection). [deepwiki.com], [blog.laozhang.ai] - Długie komendy →
processmusi być dostępny, inaczej long‑running flow się posypie. [blog.laozhang.ai]
Dopytam jedno (żeby odpowiedzieć “pod Twoją konfigurację”, nie ogólnie)
U Ciebie exec ma działać w sandboxie czy na hoście? (I czy włączone jest process?)
Na tej podstawie mogę zaproponować konkretny, bezpieczny zestaw: policy + allowlista + wzorce komend pod Twój use‑case.