VINO/WANG返回博客 ←

BLOG / POST

多智能体架构

多智能体的三种架构模式(监督者、点对点、层级化)、五层记忆系统设计,以及面向 Agent 的工具设计原则。

  • context-engineering
  • multi-agent

来源:Agent-Skills-for-Context-Engineering

模块1: 多智能体架构模式

核心概念

为什么需要多智能体架构?

单智能体的天花板:
[错误] 推理能力有限
[错误] 上下文管理受限
[错误] 工具协调复杂

随着任务复杂化:
- 上下文窗口被历史、文档、工具输出填满
- 性能下降: lost-in-middle、注意力稀缺、上下文污染

关键洞察:

子智能体存在的主要目的是隔离上下文,而不是拟人化角色分工!


[错误] 错误思维: 模拟组织角色 (像公司部门)
[正确] 正确思维: 分区上下文窗口

每个子代理在专注于其子任务的干净上下文中操作,
而不携带来自其他子任务的累积上下文。

Token经济学现实

生产数据显示:

架构 Token倍数 使用场景
单智能体聊天 1x 基线 简单查询
单智能体 + 工具 ~4x 基线 工具使用任务
多智能体系统 ~15x 基线 复杂研究/协调

研究发现 (BrowseComp评估):

三个因素解释95%的性能方差:

1. Token使用 (80%方差)
   → 更多tokens = 更好性能

2. 工具调用数量
   → 更多工具使用

3. 模型选择
   → 更好模型 > 加倍token

关键洞察:
升级到更好的模型 (Claude Sonnet 4.5, GPT-5.2思考模式)
通常比加倍token预算提供更大性能提升

→ 模型选择和多智能体架构是互补策略

并行化优势:

单智能体: 顺序执行
任务A → 任务B → 任务C
总时间 = A + B + C

多智能体: 并行执行
[任务A] [任务B] [任务C]
总时间 = max(A, B, C)

加速 = 3倍 (3个任务)

实际案例:
研究任务需要搜索多个独立源、分析不同文档、比较方法
单智能体: 顺序处理, 上下文累积
多智能体: 同时工作, 协调者聚合结果

专业化优势:

不同任务受益于不同代理配置:
- 不同系统提示词
- 不同工具集
- 不同上下文结构

通用代理必须携带所有可能配置
→ 上下文臃肿

专业化代理仅携带所需
→ 精简上下文

三种架构模式

模式1: 监督者/编排器 (Supervisor/Orchestrator)

结构:

用户查询 → 监督者 → [专家, 专家, 专家] → 聚合 → 最终输出

监督者职责:

  • 维护全局状态和轨迹
  • 分解用户目标为子任务
  • 路由到合适的worker
  • 综合worker结果

优势:

[OK] 严格控制工作流
[OK] 易于实现人工在环干预
[OK] 确保遵循预定义计划
[OK] 清晰的责任分配

劣势:

[错误] 监督者上下文成为瓶颈
[错误] 监督者失败级联到所有worker
[错误] "电话游戏"问题

电话游戏问题及解决方案:

LangGraph基准发现监督者架构初期性能差50%, 原因是监督者错误转述子代理响应, 失去保真度。

解决方案: forward_message工具

def forward_message(message: str, to_user: bool = True):
    """
    将子代理响应直接转发给用户, 无需监督者综合。

    使用时机:
    - 子代理响应最终且完整
    - 监督者综合会丢失重要细节
    - 响应格式必须完全保留

    返回:
    - to_user=True: 直接响应用户
    - to_user=False: 输入监督者
    """
    if to_user:
        return {"type": "direct_response", "content": message}
    return {"type": "supervisor_input", "content": message}

效果:

无forward_message:
监督者性能 = 基准 - 50%

有forward_message:
群体架构略优于监督者
(子代理直接响应用户, 消除翻译错误)

何时使用监督者模式:

[OK] 有明确分解的复杂任务
[OK] 需要跨域协调的任务
[OK] 人工监督重要的任务
[OK] 需要严格工作流的任务

实现示例:

class SupervisorAgent:
    def __init__(self, workers):
        self.workers = workers
        self.state = {}

    def delegate(self, task):
        # 分解任务
        subtasks = self.decompose(task)

        # 路由到workers
        results = []
        for subtask in subtasks:
            worker = self.route(subtask)
            result = worker.execute(subtask)
            results.append(result)

        # 聚合结果
        return self.synthesize(results)

    def route(self, subtask):
        # 基于子任务类型选择worker
        if subtask.type == "research":
            return self.workers["researcher"]
        elif subtask.type == "analysis":
            return self.workers["analyzer"]
        # ...

模式2: 点对点/群体 (Peer-to-Peer/Swarm)

结构:

无中央控制
代理A ⇄ 代理B ⇄ 代理C
基于预定义协议直接通信

实现:

def transfer_to_agent_b():
    """通过函数返回值转移控制"""
    return agent_b

agent_a = Agent(
    name="Agent A",
    functions=[transfer_to_agent_b]
)

# Agent A可以在任何时候将控制转移给Agent B

优势:

[OK] 无单点故障
[OK] 有效扩展广度优先探索
[OK] 允许可emergent问题解决行为
[OK] 灵活的工作流

劣势:

[错误] 协调复杂度随代理数量增加
[错误] 无中央状态保持者时存在分歧风险
[错误] 需要健壮的收敛约束
[错误] 难以预测行为

何时使用点对点模式:

[OK] 需要灵活探索的任务
[OK] 刚性规划适得其反的任务
[OK] 有emergent需求的任务
[OK] 无法预先分解的任务

收敛约束:

# 防止无限循环和分歧
constraints = {
    "max_iterations": 10,
    "convergence_threshold": 0.95,
    "timeout": 300  # 秒
}

# TTL限制
agent.ttl = 100  # 100步后停止

模式3: 层级化 (Hierarchical)

结构:

战略层 (目标定义)

规划层 (任务分解)

执行层 (原子任务)

三层示例:

战略层:

CEO Agent
- 定义高层目标
- 设置约束
- 分配资源
- 监控进度

示例:
"进入新市场, 在6个月内达到100万用户"

规划层:

Manager Agents
- 分解目标为计划
- 协调资源
- 跟踪里程碑

示例:
"市场计划需要:
- 产品本地化
- 营销活动
- 销售渠道建立"

执行层:

Worker Agents
- 执行原子任务
- 报告状态
- 完成具体工作

示例:
"翻译UI文案为西班牙语"
"设置Facebook广告"
"联系分销商"

优势:

[OK] 镜像组织结构
[OK] 关注点清晰分离
[OK] 不同层级有不同上下文结构
[OK] 可扩展到大型项目

劣势:

[错误] 层间协调开销
[错误] 战略和执行可能错位
[错误] 复杂的错误传播
[错误] 信息可能失真

何时使用层级化:

[OK] 有清晰层级结构的大型项目
[OK] 有管理层的企业工作流
[OK] 需要高层规划和详细执行的任务
[OK] 复杂的多阶段项目

上下文隔离作为设计原则

为什么上下文隔离是主要目的:

多智能体系统通过分布解决单智能体上下文限制

每个代理在专注于其子任务的干净上下文中操作,
结果在协调层聚合,
没有任何单个上下文承担完整负担。

隔离机制:

1. 完整上下文委托 (Full Context Delegation)

用于: 复杂任务, 子代理需要完整理解

过程:
- 规划者共享其整个上下文
- 子代理有自己的工具和指令
- 但接收决策的完整上下文

权衡:
[OK] 最大能力
[错误] 违背子代理目的 (上下文仍大)

示例:
规划者: "分析这个5M token代码库的架构"
      → 将所有上下文传给架构分析代理

2. 指令传递 (Instruction Passing)

用于: 简单、明确定义的子任务

过程:
- 规划者通过函数调用创建指令
- 子代理仅接收其特定任务所需的指令

权衡:
[OK] 维持隔离
[错误] 限制子代理灵活性

示例:
规划者: "读取文件config.yaml, 返回端口配置"
      → 仅传递文件路径和查询

3. 文件系统记忆 (File System Memory)

用于: 需要共享状态的复杂任务

过程:
- 代理读写持久化存储
- 文件系统作为协调机制
- 避免共享状态传递的上下文膨胀

权衡:
[OK] 无上下文传递的共享状态
[错误] 引入延迟和一致性挑战

示例:
多个代理写入/shared/task_progress.json
其他代理读取获取状态

选择指南:

选择完整上下文委托:
- 子任务复杂, 需要全局理解
- 上下文大小不是问题

选择指令传递:
- 子任务简单、明确
- 需要严格隔离

选择文件系统记忆:
- 需要共享状态
- 异步操作可接受
- 上下文传递太昂贵

共识和协调

投票问题:

简单多数投票的问题:
- 将弱模型的幻觉视为与强模型推理相等
- 多智能体讨论因内在偏向一致
- 退化为对错误前提的共识

示例:
代理A (弱): 2+2=5
代理B (强): 2+2=4
代理C (弱): 2+2=5

多数投票: 5 (错误!)

解决方案:

1. 加权投票 (Weighted Voting)

def weighted_vote(agent_responses, weights):
    """
    按置信度或专业知识加权代理投票

    weights = {
        "expert_agent": 0.5,    # 高权重
        "general_agent": 0.3,   # 中权重
        "novice_agent": 0.2     # 低权重
    }
    """
    result = aggregate(responses, weights)
    return result

2. 辩论协议 (Debate Protocols)

def debate_protocol(topic, rounds=3):
    """
    要求代理在多轮中相互批评输出

    对抗性批评 > 协作共识 (复杂推理)
    """
    for round in range(rounds):
        # 代理提出论点
        arguments = [agent.propose(topic) for agent in agents]

        # 代理批评他人论点
        critiques = []
        for agent in agents:
            critique = agent.criticize(arguments)
            critiques.append(critique)

        # 代理根据批评修订
        for agent in agents:
            agent.revise(topic, critiques)

    return final_conclusion()

3. 基于触发的干预 (Trigger-Based Intervention)

triggers = {
    "stall": StallTrigger(),      # 讨论无进展
    "sycophancy": SycophancyTrigger()  # 代理互相模仿
}

def monitor_interaction(agents):
    """监控多智能体交互的行为标记"""

    # 停滞触发器
    if no_progress_detected(agents):
        activate_intervention("redirect")

    # 唯唯诺诺触发器
    if answers_too_similar(agents):
        activate_intervention("diversify")

失败模式和缓解

失败模式 描述 缓解策略
监督者瓶颈 监督者累积所有worker上下文, 容易饱和和退化 输出模式约束 (worker返回仅摘要)、检查点持久化状态
协调开销 代理通信消耗token和延迟, 复杂协调抵消并行化好处 清晰交接协议、批处理结果、异步通信模式
分歧 代理追求不同目标无中央协调, 偏离意图目标 明确目标边界、收敛检查、TTL限制
错误传播 一个代理的输出错误传播到消费该输出的下游代理 输出前验证、重试逻辑+熔断器、幂等操作

实现示例:

# 监督者瓶颈缓解
class Supervisor:
    def aggregate_results(self, worker_outputs):
        # 要求worker返回摘要而非完整输出
        schema = {
            "summary": str,
            "key_findings": List[str],
            "confidence": float
        }
        return validate_outputs(worker_outputs, schema)

# 协调开销缓解
def handoff(agent_a, agent_b, state):
    """清晰交接协议, 最小化通信"""
    # 仅传递必要状态
    minimal_state = {
        "task": state["task"],
        "progress": state["progress"]
    }
    return agent_b.receive(minimal_state)

# 分歧缓解
def convergence_check(agents, shared_goal):
    """验证朝共享目标的进展"""
    positions = [agent.get_position() for agent in agents]
    divergence = calculate_divergence(positions)
    if divergence > threshold:
        realign_agents(agents, shared_goal)

# 错误传播缓解
def validate_output(agent_output):
    """输出前验证"""
    if not is_valid(agent_output):
        raise ValidationError(agent_output)
    return agent_output

def retry_with_circuit_breaker(agent, task, max_retries=3):
    """重试逻辑+熔断器"""
    for attempt in range(max_retries):
        try:
            return agent.execute(task)
        except TemporaryError:
            continue
        except PermanentError:
            break  # 熔断
    raise CircuitBreakerError()

模块2: 记忆系统设计

核心概念

记忆谱系:

即时上下文 ← → 永久存储

工作内存 (上下文窗口)
├─ 零延迟访问
└─ 会话结束时消失

短期记忆 (会话持久)
├─ 可搜索
└─ 会话结束消失

长期记忆 (跨会话持久)
├─ 结构化
└─ 半永久

永久记忆 (归档)
├─ 可查询
└─ 永久

有效架构使用谱系上的多层。


为什么简单向量存储不足

向量RAG的问题:

向量RAG:
- 在共享嵌入空间嵌入查询和文档
- 相似性搜索检索最语义相似的文档
- 对文档检索工作良好
- 但缺乏代理记忆的结构

示例失败:
代理学习: "客户X在日期Z购买产品Y"

向量存储可以:
[OK] 检索这个事实 (如果直接询问)

但无法回答:
[错误] "购买产品Y的客户还买了什么产品?"

原因: 关系结构未保留
     → 图查询不可能, 仅相似性搜索

时间有效性问题:

事实随时间变化:
- 用户地址从A变到B
- 产品价格从$100变到$120
- 公司名称从"X"变为"Y"

向量存储:
[错误] 无机制区分"当前事实"vs"过时事实"
[错误] 除了显式元数据和过滤

结果:
→ 检索返回过时信息
→ 上下文冲突 (矛盾信息)

迁移到基于图的记忆

知识图谱优势:

向量存储:
[文档] → 嵌入 → 相似性搜索

知识图谱:
实体A --关系R--> 实体B

示例:
(客户X) --[购买]--> (产品Y)
(产品Y) --[类别]--> (电子产品)
(产品Y) --[相关]--> (产品Z)

查询: "购买产品Y的客户还买了什么?"
遍历: (客户X) → [购买] → (产品Y) ← [购买] ← (客户W) → [购买] → (产品Z)

→ 支持遍历关系而非仅相似性的查询

时间知识图谱:

为事实添加有效性期间

事实有:
- valid_from (从何时有效)
- valid_until (到何时有效, 可选)

示例:
(客户X) --[居住在, 2020-01-01至2022-06-15]--> (地址A)
(客户X) --[居住在, 2022-06-16至今]--> (地址B)

查询: "客户X在2021-05-20的地址是什么?"
→ 仅检索在2021-05-20有效的地址
→ 返回地址A

启用:
[OK] 时间旅行查询
[OK] 重建特定时间点的知识
[OK] 防止上下文冲突 (过时vs当前信息)
[OK] 时间推理 (实体如何变化)

基准性能比较

DMR基准数据 (Deep Memory Retrieval):

记忆系统 DMR准确率 检索延迟 备注
Zep (时间KG) 94.8% 2.58s 最佳准确率, 快速检索
MemGPT 93.4% 可变 良好通用性能
GraphRAG ~75-85% 可变 比基线RAG高20-35%
Vector RAG ~60-70% 失去关系结构
递归摘要 35.3% 严重信息丢失

关键发现:

Zep vs 全上下文基线:
- 检索延迟减少90% (2.58s vs 28.9s for GPT-5.2)
- 效率来源: 仅检索相关子图而非整个上下文历史

GraphRAG vs 基线RAG:
- 复杂推理任务准确率高20-35%
- 通过基于社区的摘要减少幻觉30%

递归摘要:
- 仅35.3%准确率
- 严重信息损失
- 不推荐用于复杂任务

五层记忆架构

第1层: 工作记忆 (Working Memory)

上下文窗口本身

特点:
- 零延迟访问
- 有限容量
- 会话结束消失

使用模式:
1. 草稿本计算
   - 代理跟踪中间结果

2. 对话历史
   - 为当前任务保留对话

3. 当前任务状态
   - 跟踪活跃目标的进展

4. 活跃检索文档
   - 当前使用的信息

优化:
- 仅保留活跃信息
- 在离开注意力前摘要已完成工作
- 关键信息放在注意力优势位置

第2层: 短期记忆 (Short-Term Memory)

跨当前会话持久, 不跨会话

特点:
- 可搜索
- 会话结束消失
- 中等延迟

实现:
1. 会话范围数据库
   - persist until session end

2. 文件系统存储
   - 指定会话目录

3. 内存缓存
   - 会话ID键

用例:
- 跨轮跟踪对话状态
- 存储工具调用中间结果
- 维护任务检查清单
- 会话内缓存检索信息

第3层: 长期记忆 (Long-Term Memory)

跨会话无限期持久

特点:
- 结构化
- 半永久
- 检索延迟

实现范围:
- 简单键值存储
- 图数据库
- 向量存储
- 混合系统

选择基于:
- 建模关系的复杂性
- 需要的查询模式
- 可接受的基础设施复杂性

用例:
- 跨会话学习用户偏好
- 建立领域知识库
- 维护实体登记和关系历史
- 存储可重用的成功模式

第4层: 实体记忆 (Entity Memory)

专门跟踪实体 (人、地点、概念、对象)

维护:

1. 实体身份
   示例: "John Doe"在一个对话中提及
        是同一人在另一个对话中

2. 实体属性
   示例: John Doe属性:
        - 职业: 工程师
        - 公司: Acme Corp
        - 位置: 纽约

3. 实体关系
   示例: John Doe --[工作于]--> Acme Corp
        Acme Corp --[位于]--> 纽约

创建:
基础知识图谱

第5层: 时间知识图谱 (Temporal Knowledge Graphs)

扩展实体记忆, 显式有效性期间

事实不仅是真/假
而是在特定时间范围内为真

启用:
[OK] 查询: "用户在日期X的地址是什么?"
  通过检索该日期范围内有效的事实

[OK] 防止上下文冲突
  过时信息与新数据矛盾

[OK] 时间推理
  实体如何随时间变化

示例:
(用户X) --[居住在, 2020-01至2022-06]--> (地址A)
(用户X) --[居住在, 2022-06至今]--> (地址B)

query_2021 = "用户X的地址 (2021-05)"
→ 返回地址A

query_2023 = "用户X的地址 (2023-01)"
→ 返回地址B

记忆实现模式

模式1: 文件系统即记忆 (File-System-as-Memory)

# 简单、无需额外基础设施、渐进式加载

实现:
- 文件系统层次结构组织
- 有意义的命名约定
- 结构化格式 (JSON, YAML)
- 时间戳用于时间跟踪

优势:
[OK] 简单
[OK] 透明
[OK] 可移植

劣势:
[错误] 无语义搜索
[错误] 无关系跟踪
[错误] 需手动组织

示例结构:
memory/
├── entities/
│   ├── user_123.json
│   └── company_456.json
├── conversations/
│   └── conv_2025-01-15.json
└── facts/
    └── fact_789.json

模式2: 带元数据的向量RAG

# 语义搜索 + 过滤能力

嵌入事实/文档, 存储元数据:
{
  "embedding": [0.1, 0.2, ...],
  "metadata": {
    "entity_tags": ["user", "customer"],
    "valid_from": "2025-01-01",
    "source": "conversation_123",
    "confidence": 0.95
  }
}

查询:
元数据过滤器 + 语义搜索

示例:
query = "用户偏好"
filters = {
  "entity": "user_123",
  "valid_from": ">= 2025-01-01"
}
results = vector_store.search(query, filters)

模式3: 知识图谱

# 显式建模实体和关系

定义:
- 实体类型 (用户、产品、公司)
- 关系类型 (购买、工作于、位于)
- 图数据库或属性图存储
- 常见查询模式索引

示例Cypher查询 (Neo4j):
MATCH (user:User {id: "123"})-[:PURCHASED]->(product:Product)
MATCH (product)-[:RELATED_TO]->(related:Product)
RETURN related.name

"用户123购买的产品相关的产品"

模式4: 时间知识图谱

# 为事实添加有效性期间

实现:
- 每个关系有valid_from和valid_until
- 时间范围索引
- 时间点查询

示例查询 (Cypher):
MATCH (user:User {id: "123"})-[r:LIVES_AT]->(address:Address)
WHERE user.id = $user_id
AND r.valid_from <= $query_time
AND (r.valid_until IS NULL OR r.valid_until > $query_time)
RETURN address

"用户在特定时间的地址是什么?"

记忆检索模式

语义检索:

# 通过嵌入相似性检索

def retrieve_semantic(query, top_k=5):
    query_embedding = embed(query)
    results = vector_store.similarity_search(query_embedding, k=top_k)
    return results

实体检索:

# 通过遍历图关系

def retrieve_entity(entity_id, depth=2):
    # 检索所有与实体相关的记忆
    query = f"""
    MATCH (entity {{id: '{entity_id}'}})-[r*1..{depth}]->(related)
    RETURN related
    """
    return graph_db.query(query)

时间检索:

# 通过有效性期间过滤

def retrieve_temporal(entity_id, query_time):
    query = f"""
    MATCH (entity {{id: '{entity_id}'}})-[r]->(related)
    WHERE r.valid_from <= '{query_time}'
    AND (r.valid_until IS NULL OR r.valid_until > '{query_time}')
    RETURN related
    """
    return graph_db.query(query)

记忆整合

为什么需要整合:

记忆随时间累积
→ 需要整合防止无界增长
→ 移除过时信息
→ 提高检索性能

整合触发器:

triggers = [
    "显著记忆累积后",
    "检索返回过多过时结果",
    "定期计划 (每周/每月)",
    "显式请求整合时"
]

整合过程:

def consolidate_memory():
    # 1. 识别过时事实
    outdated = identify_outdated_facts()

    # 2. 合并相关事实
    merged = merge_related_facts()

    # 3. 更新有效性期间
    update_validity_periods()

    # 4. 归档或删除过时事实
    archive_or_delete(outdated)

    # 5. 重建索引
    rebuild_indexes()

模块3: 工具设计原则

核心概念

工具作为契约:

工具 = 确定性系统与非确定性代理间的契约

人类调用API:
- 理解契约
- 阅读文档
- 发出适当请求
- 知道如何处理错误

代理调用工具:
- 从描述推断契约
- 从自然语言生成调用
- 必须理解参数和格式
- 需要恢复指导

→ 需要重新思考API设计!

工具描述即提示词:

工具描述加载到代理上下文中
→ 共同引导行为

不仅是文档
→ 是塑造代理如何推理工具使用的提示工程

示例:
差: "搜索数据库"
好: "通过ID或电子邮件检索客户信息。
     使用时机: 用户询问特定客户详细信息...
     返回: 客户对象, 包含...
     错误: NOT_FOUND, INVALID_FORMAT..."

整合原则

核心原则:

如果人类工程师不能确定在给定情况下
应该使用哪个工具,
就不能期望代理做得更好。

→ 偏好单个综合工具而非多个狭窄工具

示例对比:

[错误] 多个狭窄工具:

list_users()      # 列出用户
list_events()     # 列出事件
create_event()    # 创建事件

代理必须:
1. 知道调用list_users查找参与者
2. 知道调用list_events检查冲突
3. 知道调用create_event创建
4. 正确排序调用
5. 处理失败
→ 复杂、易错

[OK] 单个综合工具:

schedule_event(
    title: str,
    attendees: List[str],
    duration: int
    # 内部处理:
    # - 查找参与者可用性
    # - 检查现有事件冲突
    # - 创建事件
)

代理仅:
1. 提供事件详情
2. 工具处理工作流

→ 简单、可靠

为什么整合有效:

1. 代理有有限上下文和注意力
   → 每个工具在工具选择阶段竞争注意力

2. 每个工具添加描述tokens
   → 消耗上下文预算

3. 重叠功能造成歧义
   → 哪个工具用于给定情况?

整合:
- 消除冗余描述 (减少token)
- 消除歧义 (一个工具覆盖工作流)
- 减少工具选择复杂度

何时整合:

[OK] 应该整合:
- 工具链式使用以完成工作流
- 工具重叠功能
- 工具用于一致的模式

[错误] 不应整合:
- 根本不同行为的工具
- 不同上下文中使用的工具
- 可能独立调用的工具

架构简化

文件系统代理模式:

不为数据探索、模式查找、查询验证构建自定义工具

→ 通过单个命令执行工具提供直接文件系统访问

代理使用标准Unix工具:
grep, cat, find, ls, jq, etc.

示例对比:

[错误] 复杂工具架构:

# 专门工具
explore_database_schema()
query_table()
validate_query()
analyze_results()

每个需要描述、参数、错误处理...
→ 大量维护开销

[OK] 简化架构:

# 单个执行工具
execute_command(command: str)

代理使用:
execute_command("psql -d mydb -c '\d table_name'")
execute_command("psql -d mydb -c 'SELECT * FROM users LIMIT 10'")
execute_command("cat schema.sql | grep 'CREATE TABLE'")

→ 灵活、强大、零维护

为什么有效:

1. 文件系统是模型深刻理解的经过验证的抽象
2. 标准工具有可预测、文档完善的行为
3. 代理灵活链接原语, 不受预定义工作流约束
4. 文件中的良好文档替代摘要工具需求

关键:
文档质量 > 工具复杂性

何时简化胜过复杂:

[OK] 简化有效:
- 数据层文档良好、结构一致
- 模型有足够推理能力导航复杂性
- 专门工具约束而非启用模型
- 花费更多时间维护脚手架而非改进结果

[错误] 简化失败:
- 底层数据混乱、不一致、文档不良
- 领域需要模型缺乏的专门知识
- 安全约束需要限制代理能力
- 操作真正复杂, 受益于结构化工作流

停止约束推理:

常见反模式: 构建工具"保护"模型免受复杂性

例子:
- 预过滤上下文
- 约束选项
- 包装交互验证逻辑
- 抽象复杂系统

问题:
这些护栏随模型改进常成为负债

关键问题:
工具是启用新能力, 还是约束模型本可自行处理的推理?

为未来模型构建:

模型改进快于工具跟进度

为今天模型优化的架构可能对明天模型过度约束

→ 构建最小架构, 可受益模型改进
  而非锁定当前限制的复杂架构

策略:
1. 优先考虑原语
2. 投资文档质量
3. 避免过度抽象
4. 让模型推理

工具描述工程

描述结构 (回答四个问题):

1. 工具做什么?

# 差
"搜索数据库"
# 太模糊

# 好
"通过ID或电子邮件检索客户信息"
# 清晰、具体

2. 何时使用?

"""
使用时机:
- 用户询问特定客户详细信息
- 需要客户上下文进行决策
- 验证客户身份
"""

3. 接受什么输入?

"""
参数:
    customer_id: 客户唯一标识符
        格式: "CUST-######" (例如 "CUST-000001")
    email: 客户电子邮件地址
        格式: 标准email格式
        默认: 如果提供email则忽略customer_id
"""

4. 返回什么?

"""
返回:
    Customer对象包含:
        - id: 客户ID
        - name: 全名
        - email: 电子邮件地址
        - status: 账户状态 (ACTIVE, INACTIVE, SUSPENDED)
        - created_at: 账户创建日期

错误:
    NOT_FOUND: 未找到客户
    INVALID_FORMAT: ID/email格式无效
    MULTIPLE_MATCHES: 多个客户匹配email
"""

完整示例:

def get_customer(
    customer_id: str = None,
    email: str = None,
    format: str = "concise"
) -> Customer:
    """
    通过ID或电子邮件检索客户信息。

    使用时机:
    - 用户询问特定客户详细信息、历史或状态
    - 用户提供客户标识符并需要相关信息
    - 验证客户身份或账户状态

    参数:
        customer_id: 客户ID (格式"CUST-######")
        email: 客户电子邮件地址
        format: "concise"关键字段, "detailed"完整记录

    返回:
        concise格式: id, name, email, status
        detailed格式: 完整对象, 包括历史、订单、支持票据

    错误:
        NOT_FOUND: 未找到客户
        INVALID_FORMAT: ID必须匹配CUST-######模式
    """

响应格式优化

为什么需要格式选项:

工具响应大小显著影响上下文使用

场景A: 确认客户存在
→ 需要基本字段即可

场景B: 分析客户行为
→ 需要完整历史和订单数据

→ 代理应该控制详细程度

实现:

def get_customer(
    customer_id: str,
    format: str = "concise"  # 默认concise
) -> dict:
    """
    format参数:
    - "concise": 仅关键字段
      适用: 确认、基本信息

    - "detailed": 完整对象
      适用: 决策的完整上下文
    """
    if format == "concise":
        return {
            "id": customer.id,
            "name": customer.name,
            "email": customer.email,
            "status": customer.status
        }
    else:  # detailed
        return {
            "id": customer.id,
            "name": customer.name,
            "email": customer.email,
            "status": customer.status,
            "order_history": customer.orders,
            "support_tickets": customer.tickets,
            "preferences": customer.preferences,
            "created_at": customer.created_at
        }

指导代理选择:

"""
格式选择指导:
- 使用"concise": 快速确认、状态检查
- 使用"detailed": 分析、决策、报告生成
"""

错误消息设计

两个受众:

开发者: 调试问题
代理: 从失败中恢复

→ 代理错误消息必须可操作!

设计原则:

[OK] 告诉代理什么出错
[OK] 如何纠正
[OK] 提供示例
[OK] 下一步建议

[错误] "错误: 无效输入" (无帮助)
[错误] "失败" (无信息)

示例对比:

[错误] 糟糕:

{
  "error": "Invalid input"
}
# 代理无法知道什么无效或如何修正

[OK] 良好:

{
  "error": "INVALID_FORMAT",
  "message": "customer_id必须匹配格式'CUST-######'",
  "provided": "12345",
  "expected_format": "CUST-000001",
  "suggestion": "请提供格式为CUST-######的ID, 例如CUST-000123"
}
# 代理知道:
# - 什么错误
# - 提供了什么
# - 期望什么
# - 如何修正

可恢复错误:

# 重试错误
{
  "error": "TEMPORARY_UNAVAILABLE",
  "message": "数据库暂时不可达",
  "retry_after": 5,  # 秒
  "suggestion": "5秒后重试"
}

# 输入错误
{
  "error": "MISSING_PARAMETER",
  "message": "缺少必需参数'customer_id'",
  "required_params": ["customer_id", "email"],
  "provided_params": ["email"],
  "suggestion": "提供customer_id参数"
}

# 权限错误
{
  "error": "PERMISSION_DENIED",
  "message": "无权限访问此资源",
  "required_permission": "customers:read",
  "suggestion": "联系管理员授予customers:read权限"
}

MCP工具命名要求

问题:

使用MCP (模型上下文协议) 时,
多个服务器可能提供同名工具

Example:
server_a.get_user()
server_b.get_user()

代理调用"get_user()" → "tool not found"错误

解决方案:

# [OK] 正确: 完全限定名称
"使用BigQuery:bigquery_schema工具检索表模式"
"使用GitHub:create_issue工具创建问题"

# [错误] 错误: 非限定名称
"使用bigquery_schema工具..."
# 可能因多个服务器而失败

格式: ServerName:tool_name

实施:

# 在所有工具引用中包括服务器上下文

def describe_tools():
    return """
    可用工具:
    - BigQuery:bigquery_schema: 检索BigQuery表模式
    - BigQuery:execute_query: 执行SQL查询
    - GitHub:create_issue: 创建GitHub问题
    - GitHub:get_file: 获取文件内容
    """

工具集合设计

研究显示:

工具描述重叠导致模型混乱
更多工具不总是带来更好结果

合理指南:
- 大多数应用: 10-20个工具
- 如需更多: 使用命名空间创建逻辑分组

帮助代理选择正确工具:

1. 工具分组

# 命名空间组织

database_tools = [
    "db:query",
    "db:schema",
    "db:tables"
]

file_tools = [
    "file:read",
    "file:write",
    "file:list"
]

# 代理路由到适当组

2. 基于示例的选择

def get_customer(customer_id: str):
    """
    通过ID检索客户信息

    示例:
    get_customer("CUST-000001") → 返回客户1的信息
    get_customer("CUST-999999") → 错误: 未找到

    对比:
    NOT: get_orders() # 获取订单历史
    NOT: search_customers() # 搜索客户列表
    """

3. 层级: 伞形工具

# 伞形工具路由到专门的子工具

def data_operation(operation: str, **params):
    """
    执行数据操作

    operation参数确定子工具:
    - "query": 执行SQL查询
    - "schema": 获取表模式
    - "tables": 列出所有表

    示例:
    data_operation("query", sql="SELECT * FROM users")
    data_operation("schema", table="users")
    data_operation("tables")
    """

使用代理优化工具

Claude可以优化自己的工具:

给定工具和观察到的失败模式
→ 诊断问题
→ 建议改进

生产测试:
- 任务完成时间减少40%
- 帮助未来代理避免错误

工具测试代理模式:

def optimize_tool_description(tool_spec, failure_examples):
    """
    使用代理分析工具失败并改进描述

    过程:
    1. 代理尝试在多样任务中使用工具
    2. 收集失败模式和摩擦点
    3. 代理分析失败并提出改进
    4. 对相同任务测试改进的描述
    """
    prompt = f"""
    分析此工具规范和观察到的失败。

    工具: {tool_spec}

    观察到的失败:
    {failure_examples}

    识别:
    1. 代理为什么失败
    2. 描述中缺少什么信息
    3. 什么歧义导致错误使用

    提出解决这些问题的改进工具描述。
    """

    return get_agent_response(prompt)

创建反馈循环:

代理使用工具

生成失败数据

代理分析失败

改进工具描述

减少未来失败

工具设计示例

良好设计示例

def get_customer(
    customer_id: str,
    format: str = "concise"
) -> dict:
    """
    通过ID检索客户信息。

    使用时机:
    - 用户询问特定客户详细信息
    - 决策需要客户上下文
    - 验证客户身份

    参数:
        customer_id: 格式"CUST-######" (如"CUST-000001")
        format: "concise"关键字段, "detailed"完整记录

    返回:
        concise格式: id, name, email, status
        detailed格式: 完整记录, 包括历史、订单、支持

    错误:
        NOT_FOUND: 客户ID未找到
        INVALID_FORMAT: ID必须匹配CUST-######模式

    示例:
        get_customer("CUST-000001") → 客户1的信息
        get_customer("CUST-999999", "detailed") → 错误: 未找到
    """

为什么好:

[OK] 清晰名称: get_customer (动词_名词)
[OK] 使用时机: 明确场景
[OK] 参数描述: 格式、约束、默认值
[OK] 返回描述: 格式选项、字段
[OK] 错误处理: 错误类型、含义
[OK] 示例: 成功和失败情况

糟糕设计示例

def search(query):
    """搜索数据库。"""
    pass

问题分析:

问题 描述 后果
模糊名称 “search”搜索什么, 为什么目的? 代理不知道何时使用
缺少参数 什么数据库? 查询什么格式? 代理无法正确调用
无返回描述 返回什么? 列表? 字符串? 代理无法解释结果
无使用上下文 vs其他工具? 代理选择错误工具
无错误处理 数据库不可用时? 代理无法恢复

失败模式:

1. 代理应在使用更具体工具时调用此工具
2. 代理无法确定正确查询格式
3. 代理无法解释结果
4. 代理无法从失败中恢复

核心原则总结

多智能体架构

  1. 子代理存在主要是为了隔离上下文

    • 不是拟人化角色分工
    • 每个子代理在干净上下文中操作
  2. 选择架构模式基于协调需求

    • 监督者: 明确分解、人工监督
    • 点对点: 灵活探索、emergent需求
    • 层级化: 大型项目、企业管理
  3. 实现明确交接协议

    • 状态传递
    • 避免电话游戏问题 (forward_message工具)
    • 直接响应机制
  4. 监控失败模式

    • 监督者瓶颈 (输出约束、检查点)
    • 协调开销 (批处理、异步)
    • 分歧 (收敛检查、TTL)
    • 错误传播 (验证、重试、熔断)
  5. Token经济学现实

    • 多智能体系统消耗~15x基线tokens
    • 但模型选择常比token预算更重要
    • 并行化优势 = 时间节省

记忆系统

  1. 匹配记忆架构到查询需求

    • 简单持久化: 文件系统记忆
    • 语义搜索: 向量RAG + 元数据
    • 关系推理: 知识图谱
    • 时间有效性: 时间知识图谱
  2. 实现渐进式披露

    • 按需记忆加载
    • 战略性注入注意力优势位置
  3. 使用时间有效性

    • 防止过时信息冲突
    • 时间旅行查询
    • 时间推理
  4. 定期整合

    • 防止无界增长
    • 移除过时信息
    • 合并相关事实
  5. 五层架构

    • 工作记忆 (上下文)
    • 短期记忆 (会话)
    • 长期记忆 (跨会话)
    • 实体记忆 (实体跟踪)
    • 时间KG (时间有效性)

工具设计

  1. 整合减少歧义

    • 单个综合工具vs多个狭窄工具
    • 人类无法确定 → 代理无法确定
  2. 描述回答什么、何时、返回什么

    • 清晰、具体
    • 使用上下文
    • 示例和默认值
  3. 实现响应格式选项

    • concise vs detailed
    • token效率
  4. 错误消息使代理能够恢复

    • 可操作
    • 纠正指导
    • 明确下一步
  5. 质疑工具启用还是约束模型

    • 为未来模型构建
    • 最小架构 > 复杂架构
    • 文档质量 > 工具复杂性
  6. 使用代理优化工具

    • 反馈循环
    • 失败分析
    • 迭代改进

(完)