Skip to main content التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/majiayu000/sage --skill sage-recovery-patternsيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
المهن ذات الصلةSOC
استنادا إلى تصنيف SOC المهني
| name | sage-recovery-patterns |
| description | Sage 独有的恢复模式设计,包含熔断器、限流器、重试策略的最佳实践 |
| when_to_use | 当需要实现容错机制、处理 LLM API 故障、或设计弹性系统时使用 |
| allowed_tools | ["Read","Grep","Glob","Edit","Write"] |
| user_invocable | true |
| priority | 80 |
Sage 恢复模式指南
概述
Sage 的 recovery/ 模块是独有的竞争优势,提供生产级容错能力:
- 熔断器 (Circuit Breaker): 防止级联故障
- 限流器 (Rate Limiter): 控制 API 调用频率
- 重试策略 (Retry Policy): 智能重试失败操作
- 任务监督 (Supervisor): 管理长时间运行任务
熔断器模式
状态机
成功调用
┌────────┐
│ ▼
┌───────┐ 失败次数 < 阈值 ┌───────┐
│Closed │ ─────────────────▶│Closed │
└───────┘ └───┬───┘
│ │
│ 失败次数 >= 阈值 │
▼ │
┌───────┐ │
│ Open │ ◀────────────────────┘
└───┬───┘
│ 超时后
▼
┌──────────┐
│Half-Open │
└────┬─────┘
│
├── 成功 ──▶ Closed
│
└── 失败 ──▶ Open
配置
use sage_core::recovery::{CircuitBreaker, CircuitBreakerConfig};
let config = CircuitBreakerConfig {
failure_threshold: 5,
recovery_timeout: Duration::from_secs(30),
half_open_max_calls: 3,
success_rate_threshold: 0.5,
window_size: 10,
};
let breaker = CircuitBreaker::new("llm-api", config);
使用
let result = breaker.call(|| async {
llm_client.chat(request).await
}).await;
match result {
Ok(response) => handle_success(response),
Err(CircuitBreakerError::Open) => {
return fallback_response();
}
Err(CircuitBreakerError::Rejected(e)) => {
return Err(e);
}
Err(CircuitBreakerError::Failed(e)) => {
return Err(e);
}
}
if breaker.is_open() {
log::warn!("Circuit breaker is open, using fallback");
return fallback();
}
与 LLM 提供者集成
pub struct ResilientLlmClient {
client: Box<dyn LlmClient>,
breaker: CircuitBreaker,
}
impl ResilientLlmClient {
pub async fn chat(&self, request: ChatRequest) -> Result<LlmResponse> {
self.breaker.call(|| async {
self.client.chat(request.clone()).await
}).await
.map_err(|e| match e {
CircuitBreakerError::Open => {
LlmError::ServiceUnavailable("Circuit breaker open".into())
}
CircuitBreakerError::Failed(inner) => inner,
_ => LlmError::Unknown(e.to_string()),
})
}
}
限流器模式
滑动窗口限流
use sage_core::recovery::SlidingWindowRateLimiter;
let limiter = SlidingWindowRateLimiter::new(
100,
Duration::from_secs(60),
);
limiter.acquire().await?;
if limiter.try_acquire() {
} else {
return Err(RateLimitError::TooManyRequests);
}
令牌桶限流
use sage_core::recovery::TokenBucketRateLimiter;
let limiter = TokenBucketRateLimiter::new(
10,
Duration::from_millis(100),
);
limiter.acquire_n(5).await?;
按提供者限流
use sage_core::recovery::RateLimiterRegistry;
let registry = RateLimiterRegistry::new();
registry.register("anthropic", SlidingWindowRateLimiter::new(60, Duration::from_secs(60)));
registry.register("openai", SlidingWindowRateLimiter::new(100, Duration::from_secs(60)));
registry.register("google", SlidingWindowRateLimiter::new(30, Duration::from_secs(60)));
let limiter = registry.get("anthropic")?;
limiter.acquire().await?;
重试策略
指数退避
use sage_core::recovery::{RetryPolicy, BackoffConfig};
let policy = RetryPolicy::exponential(BackoffConfig {
initial_delay: Duration::from_millis(100),
max_delay: Duration::from_secs(30),
multiplier: 2.0,
max_retries: 5,
jitter: true,
});
let result = policy.retry(|| async {
llm_client.chat(request.clone()).await
}).await?;
错误分类重试
use sage_core::recovery::{RetryPolicy, ErrorClass};
let policy = RetryPolicy::with_classifier(|error: &LlmError| {
match error {
LlmError::RateLimit(_) => ErrorClass::Transient,
LlmError::Timeout(_) => ErrorClass::Transient,
LlmError::ServerError(_) => ErrorClass::Transient,
LlmError::InvalidRequest(_) => ErrorClass::Permanent,
LlmError::AuthError(_) => ErrorClass::Permanent,
_ => ErrorClass::Unknown,
}
});
组合策略
pub async fn resilient_call<F, T, E>(
breaker: &CircuitBreaker,
limiter: &RateLimiter,
retry_policy: &RetryPolicy,
f: F,
) -> Result<T, E>
where
F: Fn() -> Future<Output = Result<T, E>>,
E: Into<RecoverableError>,
{
if breaker.is_open() {
return Err(Error::CircuitOpen);
}
limiter.acquire().await?;
let result = retry_policy.retry(|| async {
breaker.call(|| f()).await
}).await;
result
}
任务监督
监督策略
use sage_core::recovery::{TaskSupervisor, SupervisionPolicy};
let supervisor = TaskSupervisor::new(SupervisionPolicy {
max_restarts: 3,
restart_window: Duration::from_secs(60),
restart_delay: BackoffConfig::exponential(
Duration::from_secs(1),
Duration::from_secs(30),
),
on_max_restarts: SupervisionAction::Stop,
});
监督长时间任务
supervisor.supervise("agent-execution", || async {
agent.execute(task).await
}).await?;
最佳实践
1. 分层恢复
let retry = RetryPolicy::exponential(config);
let breaker = CircuitBreaker::new(config);
let limiter = RateLimiter::new(config);
limiter.acquire().await?;
breaker.call(|| retry.retry(|| api_call())).await?;
2. 监控指标
telemetry.gauge("circuit_breaker.state", breaker.state() as i64);
telemetry.counter("circuit_breaker.failures", breaker.failure_count());
telemetry.counter("rate_limiter.rejected", limiter.rejected_count());
telemetry.histogram("rate_limiter.wait_time", limiter.avg_wait_time());
telemetry.histogram("retry.attempts", retry_count);
telemetry.counter("retry.exhausted", exhausted_count);
3. 降级策略
async fn with_fallback<T>(
primary: impl Future<Output = Result<T>>,
fallback: impl Future<Output = Result<T>>,
) -> Result<T> {
match primary.await {
Ok(result) => Ok(result),
Err(e) if is_recoverable(&e) => {
log::warn!("Primary failed, using fallback: {}", e);
fallback.await
}
Err(e) => Err(e),
}
}
let response = with_fallback(
claude_client.chat(request.clone()),
openai_client.chat(request.clone()),
).await?;
4. 健康检查
pub struct HealthChecker {
breakers: HashMap<String, CircuitBreaker>,
}
impl HealthChecker {
pub fn is_healthy(&self) -> bool {
self.breakers.values().all(|b| !b.is_open())
}
pub fn health_report(&self) -> HealthReport {
HealthReport {
services: self.breakers.iter().map(|(name, breaker)| {
(name.clone(), ServiceHealth {
state: breaker.state(),
failure_rate: breaker.failure_rate(),
last_failure: breaker.last_failure_time(),
})
}).collect(),
}
}
}
配置建议
LLM API 熔断器
CircuitBreakerConfig {
failure_threshold: 5,
recovery_timeout: 30.seconds(),
success_rate_threshold: 0.5,
window_size: 10,
}
LLM API 限流器
SlidingWindowRateLimiter::new(60, 60.seconds())
SlidingWindowRateLimiter::new(100, 60.seconds())
SlidingWindowRateLimiter::new(30, 60.seconds())
重试策略
RetryPolicy::exponential(BackoffConfig {
initial_delay: 100.milliseconds(),
max_delay: 30.seconds(),
multiplier: 2.0,
max_retries: 5,
jitter: true,
})