OpenClaw 多用户模式与 USER.md 用户模型:共用一个 agent 时谁能看到谁的会话

2026-08-17

两个人共用一个 OpenClaw agent,最先撞上的往往不是技术问题,而是”这条会话是谁开的""他现在是不是也在看这个会话""我这半截活能不能先别出现在同事的侧边栏里”。再往后一点,是另一类问题:我告诉过它一次”实现过程中别写长篇解释”,下次开新会话它又忘了,这种稳定偏好该往哪儿放。

OpenClaw 把这两件事分成了两份文档:多用户模式(multi-user)管的是会话归属与在场感知,用户模型(USER.md)管的是跨会话的稳定偏好。它们看起来都像”多人协作”,但解决的问题完全不同,混着理解会踩坑——尤其是多用户模式,官方文档在开篇第二段就写了一句劝退式的警告。

先把那句警告摆在最前面,因为它决定了后面所有功能该怎么用。

多用户模式不是隔离机制,官方把这一条写在最前面

官方原文的意思很直白:任何能操作某个 agent 的人,都能让这个 agent 做它能做的任何事。会话归属、侧边栏里的可见性、在场指示器,这些是易用性功能,不是安全边界

所以文档给出的判断标准也很硬:如果这些人之间不允许互相访问对方的会话、工具、凭据和文件,那就给他们各自独立的 agent,或者干脆用独立的网关 / 宿主机作为信任边界。不要指望靠”归属头像”和”人物筛选器”来做隔离。

这一条值得展开一下,因为它经常被误读。共享网关意味着共享一个信任域——会话、工具、凭据、文件都在这个域里。多用户模式让你看得清是谁在干活,但没有让你拦得住谁去碰什么。真正约束”能做什么动作”的是操作者作用域(operator scopes),那属于另一套机制,和沙箱、工具策略、提权的边界一起理解会更清楚,可以参考沙箱、工具策略与提权的边界。而如果你的诉求本来就是”几个人各干各的、互不可见”,那正确答案是拆 agent,见多 Agent 与专家分线

会话归属:createdActor 写一次就不再改

新会话在创建时会记录一个 createdActor 字段,写一次就不再变更(write-once),前提是创建路径能够证明是谁触发的:

  • 已认证的人使用其持久的 Gateway 档案 id
  • 发起请求的 agent 和系统路径,也写入同一个 actor 字段;
  • 无法证明触发者的创建路径,会话就保持”无归属”状态。

有一个设计细节值得留意:OpenClaw 不会把显示名字存进会话条目。人的显示名是在返回会话列表时,从当前的 Gateway 档案里现查的。这意味着某人改了档案名之后,归属 UI 会直接跟着变,而不需要回头去重写历史会话记录。

对运维来说,这条的实际含义是:会话历史里存的是稳定 id,不是可能过期的名字快照;改名不会造成”同一个人在不同时期显示成两个人”。想进一步了解会话本身的生命周期,可以看会话模型:主会话、附着与状态

界面上区分”归属”和”在场”的三个信号

Web 应用把”这个会话是谁的”和”现在谁在看”做成了视觉上互不混淆的两类元素。文档写明的语义如下:

元素表示什么时效
实心(solid)归属头像这个会话的创建者会话的整个生命周期内固定不变
带圆环或半透明的在场头像当前已连接 / 正在观看的人随连接状态实时变化
侧边栏的人物筛选器只看某个身份创建的会话与既有自定义分组并存,不冲突

还有一条容易被忽略的行为:当已加载的会话列表里出现的不同创建者少于两个时,OpenClaw 会把所有归属和人物筛选相关的界面元素整体隐藏。也就是说,单人使用的网关看上去和没有多用户模式时完全一样,不会平白多出一堆用不上的头像和筛选入口。

这个设计对判断故障很有用:如果你确信有两个人在用,却看不到归属 UI,那说明系统识别到的不同创建者仍然只有一个——很可能是有人的会话走的是无法证明触发者的创建路径,落成了”无归属”,或者两个人其实共用了同一个 Gateway 档案。

按身份走的便利状态:偏好和最近使用

当一条连接具备持久的 Gateway 档案时,两类”便利状态”会跟着人走,而不是跟着浏览器走:

  • 新建会话的偏好设置:跟随这个人跨浏览器保持,但偏好本身仍然是按 agent 分别保存的
  • 选择器的最近使用(recents):只从这个人自己创建过的会话里推导。

反过来,如果一条连接没有持久身份,那么偏好就退回浏览器本地存储,最近使用则从当前加载的会话列表整体推导——也就是说,它会掺进别人的会话。

文档紧接着又强调了一遍同样的话:这套状态是为了连续性,不是授权或隔离边界。操作者作用域仍然管着动作,共享的 Gateway 仍然是一个信任域。同一句警告在一页文档里出现两次,通常说明官方在真实场景里被误用过。

草稿:把半成品挡在同事的侧边栏之外

如果一段工作还没成形,可以以草稿(draft)方式开会话,在你主动发布之前,它不会出现在队友的侧边栏里。

两个限制要记清楚:

  1. 管理员始终能看到草稿,包括别人的草稿,只是会带一个淡化的”幽灵”标记;
  2. 官方明确写了,这仍然是协作功能,不是安全边界

所以草稿的正确用法是”减少噪音”——避免半截思路刷屏、避免同事误以为某个任务已经在推进;而不是”藏东西”。

轮次归属是尽力而为,不保证逐人可分

多人同时对着一个会话说话时,一个自然的期待是:转录里能看出哪句话是谁说的。官方对此的表述是尽力而为(best-effort)

原因写得很具体:插话(steering)会把输入合并进正在进行的轮次,因此转录并不总能把每个人的贡献表示成独立的一轮。

这条要提前跟团队讲清楚。如果你打算把会话转录当成”谁提出了什么”的责任记录,那它在多人插话的场景下会失真——这不是 bug,是机制使然。

USER.md:把稳定偏好写成指令,而不是观察记录

换到另一半话题。USER.md 是 agent 工作区里可选的用户模型文件,存放稳定偏好、沟通风格、人际关系、以及当前项目背景,形式是能指导后续会话的指令

加载机制上有三点事实:

  • OpenClaw 在会话启动时把 USER.mdMEMORY.md 并列加载
  • 它有独立的、较小的 bootstrap 预算
  • 在长会话里,对该文件的编辑会在后续轮次被读取到;文件不存在时,启动流程继续,不报错。

写法上,每条目是一行元数据加一条祈使式指令

<!-- observed: 2026-07-27 | status: active -->

- Prefer concise progress updates during implementation work.

官方给出的规则是固定的五条:

规则具体要求
用祈使句开头Always / Never / Prefer 这类词开头
记录观察日期observed: 后面那个日期
状态只有两个取值只用 activesuperseded
一条指令一个行为不要把多个行为塞进一条
只存能改善协助质量的内容别把它写成个人档案

文档为”为什么要写成指令”给了一个依据:PrefEval 的研究发现,对话越长,模型遵循偏好的能力下降越明显,即便配了检索和提示也一样(官方引用的编号是 arXiv:2502.09597)。把稳定偏好复述成一条指令,等于在 agent 真正用到它的位置上,把期望行为写明白。

偏好变了要”就地取代”,不要追加

这是 USER.md 最容易写错的地方。官方要求:偏好发生变化时,更新它原有的那一节,不要在文件别处再追加一条新的 active 指令。

修改前:

<!-- observed: 2026-05-10 | status: active -->

- Prefer detailed explanations for every code change.

修改后:

<!-- observed: 2026-05-10 | status: superseded -->

- Prefer detailed explanations for every code change.

<!-- observed: 2026-07-27 | status: active -->

- Prefer concise implementation summaries unless more detail is requested.

注意旧条目没有被删掉,而是标成 superseded紧挨着新条目放。这样”当前生效的是哪一条”没有歧义。

文档同样给了依据:HorizonBench 的报告指出,系统经常在用户已经改变偏好之后,仍然选中最初表述的那一条(官方引用的编号是 arXiv:2604.17283)。只追加、不标记取代的写法,等于亲手重建这个失败模式。

一件事该写进哪个文件

USER.mdMEMORY.md 的分工是新手最常混淆的。官方文档直接给了一张对照表,照抄如下:

信息类型存到哪里
稳定的偏好或沟通风格USER.md
会改变”该如何协助此人”的人际关系或当前项目事实USER.md
持久的非个人事实、决策或经验教训MEMORY.md
详细观察或运行中的上下文memory/YYYY-MM-DD.md(日期文件)
由事件触发的未来动作常驻意图(standing intents)
精确时点或周期性动作定时任务(scheduled task)

一个可操作的判断办法:先问”这条信息是关于这个人的,还是关于这件事的”。关于人的(偏好、风格、关系、在做什么项目)进 USER.md;关于事的(结论、教训、决策)进 MEMORY.md;只是过程记录的进日期文件。至于整套记忆分层是怎么组织的,见记忆架构:内置、搜索与外接

为什么必须让 USER.md 保持紧凑

前面提到 USER.md 有”刻意更小”的 bootstrap 预算——这不是随口一提的实现细节,而是直接影响你能往里写多少东西。

文档给的清理办法有两条:

  1. 删掉过时的 superseded 条目。取代记录的作用是让”当前生效哪条”不含糊,一旦新指令稳定下来、不再有歧义,旧的就该清掉,而不是无限累积;
  2. 把不影响行为的项目细节挪走,移到日常记忆或 MEMORY.md 里。

判断标准就是”是否改变 agent 的行为”。“这个项目用 TypeScript”如果不改变它该怎么回你,那它属于 MEMORY.md,不属于 USER.md

什么时候不适用,以及哪些问题官方没解决

把上面的事实合起来,可以划出这套机制的适用边界:

不适用的场景:

  • 需要真正隔离的团队。只要必须做到”A 不能读 B 的会话、工具、凭据、文件”,多用户模式就是错误的工具,官方给的答案是拆成独立 agent 或独立网关 / 宿主机。
  • 需要精确责任追溯的场景。轮次归属是尽力而为,插话会把多人输入合并进同一轮,转录不能当作逐人可分的记录来用。
  • 需要”对管理员也保密”的草稿。管理员始终能看到别人的草稿,只是带淡化标记。

官方文档没有说明的部分:

  • 支持多少人同时在场、会话列表加载多少条才触发归属 UI 的显示阈值(只写了”少于两个不同创建者时隐藏”,没给列表规模),官方文档未说明;
  • USER.md 的 bootstrap 预算具体是多少 token 或多少字节,只写了”比一般工作区文件更小”,没给数值;
  • 无归属会话事后能否补上归属,文档只说”创建时无法证明触发者的会话保持未归属”,没有提供补录路径。

如果你现在正要给团队上共享网关,最实际的动作顺序是:先判断有没有硬隔离需求——有就直接拆 agent,别在共享网关上做文章;没有,再把多用户模式当成”看得清谁在干什么”的协作层来用,同时给每个人的 agent 工作区建一份克制的 USER.md,从三五条指令起步,变了就就地取代。

延伸阅读


本文依据 OpenClaw 官方仓库(github.com/openclaw/openclawdocs/ 下的官方文档整理,核对日 2026-08-17。 我们没有安装或运行过 OpenClaw,因此不涉及界面外观、操作手感与实测耗时的任何描述; 文中的默认值、命令与配置项均为文档口径,不构成对实际运行结果的保证。 该项目迭代很快,请以仓库最新内容为准。接入即时通讯平台前,请自行确认所在平台的规则与合规要求。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。