把 Skill 连到真实世界:连接器模式、缓存与重试策略

连接器(Connector)是什么

连接器是“把外部系统能力变成工具调用”的那层胶水。它的职责不是智能,而是稳定:

  • 认证与权限
  • 请求/响应映射
  • 限流与重试
  • 缓存与降级
  • 审计与追踪

把这些放在连接器层,Skill 才不会被外部系统的细节拖垮。

三种常见连接方式:API Key / OAuth / Webhook

你可以按“谁控制权限”和“是否需要用户授权”来选:

  • API Key:最快,适合内部系统或单租户;风险是 key 泄漏与权限过大
  • OAuth:标准做法,适合多用户/多租户;成本是实现复杂与 token 生命周期管理
  • Webhook:事件驱动,适合异步触发(PR opened -> 自动摘要);成本是幂等与重放处理

限流(Rate Limit):把“失败”变成“可预期”

连接外部系统后最常见的错误不是 500,而是 429。

建议做:

  • 客户端限流:本地令牌桶/漏桶
  • 退避重试:指数退避 + 抖动(避免雪崩)
  • 预算控制:每个 task/用户/仓库的调用预算

并把错误归类到 TOOL_RATE_LIMIT,让上层可统计。

缓存:不是为了省钱,而是为了稳定

缓存解决三件事:

  • 降低延迟(避免每步都打远程 API)
  • 规避限流(热点数据重复用)
  • 支持降级(外部系统挂了还能给“最近一次结果”)

建议至少支持两类缓存:

  • 短期缓存:分钟级(PR 元数据、差异摘要)
  • 任务级缓存:同一个 task 内复用(避免重复请求)

重试与幂等:外部系统写操作要特别小心

读操作可以相对激进地重试;写操作必须先设计幂等:

  • 写工具增加 idempotency_key
  • 或者在外部系统侧使用“upsert/compare-and-swap”
  • 或者在写之前做查重(例如评论内容相同则不再发布)

如果你只做“重试”,不做幂等,最终一定会重复写入。

Webhook:要把“重放”当成正常现象

Webhook 不是“只来一次的事件”,重放/重复投递是常态。

工程上要做:

  • event_id 去重
  • 处理顺序不可靠:要能乱序处理
  • 验签与来源校验:避免伪造事件

动手做:连接器层的“最小稳定接口”

无论你对接哪个系统,连接器层建议统一输出:

{
  "ok": true,
  "data": {},
  "meta": {
    "source": "github",
    "latency_ms": 123,
    "cache": "hit|miss",
    "rate_limit_remaining": 456
  }
}

失败时输出:

{
  "ok": false,
  "error": {
    "type": "TOOL_RATE_LIMIT",
    "retryable": true,
    "retry_after_ms": 2000
  }
}

工程化清单

  • 连接器层统一错误枚举与结构化返回
  • 支持限流、退避重试、缓存、降级
  • 写操作具备幂等与去重
  • webhook 有去重、验签、乱序容忍

常见坑

  • 把限流交给模型处理:模型无法做全局预算与节流
  • 只做重试不做幂等:写爆外部系统
  • 不做缓存:延迟与成本都失控

下一篇:从 Skill 到 Agent:什么时候需要多步自主执行

← 返回博客列表