#openclaw3.8 question

1 messages · Page 1 of 1 (latest)

fossil gardenBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

nocturne bloomBOT
#

如果你说的是「把 OpenClaw 从旧机器迁移到新机器、保留会话/配置/登录状态」的话,官方推荐的迁移步骤是:

  1. 在旧机器确认实际状态目录(state dir)/是否有 profile
openclaw status
  • 默认 state dir 是 ~/.openclaw/
  • 如果你用了 --profile <name>OPENCLAW_STATE_DIR,目录可能是 ~/.openclaw-<profile>/ 或自定义路径(迁移时一定要用同一个)
  1. 旧机器先停掉 gateway(避免拷贝过程中状态变动)
openclaw gateway stop
  1. 备份并拷贝两样东西(建议整目录迁移)
  • State dir$OPENCLAW_STATE_DIR(默认 ~/.openclaw/,里面有 config/credentials/sessions/channel 登录等)
  • Workspace:默认 ~/.openclaw/workspace/(里面是 AGENTS.md / MEMORY.md / SOUL.md / memory/* 等)
#

可选:在旧机器打包:

cd ~
tar -czf openclaw-state.tgz .openclaw
tar -czf openclaw-workspace.tgz .openclaw/workspace
  1. 新机器先安装 OpenClaw(即使生成了新的 ~/.openclaw/ 也没关系)
    按安装文档走即可,然后把上面两份拷贝过去并解压/覆盖(注意隐藏目录 .openclaw 别漏了、文件属主要正确)。

  2. 新机器跑 doctor(做迁移修复/服务修复)然后重启

openclaw doctor
openclaw gateway restart
openclaw status
#

常见坑:

  • 只拷 openclaw.json 不够(登录态/凭据/会话都在整个 state dir 里)
  • profile/state-dir 不一致会导致“看起来像全新安装”
  • ~/.openclaw 里有密钥/登录信息,备份当作机密对待

文档:

你是从哪台迁到哪台(Mac→Linux / VPS→VPS / 本地→VPS)?以及 openclaw status 里显示的 state dir 是哪个?我可以按你的情况把命令路径写死到正确目录。

pine glacier
#

我原来是在root用户部署的,现在在想迁移到新建的普通用户下执行。怎么操作

nocturne bloomBOT
#

可以的,本质就是把 root 的 state/workspace 挪到新用户家目录下,然后用新用户重新装/启用 gateway 服务(并把 root 的服务停掉/卸掉,避免端口/锁冲突)。

下面按「Linux + 之前用 openclaw gateway install/daemon 跑起来」的常见情况给步骤(其它方式也差不多):

0) 先在 root 下确认你现在用的目录

sudo -i
openclaw status
openclaw config file
openclaw config get agents.defaults.workspace

一般会是:

  • state dir:/root/.openclaw(或 /root/.openclaw-<profile>
  • workspace:通常在 state 下面:/root/.openclaw/workspace

1) 停掉 root 的 gateway(非常重要,避免拷贝中途文件变化)

#
sudo -i
openclaw gateway stop

2) 把 root 的 state dir + workspace 拷到新用户

假设新用户叫 <user>,家目录 /home/<user>

sudo rsync -aH --info=progress2 /root/.openclaw/ /home/<user>/.openclaw/
sudo chown -R <user>:<user> /home/<user>/.openclaw

如果你用的是 profile(比如 /root/.openclaw-main),就把那个目录完整 rsync 过去,并保持同样的目录名/结构。

3) 切到新用户,跑 doctor,然后重新安装/启动服务

#
sudo -iu <user>
openclaw doctor
openclaw gateway install
openclaw gateway restart
openclaw status

如果你之前 agents.defaults.workspace 配成了 /root/... 这种绝对路径,需要改到新用户目录:

openclaw config set agents.defaults.workspace "~/.openclaw/workspace"
openclaw gateway restart

4) 确认没问题后,把 root 的服务卸掉(或至少保持停止)

#
sudo -i
openclaw gateway uninstall

5) 常见坑提醒(root → 普通用户最容易踩)

  • 环境变量/密钥丢失:root 服务里可能有 env,新用户服务拿不到。建议把需要的 key 放到新用户的 ~/.openclaw/.env(或按文档启用 shell env import)。文档:
    https://docs.openclaw.ai/help/faq#how-does-openclaw-load-environment-variables
  • systemd user 服务开机不自启:如果你用的是 systemd user unit,机器重启后用户没登录可能不会起。需要的话:
    sudo loginctl enable-linger <user>

相关官方文档:

你方便贴一下(打码后)root 下 openclaw status 里显示的 state dir 路径,以及你是用 systemd/launchd 还是纯手动跑的?我可以把上面的路径/命令按你的实际情况对齐。

pine glacier
#

为啥呢zhuli@good:~/.openclaw$ openclaw doctor
openclaw: command not found

nocturne bloomBOT
#

因为你现在这个普通用户环境里 没有安装/找不到 openclaw CLI(之前很可能是装在 root 的 npm 前缀/路径里了),所以会 command not found

按下面排查/修复:

1) 先看 root 那边 openclaw 装在哪

sudo -i
command -v openclaw
openclaw --version
  • 如果这里能找到一个路径(比如 /usr/local/bin/openclaw),那说明 CLI 在 root 环境里是有的。
  • 如果这里也找不到,那就是根本没装 CLI(或只用 npx/源码跑过)。

2) 让所有用户都能用(最省事的做法:系统全局安装)

#
sudo npm i -g openclaw@latest
# 或者(如果你更习惯 pnpm)
# sudo pnpm add -g openclaw@latest

然后回到普通用户再试:

exit   # 退出 root shell(如果你在 sudo -i 里)
command -v openclaw
openclaw --version
openclaw doctor

3) 如果你坚持“只装在当前普通用户下”(不想 sudo 全局装)

在普通用户下把 npm 全局前缀改到 home(避免写系统目录权限问题):

#
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
npm i -g openclaw@latest

4) 临时救急(不安装也能跑一次 doctor)

npx -y openclaw doctor

(临时 OK,但长期跑 gateway 还是建议按上面装好。)

你方便把这两条的输出贴一下吗(打码无所谓):

#
sudo -i command -v openclaw || true
command -v openclaw || true

我就能判断是 PATH 问题还是确实没装。

pine glacier
#

我发现了新建的用户没有npm 环境

nocturne bloomBOT
#

对,这个现象基本说明:你之前是在 root 的环境里装的 Node/npm(常见是用 nvm/fnm 之类),所以新建用户的 PATH 里根本没有 node/npm,自然也装不了/找不到 openclaw

你有两条最省事的路(二选一):

方案 A(推荐):直接用 OpenClaw 安装脚本给新用户把 Node/npm + openclaw 一次装好

用新用户登录后跑:

curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash

然后重新开一个 shell(或 source ~/.bashrc / source ~/.zshrc),确认:

node -v
npm -v
#
openclaw --version
openclaw doctor

这个脚本会在需要时自动装 Node,并且在 Linux 上遇到 npm 全局目录权限/PATH 问题时,能把 prefix 切到 ~/.npm-global 并帮你补 PATH(见官方说明)。

方案 B:把 Node 22+ 装成系统级(所有用户都有 npm)

如果你是 Ubuntu/Debian:

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs

然后新用户下再装 openclaw:

#
npm i -g openclaw@latest
openclaw --version

如果你想我给你对症下药,你在新用户下贴一下这两条输出就够了:

node -v || true
npm -v || true

(如果都是 command not found,就直接走上面 A 或 B。)

pine glacier
#

我重新执行了安装脚本,再把root的文件覆盖一下就行了吗

nocturne bloomBOT
#

基本思路是对的:先把新用户环境装好(Node/npm/openclaw + service),然后再把 root 的 state dir + workspace 迁过来覆盖,这样新用户就能接管原来的会话/配置/登录态。

但要注意顺序和几个坑:

推荐操作顺序(安全版)

  1. 先停掉两边的 gateway(避免拷贝时文件变化/端口冲突)
sudo -i
openclaw gateway stop

sudo -iu <user>
openclaw gateway stop
  1. 备份一下新用户的当前状态目录(以防万一)
#
sudo -iu <user> bash -lc 'cd ~ && tar -czf openclaw-newuser-backup.tgz .openclaw'
  1. 把 root 的 state dir 覆盖到新用户
    (假设 root 的是 /root/.openclaw,新用户是 /home/<user>/.openclaw
sudo rsync -aH /root/.openclaw/ /home/<user>/.openclaw/
sudo chown -R <user>:<user> /home/<user>/.openclaw
  1. 如果 workspace 不在 state dir 里(被你改到别的路径),还要单独拷 workspace
    先在 root 下确认 workspace 路径:
sudo -i
openclaw config get agents.defaults.workspace
#

如果这里不是 /root/.openclaw/workspace 这类路径,就把那个目录也按同样方式 rsync + chown 到新用户对应位置。

  1. 切到新用户跑 doctor 做迁移修复,然后重启
sudo -iu <user>
openclaw doctor
openclaw gateway restart
openclaw status

关键点

  • 覆盖时请确保 gateway 已停止,否则 sessions/credentials 可能拷到一半变动。
  • 覆盖完一定要 chown -R,不然新用户读不到 creds/sessions。
  • 只覆盖 openclaw.json 不够,务必是整个 ~/.openclaw/(credentials/sessions 都在里面)。
  • 安装脚本生成的 systemd user service 文件通常不在 ~/.openclaw/ 里,所以不会被你覆盖掉,这一点反而是好事。

你如果告诉我两边的实际路径我可以把命令写成你能直接复制执行的版本:

#
sudo -i openclaw status
sudo -i openclaw config get agents.defaults.workspace
pine glacier
#

openclaw memory status --deep
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/home/zhuli/.openclaw/extensions/feishu/index.ts)
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/home/zhuli/.openclaw/extensions/feishu/index.ts)

🦞 OpenClaw 2026.3.8 (3caab92) — I'm not AI-powered, I'm AI-possessed. Big difference.



node:internal/fs/promises:1029
const result = await PromisePrototypeThen(
^

Error: EACCES: permission denied, stat '/root/.openclaw/workspace/MEMORY.md'
at async Object.stat (node:internal/fs/promises:1029:18)
at async NodeFsHandler._addToNodeFs (file:///home/zhuli/.npm-global/lib/node_modules/openclaw/node_modules/chokidar/handler.js:580:27)
at async file:///home/zhuli/.npm-global/lib/node_modules/openclaw/node_modules/chokidar/index.js:367:25
at async Promise.all (index 0)
Emitted 'error' event on FSWatcher instance at:
at FSWatcher._handleError (file:///home/zhuli/.npm-global/lib/node_modules/openclaw/node_modules/chokidar/index.js:558:18)
at NodeFsHandler._addToNodeFs (file:///home/zhuli/.npm-global/lib/node_modules/openclaw/node_modules/chokidar/handler.js:626:26)
at async file:///home/zhuli/.npm-global/lib/node_modules/openclaw/node_modules/chokidar/index.js:367:25
at async Promise.all (index 0) {
errno: -13,
code: 'EACCES',
syscall: 'stat',
path: '/root/.openclaw/workspace/MEMORY.md'
}

Node.js v22.22.1 怎么处理

nocturne bloomBOT
#

这个报错的核心是:你现在用普通用户 zhuli 在跑 OpenClaw,但配置里的 workspace 还指向 root 的路径

EACCES ... stat '/root/.openclaw/workspace/MEMORY.md'

所以 chokidar 监控 MEMORY.md 时,去读 /root/... 被权限挡住了。

处理方法(把 workspace 路径改到新用户目录)

zhuli 用户下执行:

openclaw config file
openclaw config get agents.defaults.workspace

你大概率会看到 workspace 还是 /root/.openclaw/workspace。把它改掉:

#
openclaw config set agents.defaults.workspace "~/.openclaw/workspace"
mkdir -p ~/.openclaw/workspace

然后确认新路径下有你的 MEMORY.md 等文件(如果你之前 rsync/覆盖时把 workspace 也带过来了,通常已经有了):

ls -la ~/.openclaw/workspace/MEMORY.md

如果没有,就把 root 的 workspace 拷过来一次(需要 sudo):

sudo rsync -aH /root/.openclaw/workspace/ /home/zhuli/.openclaw/workspace/
sudo chown -R zhuli:zhuli /home/zhuli/.openclaw/workspace
#

最后再跑一次:

openclaw doctor
openclaw memory status --deep

另外那两条 feishu duplicate plugin id warning

这通常是不小心把 同一个 feishu 插件加载了两次(比如既在 plugins.entries 里配置了,又在 ~/.openclaw/extensions/feishu/ 里有一份)。它只是 warning,不影响你先解决 workspace 权限问题;之后想清爽一点再处理也行。

如果你愿意,把下面这两条输出贴一下(不用贴敏感内容)我可以帮你确认有没有别的 workspace 覆盖项:

openclaw config get agents.defaults.workspace
openclaw config get agents.list
pine glacier
#

OK了,这个问题怎么解决openclaw security audit --deep
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/home/zhuli/.openclaw/extensions/feishu/index.ts)
Config warnings:\n- plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may be overridden (/home/zhuli/.openclaw/extensions/feishu/index.ts)

🦞 OpenClaw 2026.3.8 (3caab92) — I read logs so you can keep pretending you don't have to.


◇ Config warnings
│ │
│ - plugins.entries.feishu: plugin feishu: duplicate plugin id detected; later plugin may │
│ be overridden (/home/zhuli/.openclaw/extensions/feishu/index.ts)
OpenClaw security audit
Summary: 0 critical · 2 warn · 1 info
Run deeper: openclaw security audit --deep

WARN
channels.feishu.doc_owner_open_id Feishu doc create can grant requester permissions
channels.feishu tools include "doc"; feishu_doc action "create" can grant document access to the trusted requesting Feishu user.
Fix: Disable channels.feishu.tools.doc when not needed, and restrict tool access for untrusted prompts.
plugins.installs_unpinned_npm_specs Plugin installs include unpinned npm specs
Unpinned plugin install records:

  • feishu (@m1heng-clawd/feishu)
  • wecom-openclaw-plugin (@wecom/wecom-openclaw-plugin)
    Fix: Pin install specs to exact versions (for example, @scope/pkg@1.2.3) for higher supply-chain stability.
    INFO
    summary.attack_surface Attack surface summary
    groups: open=0, allowlist=0
    tools.elevated: disabled
    hooks.webhooks: disabled
    hooks.internal: enabled
    browser control: enabled
    trust model: personal assistant (one trusted operator boundary), not hostile multi-tenant on one shared gateway
nocturne bloomBOT
#

这些都不是“错误”,只是 security audit 的提醒(你现在是个人助手/单一可信操作者模型,所以很多人会选择接受这些 warn)。如果你想把 warn 消掉/降风险,可以按下面逐个处理:


1) plugin feishu: duplicate plugin id detected

意思是:有两份 id 都叫 feishu 的插件同时被加载了,其中一份来自:
/home/zhuli/.openclaw/extensions/feishu/index.ts

处理思路:只保留一个 feishu 插件来源

先看看到底加载了哪些:

openclaw plugins list
openclaw plugins info feishu
openclaw config get plugins.load.paths
openclaw config get plugins.entries.feishu
#

常见解决法(二选一):

  • 只用 npm 安装的插件:把你手动放进 ~/.openclaw/extensions/feishu/ 的那份(或通过 plugins.load.paths link 的那份)移走/取消 link。
  • 只用本地开发版(extensions 里那份):把 config 里的 plugins.entries.feishu(或 npm 安装记录)删掉/卸载掉。

不建议“两个都留着”,因为到底谁覆盖谁会不稳定。


2) channels.feishu.doc_owner_open_id ... doc create can grant requester permissions

这是在提醒:你启用了 Feishu 的 doc 工具,而 feishu_doc.create 可能会给“发起请求的 Feishu 用户”授予文档权限(属于能力很强的写权限)。

如果你不需要让机器人创建/授权文档,直接关掉这个工具就行:

先看你的配置长啥样:

openclaw config get channels.feishu.tools
#

然后按你的实际结构关掉 doc(audit 建议的路径是 channels.feishu.tools.doc):

openclaw config set channels.feishu.tools.doc false --strict-json

如果你确实需要 doc 功能,那就别追求把这个 warn 变成 0,而是把 Feishu 渠道做强约束(只允许可信的人/群触发):allowlist / requireMention / groupPolicy 等(文档: https://docs.openclaw.ai/channels/feishu )。


3) plugins.installs_unpinned_npm_specs(插件安装没 pin 版本)

这是供应链稳定性提醒:你现在记录的是 @scope/pkg(不带版本),以后更新/重装可能拿到不同版本。

做法:把安装 spec pin 到确切版本

先看当前版本:

#
openclaw plugins info feishu
openclaw plugins info wecom-openclaw-plugin

然后用 --pin 重新安装/记录(会把 spec 固定成 name@x.y.z):

openclaw plugins install @m1heng-clawd/feishu --pin
openclaw plugins install @wecom/wecom-openclaw-plugin --pin

最后复查:

openclaw security audit --deep
#

如果你把 openclaw plugins listopenclaw config get plugins.entries.feishu 的输出贴一下(可以打码),我可以直接告诉你“应该删哪一份 feishu”来消掉 duplicate id 那条。

pine glacier
#

Feishu │ feishu │ loaded │ stock:feishu/index.ts │ 2026.3.8-beta.1 ----@m1heng- │ feishu │ disabled │ global:feishu/index.ts │ 0.1.16 │
│ clawd/feishu │ │ │ OpenClaw Feishu/Lark channel plugin │ │
│ 企业微信 │ wecom- │ loaded │ global:wecom-openclaw-plugin/dist/index.esm.js │ 1.0.5 │
│ │ openclaw │ │ 企业微信 OpenClaw 插件 │ │
│ │ -plugin │ │ │ 我要使用 @m1heng- │ feishu │ disabled │ global:feishu/index.ts │ 0.1.16 版本的飞书

nocturne bloomBOT
#

从你这份 plugins list 看出来了:你现在同时有两份 id 都叫 feishu 的实现:

  • stock:feishu/index.tsloaded,版本跟 OpenClaw 一样:2026.3.8-beta.1)——这是 OpenClaw 自带/内置的 Feishu 通道实现
  • global:feishu/index.tsdisabled@m1heng-clawd/feishu 0.1.16)——你额外装的 npm 插件

因为 插件 id 冲突(都叫 feishu),所以才会一直报 duplicate plugin id,而且实际运行时通常会优先用其中一个(你这里明显是 stock 那个在生效)。

结论(直说)

不改源码/不 fork 插件改 id 的情况下,你没法“同时保留 stock,又指定用 @m1heng 的 feishu 0.1.16”。要消掉 warning、也让行为稳定,必须 二选一
并且从版本上看,stock 这份更新、更匹配你当前 OpenClaw 版本——我建议你直接用 stock,把 @m1heng... 那份卸掉。


推荐做法:卸载 @m1heng 那个(保留 stock)

先 dry-run 看会删什么:

#
openclaw plugins uninstall feishu --dry-run

确认无误后执行:

openclaw plugins uninstall feishu
openclaw gateway restart
openclaw security audit --deep

这一般会把 ~/.openclaw/extensions/feishu 那份(npm/全局的)移除,剩下 stock 的就不会再 duplicate 了。


如果你强烈想用 @m1heng-clawd/feishu@0.1.16

那就得走“高级/不太官方支持”的路:fork 插件并改 plugin id(否则永远撞车 feishu 这个 id),然后把配置从 channels.feishu... 迁到 channels.<新id>...。这个我可以帮你梳理,但需要你接受要改插件包/manifest 的工作量。

#

另外:你 audit 里 wecom-openclaw-plugin 的 “unpinned” 可以单独 pin 掉(不影响 feishu):

openclaw plugins install @wecom/wecom-openclaw-plugin --pin

你想先走“推荐做法(用 stock)”还是“坚持用 @m1heng(fork 改 id)”?我按你选的路线给你下一步最短命令。

pine glacier
#

我发现,在linux下面, 使用root用户比普通用户响应速度更快,openclaw gateway restart 命令

nocturne bloomBOT
#

root 身份本身不会让 OpenClaw “回复更快”(模型调用/网络延迟才是大头)。你看到“root 更快”,99% 是因为你实际上在对比 两套不同的网关实例/配置,比如:

  • root 的 gateway 还在跑,你的 UI 还连着它(所以感觉更快/更“正常”)
  • 普通用户这套 gateway 用了不同的 ~/.openclaw、不同默认模型/密钥、或还在冷启动
  • 两边甚至可能跑在不同端口/不同 profile

先确认:到底跑了几个 gateway(最关键)

分别在 root 和普通用户下跑一下(看 RPC probe 和服务名):

sudo -i openclaw gateway status --deep
sudo -iu zhuli openclaw gateway status --deep

以及(更直观):

#
openclaw gateway probe

如果你发现 root 的服务还在 enable/running,先把它停掉/卸掉,避免 UI 误连旧的:

sudo -i openclaw gateway stop
# 确认要彻底迁走的话:
sudo -i openclaw gateway uninstall

关于 openclaw gateway restart 到底该用谁的权限

这条命令是“重启服务”,需要用安装该服务的那个用户来执行:

  • 如果你是用 zhuli 安装的 user service:
#
  openclaw gateway restart
  • 如果你现在人在 root/想帮 zhuli 重启:
    sudo -iu zhuli openclaw gateway restart
    

(反过来,如果是 root 装成 system service,那就需要 sudo openclaw gateway restart。)


你说的“响应速度更快”具体是指:CLI 重启命令返回更快,还是 聊天回复更快
把上面两条 gateway status --deep 的输出贴一下(打码没关系),我基本就能一眼看出你现在是不是同时跑着两套 gateway 或者 UI 连错了实例。

pine glacier
#

OK。openclaw,怎么看执行的步骤啊。我通过飞书发布任务,看不到执行步骤,智能被动等地啊

nocturne bloomBOT
#

在飞书里“看不到执行步骤、只能等结果”基本是正常现象:飞书是一个聊天出口,默认只把最终回复发回来;中间的 tool 调用/日志/推理过程不会像 Debug 控制台那样全量展示。

你有 3 种方式能看到“在干嘛”:


1) 飞书侧看到“生成进度”(推荐先开这个)

飞书支持流式卡片,会实时更新消息内容(但注意:这显示的是输出生成进度,不是每个 tool 的详细日志)。

确认你的配置开启了(默认应是 true):

{
  channels: {
    feishu: {
      streaming: true,
#
      blockStreaming: true,
    },
  },
}

文档(中文):https://docs.openclaw.ai/zh-CN/channels/feishu#流式输出


2) 想看真正的“执行步骤/工具调用”:用 Control UI / Dashboard 看 session

这是最接近“可视化执行过程”的地方(能看到 tool 调用、阶段性输出、最终结果等)。

在网关机器上:

#
openclaw dashboard

如果网关在 VPS 上,本地用 SSH 转发:

ssh -N -L 18789:127.0.0.1:18789 <user>@<host>

然后浏览器打开 http://127.0.0.1:18789/(按提示贴 token)。


3) 终端看执行日志(偏工程向)

直接 tail 网关 file logs:

openclaw logs --follow
#

如果你想看到更多细节(包括工具相关日志),可以临时把日志级别调高(会更吵,也可能包含敏感信息,注意别外发):

openclaw config set logging.level "debug"
openclaw gateway restart
openclaw logs --follow

如果你希望在飞书里也能“阶段性回报”(比如“第 1 步在做 X / 第 2 步在做 Y”),也可以在任务里明确要求机器人“每完成一步就发一条进度更新”。但这会增加消息数量,群里可能有点刷屏。

你更想要哪种体验:飞书卡片流式进度、Control UI 看完整执行、还是终端日志?我按你的使用场景给你最短路径配置。

pine glacier
#

14:15:46 warn memory {"subsystem":"memory"} qmd collection add failed for memory-root-main: qmd collection add /home/zhuli/.openclaw/workspace --name memory-root-main --mask MEMORY.md failed (code 1):
14:15:49 warn memory {"subsystem":"memory"} qmd collection add failed for memory-alt-main: qmd collection add /home/zhuli/.openclaw/workspace --name memory-alt-main --mask memory.md failed (code 1):
14:15:52 warn memory {"subsystem":"memory"} qmd collection add failed for memory-dir-main: qmd collection add /home/zhuli/.openclaw/workspace/memory --name memory-dir-main --mask **/*.md failed (code 1):
14:15:52 info gateway {"subsystem":"gateway"} qmd memory startup initialization armed for agent "main"
14:15:54 warn memory {"subsystem":"memory"} qmd boot update failed: Error: qmd update failed (code 1):
14:15:57 warn memory {"subsystem":"memory"} qmd collection add failed for memory-root-code: qmd collection add /home/zhuli/.openclaw/workspace-code --name memory-root-code --mask MEMORY.md failed (code 1): 我应该如何正确配置qmd

nocturne bloomBOT
#

你现在这几行日志的意思很明确:OpenClaw 调用了 qmd collection add ...,但 qmd 子进程每次都以 exit code 1 失败了。这不是“配置写法问题”,而是 qmd 本身没跑起来/版本不兼容/服务环境找不到依赖 这类问题。

你有两条路:


路线 A(最省事):不用 QMD,先恢复到默认内置 memory(SQLite)

如果你只是想要 memory 正常工作,不一定要 qmd:

openclaw config unset memory.backend
openclaw gateway restart
openclaw memory status --deep

(QMD 是 experimental,本来就更容易踩坑。)

#

路线 B:继续用 QMD(正确姿势排查/配置)

1) 先确认 qmd 在 zhuli 用户下能跑

command -v qmd
qmd --version
  • 如果这里就找不到/跑不了:先把 QMD CLI 安装好(两种方式:下载 qmd release 或按 QMD 项目文档安装)。关键是:qmd 必须在网关运行用户的 PATH 里。

2) 很常见的坑:service 环境 PATH 没有 qmd

就算你交互式 shell 能 qmd --version,systemd service 也可能找不到。

最稳的是在 OpenClaw 配置里写死 qmd 的绝对路径(例如你把 qmd 装在 ~/.bun/bin/qmd 或别的地方):

#
openclaw config set memory.qmd.command "/完整路径/qmd" --strict-json
openclaw gateway restart

你可以用 command -v qmd 的输出当作这个“完整路径”。

3) 用和 OpenClaw 一样的 XDG 目录,手动跑一次 qmd 看真实报错

OpenClaw 会把 qmd 的 XDG home 放在 state dir 下面,你可以这样复现:

STATE_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
export XDG_CONFIG_HOME="$STATE_DIR/agents/main/qmd/xdg-config"
export XDG_CACHE_HOME="$STATE_DIR/agents/main/qmd/xdg-cache"

qmd collection add "$HOME/.openclaw/workspace" --name memory-root-main --mask MEMORY.md
#
qmd update
qmd embed

这一步会把“code 1”背后的真正 stderr 打出来(比如:qmd 版本太旧不支持 --mask、缺 sqlite 扩展能力、缺依赖、权限/路径问题等)。


你现在最需要贴的 3 个输出(我就能快速判断是哪种原因)

zhuli 用户下执行并贴结果(可以打码):

openclaw config get memory.backend
command -v qmd || true
qmd --version || true
#

大概率会是:

  • qmd 没装 / service 找不到 qmd(PATH),或者
  • qmd 版本太旧(不兼容 OpenClaw 这边用的 collection add --mask 语法)
pine glacier
#

如果你希望在飞书里也能“阶段性回报”(比如“第 1 步在做 X / 第 2 步在做 Y”),也可以在任务里明确要求机器人“每完成一步就发一条进度更新”。但这会增加消息数量,群里可能有点刷屏。
在哪里添加要求、

nocturne bloomBOT
#

你可以在 两种地方加这个“阶段性回报”的要求——看你是想“这一次任务生效”还是“以后默认都这样”。

A) 只对这一次任务生效(最简单)

就在你发给飞书机器人的那条任务消息里,直接写在开头即可,例如:

请帮我做 X。
要求:执行过程中每完成一个关键步骤就回复一条进度(步骤名 + 当前结果/下一步),直到完成。

或者更不刷屏一点:

每 2–3 分钟汇报一次进度;遇到卡住/报错立刻汇报。

B) 变成默认习惯(长期生效)

把这条偏好写进你这个 agent 的 工作区的 AGENTS.md(或 SOUL.md,但一般建议放 AGENTS.md 更“行为规则”)。

例如加一段:

#
## Progress updates (Feishu)
When a task may take >1 minute, send short progress updates after each major step.
Keep updates brief (1-2 lines).

然后重启 gateway 或等下次对话即可生效。

如果你有多 Agent / bindings,要写到实际接收飞书消息的那个 agent workspace 里。

你更希望“每完成一步就回报”,还是“每隔 N 分钟回报一次”?我可以给你一条更合适、不会刷屏的模板句子直接复制到飞书里用。

pine glacier
#

从我下达命令开始,每执行一步都汇报,关键的操作需要我授权

nocturne bloomBOT
#

把下面这段当成“执行协议”,直接粘贴到你给飞书机器人的任务消息开头(一次性生效),或者放进该 agent 的 AGENTS.md(长期生效)都行:


执行协议(进度回报 + 授权)

  1. 从我发出指令开始,你需要把任务拆成清晰的步骤列表(Step 1…N),然后立刻开始执行。
  2. 每执行一步都要汇报两次
    • 开始前:准备执行 Step k/N:<做什么>(原因/目标)
    • 结束后:完成 Step k/N:结果摘要(关键输出/链接/变更点)
  3. 以下“关键操作”必须先向我申请授权,并等待我明确回复“批准/继续/OK”后才能执行:
    • 会修改/写入配置文件(例如 openclaw.json、.env、系统服务文件)
    • 安装/卸载软件或插件(npm/pnpm/apt/systemctl 等)
    • 重启/停止服务(openclaw gateway restart/stop、systemd/launchd)
    • 删除/覆盖文件、批量移动、改权限/属主(rm、chown、chmod、rsync 覆盖等)
    • 任何需要 sudo/root 权限的命令
    • 任何对外发送消息/邀请/授权(例如创建文档并授予权限)
  4. 如果你不确定某步是否关键,默认当作关键操作先问我
#
  1. 申请授权时请用这种格式,方便我一眼确认:
    • 需要授权:将执行 <命令/操作>;影响:<会改什么>;可回滚:<如何回滚>。请回复“批准”继续。

如果你愿意,我也可以帮你把“关键操作”再精简成一个更适合你日常的清单(比如你只关心:重启服务/改配置/删文件这三类)。你希望授权口令固定用“批准”吗?还是用 “yes/continue”?

pine glacier
#

14:51:25 info gateway/channels/feishu {"subsystem":"gateway/channels/feishu"} feishu[code]: WebSocket client started
14:51:25 info [info]: [ '[ws]', 'ws client ready' ]
14:51:25 info [info]: [ '[ws]', 'ws client ready' ]
14:51:25 info [info]: [ '[ws]', 'ws client ready' ]
14:51:25 info [info]: [ '[ws]', 'ws client ready' ]
14:51:25 info [info]: [ '[ws]', 'ws client ready' ]
14:51:25 info [info]: [ '[ws]', 'ws client ready' ]
Log tail truncated (increase --max-bytes).
Gateway not reachable. Is it running and accessible?
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/zhuli/.openclaw/openclaw.json
Bind: loopback
Hint: run openclaw doctor. 现在无法启动了,但是看systemctl --user status openclaw-gateway.service
● openclaw-gateway.service - OpenClaw Gateway (v2026.3.8)
Loaded: loaded (/home/zhuli/.config/systemd/user/openclaw-gateway.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-03-10 22:50:49 CST; 7s ago
Main PID: 53423 (openclaw-gatewa)
Tasks: 11 (limit: 23834)
Memory: 533.9M
CPU: 6.910s
CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/openclaw-gateway.service
└─53423 openclaw-gateway "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">

Mar 10 22:50:54 good node[53423]: 2026-03-10T22:50:54.601+08:00 [wecom] [default] Heartbeat timer started, inte>
Mar 10 22:50:54 good node[53423]: 2026-03-10T22:50:54.603+08:00 [wecom] [default] Authenticated
Mar 10 22:50:54 good node[53423]: 2026-03-10T22:50:54.604+08:00 [wecom] [default] Authentication successful
Mar 10 22:50:54 good node[53423]: 2026-03-10T22:50:54.607+08:00 [info]: [ '[ws]', 'ws client ready' ]
Mar 10 22:50:54 good node[53423]: 2026-03-10T22:50:54.627+08:00 [info]: [ '[ws]', 'ws client ready' ]

nocturne bloomBOT
#

你这情况更像是:gateway 进程确实在跑(systemd 显示 active),但 CLI 在用 ws://127.0.0.1:18789 去探测时连不上——最常见原因就两个:

  1. 服务实际监听的端口不是 18789(安装时自动换了端口 / unit 里写了 --port
  2. 18789 被别的实例占着(比如 root 的 gateway),导致你以为在连 zhuli 的,其实端口对应的是别的/或者没在 listen

按下面 3 步定位,基本一眼就能确定:


1) 看 systemd unit 里到底用的什么端口/参数

systemctl --user cat openclaw-gateway.service

重点找 ExecStart=... openclaw gateway ... 里面有没有 --port,以及有没有 OPENCLAW_GATEWAY_PORT 之类的 Environment。


#

2) 看 18789 到底是谁在监听(以及 openclaw 实际监听哪)

ss -ltnp | grep -E '18789|openclaw' || true

如果你看不到 PID/进程名,用 sudo 再来一次:

sudo ss -ltnp | grep -E '18789|openclaw' || true

3) 确认你 CLI 用的配置端口是什么

openclaw config get gateway.port
openclaw config get gateway.bind
#

接下来怎么修

  • 如果 unit 里端口不是 18789:那就用 unit 的端口去连(或把 gateway.port 改回 18789 并重启服务)。
  • 如果 18789 被 root 的实例占用:先把 root 那个停掉/卸掉,再重启 zhuli 的服务:
    sudo -i openclaw gateway stop
    sudo -i openclaw gateway uninstall   # 确认不再需要 root 那套的话
    sudo -iu zhuli openclaw gateway restart
    

你把 systemctl --user cat openclaw-gateway.service 里那行 ExecStart=...(以及 ss -ltnp | grep 18789 的结果)贴出来,我就能直接告诉你应该改端口还是清理掉另一个实例。

pine glacier
#

原来在root用户下也有openclaw。卸载了

nocturne bloomBOT
#

好,这一步很关键——root 那套卸载后,端口/服务冲突的可能性就基本排除了。

接下来按这个顺序确认一下 zhuli 这套是不是已经“真正对外监听 + CLI 能连上”:

  1. 确认 18789 现在是谁在监听(应该是 zhuli 的 openclaw)
ss -ltnp | grep 18789 || true

(如果看不到进程名就用 sudo ss -ltnp | grep 18789。)

  1. 重启 zhuli 的 gateway
    二选一:
openclaw gateway restart
# 或
systemctl --user restart openclaw-gateway.service
#
  1. 再跑一次探测
openclaw gateway status
openclaw gateway probe

如果此时还提示 “Gateway not reachable”,那就几乎只剩两种情况:

  • 你的 user service 实际监听端口不是 18789(需要看 systemctl --user cat openclaw-gateway.service 里的 ExecStart/--port)
  • 或者 gateway.port 配置改过(openclaw config get gateway.port

你把下面两条输出贴一下,我可以直接告诉你应该对齐哪个端口:

systemctl --user cat openclaw-gateway.service | sed -n 's/^ExecStart=//p'
openclaw config get gateway.port
pine glacier
#

好了 。1、在home目录创建一个 test.md,然后写入 123
搞定 ✅ 文件已创建:/home/zhuli/test.md,内容是 123。
⚠️ ✍️ Write: to ~/test.md (3 chars) failed 为啥会有这样的提示?2、agent怎么执行危险命令需要确认才能执行啊

nocturne bloomBOT
#

这俩问题本质上都是“工具层的真实结果 vs 模型嘴上说的结果”以及“怎么把危险操作变成必须人类点头”。


1) 为啥提示 Write ... failed,但又说“搞定文件已创建”?

⚠️ ✍️ Write: to ~/test.md ... failed 说明:文件写入工具那次调用失败了(这条比“搞定✅”更可信)。

最常见原因是你启用了“文件工具只能在 workspace 里读写”的安全护栏:

  • tools.fs.workspaceOnly: true 时,read/write/edit/apply_patch 只能访问 workspace 目录(通常是 ~/.openclaw/workspace
  • 所以写 ~/test.md(也就是 /home/zhuli/test.md)会被拒绝/失败

你可以先确认一下到底有没有写成功(别信“搞定✅”那句):

ls -la ~/test.md || true
cat ~/test.md || true
#

推荐做法:让 agent 写到 workspace 里,比如:

  • ~/.openclaw/workspace/test.md

如果你确实想允许 agent 写到 home 任意路径(风险更大),可以检查/关闭这个护栏:

openclaw config get tools.fs.workspaceOnly
# 如果是 true,并且你愿意放开:
openclaw config set tools.fs.workspaceOnly false --strict-json
openclaw gateway restart

安全建议:多数情况下别关,保持“只在 workspace 写文件”最省心。


2) “危险命令必须确认才能执行”怎么做?

分两层:

#

A) 行为层(在飞书里先问你再做)——你已经在用的那种“协议”

把你刚才那段“每一步汇报 + 关键操作先授权”的要求写进任务消息或 AGENTS.md,这会让 agent 先问再做

但注意:这只是“提示约束”,不是强制。

B) 强制层(没授权就根本跑不了)——用 exec allowlist / approvals

要做到“没确认就执行不了”,核心思路是:默认不允许 exec,只允许白名单里的安全命令;需要做危险操作时,你手动把该命令加进白名单(这一步就是你的“授权”)。

OpenClaw 这块叫 Exec approvals / allowlist,用 CLI 管:

openclaw approvals get
openclaw approvals allowlist add "/usr/bin/uptime"

文档: https://docs.openclaw.ai/tools/exec-approvals

说明:在纯 Linux headless 环境里,“弹窗让你点批准”的交互式审批 UI 不一定存在,所以更稳的方式是 allowlist + 你手动加白名单(等价于确认)。

#

如果你把下面两条输出贴一下(打码没关系),我可以告诉你当前到底是哪种限制导致 ~/test.md 写失败,以及你现在 exec 是“全开/allowlist/deny”哪种模式:

openclaw config get tools.fs.workspaceOnly
openclaw approvals get
pine glacier
nocturne bloomBOT
#

这两个其实是一套东西:tools/exec 决定 exec 怎么跑exec-approvals 决定 在 gateway/node 上跑时怎么“卡口/白名单/要不要审批”。怎么配“比较好”,取决于你要的安全强度和你是否真的想让 agent 动到系统。

下面给你一套我在“个人自用、但希望关键操作必须我点头”的 实用默认(Linux 网关、你是唯一操作者):


推荐目标(你现在的诉求)

  1. 日常命令(ls/查看状态)可以自动跑
  2. 关键/危险命令(rm、apt、systemctl、覆盖文件等)默认跑不了 → agent 必须先问你
  3. 你确认后再放行(通过把对应二进制加进 allowlist,或你自己手动执行)

1) openclaw.json:把 host exec 设成 allowlist

建议这样配(核心是:host=gateway + security=allowlist + ask=on-miss):

#
{
  tools: {
    // 可选:把读写限制在 workspace,避免 agent 乱动 home
    fs: { workspaceOnly: true },

    exec: {
      host: "gateway",        // 让 exec 走“host 执行路径”,从而受 approvals 管控
      security: "allowlist",  // 只允许白名单二进制
      ask: "on-miss",         // 不在白名单就触发“需要审批/放行”的路径
      safeBins: ["jq", "head", "tail", "cut", "tr", "wc", "uniq"],
    },

    // 重要:别开 elevated(开了等于直接 full,容易绕过审批/白名单)
    elevated: { enabled: false },
  },
#
}

改完重启:

openclaw gateway restart

说明:如果你把 host 留在默认 sandbox,很多命令只会在容器里跑,看不到真实系统状态;你想管服务器的话,一般会更想用 gateway 这个模式。


2) exec-approvals:用 allowlist 决定“哪些命令算安全可自动执行”

先看当前 approvals:

#
openclaw approvals get

然后把你愿意自动允许的只读类二进制加进去(示例):

openclaw approvals allowlist add "/usr/bin/uname"
openclaw approvals allowlist add "/usr/bin/uptime"
openclaw approvals allowlist add "/usr/bin/df"
openclaw approvals allowlist add "/usr/bin/free"
openclaw approvals allowlist add "/usr/bin/ls"
openclaw approvals allowlist add "/usr/bin/id"
openclaw approvals allowlist add "/usr/bin/whoami"

之后:

  • agent 执行这些命令会直接通过
#
  • 遇到不在 allowlist 的(比如 rmaptsystemctl),会走“on-miss”路径——你就能实现“先问我/我授权再做”的工作流

你可能会关心的两个现实点

  • Linux headless 上“弹窗点批准”通常没有 UI:所以更常用的就是 allowlist 卡口(你手动把某个二进制放行=你的授权)。
  • allowlist 是按“二进制路径”匹配,不是按整条 shell 文本;并且 allowlist 模式下对 &&、重定向等会更严格(这是安全设计,避免一条命令夹带副作用)。

如果你把 openclaw approvals get 的输出(尤其是 defaults/agents 那段)贴一下,我可以帮你把 allowlist 初始清单配得更贴合你的机器(比如 ssjournalctlsystemctl 这些你到底要不要让它自动跑)。

pine glacier
#

怎么解决安全的问题。被各种诱导

nocturne bloomBOT
#

“被各种诱导”(prompt injection / 社工)在聊天型 agent 里不可避免,解决思路不是指望模型永远聪明,而是做 分层防护:让它就算被骗也做不了坏事

下面给你一套在 OpenClaw 里最有效、最实用的加固顺序(从收益最大开始):


1) 先把“暴露面”收紧(渠道侧)

只让可信的人能触发你有能力的 agent

  • DM:用 pairing / allowlist
  • 群:requireMention: true + 群白名单(不要 open groups)

飞书相关配置点(文档里都有):channels.feishu.dmPolicy / allowFrom / groupPolicy / groupAllowFrom / groups.<chatId>.requireMention
https://docs.openclaw.ai/zh-CN/channels/feishu


#

2) 工具侧:把“能造成损害的工具”从不可信入口移走(最关键)

OpenClaw 的工具策略非常适合防注入:即便模型被诱导,也拿不到 exec/write/browser 这种高危能力

推荐:用工具 profile

  • 公开/群聊入口tools.profile: "messaging"(只允许发消息 + 查会话,不给文件/命令)
  • 你自己的私聊 → 才给 coding 或更宽的权限

示例(全局先收紧为 messaging,只在你信任的 agent/入口再放开):

{
  tools: { profile: "messaging" },
}

文档:工具 profile 说明
https://docs.openclaw.ai/zh-CN/tools

#

3) 沙箱 + 文件边界:让“就算能跑命令/读写”也被关在笼子里

  • 开沙箱:agents.defaults.sandbox.mode: "all""non-main"(群聊通常属于 non-main,会自动进沙箱)
  • 文件工具只允许 workspace:tools.fs.workspaceOnly: true(防止它去读 ~/.ssh、系统配置等)

相关文档:
https://docs.openclaw.ai/zh-CN/gateway/sandboxing
https://docs.openclaw.ai/zh-CN/gateway/security


4) 对“危险命令”启用强制卡口(exec allowlist / approvals)

你之前的诉求“关键操作要我授权”最稳的落地方式是:

  • exec 默认 security=allowlist
  • 白名单只放只读命令
  • 真要跑危险的,你手动把对应二进制加白名单(这一步就是你的授权)
#

文档:
https://docs.openclaw.ai/zh-CN/tools/exec
https://docs.openclaw.ai/zh-CN/tools/exec-approvals


建议你现在先做的一件事

跑一遍并按提示逐条修:

openclaw security audit --deep

如果你把 audit 的输出贴出来(尤其是 exposure / tools / sandbox 相关的几条 warn/critical),我可以按你的实际场景(飞书是 DM 还是群?有没有多人?需不需要 exec?)给你一份“最小改动但立刻安全很多”的 openclaw.json 配置块。

pine glacier
#

我已经卸载了计划所有的agent都跑到隔离环境,与宿主机完全分离,但是 应该怎么配置

nocturne bloomBOT
#

你说的“所有 agent 都跑到隔离环境、与宿主机完全分离”,在 OpenClaw 里有两种不同层级的做法(差别很大):

路线 1:主机跑 Gateway,但所有工具执行都进 Docker 沙箱(最常用)

这能做到:exec/read/write/browser 这类“会碰系统/文件”的动作都在容器里,不直接碰宿主机。

推荐配置(核心三件事:sandbox=all、workspaceAccess=none、禁用 host exec):

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",            // 所有会话都进沙箱
        scope: "session",       // 每会话一个容器(更隔离)
        workspaceAccess: "none" // 不把宿主机 workspace 挂进容器
      }
#
    }
  },
  tools: {
    exec: {
      host: "sandbox",   // 默认 exec 只在沙箱里跑
      security: "deny"   // 禁止 host=gateway/node(防“逃逸到宿主机”)
    },
    elevated: { enabled: false }, // 禁止 elevated 这条“全开后门”
    fs: { workspaceOnly: true }   // 额外保险:文件工具只允许 workspace(可选)
  }
}

注意取舍(这点很关键):

  • workspaceAccess: "none" 意味着:工具看到的是沙箱 workspace~/.openclaw/sandboxes/...),不是你真实的 ~/.openclaw/workspace
    → 所以像“让 agent 改 AGENTS.md / 写 MEMORY.md”这种会变得不直观(写到容器里,不会落到你的真实 workspace)。
#

前提:你得有 Docker,并按文档把 sandbox 镜像准备好:
https://docs.openclaw.ai/zh-CN/gateway/sandboxing


路线 2:整个 Gateway 都容器化(更接近“与宿主机分离”)

如果你真的想“OpenClaw 本体也别在宿主机上跑”,那就走 Docker Compose,把整个 Gateway 放进容器(宿主机只负责 Docker 运行时 + 少量挂载卷)。

文档(中文):
https://docs.openclaw.ai/zh-CN/install/docker


你先回答我一个问题,我就能把配置给你收敛到“最合适”

你说的“完全分离”里,你还希望保留哪种能力?

  1. agent 能不能写入持久化文件(比如更新 AGENTS.md / MEMORY.md)?
#
  • 能 → 你可能需要 workspaceAccess: "rw"(但这就不算“完全分离”了)
  • 不能 → workspaceAccess: "none" 最硬
  1. 你有没有 Docker(docker ps 能跑吗)?

你把 openclaw config get agents.defaults.sandboxopenclaw security audit --deep 的相关片段贴一下也行,我按你现状给你一份可直接复制的 openclaw.json 块。

pine glacier
#

那我应该怎么操作呢。我考虑地是安全性。把workspace 挂挂载或则我新建一个目录呢

nocturne bloomBOT
#

你这个点抓得很对:安全性主要取决于你“挂进去给沙箱看的那部分宿主机目录有多大”。结论先说:

  • 不要$HOME / / 这种大目录挂进沙箱
  • 最好新建一个“最小工作区目录”,只放 AGENTS/MEMORY 之类的文件
  • 挂载方式按安全强度从高到低:none > ro > rw

下面给你一个我建议的“安全优先”操作路径。


方案选择(你按需要选)

A) 最安全(强隔离):不挂 workspace

  • workspaceAccess: "none"
  • agent 的 read/write/edit 都只发生在沙箱自己的 workspace(~/.openclaw/sandboxes/...),不会碰你的真实文件
  • 缺点:agent 无法持久化写 AGENTS.md / MEMORY.md(只能你手动拷贝/同步)

B) 安全 + 可用性平衡(推荐先从这里开始):挂载一个“最小 workspace”,先用只读

#
  • 新建一个目录当 workspace,只放你愿意暴露给 agent 的文件
  • workspaceAccess: "ro":agent 能读规则/记忆,但不能改(防注入把你的 AGENTS.md 改成“放开权限”)

C) 方便但风险更高:挂载最小 workspace 为读写

  • workspaceAccess: "rw":agent 可以写入 MEMORY/日志等
  • 前提:workspace 里绝对不要放密钥/ssh key/.env/私密资料(只放“允许 agent 看到的东西”)

我建议你怎么操作(安全优先、一步步来)

Step 1:新建一个“最小 workspace”目录

例如:

mkdir -p ~/oc-workspace

把你需要的文件放进去(比如从原来的 ~/.openclaw/workspace 复制):

#
rsync -a ~/.openclaw/workspace/ ~/oc-workspace/

Step 2:把 OpenClaw 的 workspace 指到这个新目录

openclaw config set agents.defaults.workspace "~/oc-workspace"

Step 3:打开沙箱 + 先用只读挂载(推荐)

openclaw config set agents.defaults.sandbox.mode "all"
openclaw config set agents.defaults.sandbox.workspaceAccess "ro"

(可选但很建议)再加两道保险:

#
openclaw config set tools.fs.workspaceOnly true --strict-json
openclaw config set tools.elevated.enabled false --strict-json
openclaw config set tools.exec.host "sandbox"
openclaw config set tools.exec.security "deny"

重启:

openclaw gateway restart

Step 4:确认隔离是否达成

跑:

openclaw security audit --deep
#

以及让 agent 试一下写 ~/test.md,应该会失败;写 workspace 里的文件也会因为 ro 挂载而失败(这就是你想要的“防诱导”效果)。


什么时候该用 rw

当你确认:

  • 你的 workspace 已经足够“干净”(没有任何 secrets/隐私)
  • 你确实需要 agent 自动写 MEMORY/产出文件到宿主机

再切到:

openclaw config set agents.defaults.sandbox.workspaceAccess "rw"
openclaw gateway restart

#

你现在更希望:

  1. agent 能不能修改 AGENTS.md/MEMORY.md(持久化写入)?
  2. 你的服务器上 Docker 已经装好并能跑沙箱镜像了吗?

你回答这两点,我可以把上面那段配置精简成你能直接复制粘贴的一份 openclaw.json 最小安全模板。

pine glacier
#

那看来没有绝对安全了。不能读取.env那么 就不能操作登陆什么的了

nocturne bloomBOT
#

对,“绝对安全”确实不存在,但你这里有个关键误解需要纠正:

不让 agent 读取 .env(或不把 state dir 挂进沙箱)≠ 不能登录/不能用凭据。

OpenClaw 里凭据的使用分两层:

1) 凭据是给 Gateway 进程用的,不是给 agent 文件工具用的

  • ~/.openclaw/.env(state dir 里的 .env)和 ~/.openclaw/openclaw.json 里的密钥/SecretRef
    → 是 Gateway 启动时读取,用于连接模型、飞书、企业微信等渠道
  • 你把 tools.fs.workspaceOnly: truesandbox.workspaceAccess: none/ro 打开后
    → 只是限制 read/write/edit 工具不能乱读宿主机文件
    不会影响 Gateway 本身使用这些密钥来工作

所以:你完全可以做到

  • agent 工具读不到 .env
  • 但飞书/企业微信/模型照样能正常登录和发送消息
#

2) “需要修改配置/登录配置”的动作,建议由你(人)来做

像首次接入飞书、更新 token、装插件这类,本来就更适合你用:

  • openclaw onboard / openclaw configure
    来完成(这是你要的“关键操作需授权”的最佳落点)。

最推荐的安全结构(现实可用)

  • .env 放在 state dir~/.openclaw/.env(不要放到 workspace)
  • workspace 只放可公开的 agent 文件(AGENTS/MEMORY 等)
  • 沙箱模式跑工具:sandbox.mode: "all",并且 workspaceAccess: "ro""none"
  • tools.fs.workspaceOnly: true 防止工具读到 ~/.openclaw 里的 secrets

如果你把你现在的目标说清楚一句:
你是希望 “agent 永远不能碰凭据文件”,还是 “agent 不能修改/泄露凭据,但可以正常使用渠道”
我可以按你的目标给你一份最小配置模板。

pine glacier
#

那就是说可以把.env放到.openclaw目录。其他的不允许访问就行了

nocturne bloomBOT
#

对,这样做是推荐路径之一

  • 把密钥放在 state dir$OPENCLAW_STATE_DIR/.env(默认就是 ~/.openclaw/.env
  • 然后把 agent 能用的文件/命令工具限制在 workspace / 沙箱里,不要让它能读到 state dir 其它东西

几个关键点(按安全优先):

1) .env 放哪里

放这里即可(默认会被服务读取):

~/.openclaw/.env
chmod 600 ~/.openclaw/.env

OpenClaw 会读取:

  • 当前目录的 .env
  • 以及 state dir 的 .env~/.openclaw/.env
#

2) 禁止 agent 访问 .openclaw 其它内容(工具层)

建议至少打开这个:

{
  tools: { fs: { workspaceOnly: true } }
}

这样 read/write/edit 只能在 workspace 内活动,读不到 ~/.openclaw/.env、credentials、sessions 等。

3) 如果你还允许 exec:务必别让它在宿主机上跑

否则它可以 cat ~/.openclaw/.env
建议:

{
  agents: { defaults: { sandbox: { mode: "all", workspaceAccess: "ro" } } },
  tools: {
#
    exec: { host: "sandbox", security: "deny" },
    elevated: { enabled: false },
  },
}

额外建议(更稳)

如果你想把风险再压低一档:把 workspace 移到 ~/oc-workspace 这种独立目录(不要放在 ~/.openclaw/workspace 里),这样 state dir 跟 workspace 物理隔离更清晰。

你现在的 workspace 路径是默认 ~/.openclaw/workspace 还是你新建的 ~/oc-workspace?我可以按你现状给你一段最小配置,保证“gateway 能用 .env,但 agent 工具读不到”。

pine glacier
#

多agent怎么解决呢

nocturne bloomBOT
#

多 agent 的“安全解法”一般是:把不同信任级别的入口,路由到不同能力的 agent。这样就算有人诱导,也只能诱导到“低权限 agent”。

OpenClaw 的多 agent 本身就隔离了这些东西(很适合做安全分层):

  • 每个 agent 独立 workspace
  • 每个 agent 独立 auth profiles(模型/密钥不自动共享)
  • 每个 agent 独立 sessions

文档(强烈建议看这篇):https://docs.openclaw.ai/zh-CN/concepts/multi-agent


推荐架构:2 个 agent(高信任 / 低信任)

Agent A:main(你自己的私聊,高权限但仍受沙箱/allowlist约束)

  • 可以用 coding profile(需要文件/exec 就给)
  • 沙箱可以 all 或按你需要

Agent B:public(群聊/不可信入口,低权限)

#
  • tools.profile: "messaging"(只允许发消息/查会话;不给 exec/fs/web)
  • sandbox.mode: "all" + workspaceAccess: "none"(就算未来放开工具,也先关进笼子)
  • 可选:tools.fs.workspaceOnly: true 全局再加一道

关键:用 bindings 把不同入口路由到不同 agent

示例(伪代码,按你实际的飞书 dm id / 群 id 填):

{
  agents: {
    list: [
      { id: "main", default: true, workspace: "~/oc-ws-main" },

      {
#
        id: "public",
        workspace: "~/oc-ws-public",
        tools: { profile: "messaging" },
        sandbox: { mode: "all", workspaceAccess: "none" },
      },
    ],
  },

  bindings: [
    // 你的飞书私聊 -> main
    { agentId: "main", match: { channel: "feishu", peer: { kind: "dm", id: "ou_xxx..." } } },

    // 某个飞书群 -> public
    { agentId: "public", match: { channel: "feishu", peer: { kind: "group", id: "oc_yyy..." } } },
  ],
#

  // 重要:默认别开 agent-to-agent,防止低权限 agent “跳板”到高权限 agent
  tools: {
    agentToAgent: { enabled: false }
  }
}

你要“更绝对隔离”的版本

如果你担心“同一 gateway 进程里仍有共享面”(比如 channels 凭据、全局插件等),那就上 两个 gateway / 两个 OS 用户 / 两个 state dir(不同 OPENCLAW_STATE_DIR / --profile / 端口)。这是最硬的隔离边界。


你现在最想分几类入口?

#
  1. 飞书私聊(你自己)
  2. 飞书群(别人可能发消息)
    如果你把这两个 chat id(dm 的 ou_...、群的 oc_...)贴一下,我可以直接把 bindings 按你实际情况写好。
pine glacier
#

我是这样想的,两个agent,一个写代码一个审核代码。怎么解决这个问题。环境依赖代码等等

nocturne bloomBOT
#

你这个“一个写代码、一个审核代码”的双 agent 设计很好,但确实会遇到你说的 环境依赖 / 代码如何共享 这两个问题。比较靠谱的做法是:共享“镜像/依赖环境”,但不要共享同一份工作目录的写权限

下面给你两种落地方案(按安全优先排序):


方案 1(推荐,安全且清晰):两个 agent 各自一份 workspace(各自 clone),用 git/patch 交接

优点

  • 两个 agent 互不踩文件
  • review agent 可以做到几乎只读(至少不直接改你 coding workspace)
  • 环境依赖统一:两边用同一个 sandbox 镜像/同一个 setupCommand

做法

  1. 两个 workspace:
  • ~/ws-code:coding agent 用
  • ~/ws-review:review agent 用(单独 clone 同一个 repo)
#
  1. 统一用沙箱 + 固定镜像(避免每次装依赖):
  • sandbox.mode: "all"
  • sandbox.scope: "agent"(每个 agent 一个长期容器,依赖装一次即可)
  • sandbox.docker.image 指向你准备好的 common 镜像(里面带 git/node/python 等)
  1. 交接方式:
  • coding agent:提交到分支 / 生成 git diff(patch)
  • review agent:拉取分支或直接读 patch 做 review

这种方式最接近真实团队协作,也最不容易因为隔离导致“依赖/目录/权限”乱套。


方案 2(更省事但更危险):两个 agent 共享同一个 workspace,一个 rw 一个 ro

优点

  • review 看到的就是最新改动
#

缺点(安全坑)

  • ro 挂载时,很多项目跑测试会写 node_modules/target/dist/,容易失败
  • rw 挂载时,review agent 理论上也可能改文件(即使你 deny 了 write/edit,exec 仍可能改)

所以我一般只建议用于“review 只看 diff 不跑构建”的场景。


环境依赖怎么解决(两种方案都适用)

不要靠每次 session 里 apt-get install(默认 docker.network 还是 none,会失败)。更稳的是:

  • 用官方的 sandbox common 镜像(带常用工具),或
  • 自己 bake 一个镜像(把 node/git/python 等都装进去)

并且把 scope 设成 "agent",避免每次都重装:

#
agents: {
  list: [
    {
      id: "code",
      workspace: "~/ws-code",
      sandbox: { mode: "all", scope: "agent", workspaceAccess: "rw" },
      tools: { profile: "coding" },
    },
    {
      id: "review",
      workspace: "~/ws-review",
      sandbox: { mode: "all", scope: "agent", workspaceAccess: "rw" },
      tools: {
        profile: "coding",
        deny: ["write", "edit", "apply_patch"], // 先做“软只读”(至少不让它用文件工具改)
#
      },
    },
  ],
}

真“硬只读”只能靠 workspaceAccess: "ro",但那样很多项目测试会因为无法写入依赖/构建产物而痛苦。


你希望 review agent 做到哪种程度?

  1. 只做静态 review(看 diff、提建议) ——我建议方案 1,review agent 可以几乎不需要 exec
  2. 要跑测试/构建来验证 ——review agent 需要可写环境(至少容器内可写),那就用“独立 clone + scope=agent + 固定镜像”

你用的是什么项目栈(Node / Python / Go / Rust)?我可以给你一份更贴合的 sandbox 镜像/依赖策略。

pine glacier
#

ok ,我已经在一台权限的ubuntu desktop 上部署了,只给了普通的权限。

nocturne bloomBOT
#

跑在普通用户下这点是对的(比 root 安全很多)。接下来如果你的目标还是“安全 + 隔离 + 多 agent(写代码/审核)”,我建议你在这台 Ubuntu Desktop 上按这个顺序做个最小检查 + 下一步配置:

1) 先确认网关服务和配置路径都对

openclaw --version
openclaw gateway status --deep
openclaw config file

2) 先跑一次安全审计,看看当前暴露面

openclaw security audit --deep

把输出里 critical/warn 贴出来(打码即可),我可以逐条告诉你哪些是“必须改”、哪些是“可接受的风险”。

3) 如果你要“所有 agent 都在隔离环境里跑”:装 Docker + 开沙箱

Ubuntu Desktop 上最常见的隔离就是 Docker 沙箱。你先确认 Docker 是否可用:

#
docker ps

然后再看 OpenClaw 沙箱状态:

openclaw sandbox explain

4) 开始落地“两 agent(code/review)”

如果你愿意,我下一步可以直接给你一份 openclaw.json 模板,包含:

  • agents.listcode + review
  • 各自 workspace
  • sandbox.mode: "all" + scope: "agent"(依赖装一次)
  • review 禁止写文件工具(更像“审查员”)

你现在这台 Ubuntu Desktop 上:

  1. 你打算用 Docker 做沙箱吗?(docker ps 能跑通不)
#
  1. 主要是写哪种项目(Node/Python/Go/Rust)?
pine glacier
#

这样的话就不做沙箱,直接跑了

nocturne bloomBOT
#

可以,不做沙箱也能跑起来;但你之前说你更看重安全,那就要明确:不做沙箱 = 所有工具默认都在宿主机上执行,安全主要就得靠“工具策略 + 路由分层”。

我给你一个“不用沙箱但尽量稳”的配置方向(按优先级):


1) 至少把文件工具锁在 workspace(强烈建议)

不然被诱导后,read/write/edit 可能去读你 home 下的敏感文件。

{
  tools: {
    fs: { workspaceOnly: true },
  },
}
#

并且建议把 workspace 放到一个“干净目录”(别放密钥、别放 .env):

  • ~/ws-code
  • ~/ws-review

.env 放在 ~/.openclaw/.env(state dir)就好。


2) 如果你不需要 agent 跑命令:直接禁用 exec(最安全)

这会大幅降低“被诱导执行危险命令”的风险:

{
  tools: { deny: ["group:runtime"] } // 等价于 deny exec/process/bash
}
#

这样 agent 负责写代码/审代码,你自己在终端跑构建/测试。


3) 如果你需要 exec(跑测试/格式化):用 allowlist(别用 full)

不开沙箱时,exec host=sandbox 其实也是宿主机执行且不走审批;所以要强制走受控路径,建议把 exec 默认 host 设为 gateway 并用 allowlist:

{
  tools: {
    exec: {
      host: "gateway",
      security: "allowlist",
      ask: "on-miss",
      safeBins: ["jq", "head", "tail", "cut", "tr", "wc", "uniq"],
    },
#
    elevated: { enabled: false },
  },
}

然后用 openclaw approvals allowlist add "/usr/bin/git" 这类方式,把你认可的二进制加白名单。


4) 两个 agent(写代码/审核)怎么配(无沙箱版)

建议 reviewer 彻底不允许写/执行,只做只读审查:

{
  agents: {
#
    list: [
      {
        id: "code",
        workspace: "~/ws-code",
        tools: { profile: "coding" },
      },
      {
        id: "review",
        workspace: "~/ws-review",
        tools: {
          profile: "coding",
          deny: ["write", "edit", "apply_patch", "exec", "process"],
        },
      },
    ],
#
  },
}

如果你确认“不做沙箱但要跑测试”,我建议你回答一句:你主要是 Node / Python / Go / Rust 哪种项目?
我可以给你一份更贴合的 allowlist 初始清单(哪些命令该放行、哪些坚决别放)。

pine glacier
#

Node / Python / Go / Rust 这几个类型的

nocturne bloomBOT
#

明白了:你这边项目栈可能是 Node + Python + Go + Rust 都会用到。那我给你一个“不开沙箱但尽量安全”的现实建议(重点是:哪些二进制一旦进 allowlist,就等于给了几乎无限执行能力)。


先说结论:allowlist 要分层

1) “相对安全、可以长期放行”的(偏只读/检查类)

这些一般风险低很多,适合默认放行给 review agent

  • git(主要用 status/diff/log
  • rg/grep(搜索)
  • ls/stat/wc/head/tail(查看文件)
  • (可选)jq(stdin 过滤类)

2) “一旦放行就很危险”的(本质是任意代码执行/任意脚本入口)

这些放进 allowlist,基本等于“agent 可以运行任意代码”:

  • Node:nodenpmpnpm
  • Python:python3pip
  • Go:go
#
  • Rust:cargorustc

原因很简单:它们都能 -c / 执行脚本 / 拉依赖 / 跑构建脚本 —— 参数不受 allowlist 约束

所以我的建议是:

  • review agent:默认不要放行这些(只看 diff/做审查)
  • code agent:如果你必须让它跑测试/构建,那就只能放行其中一部分,但要配合你之前那套“关键操作先授权”的流程

实操怎么配(按 agent 分开 allowlist)

你可以用 openclaw approvals--agent 参数,只给 code agent 放更宽的 allowlist:

1) 先查二进制真实路径(Ubuntu 上路径可能不一样)

command -v git rg ls node pnpm python3 go cargo rustc
#

2) 给 review agent:只放“审查需要的”

openclaw approvals allowlist add --agent review "$(command -v git)"
openclaw approvals allowlist add --agent review "$(command -v rg)"
openclaw approvals allowlist add --agent review "$(command -v ls)"

3) 给 code agent:按需逐个放行(别一口气全放)

例如你当前主要是 Node:

openclaw approvals allowlist add --agent code "$(command -v node)"
openclaw approvals allowlist add --agent code "$(command -v pnpm)"
openclaw approvals allowlist add --agent code "$(command -v git)"

Rust 如果是 rustup 安装,通常在 ~/.cargo/bin/cargo,也一样用 command -v cargo 取路径再加。

#

配套建议(不开沙箱时尤其重要)

  1. code agent 的 workspace 单独一个目录(不要放任何 secrets/.env/ssh key)
  2. tools.fs.workspaceOnly: true(防止 read/write/edit 乱读 home)
  3. 如果你还没设:让 exec 强制走 allowlist 模式:
{
  tools: {
    exec: { host: "gateway", security: "allowlist", ask: "on-miss" },
    elevated: { enabled: false }
  }
}

#

你现在更偏向哪种工作流?

  • A) review agent 只看 diff(最安全,最简单)
  • B) review agent 也要 跑测试/构建(那它也得放行 node/python/go/cargo 这类“脚本入口”,安全性会明显下降)

你选 A 还是 B?我可以给你一份更具体的“Node/Python/Go/Rust 各自最小白名单”清单。

pine glacier
#

{
tools: {
exec: { host: "gateway", security: "allowlist", ask: "on-miss" },
elevated: { enabled: false }
}
}这个 host: "gateway"是什么意思

nocturne bloomBOT
#

host: "gateway"exec 这条命令要在哪台“执行主机”上跑 的意思。

在 OpenClaw 里 exec.host 有 3 个常见取值(对应你贴的 /tools/exec 文档):

  • host: "sandbox"
    在“沙箱执行环境”里跑(如果你没开沙箱,这个值实际会退化成在宿主机直接跑,而且不走 approvals/allowlist——这就是为啥不开沙箱时我更建议用 gateway 来强制走受控路径)

  • host: "gateway"
    在 Gateway 所在的那台机器上执行命令(也就是你这台 Ubuntu 上跑着 openclaw-gateway 的机器),并且会走:

    • security: "allowlist" | "deny" | "full" 的策略
    • ask: "on-miss" | "always" | "off" 的审批逻辑
      也就是说:你配置的 allowlist / exec-approvals.json 才会真正生效。
  • host: "node"
    把命令下发到你配对的 node(macOS app 或 headless node host)上执行。

所以你这段:

#
exec: { host: "gateway", security: "allowlist", ask: "on-miss" }

读成一句话就是:

“所有 exec 都在网关宿主机上跑,但必须命中白名单;如果没命中,就进入需要审批/放行的路径。”

相关文档:

你现在是“不做沙箱直接跑”,对吧?如果是,那用 host:"gateway" 的主要目的就是避免 host:"sandbox" 在无沙箱时绕过 allowlist

pine glacier
#

记忆怎么搞定,有的推荐使用qmd,减少token的消耗

nocturne bloomBOT
#

“记忆省 token”其实分两种消耗,先分清楚会更好配:

  1. 索引/Embedding 成本(把你的 MEMORY.md 做向量化时产生的 API 成本)
  2. 对话上下文 tokenmemory_search 把若干段 snippet 注入到 prompt 里,导致每次对话上下文变长)

QMD 主要省的是 (1) embedding 的远程 API 成本(更多走本地检索/本地模型);但 (2) snippet 注入 还是会增加上下文 token,所以也要同时限流。


方案 A(最省事,先推荐):继续用 builtin,但把“注入量”降下来 + 打开缓存

这对“token 消耗”立刻有感(无论你是否用 QMD):

{
  agents: {
    defaults: {
#
      memorySearch: {
        // 控制每次召回注入多少段
        query: {
          maxResults: 4,   // 默认通常偏大;先降到 3~5
          minScore: 0.2,   // 提高一点可以减少“硬凑”的低相关片段
        },
        // 避免重复 embed 未变化内容(省 embedding 成本 + 加速)
        cache: { enabled: true, maxEntries: 50000 },
      }
    }
  }
}

#

方案 B(省 embedding API 成本,不上 QMD):把 embeddings 改成本地(0 API 成本)

如果你主要想省“embedding 的钱/调用”,而不是只省 prompt tokens,这个比 QMD更“OpenClaw 原生”:

{
  agents: {
    defaults: {
      memorySearch: {
        provider: "local",
        fallback: "none",
        // local.modelPath 按文档给一个 GGUF / hf: URI
        local: { modelPath: "hf:..." }
      }
    }
  }
}
#

代价:需要本机能编译/运行 node-llama-cpp(CPU/内存/磁盘也会增加)。


方案 C(你提到的 QMD):本地侧车检索,省远程 embedding,但运维成本更高

启用是这两块:

  1. 切 backend:
{
  memory: { backend: "qmd" }
}
  1. 配 QMD 的“召回注入限流”(否则 prompt 还是会被塞很多):
#
{
  memory: {
    backend: "qmd",
    qmd: {
      command: "qmd", // 或写绝对路径,避免 systemd PATH 问题
      includeDefaultMemory: true,
      limits: {
        maxResults: 4,
        maxSnippetChars: 700,
        maxInjectedChars: 2500,
        timeoutMs: 4000
      }
    }
  }
}
#

然后你还得保证 qmd CLI 在 gateway 服务的 PATH 里(不然就会像你之前那样 code 1 失败)。

文档对应段落: https://docs.openclaw.ai/concepts/memory (QMD backend)


我建议你怎么选(按性价比)

  • 只想“少塞上下文、少烧 token” → 先做方案 A(最立竿见影)
  • 想把 embedding 也变成 0 API 成本 → 方案 B(local embeddings)方案 C(QMD)
    • 你之前 QMD 出错多的话,我会更倾向先试 local embeddings(少一个外部 CLI 依赖)

你现在主要是想省哪一种:embedding 的 API 花费,还是 对话上下文 token?我可以按你的目标给你一份最小配置块。

pine glacier
#

那选择B,怎么配置

nocturne bloomBOT
#

选 B(memorySearch.provider: "local")的话,配置分三步:改配置 → 重启 → 确认本地模型/依赖就绪


1) 写配置(建议用 openclaw config set

把 memory search 改成本地 embedding,并关闭远程 fallback(否则本地失败时会偷偷走远程,还是会花钱):

openclaw config set agents.defaults.memorySearch.provider "local"
openclaw config set agents.defaults.memorySearch.fallback "none"
openclaw config set agents.defaults.memorySearch.local.modelPath "hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf"
openclaw config set agents.defaults.memorySearch.cache.enabled true --strict-json
openclaw config set agents.defaults.memorySearch.query.maxResults 4 --strict-json
openclaw config set agents.defaults.memorySearch.query.minScore 0.2 --strict-json

modelPath 这个是文档里默认推荐的本地 embedding GGUF(大概 0.6GB),首次会自动下载。

#

2) 重启 Gateway

openclaw gateway restart

3) 验证是否真的在用本地(以及是否报错)

openclaw memory status --deep

如果成功,你会看到 provider/后端相关信息,并且后续索引/查询不会再走远程 embedding API。


#

常见坑(你提前知道就不会卡住)

  1. 首次会下载模型:需要网络 + 磁盘空间(~0.6GB+缓存)。
  2. 本地模式依赖 node-llama-cpp 原生构建
    • 如果你是用 pnpm 全局安装的,且看到过 “Ignored build scripts”,按安装文档需要:
      pnpm approve-builds -g
      pnpm add -g openclaw@latest
      
    • 如果你是用 npm 安装的,一般不会卡 approve-builds,但如果缺编译工具会报 node-gyp/编译失败(这时需要装 build-essential 等)。

你跑完第 3 步如果有报错,把 openclaw memory status --deep 的报错贴出来,我可以直接判断是“模型下载问题”还是“node-llama-cpp 编译/依赖问题”。

pine glacier
#

Memory Search (main)
Provider: local (requested: local)
Model: hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf
Sources: memory
Indexed: 0/0 files · 0 chunks
Dirty: yes
Store: ~/.openclaw/memory/main.sqlite
Workspace: ~/.openclaw/workspace
Embeddings: ready
By source:
memory · 0/0 files · 0 chunks
Vector: ready
Vector path: ~/.npm-global/lib/node_modules/openclaw/node_modules/sqlite-vec-linux-x64/vec0.so
FTS: ready
Embedding cache: enabled (0 entries)
Cache cap: 50000
Batch: disabled (failures 0/2)
Issues:
memory directory missing (~/.openclaw/workspace/memory)

nocturne bloomBOT
#

你这份输出其实说明 本地 embeddings 已经配置成功了Embeddings: ready、sqlite-vec/FTS 都 ready)。现在的问题很简单:

没有任何“记忆文件”可供索引
所以显示 Indexed: 0/0 files,并提示 memory directory missing (~/.openclaw/workspace/memory)

OpenClaw 默认会索引这些路径(Markdown):

  • ~/.openclaw/workspace/MEMORY.md
  • ~/.openclaw/workspace/memory.md
  • ~/.openclaw/workspace/memory/**/*.md

解决:建目录 + 放入至少一个记忆文件,然后重建索引

1) 创建 memory 目录(按提示)

#
mkdir -p ~/.openclaw/workspace/memory

2) 创建一个最小的 MEMORY.md(示例)

cat > ~/.openclaw/workspace/MEMORY.md <<'EOF'
# MEMORY.md

## Preferences
- Prefer progress updates for long tasks.
EOF

(你也可以改用 memory/2026-03-12.md 这种日记文件结构。)

3) 触发索引

#
openclaw memory index --force
# 或者:
# openclaw memory status --deep --index

4) 验证能搜到

openclaw memory search "progress updates"

如果你之前老环境里已经有 MEMORY.md / memory/,直接把它们 复制到当前 workspace 就行(然后再 memory index --force)。

pine glacier
nocturne bloomBOT
#

你现在有 3 个 agent(main / code / review),这些文件(AGENTS.md / SOUL.md / USER.md ...)的核心原则是:

  • 每个 agent 的 workspace 都是一套独立“大脑文件”(互不共享)
  • 你要分别在 3 个 workspace 里放对应的文件
  • 不要把 BOOTSTRAP.md 长期留着(它是“首次启动引导文件”,留着很容易让 agent 每次都以为自己在 bootstrapping ——我们之前提到过这个坑)

0) 先找出每个 agent 的 workspace 路径

在机器上跑:

openclaw agents list

你会看到类似:

  • main → ~/.openclaw/workspace(默认)
#
  • code → ~/.openclaw/workspace-code(或你自定义的)
  • review → ~/.openclaw/workspace-review

1) 每个 workspace 里该放什么文件?(推荐模板)

✅ main(你的“日常助理”)

建议放齐全:

  • AGENTS.md:行为规则/安全边界/工具使用原则(比如“关键操作先授权、每步汇报”)
  • SOUL.md:性格/表达风格
  • IDENTITY.md:名字/头像/角色(可选)
  • USER.md:你的偏好/个人信息(不含 secrets)
  • MEMORY.md + memory/:长期记忆(你刚配置了本地 embeddings,这里要有内容才能索引)
  • HEARTBEAT.md:如果你启用 heartbeat 才需要(不需要就留空或不放)

✅ code(“写代码”的 agent)

#

目标是:能产出代码/patch,但别把个人信息混进来。

  • AGENTS.md:写代码约束(目录结构、必须先跑测试/格式化、输出 patch/commit 等)
  • SOUL.md / IDENTITY.md:可以简化(比如“冷静工程师风格”)
  • USER.md:可选(如果不想它知道太多个人偏好就别放)
  • MEMORY.md:可选(很多人不给 code agent 记忆,避免乱增长)

✅ review(“审核代码”的 agent)

目标是:强约束、尽量只读

  • AGENTS.md:写清楚“只做 review,不直接改代码;输出 review checklist + 风险点 + 建议 patch”
  • SOUL.md / IDENTITY.md:可以是“严格审查员”
  • 一般不需要 HEARTBEAT.md
  • MEMORY.md 可选(也可以完全不用记忆,避免它越学越“会放水”)

2) BOOTSTRAP.md 怎么处理?

  • 只在你需要“首次引导提示词”时临时存在
#
  • 一旦 agent 正常工作了,建议把各个 workspace 里的 BOOTSTRAP.md 删掉或改名(比如 BOOTSTRAP.disabled.md

3) 文件改完后怎么生效?

一般不需要重启 gateway:

  • 对正在进行的对话:发 /reset 开新 session 最稳
  • 或者等下次新会话启动时加载

如果你愿意,我可以直接给你 3 份 AGENTS.md 的“起步内容模板”(main/code/review 各一份),你复制到对应 workspace 里就能用。你希望 code/review 的工作流是:

  • code 产出 git diff patch 给 review 看?还是
  • code 直接改文件,review 只评论?
pine glacier
#

我怎么把机器人绑定给指定的agent

nocturne bloomBOT
#

“绑定机器人到指定 agent”在 OpenClaw 里就是配置 routing bindings。有两种粒度,你先选你要哪一种:


A) 绑定“整个渠道账号”到某个 agent(最简单)

比如把 Feishu 这个账号的所有消息都交给 maincode

openclaw agents bindings
openclaw agents bind --agent code --bind feishu
# 如果你有多账号:openclaw agents bind --agent code --bind feishu:<accountId>

解绑:

openclaw agents unbind --agent code --bind feishu
#

这种方式适合“这个机器人号只干一件事”。


B) 绑定“某个具体对话(DM/群)”到某个 agent(你现在更需要的)

你有 main/code/review 三个 agent,通常要按 DM/群 分流,这就需要在 openclaw.json 里写 bindings(按 peer.kind + peer.id 精确匹配)。

1) 先拿到 Feishu 的 peer id(ou_... / oc_...)

最简单的办法:先在那个 DM/群里给机器人发一句“ping”,然后在网关机器上跑:

openclaw sessions --active 30 --all-agents
# 或者 JSON 方便复制:
openclaw sessions --active 30 --all-agents --json

你会看到 session key 里带类似:

#
  • ...:feishu:dm:ou_xxx...
  • ...:feishu:group:oc_yyy...

ou_... / oc_... 记下来。

2) 在 openclaw.json 里加 bindings

示例(按你的 id 替换):

{
  bindings: [
    { agentId: "main", match: { channel: "feishu", peer: { kind: "dm", id: "ou_你的私聊ID" } } },
    { agentId: "code", match: { channel: "feishu", peer: { kind: "group", id: "oc_写代码群ID" } } },
    { agentId: "review", match: { channel: "feishu", peer: { kind: "group", id: "oc_审核群ID" } } },
  ],
}
#

改完后:

openclaw config validate
openclaw gateway restart

如果你把 openclaw sessions --active 30 --all-agents 那段输出里 feishu 的 dm/group key 贴出来(打码别的字段也行),我可以直接帮你把 bindings 三条写成你能复制粘贴的最终版本。

pine glacier
#

我忘记怎么添加多个飞书机器人了。现在只绑定一个

nocturne bloomBOT
#

添加多个飞书机器人(多账号)的方式就是:在 openclaw.json 里给 channels.feishu.accounts 增加多个 account,并用 defaultAccount 指定默认出站账号。

1) 配置多个 Feishu 账号

编辑 ~/.openclaw/openclaw.json,类似这样:

{
  channels: {
    feishu: {
      enabled: true,
      defaultAccount: "main", // 不指定 accountId 发送时,用哪个账号
      accounts: {
        main: {
          appId: "cli_xxx",
          appSecret: "xxx",
          botName: "主机器人",
#
        },
        code: {
          appId: "cli_yyy",
          appSecret: "yyy",
          botName: "写代码机器人",
        },
        review: {
          appId: "cli_zzz",
          appSecret: "zzz",
          botName: "审核机器人",
        },
      },
    },
  },
}
#

改完重启:

openclaw gateway restart

文档位置(中文):https://docs.openclaw.ai/zh-CN/channels/feishu#多账号配置

2) 把“某个飞书账号”绑定到“某个 agent”

如果你希望不同机器人走不同 agent,最简单是按 accountId 绑定:

openclaw agents bind --agent main   --bind feishu:main
openclaw agents bind --agent code   --bind feishu:code
openclaw agents bind --agent review --bind feishu:review
openclaw agents bindings
#

这样:feishu:code 这个机器人收到的消息就会进 code agent。

如果你把你现在的 channels.feishu.accounts 配置片段(隐藏 appSecret 也行)贴一下,我可以帮你把 accountId 命名和 agent 绑定对应关系整理成一套最清晰的。

pine glacier
#

启用群聊在哪里配置,我改了没成功

nocturne bloomBOT
#

飞书“群聊是否处理消息”主要就看这几个配置项(都在 ~/.openclaw/openclaw.json):

  1. 群组策略channels.feishu.groupPolicy
  • "open":允许所有群(默认)
  • "allowlist":只允许 groupAllowFrom 里列出的群
  • "disabled":完全不处理群消息
  1. 群白名单(当 groupPolicy: "allowlist" 时必填):channels.feishu.groupAllowFrom: ["oc_xxx"]

  2. 是否必须 @ 才响应channels.feishu.groups.<chat_id>.requireMention(默认 true

文档位置(中文):https://docs.openclaw.ai/zh-CN/channels/feishu#群组访问


最常见的“我改了但没生效”原因(逐个排)

A) 没有重启 gateway

#

改完 config 后跑:

openclaw config validate
openclaw gateway restart

B) 你其实还没 @ 到机器人(默认必须 @)

默认 requireMention: true,所以群里必须 @ 机器人它才回。

C) 你开了 allowlist,但 groupAllowFrom 没填对 chat_id

先在群里 @机器人发一句话,然后:

openclaw logs --follow

日志里会出现 chat_id: oc_...,把这个 oc_... 填进 groupAllowFrom

D) 多账号(多飞书机器人)时改错账号/改错配置块

#

如果你用了 channels.feishu.accounts.{main,code,review},确认你改的是同一份 channels.feishu 配置(它是 channel 级配置,通常对所有 accounts 生效),并且该群里加的是你预期的那个机器人。


两个“可直接用”的示例

允许所有群(但必须 @)

{
  channels: { feishu: { groupPolicy: "open" } }
}

只允许特定群(并且不需要 @)

{
#
  channels: {
    feishu: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["oc_xxx"],
      groups: {
        oc_xxx: { requireMention: false },
      },
    },
  },
}

你把你现在的 channels.feishu 这段配置(打码 appSecret 没关系)贴一下,再告诉我:你是在群里 @ 了机器人 还是希望 不 @ 也响应?我就能直接指出是哪一项没对齐。

pine glacier
#

群聊哈了15:05:57 warn plugins {"subsystem":"plugins"} [plugins] plugins.allow is empty; discovered non-bundled plugins may auto-load: feishu (/home/zhuli/.npm-global/lib/node_modules/openclaw/extensions/feishu/index.ts). Set plugins.allow to explicit trusted ids.
15:05:57 info plugins {"subsystem":"plugins"} feishu_doc: Registered feishu_doc, feishu_app_scopes
15:05:57 info plugins {"subsystem":"plugins"} feishu_chat: Registered feishu_chat tool
15:05:57 info plugins {"subsystem":"plugins"} feishu_wiki: Registered feishu_wiki tool
15:05:57 info plugins {"subsystem":"plugins"} feishu_drive: Registered feishu_drive tool
15:05:57 info plugins {"subsystem":"plugins"} feishu_bitable: Registered bitable tools
15:05:57 warn tools {"subsystem":"tools"} tools.profile (coding) allowlist contains unknown entries (apply_patch, cron, image). These entries won't match any tool unless the plugin is enabled.

nocturne bloomBOT
#

你这段日志里有两类 warning,都不会直接“卡死群聊”,但确实建议处理一下(尤其是第一个)。


1) [plugins] plugins.allow is empty ... discovered non-bundled plugins may auto-load: feishu

意思是:你现在没设置插件白名单,OpenClaw 发现了一个“非内置插件”(feishu) 可以被自动加载,所以提醒你显式信任,避免将来目录里多了别的插件也被加载。

解决:在 openclaw.json 里加 plugins.allow

例如你只用飞书 + 企业微信:

{
  plugins: {
    allow: ["feishu", "wecom-openclaw-plugin"],
  },
}
#

改完一定要:

openclaw gateway restart

(插件配置改动需要重启才生效。)


2) tools.profile (coding) allowlist contains unknown entries (apply_patch, cron, image)

这表示:当前运行时“可用工具列表”里没有这些工具,所以它提示“这些条目不会匹配任何工具”。

常见原因:

  • apply_patch:是实验能力/有条件才出现(比如需要启用 tools.exec.applyPatch.enabled,且通常只对特定模型/环境生效)
  • cron:是 ownerOnly 工具,你当前会话/身份不满足 owner 时它不会出现在可用工具里
  • image:如果你没启用/没配置图像理解相关能力,也可能不会加载
#

这条 一般可以先忽略(它更多是“你以为有这些工具,但现在其实没有”),不影响飞书群聊收发。


群聊没响应的核心还是看 Feishu 的 groupPolicy / requireMention

你如果是“群里不回”,最常见还是:

  • 没 @ 机器人(默认 requireMention=true)
  • groupPolicy/groupAllowFrom 没配对
  • 改了 config 没重启

你把你现在 openclaw config get plugins(或 openclaw.json 里 plugins 那段)贴一下,我可以帮你把 plugins.allow 写成最小且正确的列表,避免以后插件越装越多风险扩大。

pine glacier
#

ue
running: false
cdpPort: 18800
cdpUrl: http://127.0.0.1:18800
browser: unknown
detectedBrowser: chromium
detectedPath: /snap/bin/chromium
profileColor: #FF4500
zhuli@zhuli-pc:~$ openclaw browser start

🦞 OpenClaw 2026.3.11 (29dc654) — Finally, a use for that always-on Mac Mini under your desk.



GatewayClientRequestError: Error: Failed to start Chrome CDP on port 18800 for profile "openclaw".
Hint: If running in a container or as root, try setting browser.noSandbox: true in config.
Chrome stderr:
[25015:25015:0312/231003.858833:ERROR:chrome/browser/process_singleton_posix.cc:345] Failed to create /home/zhuli/.openclaw/browser/openclaw/user-data/SingletonLock: Permission denied (13)
[25015:25015:0312/231003.859007:ERROR:chrome/app/chrome_main_delegate.cc:513] Failed to create a ProcessSingleton for your profile directory. This means that running multiple instances would start multiple browser processes rather than opening a new window in the existing process. Aborting now to avoid profile corruption.
怎么解决

nocturne bloomBOT
#

这个报错的根因不是 CDP 端口,而是 浏览器 profile 目录权限不对

Failed to create .../user-data/SingletonLock: Permission denied (13)

通常是因为:

  • 之前用 root 跑过 OpenClaw/浏览器,~/.openclaw/browser/... 被 root 拥有;或
  • 目录权限被改坏了;或
  • 有残留的锁文件但当前用户没权限覆盖。

解决(推荐顺序)

1) 先看这个目录是谁的

ls -ld ~/.openclaw/browser ~/.openclaw/browser/openclaw ~/.openclaw/browser/openclaw/user-data
ls -l  ~/.openclaw/browser/openclaw/user-data | head
#

如果 owner 不是 zhuli,就修复所有权:

sudo chown -R zhuli:zhuli ~/.openclaw/browser
sudo chmod -R u+rwX ~/.openclaw/browser

2) 清理/重置锁文件(不建议直接 rm -rf,先改名备份)

mv ~/.openclaw/browser/openclaw/user-data \
   ~/.openclaw/browser/openclaw/user-data.bak.$(date +%s)

这会重置 OpenClaw 管理的 Chromium 用户数据目录(相当于给它一个全新的 profile)。

3) 再启动

#
openclaw browser start

补充说明:

  • 日志里提示的 browser.noSandbox: true 主要是给 root/容器 用的;你这里是普通用户权限问题,通常不用开 noSandbox
  • 如果你之后仍失败,把 ls -ld ... 那几行输出贴一下,我可以确认是不是又有某个子目录权限没修到。
pine glacier
#

zhuli@zhuli-pc:~$ ls -ld ~/.openclaw/browser ~/.openclaw/browser/openclaw ~/.openclaw/browser/openclaw/user-data
drwxrwxr-x 3 zhuli zhuli 4096 3月 12 23:08 /home/zhuli/.openclaw/browser
drwxrwxr-x 3 zhuli zhuli 4096 3月 12 23:08 /home/zhuli/.openclaw/browser/openclaw
drwxrwxr-x 3 zhuli zhuli 4096 3月 12 23:08 /home/zhuli/.openclaw/browser/openclaw/user-data
zhuli@zhuli-pc:~$ ls -l ~/.openclaw/browser/openclaw/user-data | head
总计 8
drwxrwxr-x 2 zhuli zhuli 4096 3月 12 23:08 Default
-rw-rw-r-- 1 zhuli zhuli 414 3月 12 23:08 Local State
zhuli@zhuli-pc:~$ mv ~/.openclaw/browser/openclaw/user-data
~/.openclaw/browser/openclaw/user-data.bak.$(date +%s)
zhuli@zhuli-pc:~$ openclaw browser start

🦞 OpenClaw 2026.3.11 (29dc654) — I can run local, remote, or purely on vibes—results may vary with DNS.



GatewayClientRequestError: Error: Failed to start Chrome CDP on port 18800 for profile "openclaw".
Hint: If running in a container or as root, try setting browser.noSandbox: true in config.
Chrome stderr:
[25572:25572:0312/231303.273559:ERROR:chrome/browser/process_singleton_posix.cc:345] Failed to create /home/zhuli/.openclaw/browser/openclaw/user-data/SingletonLock: Permission denied (13)
[25572:25572:0312/231303.273697:ERROR:chrome/app/chrome_main_delegate.cc:513] Failed to create a ProcessSingleton for your profile directory. This means that running multiple instances would start multiple browser processes rather than opening a new window in the existing process. Aborting now to avoid profile corruption.
zhuli@zhuli-pc:~$

nocturne bloomBOT
#

你这个不是 .openclaw 目录权限的问题(你已经是 zhuli:zhuli 了),而是 Ubuntu 上的 snap Chromium / AppArmor 限制的典型症状。

OpenClaw 文档里专门写了这类报错(“Failed to start Chrome CDP on port 18800” + 各种 Permission denied / singleton lock)。对应页面:
https://docs.openclaw.ai/zh-CN/tools/browser-linux-troubleshooting

你有两个可选解法:


解法 1(推荐,最省心):装 Google Chrome 的 .deb(避开 snap 限制)

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
sudo apt --fix-broken install -y

然后配置 OpenClaw 用它(~/.openclaw/openclaw.json):

#
{
  browser: {
    enabled: true,
    executablePath: "/usr/bin/google-chrome-stable",
    headless: true,
    noSandbox: true,
  },
}

重启 gateway 后再试:

openclaw gateway restart
openclaw browser start
#

解法 2:继续用 snap Chromium,但改成 attachOnly(OpenClaw 不负责启动,只负责连接)

配置:

{
  browser: {
    enabled: true,
    attachOnly: true,
    headless: true,
    noSandbox: true,
  },
}

然后你自己手动起 Chromium(或做一个 systemd user service):

#
chromium-browser --headless --no-sandbox --disable-gpu \
  --remote-debugging-port=18800 \
  --user-data-dir=$HOME/.openclaw/browser/openclaw/user-data \
  about:blank &

如果你这一步仍然 permission denied,那就把 --user-data-dir 换到 snap 允许写的目录(通常是 $HOME/snap/chromium/common/...),再 attach。


我建议你直接走“解法 1”(装 deb 版 Chrome),在 Ubuntu Desktop 上最稳定。你想用 Chrome 还是继续坚持 Chromium?我可以按你选的路线把 openclaw config set ... 的命令也给你写好。

pine glacier
#

为什么会莫名奇妙的收到消息OpenClaw: access not configured.
Your Feishu user id: ou_6b81715baee4729fd00e114a91e98257
Pairing code: F2C84GDL
Ask the bot owner to approve with:
openclaw pairing approve feishu F2C84GDL
Exec approval is required, but Feishu does not support chat exec approvals.
Approve it from the Web UI or terminal UI, or from Discord or Telegram if those approval clients are enabled.
收到!我在这里。有什么需要帮忙的吗?
新消息
收到!有什么我可以帮你的吗?

nocturne bloomBOT
#

这条不是“莫名其妙的消息”,它是 OpenClaw 的 Feishu 私聊访问控制(pairing) 提示。

为什么会出现

你当前的飞书私聊策略大概率是默认的:

  • channels.feishu.dmPolicy: "pairing"

所以当机器人收到一个未配置/未批准的飞书用户发来的 DM(包括你自己在迁移/换机器人后 open_id 变了的情况),就会自动回一条:

  • OpenClaw: access not configured
  • 给你一个 Pairing code
  • 要求 bot owner 在服务器上 openclaw pairing approve feishu <CODE> 批准

另外:飞书的 open_id 是“应用维度”的。你新增/换了一个飞书机器人(不同 appId)后,同一个人看到的 ou_... 可能会变化,所以需要重新配对一次是正常的。

怎么解决(两种方式)

方式 A:批准这次配对(推荐)

#

在跑 Gateway 的那台机器上执行:

openclaw pairing list feishu
openclaw pairing approve feishu F2C84GDL

方式 B:改成 allowlist(不想再收到配对码)

{
  channels: {
    feishu: {
      dmPolicy: "allowlist",
      allowFrom: ["ou_6b81715baee4729fd00e114a91e98257"],
    },
  },
}
#

然后:

openclaw gateway restart

关于那句 “Exec approval is required, but Feishu does not support chat exec approvals.”

这表示:你的 agent 触发了一个需要 exec 审批 的命令,但飞书不能在聊天里做审批交互。解决思路:

  • 要么去 Web UI / 终端 UI 里审批
  • 要么把 Feishu 里的 exec 限制得更死(deny exec / allowlist 命中即可不触发审批)

你想走哪种?你把你现在的 channels.feishu.dmPolicy/allowFromtools.exec.* 配置贴一下(打码 appSecret),我帮你配成“不会乱弹 pairing/exec 审批”的组合。

pine glacier
#

问题是,我在跟A机器人对话,B机器人莫名其妙的回消息了

nocturne bloomBOT
#

这件事从 OpenClaw 的机制上看,基本只有两种可能(结论先说):

同一条入站消息在一个 Gateway 里只会路由给一个 agent。
所以你看到 “跟 A 对话,B 也回了”,通常意味着:

情况 1(最常见):你在同一个飞书群里加了两个/多个“机器人账号”(多 Feishu bot)

飞书群里每个 bot 都能收到同一条群消息事件——如果你把 requireMention 关了(或你没 @ 但 bot 仍响应),那就会出现 A、B 都回

解决:

  • 最推荐:每个 bot 用不同的群(写代码群 / 审核群分开)
  • 或者:保持默认的“必须 @ 才响应”:
    {
      channels: {
        feishu: {
          groups: {
    
#
          oc_xxx: { requireMention: true }, // 默认就是 true
        },
      },
    },
  }

然后你在群里只 @ 你想要的那个机器人(A 或 B)。

你之前如果为了测试把 requireMention: false 配过,记得改回去并 openclaw gateway restart


情况 2:其实有两套 Gateway/服务在跑(两个 OpenClaw 实例都连着 Feishu)

比如你之前 root 那套没完全停干净、或另一台机器也在跑,导致同一个群消息被两个实例消费,从而“另一个机器人/另一个 agent”也回了。

快速确认:

#
openclaw gateway status --deep
openclaw gateway probe

以及看路由到底进了哪个 agent:

openclaw agents bindings
openclaw logs --follow

日志里会出现 sessionKey/agentId,能一眼看出是谁处理的。


你这个现象发生在 飞书群 还是 私聊?以及你那个群里现在是不是同时加了 main/code/review 三个 bot?
只要你回答这两个问题,我就能直接告诉你应该用“分群”还是“强制 @ 才响应”的配置。

pine glacier
#

单聊

pine glacier
#

openclaw secrets audit

🦞 OpenClaw 2026.3.11 (29dc654) — I run on caffeine, JSON5, and the audacity of "it worked on my machine."

Secrets audit: findings. plaintext=13, unresolved=0, shadowed=0, legacy=0.

  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/openclaw.json:channels.feishu.accounts.main.appSecret channels.feishu.accounts.main.appSecret is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/openclaw.json:channels.feishu.accounts.coder.appSecret channels.feishu.accounts.coder.appSecret is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/openclaw.json:channels.feishu.accounts.review.appSecret channels.feishu.accounts.review.appSecret is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/openclaw.json:channels.feishu.accounts.architect.appSecret channels.feishu.accounts.architect.appSecret is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/openclaw.json:gateway.auth.token gateway.auth.token is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/agents/main/agent/auth-profiles.json:profiles.minimax-cn:default.key Auth profile API key is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/agents/architect/agent/auth-profiles.json:profiles.minimax-cn:default.key Auth profile API key is stored as plaintext.
  • [PLAINTEXT_FOUND] /home/zhuli/.openclaw/agents/code/agent/auth-profiles.json:profiles.minimax-cn:default.key Auth profile API key is stored as plaintext.

zhuli@zhuli-pc:~/.openclaw$  如何修复

nocturne bloomBOT
#

secrets audit 这类 “PLAINTEXT_FOUND” 的修复方式就是:把这些字段从明文改成 SecretRef(通常落到 ~/.openclaw/.env 里),然后让 CLI 帮你把 openclaw.json / auth-profiles.json 里的明文 一键 scrub 掉

最推荐的流程(官方就是这么设计的):

1) 先跑交互式向导生成/应用方案

在网关机器的终端(需要 TTY):

openclaw secrets configure

在向导里你一般会做两件事:

  1. 配置一个 secrets provider(最简单是 env provider,对应 ~/.openclaw/.env
  2. 把这些明文字段映射成 SecretRef(比如 Feishu 的 appSecretgateway.auth.token、以及各 agent 的 auth-profiles.json API key)

最后选择 Apply,它会:

  • openclaw.json / auth-profiles.json 改成 { source, provider, id } 形式
#
  • 同时把原来的明文值 scrub 掉(不可逆)

2) 因为你有多个 agent:对每个 agent 的 auth-profiles 做一次(推荐)

audit 里显示明文出现在 agents/mainagents/architectagents/code ……
所以你可以分别跑:

openclaw secrets configure --agent main
openclaw secrets configure --agent code
openclaw secrets configure --agent review
openclaw secrets configure --agent architect

(每次都会处理 openclaw.json 的全局字段 + 该 agent 的 auth-profiles。)

3) 应用后复查 + 重新加载快照

#
openclaw secrets audit --check
openclaw secrets reload
openclaw gateway restart

4) 保护 .env(别忘了)

chmod 600 ~/.openclaw/.env

补充:即使改成 SecretRef,.env 依然是明文文件(只是把明文集中到一个权限更好控制的位置,并避免散落在多个 JSON 里/被误提交)。如果你想更强(keyring/1Password/pass 等),也可以换 SecretRef provider,但 env 是最快落地的。

你现在方便跑 openclaw secrets configure 吗(在有交互终端的机器上)?如果你把向导里 “provider 选择界面” 截图/贴一下选项,我可以告诉你该选哪一种最适合 Ubuntu。

pine glacier
#

Provider source
│ ● env
│ ○ file
│ ○ exec

选哪一种

nocturne bloomBOT
#

这一步是在选 SecretRef 的“存储/取值来源”。三个选项含义和推荐如下(按“易用→复杂”排序):

✅ 选 env(我最推荐你先用这个)

  • 会把密钥迁移到:~/.openclaw/.env(也就是 $OPENCLAW_STATE_DIR/.env
  • Gateway 作为 systemd 服务启动时也能稳定读取(不会丢环境变量)
  • 你只要把文件权限锁好就行:
chmod 600 ~/.openclaw/.env

适用:个人机器/单机部署、追求省事 + 足够安全。


file(把 secrets 放到一个 JSON 文件里)

  • 会用类似 ~/.openclaw/secrets.json 这种文件存成 JSON(通过 JSON pointer 取值)
#
  • 依然是明文文件(除非你自己做磁盘加密/加密文件),但比散落在 openclaw.json 里更好管理

适用:你不喜欢 .env,或者想更结构化地管理 secrets。


exec(最强但最复杂)

  • 不在磁盘里存密钥;每次需要时执行一个“resolver 命令”去取(例如 Vault/1Password/pass/自写脚本)
  • 安全性上限最高,但配置和维护成本也最高(还要考虑可执行文件路径可信、权限、超时等)

适用:你已经有成熟的 secrets manager,并且愿意多折腾来换更强安全。


结论

你现在是在 Ubuntu Desktop 上做个人部署、主要想先把 secrets audit 里明文清掉 —— env 就对了。后面真需要再升级到 exec 也不晚。

#

选完 env 后,如果向导让你给变量命名,我建议按账号/agent 分开命名(例如 FEISHU_MAIN_APP_SECRETFEISHU_CODE_APP_SECRETMINIMAX_API_KEY_CODE 这种),方便长期维护。

pine glacier
#

openclaw secrets configure --agent main

🦞 OpenClaw 2026.3.11 (29dc654) — It's not "failing," it's "discovering new ways to configure the same thing wrong."


◇ Configure secret providers (only env refs are available until file/exec providers are added)
│ Add provider

◇ Provider source
│ env

◇ Provider alias
│ default

◇ Env allowlist (comma-separated, blank for unrestricted)


◇ Configure secret providers
│ Continue

◇ Select credential field
│ profiles.minimax-cn:default.key (auth profile, agent main)

◇ Secret source
│ env

◇ Provider alias
│ default

◇ Secret id
│ MINIMAX_API_KEY
SecretRefResolutionError: Environment variable "MINIMAX_API_KEY" is missing or empty.

nocturne bloomBOT
#

这个报错很正常:secrets configure 选了 source=env 后,会做 预检——要求你指定的环境变量在当前环境里必须已经存在且非空,它不会“帮你自动生成/猜出” MINIMAX_API_KEY

所以你现在要做的是:先把 key 放进环境变量(或放进 ~/.openclaw/.env 并让当前 shell 也能读到),再重新跑 secrets configure


推荐修复步骤(最稳、不会丢 key)

1) 先把 MINIMAX key 写到 ~/.openclaw/.env(持久化给 gateway service)

chmod 700 ~/.openclaw 2>/dev/null || true
touch ~/.openclaw/.env
chmod 600 ~/.openclaw/.env
# 然后用编辑器把这一行加进去(值从你现有 auth-profiles.json 里复制)
# MINIMAX_API_KEY=xxxxxxxx
#

注意:值不要发到群里/截图里。

2) 让当前终端也能看到这个变量(给 configure 预检用)

set -a
source ~/.openclaw/.env
set +a
echo "${MINIMAX_API_KEY:+OK}"

看到 OK 就说明当前 shell 已经有变量了。

3) 重新跑

openclaw secrets configure --agent main
#

等它生成 plan 并 apply 后,再跑:

openclaw secrets audit --check
openclaw secrets reload
openclaw gateway restart

小建议(多 agent 时避免冲突)

如果你不同 agent 用不同 key,环境变量 id 建议分开命名:

  • MINIMAX_API_KEY_MAIN
  • MINIMAX_API_KEY_CODE
  • MINIMAX_API_KEY_REVIEW

然后在 configure 里分别选对应的 id。

#

如果你愿意,把你 main 的 auth-profiles.json 里 profile 名字那行(不含 key 值)贴一下,我可以告诉你应该映射到哪个 env id 最清晰。

pine glacier
#

exec-approvals.json 应该怎么配置,

nocturne bloomBOT
#

exec-approvals.json 的作用是:当你用 exec host=gateway|node 时,按 security/allowlist/ask 决定“这条命令能不能在真实主机上跑”。文件位置默认是:

  • ~/.openclaw/exec-approvals.json

文档: https://docs.openclaw.ai/tools/exec-approvals


先给你一个关键建议(Linux + Feishu 场景)

你之前也看到了提示:Feishu 不支持 chat 里审批 exec
所以如果你没有用 Web UI / Terminal UI 来点“批准”,那我建议把 ask 设成 off,只用 allowlist 做硬卡口(不弹审批、没白名单就直接拒绝)。


推荐模板(main/code/review 三个 agent)

#
{
  "version": 1,
  "defaults": {
    "security": "allowlist",
    "ask": "off",
    "askFallback": "deny",
    "autoAllowSkills": false
  },
  "agents": {
    "main": {
      "security": "allowlist",
      "ask": "off",
      "askFallback": "deny",
      "autoAllowSkills": false,
      "allowlist": [
#
        { "pattern": "/usr/bin/git" },
        { "pattern": "/usr/bin/rg" },
        { "pattern": "/usr/bin/ls" }
      ]
    },
    "code": {
      "security": "allowlist",
      "ask": "off",
      "askFallback": "deny",
      "autoAllowSkills": false,
      "allowlist": [
        { "pattern": "/usr/bin/git" },
        { "pattern": "/usr/bin/node" },
        { "pattern": "/usr/bin/pnpm" }
      ]
#
    },
    "review": {
      "security": "deny",
      "ask": "off",
      "askFallback": "deny",
      "autoAllowSkills": false,
      "allowlist": []
    }
  }
}

说明:

  • review 我直接给 security: "deny",相当于这个 agent 永远不能 exec(更符合“只审不跑”)。
  • code 里如果你把 node/pnpm 放行,就等于允许它跑任意构建/脚本(风险更高);你可以先不放,按需再加。
#

更省事的方式:用 CLI 管理 allowlist(不手改 JSON)

查看当前:

openclaw approvals get

给某个 agent 加一条(推荐用 command -v 拿真实路径):

openclaw approvals allowlist add --agent code "$(command -v git)"
openclaw approvals allowlist add --agent code "$(command -v pnpm)"
openclaw approvals allowlist add --agent main "$(command -v rg)"

#

最后提醒一下:你在 openclaw.json 里也要配好 exec 走 gateway 受控路径(否则 approvals 没意义):

{
  tools: { exec: { host: "gateway", security: "allowlist", ask: "off" } }
}

你现在 node/pnpm/go/cargo 这些工具是装在 /usr/bin 还是 nvm/rustup(~/.nvm/...~/.cargo/bin/...)?路径不同,我建议的 allowlist pattern 写法也会不一样。

spice wigeonBOT
#

This thread is getting very long and answers may not be accurate due to the large context. Please start a new thread for any different problems/topics. @nocturne bloom please sum up the answer to the initial message and the conversation briefly.

pine glacier
#

@nocturne bloom please sum up the answer to the initial message and the conversation briefly.

nocturne bloomBOT
#
  • 迁移(root → 普通用户/新机器):核心是迁移两样东西:$OPENCLAW_STATE_DIR(默认 ~/.openclaw/,含 config/credentials/sessions)+ workspace(默认 ~/.openclaw/workspace/)。先 openclaw gateway stop,拷贝完整目录到新用户家目录并 chown -R,再在新用户下跑 openclaw doctor + openclaw gateway install/restart
  • 普通用户提示 openclaw: command not found:说明新用户没有 Node/npm/CLI 环境;解决是给新用户安装 Node 22+ 和 OpenClaw(推荐直接跑 install.sh),或全局安装到 /usr/local/bin
  • EACCES 访问 /root/.openclaw/workspace/...:配置还指向 root 的 workspace;用 openclaw config set agents.defaults.workspace "~/.openclaw/workspace"(或你的新路径)并确保 workspace 文件复制到位。
  • 安全/防诱导的思路:靠分层防护而不是“模型别被骗”。收紧群聊策略(groupPolicy/requireMention/allowlist),收紧工具(tools.profile: messaging/minimal 给不可信入口),必要时启用沙箱;文件工具可用 tools.fs.workspaceOnly: true 限制只能读写 workspace。
  • exec 的确认/白名单:飞书不支持聊天内 exec 审批;更实用的是 tools.exec.host: "gateway" + security: "allowlist",用 exec-approvals.json/openclaw approvals allowlist add 做硬卡口(无 UI 的情况下建议 ask: off,没白名单就直接拒绝)。
  • 记忆省 token(选了本地 embeddings):配置 agents.defaults.memorySearch.provider: "local" + fallback: "none" + local.modelPath: hf:...,并调小 query.maxResults/提高 minScore;如果 status 提示 memory directory missing,创建 workspace/memory/MEMORY.mdopenclaw memory index --force
  • 多 Feishu 机器人/多 agent:多个机器人用 channels.feishu.accounts.{id} + defaultAccount;把账号绑定到 agent 用 openclaw agents bind --agent X --bind feishu:<accountId>;群聊启用看 channels.feishu.groupPolicy/groupAllowFrom/groups.<id>.requireMention,改完要 gateway restart
  • 为什么 A 对话 B 也回:通常是同一个群里加了多个 bot 且不要求 @,或有两套 gateway 同时跑;用 requireMention: true/分群、以及检查 gateway status --deep + agents bindings + logs 来定位。
  • 浏览器在 Ubuntu 上启动失败:snap Chromium 常见;推荐装 Google Chrome deb 并设置 browser.executablePath,或走 attachOnly 手动启动。
  • Secrets audit 明文:用 openclaw secrets configure/apply 把明文字段迁到 SecretRef(常用 env~/.openclaw/.envchmod 600),并对每个 agent 的 auth-profiles.json 分别处理(--agent <id>),最后 `secrets audit