# 🔴 自适应模式（Adaptive Mode）深度解析

> Nexus 框架的核心创新 — 让 Agent 团队像人类团队一样自组织

---

## 目录

- [为什么需要自适应模式](#为什么需要自适应模式)
- [核心思想：Contract Net 协议](#核心思想contract-net-协议)
- [三大核心机制](#三大核心机制)
  - [1. 能力向量（Capability Vector）](#1-能力向量capability-vector)
  - [2. 余弦相似度匹配](#2-余弦相似度匹配)
  - [3. ELO 评分系统](#3-elo-评分系统)
- [完整工作流程](#完整工作流程)
- [与其他模式的对比](#与其他模式的对比)
- [自适应模式的价值](#自适应模式的价值)
- [代码示例](#代码示例)
- [技术细节](#技术细节)
- [适用场景 vs 不适用场景](#适用场景-vs-不适用场景)
- [未来演进方向](#未来演进方向)

---

## 为什么需要自适应模式

### 现有框架的编排困境

现有多智能体框架的编排方式可以归为两类：

| 方式 | 代表 | 问题 |
|------|------|------|
| **静态编排** | LangGraph, CrewAI | 开发者必须在编码时就知道"谁该做什么"，任务分配被硬编码 |
| **简单路由** | Swarm, AutoGen | 由 LLM 决定下一步交给谁，但没有记忆，每次都从零判断 |

这两种方式在实际生产环境中都有明显短板：

1. **静态编排**在任务类型变化时需要重写流程
2. **简单路由**缺乏对 Agent 历史表现的感知，同样的错误会反复发生
3. **两者都不具备自我优化能力**——系统不会随使用变得更好

### 真实世界的类比

想象一个软件公司：

- **静态编排** = 把所有需求写成流水线 SOP。来了新类型的需求？改 SOP。
- **简单路由** = 每次来需求都问一遍 "谁去做？"，不看谁做得好，不看谁更擅长。
- **自适应模式** = 项目经理知道每个人的能力画像、历史绩效，自动把任务分配给最合适的人，而且越用越准。

这就是 Nexus 自适应模式要做的事。

---

## 核心思想：Contract Net 协议

自适应模式的灵感来源于 1980 年代 Smith 提出的 **Contract Net Protocol (CNP)**——一种经典的多智能体任务分配协议：

```
任务宣布 → Agent 投标 → 评估投标 → 分配任务 → 执行 → 反馈
```

Nexus 在 CNP 的基础上做了现代化改造：

| CNP 原始概念 | Nexus 实现 |
|-------------|-----------|
| Agent 自己投标 | 系统根据能力向量自动计算匹配度 |
| 人工评估投标 | 余弦相似度 + ELO 评分加权排序 |
| 一次性分配 | 支持多轮重规划（re-planning） |
| 无反馈 | 执行结果自动更新 Agent 评分 |

---

## 三大核心机制

### 1. 能力向量（Capability Vector）

每个 Agent 在创建时声明自己的能力，这些能力被建模为一个 **8 维浮点向量**：

```python
class AgentCapability(BaseModel):
    coding: float        # 编码能力         [0.0 - 1.0]
    reasoning: float     # 推理能力         [0.0 - 1.0]
    writing: float       # 写作能力         [0.0 - 1.0]
    research: float      # 研究/搜索能力     [0.0 - 1.0]
    data_analysis: float # 数据分析能力      [0.0 - 1.0]
    math: float          # 数学能力         [0.0 - 1.0]
    creativity: float    # 创造力           [0.0 - 1.0]
    communication: float # 沟通/表达能力     [0.0 - 1.0]
    
    custom: dict[str, float]  # 可扩展的自定义维度
```

#### 为什么用向量而不是标签？

传统框架通常用标签来描述能力（如 `skills=["coding", "python"]`），这有几个问题：

- **标签是布尔的**：一个 Agent 要么有 "coding" 标签，要么没有。但现实中能力有强弱之分。
- **标签不可计算**：你无法对两组标签做"相似度计算"。
- **标签粒度固定**：无法表达 "擅长编码但也能写点文档"。

而向量可以：

```python
# 全栈型 Agent — 什么都会，但不精
generalist = AgentCapability(coding=0.5, writing=0.5, reasoning=0.5)

# 纯代码型 Agent — 编码极强，其余一般
coder = AgentCapability(coding=1.0, reasoning=0.7, writing=0.2)

# 创意型 Agent — 写作和创意拉满
creative = AgentCapability(writing=0.9, creativity=1.0, communication=0.8)
```

#### 可扩展性

8 个内建维度不够用？用 `custom` 字段扩展：

```python
domain_expert = AgentCapability(
    reasoning=0.9,
    custom={
        "medical_knowledge": 0.95,
        "legal_compliance": 0.8,
    }
)
```

`custom` 字段的值会被追加到向量末尾（按 key 排序），保证确定性。

---

### 2. 余弦相似度匹配

当一个任务进入系统，它也可以带有能力需求向量：

```python
task = Task(
    name="实现快排算法",
    required_capabilities=AgentCapability(coding=0.9, reasoning=0.7),
)
```

系统通过 **余弦相似度** 来衡量任务需求与 Agent 能力之间的匹配程度：

$$
\text{similarity}(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{|\mathbf{a}| \cdot |\mathbf{b}|}
$$

其中 $\mathbf{a}$ 是 Agent 的能力向量，$\mathbf{b}$ 是任务的需求向量。

#### 为什么选择余弦相似度？

- **方向敏感**：关注的是 "能力分布的形状"，而非绝对值。一个 `(0.5, 0.5)` 的 Agent 与 `(1.0, 1.0)` 的需求完美匹配（都均衡），相似度为 1.0。
- **尺度无关**：Agent 声明 `coding=0.8` 和 `coding=0.4` 的比例关系比绝对值更重要。
- **计算高效**：纯浮点运算，无需 LLM 调用。
- **可解释**：返回 0.0~1.0 的分数，直观易懂。

#### 匹配示例

```
任务需求: coding=0.9, reasoning=0.7

Agent A (coder):    coding=1.0, reasoning=0.8 → 相似度 = 0.99 ✅ 最佳
Agent B (writer):   writing=0.9, creativity=1.0 → 相似度 = 0.00 ❌ 不匹配
Agent C (全能):     coding=0.5, reasoning=0.5, writing=0.5 → 相似度 = 0.87 🟡 可以
```

---

### 3. ELO 评分系统

这是让系统 **越用越准** 的关键机制。

#### 灵感来源

ELO 评分最初是国际象棋的等级分系统。Nexus 将其改造用于 Agent 绩效追踪：

- 每个 Agent 初始评分 **1000 分**
- 完成任务后，根据任务质量上调或下调
- 任务失败直接扣 16 分
- 评分影响未来任务分配的优先级

#### 评分更新公式

$$
R_{new} = R_{old} + K \times (S - E)
$$

其中：

- $R$ = Agent 评分
- $K = 32$（敏感度系数，同国际象棋）
- $S$ = 实际任务质量分数（0.0 ~ 1.0）
- $E$ = 期望表现 = $\frac{1}{1 + 10^{(1000 - R_{old}) / 400}}$

#### 效果说明

| 场景 | 评分变化 |
|------|---------|
| 新 Agent (1000分) 完成高质量任务 (0.9) | +12.8 → 1012.8 |
| 新 Agent (1000分) 完成低质量任务 (0.3) | -6.4 → 993.6 |
| 高评分 Agent (1200分) 完成高质量任务 | +5.8 → 1205.8（高位增长慢） |
| 任意 Agent 任务失败 | -16（硬惩罚） |

这意味着：

- **新 Agent** 评分波动大，系统快速学习它的水平
- **老 Agent** 评分趋于稳定，偶尔失误不会大幅影响
- **持续表现差的 Agent** 评分持续走低，自然被淘汰出匹配池

#### 评分在匹配中的权重

最终匹配分数 = **60% 能力相似度 + 40% 历史绩效**

```python
combined_score = 0.6 * cosine_similarity + 0.4 * (elo_rating / 2000.0)
```

这个 6:4 的比例是经过权衡的：

- **能力匹配** 权重更高，保证方向正确（不会把写作任务分给纯码农）
- **历史绩效** 作为修正因子，在能力相近的 Agent 之间做区分

---

## 完整工作流程

```
                          ┌─────────────────────────────┐
                          │     任务进入系统              │
                          └─────────┬───────────────────┘
                                    │
                          ┌─────────▼───────────────────┐
                          │  Phase 1: 规划 (Plan)        │
                          │                              │
                          │  对每个任务:                   │
                          │  1. 提取能力需求向量            │
                          │  2. 遍历 Agent 池              │
                          │  3. 计算余弦相似度              │
                          │  4. 加权历史 ELO 评分           │
                          │  5. 负载均衡惩罚               │
                          │  6. 约束检查 (预算/时间/工具)    │
                          │  7. 排序，选 Top 1             │
                          └─────────┬───────────────────┘
                                    │
                          ┌─────────▼───────────────────┐
                          │  Phase 2: 执行 (Execute)      │
                          │                              │
                          │  - 按 DAG 拓扑序执行           │
                          │  - 同层任务并行执行             │
                          │  - 注入上游依赖结果             │
                          │  - 捕获质量分数和耗时           │
                          └─────────┬───────────────────┘
                                    │
                          ┌─────────▼───────────────────┐
                          │  Phase 3: 反馈 (Feedback)     │
                          │                              │
                          │  - 记录 QualityRecord         │
                          │  - 更新 Agent ELO 评分         │
                          │  - 更新平均质量/延迟/成本       │
                          └─────────┬───────────────────┘
                                    │
                          ┌─────────▼───────────────────┐
                          │  Phase 4: 重规划? (Re-plan?)   │
                          │                              │
                          │  检查:                        │
                          │  - 有任务失败? → 重试           │
                          │  - 质量低于阈值? → 换 Agent 重做│
                          │  - 最多重规划 3 轮              │
                          └─────────┬───────────────────┘
                                    │
                          ┌─────────▼───────────────────┐
                          │     返回最终结果               │
                          └─────────────────────────────┘
```

### 关键细节

#### 负载均衡

当一轮规划中多个任务需要分配，系统会对已经分配了任务的 Agent 施加负载惩罚：

```python
load_penalty = current_task_count * 0.1  # 每多一个任务，分数 -0.1
final_score = base_score - load_penalty
```

这避免了最优 Agent 被所有任务挤爆。

#### 重规划机制

自适应模式最多进行 `max_replanning_rounds`（默认 3）轮重规划。重规划触发条件：

1. **任务失败** 且 重试次数未耗尽 → 重置任务状态，重新分配（可能换一个 Agent）
2. **任务质量低于阈值**（默认 0.6）且可重试 → 同上

因为失败的 Agent 的 ELO 评分已经被下调，所以重规划时系统自然会倾向于选择不同的 Agent——**这是自修复的关键**。

---

## 与其他模式的对比

| 维度 | 🔷 图模式 (Graph) | 🔶 路由模式 (Router) | 🔴 自适应模式 (Adaptive) |
|------|------------------|---------------------|------------------------|
| **拓扑** | 编码时确定 | 运行时 LLM 决策 | 运行时算法匹配 |
| **决策成本** | 零（预定义） | 高（每步一次 LLM 调用） | 低（纯数学计算） |
| **自我优化** | ❌ | ❌ | ✅ ELO 反馈循环 |
| **处理失败** | 需手写 fallback | 依赖 LLM 判断 | 自动重规划+换 Agent |
| **并行执行** | DAG 同层并行 | 单步执行 | DAG 同层并行 |
| **适用团队规模** | 2-5 Agent | 2-10 Agent | 5-50+ Agent |
| **学习曲线** | 中（要理解 DAG） | 低（写 prompt 即可）| 低（声明能力即可） |
| **可预测性** | 高 | 低 | 中 |

---

## 自适应模式的价值

### 1. 🧠 越用越聪明

这是与其他所有框架的最大差异。

传统框架每次执行都是"无记忆"的——上一次 Agent A 做砸了这个任务，下一次来了同类任务，系统还是可能把它分给 Agent A。

自适应模式通过 ELO 评分闭环，让系统 **持续学习**：

```
执行 → 打分 → 更新评分 → 影响下一次分配 → 执行 → ...
```

随着使用时间增长，系统会越来越准确地知道：
- 哪个 Agent 擅长写代码
- 哪个 Agent 擅长做研究
- 哪个 Agent 在高压下（高并发）依然稳定

### 2. 💰 零额外 LLM 成本

路由模式需要一次 LLM 调用来决定 "谁来做这个任务"。如果一个工作流有 10 步，就需要 10 次额外的路由调用。

自适应模式的匹配完全基于 **余弦相似度 + ELO 算术运算**，不消耗任何 Token。

| 10 步工作流 | Router 模式 | Adaptive 模式 |
|------------|------------|--------------|
| 路由决策成本 | ~10,000 tokens | **0 tokens** |
| 路由延迟 | ~5-10 秒 | **< 1 毫秒** |

在大规模系统（数十个 Agent、数百个任务）中，这个差异被急剧放大。

### 3. 🔄 自动容错与自愈

传统框架处理失败的方式：
- 抛异常，让开发者自己 catch
- 或者简单重试同一个 Agent

自适应模式的处理：
1. Agent A 执行失败
2. Agent A 的 ELO 评分下降 16 分
3. 系统触发重规划
4. 重规划时，Agent A 的分数更低了，系统自然选择 Agent B
5. Agent B 执行成功
6. Agent B 的 ELO 评分上升

**失败不需要人工干预，系统自动"学会"避开不靠谱的 Agent。**

### 4. 📐 规模无关性

静态图模式在 Agent 数量增长时变得难以维护——你需要手动更新每一条边和路由逻辑。

自适应模式的复杂度与 Agent 数量解耦：
- 加一个新 Agent？声明它的能力向量，注册到池里就行
- 系统自动把合适的任务匹配给它
- 无需修改任何流程代码

```python
# 添加新 Agent 只需一行
orchestrator.add_agent(Agent(
    name="legal-reviewer",
    capabilities=AgentCapability(reasoning=0.9, communication=0.8, custom={"legal": 0.95}),
))
# 下一个法律相关任务会自动匹配到它，无需改任何代码
```

### 5. 🔍 可观测 & 可解释

每一次任务分配都有明确的 `match_score` 和 `reason`，可以被追踪和审计：

```python
plan = orchestrator.plan(task_graph)
for assignment in plan.assignments:
    print(f"Task {assignment.task_id} → Agent {assignment.agent_id}")
    print(f"  匹配分数: {assignment.match_score:.3f}")
    print(f"  原因: {assignment.reason}")
```

整个 Agent 池可以通过排行榜查看：

```python
for score in discovery.get_leaderboard():
    print(f"{score.agent_id}: rating={score.rating:.0f}, "
          f"completed={score.tasks_completed}, "
          f"avg_quality={score.avg_quality:.2f}")
```

这让调试和优化变得透明——你能清楚看到 **为什么** 系统做了这个分配决策。

### 6. 🌐 与协议层的协同效应

自适应模式与 Nexus 的协议层（A2A + MCP）结合后，价值进一步放大：

- **A2A 发现远程 Agent** → 注册到 DiscoveryService → 自动参与匹配
- 远程 Agent 和本地 Agent 在同一个能力空间中被统一排名
- 一个跨组织的 Agent 团队可以完全自组织——不需要知道谁在哪里，只需要知道谁擅长什么

```python
# 发现远程 Agent 并自动纳入匹配池
await discovery.discover_remote("https://partner-company.com/agents/legal-ai")
# 从此，法律相关任务可能被路由到这个远程 Agent
```

---

## 代码示例

### 基础用法

```python
from nexus import Team
from nexus.types import AgentCapability

async with Team(model="gpt-4o") as team:
    # 定义 Agent 的能力画像
    team.add_agent(
        "researcher",
        instructions="你是一个研究专家，擅长信息收集和分析",
        capabilities=AgentCapability(research=1.0, reasoning=0.8, data_analysis=0.7),
    )
    team.add_agent(
        "coder",
        instructions="你是一个编程专家，擅长 Python 和系统设计",
        capabilities=AgentCapability(coding=1.0, reasoning=0.9, math=0.6),
    )
    team.add_agent(
        "writer",
        instructions="你是一个技术写手，擅长将复杂概念转化为清晰文档",
        capabilities=AgentCapability(writing=1.0, communication=0.9, creativity=0.7),
    )

    # 自适应模式自动匹配
    await team.run("调研 Rust 的内存安全机制")    # → researcher
    await team.run("用 Python 实现一个 LRU 缓存")  # → coder
    await team.run("写一篇关于微服务的技术博客")     # → writer
```

### 高级用法 — 直接使用 AdaptiveOrchestrator

```python
from nexus.orchestration.adaptive import AdaptiveOrchestrator
from nexus.core.task import Task, TaskGraph
from nexus.core.agent import Agent
from nexus.types import AgentCapability

# 创建 Agent 池
researcher = Agent(name="researcher", capabilities=AgentCapability(research=1.0))
coder = Agent(name="coder", capabilities=AgentCapability(coding=1.0))
writer = Agent(name="writer", capabilities=AgentCapability(writing=1.0))

# 初始化自适应编排器
orchestrator = AdaptiveOrchestrator(
    quality_threshold=0.7,        # 质量低于 0.7 的任务会被重做
    max_replanning_rounds=3,      # 最多重规划 3 轮
)
orchestrator.add_agent(researcher)
orchestrator.add_agent(coder)
orchestrator.add_agent(writer)

# 构建任务图（支持 DAG 依赖）
graph = TaskGraph()
t1 = Task(name="调研竞品", required_capabilities=AgentCapability(research=0.8))
t2 = Task(name="编写核心逻辑", depends_on=[t1.id], required_capabilities=AgentCapability(coding=0.9))
t3 = Task(name="撰写文档", depends_on=[t2.id], required_capabilities=AgentCapability(writing=0.8))
graph.add_task(t1)
graph.add_task(t2)
graph.add_task(t3)

# 一键执行：自动规划 → 并行执行 → 反馈 → 必要时重规划
results = await orchestrator.run(graph)

# 查看分配方案
plan = orchestrator.plan(graph)
for a in plan.assignments:
    print(f"{a.task_id} → {a.agent_id} (score: {a.match_score:.3f})")

# 查看 Agent 排行榜
for s in orchestrator.discovery.get_leaderboard():
    print(f"{s.agent_id}: ELO={s.rating:.0f}, 完成={s.tasks_completed}")
```

---

## 技术细节

### 匹配分数计算公式

$$
\text{score}_{final} = 0.6 \times \cos(\mathbf{c}_{agent}, \mathbf{c}_{task}) + 0.4 \times \frac{R_{ELO}}{2000} - 0.1 \times N_{load}
$$

其中：
- $\cos(\mathbf{c}_{agent}, \mathbf{c}_{task})$ = 能力向量余弦相似度
- $R_{ELO}$ = Agent 当前 ELO 评分
- $N_{load}$ = 当前轮已分配给该 Agent 的任务数

### ELO 评分更新公式

$$
R_{new} = R_{old} + 32 \times (S_{actual} - E_{expected})
$$

$$
E_{expected} = \frac{1}{1 + 10^{(1000 - R_{old}) / 400}}
$$

### 算法复杂度

| 操作 | 时间复杂度 |
|------|-----------|
| 单任务匹配 | $O(N)$，N = Agent 数量 |
| 完整规划（M 个任务） | $O(M \times N \times \log N)$ |
| ELO 更新 | $O(1)$ |
| 余弦相似度 | $O(D)$，D = 向量维度（默认 8） |

对于 50 个 Agent + 100 个任务的规模，规划时间 < 1ms。

### 贪心算法 vs 最优解

当前实现使用 **贪心算法**（按任务优先级逐个分配最优 Agent）。这在绝大多数场景下效果良好，但不保证全局最优。

未来可以引入：
- **匈牙利算法** — 当任务数 = Agent 数时，找到全局最优分配
- **约束满足求解器（CSP）** — 当约束条件复杂时（预算、时间、工具依赖）
- **强化学习** — 通过历史数据学习最优分配策略

---

## 适用场景 vs 不适用场景

### ✅ 非常适合

- **Agent 数量 ≥ 5 的团队** — Agent 越多，手动编排越痛苦，自适应优势越明显
- **任务类型多变** — 不知道下一个任务是什么类型，让系统自动匹配
- **长期运行的系统** — ELO 评分需要时间积累，运行越久越准
- **需要容错的生产环境** — 自动重规划比手动 try/catch 更健壮
- **多模型混用** — 不同 Agent 用不同模型（GPT-4o 做推理，Claude 做写作，Ollama 做简单任务），系统自动学习谁配什么模型最好

### ⚠️ 不太适合

- **流程固定的简单管线** — 只有 2-3 个固定步骤，用图模式更直观
- **需要 100% 确定性的场景** — 同样的输入不一定每次路由到同一个 Agent（虽然趋势一致）
- **Agent 池只有 1-2 个** — 匹配没有太大意义，直接指定就好

---

## 未来演进方向

| 方向 | 描述 | 状态 |
|------|------|------|
| 🔬 匈牙利算法 | 全局最优分配 | 规划中 |
| 🧬 能力向量自动推断 | 根据执行历史自动调整 Agent 的能力声明 | 规划中 |
| 📈 时序评分衰减 | 近期表现权重更高（避免"吃老本"） | 规划中 |
| 🌍 跨集群分配 | 结合 A2A 协议，跨组织的 Agent 池联邦匹配 | 远期 |
| 🤖 元学习 | 用 RL 训练一个分配策略网络替代贪心算法 | 远期 |

---

> **自适应模式的本质：把多智能体编排从"人工编程"变成"系统自学习"。**
>
> 你声明每个 Agent 擅长什么，声明每个任务需要什么，然后让 Nexus 自己去想办法。
> 而且它会越来越擅长想办法。
