龙虾调教过程
OpenClaw 是一个可以本地部署的 AI 助手框架,支持通过配置文件定制行为,通过 Skills 系统扩展能力,并提供跨 session 的持久化记忆机制。这篇文章记录从默认安装状态开始,逐步将其配置为一个有身份、有记忆、能主动工作的私人助理的完整过程。
1. 从默认状态说起
OpenClaw 安装完成后,初始状态相当于一个通用 AI 助手:有工具调用能力,能搜索、执行代码,但对用户一无所知,每次 session 独立,也没有任何可扩展的业务逻辑。
这个默认状态对于轻度使用足够,但如果希望它真正融入工作流,有几个核心问题需要解决:
- 它不知道你是谁——没有背景信息,每次都要重新建立上下文
- 它没有记忆——session 结束后一切归零,下次开始不知道上次发生了什么
- 行为边界不清——什么可以直接做,什么需要确认,没有规范
- 能力固定——默认 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 streaming | channels.telegram.streaming | 生成过程中实时更新消息内容 |
| Block streaming | agents.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 Pro | 200 万 token 上下文 |
| 代码任务 | Claude Sonnet / Cursor Agent | Cursor 有项目上下文优势 |
| 快速搜索/简单回答 | 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 | 环境变量 | 说明 |
|---|---|---|
| OpenRouter | OPENROUTER_API_KEY | 统一入口,推荐 |
| Anthropic | ANTHROPIC_API_KEY | 直连,无需 OpenRouter 中转 |
GEMINI_API_KEY | Gemini 系列 | |
| DeepSeek | DEEPSEEK_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) | 需确认是否有密码保护,是否只限局域网 |
| 22 | SSH(系统远程登录服务) | 如不需要远程 SSH,建议关闭 |
| 8080 | OrbStack / 容器管理 | 正常开发工具,低风险 |
| 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_ineffective:denyCommands只做精确命令名匹配,列出的 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远程这类工具,需要额外排查两件事:
- 是否开启了自动连接——很多工具默认允许无人值守访问(Unattended Access),即不需要本机确认就能远程登入。确认这个选项是否关闭,或者访问密码是否是你自己设置的强密码,而非工具自动生成的弱密码。
- 登录的是自己的账号——确认工具绑定的账号是你本人的,没有被他人账号关联。TeamViewer 尤其要检查”受信任设备”列表,清理掉不认识的设备。
清理建议:
- 如果只偶尔用,用到时再开,不用就退出后台进程
- 彻底不再需要的,从
/Applications删除,同时清理防火墙规则 - 保留一个即可,不要多个重叠
确认某个工具是否还在运行:
# 以 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 的迭代也交给了系统本身。