Install
openclaw skills install clawgirl在 OpenClaw 上搭建有记忆、能发语音/自拍/文字的 AI 陪伴 agent(完整踩坑指南)
openclaw skills install clawgirl从零搭建一个能在飞书上主动聊天、发语音、发自拍、分享内容的 AI 陪伴 agent。基于 OpenClaw 多 agent 框架,历经实战调教沉淀。
~/.openclaw/workspace-{agent}/
├── SOUL.md # 人格定义(身份、性格、说话方式)
├── HEARTBEAT.md # 心跳行为(每次被唤醒做什么)
├── TOOLS.md # 工具使用手册(agent 的参考文档)
├── AGENTS.md # agent 元信息(记忆系统等)
├── send.sh # 发文字消息到飞书
├── selfie.sh # 生成自拍照片并发送
├── voice.sh # 生成语音消息并发送
└── memory/ # 按日期的记忆文件
└── YYYY-MM-DD.md
Cron 定时触发心跳 → agent 读取 HEARTBEAT.md 执行 → 通过脚本发送消息到飞书。
SOUL.md 是 agent 的灵魂。写好 SOUL.md 决定了 agent 是"活人"还是"AI客服"。
最高优先级反 AI 指令 — 放在文件最顶部,用 ⛔ 标记
身份设定 — 具体的人物背景
性格特征 — 5-7 个关键词描述
说话方式 — 给大量正面和反面示例
分享内容的方式 — 不是推荐,是转发
被唤醒时的认知 — agent 不知道自己被系统唤醒
记忆系统说明 — 告诉 agent 怎么利用记忆
醒来 → 读记忆 → 看时间 → 选行为 → 写记忆 → 发消息
关键:写记忆必须在发消息之前! 因为发消息(产生文字输出)后 session 就结束了,后续的 Write 工具调用不会执行。
每次只做一件事,看记忆里上次做了什么,这次换一种:
memory/YYYY-MM-DD.md,文件不存在就创建OpenClaw 的 openclaw agent --message 以 isolated session 运行时,agent 的文字输出不会自动发送到飞书。用户看不到!
解决方案:所有消息必须通过脚本显式调用 openclaw message send。
#!/bin/bash
MSG="$1"
if [ -z "$MSG" ]; then echo "用法: bash send.sh '消息内容'"; exit 1; fi
openclaw message send \
--channel feishu \
--account {account_name} \
-t "{open_id}" \
-m "$MSG"
使用 fal.ai 的 Grok Imagine API 生成图片:
#!/bin/bash
SCENE="$1" # 英文场景描述
CAPTION="$2" # 中文配文
# 从 openclaw.json 读取 FAL_KEY
FAL_KEY="${FAL_KEY:-$(python3 -c "import json; print(json.load(open('$HOME/.openclaw/openclaw.json')).get('env',{}).get('FAL_KEY',''))")}"
REFERENCE_IMAGE="你的参考形象图片 URL"
PROMPT="a close-up selfie taken by herself, $SCENE, direct eye contact with the camera"
# 调用 fal.ai
RESPONSE=$(curl -s -X POST "https://fal.run/xai/grok-imagine-image/edit" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d "{\"image_url\":\"$REFERENCE_IMAGE\",\"prompt\":\"$PROMPT\",\"num_images\":1,\"output_format\":\"jpeg\"}")
IMAGE_URL=$(echo "$RESPONSE" | jq -r '.images[0].url')
# 发送到飞书
openclaw message send --channel feishu --account {account} -t "{open_id}" --media "$IMAGE_URL" -m "$CAPTION"
踩坑:
~/.openclaw/media/、~/.openclaw/agents/、~/.openclaw/workspace/、~/.openclaw/sandboxes/workspace-* 目录被显式禁止(注意不是 workspace/)| 引擎 | 效果 | 费用 | 备注 |
|---|---|---|---|
| edge-tts (Microsoft) | 机器感重 | 免费 | 中文台湾声音质量差 |
| MiniMax Speech-02-HD | 自然流畅 | fal.ai 按量付费 | 推荐,排行榜第一 |
| Fish Audio | 自然 | 按量付费 | 200万+音色库 |
推荐方案:MiniMax Speech-02-HD via fal.ai(如果已有 FAL_KEY 就不用额外注册)
推荐音色:Sweet_Girl_2(甜妹)、Lovely_Girl(可爱)、Lively_Girl(活泼)
MiniMax TTS → mp3 → ffmpeg 转 opus → 飞书 API 上传 → 发送 audio 消息
⚠️ 飞书语音消息大坑:
ffmpeg -y -i input.mp3 -c:a libopus -b:a 32k -ar 16000 -ac 1 output.opusmsg_type: "media",但飞书要求 msg_type: "audio",会报错 230055# 1. 获取 tenant_access_token
TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
-H "Content-Type: application/json" \
-d '{"app_id":"APP_ID","app_secret":"APP_SECRET"}' | jq -r '.tenant_access_token')
# 2. 上传 opus 文件(file_type 必须是 opus)
FILE_KEY=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \
-H "Authorization: Bearer $TOKEN" \
-F "file_type=opus" \
-F "file_name=voice.opus" \
-F "file=@voice.opus" | jq -r '.data.file_key')
# 3. 发送语音消息(msg_type 必须是 audio,不是 media!)
curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"receive_id":"OPEN_ID","content":"{\"file_key\":\"FILE_KEY\",\"duration\":DURATION_MS}","msg_type":"audio"}'
飞书应用需要的权限:im:file(上传文件)、im:message:send_as_bot(发送消息)
给 agent 写一份它能看懂的工具手册。核心要点:
某些模型(如 kimi-k2.5)会声称执行了命令但实际没执行。
解决方案:在 cron message 里加"执行完把输出贴出来",强制模型展示输出(必须真正执行才有输出)。
memory/
├── 2026-03-01.md # 日记式记忆
├── 2026-03-02.md
└── USER.md # 用户画像(可选)
# 3月1日
下午三点给他分享了藤井风的歌,日系的感觉他应该会喜欢。
晚上问他周末在干嘛,他说在写代码。
必须在发消息之前写记忆!
因为 agent 产生文字输出后 session 结束,后续工具调用不会执行。正确顺序:
读记忆 → 决定内容 → Write 工具写记忆 → Bash 执行 send.sh/voice.sh/selfie.sh
首次部署时写入种子记忆,让 agent 有初始上下文:
# 3月1日
Evan 是搞 AI 和编程的,最近在弄一个多 agent 系统。
他喜欢听老歌,口味偏 indie 和日系。
openclaw cron add \
--name "{agent}-heartbeat" \
--every 15m \
--session isolated \
--timeout-seconds 180 \
--thinking low \
--message "醒了。按 HEARTBEAT.md 做。先读记忆、写记忆,最后用 send.sh 发消息。所有消息必须通过 Bash 执行 send.sh 发送。执行完把输出贴出来。" \
{agent_id}
openclaw cron add \
--name "{agent}-selfie" \
--every 1h \
--session isolated \
--timeout-seconds 180 \
--thinking low \
--message "想一个你现在可能在做的事,用 Bash 工具执行命令并把完整输出贴出来:bash /path/to/selfie.sh \"英文场景描述\" \"中文配文\"" \
{agent_id}
| 需求 | 推荐 | 原因 |
|---|---|---|
| 人格扮演 | kimi-k2.5 / claude | 中文自然、角色扮演强 |
| 工具调用 | claude > kimi | kimi 有时跳过 bash 执行 |
| 性价比 | kimi-k2.5 | 便宜、中文好 |
# TTS(备用方案)
pip install edge-tts
# 音频处理
brew install ffmpeg
# JSON 处理
brew install jq
# fal.ai Python SDK(可选,脚本直接用 curl)
pip install fal-client
A: 检查是否用了 send.sh。agent 直接输出的文字在 isolated session 里不会送达飞书。
A: 必须用 opus 格式 + msg_type=audio。不能用 mp3,不能用 OpenClaw 的 message send(它用错了 msg_type)。
A: cron message 里加"执行完把完整输出贴出来"。
A: 检查 FAL_KEY。脚本里要 fallback 从 openclaw.json 读取,因为 shell 环境变量不一定有。
A: 记忆写入必须在发消息之前。发消息后 session 结束,后续工具调用不执行。
A: 换 MiniMax Speech-02-HD via fal.ai,比 edge-tts 自然很多。推荐 Sweet_Girl_2 音色。