Skip to main content

作用域与命名空间

作用域不是记忆对象上的附属标签,而是整个系统的第一隔离机制。只要 Scope 设计不清楚,后续的读取策略、覆盖优先级和权限边界都会变得含糊。

Scope 层级

羽忆采用由粗到细的层级式 Scope:

global
-> tenant
-> team
-> user
-> project
-> agent
-> session

第一阶段真正主打的是 userprojectagentsession 这几层;tenantteam 主要是对象模型上的预留,为后续协作和商业化场景保留扩展空间。

各层级适合存什么

层级典型内容
user个人偏好、长期习惯、通用约束
project项目约定、技术决策、项目目标
agent某个宿主下的特定使用偏好
session当前会话的临时决定或阶段上下文

系统之所以强调“优先写入最小且最精确的 Scope”,是为了防止过宽的记忆污染后续召回。例如某个只属于单项目的约定,如果被写成 user 级,就会在其他项目里产生误导。

Namespace 的存储表达

在存储层里,Scope 最终会被展开成命名空间字段组合,例如:

{
"tenant_id": "t_default",
"user_id": "u_001",
"team_id": "team_dev",
"project_id": "p_demo",
"agent_id": "antigravity",
"session_id": "s_456"
}

这里最重要的约束是:Scope 的解析和权限判断必须由服务端负责。Adapter 只负责透传身份和上下文,不负责做最终的作用域仲裁,否则不同接入层很快就会出现行为漂移。

默认读取策略

对任务召回来说,默认范围通常是:

user + current_project + recent_session

这样设计是因为:

  • user 层承载长期个人偏好
  • project 层承载当前项目最关键的约定与决策
  • session 层承载最近一次工作连续性的材料

如果默认把更宽范围都打开,召回结果很快会被噪声淹没。

写入推断规则

当调用方没有显式给出完整 Scope 时,服务端通常按以下顺序推断:

  1. 请求里包含 project_id,优先写入 project
  2. 内容明显属于长期个人偏好,写入 user
  3. 内容明显是特定 Agent 行为偏好,写入 agent
  4. 无法可靠判断时,先落到 user,并提示调用方确认

这个推断顺序不是为了偷懒,而是为了避免把模糊信息直接放到过宽或过深的层级里。

同一语义跨 Scope 的优先级

当不同 Scope 中出现语义相似或 semantic_key 相同的内容时,默认优先级为:

session > project > agent > user > team > tenant > global

原则非常简单:越贴近当前上下文的 Scope,越优先。

具体仲裁时还要叠加以下规则:

  • active 永远优先于 archivedinvalid
  • 同一 Scope 内优先 version 更高的内容
  • version 相同时再比较 importance
  • 再相同时才比较最近更新时间

Scope 与权限的关系

Scope 同时也是权限边界。第一阶段至少要保证:

  • 用户默认只能读取自己的 user 级内容
  • project 级内容要经过项目归属校验
  • 不允许跨用户、跨租户直接读取
  • global 级内容只读范围可以更广,但写权限必须极少

如果 Scope 只被当成检索过滤条件,而没有真正参与权限判断,系统在安全上就是不完整的。