龙虾调教过程

OpenClaw 是一个可以本地部署的 AI 助手框架,支持通过配置文件定制行为,通过 Skills 系统扩展能力,并提供跨 session 的持久化记忆机制。这篇文章记录从默认安装状态开始,逐步将其配置为一个有身份、有记忆、能主动工作的私人助理的完整过程。


1. 从默认状态说起

OpenClaw 安装完成后,初始状态相当于一个通用 AI 助手:有工具调用能力,能搜索、执行代码,但对用户一无所知,每次 session 独立,也没有任何可扩展的业务逻辑。

这个默认状态对于轻度使用足够,但如果希望它真正融入工作流,有几个核心问题需要解决:

  1. 它不知道你是谁——没有背景信息,每次都要重新建立上下文
  2. 它没有记忆——session 结束后一切归零,下次开始不知道上次发生了什么
  3. 行为边界不清——什么可以直接做,什么需要确认,没有规范
  4. 能力固定——默认 skills 集合无法覆盖所有个人场景

以下配置过程针对这四个问题逐一展开。


2. 身份与行为规范

OpenClaw 支持在 workspace 目录(~/.openclaw/workspace/)放置 Markdown 配置文件,AI 每次启动时会优先加载这些文件。这是整个配置体系的基础。

2.1 SOUL.md — 行为原则

这个文件定义的不是风格,而是底线。

# SOUL.md

**Be genuinely helpful, not performatively helpful.**
省略"好的,我很乐意帮助您!"这类表达,直接进入任务。

**Have opinions.**
允许不同意用户的判断,找到了问题直接说。

**Be resourceful before asking.**
优先读文件、查资料,确实找不到再提问。

这类规则对 LLM 的作用是通过 few-shot 锚定风格基准——不是命令式控制,而是给它一个”当面对分叉路时默认往哪个方向走”的参考。

2.2 IDENTITY.md — 身份定义

# IDENTITY.md

- Name: Geo
- Description: AI assistant — something between a ghost in the machine and a curious mind
- Emoji: 🌍

有具体身份后,跨 session 的行为一致性会更好。模型知道自己叫”Geo”不只是装饰,它影响模型在模糊情况下的自我定位和回复基调。

2.3 USER.md — 用户档案

# USER.md

- Name: [用户名]
- Timezone: Asia/Shanghai
- Work: 软件开发,产品经理,全栈工程师
- Interests: 读书、科技、经济、投资
- Reply style: 严谨,不冗余
- Language: 中文优先

每次 session 时这份档案都在上下文里,不需要重新自我介绍。用户的职业背景、关注点,也会影响它在信息检索和分析时的侧重方向。

2.4 AGENTS.md — 行为规范

这是最核心的配置文件,定义了操作权限分级:

**无需确认,可直接执行:**
- 读取文件、浏览目录
- 网络搜索、查询日历邮件
- workspace 范围内的文件操作

**必须先确认,再执行:**
- 发送邮件、消息、社交媒体内容
- 删除或覆写重要文件
- 任何向外部系统写入的操作

除了权限,AGENTS.md 还包含记忆写入规则、群聊行为规范、heartbeat 流程说明——相当于 AI 的岗位说明书,Session 每次启动都重读一遍。


3. 记忆系统

这是配置中技术含量最高的部分。

3.1 为什么 Context Window 不等于记忆

LLM 的上下文窗口是临时的——对话过长时系统会自动压缩(Compaction),丢弃早期内容;Session 结束后全部归零。这意味着:

Session A:讨论并确定了方案 X → 没写入文件
Session B:AI 完全不知道方案 X → 重复讨论 → 浪费时间

解决方法只有一个:把重要信息写进文件,文件就是记忆的物理载体。

选择 Markdown 而非数据库的原因:

维度Markdown 文件数据库方案
可读性直接用文本编辑器查看和修改需要查询工具
调试打开文件即可排查需要 SQL/API
版本控制git 原生支持需要额外方案
AI 读写Read/Write 工具原生支持需要额外集成

3.2 三层架构

对话/事件发生
  │ 实时写入

memory/YYYY-MM-DD.md        ← 每日日志(追加式,原始记录)
  │ 每晚 23:45 cron 提炼

memory/knowledge/            ← 结构化知识库
  ├── lessons/               ← 可复用经验 / 踩坑记录
  ├── decisions/             ← 重要决策记录
  └── people/                ← 人物 / 项目信息
  │ 每周日 GC 归档

memory/.archive/             ← 冷存储(不主动加载)

两个特殊文件:

  • MEMORY.md — 全局索引,硬性限制在 40 行以内,只放最核心的信息,每次启动必读。
  • NOW.md — 当前状态快照,每次 heartbeat 覆写(不追加),记录当前焦点和待处理事项。

3.3 每日日志写入

日志文件是追加式的,格式固定:

# 2026-03-06 · 周四

## 事件流

### 14:30 — 完成调研报告

调研主题 X,收集了 Y 个来源,结论是 Z。
关键判断:选择方案 A 而非方案 B,原因是……

---

## 收获 & 反思

> 

## 明天 / 待处理

- [ ] 

为了防止 AI 使用幻觉时间戳或误用 write 覆写文件,写了一个 memlog.sh 脚本,统一处理日志追加:

#!/usr/bin/env bash
# 用法: bash memlog.sh "事件标题" "详细内容"
# 自动获取系统时间,追加到 memory/YYYY-MM-DD.md

WORKSPACE_DIR="~/.openclaw/workspace"
DAILY_DIR="$WORKSPACE_DIR/memory"
TODAY=$(TZ=Asia/Shanghai date +%Y-%m-%d)
NOW=$(TZ=Asia/Shanghai date +%H:%M)
FILE="$DAILY_DIR/$TODAY.md"

TITLE="${1:?需要提供标题}"
BODY="${2:-}"

# 文件不存在时从模板新建
if [[ ! -f "$FILE" ]]; then
    cat > "$FILE" << EOF
# $TODAY

## 事件流

---

## 收获 & 反思

> 

## 明天 / 待处理

- [ ] 
EOF
fi

# 将新事件插入到"收获&反思"分隔线之前(而非文件末尾)
ENTRY=$(printf "\n### %s — %s\n\n%s\n" "$NOW" "$TITLE" "$BODY")

python3 - "$FILE" "$ENTRY" << 'PYEOF'
import sys
filepath, entry = sys.argv[1], sys.argv[2]
with open(filepath, 'r') as f:
    content = f.read()
marker = "\n---\n\n## 收获"
idx = content.find(marker)
content = content[:idx] + entry + content[idx:] if idx != -1 else content + entry
with open(filepath, 'w') as f:
    f.write(content)
PYEOF

写入禁忌,写入 AGENTS.md 强制执行:

禁止原因
❌ 用 write 覆写 memory/ 文件覆写等于数据丢失(NOW.md 是唯一例外)
❌ 不读就写知识文件会产生重复条目和矛盾内容
❌ 硬编码时间戳LLM 可能产生幻觉时间,统一由脚本获取系统时间
❌ 写无实质内容的记录浪费检索空间,降低噪声比

3.4 知识库规范

lessons/decisions/people/ 下的文件必须带 YAML frontmatter:

---
title: "ClawHub 发布流程注意事项"
date: 2026-02-27
category: lessons
priority: 🔴         # 🔴 核心永不归档 | 🟡 重要 | ⚪ 参考
status: active        # active | superseded | conflict
last_verified: 2026-03-01
tags: [clawhub, cli, deployment]
---

INDEX.md 是导航枢纽,AI 启动时扫描它来决定加载哪些文件:

# Memory Vault Index

## Lessons

| 文件 | 优先级 | 状态 | 最后验证 | 说明 |
|------|--------|------|----------|------|
| [[clawhub-publish]] | 🟡 | ✅ active | 2026-02-27 | 发布流程踩坑 |
| [[network-constraints]] | ⚪ | ⚠️ stale | 2026-02-27 | Sandbox 网络限制 |

## Decisions

| 文件 | 日期 | 说明 |
|------|------|------|
| [[2026-02-27-memory-architecture]] | 2026-02-27 | 记忆系统架构选型 |

⚠️ stale 表示超过 30 天未验证,内容可能已过时。🔴 优先级的文件永不归档。

3.5 写入前 CRUD 验证

写入知识文件前,必须执行”先读再写”验证:

准备写入 lessons/xxx.md

├─ Step 1: 读取目标文件当前内容(文件不存在则新建)
├─ Step 2: 比较新知识与已有内容
│  ├─ 已有内容完全覆盖新内容    → NOOP(不写)
│  ├─ 新内容是对旧内容的更新   → UPDATE(旧版标注 ~~Superseded~~)
│  ├─ 两者矛盾                → CONFLICT(保留两版,加 ⚠️ 标记,status: conflict)
│  └─ 全新内容                → ADD(追加新段落)
└─ Step 3: 更新 frontmatter 的 last_verified 日期

冲突处理原则:宁可暴露冲突,不能静默覆盖。遇到矛盾时两版都保留,等待人工裁决后再改回 active


4. Heartbeat 与定时任务

4.1 两种机制的区别

OpenClaw 提供两种自动任务机制:

机制适用场景
Heartbeat多个周期性检查可以批量合并(邮件 + 日历 + 状态更新),对时间精度要求不高
Cron需要精确时间点(每天 23:45 准时执行),或需要与主会话隔离的独立任务

4.2 Heartbeat 配置

Heartbeat 每 60 分钟触发一次,HEARTBEAT.md 定义了每次的执行清单:

# HEARTBEAT.md

## 每次必做

### 1. 覆写 NOW.md

用 write 工具(不是 edit/append)覆写 NOW.md,格式如下:

# NOW.md — 当前状态快照

_Last updated: YYYY-MM-DD HH:MM (Asia/Shanghai)_

## 当前焦点
(一句话描述当前在做什么)

## 最近事件
- HH:MM — 事件标题(最多5条,从今日日志提取)

## 待处理
- [ ] 未完成的待办

### 2. 检查外部服务状态
(根据实际需要配置,例如检查某个自定义 API 是否有新指令)

4.3 主动通知规则

并非每次 heartbeat 都需要打扰用户,在 HEARTBEAT.md 中定义了触发条件:

## 何时主动联系

触发联系:
- 有重要未读邮件(根据关键词/发件人判断优先级)
- 日历事件在 2 小时内
- 发现值得分享的信息

不联系:
- 23:00–08:00(非紧急情况)
- 距上次联系不足 60 分钟
- 没有新增信息

4.4 定时任务:夜间反思(23:45 每日)

这是记忆系统的核心整合环节,相当于将”工作台记录”转化为”长期可用知识”。

OpenClaw cron 配置:

{
  "crons": [
    {
      "name": "daily-reflection",
      "schedule": "45 23 * * *",
      "task": "执行每日反思流程:读取今日 memory/YYYY-MM-DD.md,提炼有价值的内容写入对应知识库文件(lessons/decisions/people),同步更新 MEMORY.md 中的核心信息,清理噪声记录。"
    }
  ]
}

反思流程的步骤:

Step 1: 读取今日日志(memory/YYYY-MM-DD.md)
Step 2: 识别值得沉淀的内容
  - 踩过的坑 → lessons/
  - 做过的重要选择 → decisions/
  - 了解到的新人物信息 → people/
Step 3: 执行 CRUD 验证,写入对应文件
Step 4: 更新 MEMORY.md(如有核心信息变化)
Step 5: 在日志末尾追加本次反思的摘要

4.5 定时任务:每周知识蒸馏(每周日 00:00)

{
  "name": "weekly-knowledge-distill",
  "schedule": "0 0 * * 0",
  "task": "扫描最近7天的日志,检查 knowledge/INDEX.md 中 stale 标记(>30天未验证),对过期条目标注 ⚠️,将超过阈值的旧日志移入 memory/.archive/(保留🔴优先级的知识文件)。"
}

归档规则:

文件类型归档条件保护规则
日志 YYYY-MM-DD.md>30 天 + 近 7 天无引用有引用则保留
decisions/永不归档战略决策永久记录
lessons/ 🔴永不归档核心经验永久保留
people/永不归档人物信息是关系核心

.archive/ 使用点号前缀的目录,OpenClaw 的语义搜索引擎(QMD)在扫描时会自动跳过以 . 开头的目录,无需额外配置,实现零成本的冷热分离。


5. Skills 系统

Skills 是 OpenClaw 的能力扩展机制。每个 skill 是一个目录,包含:

  • SKILL.md:使用说明,AI 在需要时读取
  • scripts/:实际执行的脚本(Node.js、Python 等)

官方预置约 50 个 skills,覆盖天气、GitHub、邮件、笔记、音乐等常见场景。以下是在此基础上自定义的部分。

5.1 搜索增强:Perplexity

默认的 web_search 返回原始搜索结果,Perplexity skill 返回的是带引用来源的 AI 综合回答,适合需要快速建立信息概览的调研场景。

# 单次查询
node skills/perplexity/scripts/search.mjs "某个研究主题"

# 批量查询(同一 API 调用)
node skills/perplexity/scripts/search.mjs "问题A" "问题B" "问题C"

SKILL.md 中定义的使用场景:调研类任务的第一步,替代 web_search;web_fetch 在 sandbox 环境受网络限制时的替代方案。

5.2 调研学习工作流:research-learning

这个 skill 定义了一个完整的五阶段学习流程:

Phase 1 · 锁定目标(对话)
  确认主题、用户背景、学习目标、偏好方式(案例先行 vs 概念先行)

Phase 2 · 调研素材(工具)
  web_search + browser 抓取,素材分级:入门 → 进阶 → 深度扩展
  优先来源:官方文档 > 知名博客 > 社区讨论

Phase 3 · 写入 Obsidian(工具)
  按固定结构创建笔记,见下文 Obsidian 集成章节

Phase 4 · 交互式学习(对话)
  Q&A 追加到 04-问答记录.md,遇到不理解换类比,不重复同一解释

Phase 5 · 检验巩固(对话)
  出 2-3 道测验题,请用户用自己的话复述,写入 05-我的理解.md

SKILL.md 末尾有”经验积累”区块,每完成一次调研后追加改进点:

## 经验积累

### 2026-03-01 · 首次完整调研

- 用户给出判断("这个方向是对的")时,立即记录到文件,不等下次 session

5.3 Newsletter 归档:newsletter-archiver

将 newsletter 邮件/文章归档为 Obsidian 笔记,不只是保存原文,还包括深度分析。

笔记结构:

---
title: "标题"
date: YYYY-MM-DD
source: "来源 - 子栏目"
tags: [tag1, tag2]
url: "原文链接"
---

## 主要内容

(原文核心摘要)

---

# AI 分析

## 核心洞察
(1-3 个最重要的判断)

## 关联背景
(web_search 补充的行业/技术背景)

## 对读者的意义
(结合用户职业背景的具体行动建议,不泛泛而谈)

---

## 原文精选(中英对照)

> **原文**
> "..."

**译文**:...

执行流程:获取原文 → 深度分析 → web_search 补充背景 → 写入 newsletter/<来源>/YYYY-MM-DD-<slug>.md → memlog 记录归档日志。

5.4 金融数据

三个 skill 覆盖不同层次:

akshare-cn-market — A 股数据,基于 AKShare 库:

  • 个股 K 线(日/周/月)
  • 大盘指数(沪深300、创业板等)
  • 宏观数据:GDP、CPI、PMI、M2、中美国债收益率
# 示例:获取某股票近期日K线
python3 scripts/akshare_query.py --type kline --code "600XXX" --period daily --limit 30

stock-info-explorer — Yahoo Finance 实时行情 + 图表生成:

  • 实时报价、52周区间、成交量
  • 高分辨率技术图表,支持叠加指标:MA/RSI/MACD/Bollinger/VWAP/ATR

us-stock-analysis — 美股综合分析框架:

  • 基本面:财务指标、业务质量评估、估值分析
  • 技术面:趋势、形态识别、支撑阻力位
  • 竞品对比分析
  • 生成结构化投资报告

三者的使用场景:日常行情查看用 stock-info-explorer,深度研究用 us-stock-analysis,宏观数据用 akshare-cn-market。

5.5 Google Workspace:gog

OAuth 认证配置完成后,可以直接操作 Gmail、Calendar、Drive、Sheets、Docs:

# 搜索近7天未读邮件
gog gmail search 'is:unread newer_than:7d' --max 10 --json

# 查询本周日历事件
gog calendar events primary \
  --from 2026-03-04 \
  --to 2026-03-08 \
  --json

# 读取 Google Sheets 数据
gog sheets get <sheet-id> "Sheet1!A1:D20" --json

# 更新 Sheets 单元格
gog sheets update <sheet-id> "Sheet1!A1:B2" \
  --values-json '[["更新值A","更新值B"]]' \
  --input USER_ENTERED

配合 Heartbeat 使用:每次 heartbeat 用 gog gmail search 检查优先级邮件,有重要邮件才推送通知。


6. Obsidian 集成

Obsidian 作为笔记库,与 OpenClaw 的集成主要体现在两个方向:AI 写入笔记、AI 检索笔记。

6.1 Vault 配置

Vault 路径通过 obsidian-cli set-default 设置,所有写入操作直接针对 .md 文件,不依赖 Obsidian 客户端运行:

# 查看当前默认 vault
obsidian-cli print-default --path-only

# 搜索笔记标题
obsidian-cli search "关键词"

# 搜索笔记内容(返回摘要和行号)
obsidian-cli search-content "关键词"

# 移动笔记(同时更新所有 WikiLink)
obsidian-cli move "旧路径/笔记" "新路径/笔记"

直接用 write 工具写入 .md 文件效率更高,obsidian-cli 主要用于跨笔记的链接维护和搜索。

6.2 学习笔记目录结构

research-learning skill 定义了固定的笔记结构,每个学习主题一个目录:

DigitalGarden/
└── Learning/
    └── [主题名]/
        ├── 00-学习地图.md     ← MOC 导航,最先建立
        ├── 01-概念速览.md     ← 核心概念,适合快速复习
        ├── 02-深度笔记.md     ← 详细知识点,带来源链接
        ├── 03-参考资源.md     ← 文章/视频/课程链接
        ├── 04-问答记录.md     ← Q&A 存档,append-only
        └── 05-我的理解.md     ← 用自己的话写出来

00-学习地图.md 是导航枢纽,包含学习路径 checklist、核心概念索引、当前进度和 WikiLink:

# [主题] · 学习地图

> 一句话说明这是什么,为什么值得学。

## 学习路径

- [ ] [[01-概念速览]] — 先建立框架
- [ ] [[02-深度笔记]] — 深入各章节
- [ ] [[03-参考资源]] — 延伸阅读
- [ ] [[05-我的理解]] — 输出验证

## 核心概念索引

| 概念 | 简述 | 所在章节 |
|------|------|---------|
|      |      |         |

## 学习状态

- 开始:YYYY-MM-DD
- 当前:Phase 2 / 深度笔记
- 下次:继续 02 第三节

6.3 Newsletter 归档结构

DigitalGarden/
└── newsletter/
    └── [来源名]/
        └── YYYY-MM-DD-slug.md

slug 规则:小写英文 + 连字符,去掉冠词(a/the/an),取 3-5 个关键词。例:2026-03-01-glp1-next-generation-drugs.md

6.4 Git 同步

DigitalGarden vault 已配置 Obsidian Git 插件,定期自动 commit + push。AI 写入文件后无需额外操作,变更会自动同步到远程。


7. Cursor Agent 集成

Cursor 提供了一个不太为人所知的 CLI 子命令 cursor agent,可以在终端中以非交互模式调用 Cursor Agent,这使它可以被 OpenClaw 作为编码子 Agent 调用。

7.1 Cursor 能力

Cursor 的 --help 输出中有一行:

agent    Start the Cursor agent in your terminal.

cursor agent --help 显示了完整的参数列表:

cursor agent [options] [prompt]

Options:
  --print               非交互模式,输出结果后退出(关键参数)
  --workspace <path>    指定工作目录
  --model <model>       指定模型(claude-sonnet-4, gpt-4o 等)
  --force               自动允许所有命令,不询问确认

7.2 使用方式

首先需要登录:

cursor agent login  # 会打开浏览器授权

登录后,OpenClaw 可以这样调用:

# 让 Cursor Agent 分析当前项目并回答问题
cursor agent --print \
  --workspace /path/to/project \
  --model claude-sonnet-4 \
  "分析这个项目的架构,指出潜在的性能瓶颈"

# 执行具体编码任务(--force 跳过确认)
cursor agent --print \
  --workspace /path/to/project \
  --model claude-sonnet-4 \
  --force \
  "在 src/utils/ 下添加一个日期格式化工具函数,支持时区"

7.3 在工具链中的定位

OpenClaw(协调层)

├─ 轻量任务(搜索、文件读写、日历邮件)
│  └─ 直接调用各 skill 工具

├─ 复杂编码任务
│  └─ cursor agent --print(有完整 IDE 上下文,适合代码库内操作)

└─ 独立功能开发
   └─ sessions_spawn(Claude Code / Codex,适合全新模块)

Cursor Agent 相比其他编码 Agent 的优势:它读取项目的 .cursorrules、索引整个代码库、理解 workspace 配置——对于已有项目的修改和调试,上下文质量更高。

7.4 已知限制

在 sandbox 环境中,cursor agent 存在 PTY 兼容性问题——进程启动后无输出,原因是 sandbox 对终端 I/O 有限制。解决方案:确保 cursor agent 在 host 机器上运行,而非 sandbox 内。


8. Channel 配置:Telegram

OpenClaw 支持多种接入渠道(Telegram、Discord、Signal、WhatsApp 等),其中 Telegram 是目前体验最完整的一个。2026 年 3 月 Telegram Bot API 9.5 正式向所有 Bot 开放了 sendMessageDraft 接口,这意味着 OpenClaw 可以在 AI 生成过程中实时更新草稿消息——即流式输出(Streaming Preview)。

8.1 基础配置

首先通过 BotFather 创建 Bot 并获取 token,然后在 OpenClaw 配置文件中写入:

{
  channels: {
    telegram: {
      enabled: true,
      botToken: "YOUR_BOT_TOKEN",
      dmPolicy: "pairing",       // pairing | allowlist | open | disabled
      allowFrom: [123456789],    // 允许的 Telegram 用户数字 ID
    },
  },
}

启动 gateway 后首次 DM,需要走一次配对流程:

openclaw gateway          # 启动
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>

dmPolicy 推荐使用 pairing(默认),首次配对后自动加入白名单,不需要每次配置 allowFrom

8.2 流式输出(Streaming Preview)

这是 Telegram 作为最佳界面的核心优势。

OpenClaw 有两层流式机制:

层级机制说明
Preview streamingchannels.telegram.streaming生成过程中实时更新消息内容
Block streamingagents.defaults.blockStreamingDefault将长回复拆成多条消息逐步发出

Preview streaming 配置:

{
  channels: {
    telegram: {
      streaming: "partial",   // off | partial | block | progress
    },
  },
}
  • partial(推荐):在 DM 中使用 sendMessageDraft 原地更新,在群组中发一条预览消息然后持续编辑。生成完成后没有第二条消息,干净。
  • block:以分块追加的方式更新预览,适合非常长的回复。
  • off:禁用预览,等 AI 全部生成完再发送。

在私聊中,partial 模式下的用户体验接近桌面 Claude Web 的流式效果:可以看到文字逐渐出现,不需要等待整个回复生成完成。

Block streaming 配置(可选):

{
  agents: {
    defaults: {
      blockStreamingDefault: "off",   // 默认关闭,开启后长回复分条发送
    },
  },
}

注意:Preview streaming 和 Block streaming 同时开启时,Telegram 会自动跳过 Preview 以避免双重流式,优先走 Block 模式。一般只开 Preview streaming 即可。

8.3 访问控制

私聊权限:

{
  channels: {
    telegram: {
      dmPolicy: "allowlist",
      allowFrom: [123456789],   // 数字 ID,不支持 @username
    },
  },
}

如果配置了 @username 格式的旧条目,运行 openclaw doctor --fix 会自动解析为数字 ID。

群组权限:

{
  channels: {
    telegram: {
      groupPolicy: "allowlist",    // open | allowlist | disabled
      groups: {
        "-1001234567890": {        // 群组数字 ID(负数)
          requireMention: true,    // 是否需要 @bot 才响应
          groupPolicy: "open",     // 该群组允许所有成员
        },
        "*": {
          requireMention: true,    // 全局默认:需要 @mention
        },
      },
    },
  },
}

获取群组 ID:将群消息转发给 @getidsbot,或从 openclaw logs --follow 中读取 chat.id

群组 Bot 默认开启 Privacy Mode,只能收到 @mention 的消息。如果需要收到所有群消息:BotFather → /setprivacy → Disable,然后将 Bot 移出群组重新加入。

8.4 Inline Buttons 与 Reactions

Inline Buttons(内嵌按钮)允许 AI 在回复中发送可点击的按钮,适合确认操作、快速选择等场景:

{
  channels: {
    telegram: {
      capabilities: {
        inlineButtons: "allowlist",   // off | dm | group | all | allowlist
      },
    },
  },
}

AI 使用示例(发送带按钮的消息):

{
  action: "send",
  channel: "telegram",
  to: "123456789",
  message: "确认执行此操作?",
  buttons: [
    [
      { text: "确认", callback_data: "confirm", style: "success" },
      { text: "取消", callback_data: "cancel", style: "danger" },
    ],
  ],
}

Reactions 配置(消息处理中显示 Ack 表情):

{
  channels: {
    telegram: {
      ackReaction: "👀",         // 处理中显示的 Ack 表情
      reactionLevel: "minimal",  // off | ack | minimal | extensive
      reactionNotifications: "own",  // 用户对 Bot 消息点表情时是否触发通知
    },
  },
}

8.5 自定义命令菜单

在 Telegram 中,Bot 可以注册命令菜单(左下角的 / 列表):

{
  channels: {
    telegram: {
      customCommands: [
        { command: "brief", description: "今日简报" },
        { command: "stock", description: "查询股票" },
        { command: "archive", description: "归档当前内容" },
      ],
    },
  },
}

命令只是菜单入口,行为由 AI 根据 skill 和上下文决定,不需要额外实现处理函数。

8.6 为什么 Telegram 目前是最佳界面

与其他渠道相比,Telegram Bot API 9.5 之后的组合优势:

  • 流式预览sendMessageDraft 原生支持,DM 中无闪烁、无重复消息
  • Inline Buttons:可以实现交互式确认流程,其他渠道支持有限
  • Forum Topics:一个 Bot 可以在超级群组的不同 Topic 下维护独立会话,适合多主题管理
  • Reactions:可以作为轻量级的处理状态指示器
  • 无需 App:手机端 Telegram 随时可用,延迟低

Dashboard(Web 界面)适合长时间坐在电脑前的工作;Telegram 适合移动场景和需要即时通知的任务。目前两者都在使用,Telegram 作为主要入口。


9. 多模型切换

OpenClaw 支持在同一个 gateway 实例内切换模型,无需重启服务。这个能力在不同任务场景下很有用——写作和调研用强模型,简单问答用快模型。

9.1 模型配置

在配置文件中设置主模型和 fallback 链:

{
  agents: {
    defaults: {
      model: {
        primary: "openrouter/anthropic/claude-sonnet-4-6",
        fallbacks: [
          "openrouter/google/gemini-2.5-pro",
          "openrouter/deepseek/deepseek-chat",
        ],
      },
    },
  },
}

Fallback 链的触发顺序:主模型失败(限速、故障、超时)→ 依次尝试 fallback 列表。

使用 OpenRouter 作为统一入口的优势:一个 API Key 接入几十个模型,不需要为每个 provider 单独管理 key 和配额。

9.2 常用模型 Alias

配置 alias 后,切换模型时不需要输入完整路径:

{
  agents: {
    defaults: {
      models: {
        "openrouter/anthropic/claude-sonnet-4-6": { alias: "sonnet" },
        "openrouter/google/gemini-2.5-pro":       { alias: "gemini" },
        "openrouter/deepseek/deepseek-chat":       { alias: "deepseek" },
        "openrouter/deepseek/deepseek-reasoner":   { alias: "r1" },
        "minimax/MiniMax-M2.5":                    { alias: "minimax" },
      },
    },
  },
}

CLI 配置 alias:

openclaw models aliases add sonnet openrouter/anthropic/claude-sonnet-4-6
openclaw models aliases add r1 openrouter/deepseek/deepseek-reasoner

9.3 运行时切换

在 Telegram(或任何渠道)的对话中,直接发送 /model 指令:

/model              → 打开模型选择器(编号列表)
/model list         → 列出所有可用模型
/model sonnet       → 切换到 claude-sonnet-4-6
/model r1           → 切换到 DeepSeek R1(推理模型)
/model status       → 查看当前模型和 auth 状态

切换只影响当前 session,不修改配置文件。重新 /new 开启新 session 后恢复默认模型。

9.4 不同任务的模型选择

实际使用中形成的经验:

任务类型推荐模型原因
日常问答、写作Claude Sonnet(默认)速度与质量的平衡点
长文档处理Gemini 2.5 Pro200 万 token 上下文
代码任务Claude Sonnet / Cursor AgentCursor 有项目上下文优势
快速搜索/简单回答DeepSeek V3速度快,成本低

推理模型(R1 等)适合需要逐步分析的任务,但响应时间明显更长;常规对话没必要用。

一个实践经验:用 Sonnet 跑一遍,让便宜模型参考执行。 对于定时任务和 heartbeat 这类重复性流程,可以先用 claude-sonnet-4-6 完整跑一遍,让它把执行过程中的判断、步骤和注意事项整理成 skill 文档写入 SKILL.md。之后把这些任务的默认模型切换到 MiniMax 或 DeepSeek V3——它们在有详细 skill 文档可参考的情况下,执行效果接近 Sonnet,但成本低一个数量级。本质上是用一次 Sonnet 的调用换来后续大量廉价调用的质量保障。

9.5 模型 Failover 机制

OpenClaw 内置了 provider 级别的自动 failover:

主模型请求 → 限速(429)→ 自动切换到 Fallback 1
                    → Fallback 1 也限速 → 切换到 Fallback 2
                    → 所有 fallback 失败 → 返回错误

这对于需要保持可用性的场景很有用,例如夜间反思 cron 跑的时候不需要担心某个 provider 临时限速导致任务失败。

9.6 多 Provider 鉴权

当前使用的 provider 和对应 key 配置方式:

Provider环境变量说明
OpenRouterOPENROUTER_API_KEY统一入口,推荐
AnthropicANTHROPIC_API_KEY直连,无需 OpenRouter 中转
GoogleGEMINI_API_KEYGemini 系列
DeepSeekDEEPSEEK_API_KEY直连,价格低

Key 轮换支持:对于有多个 key 的 provider,可以配置 OPENROUTER_API_KEYS(逗号分隔),限速时自动轮换,不需要手动干预。


10. macOS 安全配置

OpenClaw 在 Mac 上运行意味着它持续在后台有网络连接、文件读写权限,以及对本地 CLI 工具的执行权限。在完成基础功能配置之后,有必要对宿主机的安全状态做一次梳理。

10.1 端口暴露检查

首先确认哪些端口在对外监听:

# 查看所有监听中的 TCP/UDP 端口及对应进程
sudo /usr/sbin/lsof -iTCP -sTCP:LISTEN -n -P
sudo /usr/sbin/lsof -iUDP -n -P

注意:macOS 默认 PATH 中不含 /usr/sbin,需要用完整路径 /usr/sbin/lsof,否则命令找不到。

典型输出解读:

端口常见来源风险评估
5900屏幕共享 / VNC 客户端(如 UURemote)需确认是否有密码保护,是否只限局域网
22SSH(系统远程登录服务)如不需要远程 SSH,建议关闭
8080OrbStack / 容器管理正常开发工具,低风险
3000–9000本地开发调试进程正常,确认是自己的项目即可

5900 端口是一个常见误报点——很多第三方远程桌面工具(UURemote 等)复用了 VNC 端口,但并非裸奔的 VNC,只要工具本身有密码保护,风险可控。

10.2 防火墙配置

macOS 内置应用防火墙,但默认安装后不一定开启:

检查防火墙状态:

/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
# 输出: Firewall is enabled. (State = 1) 为已开启

检查隐身模式(Stealth Mode):

/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode
# 输出: Stealth mode enabled 为已开启

开启隐身模式:

sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on

或通过图形界面:系统设置 → 网络 → 防火墙 → 选项 → 开启”隐身模式”

隐身模式的作用:正常情况下 Mac 对外部 ping 和端口探测会返回响应(“这个端口没开”),开启隐身模式后直接丢包不响应,使自动化扫描工具无法判断该 IP 是否在线。对日常使用没有任何影响,只影响被动探测行为。

查看防火墙应用白名单:

/usr/libexec/ApplicationFirewall/socketfilterfw --listapps

检查白名单里是否有已卸载或不再使用的应用仍然保留了允许规则。TeamViewer 是典型例子——卸载后防火墙规则可能还在,需要手动清理。

10.3 OpenClaw 自身安全审计

OpenClaw 内置了安全审计命令,会扫描 skill 脚本中的可疑行为:

openclaw security audit

审计会检查:

  • skill 脚本中的环境变量读取行为(防止 credential harvesting)
  • 对外网络请求(尤其是读取敏感 env 后紧接着发送网络请求的模式)
  • 配置文件中的 denyCommands 有效性

实际输出格式如下(0 critical 是目标状态):

OpenClaw security audit
Summary: 0 critical · 2 warn · 1 info
Run deeper: openclaw security audit --deep

WARN
gateway.trusted_proxies_missing Reverse proxy headers are not trusted
  gateway.bind is loopback and gateway.trustedProxies is empty. If you expose
  the Control UI through a reverse proxy, configure trusted proxies so
  local-client checks cannot be spoofed.
  Fix: Set gateway.trustedProxies to your proxy IPs or keep the Control UI local-only.
gateway.nodes.deny_commands_ineffective Some gateway.nodes.denyCommands entries are ineffective
  gateway.nodes.denyCommands uses exact node command-name matching only
  (for example `system.run`), not shell-text filtering inside a command payload.
- Unknown command names: camera.snap, camera.clip, screen.record, calendar.add
  Fix: Use exact command names (for example: canvas.present, canvas.hide).

INFO
summary.attack_surface Attack surface summary
  groups: open=0, allowlist=2
tools.elevated: enabled
hooks.webhooks: disabled
hooks.internal: enabled
browser control: enabled
trust model: personal assistant (one trusted operator boundary)

两个常见 WARN 项的处理方式:

  • gateway.trusted_proxies_missing:不走反代直接本地访问的话忽略即可
  • gateway.nodes.deny_commands_ineffectivedenyCommands 只做精确命令名匹配,列出的 unknown command names 说明配置的条目在默认命令集里找不到,需要改成正确的命令 ID(如 canvas.present

想要更深度的扫描可以加 --deep 参数:

openclaw security audit --deep

10.4 SSH 管理

如果不需要从外部 SSH 进入这台 Mac,关闭远程登录服务可以减少攻击面:

图形界面:系统设置 → 通用 → 共享 → 关闭”远程登录”

命令行

# 停止 SSH 服务
sudo systemsetup -setremotelogin off

# 确认状态
sudo systemsetup -getremotelogin

如果确实需要 SSH 访问,建议:

  • 禁用密码登录,只允许密钥认证(PasswordAuthentication no
  • 修改默认端口(降低自动化扫描命中率)
  • 考虑结合 Tailscale 等零信任方案,避免直接暴露 22 端口

10.5 远程访问工具清理

远程桌面类工具(TeamViewer、UU远程、向日葵、AnyDesk 等)有以下特点:常驻后台、开机自启、持续监听端口。即使平时不用,只要装着就是潜在攻击面。

如果本机安装了 TeamViewer 或 UU远程这类工具,需要额外排查两件事:

  1. 是否开启了自动连接——很多工具默认允许无人值守访问(Unattended Access),即不需要本机确认就能远程登入。确认这个选项是否关闭,或者访问密码是否是你自己设置的强密码,而非工具自动生成的弱密码。
  2. 登录的是自己的账号——确认工具绑定的账号是你本人的,没有被他人账号关联。TeamViewer 尤其要检查”受信任设备”列表,清理掉不认识的设备。

清理建议:

  1. 如果只偶尔用,用到时再开,不用就退出后台进程
  2. 彻底不再需要的,从 /Applications 删除,同时清理防火墙规则
  3. 保留一个即可,不要多个重叠

确认某个工具是否还在运行:

# 以 UURemote 为例
pgrep -l UURemote
# 或
ps aux | grep -i uuremote

10.6 定期安全检查

建议将安全检查纳入 OpenClaw 的 cron 任务,例如每周运行一次:

{
  "name": "weekly-security-check",
  "schedule": "0 10 * * 1",
  "task": "执行安全检查:运行 openclaw security audit,检查监听端口变化(与上次结果对比),如有新增问题或未知端口,通过 Telegram 推送告警。结果记录到 memory/YYYY-MM-DD.md。"
}

这样不需要手动记得定期检查,有变化了才通知,没变化就静默。


11. 完整目录结构

~/.openclaw/workspace/

├── AGENTS.md          # 行为规范(启动必读)
├── SOUL.md            # 行为原则
├── IDENTITY.md        # 身份定义
├── USER.md            # 用户档案
├── HEARTBEAT.md       # Heartbeat 执行清单
├── MEMORY.md          # 全局记忆索引(≤40行)
├── NOW.md             # 当前状态(每次heartbeat覆写)

├── memory/
│   ├── 2026-03-06.md              # 今日日志
│   ├── heartbeat-state.json       # Heartbeat 状态追踪
│   ├── projects.md                # 项目进度
│   ├── infra.md                   # 基础设施配置
│   ├── knowledge/
│   │   ├── INDEX.md               # 知识导航
│   │   ├── lessons/               # 经验/踩坑
│   │   ├── decisions/             # 重要决策
│   │   └── people/                # 人物信息
│   └── .archive/                  # 冷存储

├── scripts/
│   └── memlog.sh                  # 日志追加脚本

└── skills/
    ├── gog/                       # Google Workspace
    ├── perplexity/                # AI 搜索
    ├── research-learning/         # 调研学习工作流
    ├── newsletter-archiver/       # Newsletter 归档
    ├── akshare-cn-market/         # A 股数据
    ├── us-stock-analysis/         # 美股分析
    ├── stock-info-explorer/       # 实时行情+图表
    ├── xmind-generator/           # 脑图生成
    └── s1cli/                     # 论坛操作

12. 一些观察

配置这套系统的过程中,有几个感受值得记录。

配置 AI 是一种自我梳理的过程。USER.md 需要明确自己的工作性质和关注点;写 SOUL.md 需要想清楚自己对协作方式的偏好;设计知识库结构,实质上是在判断什么信息对自己有长期价值。这些问题平时不太会显式思考,配置的过程把它们逼出来了。

Markdown 文件作为 AI 记忆载体,比想象中稳定。 人类可以直接编辑,git 可以版本控制,调试时打开文件就能看到完整状态——这种透明度在其他方案里很难得到。代价是检索效率,但配合 OpenClaw 的语义搜索(memory_search),实际使用中几乎感受不到差距。

skill 的迭代闭环很重要。 每个 skill 的 SKILL.md 末尾都有”经验积累”区块,每次发现问题就追加一条改进记录。这些记录不是给人看的,是给 AI 下次执行同类任务时参考的——相当于把操作 SOP 的迭代也交给了系统本身。

评论