OpenClaw实战 #07:从 0 写一个自定义 Skill——让 AI 自动同步 Notion 待办到飞书(完整代码)

OpenClaw实战 #07:从 0 写一个自定义 Skill------让 AI 自动同步 Notion 待办到飞书(完整代码)

🎯本文目标:从零开始,手把手带你写出一个完整可用的 OpenClaw 自定义 Skill。读完后你将掌握:

  • Skill 的目录结构与 [SKILL.md]规范
  • 如何让 Agent 调用外部 API(Notion + 飞书)
  • policy.yaml 权限声明的正确姿势
  • 从开发到调试到上线的完整链路

前置条件:已完成 OpenClaw 安装并能正常运行(参考本系列 #02)


一、为什么要自己写 Skill

如果你跟完了本系列的 #05 架构拆解,你已经知道:

  • OpenClaw 的能力边界 = 内置 Tool + 加载的 Skill
  • Skill 本质上是一份 Markdown 指令文件,教 LLM 在特定场景下该怎么调用工具、按什么流程完成任务
  • Skill 不是"插件代码",而是 "可审计的能力合同"

但内置 Skill 和社区 Skill 永远不可能覆盖你的私有场景。比如:

  • 你想让 Agent 每天早上把 Notion 里 Status = To Do 的任务同步到飞书群
  • 你想让 Agent 自动把飞书收到的客户反馈写回 Notion 数据库
  • 你想让 Agent 定时检查某个 API 的健康状态并推送告警

这些场景,只有自定义 Skill 能解决

而且,一旦你掌握了 Skill 开发的完整流程,你就从 OpenClaw 的"使用者"变成了"扩展者"------这是质变。


二、我们要做什么:完整需求描述

场景

你在 Notion 中维护一个任务数据库,字段包括:

  • Name(标题)
  • Status(状态:To Do / In Progress / Done)
  • Priority(优先级:High / Medium / Low)
  • Due Date(截止日期)

你希望 OpenClaw 能够:

  1. 查询 Notion 数据库中所有 Status = To Do 的任务
  2. 格式化 成结构清晰的消息
  3. 推送 到指定的飞书群机器人

并且可以通过自然语言触发,比如:

"帮我把 Notion 里今天待办同步到飞书群"


三、准备工作(5 分钟搞定)

3.1 获取 Notion API Token 和数据库 ID

第一步:创建 Notion Integration

  1. 打开 https://www.notion.so/my-integrations
  2. 点击 "New integration"
  3. 填写名称(如 OpenClaw-Sync),选择关联的 Workspace
  4. 记录生成的 Internal Integration Secret (以 ntn_ 开头)

第二步:获取数据库 ID

  1. 打开你的 Notion 任务数据库页面

  2. 看浏览器地址栏,URL 格式如下:

    https://www.notion.so/yourworkspace/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?v=...
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    这一段就是 Database ID

  3. 复制这 32 位字符串

第三步:给 Integration 授权

  1. 在 Notion 数据库页面点击右上角 ...Connections
  2. 搜索并添加你刚创建的 OpenClaw-Sync Integration

3.2 创建飞书群机器人 Webhook

  1. 打开目标飞书群 → 设置 → 群机器人 → 添加机器人
  2. 选择 "自定义机器人"
  3. 填写名称(如 OpenClaw 同步
  4. 记录生成的 Webhook URL (以 https://open.feishu.cn/open-apis/bot/v2/hook/ 开头)



3.3 配置环境变量

将凭证写入 OpenClaw 的环境变量文件:

bash 复制代码
# 编辑 OpenClaw 环境配置
nano ~/.openclaw/.env

# 添加以下两行
NOTION_API_KEY=ntn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

保存后重启 Gateway:

bash 复制代码
openclaw gateway restart

⚠️ 安全提醒 :永远不要把 API Key 硬编码在 SKILL.md 或脚本里。通过环境变量注入是 OpenClaw 的推荐做法。


四、Skill 目录结构:先搭骨架

OpenClaw 的 Skill 加载有三层优先级:

路径 作用域 优先级 适用场景
./skills/ 当前项目 ⭐⭐⭐⭐⭐ 最高 项目专属定制
~/.openclaw/skills/ 本机全局 ⭐⭐⭐⭐ 个人通用高频 Skill
内置 Bundled 所有 Agent ⭐ 最低 基础能力

我们这次写的是个人通用 Skill,放在 ~/.openclaw/skills/ 下:

bash 复制代码
# 创建 Skill 目录
mkdir -p ~/.openclaw/skills/notion-feishu-sync
cd ~/.openclaw/skills/notion-feishu-sync

# 创建标准目录结构
mkdir scripts references
touch SKILL.md
touch scripts/sync_notion_to_feishu.sh
touch scripts/query_notion.py
touch scripts/push_feishu.py

最终目录结构:

复制代码
notion-feishu-sync/
├── SKILL.md                          # 核心:Skill 定义 + LLM 指令
├── scripts/
│   ├── query_notion.py               # 查询 Notion 数据库
│   ├── push_feishu.py                # 推送到飞书
│   └── sync_notion_to_feishu.sh      # 编排脚本(查询 → 格式化 → 推送)
└── references/
    └── notion_api_cheatsheet.md      # 可选:Notion API 速查(供 LLM 按需加载)

五、写 [SKILL.md]:Skill 的灵魂

SKILL.md 是整个 Skill 的核心。它不是给人看的文档,而是给 LLM 看的指令合同

LLM 通过读取 [SKILL.md]来决定:

  • 什么时候触发这个 Skill
  • 调用哪些工具
  • 按什么顺序执行
  • 遇到错误怎么处理

完整 SKILL.md

markdown 复制代码
---
name: notion-feishu-sync
description: 查询 Notion 数据库中的待办任务并推送到飞书群机器人
user-invocable: true
metadata:
  openclaw:
    emoji: "📋"
    skillKey: "notion-feishu-sync"
    requires:
      bins: ["python3", "curl"]
      env: ["NOTION_API_KEY", "FEISHU_WEBHOOK_URL"]
---

# Notion → 飞书 待办同步

## 触发条件

当用户要求同步 Notion 待办到飞书,或要求查看 Notion 中的待办任务并发送到飞书群时,使用此 Skill。

常见触发语句示例:
- "把 Notion 待办同步到飞书"
- "帮我把今天的任务推到飞书群"
- "同步一下 Notion 里的 To Do"
- "Notion 飞书同步"

## 执行流程

严格按以下步骤执行,不要跳过任何一步:

### Step 1:验证环境

执行以下命令确认环境变量已配置:
[ -z "$NOTION_API_KEY" ] && echo "ERROR: NOTION_API_KEY not set" && exit 1
[ -z "$FEISHU_WEBHOOK_URL" ] && echo "ERROR: FEISHU_WEBHOOK_URL not set" && exit 1
echo "Environment OK"

如果任一变量未设置,停止执行并告知用户需要配置环境变量。

### Step 2:查询 Notion 待办

执行查询脚本:
python3 ~/.openclaw/skills/notion-feishu-sync/scripts/query_[notion.py](http://notion.py)

该脚本会输出 JSON 格式的待办列表。如果输出为空数组 `[]`,告知用户当前没有待办任务,无需推送。

### Step 3:推送到飞书

将 Step 2 的输出通过管道传递给推送脚本:
python3 ~/.openclaw/skills/notion-feishu-sync/scripts/query_[notion.py](http://notion.py) | python3 ~/.openclaw/skills/notion-feishu-sync/scripts/push_feishu.py

bash ~/.openclaw/skills/notion-feishu-sync/scripts/sync_notion_to_feishu.sh

### Step 4:确认结果

脚本执行成功后,向用户报告:
- 同步了多少条待办
- 包含哪些高优先级任务
- 推送目标(飞书群)

## 错误处理

- Notion API 返回 401:API Key 无效或过期,提示用户检查 `NOTION_API_KEY`
- Notion API 返回 404:数据库 ID 错误,提示用户检查配置
- 飞书 Webhook 返回非 0 code:Webhook URL 可能失效,提示用户重新生成
- 网络超时:提示用户检查网络连接,建议稍后重试

## 安全边界

- 此 Skill 只读取 Notion 数据,不修改任何 Notion 内容
- 此 Skill 只向飞书 Webhook 发送消息,不执行任何其他飞书 API 操作
- 不要在日志或输出中暴露 API Key 或 Webhook URL 的完整内容

SKILL.md 关键设计解读

字段 / 段落 为什么这么写
user-invocable: true 允许用户通过自然语言主动触发,而不是只能被其他 Skill 调用
requires.bins 声明运行依赖。如果系统没有 python3 或 curl,Skill 不会被加载,避免运行时才报错
requires.env 声明环境变量依赖。未配置时 Skill 不可见,防止 Agent 在缺少凭证时盲目执行
触发条件 + 示例语句 帮助 LLM 精准识别何时该调用这个 Skill,减少误触发
严格的 Step 1-4 流程 让 LLM 按确定性路径执行,而不是自由发挥。这是 Skill 区别于普通 Prompt 的核心
错误处理段落 教 LLM 遇到异常时该怎么反馈,而不是默默失败或编造结果
安全边界段落 显式声明 Skill 能做什么、不能做什么。这是 #05-5 里讲的"防御性设计"的落地

六、写执行脚本:让 Skill 真正能干活

6.1 query_notion.py --- 查询 Notion 待办

python 复制代码
#!/usr/bin/env python3
"""查询 Notion 数据库中 Status = To Do 的任务,输出 JSON"""

import os
import sys
import json
import urllib.request
import urllib.error

# ====== 配置 ======
NOTION_API_KEY = os.environ.get("NOTION_API_KEY")
# 将下面的 ID 替换为你自己的 Notion 数据库 ID
DATABASE_ID = os.environ.get("NOTION_DATABASE_ID", "在这里填入你的数据库ID")
NOTION_API_VERSION = "2022-06-28"

def query_notion_todos():
    """查询 Notion 数据库中所有 To Do 状态的任务"""
    if not NOTION_API_KEY:
        print(json.dumps({"error": "NOTION_API_KEY not set"}))
        sys.exit(1)

    url = f"https://api.notion.com/v1/databases/{DATABASE_ID}/query"

    # 构建筛选条件:Status = To Do
    payload = json.dumps({
        "filter": {
            "property": "Status",
            "status": {
                "equals": "To Do"
            }
        },
        "sorts": [
            {
                "property": "Priority",
                "direction": "ascending"
            },
            {
                "property": "Due Date",
                "direction": "ascending"
            }
        ]
    }).encode("utf-8")

    headers = {
        "Authorization": f"Bearer {NOTION_API_KEY}",
        "Content-Type": "application/json",
        "Notion-Version": NOTION_API_VERSION
    }

    req = urllib.request.Request(url, data=payload, headers=headers, method="POST")

    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            data = json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        error_body = e.read().decode("utf-8") if e.fp else ""
        print(json.dumps({
            "error": f"Notion API HTTP {e.code}",
            "detail": error_body[:200]
        }))
        sys.exit(1)
    except Exception as e:
        print(json.dumps({"error": str(e)}))
        sys.exit(1)

    # 解析结果
    tasks = []
    for page in data.get("results", []):
        props = page.get("properties", {})

        # 提取标题
        name_prop = props.get("Name", {}).get("title", [])
        name = name_prop[0]["plain_text"] if name_prop else "(无标题)"

        # 提取优先级
        priority_prop = props.get("Priority", {}).get("select")
        priority = priority_prop["name"] if priority_prop else "未设置"

        # 提取截止日期
        due_prop = props.get("Due Date", {}).get("date")
        due_date = due_prop["start"] if due_prop else "无截止日期"

        tasks.append({
            "name": name,
            "priority": priority,
            "due_date": due_date,
            "url": page.get("url", "")
        })

    print(json.dumps(tasks, ensure_ascii=False, indent=2))

if __name__ == "__main__":
    query_notion_todos()

6.2 push_feishu.py --- 推送到飞书群

python 复制代码
#!/usr/bin/env python3
"""从 stdin 读取任务 JSON,格式化后推送到飞书群机器人"""

import os
import sys
import json
import urllib.request
import urllib.error
from datetime import datetime

FEISHU_WEBHOOK_URL = os.environ.get("FEISHU_WEBHOOK_URL")

PRIORITY_EMOJI = {
    "High": "🔴",
    "Medium": "🟡",
    "Low": "🟢",
    "未设置": "⚪"
}

def format_tasks(tasks):
    """将任务列表格式化为飞书富文本消息"""
    if not tasks:
        return None

    now = datetime.now().strftime("%Y-%m-%d %H:%M")
    high_count = sum(1 for t in tasks if t["priority"] == "High")

    lines = []
    for i, task in enumerate(tasks, 1):
        emoji = PRIORITY_EMOJI.get(task["priority"], "⚪")
        due = task["due_date"] if task["due_date"] != "无截止日期" else "无 DDL"
        lines.append(f"{i}. {emoji} {task['name']}\n   优先级: {task['priority']} | 截止: {due}")

    task_block = "\n".join(lines)

    # 构建飞书卡片消息
    card = {
        "msg_type": "interactive",
        "card": {
            "header": {
                "title": {
                    "tag": "plain_text",
                    "content": f"📋 Notion 待办同步 ({len(tasks)} 项)"
                },
                "template": "blue" if high_count == 0 else "red"
            },
            "elements": [
                {
                    "tag": "div",
                    "text": {
                        "tag": "lark_md",
                        "content": task_block
                    }
                },
                {
                    "tag": "hr"
                },
                {
                    "tag": "note",
                    "elements": [
                        {
                            "tag": "plain_text",
                            "content": f"🤖 由 OpenClaw 自动同步 | {now}"
                        }
                    ]
                }
            ]
        }
    }

    return card

def push_to_feishu(message):
    """发送消息到飞书 Webhook"""
    if not FEISHU_WEBHOOK_URL:
        print("ERROR: FEISHU_WEBHOOK_URL not set")
        sys.exit(1)

    payload = json.dumps(message).encode("utf-8")
    headers = {"Content-Type": "application/json"}

    req = urllib.request.Request(
        FEISHU_WEBHOOK_URL,
        data=payload,
        headers=headers,
        method="POST"
    )

    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            if result.get("code") == 0:
                print(f"SUCCESS: 推送成功")
            else:
                print(f"WARN: 飞书返回非零 code: {result}")
    except urllib.error.HTTPError as e:
        print(f"ERROR: 飞书 API HTTP {e.code}")
        sys.exit(1)
    except Exception as e:
        print(f"ERROR: {e}")
        sys.exit(1)

if __name__ == "__main__":
    # 从 stdin 读取任务 JSON
    raw = sys.stdin.read().strip()

    try:
        tasks = json.loads(raw)
    except json.JSONDecodeError:
        print(f"ERROR: 无法解析输入 JSON")
        sys.exit(1)

    if isinstance(tasks, dict) and "error" in tasks:
        print(f"ERROR from upstream: {tasks['error']}")
        sys.exit(1)

    if not tasks:
        print("INFO: 当前没有待办任务,无需推送")
        sys.exit(0)

    message = format_tasks(tasks)
    if message:
        push_to_feishu(message)
        print(f"共同步 {len(tasks)} 条待办任务")

6.3 sync_notion_to_feishu.sh --- 编排脚本

bash 复制代码
#!/usr/bin/env bash
# 编排脚本:查询 Notion → 格式化 → 推送飞书
# 使用方式:bash sync_notion_to_feishu.sh

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

echo "[1/3] 检查环境变量..."
if [ -z "${NOTION_API_KEY:-}" ]; then
    echo "ERROR: NOTION_API_KEY 未设置"
    exit 1
fi
if [ -z "${FEISHU_WEBHOOK_URL:-}" ]; then
    echo "ERROR: FEISHU_WEBHOOK_URL 未设置"
    exit 1
fi
echo "      环境变量 OK"

echo "[2/3] 查询 Notion 待办..."
TASKS=$(python3 "$SCRIPT_DIR/query_notion.py")

# 检查是否有任务
TASK_COUNT=$(echo "$TASKS" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo "0")

if [ "$TASK_COUNT" = "0" ]; then
    echo "      当前没有待办任务,无需推送"
    exit 0
fi

echo "      找到 $TASK_COUNT 条待办任务"

echo "[3/3] 推送到飞书..."
echo "$TASKS" | python3 "$SCRIPT_DIR/push_feishu.py"

echo ""
echo "✅ 同步完成:$TASK_COUNT 条待办已推送到飞书群"

给脚本加上执行权限:

bash 复制代码
chmod +x ~/.openclaw/skills/notion-feishu-sync/scripts/*.sh
chmod +x ~/.openclaw/skills/notion-feishu-sync/scripts/*.py

七、配置 policy.yaml:给 Skill 划安全边界

如果你跟过本系列 #05-6(Tool + Policy),你知道 policy.yaml 是 Agent 的安全闸门

在 OpenClaw 的全局或项目 policy 中,为这个 Skill 添加精确的权限声明:

yaml 复制代码
# ~/.openclaw/policy.yaml(追加以下内容)

skills:
  notion-feishu-sync:
    # 允许的工具
    allowed_tools:
      - exec           # 需要执行脚本
      - read           # 需要读取脚本文件
    
    # 网络访问白名单
    network:
      allow:
        - "api.notion.com"
        - "open.feishu.cn"
    
    # 文件系统访问范围
    filesystem:
      read:
        - "~/.openclaw/skills/notion-feishu-sync/**"
      write: []          # 不需要写入任何文件
    
    # 环境变量访问
    env:
      - "NOTION_API_KEY"
      - "NOTION_DATABASE_ID"
      - "FEISHU_WEBHOOK_URL"
    
    # 明确禁止
    deny:
      - "不要修改或删除 Notion 中的任何数据"
      - "不要向飞书发送除任务同步以外的任何消息"
      - "不要在输出中暴露完整的 API Key 或 Webhook URL"

policy 设计要点

🔒核心原则:Skill 能做的事 = policy 显式允许的事。

不被允许的,默认就是禁止的。

  • network.allow 只开放两个域名,Agent 不会去请求其他任何外部服务
  • filesystem.write: [] 明确声明不需要写权限
  • deny 段落用自然语言告诉 LLM 绝对不能做的事

八、调试全流程

8.1 确认 Skill 已加载

bash 复制代码
openclaw skills status

输出中应该能看到:

复制代码
📋 notion-feishu-sync  (user, ~/.openclaw/skills/notion-feishu-sync)
   requires: python3 ✅, curl ✅
   env: NOTION_API_KEY ✅, FEISHU_WEBHOOK_URL ✅

如果显示 ❌,说明依赖或环境变量未满足,Skill 不会被加载。

8.2 单独测试脚本

先脱离 OpenClaw,手动验证每个脚本:

bash 复制代码
# 测试 Notion 查询
python3 ~/.openclaw/skills/notion-feishu-sync/scripts/query_notion.py

# 预期输出:JSON 格式的任务列表
# [
#   {
#     "name": "写 CSDN 博文",
#     "priority": "High",
#     "due_date": "2026-03-17",
#     "url": "https://notion.so/..."
#   },
#   ...
# ]
bash 复制代码
# 测试飞书推送(用 Notion 查询的输出作为输入)
python3 ~/.openclaw/skills/notion-feishu-sync/scripts/query_notion.py | \
python3 ~/.openclaw/skills/notion-feishu-sync/scripts/push_feishu.py

# 预期输出:SUCCESS: 推送成功
bash 复制代码
# 测试编排脚本
bash ~/.openclaw/skills/notion-feishu-sync/scripts/sync_notion_to_feishu.sh

# 预期输出:
# [1/3] 检查环境变量...
#       环境变量 OK
# [2/3] 查询 Notion 待办...
#       找到 5 条待办任务
# [3/3] 推送到飞书...
# SUCCESS: 推送成功
# 共同步 5 条待办任务
#
# ✅ 同步完成:5 条待办已推送到飞书群

8.3 通过 OpenClaw 触发

脚本验证通过后,重启 Gateway 让 Skill 生效:

bash 复制代码
openclaw gateway restart

然后在你的聊天入口(Web UI / 飞书 / Slack)中发送:

"帮我把 Notion 里的待办同步到飞书群"

Agent 应该会:

  1. 识别到 notion-feishu-sync Skill
  2. 按 Step 1-4 的流程执行
  3. 返回同步结果

8.4 常见调试问题

现象 原因 解决
Agent 说不知道这个功能 Skill 未被加载 运行 openclaw skills status 检查,确认 requires 条件全部满足
Agent 识别到了但不执行脚本 policy 未放行 exec 工具 检查 policy.yaml 中 allowed_tools 是否包含 exec
Notion API 返回 401 API Key 无效或未授权 检查 Integration 是否已连接到数据库
飞书推送无反应 Webhook URL 过期 在飞书群设置中重新生成机器人 Webhook
脚本手动能跑但 Agent 跑不了 环境变量未注入到 Agent 进程 确认 .env 文件路径正确,并重启 Gateway

九、进阶:加上定时任务,每天自动同步

手动触发已经很好了,但真正的生产力提升来自定时自动执行

OpenClaw 支持 Cron 定时任务(也可以通过web ui和openclaw对话加入)。编辑 ~/.openclaw/cron/jobs.json

json 复制代码
[
  {
    "name": "daily-notion-feishu-sync",
    "schedule": "0 9 * * 1-5",
    "prompt": "请同步 Notion 中的待办任务到飞书群,只同步 Status 为 To Do 的任务。",
    "enabled": true
  }
]

这条配置的含义:

  • 0 9 * * 1-5:周一到周五,每天早上 9:00
  • prompt:Agent 收到的指令(会触发 notion-feishu-sync Skill)
  • enabled: true:启用

保存后重启:

bash 复制代码
openclaw gateway restart

从此,每个工作日早上 9 点,你的飞书群会自动收到一条 Notion 待办同步消息。


十、完整文件清单 & 一键部署

为了方便你直接复制使用,这里汇总所有文件:

目录结构

复制代码
~/.openclaw/skills/notion-feishu-sync/
├── SKILL.md                          # → 第五节
├── scripts/
│   ├── query_notion.py               # → 第六节 6.1
│   ├── push_feishu.py                # → 第六节 6.2
│   └── sync_notion_to_feishu.sh      # → 第六节 6.3
└── references/
    └── (可选) notion_api_cheatsheet.md

环境变量(~/.openclaw/.env)

bash 复制代码
NOTION_API_KEY=ntn_your_key_here
NOTION_DATABASE_ID=your_32_char_database_id
FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/your_hook_id

安装检查清单

  • Python 3 已安装(python3 --version
  • Notion Integration 已创建并授权给目标数据库
  • 飞书群机器人已创建并获取 Webhook URL
  • 环境变量已写入 ~/.openclaw/.env
  • Skill 目录结构正确,SKILL.md存在
  • 脚本有执行权限(chmod +x
  • openclaw skills status 显示 Skill 已加载
  • 手动执行脚本测试通过
  • 通过聊天触发测试通过
  • (可选)Cron 定时任务已配置

十一、Skill 开发的 5 条核心原则(经验总结)

写完这个 Skill,回头看,有几条原则值得提炼:

1. 单一职责

一个 Skill 只做一件事。不要把"查询 Notion"和"推送飞书"和"生成日报"和"发送邮件"塞进一个 Skill。

拆成多个小 Skill,让 Agent 自己组合,才是可维护的做法。

2. 执行规程化

SKILL.md 里的流程必须是确定性的

不要写"你可以灵活选择",而要写"严格按 Step 1-4 执行"。LLM 越有明确指令,执行越可控。

3. 显式声明边界

requires 声明依赖,policy 声明权限,deny 声明禁区。

没有边界的 Skill 就是没有安全带的赛车------跑得快,但迟早翻车。

4. 防御性处理外部内容

从 Notion API 拿到的数据、从飞书返回的结果,都不能盲信。

每个脚本都要处理:空值、异常格式、网络超时、认证失败。

5. 脚本先能独立跑

先让脚本脱离 OpenClaw 独立运行通过,再让 Agent 调用。

如果脚本本身就有 Bug,那让 Agent 去调它只会放大问题。


十二、总结与下一步

这篇文章带你走通了 OpenClaw 自定义 Skill 开发的完整链路:

步骤 内容
准备 获取 Notion API Key + 飞书 Webhook + 配置环境变量
骨架 创建标准目录结构(SKILL.md • scripts/ + references/)
灵魂 编写 SKILL.md(元数据 + 触发条件 + 执行流程 + 错误处理 + 安全边界)
血肉 编写 Python 脚本(查询 + 推送 + 编排)
护栏 配置 policy.yaml(工具白名单 + 网络白名单 + 文件权限)
调试 独立测试 → Agent 触发测试 → 问题排查
上线 配置 Cron 定时任务,实现每日自动同步

掌握了这套流程,你可以举一反三,去写任何你需要的自定义 Skill。

下一篇预告

OpenClaw实战 #08:Token 成本深度优化------从日均 ¥200 降到 ¥15 的实战记录
几乎所有教程只教你怎么跑 OpenClaw,没人教你怎么省钱。下一篇我会用真实账单数据,拆解 Token 到底花在哪,并给出 5 个可直接复制的优化配置。


如果这篇文章帮到了你,记得点赞 + 收藏 + 关注专栏,你的支持是我持续更新的动力 🦞

相关推荐
进击ing小白1 小时前
OpenCv之图像的仿射和透视变化
人工智能·opencv·机器学习
lpfasd1231 小时前
2026创业风向:做一款“AI陪伴成长”App,是风口还是雷区?
人工智能
ECT-OS-JiuHuaShan1 小时前
朱梁万有递归元定理,解构西方文明中心论幻觉
开发语言·人工智能·php
Aubrey-J2 小时前
练习开发Skill——网页内容抓取Skill(website-content-fetch)
开发语言·人工智能
超自然祈祷2 小时前
从gym到gymnasium的倒立摆
人工智能·机器学习
GEO_Huang2 小时前
企业智脑如何生成决策方案?数谷的AI定制化服务的深度在哪?
大数据·人工智能·rpa·geo·ai定制·企业ai智能体定制
星浩AI2 小时前
清华团队开源!我给孩子制作了 AI 互动课堂,手把手教你给孩子做一个
人工智能·后端·github
图图的点云库2 小时前
点云深度学习算法概述
人工智能·深度学习·算法
EasyGBS2 小时前
国标GB28181视频分析平台EasyGBS视频质量诊断让监控故障“可防可控可溯源“
人工智能·音视频·gb28181·视频质量诊断