# Scope 设计文档

## 概述

Scope 系统用于控制知识的可见性和访问权限。采用**灵活的标签系统**，而非固定的层级结构。

## 核心原则

1. **知识类型与可见性分离**
   - `type` 字段表示知识类型（What）
   - `scopes` 字段表示可见范围（Who）

2. **多 Scope 支持**
   - 一条知识可以有多个 scope 标签
   - 支持灵活的共享关系

3. **明确的所有权**
   - `owner` 字段表示唯一所有者
   - 只有所有者有权修改/删除

## Scope 格式

```
格式：{entity_type}:{entity_id}

示例：
- user:123
- agent:general_assistant
- project:456
- team:frontend
- org:company
- public
```

## Scope 类型

| Scope 类型 | 格式 | 说明 | 示例 |
|-----------|------|------|------|
| 用户级 | `user:{user_id}` | 用户个人可见 | `user:123` |
| Agent 级 | `agent:{agent_id}` | 特定 Agent 可见 | `agent:crawler_ops` |
| 项目级 | `project:{project_id}` | 项目组可见 | `project:456` |
| 团队级 | `team:{team_id}` | 部门可见 | `team:frontend` |
| 组织级 | `org:{org_id}` | 全公司可见 | `org:company` |
| 公开 | `public` | 所有人可见 | `public` |

## 数据结构

```json
{
  "id": "knowledge_001",

  "type": "user_profile",

  "scopes": [
    "user:123",
    "project:456"
  ],

  "owner": "user:123",

  "visibility": "shared",

  "content": "...",
  "tags": {...},
  "source": {...},
  "eval": {...}
}
```

## 字段说明

### type（知识类型）

- `user_profile`：用户画像
- `strategy`：执行经验
- `tool`：工具知识
- `usecase`：用例
- `definition`：概念定义
- `plan`：方法论

### scopes（可见范围）

- 数组类型，可包含多个 scope
- 知识对所有 scopes 中的实体可见
- 检索时匹配：知识的 scopes 与用户的 visible_scopes 有交集

### owner（所有者）

- 字符串类型，格式同 scope
- 唯一所有者，有权修改/删除
- 通常是创建者

### visibility（可见性级别）

快速过滤标签，用于 UI 展示和简单查询：

- `private`：私有（仅所有者）
- `shared`：共享（多个实体）
- `org`：组织级
- `public`：公开

## 使用场景

### 场景 1：用户的私有偏好

```json
{
  "type": "user_profile",
  "scopes": ["user:123"],
  "owner": "user:123",
  "visibility": "private",
  "content": "用户偏好使用 TypeScript"
}
```

### 场景 2：项目组共享的经验

```json
{
  "type": "strategy",
  "scopes": ["project:456"],
  "owner": "agent:crawler_ops",
  "visibility": "shared",
  "content": "爬虫反爬策略：使用代理池 + 随机 UA"
}
```

### 场景 3：跨项目的用户偏好

```json
{
  "type": "user_profile",
  "scopes": ["user:123", "project:456", "project:789"],
  "owner": "user:123",
  "visibility": "shared",
  "content": "用户在多个项目中都偏好使用 React"
}
```

### 场景 4：Agent 间共享的工具知识

```json
{
  "type": "tool",
  "scopes": [
    "agent:crawler_ops",
    "agent:content_library",
    "agent:general_assistant"
  ],
  "owner": "agent:crawler_ops",
  "visibility": "shared",
  "content": "Selenium 使用技巧：headless 模式配置"
}
```

### 场景 5：组织级公开知识

```json
{
  "type": "definition",
  "scopes": ["org:company"],
  "owner": "org:company",
  "visibility": "org",
  "content": "公司技术栈：React + TypeScript + Node.js"
}
```

### 场景 6：完全公开的知识

```json
{
  "type": "tool",
  "scopes": ["public"],
  "owner": "org:company",
  "visibility": "public",
  "content": "Git 常用命令速查表"
}
```

## 检索逻辑

### 构建可见范围

```python
def build_visible_scopes(context):
    """
    根据执行上下文构建用户的所有可见 scopes

    context = {
        "user_id": "123",
        "agent_id": "general_assistant",
        "project_id": "456",
        "team_id": "frontend",
        "org_id": "company"
    }
    """
    scopes = []

    if context.get("user_id"):
        scopes.append(f"user:{context['user_id']}")

    if context.get("agent_id"):
        scopes.append(f"agent:{context['agent_id']}")

    if context.get("project_id"):
        scopes.append(f"project:{context['project_id']}")

    if context.get("team_id"):
        scopes.append(f"team:{context['team_id']}")

    if context.get("org_id"):
        scopes.append(f"org:{context['org_id']}")

    scopes.append("public")

    return scopes
```

### 检索查询

```python
def search_knowledge(query, context, knowledge_type=None):
    """
    检索知识

    query: 查询内容
    context: 用户上下文
    knowledge_type: 可选，过滤知识类型
    """
    # 1. 构建可见范围
    visible_scopes = build_visible_scopes(context)

    # 2. 构建查询条件
    filters = {
        "scopes": {"$in": visible_scopes}  # 交集匹配
    }

    if knowledge_type:
        filters["type"] = knowledge_type

    # 3. 向量检索 + 过滤
    results = vector_db.search(
        query=query,
        filter=filters,
        top_k=10
    )

    # 4. 按优先级排序
    return rank_by_scope_priority(results, context)
```

### 优先级排序

```python
def rank_by_scope_priority(results, context):
    """
    按 scope 优先级排序

    优先级：user > project > agent > team > org > public
    """
    priority_map = {
        f"user:{context.get('user_id')}": 6,
        f"project:{context.get('project_id')}": 5,
        f"agent:{context.get('agent_id')}": 4,
        f"team:{context.get('team_id')}": 3,
        f"org:{context.get('org_id')}": 2,
        "public": 1
    }

    def get_priority(knowledge):
        # 取知识的 scopes 中优先级最高的
        max_priority = 0
        for scope in knowledge["scopes"]:
            max_priority = max(max_priority, priority_map.get(scope, 0))
        return max_priority

    return sorted(results, key=get_priority, reverse=True)
```

## 权限控制

### 读权限

用户可以读取知识，当且仅当：
- 知识的 `scopes` 与用户的 `visible_scopes` 有交集

### 写权限

用户可以修改/删除知识，当且仅当：
- 用户是知识的 `owner`

### 特殊情况

- 管理员可以修改/删除所有知识
- 组织级知识（owner=org:xxx）可以由管理员管理

## 实现位置

- `agent/tools/builtin/knowledge.py`：知识管理工具（KnowHub API 封装）+ KnowledgeConfig

## 扩展性

### 新增 Scope 类型

如需新增 scope 类型（如 `department:{dept_id}`），只需：

1. 在 `build_visible_scopes` 中添加逻辑
2. 在 `rank_by_scope_priority` 中添加优先级
3. 无需修改数据结构和存储逻辑

### 升级为 ACL

如需更细粒度的权限控制，可扩展为 ACL 系统：

```json
{
  "id": "knowledge_001",
  "type": "strategy",
  "owner": "user:123",
  "acl": [
    {"entity": "user:123", "permission": "read_write"},
    {"entity": "project:456", "permission": "read"},
    {"entity": "agent:general_assistant", "permission": "read"}
  ]
}
```

但对于大多数场景，当前的 scope 标签系统已经足够。

