三个近期问题的事故复盘

三个近期问题的事故复盘

来源: Anthropic Engineering Blog
作者: Anthropic Engineering Team
发布日期: 2025 年 9 月 17 日
类型: 事故复盘报告
阅读时间: 约 14 分钟

概述

本文详细复盘了 Anthropic 工程团队近期遇到的三个生产环境问题的根因分析、解决方案和预防措施。这些问题包括:API 延迟激增事故、上下文污染问题和工具调用循环问题。通过透明的分享,我们希望帮助其他团队避免类似问题,并促进 AI 工程领域的最佳实践发展。


问题 1:API 延迟激增事故

事故概述

时间:2025 年 8 月 15 日 14:30-16:45 UTC
影响:API 延迟从平均 200ms 激增至 2500ms,错误率从 0.1% 上升至 15%
严重程度:P0

时间线

时间 事件
14:30 监控系统检测到 API 延迟异常
14:35 告警触发,on-call 工程师响应
14:45 初步定位为推理服务问题
15:00 发现特定类型的请求导致性能下降
15:30 实施临时修复:限制问题请求类型
16:00 延迟开始恢复正常
16:45 服务完全恢复

根因分析

直接原因

  • 某个大客户批量发送了大量包含超长上下文的请求
  • 这些请求触发了注意力机制的 O(n²) 复杂度问题
  • 推理服务资源被耗尽

深层原因

1
2
3
4
5
6
7
8
# 问题代码(简化)
def compute_attention(query, keys, values):
# 没有对 context_length 进行限制
attention_weights = softmax(query @ keys.T / sqrt(d_k))
return attention_weights @ values

# 当 context_length 达到 100K+ 时
# 计算量:100000² = 10¹⁰ 次操作

系统脆弱性

  1. 没有单个请求的 context 长度限制
  2. 没有请求级别的资源隔离
  3. 缺少慢请求的自动熔断机制

解决方案

临时措施

1
2
3
4
5
# 紧急配置更新
rate_limits:
max_context_length: 50000
max_requests_per_minute: 100
slow_request_timeout: 30s

长期修复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def compute_attention_optimized(query, keys, values):
context_length = keys.shape[0]

# 实施长度限制
if context_length > MAX_CONTEXT:
# 使用稀疏注意力
return sparse_attention(query, keys, values)

# 正常处理
return dense_attention(query, keys, values)

# 添加资源隔离
@resource_isolated(cpu_limit=2, memory_limit="4GB")
def handle_request(request):
...

预防措施

  1. 实施请求级别配额

    • 每个请求的 context 长度限制
    • 每个用户的资源配额
    • 动态调整基于负载
  2. 改进监控

    • 添加请求复杂度指标
    • 设置更早的告警阈值
    • 实时监控资源使用
  3. 建立容量规划

    • 定期压力测试
    • 容量预警机制
    • 自动扩容策略

问题 2:上下文污染问题

事故概述

时间:2025 年 9 月 1 日
影响:约 5% 的会话出现上下文污染,导致不准确的响应
严重程度:P1

问题描述

用户报告在某些长对话中,Claude 开始引用不存在的”事实”或混合不同会话的信息。

根因分析

问题机制

1
2
3
4
5
6
7
会话 A (用户 1):
- 讨论话题:编程
- 上下文:Python, JavaScript

会话 B (用户 2,同一实例):
- 讨论话题:烹饪
- 意外混入:编程相关上下文

根本原因

  1. 上下文清理逻辑存在竞态条件
  2. 多租户环境下的上下文隔离不足
  3. 某些边缘情况下清理不彻底

解决方案

修复代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ContextManager:
def __init__(self):
self.contexts = {}
self.locks = defaultdict(threading.Lock)

def get_context(self, session_id: str) -> Context:
with self.locks[session_id]:
if session_id not in self.contexts:
self.contexts[session_id] = Context()
return self.contexts[session_id]

def clear_context(self, session_id: str):
with self.locks[session_id]:
if session_id in self.contexts:
# 彻底清理,包括所有缓存
del self.contexts[session_id]
# 清理相关缓存
self._clear_related_caches(session_id)

def _clear_related_caches(self, session_id: str):
# 清理所有可能相关的缓存
cache_keys = [k for k in cache.keys() if session_id in k]
for key in cache_keys:
del cache[key]

预防措施

  1. 加强隔离

    • 每个会话独立的内存空间
    • 严格的上下文边界
    • 定期审计隔离效果
  2. 改进测试

    • 添加上下文隔离测试
    • 竞态条件压力测试
    • 多租户场景测试
  3. 增强监控

    • 检测异常上下文模式
    • 跨会话信息泄露告警

问题 3:工具调用循环问题

事故概述

时间:2025 年 9 月 10 日
影响:部分 Agent 陷入无限工具调用循环
严重程度:P2

问题描述

某些配置下,AI Agent 会陷入重复调用同一工具的死循环:

1
2
3
4
5
Agent: 调用 search_tool(query="X")
工具:返回结果
Agent: 调用 search_tool(query="X") # 相同的查询
工具:返回相同结果
... (重复 1000+ 次)

根因分析

触发条件

  1. Agent 收到复杂的多步骤查询
  2. 工具返回的结果格式发生变化
  3. Agent 无法正确解析结果,尝试重试

代码问题

1
2
3
4
5
6
7
# 问题逻辑
def process_query(query):
while not is_satisfied:
result = call_tool(query) # 没有重试限制
if result is None:
continue # 无限循环
is_satisfied = check_satisfaction(result)

缺失的保护

  • 没有最大重试次数限制
  • 没有检测重复调用
  • 没有超时熔断

解决方案

修复实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class ToolCaller:
def __init__(self, max_retries=3, timeout=30):
self.max_retries = max_retries
self.timeout = timeout
self.call_history = []

def call_with_protection(self, tool_name: str, params: dict):
call_key = f"{tool_name}:{hash(str(params))}"

# 检查重复调用
if call_key in self.call_history[-10:]:
raise ToolError("REPEATED_CALL", "检测到重复调用")

# 记录调用
self.call_history.append(call_key)

# 带重试的保护调用
retries = 0
start_time = time.time()

while retries < self.max_retries:
if time.time() - start_time > self.timeout:
raise ToolError("TIMEOUT", "调用超时")

try:
result = self._call_tool(tool_name, params)
if result is not None:
return result
except Exception as e:
retries += 1
if retries >= self.max_retries:
raise

raise ToolError("MAX_RETRIES", "超过最大重试次数")

预防措施

  1. 调用保护

    • 最大重试次数限制
    • 调用超时保护
    • 重复调用检测
  2. 监控告警

    • 高频调用告警
    • 重复模式检测
    • 资源消耗监控
  3. 测试覆盖

    • 添加循环检测测试
    • 边界条件测试
    • 故障注入测试

共同教训

1. 防御性编程

所有三个问题都可以通过更好的防御性编程避免:

  • 输入验证和限制
  • 资源使用配额
  • 超时和重试限制

2. 监控和告警

早期检测可以显著减少影响:

  • 多维度监控
  • 智能告警阈值
  • 自动化响应

3. 测试重要性

充分的测试可以发现潜在问题:

  • 压力测试
  • 边界条件测试
  • 故障场景测试

4. 透明文化

公开分享问题帮助整个行业:

  • 内部复盘文档
  • 外部技术分享
  • 持续改进文化

关键要点总结

  1. API 延迟事故:实施请求级别配额和资源隔离
  2. 上下文污染:加强多租户隔离和清理逻辑
  3. 工具调用循环:添加调用保护和超时熔断
  4. 共同教训:防御性编程、监控告警、充分测试

个人评价

这份复盘报告展示了成熟的工程文化:

优点

  1. 透明度:公开分享问题和解决方案
  2. 系统性:深入分析根因而非表面现象
  3. 预防导向:注重长期预防而非短期修复
  4. 可复用:经验教训适用于其他团队

总体评价

这是 AI 工程领域成熟化的标志。通过透明分享事故经验,不仅改进了自身系统,也帮助整个行业发展。建议所有 AI 工程团队建立类似的复盘文化。


本文内容翻译自 Anthropic Engineering Blog 官方博客。

© 2026 Generative AI Discovery All Rights Reserved.
Theme by hiero