Initial commit: OpenClaw Skill Collection
6 custom skills (assign-task, dispatch-webhook, daily-briefing, task-capture, qmd-brain, tts-voice) with technical documentation. Compatible with Claude Code, OpenClaw, Codex CLI, and OpenCode.
This commit is contained in:
85
chapters/03-services.md
Normal file
85
chapters/03-services.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# 3. 服務安裝紀錄
|
||||
|
||||
### 3.1 安裝前置準備
|
||||
|
||||
**問題:安裝腳本需要 root 權限**
|
||||
```bash
|
||||
# 錯誤方式(process substitution + sudo 不相容)
|
||||
sudo bash <(curl -sL kejilion.sh) app OpenClaw
|
||||
|
||||
# 正確方式
|
||||
curl -sL kejilion.sh -o /tmp/kejilion.sh && sudo bash /tmp/kejilion.sh app OpenClaw
|
||||
```
|
||||
|
||||
**問題:Webmin apt repo GPG key 失效導致 apt update 失敗**
|
||||
```bash
|
||||
sudo rm -f /etc/apt/sources.list.d/webmin.list
|
||||
sudo apt-get update
|
||||
# 然後手動裝 Node.js 22
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
### 3.2 CLIProxyAPI
|
||||
|
||||
安裝來源:`sudo bash /tmp/kejilion.sh app CLIProxyAPI`
|
||||
|
||||
安裝後設定:
|
||||
- WebUI:`http://192.168.31.169:8317/management.html`
|
||||
- Docker restart policy:`unless-stopped`
|
||||
|
||||
### 3.3 OpenClaw
|
||||
|
||||
安裝來源:`curl -fsSL https://openclaw.ai/install.sh | bash`
|
||||
|
||||
**啟動問題(腳本預期 tmux,後改為 systemd):**
|
||||
|
||||
腳本用 `pgrep -f "openclaw gateway"` 判斷是否運行,原本用 pm2 啟動會比對失敗。最終改用 systemd:
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/openclaw.service
|
||||
[Unit]
|
||||
Description=OpenClaw Gateway
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Environment=NODE_OPTIONS=--dns-result-order=ipv4first
|
||||
ExecStartPre=/bin/sh -c 'tmux kill-session -t gateway 2>/dev/null; true'
|
||||
ExecStart=/usr/bin/openclaw gateway
|
||||
ExecStop=/usr/bin/openclaw gateway stop
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable openclaw.service
|
||||
sudo systemctl start openclaw.service
|
||||
```
|
||||
|
||||
### 3.4 nginx
|
||||
|
||||
安裝來源:`/home/web/docker-compose.yml`(已有 Docker Compose 管理)
|
||||
|
||||
**問題:系統 nginx 佔用 port 80**
|
||||
```bash
|
||||
sudo systemctl stop nginx
|
||||
sudo systemctl disable nginx
|
||||
sudo docker restart nginx
|
||||
```
|
||||
|
||||
### 3.5 設備配對(Browser → OpenClaw)
|
||||
|
||||
```bash
|
||||
# 查看待審核配對請求
|
||||
sudo openclaw devices list
|
||||
|
||||
# 核准配對
|
||||
sudo openclaw devices approve <request-id>
|
||||
```
|
||||
312
chapters/04-known-issues.md
Normal file
312
chapters/04-known-issues.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# 4. 已知問題與修復
|
||||
|
||||
### 4.1 Node.js 22/24 fetch 無法連線 Telegram API
|
||||
|
||||
**症狀**:`Telegram: failed - fetch failed`,但 curl 可以正常連線
|
||||
|
||||
**根因**:Node.js 22+ 的 `fetch`(基於 undici)有 `autoSelectFamily`(happy eyeballs),優先嘗試 IPv6。伺服器沒有可用的 IPv6 對外連線。
|
||||
|
||||
**修復(三層)**:
|
||||
|
||||
1. 系統層停用 IPv6:
|
||||
```bash
|
||||
# 永久設定(/etc/sysctl.conf)
|
||||
net.ipv6.conf.all.disable_ipv6=1
|
||||
net.ipv6.conf.default.disable_ipv6=1
|
||||
net.ipv6.conf.lo.disable_ipv6=1
|
||||
```
|
||||
|
||||
2. gateway.env 加入 NODE_OPTIONS:
|
||||
```
|
||||
NODE_OPTIONS=--dns-result-order=ipv4first --no-network-family-autoselection
|
||||
```
|
||||
|
||||
3. openclaw.json config 層覆蓋(**Node 24 必須,因 OpenClaw 內部 hardcode `autoSelectFamily:true`**):
|
||||
```json
|
||||
{ "channels": { "telegram": { "network": { "autoSelectFamily": false, "dnsResultOrder": "ipv4first" } } } }
|
||||
```
|
||||
|
||||
**注意**:sysctl + NODE_OPTIONS 在 Node 22 就夠了,但 Node 24 的 undici 不吃這些設定,必須用 openclaw.json config 覆蓋(見 §4.13)。
|
||||
|
||||
### 4.2 OpenClaw 腳本顯示「未運行」
|
||||
|
||||
**症狀**:`sudo bash kejilion.sh app OpenClaw` 顯示「已安裝 未運行」,但 Gateway 實際在跑
|
||||
|
||||
**根因**:腳本用 `pgrep -f "openclaw gateway"` 判斷,但 pm2/systemd 啟動的進程名稱不符
|
||||
|
||||
**修復**:改用 tmux 啟動(若要讓腳本正確識別),或改用 systemd(推薦)
|
||||
|
||||
### 4.3 Docker nginx 開機後無法啟動
|
||||
|
||||
**症狀**:`nginx: bind() to 0.0.0.0:80 failed (98: Address in use)`
|
||||
|
||||
**根因**:系統安裝的 nginx(`/usr/sbin/nginx`)設為 enabled,開機時搶先佔用 port 80
|
||||
|
||||
**修復**:
|
||||
```bash
|
||||
sudo systemctl stop nginx
|
||||
sudo systemctl disable nginx
|
||||
```
|
||||
|
||||
### 4.4 Multi-Agent Config Schema 與文件不符(v2026.2.17)
|
||||
|
||||
**症狀**:修改 `openclaw.json` 後 Gateway 啟動失敗,報 `Unrecognized key: "agentId"` 和 `bindings.0.match: Invalid input`
|
||||
|
||||
**根因**:官方文件範例使用舊版 schema,與實際 v2026.2.17 不相容
|
||||
|
||||
**正確格式**:
|
||||
- `agents.list[].id`(不是 `agentId`)
|
||||
- `bindings[]` 需要 `{ "agentId": "xxx", "match": { "channel": "telegram", "accountId": "yyy" } }`
|
||||
- 詳見 [06-config.md 6.2 節](06-config.md)
|
||||
|
||||
### 4.5 新 Bot /start 無配對碼回應
|
||||
|
||||
**症狀**:在新 Telegram Bot 按 /start 沒有任何回應
|
||||
|
||||
**根因**:按 /start 時 Gateway 尚未載入新 Bot Token,Telegram update 被消耗但無人處理
|
||||
|
||||
**修復**:確保 config 已正確 + Gateway 重啟成功後再按 /start
|
||||
|
||||
### 4.6 使用 accounts 後主 Bot 通道不啟動(2026-02-25)
|
||||
|
||||
**症狀**:`openclaw channels list` 只顯示 `life-bot`,主 Bot(@Cimon168_bot)不啟動,啟動日誌無 `[default] starting provider` 訊息
|
||||
|
||||
**根因**:當 `channels.telegram.accounts` 區塊存在時,OpenClaw 只啟動 `accounts` 裡明確列出的帳號。頂層 `botToken` 不再被視為獨立通道。
|
||||
|
||||
**修復**:將主 Bot token 從頂層移入 `accounts.default`:
|
||||
|
||||
```json
|
||||
"accounts": {
|
||||
"default": {
|
||||
"botToken": "<主 Bot Token>"
|
||||
},
|
||||
"life-bot": {
|
||||
"botToken": "<生活 Bot Token>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
修改後重啟:`systemctl --user restart openclaw-gateway`
|
||||
|
||||
### 4.7 Multi-Agent 後 workspace skills 消失(2026-02-25)
|
||||
|
||||
**症狀**:Gateway 重啟後 `openclaw skills list` 只顯示 bundled skills,workspace skills(daily-briefing、qmd-brain、task-capture)消失。Agent 回覆不認識這些 skills。
|
||||
|
||||
**根因**:`agents.list` 只有具名 agent(如 `life-assistant`)時,隱含的預設 agent(main)不會觸發 workspace skills 掃描。OpenClaw 只對 `agents.list` 中明確列出的 agent 執行 workspace 目錄的 skills 發現。
|
||||
|
||||
**修復**:在 `agents.list` 明確加入 `main` agent,並在 `bindings` 加入 `default → main` 綁定:
|
||||
|
||||
```json
|
||||
"agents": {
|
||||
"list": [
|
||||
{
|
||||
"id": "main",
|
||||
"name": "主 Agent",
|
||||
"model": { "primary": "cliapi/gpt-5.3-codex" },
|
||||
"workspace": "/home/selig/.openclaw/workspace"
|
||||
},
|
||||
{ "id": "life-assistant", "..." }
|
||||
]
|
||||
},
|
||||
"bindings": [
|
||||
{ "agentId": "main", "match": { "channel": "telegram", "accountId": "default" } },
|
||||
{ "agentId": "life-assistant", "match": { "channel": "telegram", "accountId": "life-bot" } }
|
||||
]
|
||||
```
|
||||
|
||||
修改後重啟:`systemctl --user restart openclaw-gateway`
|
||||
|
||||
**驗證**:檢查啟動 log 是否有 workspace skills 的 sanitization 記錄:
|
||||
```bash
|
||||
journalctl --user -u openclaw-gateway --since "1 min ago" --no-pager | grep daily-briefing
|
||||
```
|
||||
|
||||
### 4.8 OpenClaw WebUI 配對問題
|
||||
|
||||
**症狀**:`https://oclaw.nature.edu.kg/#token=...` 顯示 "backend not paired yet"
|
||||
|
||||
**修復**:在後端核准配對請求
|
||||
```bash
|
||||
sudo openclaw devices list # 查看 pending request ID
|
||||
sudo openclaw devices approve <request-id>
|
||||
```
|
||||
|
||||
### 4.9 升級 2026.2.25 後 Gateway 啟動失敗(2026-02-27)
|
||||
|
||||
**症狀**:`Error: Unsafe fallback OpenClaw temp dir: /tmp/openclaw-1000`
|
||||
|
||||
**根因**:新版加強 temp 目錄安全檢查,要求 `/tmp/openclaw-<UID>` 權限必須 `700`(owner-only),舊版建立的目錄權限為 `775`。
|
||||
|
||||
**修復**:
|
||||
```bash
|
||||
chmod 700 /tmp/openclaw-1000 # selig (UID 1000)
|
||||
# root 的 temp dir 也需清理
|
||||
sudo rm -rf /tmp/openclaw-0 && sudo mkdir -p /tmp/openclaw-0 && sudo chmod 700 /tmp/openclaw-0
|
||||
```
|
||||
|
||||
### 4.10 升級後 `google-antigravity-auth` plugin 警告(2026-02-27)
|
||||
|
||||
**症狀**:`plugin removed: google-antigravity-auth (stale config entry ignored)`
|
||||
|
||||
**根因**:`google-antigravity-auth` plugin 已從 2026.2.25 移除,但 `openclaw.json` 仍有殘留設定。
|
||||
|
||||
**修復**:從 `openclaw.json` 的 `plugins.entries` 刪除 `google-antigravity-auth` 條目。此 plugin 用於 OpenClaw 直連 Google API 認證,與 CLIProxyAPI 代理的 Gemini 模型無關。
|
||||
|
||||
### 4.11 `sudo openclaw skills list` 偵測不到 selig 環境的 CLI(2026-02-27)
|
||||
|
||||
**症狀**:`coding-agent` 和 `summarize` 顯示 `✗ missing`,但實際 CLI 已安裝。
|
||||
|
||||
**根因**:`sudo openclaw` 以 root 執行,PATH 不含 selig 的 `~/.local/bin` 和 nvm 路徑。
|
||||
|
||||
**修復**:使用 `openclaw skills list`(不加 sudo)即可正確偵測。Gateway 以 selig user service 運行,不受影響。
|
||||
|
||||
### 4.12 Browser control 連線逾時(2026-03-02)
|
||||
|
||||
**症狀**:Telegram Agent 嘗試操控瀏覽器時報 `Browser control service 連線逾時(15 秒)`
|
||||
|
||||
**根因**(多層問題):
|
||||
1. **Node service 未安裝**:OpenClaw 的瀏覽器控制需要 Node Host service 作為 Gateway 和本機瀏覽器之間的 relay
|
||||
2. **Node service 未配對**:首次連線 Gateway 時需經過 device pairing 核准
|
||||
3. **缺少 DISPLAY 環境變數**:Gateway 和 Node service 的 systemd unit 都沒有 `DISPLAY=:99`,導致無法操控 Xvfb 上的瀏覽器
|
||||
4. **Snap Chromium 限制**:Ubuntu snap 版 Chromium 的包裝器會剝掉 `--load-extension` 和 `--remote-debugging-port` 旗標,無法載入 OpenClaw 擴充套件或啟用 CDP
|
||||
|
||||
**修復**:
|
||||
```bash
|
||||
# 1. 安裝 Node service 並加入 DISPLAY
|
||||
openclaw node install
|
||||
# 編輯 ~/.config/systemd/user/openclaw-node.service 加入 Environment=DISPLAY=:99
|
||||
|
||||
# 2. 在 gateway.env 加入 DISPLAY,Gateway service 也要加
|
||||
echo 'DISPLAY=:99' >> ~/.config/openclaw/gateway.env
|
||||
# 編輯 ~/.config/systemd/user/openclaw-gateway.service 加入 Environment=DISPLAY=:99
|
||||
|
||||
# 3. 啟動 Node service 並配對
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now openclaw-node.service
|
||||
openclaw devices list # 等待 pending request
|
||||
openclaw devices approve <id> # 核准
|
||||
|
||||
# 4. 改用 Playwright Chromium(非 snap,支援 CDP 直連)
|
||||
# 建立 playwright-chrome.service 並啟用
|
||||
systemctl --user enable --now playwright-chrome.service
|
||||
|
||||
# 5. 建立 cdp-direct profile 設為預設
|
||||
openclaw browser create-profile --name cdp-direct --cdp-url http://127.0.0.1:18801
|
||||
# openclaw.json → browser.defaultProfile: "cdp-direct"
|
||||
|
||||
# 6. 重啟 Gateway
|
||||
systemctl --user restart openclaw-gateway
|
||||
```
|
||||
|
||||
### 4.16 Agent browser tool timeout — `openclaw` profile 啟動失敗(2026-03-11)
|
||||
|
||||
**症狀**:CLI 的 `openclaw browser navigate` 正常,但 Agent 透過 tool call 使用瀏覽器時 15 秒 timeout:
|
||||
```
|
||||
[tools] browser failed: timed out. Restart the OpenClaw gateway...
|
||||
```
|
||||
|
||||
**根因**:v2026.3.7 內建了 `openclaw` browser profile(port 18800),Gateway 啟動時會嘗試用 `detectedPath`(`/usr/bin/chromium-browser`,snap 版)啟動這個 profile。snap Chromium 會剝掉 `--remote-debugging-port` 參數,導致 CDP 永遠無法建立。`openclaw browser profiles` 顯示此 profile 為 `stopped` 狀態。
|
||||
|
||||
**關鍵差異**:CLI 指令走 `defaultProfile`(cdp-direct),但 agent tool call 可能嘗試使用 `openclaw` profile。
|
||||
|
||||
**修復**:
|
||||
1. 在 `openclaw.json` 的 `browser.profiles` 覆寫 `openclaw` profile,讓它指向 Playwright CDP:
|
||||
```json
|
||||
{
|
||||
"browser": {
|
||||
"profiles": {
|
||||
"openclaw": {
|
||||
"cdpUrl": "http://127.0.0.1:18801",
|
||||
"color": "#FF4500"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
2. 確認 Gateway service 有 `Environment=DISPLAY=:99`(`~/.config/systemd/user/openclaw-gateway.service`)
|
||||
|
||||
**驗證**:
|
||||
```bash
|
||||
openclaw browser profiles
|
||||
# 三個 profile(cdp-direct、chrome、openclaw)都應顯示 running,port 18801
|
||||
```
|
||||
|
||||
### 4.13 Node.js 24 undici autoSelectFamily 導致 Telegram 連線逾時(2026-03-02)
|
||||
|
||||
**症狀**:Gateway 重啟後 Telegram 持續 `Network request failed`,但 `curl` 可正常連線 Telegram API
|
||||
|
||||
**根因**:Node.js 24 的 `fetch()`(undici)有 `autoSelectFamily`(happy eyeballs),會同時嘗試 IPv4/IPv6。即使系統 sysctl 停用 IPv6 + `NODE_OPTIONS=--dns-result-order=ipv4first`,OpenClaw 內部(`ssrf-D_av5wos.js`)hardcode `autoSelectFamily: true`,覆蓋了 NODE_OPTIONS。
|
||||
|
||||
**修復**:在 `openclaw.json` 用 config 層級覆蓋:
|
||||
```json
|
||||
{
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"network": {
|
||||
"autoSelectFamily": false,
|
||||
"dnsResultOrder": "ipv4first"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
同時在 `gateway.env` 的 NODE_OPTIONS 加入 `--no-network-family-autoselection`(雙保險)。
|
||||
|
||||
**驗證**:Gateway log 應顯示 `autoSelectFamily=false (config)`
|
||||
|
||||
### 4.14 GPU driver suspend/resume 死鎖導致 Bot 全卡(2026-03-02)
|
||||
|
||||
**症狀**:所有 Telegram Bot 收到訊息後無回應,`nvidia-smi` 掛起不返回
|
||||
|
||||
**根因(三層連鎖故障)**:
|
||||
1. **系統觸發 suspend/resume** → `nvidia-sleep.sh` 在 kernel 的 `uvm_suspend()` 死鎖(狀態 `Ds` 不可中斷)
|
||||
2. **GPU driver 無法存取** → llama-embed 的 port 11435 雖然 listen,但 embedding 請求永遠無回應
|
||||
3. **memory-lancedb-pro 的 `before_agent_start` hook 阻塞** → 每個 agent 啟動時呼叫 embedding API 做 autoRecall,因 llama-embed 無回應而無限等待,導致所有 agent 卡死
|
||||
|
||||
**診斷流程**:
|
||||
```bash
|
||||
# 1. 確認 GPU 死鎖
|
||||
timeout 5 nvidia-smi || echo "GPU driver 死鎖"
|
||||
|
||||
# 2. 確認 llama-embed 無回應
|
||||
timeout 5 curl -s http://127.0.0.1:11435/v1/embeddings \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"input":"test","model":"nomic-embed-text-v1.5"}' || echo "embedding 無回應"
|
||||
|
||||
# 3. 確認殘留 process
|
||||
ps aux | grep nvidia-sleep # 看到 Ds 狀態 = 死鎖
|
||||
ps aux | grep llama-server # 可能有殘留舊 process 占住 port
|
||||
```
|
||||
|
||||
**緊急修復(免重開機讓 Bot 恢復)**:
|
||||
```bash
|
||||
# 關閉 autoRecall,讓 agent 不依賴 embedding 即可啟動
|
||||
openclaw config set plugins.entries.memory-lancedb-pro.config.autoRecall false
|
||||
# Gateway 會自動偵測 config 變更並重啟
|
||||
```
|
||||
|
||||
**根治**:重開機修復 GPU driver
|
||||
|
||||
**預防**:停用系統休眠
|
||||
```bash
|
||||
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
|
||||
```
|
||||
|
||||
### 4.15 Embedding 容錯策略(2026-03-02)
|
||||
|
||||
llama-embed(GPU)是唯一的 production embedding 路徑。Ollama CPU 模式雖有 `nomic-embed-text`(port 11434,~1.4s/call),但在 4 核心 + 高 load 系統上會拖垮效能,**不適合作為常態 fallback**。
|
||||
|
||||
**容錯層級**(由 `~/clawd/scripts/embed-health.sh` 自動執行,cron */30 分鐘,2026-03-02 已實作):
|
||||
|
||||
| 層級 | 條件 | 動作 |
|
||||
|------|------|------|
|
||||
| 正常 | llama-embed port 11435 回應 < 2s | `autoRecall: true`, `autoCapture: true` |
|
||||
| 降級 | llama-embed 無回應或逾時 | 自動設定 `autoRecall: false`, `autoCapture: false`;Telegram 通知使用者 |
|
||||
| 恢復 | 重開機後 llama-embed 恢復 | 自動設定 `autoRecall: true`, `autoCapture: true`;Telegram 通知 |
|
||||
|
||||
**設計原則**:
|
||||
- 不使用 Ollama CPU fallback(CPU 資源不足)
|
||||
- 不使用線上 embedding API(隱私考量 + 增加外部依賴)
|
||||
- embedding 掛了 = 記憶暫停,不影響 Bot 核心回覆功能
|
||||
- 健康檢查腳本放入 crontab 每 30 分鐘執行
|
||||
155
chapters/05-agents.md
Normal file
155
chapters/05-agents.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 5. Agent Team 架構設計
|
||||
|
||||
### 5.1 行動任務 Team
|
||||
|
||||
#### 架構圖
|
||||
|
||||
```
|
||||
使用者 (Telegram)
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ OpenClaw (x550v) │
|
||||
│ Skill 庫:assign-task, dispatch-webhook, │
|
||||
│ project-review, code-review │
|
||||
│ │ │
|
||||
│ ┌──────────▼──────────┐ │
|
||||
│ │ 主 Agent (main) │ │
|
||||
│ │ Model: Gemini Flash│ │
|
||||
│ │ 收 Telegram 訊息 │ │
|
||||
│ └──────┬──────────────┘ │
|
||||
└────────────────┼─────────────────────────────────┘
|
||||
│ 分派任務(Skill / Webhook / API)
|
||||
┌────────┴────────────────┐
|
||||
│ │
|
||||
┌───────▼──────────┐ ┌──────────▼─────────────┐
|
||||
│ VPS-A │ │ VPS-B │
|
||||
│ Claude Code │ │ OpenCode / Other LLMs │
|
||||
│ (Opus/Sonnet) │ │ (Codex / Gemini / …) │
|
||||
│ │ │ │
|
||||
│ 角色:專案經理 │ │ 角色:專案經理/執行者 │
|
||||
│ ・主要專案開發 │ │ ・其他專案開發 │
|
||||
│ ・Webhook 接收 │ │ ・Webhook 接收 │
|
||||
│ ・回報結果 │ │ ・回報結果 │
|
||||
└──────────────────┘ └────────────────────────┘
|
||||
│ │
|
||||
└──────────┬──────────────┘
|
||||
▼
|
||||
執行結果回傳 Telegram
|
||||
```
|
||||
|
||||
#### 角色說明
|
||||
|
||||
| 角色 | 模型 | 位置 | 職責 |
|
||||
|------|------|------|------|
|
||||
| 協調者 (Coordinator) | Gemini Flash | OpenClaw x550v | 接收需求,分派任務,彙整回報 |
|
||||
| 專案經理-A (PM-A) | Claude Code Opus | VPS-A | 主要專案規劃、架構設計、任務分派 |
|
||||
| 專案經理-B (PM-B) | OpenCode Codex | VPS-B | 其他專案規劃、多 LLM 調度 |
|
||||
| 開發執行者 | Sonnet / Gemini / 其他 | VPS-A/B | 實際寫程式、測試、文件 |
|
||||
|
||||
#### 任務流程
|
||||
|
||||
```
|
||||
1. 使用者在 Telegram 描述任務
|
||||
│
|
||||
2. OpenClaw 主 agent 接收,判斷任務類型
|
||||
│
|
||||
3. 呼叫 assign-task skill:
|
||||
├── 主要專案 → 觸發 VPS-A Webhook (Claude Code)
|
||||
└── 其他專案 → 觸發 VPS-B Webhook (OpenCode)
|
||||
│
|
||||
4. PM 接收任務,制定計劃,分派給執行者
|
||||
│
|
||||
5. 執行者完成任務,回報 PM
|
||||
│
|
||||
6. PM 整理結果,透過 API 回傳 OpenClaw
|
||||
│
|
||||
7. OpenClaw 回報使用者(Telegram)
|
||||
```
|
||||
|
||||
#### Webhook 設計
|
||||
|
||||
**VPS-A Webhook Endpoint**(Claude Code 接收端)
|
||||
```
|
||||
POST https://vps-a.example.com/webhook/openclaw
|
||||
Headers:
|
||||
X-OpenClaw-Token: <shared-secret>
|
||||
Content-Type: application/json
|
||||
|
||||
Body:
|
||||
{
|
||||
"task_id": "task-uuid",
|
||||
"type": "project_development",
|
||||
"project": "project-name",
|
||||
"description": "任務描述",
|
||||
"priority": "high|normal|low",
|
||||
"context": { ... },
|
||||
"callback_url": "https://oclaw.nature.edu.kg/webhook/callback",
|
||||
"callback_token": "<session-token>"
|
||||
}
|
||||
```
|
||||
|
||||
**回傳格式**
|
||||
```json
|
||||
{
|
||||
"task_id": "task-uuid",
|
||||
"status": "completed|failed|in_progress",
|
||||
"summary": "執行摘要",
|
||||
"artifacts": ["file1.py", "README.md"],
|
||||
"next_steps": ["部署測試", "code review"]
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 生活安排 Team
|
||||
|
||||
#### 架構圖
|
||||
|
||||
```
|
||||
使用者 (Telegram)
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ OpenClaw 生活安排 Agent │
|
||||
│ Model: Gemini Flash / Claude Sonnet │
|
||||
│ │
|
||||
│ Skill 庫: │
|
||||
│ ・calendar-check 行事曆查詢 │
|
||||
│ ・schedule-plan 行程規劃 │
|
||||
│ ・daily-briefing 每日摘要 │
|
||||
│ ・reminder-set 提醒設定 │
|
||||
│ ・task-capture 快速記錄待辦 │
|
||||
└──────────────────────────────────────────────┘
|
||||
│
|
||||
├── Google Calendar API
|
||||
├── 天氣 API
|
||||
├── cron (OpenClaw 內建排程)
|
||||
└── Telegram 推送
|
||||
```
|
||||
|
||||
#### 功能說明
|
||||
|
||||
| 功能 | 觸發方式 | 說明 |
|
||||
|------|---------|------|
|
||||
| 每日簡報 | cron 每早 8:00 | 今日行程 + 天氣 + 待辦摘要 |
|
||||
| 行程安排 | Telegram 指令 | 新增/查詢 Google Calendar |
|
||||
| 提醒設定 | Telegram 指令 | 設定 cron job 定時提醒 |
|
||||
| 快速待辦 | Telegram 指令 | 記錄到 workspace/TODO.md |
|
||||
| 週報 | cron 每週日晚 | 本週完成事項彙整 |
|
||||
|
||||
#### Cron Job 設定範例
|
||||
|
||||
```bash
|
||||
# 每日 8:00 早安簡報
|
||||
openclaw cron add \
|
||||
--name "daily-briefing" \
|
||||
--cron "0 8 * * *" \
|
||||
--session main \
|
||||
--system-event "請執行每日簡報:查詢今日行程、天氣,整理待辦事項,用繁體中文發送到 Telegram"
|
||||
|
||||
# 每週日 21:00 週報
|
||||
openclaw cron add \
|
||||
--name "weekly-review" \
|
||||
--cron "0 21 * * 0" \
|
||||
--session main \
|
||||
--system-event "請整理本週完成的工作、學習重點,以及下週計劃,發送週報到 Telegram"
|
||||
```
|
||||
421
chapters/06-config.md
Normal file
421
chapters/06-config.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# 6. OpenClaw 設定參考
|
||||
|
||||
### 6.1 主設定結構 `/root/.openclaw/openclaw.json`
|
||||
|
||||
```json5
|
||||
{
|
||||
"meta": { "lastTouchedVersion": "2026.2.25" },
|
||||
|
||||
// Agent 預設設定
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "google-antigravity/gemini-3-flash"
|
||||
},
|
||||
"workspace": "/root/.openclaw/workspace",
|
||||
"compaction": { "mode": "safeguard" },
|
||||
"maxConcurrent": 4,
|
||||
"subagents": { "maxConcurrent": 8 }
|
||||
}
|
||||
},
|
||||
|
||||
// Telegram 頻道
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"botToken": "<your-bot-token>",
|
||||
"dmPolicy": "pairing", // 只有配對裝置可以 DM
|
||||
"groupPolicy": "allowlist",
|
||||
"streamMode": "partial"
|
||||
}
|
||||
},
|
||||
|
||||
// Gateway 設定
|
||||
"gateway": {
|
||||
"port": 18789,
|
||||
"mode": "local",
|
||||
"bind": "loopback", // 只接受本機連線,由 nginx 代理
|
||||
"auth": {
|
||||
"mode": "token",
|
||||
"token": "<access-token>"
|
||||
}
|
||||
},
|
||||
|
||||
// 訊息設定
|
||||
"messages": {
|
||||
"ackReactionScope": "group-mentions"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 多 Agent / 多模型設定(獨立 Bot Token 方案)
|
||||
|
||||
> **踩坑紀錄(2026-02-24 ~ 02-25,v2026.2.17)**
|
||||
> - 文件範例用 `agentId`,但實際 schema 要用 **`id`**(否則報 `Unrecognized key: "agentId"`)
|
||||
> - `bindings` 需要 **`match` 包裝層**,不是直接放 `channel` / `accountId`
|
||||
> - 新 Bot 必須**先完成 config + 重啟 Gateway 後**才按 `/start`,否則配對碼不會回傳
|
||||
> - 各獨立 agent 的 `auth-profiles.json` 不會自動共享,需手動複製
|
||||
> - **(2026-02-25 新增)** 當使用 `accounts` 區塊後,頂層 `botToken` **不再被當作獨立通道啟動**。所有 Bot(包含主 Bot)都必須放入 `accounts` 內,否則 `channels list` 不會列出、provider 也不會啟動。主 Bot 建議使用 `"default"` 作為 accountId。
|
||||
> - **(2026-02-25 新增)** `agents.list` 只有具名 agent(如 life-assistant)時,**隱含的預設 agent 不會掃描 workspace skills**。必須在 `agents.list` 明確加入 `main` agent(含 workspace 路徑),並在 `bindings` 加入 `{ "agentId": "main", "match": { "channel": "telegram", "accountId": "default" } }` 綁定。否則 workspace skills(如 daily-briefing)不會載入。
|
||||
|
||||
#### 正確的 config 格式(已驗證可用)
|
||||
|
||||
```json5
|
||||
{
|
||||
// 1. channels:所有 Bot Token 都放在 accounts 下
|
||||
// 頂層 botToken 在使用 accounts 後不再啟動為獨立通道
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"dmPolicy": "pairing",
|
||||
"groupPolicy": "allowlist",
|
||||
"streamMode": "partial",
|
||||
"accounts": {
|
||||
"default": { // 主 Bot(@Cimon168_bot)
|
||||
"botToken": "<主 Bot Token>"
|
||||
},
|
||||
"life-bot": { // accountId,自訂名稱
|
||||
"botToken": "<新 Bot Token>" // @Cimon_life_bot
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 2. agents.list:用 "id" 不是 "agentId"
|
||||
// 主 agent 也必須明確列出,否則 workspace skills 不會載入
|
||||
"agents": {
|
||||
"list": [
|
||||
{
|
||||
"id": "main", // 主 agent,必須明確列出
|
||||
"name": "主 Agent",
|
||||
"model": { "primary": "cliapi/gpt-5.3-codex" },
|
||||
"workspace": "/home/selig/.openclaw/workspace"
|
||||
},
|
||||
{
|
||||
"id": "life-assistant", // <- 必須用 "id"
|
||||
"name": "生活助理",
|
||||
"model": { "primary": "cliapi/gpt-5.3-codex" },
|
||||
"workspace": "/home/selig/.openclaw/agents/life-assistant"
|
||||
}
|
||||
],
|
||||
"defaults": { "..." }
|
||||
},
|
||||
|
||||
// 3. bindings:match 包裝層(channel + accountId 放 match 內)
|
||||
// 每個 account 都需要綁定到對應 agent
|
||||
"bindings": [
|
||||
{
|
||||
"agentId": "main", // 主 Bot → main agent
|
||||
"match": {
|
||||
"channel": "telegram",
|
||||
"accountId": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"agentId": "life-assistant", // 這裡用 agentId
|
||||
"match": { // <- 必須有 match 物件
|
||||
"channel": "telegram",
|
||||
"accountId": "life-bot" // 對應 accounts 裡的 key
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 安裝步驟
|
||||
|
||||
```bash
|
||||
# 1. BotFather /newbot → 取得 Token
|
||||
# 2. 建立 agent 目錄
|
||||
mkdir -p ~/.openclaw/agents/<agent-name>/{agent,sessions}
|
||||
# 3. 修改 ~/.openclaw/openclaw.json(按上方格式)
|
||||
# 4. 重啟 Gateway
|
||||
systemctl --user restart openclaw-gateway
|
||||
# 5. 確認 log 無錯誤
|
||||
journalctl --user -u openclaw-gateway --since "30 sec ago" --no-pager
|
||||
# 6. 在 Telegram 新 Bot 發送 /start → 取得配對碼
|
||||
# 7. 配對
|
||||
openclaw pairing approve telegram <CODE>
|
||||
```
|
||||
|
||||
#### 目前已部署的 Agent
|
||||
|
||||
| Agent ID | Bot | 用途 | Model |
|
||||
|----------|-----|------|-------|
|
||||
| main | @Cimon168_bot | 工作/專案/協調 | cliapi/gpt-5.3-codex |
|
||||
| life-assistant | @Cimon_life_bot | 生活安排 | cliapi/gpt-5.3-codex |
|
||||
|
||||
### 6.3 CLIProxyAPI 連線設定
|
||||
|
||||
CLIProxyAPI 作為 OpenAI-compatible proxy,讓 OpenClaw 可以使用多種 AI 帳號:
|
||||
|
||||
```json5
|
||||
// 在 openclaw.json 加入 custom provider
|
||||
{
|
||||
"models": {
|
||||
"providers": {
|
||||
"cliapi": {
|
||||
"baseUrl": "http://127.0.0.1:8317/v1",
|
||||
"apiKey": "<management-key>",
|
||||
"api": "openai-completions"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
CLIProxyAPI 管理介面:`http://192.168.31.169:8317/management.html`
|
||||
|
||||
### 6.3.1 CLIProxyAPI LLM 輪換規則
|
||||
|
||||
> 原始碼位置:`sdk/cliproxy/auth/selector.go`、`config.yaml`
|
||||
|
||||
#### 輪換策略:Round-Robin(按請求次數)
|
||||
|
||||
**不是依時間輪換**,而是每一個 API request 進來就推進一格。
|
||||
|
||||
```
|
||||
每個 (provider, model) 組合 → 獨立計數器 (cursor)
|
||||
cursor → 每次請求 +1
|
||||
選取:available[cursor % len(available)]
|
||||
```
|
||||
|
||||
目前設定(`/home/docker/CLIProxyAPI/config.yaml`):
|
||||
|
||||
```yaml
|
||||
routing:
|
||||
strategy: "round-robin" # 另一選項:fill-first(固定燒第一個帳號)
|
||||
request-retry: 3 # 失敗後最多重試 3 次(自動換下一個憑證)
|
||||
max-retry-interval: 30 # 冷卻等待上限 30 秒
|
||||
quota-exceeded:
|
||||
switch-project: true # Quota 超限時自動切換帳號
|
||||
switch-preview-model: true
|
||||
```
|
||||
|
||||
#### 失敗重試(Fallback)
|
||||
|
||||
觸發條件(HTTP 狀態碼):`403 / 408 / 500 / 502 / 503 / 504`
|
||||
|
||||
- 遇到錯誤 → cursor 繼續推進 → 下次自動選到不同憑證
|
||||
- 不是獨立的「備援」邏輯,而是 round-robin 繼續走的自然結果
|
||||
|
||||
#### 冷卻機制(Quota 超限)
|
||||
|
||||
- 憑證觸發 **429** → 進入冷卻,指數退避(底數 1s,上限 30min)
|
||||
- 冷卻中的憑證從可用池排除,round-robin 只從未冷卻憑證中選
|
||||
- 冷卻時間到後自動恢復可用
|
||||
|
||||
#### 活躍 Provider(目前)
|
||||
|
||||
| Provider | 模型類型 |
|
||||
|----------|---------|
|
||||
| Grok (xai) | grok-4 系列、grok-code、grok-imagine |
|
||||
| api.navy | qwen3.5、claude-sonnet-4.6、text-embedding |
|
||||
|
||||
### 6.3.2 CLIProxyAPI 模型清單自動更新
|
||||
|
||||
當 CLIProxyAPI 新增/移除 AI provider 後,OpenClaw 不會自動偵測到新模型。需要更新 `openclaw.json` 中的 `models.providers.cliapi.models` 陣列。
|
||||
|
||||
**自動更新腳本**:`~/clawd/scripts/refresh-llm-list.sh`
|
||||
|
||||
```bash
|
||||
# 手動執行
|
||||
bash ~/clawd/scripts/refresh-llm-list.sh
|
||||
|
||||
# 排程:每週日 02:00(crontab)
|
||||
0 2 * * 0 /home/selig/clawd/scripts/refresh-llm-list.sh >> /var/log/refresh-llm-list.log 2>&1
|
||||
```
|
||||
|
||||
**腳本流程**:
|
||||
1. 從 CLIProxyAPI `/v1/models` 取得最新模型清單
|
||||
2. 依模型名稱自動分級(high/mid/low → 不同 cost 設定)
|
||||
3. 備份 `openclaw.json` → `openclaw.json.bak`
|
||||
4. 更新模型陣列,保留其他設定不變
|
||||
5. 重啟 Gateway
|
||||
6. 輸出差異(新增/移除的模型)
|
||||
|
||||
**日誌**:`/var/log/refresh-llm-list.log`
|
||||
|
||||
**模型分級規則**:
|
||||
| 級別 | 關鍵字 | input cost | contextWindow |
|
||||
|------|--------|-----------|---------------|
|
||||
| high | opus, pro-high, thinking, codex-max, pro-preview | 0.3 | 1M |
|
||||
| mid | sonnet, grok, qwen, 預設 | 0.14 | 128K |
|
||||
| low | haiku, flash-lite, embedding, mini | 0.07 | 128K |
|
||||
| GPT | gpt-* | 0.2 | 128K |
|
||||
|
||||
### 6.3.3 發送 Telegram 訊息(通知 Agent)
|
||||
|
||||
```bash
|
||||
# 發送訊息到指定群組或用戶
|
||||
sudo openclaw message send --channel telegram --target <chat-id> -m "訊息內容"
|
||||
|
||||
# 群組 ID 對照
|
||||
# kaiwu(開物):-5178404192
|
||||
# tiangong(天工):-5249018181
|
||||
# yucheng(玉成):-5296222979
|
||||
|
||||
# 範例:通知開物群組
|
||||
sudo openclaw message send --channel telegram --target -5178404192 -m "preview 網站已上線"
|
||||
|
||||
# 附帶圖片
|
||||
sudo openclaw message send --channel telegram --target -5178404192 -m "截圖" --media /path/to/image.png
|
||||
|
||||
# 靜音發送(不觸發通知音)
|
||||
sudo openclaw message send --channel telegram --target -5178404192 -m "背景通知" --silent
|
||||
```
|
||||
|
||||
### 6.4 Session Scope 設定
|
||||
|
||||
```json5
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"session": {
|
||||
// 推薦:每個 Telegram 用戶獨立 session,防止資訊洩漏
|
||||
"dmScope": "per-channel-peer",
|
||||
// 每日 04:00 自動重置 session
|
||||
"reset": { "schedule": "0 4 * * *" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.5 Auth Profiles(模型認證)
|
||||
|
||||
位置:`/root/.openclaw/agents/main/auth-profiles.json`
|
||||
|
||||
```json5
|
||||
{
|
||||
"version": 1,
|
||||
"profiles": {
|
||||
"anthropic:manual": {
|
||||
"type": "token",
|
||||
"provider": "anthropic",
|
||||
"token": "sk-ant-..."
|
||||
},
|
||||
"cliapi:main": {
|
||||
"type": "api-key",
|
||||
"provider": "openai-compat",
|
||||
"apiKey": "<key>",
|
||||
"baseUrl": "http://127.0.0.1:8317/v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.6 Heartbeat(心跳巡查)
|
||||
|
||||
Agent 定期自動觸發巡查,執行 `HEARTBEAT.md` 中定義的任務。
|
||||
|
||||
**預設間隔**(原始碼邏輯):
|
||||
- `gateway.auth.mode = "oauth"` → `1h`
|
||||
- 其他模式(token、local) → `30m`
|
||||
|
||||
**設定方式**:
|
||||
```json5
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"heartbeat": {
|
||||
"every": "30m" // 所有 agent 預設間隔(支援 "15m", "1h", "2h" 等)
|
||||
}
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "main",
|
||||
"heartbeat": {
|
||||
"every": "15m" // 個別 agent 覆寫
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**指令**:
|
||||
```bash
|
||||
# 查看目前設定
|
||||
openclaw config get agents.defaults.heartbeat
|
||||
|
||||
# 修改全域間隔
|
||||
openclaw config set agents.defaults.heartbeat.every "15m"
|
||||
|
||||
# 修改單一 agent(需知道 list index,如 main 是 index 0)
|
||||
openclaw config set agents.list.0.heartbeat.every "20m"
|
||||
```
|
||||
|
||||
**巡查內容**:定義在各 agent workspace 的 `HEARTBEAT.md`,例如:
|
||||
- `~/.openclaw/workspace/HEARTBEAT.md`(主 agent)
|
||||
- `~/.openclaw/agents/life-assistant/HEARTBEAT.md`(生活助理)
|
||||
|
||||
**Telegram 頻道 heartbeat 可見性**:
|
||||
```json5
|
||||
{
|
||||
"channels": {
|
||||
"telegram": {
|
||||
"heartbeat": "silent" // "visible" | "silent" | "hidden"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.7 Exec Approvals(指令執行審批)
|
||||
|
||||
Agent 執行 shell 指令(`exec` tool)時的安全策略。**兩個地方都需要設定**:
|
||||
|
||||
#### 主控制:`openclaw.json` → `tools.exec`
|
||||
|
||||
這是**真正的 policy 控制點**,決定 agent 能否自動執行指令:
|
||||
|
||||
```json5
|
||||
{
|
||||
"tools": {
|
||||
"exec": {
|
||||
"security": "full", // "deny" | "allowlist" | "full"
|
||||
"ask": "off" // "off" | "on-miss" | "always"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| security | 行為 |
|
||||
|----------|------|
|
||||
| `deny` | 封鎖所有 exec(sandbox 預設) |
|
||||
| `allowlist` | 只允許白名單內的指令(**gateway/node 未設時的預設值**) |
|
||||
| `full` | 允許所有指令 |
|
||||
|
||||
| ask | 行為 |
|
||||
|-----|------|
|
||||
| `off` | 永不詢問 |
|
||||
| `on-miss` | 指令不在白名單時才詢問(**預設值**) |
|
||||
| `always` | 每次都詢問 |
|
||||
|
||||
```bash
|
||||
# 設定指令
|
||||
openclaw config set tools.exec.security full
|
||||
openclaw config set tools.exec.ask off
|
||||
# 重啟 Gateway 生效
|
||||
systemctl --user restart openclaw-gateway
|
||||
```
|
||||
|
||||
#### 輔助儲存:`~/.openclaw/exec-approvals.json`
|
||||
|
||||
儲存 allowlist(已核准的指令清單)和 socket 資訊,**不是主要 policy 控制點**:
|
||||
|
||||
```bash
|
||||
# 查看
|
||||
openclaw approvals get
|
||||
# 設定(覆寫整個檔案)
|
||||
openclaw approvals set --stdin < file.json
|
||||
```
|
||||
|
||||
> **踩坑(2026-03-02)**:只設定 `exec-approvals.json` 的 `defaults.security=full` + `defaults.ask=off` **不會生效**。必須在 `openclaw.json` 的 `tools.exec` 設定才是真正的控制點。未設定 `tools.exec` 時,預設為 `security: "allowlist"` + `ask: "on-miss"`,導致 Telegram agent 每次執行指令都需要手動批准,而 Telegram 無法批准 → 120 秒超時。
|
||||
|
||||
#### Safe Bins(免審批的安全指令)
|
||||
|
||||
以下 stdin-only 工具即使在 `allowlist` 模式下也不需要白名單:
|
||||
- `jq`, `cat`, `head`, `tail`, `cut`, `uniq`, `tr`, `wc`
|
||||
- 可透過 `tools.exec.safeBins` 自訂
|
||||
- 信任目錄:`/bin`, `/usr/bin`(可透過 `tools.exec.safeBinTrustedDirs` 擴充)
|
||||
140
chapters/07-skills.md
Normal file
140
chapters/07-skills.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# 7. Skill 庫說明
|
||||
|
||||
Skills 位置:`~/.openclaw/workspace/skills/` 或 OpenClaw 官方 skill 庫
|
||||
|
||||
### 7.1 行動任務 Skills
|
||||
|
||||
| Skill | 功能 | 觸發方式 |
|
||||
|-------|------|---------|
|
||||
| `assign-task` | 分析任務,分派給 VPS-A 或 VPS-B | 使用者描述任務 |
|
||||
| `dispatch-webhook` | 發送 Webhook 到 VPS,等待回應 | assign-task 呼叫 |
|
||||
| `project-status` | 查詢進行中的專案狀態 | 使用者查詢 |
|
||||
| `code-review-request` | 提交 code review 請求 | 開發完成後 |
|
||||
|
||||
### 7.2 生活安排 Skills
|
||||
|
||||
| Skill | 功能 | 觸發方式 |
|
||||
|-------|------|---------|
|
||||
| `daily-briefing` | 每日簡報(行程+天氣+待辦) | cron 08:00 |
|
||||
| `calendar-check` | 查詢 Google Calendar | 使用者查詢 |
|
||||
| `schedule-plan` | 安排行程 | 使用者指令 |
|
||||
| `reminder-set` | 設定定時提醒 | 使用者指令 |
|
||||
| `task-capture` | 快速記錄待辦 | 使用者指令 |
|
||||
|
||||
### 7.3 ClawHub Skills(已安裝)
|
||||
|
||||
| Skill | 功能 | 來源 | 備註 |
|
||||
|-------|------|------|------|
|
||||
| `skill-vetter` | 安裝前安全審查(檢查權限範圍、可疑模式、風險分級) | ClawHub | 純指引型,無需額外設定 |
|
||||
| `tavily-tool` | Tavily 網頁搜尋/探索,附來源引用摘要 | ClawHub | 需 `TAVILY_API_KEY`(已設於 `gateway.env`,透過 `EnvironmentFile` 載入) |
|
||||
|
||||
> **ClawHub 帳號**:`@selika`(GitHub: sovaha@gmail.com),登入方式:`npx clawhub login --token <token> --no-browser`
|
||||
> **Python 依賴**:`tavily-python 0.7.23`(已安裝於 `~/.openclaw/venv/`)
|
||||
> **踩坑**(2026-03-11):Gateway service 原本沒有 `EnvironmentFile`,`gateway.env` 的變數不會進入 Gateway 進程。修復:service 加 `EnvironmentFile=/home/selig/.config/openclaw/gateway.env`
|
||||
> **踩坑**(2026-03-11):skill 用 symlink 分發到 agent workspace 會被 Gateway 安全機制擋掉(`Skipping skill path that resolves outside its configured root`),必須用 `cp -r` 複製
|
||||
|
||||
### 7.4 Bundled Skills(已啟用)
|
||||
|
||||
| Skill | 功能 | 依賴 CLI | 備註 |
|
||||
|-------|------|---------|------|
|
||||
| `coding-agent` | 分派 coding 任務給 Claude Code/Codex/OpenCode | `claude`(`~/.local/bin/claude`) | 需 bash pty:true |
|
||||
| `summarize` | 摘要 URL/影片/Podcast 內容 | `summarize`(`~/.local/bin/summarize` → nvm) | `@steipete/summarize` npm 套件 |
|
||||
|
||||
> **注意**:bundled skills 的 CLI 安裝在 nvm 路徑時,需 symlink 到 `~/.local/bin/` 才能被 Gateway 的 PATH 找到。
|
||||
> Gateway service PATH:`%h/.local/bin:/usr/local/bin:/usr/bin:/bin`
|
||||
|
||||
### 7.5 知識庫 Skills
|
||||
|
||||
| Skill | 功能 | 觸發方式 |
|
||||
|-------|------|---------|
|
||||
| `qmd-brain` | 第二大腦搜尋(BM25 + pgvector 語意) | 搜尋、查找、recall、之前說過... |
|
||||
|
||||
#### qmd-brain 架構
|
||||
|
||||
```
|
||||
使用者 Telegram 查詢
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ qmd-brain skill │
|
||||
│ 1. qmd search → BM25 全文搜尋 (SQLite) │
|
||||
│ 2. embed_to_pg → 語意搜尋 (PostgreSQL) │
|
||||
│ └─ CLIProxyAPI text-embedding-ada-002 │
|
||||
└─────────────────────────────────────────────┘
|
||||
|
||||
夜間排程(02:00):
|
||||
qmd embed → 更新本地索引
|
||||
embed_to_pg embed → 更新 PG 向量庫
|
||||
```
|
||||
|
||||
#### 相關路徑
|
||||
|
||||
```
|
||||
/home/selig/apps/qmd-pg/
|
||||
├── embed_to_pg.py # 向量寫入/搜尋 Python 腳本
|
||||
├── nightly-embed.sh # 夜間排程腳本
|
||||
└── venv/ # Python 虛擬環境
|
||||
|
||||
PostgreSQL:
|
||||
database: qmd_brain
|
||||
table: brain_documents (vector(1536), HNSW)
|
||||
user: qmd_user
|
||||
|
||||
qmd:
|
||||
collections: selig-home (/home/selig)
|
||||
index: ~/.cache/qmd/index.sqlite
|
||||
```
|
||||
|
||||
### 7.6 Skill 格式說明
|
||||
|
||||
每個 Skill 由兩個檔案組成:
|
||||
|
||||
**SKILL.md(Frontmatter + 說明)**
|
||||
```yaml
|
||||
---
|
||||
name: skill-name # 必填,kebab-case,和資料夾同名
|
||||
description: 一句話說明用途 # 必填,顯示在 skills list
|
||||
triggers: # 必填,空陣列 = 僅供內部呼叫
|
||||
- "關鍵字1"
|
||||
- "關鍵字2"
|
||||
tools: # 必填,宣告可用工具
|
||||
- exec
|
||||
- web_fetch
|
||||
internal: false # 選填,true = 對使用者隱藏
|
||||
---
|
||||
|
||||
# Skill 標題
|
||||
## 功能說明
|
||||
詳細說明 Skill 的功能、輸入、輸出...
|
||||
```
|
||||
|
||||
**handler.ts(實作)**
|
||||
```typescript
|
||||
export async function handler(ctx: any) {
|
||||
const message = ctx.message?.text || ctx.message?.content || '';
|
||||
// skill 邏輯...
|
||||
return {
|
||||
reply: '回覆文字(支援 Markdown)',
|
||||
metadata: { key: 'value' }, // 選填,結構化資料
|
||||
files: ['/tmp/output.wav'], // 選填,附件檔案路徑
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
> 注意:不可 import 第三方 npm 套件(skill 環境無 node_modules),外部依賴改用 `execSync('curl ...')` 呼叫。
|
||||
|
||||
### 7.7 語音合成 Skill(tts-voice)
|
||||
|
||||
| Skill | 功能 | 觸發方式 |
|
||||
|-------|------|---------|
|
||||
| `tts-voice` | 文字轉語音(LuxTTS Voice Cloning,48kHz) | tts、文字轉語音、語音合成、唸出來、說出來 |
|
||||
|
||||
- 呼叫本機 LuxTTS API(localhost:7860),自動取得登入 cookie
|
||||
- 支援修飾詞:慢速/快速/高品質
|
||||
- 原始碼:`/home/selig/openclaw-skill/skills/tts-voice/`
|
||||
|
||||
### 7.8 Skill 開發指南
|
||||
|
||||
完整的 Skill 開發教學(含 SKILL.md 格式、handler.ts 寫法、觸發機制、context 物件、回傳格式、安裝驗證、實戰範例、常見踩坑)請參考:
|
||||
|
||||
`/home/selig/openclaw-skill/create-skill.md`
|
||||
70
chapters/08-plugins.md
Normal file
70
chapters/08-plugins.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 8. Plugin 說明
|
||||
|
||||
### 8.1 memory-lancedb-pro(對話記憶)
|
||||
|
||||
**功能**:自動從 OpenClaw 對話中捕捉偏好、事實、決策,並在後續對話中自動召回相關記憶。
|
||||
|
||||
**與 qmd-brain 的差異**:
|
||||
| | qmd-brain | memory-lancedb-pro |
|
||||
|---|-----------|-------------------|
|
||||
| 資料來源 | ~/home 的 markdown 文件 | OpenClaw 對話本身 |
|
||||
| 觸發方式 | 手動(「搜尋」「recall」) | 自動捕捉+自動召回 |
|
||||
| 儲存 | PostgreSQL pgvector | LanceDB(本地檔案) |
|
||||
| Embedding | llama-embed(本地 GPU) | llama-embed(本地 GPU) |
|
||||
| 作用域 | 單一 collection | per-agent(global + agent:xxx) |
|
||||
|
||||
**設定摘要**:
|
||||
```json5
|
||||
// openclaw.json → plugins.entries.memory-lancedb-pro
|
||||
{
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"embedding": {
|
||||
"provider": "openai-compatible",
|
||||
"apiKey": "ollama",
|
||||
"model": "nomic-embed-text-v1.5",
|
||||
"baseURL": "http://127.0.0.1:11435/v1",
|
||||
"dimensions": 768
|
||||
},
|
||||
"dbPath": "/home/selig/.openclaw/memory-lancedb-pro/data",
|
||||
"autoCapture": true, // 自動從對話提取記憶
|
||||
"autoRecall": true, // 查詢前自動注入相關記憶
|
||||
"captureAssistant": false, // 不記錄 assistant 的回覆
|
||||
"retrieval": {
|
||||
"mode": "hybrid", // 向量 + BM25 混合
|
||||
"vectorWeight": 0.7,
|
||||
"bm25Weight": 0.3,
|
||||
"rerank": "lightweight" // 不需外部 API
|
||||
},
|
||||
"scopes": {
|
||||
"default": "global",
|
||||
"agentAccess": {
|
||||
"main": ["global", "agent:main"],
|
||||
"kaiwu": ["global", "agent:kaiwu"],
|
||||
"tiangong": ["global", "agent:tiangong"],
|
||||
"yucheng": ["global", "agent:yucheng"],
|
||||
"life-assistant": ["global", "agent:life-assistant"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**相關路徑**:
|
||||
```
|
||||
~/.openclaw/plugins/memory-lancedb-pro/ # plugin 原始碼
|
||||
~/.openclaw/memory-lancedb-pro/data/ # LanceDB 資料庫
|
||||
```
|
||||
|
||||
**維運注意**:
|
||||
- 改 plugin `.ts` 後必須清 jiti 快取:`rm -rf /tmp/jiti/`,再重啟 Gateway
|
||||
- 只改 `openclaw.json` config 不需清 jiti,直接重啟即可
|
||||
- 舊版 `memory-lancedb` 已設為 `enabled: false`,不會衝突
|
||||
- **`autoRecall` 的 `before_agent_start` hook 是同步阻塞的**。若 embedding API 無回應,所有 agent 會卡死。llama-embed 異常時必須立即關閉 `autoRecall`(見 04-known-issues.md §4.14、§4.15)
|
||||
- 容錯腳本 `~/clawd/scripts/embed-health.sh`(已實作,cron */30 分鐘)自動偵測 + 降級 + 通知
|
||||
|
||||
**記憶鐵律**(寫入 AGENTS.md,agent 每個 session 都會遵守):
|
||||
1. 踩坑後立即存雙層記憶(Technical + Principle)
|
||||
2. 記憶條目 < 500 字元,原子化,不存大段摘要
|
||||
3. 遇錯先 `memory_recall` 再重試
|
||||
4. 改 `.ts` 必清 `/tmp/jiti/`
|
||||
146
chapters/09-browser.md
Normal file
146
chapters/09-browser.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# 9. Browser Control 瀏覽器控制
|
||||
|
||||
### 9.1 架構總覽
|
||||
|
||||
```
|
||||
Telegram Agent 發出瀏覽器指令
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ OpenClaw Gateway (port 18789) │
|
||||
│ browser.request → 轉發給 Node Host │
|
||||
└──────────────┬───────────────────────────────┘
|
||||
│ WebSocket
|
||||
┌──────────────▼───────────────────────────────┐
|
||||
│ OpenClaw Node Host │
|
||||
│ systemd user: openclaw-node.service │
|
||||
│ browser relay:接收 Gateway 指令 │
|
||||
│ caps: browser, system │
|
||||
└──────────────┬───────────────────────────────┘
|
||||
│ CDP (Chrome DevTools Protocol)
|
||||
┌──────────────▼───────────────────────────────┐
|
||||
│ Playwright Chromium (port 18801) │
|
||||
│ systemd user: playwright-chrome.service │
|
||||
│ binary: ~/.cache/ms-playwright/chromium-1208 │
|
||||
│ user-data: ~/.openclaw/browser/playwright-data│
|
||||
│ DISPLAY=:99 (Xvfb) │
|
||||
└───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.2 服務組成
|
||||
|
||||
| 服務 | systemd unit | 功能 | 環境要求 |
|
||||
|------|-------------|------|---------|
|
||||
| Node Host | `openclaw-node.service` | Gateway <-> Chrome relay | `DISPLAY=:99` |
|
||||
| Playwright Chrome | `playwright-chrome.service` | Chromium 實例,CDP port 18801 | `DISPLAY=:99` |
|
||||
|
||||
### 9.3 Browser Profile
|
||||
|
||||
| Profile 名稱 | Driver | Port | 用途 | 狀態 |
|
||||
|-------------|--------|------|------|------|
|
||||
| `cdp-direct` | openclaw (CDP) | 18801 | **預設**(CLI 使用),直連 Playwright Chromium | 使用中 |
|
||||
| `chrome` | openclaw (CDP) | 18801 | **覆寫為 CDP**,Agent 透過 Node Host 操控時固定走此 profile | 使用中 |
|
||||
| `openclaw` | openclaw (CDP) | 18801 | **覆寫為 CDP**(原為 Gateway 內建 port 18800,會嘗試啟動 snap Chromium 而失敗) | 使用中 |
|
||||
|
||||
設定位置:`~/.openclaw/openclaw.json` → `browser.defaultProfile: "cdp-direct"`
|
||||
|
||||
> **踩坑 1**:`defaultProfile` 只影響 CLI 指令。Agent 透過 Node Host 操控瀏覽器時**固定走 `chrome` profile**,因此必須在 `browser.profiles` 中覆寫 `chrome` 的 `cdpUrl` 指向 Playwright CDP(port 18801),否則會走 extension relay 模式而報錯。
|
||||
>
|
||||
> **踩坑 2**:v2026.3.7 內建 `openclaw` profile(port 18800),Gateway 會嘗試用 detectedPath(`/usr/bin/chromium-browser`,snap 版)啟動瀏覽器。snap Chromium 會剝掉 CDP 參數導致永遠啟動失敗,agent tool call 15 秒後 timeout。**修復**:在 `browser.profiles` 覆寫 `openclaw` profile,讓它也指向 Playwright CDP(port 18801)。
|
||||
|
||||
### 9.4 常用指令
|
||||
|
||||
```bash
|
||||
# 狀態查看
|
||||
openclaw browser status # 查看預設 profile 狀態
|
||||
openclaw browser profiles # 列出所有 profile
|
||||
openclaw nodes status # Node Host 連線狀態
|
||||
|
||||
# 分頁操作
|
||||
openclaw browser tabs # 列出分頁
|
||||
openclaw browser open <url> # 開新分頁
|
||||
openclaw browser navigate <url> # 當前分頁導航
|
||||
openclaw browser focus <tab-id> # 切換分頁
|
||||
openclaw browser close <tab-id> # 關閉分頁
|
||||
|
||||
# 截圖與快照
|
||||
openclaw browser screenshot # 截圖
|
||||
openclaw browser screenshot --full-page # 完整頁面截圖
|
||||
openclaw browser snapshot # AI 可讀的頁面快照(預設 ai 格式)
|
||||
openclaw browser snapshot --format aria # Accessibility tree 格式
|
||||
|
||||
# 互動操作
|
||||
openclaw browser click <ref> # 點擊元素
|
||||
openclaw browser type <ref> "text" # 輸入文字
|
||||
openclaw browser press Enter # 按鍵
|
||||
openclaw browser hover <ref> # 滑鼠 hover
|
||||
openclaw browser fill --fields '[...]' # 表單填寫
|
||||
|
||||
# 其他
|
||||
openclaw browser pdf # 存成 PDF
|
||||
openclaw browser console --level error # 查看 console 錯誤
|
||||
openclaw browser evaluate --fn '...' # 執行 JavaScript
|
||||
```
|
||||
|
||||
### 9.5 安裝步驟(從零開始)
|
||||
|
||||
```bash
|
||||
# 1. 確保 Xvfb 在運行(DISPLAY=:99)
|
||||
pgrep -la Xvfb
|
||||
|
||||
# 2. 安裝 Playwright 瀏覽器(如未安裝)
|
||||
npx playwright install chromium
|
||||
|
||||
# 3. 安裝 OpenClaw Node service
|
||||
openclaw node install
|
||||
# 手動加入 DISPLAY=:99 到 service 檔案
|
||||
# ~/.config/systemd/user/openclaw-node.service → Environment=DISPLAY=:99
|
||||
|
||||
# 4. 確保 gateway.env 也有 DISPLAY=:99
|
||||
echo 'DISPLAY=:99' >> ~/.config/openclaw/gateway.env
|
||||
|
||||
# 5. 啟動 Node service 並配對
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now openclaw-node.service
|
||||
# 等待 Node 連上 Gateway 後出現 pending device
|
||||
openclaw devices list # 查看 pending request
|
||||
openclaw devices approve <id> # 核准配對
|
||||
|
||||
# 6. 建立 Playwright Chrome service
|
||||
# 見 ~/.config/systemd/user/playwright-chrome.service
|
||||
systemctl --user enable --now playwright-chrome.service
|
||||
|
||||
# 7. 建立 cdp-direct browser profile
|
||||
openclaw browser create-profile --name cdp-direct --cdp-url http://127.0.0.1:18801 --driver openclaw
|
||||
|
||||
# 8. 設為預設 profile,並覆寫 chrome + openclaw profile
|
||||
# 在 openclaw.json 的 browser 區塊:
|
||||
# "defaultProfile": "cdp-direct"
|
||||
# "profiles": {
|
||||
# "cdp-direct": { "cdpUrl": "http://127.0.0.1:18801", "color": "#00AAFF" },
|
||||
# "chrome": { "cdpUrl": "http://127.0.0.1:18801", "color": "#00AA00" },
|
||||
# "openclaw": { "cdpUrl": "http://127.0.0.1:18801", "color": "#FF4500" }
|
||||
# }
|
||||
# chrome profile 必須覆寫,Agent 透過 Node Host 固定走此 profile
|
||||
# openclaw profile 必須覆寫,否則 Gateway 嘗試用 snap Chromium 啟動而 timeout
|
||||
|
||||
# 9. 重啟 Gateway
|
||||
systemctl --user restart openclaw-gateway
|
||||
|
||||
# 10. 驗證
|
||||
openclaw browser status
|
||||
openclaw browser navigate https://example.com
|
||||
openclaw browser screenshot
|
||||
```
|
||||
|
||||
### 9.6 已知問題
|
||||
|
||||
| 問題 | 原因 | 修復 |
|
||||
|------|------|------|
|
||||
| Snap Chromium 不支援 `--load-extension` / `--remote-debugging-port` | snap 沙箱會剝掉安全相關旗標 | 改用 Playwright Chromium(非 snap,直接二進位) |
|
||||
| Node service `pairing required` | 首次連線需經 Gateway 核准 | `openclaw devices approve <id>` |
|
||||
| Browser start timeout | Node/Gateway 缺少 `DISPLAY` 環境變數 | 在 service 和 gateway.env 加 `DISPLAY=:99`;Gateway service 本身也需要 `Environment=DISPLAY=:99` |
|
||||
| `openclaw browser start --browser-profile chrome` 需要點擴充套件 | `chrome` profile 使用 extension relay 模式 | 改用 `cdp-direct` profile(CDP 直連,不需擴充套件) |
|
||||
| Port 18800 被 Gateway 佔用 | `openclaw` profile 預設使用 18800 | 自訂 port 使用 18801 |
|
||||
| Agent 操控瀏覽器仍報 extension relay 錯誤 | `defaultProfile` 只影響 CLI,Agent 透過 Node Host 固定走 `chrome` profile | 在 `openclaw.json` 的 `browser.profiles` 覆寫 `chrome` 的 `cdpUrl` 指向 Playwright CDP port 18801 |
|
||||
| Agent browser tool timeout(v2026.3.7,2026-03-11) | 內建 `openclaw` profile 嘗試用 snap Chromium 啟動(detectedPath: `/usr/bin/chromium-browser`),snap 會剝掉 `--remote-debugging-port` 導致 CDP 永遠無法建立 | 在 `browser.profiles` 覆寫 `openclaw` profile 的 `cdpUrl` 指向 Playwright CDP port 18801;同時確認 Gateway service 有 `Environment=DISPLAY=:99` |
|
||||
221
chapters/10-operations.md
Normal file
221
chapters/10-operations.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# 10. 維運操作手冊
|
||||
|
||||
### 10.1 每日確認指令
|
||||
|
||||
```bash
|
||||
# 快速健康檢查
|
||||
sudo openclaw health
|
||||
|
||||
# 查看所有 Docker 容器
|
||||
sudo docker ps
|
||||
|
||||
# 查看 OpenClaw 服務狀態(user service)
|
||||
systemctl --user status openclaw-gateway
|
||||
|
||||
# 查看 skills 狀態(不加 sudo)
|
||||
openclaw skills list
|
||||
```
|
||||
|
||||
### 10.2 服務重啟
|
||||
|
||||
```bash
|
||||
sudo docker restart nginx # 重啟 nginx
|
||||
sudo docker restart cli-proxy-api # 重啟 CLIProxyAPI
|
||||
sudo systemctl restart openclaw # 重啟 OpenClaw
|
||||
```
|
||||
|
||||
### 10.3 OpenClaw 升級
|
||||
|
||||
```bash
|
||||
# 1. 備份設定
|
||||
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.pre-upgrade-$(date +%Y%m%d)
|
||||
|
||||
# 2. 停止 Gateway(避免升級期間衝突)
|
||||
systemctl --user stop openclaw-gateway
|
||||
|
||||
# 3. 下載並執行安裝腳本(自動偵測升級)
|
||||
# 指定版本:OPENCLAW_VERSION=2026.3.7 NO_PROMPT=1
|
||||
# 安裝 beta:加 --beta 旗標
|
||||
curl -fsSL https://openclaw.ai/install.sh -o /tmp/openclaw-install.sh
|
||||
sudo OPENCLAW_VERSION=<版本號> NO_PROMPT=1 bash /tmp/openclaw-install.sh
|
||||
|
||||
# 4. 修正 temp 目錄權限(新版安全檢查要求 700)
|
||||
chmod 700 /tmp/openclaw-$(id -u)
|
||||
|
||||
# 5. 驗證 config JSON 有效
|
||||
python3 -m json.tool ~/.openclaw/openclaw.json > /dev/null
|
||||
|
||||
# 6. 啟動 Gateway
|
||||
systemctl --user start openclaw-gateway
|
||||
|
||||
# 7. 驗證
|
||||
openclaw --version
|
||||
systemctl --user status openclaw-gateway
|
||||
openclaw skills list
|
||||
```
|
||||
|
||||
> **注意**:
|
||||
> - 升級後若出現 plugin 警告(如 `plugin removed: xxx`),需手動從 `openclaw.json` 的 `plugins.entries` 移除過期條目。
|
||||
> - Doctor 在無 TTY 環境(如 SSH non-interactive)會跳過 plugin 更新,這是正常的。
|
||||
> - v2026.3.7 起 browser control server 預設佔用 `gatewayPort + 2`(即 18791),無獨立 config key 可改。若與其他服務衝突需搬移對方。
|
||||
|
||||
#### 版本紀錄
|
||||
|
||||
| 日期 | 版本 | 備註 |
|
||||
|------|------|------|
|
||||
| 2026-02-27 | 2026.2.25 | 升級後 `google-antigravity-auth` plugin 殘留需清理 |
|
||||
| 2026-02-27 | 2026.2.22 | 回滾(skill 作者建議此版較穩) |
|
||||
| 2026-03-08 | 2026.3.7 | 正式版升級,browser control port 18791 與 oclaw-auth 衝突,已將 oclaw-auth 搬至 18793 |
|
||||
|
||||
### 10.3.1 CLIProxyAPI 升級
|
||||
|
||||
```bash
|
||||
# 手動升級(需 sudo)
|
||||
cd /home/docker/CLIProxyAPI
|
||||
sudo git pull --ff-only origin main
|
||||
sudo docker compose down && sudo docker compose build --no-cache && sudo docker compose up -d
|
||||
|
||||
# 驗證
|
||||
sudo docker compose ps
|
||||
curl -s -H "Authorization: Bearer <API_KEY>" http://127.0.0.1:8317/v1/models | python3 -c "import json,sys; print(len(json.load(sys.stdin)['data']), 'models')"
|
||||
```
|
||||
|
||||
> **自動更新**:`~/clawd/scripts/update-cliproxyapi.sh`(root crontab,每週日 03:30)
|
||||
> 自動 git pull + docker rebuild,日誌 `/var/log/cliproxyapi-update.log`
|
||||
|
||||
### 10.3.2 自動更新排程(每週日)
|
||||
|
||||
| 時間 | 腳本 | Crontab | 說明 |
|
||||
|------|------|---------|------|
|
||||
| 02:00 | `nightly-embed.sh` | selig(每天) | 知識庫向量更新 |
|
||||
| 03:00 | `git pull` OpenClaw Skill | selig | Claude Code skill 更新 |
|
||||
| 03:30 | `update-cliproxyapi.sh` | root | CLIProxyAPI git pull + Docker rebuild |
|
||||
| 05:00 | `refresh-llm-list.sh` | selig | 同步 CLIProxyAPI 新模型到 OpenClaw config |
|
||||
|
||||
> **順序很重要**:CLIProxyAPI 先更新(03:30),模型列表才能在之後(05:00)抓到新模型。
|
||||
|
||||
### 10.3.3 模型冷卻自動切換
|
||||
|
||||
`~/clawd/scripts/model-cooldown-watch.sh`(cron 每 12 小時)偵測 CLIProxyAPI 模型 cooldown,自動切 fallback 並用 `at` 排程精準恢復。
|
||||
|
||||
```bash
|
||||
# 手動觸發
|
||||
bash ~/clawd/scripts/model-cooldown-watch.sh
|
||||
|
||||
# 查看日誌
|
||||
cat /var/log/model-cooldown.log
|
||||
|
||||
# 查看排程的恢復任務
|
||||
at -l
|
||||
```
|
||||
|
||||
> **原理**:API 回 `model_cooldown` + `reset_seconds` → 批量切受影響 agent 到 `agents.defaults.model.fallbacks[0]` → `at now + (reset_seconds+300)/60 minutes` 排程恢復。不依賴 cron 輪詢恢復,避免浪費 API 請求。
|
||||
|
||||
### 10.4 日誌查看
|
||||
|
||||
```bash
|
||||
sudo docker logs nginx --tail 50 # nginx 日誌
|
||||
sudo docker logs cli-proxy-api --tail 50 # CLIProxyAPI 日誌
|
||||
sudo journalctl -u openclaw -n 50 -f # OpenClaw 即時日誌
|
||||
sudo openclaw logs # OpenClaw 結構化日誌
|
||||
```
|
||||
|
||||
### 10.5 OpenClaw 管理指令
|
||||
|
||||
```bash
|
||||
# 設備管理
|
||||
sudo openclaw devices list
|
||||
sudo openclaw devices approve <id>
|
||||
|
||||
# Session 管理
|
||||
sudo openclaw status
|
||||
sudo openclaw status --deep
|
||||
|
||||
# Cron 任務
|
||||
sudo openclaw cron list
|
||||
sudo openclaw cron add --name "test" --cron "0 8 * * *" --session main --system-event "早安"
|
||||
sudo openclaw cron run <job-id>
|
||||
|
||||
# 模型設定
|
||||
sudo openclaw models status
|
||||
sudo openclaw doctor
|
||||
|
||||
# 安全審計
|
||||
sudo openclaw security audit
|
||||
```
|
||||
|
||||
### 10.6 備份
|
||||
|
||||
```bash
|
||||
sudo bash ~/backup.sh
|
||||
# 產生:~/server-backup-YYYYMMDD_HHMMSS.tar.gz(約 80KB)
|
||||
```
|
||||
|
||||
### 10.7 在新機器還原
|
||||
|
||||
```bash
|
||||
scp server-backup-*.tar.gz user@新機器:~/
|
||||
ssh user@新機器
|
||||
tar -xzf server-backup-*.tar.gz
|
||||
sudo bash restore.sh ~/server-backup-YYYYMMDD_HHMMSS
|
||||
```
|
||||
|
||||
### 10.8 Crontab
|
||||
|
||||
**selig user**(`crontab -l`):
|
||||
```
|
||||
0 2 * * * /home/selig/apps/qmd-pg/nightly-embed.sh # 知識庫向量更新
|
||||
0 2 * * 0 /home/selig/clawd/scripts/refresh-llm-list.sh # 每週日更新 CLIProxyAPI 模型清單
|
||||
*/15 * * * ~/.acme.sh/acme.sh --cron # SSL 憑證自動續期
|
||||
```
|
||||
|
||||
**root**(`sudo crontab -l`):
|
||||
```
|
||||
0 0 * * * ~/auto_cert_renewal.sh
|
||||
0 2 * * * docker exec nginx apk add logrotate && docker exec nginx logrotate -f /etc/logrotate.conf
|
||||
@reboot iptables-restore < /etc/iptables/rules.v4
|
||||
```
|
||||
|
||||
### 10.9 開機自啟動架構
|
||||
|
||||
| 服務 | 機制 |
|
||||
|------|------|
|
||||
| Docker 本身 | systemd enabled |
|
||||
| nginx | Docker restart: always |
|
||||
| CLIProxyAPI | Docker restart: unless-stopped |
|
||||
| OpenClaw Gateway | systemd user `openclaw-gateway.service` enabled |
|
||||
| OpenClaw Node Host | systemd user `openclaw-node.service` enabled |
|
||||
| Playwright Chrome | systemd user `playwright-chrome.service` enabled |
|
||||
| iptables 規則 | crontab @reboot |
|
||||
| IPv6 停用 | /etc/sysctl.conf 永久設定 |
|
||||
|
||||
---
|
||||
|
||||
## 附錄:OpenClaw 重要路徑
|
||||
|
||||
```
|
||||
~/.openclaw/openclaw.json 主設定
|
||||
~/.openclaw/workspace/ Agent 工作目錄
|
||||
~/.openclaw/agents/main/ 主 Agent 資料
|
||||
├── auth-profiles.json LLM 認證
|
||||
├── sessions/sessions.json Session 狀態
|
||||
└── sessions/*.jsonl 對話記錄
|
||||
~/.openclaw/credentials/ 頻道憑證
|
||||
~/.openclaw/devices/paired.json 已配對裝置
|
||||
~/.openclaw/cron/jobs.json 排程任務
|
||||
~/.openclaw/logs/ 日誌
|
||||
|
||||
# Browser Control
|
||||
~/.openclaw/browser/chrome-extension/ Chrome 擴充套件(snap 不適用)
|
||||
~/.openclaw/browser/playwright-data/ Playwright Chrome user-data
|
||||
~/.openclaw/media/browser/ 截圖輸出目錄
|
||||
~/.cache/ms-playwright/chromium-1208/ Playwright Chromium 二進位
|
||||
|
||||
# systemd user services
|
||||
~/.config/systemd/user/openclaw-gateway.service Gateway
|
||||
~/.config/systemd/user/openclaw-node.service Node Host(需 DISPLAY=:99)
|
||||
~/.config/systemd/user/playwright-chrome.service Playwright Chrome(需 DISPLAY=:99)
|
||||
~/.config/openclaw/gateway.env Gateway 環境變數(含 DISPLAY=:99)
|
||||
|
||||
/tmp/openclaw-1000/openclaw-YYYY-MM-DD.log 即時日誌(重啟後清除)
|
||||
```
|
||||
Reference in New Issue
Block a user