Agent Skill 原理与工程实践(十七):循环、重试、Fallback 怎么设计

Agent Skill 原理与工程实践(十七):循环、重试、Fallback 怎么设计

上一章讨论了条件判断与分支。分支解决“下一步走哪条路”,但复杂任务还会出现另一类控制流:同一类动作需要重复执行。

例如研究任务:

1
2
3
4
5
6
7
8
9
Search
↓
Enough evidence?
├── yes → continue
└── no
↓
refine query
↓
search again

又例如工具调用失败:

1
2
3
4
5
Tool A
↓ failed
Retry Tool A?
↓ no
Fallback Tool B

如果设计得好,循环能逐步收集证据、修正结果并完成恢复;如果设计得差,Agent 会陷入无限搜索、重复写入、成本失控或静默降级。

本章的核心认知是:

每个循环都必须有进度指标和终止条件;每次重试都必须有错误分类和预算;每个 Fallback 都必须声明适用条件与质量损失。


1. 这一章要解决什么问题

本章集中回答:

1
2
3
4
5
6
7
8
9
10
Skill 中为什么需要循环?
循环的状态、进度和终止条件怎样定义?
什么错误适合重试,什么错误不应重试?
重试次数、时间和成本预算怎样设计?
指数退避与 Retry-After 怎样使用?
为什么重试前必须确认副作用?
Fallback 与 Retry、Degradation 有何区别?
Fallback 何时触发,怎样证明结果仍然可用?
恢复后为什么必须重新验证?
如何测试死循环、重复副作用和静默降级?

2. 三个概念先分清

2.1 Loop:重复执行一个阶段

循环的目标通常是逐步逼近完成条件:

  • 搜索更多证据;
  • 修复验证错误;
  • 分页读取数据;
  • 处理批量对象;
  • 驱动 Tool Call Agent Loop;
  • 迭代生成和审查。

2.2 Retry:重新尝试同一逻辑操作

Retry 通常针对暂时性失败:

  • 网络中断;
  • 限流;
  • 服务过载;
  • 短暂超时;
  • 可解决的并发冲突。

重试的前提是:导致失败的条件可能随时间或参数修正而改变。

2.3 Fallback:切换到替代路径

Fallback 不是再次尝试原路径,而是使用另一个方案:

  • Tool A 不可用,使用 Tool B;
  • 实时数据不可用,使用标明时间的缓存;
  • 专用解析器失败,使用通用解析器;
  • 无法生成图表,交付表格;
  • 高质量路径超出预算,切换到较低成本但合格的路径。

可以概括为:

1
2
3
4
5
6
7
8
Loop
→ 重复一个阶段直到满足退出条件

Retry
→ 同一逻辑操作再次尝试

Fallback
→ 改走另一条实现路径

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
Enter Stage
│
▼
Perform Attempt
│
▼
Validate Result
│
┌──┼───────────────────────┐
│ │ │
│ success failure
│ │ │
│ ▼ ▼
│ Exit Classify Failure
│ │
│ ┌────────────┼─────────────┐
│ ▼ ▼ ▼
│ Retry Fallback Ask / Stop
│ │ │
│ └──────┬─────┘
│ ▼
│ Revalidate
│ │
└────────────────────┘

任何返回循环顶部的边都必须回答:

  • 状态发生了什么变化?
  • 为什么下一次可能成功?
  • 还剩多少预算?
  • 是否会重复副作用?

4. Loop Contract:循环必须有契约

一个可靠循环至少包含七个元素。

4.1 Initial State

循环开始前已经知道什么:

1
query、cursor、已收集证据、预算、目标

4.2 Loop Body

每轮执行什么:

1
搜索 → 筛选 → 去重 → 评估证据

4.3 Progress Measure

如何知道正在前进:

  • 新增有效来源数量;
  • 未解决问题数量下降;
  • 验证错误数量下降;
  • 分页 cursor 前进;
  • 待处理对象数量减少;
  • 置信度达到阈值。

4.4 Success Condition

什么时候认为完成:

1
每个关键论断至少有一个可信来源,且没有阻断性证据缺口

4.5 Termination Condition

即使没有成功,也必须退出:

  • 最大轮数;
  • 最大耗时;
  • 最大成本;
  • 无新增进展;
  • 重复相同错误;
  • 用户取消;
  • 安全边界触发。

4.6 State Update

每轮结束后保存:

  • 新结果;
  • 去重集合;
  • 下一 cursor;
  • 剩余问题;
  • 尝试次数;
  • 最新错误。

4.7 Exit Behavior

退出后怎样处理:

  • 成功进入下一阶段;
  • 部分完成并披露限制;
  • 尝试 Fallback;
  • 请求用户信息;
  • 停止。

5. 循环的三类终止条件

5.1 目标驱动终止

1
2
3
4
until evidence is sufficient
until validator passes
until all pages are consumed
until pending items are empty

目标必须可判定。until the answer is good enough 太主观,除非进一步定义评价维度。

5.2 预算驱动终止

1
2
3
4
maximum 5 search rounds
maximum 90 seconds
maximum 20 tool calls
maximum estimated cost

预算是安全阀,不是完成标准。达到预算时应报告未完成状态,而不是强行宣称成功。

5.3 无进展终止

1
2
if two consecutive rounds add no new evidence:
stop refining the same query

无进展检测可以避免 Agent 用不同措辞重复同一操作。

最稳健的写法通常同时包含三类:

1
2
Continue until all required claims have supporting evidence, but stop after
five rounds, 20 tool calls, or two consecutive rounds with no new useful source.

6. 搜索循环怎样设计

一个常见反模式:

1
Keep searching until enough information is found.

问题在于 enough 没有定义。

更好的搜索循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## Evidence collection loop

Initial state:
- unanswered questions from the analysis plan;
- an empty canonical-source set;
- search_round = 0.

Each round:
1. Select the highest-priority unanswered question.
2. Build one focused query.
3. Search and inspect candidate sources.
4. Keep only sources that directly support or contradict the question.
5. Deduplicate by canonical URL and claim.
6. Update the evidence matrix.

Success:
- every blocking question has evidence; and
- conflicting evidence is either resolved or disclosed.

Stop without success when:
- five rounds have completed;
- two rounds add no useful evidence;
- only inaccessible sources remain.

循环不是“多搜几次”,而是每轮减少一个明确的知识缺口。


7. 分页循环怎样设计

分页看似简单,也容易出错:

1
2
3
4
5
6
cursor = null
do:
page = fetch(cursor)
process(page.items)
cursor = page.next_cursor
while cursor exists

还要验证:

  • cursor 是否真的变化;
  • 页面是否重复;
  • item ID 是否去重;
  • next_cursor 缺失是结束还是异常;
  • 是否有总页数或上限;
  • 中途失败后从哪个 cursor 恢复。

安全规则:

1
2
3
4
5
- Stop if the next cursor equals the current cursor.
- Deduplicate items by stable ID.
- Record the last fully processed cursor.
- Do not restart from page 1 after a transient failure unless processing is
idempotent.

8. Validate–Fix 循环怎样设计

1
2
3
4
5
6
7
8
9
Generate
↓
Validate
├── pass → continue
└── fail
↓
Fix
↓
Validate again

Anthropic Skill 最佳实践强调在质量关键任务中使用验证反馈循环:立即运行验证器、根据具体错误修复、重新验证,只有通过后才能继续。

8.1 修复必须针对错误

不要每轮完全重写全部产物。应使用错误列表定位受影响部分。

8.2 修复后必须从验证器重新开始

模型认为“已经修好”不等于验证通过。

8.3 限制轮数

1
最多 3 轮修复

如果相同错误持续出现,说明自动修复路径失效,应停止并报告。

8.4 错误变化时重新分类

第一次是缺字段,修复后变成文件损坏,不应继续沿用原来的重试策略。


9. Agent Tool Loop 的退出条件

客户端工具调用通常形成:

1
2
3
while stop_reason == tool_use:
execute tool calls
return tool results

Anthropic 官方 Tool Use 文档指出,遇到其他停止原因时循环应退出并按其语义处理,例如:

  • end_turn:正常结束;
  • max_tokens:输出被预算截断;
  • stop_sequence:遇到指定停止序列;
  • refusal:模型拒绝;
  • pause_turn:服务器侧循环暂时暂停,需要按协议继续。

不能把所有非 end_turn 状态都当成失败后重新发送同一请求,否则可能重复工具副作用。


10. Retry 前先分类错误

错误类别 例子 原样重试是否通常有效 正确动作
输入错误 缺参数、Schema 错误 否 修正或询问
认证错误 Token 失效 否 修复凭据
权限错误 无权访问资源 否 请求授权或停止
额度错误 余额、预算耗尽 否 等待外部处理
冲突错误 资源已被修改 有条件 读取最新状态后重建请求
临时错误 限流、超时、过载 是 有界退避重试
工具实现错误 脚本崩溃 通常否 修复实现或 Fallback
语义失败 结果不满足 Contract 原样重试通常否 修改策略或输入

原则:

如果不改变任何条件,同一操作必然再次失败,就不应自动重试。


11. Retryable 与 Non-Retryable

11.1 通常可重试

  • 临时网络失败;
  • 服务器过载;
  • 有明确恢复时间的速率限制;
  • 短暂超时;
  • 服务端标记可重试的错误;
  • 已重新读取状态并修正的并发冲突。

11.2 通常不可原样重试

  • 参数非法;
  • 文件不存在;
  • 凭据错误;
  • 没有权限;
  • 固定大小限制;
  • 账户额度耗尽;
  • 不支持的格式或版本;
  • 安全策略拒绝;
  • 确定性脚本 Bug。

11.3 429 也要分类

有些 429 是短期限流,带 Retry-After;有些可能表示消费上限,等待几秒不会恢复。应依据结构化错误类型和响应头,而不是只看状态码。


12. Retry Budget:重试必须有预算

至少定义:

  • max_attempts:最大尝试次数;
  • max_elapsed_time:最大总时长;
  • retryable_codes:允许重试的错误;
  • backoff:等待策略;
  • stop_on_error_change:错误变化是否停止;
  • fallback_after:何时切换替代方案;
  • on_exhausted:预算耗尽后的行为。

示例:

1
2
3
4
5
6
7
8
9
10
retry_policy:
max_attempts: 3
max_elapsed_seconds: 90
retryable_codes:
- rate_limited
- timeout
- service_unavailable
honor_retry_after: true
stop_on_error_change: true
on_exhausted: try_approved_fallback

OpenAI 官方错误恢复文档要求重试遵守 Retry-After,并设置尝试次数或截止时间;达到上限或错误变化时应停止自动重试。


13. 指数退避与抖动

13.1 固定间隔的问题

大量客户端同时每秒重试,会形成惊群效应,让刚恢复的服务再次过载。

13.2 指数退避

1
delay = min(base × 2^attempt, max_delay)

例如:

1
1s → 2s → 4s → 8s

13.3 Jitter

加入随机抖动:

1
delay = random(0, min(base × 2^attempt, max_delay))

13.4 服务端提示优先

如果响应包含 Retry-After 或等价指示,应优先遵守。

13.5 不在 Skill 中重新实现 SDK 已有策略

Anthropic 官方 SDK 对部分临时错误已经默认进行有限指数退避重试。Skill 层若再次重试,可能出现次数相乘:

1
SDK 3 次 × Workflow 3 次 = 9 次调用

必须明确重试责任属于:

  • SDK 请求层;
  • Tool 层;
  • Skill 步骤层;
  • 整体任务层。

14. 重试前必须检查副作用

这是本章最重要的安全原则之一。

请求超时只代表客户端没有收到确定结果,不代表服务端没有执行。

1
2
3
4
5
6
7
Client sends create_issue
↓
Server creates issue
↓
Response lost
↓
Client sees timeout

如果直接重试,可能创建两个 Issue。

OpenAI 官方 Agent 恢复文档明确要求:失败的 Turn 可能已经修改文件或调用外部工具,重试前必须检查保存状态和已完成动作。

推荐模式:

1
2
3
4
5
6
failure / timeout
↓
query operation status
├── completed → reuse result
├── confirmed absent → safe retry
└── unknown → do not blindly retry non-idempotent action

15. Idempotency:安全重试的基础

幂等表示同一个逻辑操作执行多次,最终效果与执行一次相同。

15.1 较容易幂等

  • 读取资源;
  • 将字段设置为确定值;
  • 使用稳定键执行 upsert;
  • 生成到新临时路径。

15.2 通常非幂等

  • 发送邮件;
  • 创建资源;
  • 扣款;
  • 对计数器加一;
  • 追加日志或评论;
  • 触发外部任务。

15.3 Idempotency Key

同一逻辑操作的重试应复用同一幂等键:

1
run_id + step_id + target_id

每次重试都生成新键会失去幂等保护。

15.4 服务不支持幂等键时

1
2
3
4
5
生成稳定业务标识
→ 操作前查询
→ 执行
→ 超时后按业务标识回读
→ 仅在确认未执行时重试

16. Fallback 与 Degradation 的区别

16.1 Fallback:替代实现

目标基本相同,实现路径改变:

1
2
3
Primary parser → General parser
Primary search source → Secondary trusted source
Live endpoint → Versioned snapshot

16.2 Degradation:降低交付等级

无法满足完整目标,交付较小但仍有用的成果:

1
2
3
无法生成图表 → 提供数据表
无法验证全部来源 → 标注未验证项
无法完成所有文件 → 交付成功列表与失败清单

16.3 Retry:路径不变

1
Tool A failed transiently → wait → Tool A again

因此:

1
Retry ≠ Fallback ≠ Degradation

17. Fallback Contract

每个 Fallback 至少说明:

17.1 Trigger

什么条件下启用:

1
primary tool unavailable after retry budget exhausted

17.2 Preconditions

替代方案自身需要什么:

1
cached data is not older than 24 hours

17.3 Capability Difference

它与主路径有什么差别:

  • 数据更新频率;
  • 字段完整度;
  • 精度;
  • 权限;
  • 成本;
  • 可验证性。

17.4 Output Label

最终结果怎样标注使用了 Fallback。

17.5 Validation

Fallback 结果需要独立的 Postcondition,不能因为它是“备用”就降低到没有验证。

17.6 Exit

Fallback 也失败时是再换路径、询问用户,还是停止。


18. Fallback 不是随意换工具

错误写法:

1
If Tool A fails, try any other available tool.

问题:

  • 另一个工具可能语义不同;
  • 数据来源可信度不同;
  • 返回字段不兼容;
  • 可能产生额外副作用;
  • 用户可能没有授权。

更好的写法:

1
2
3
4
If `primary_trace_parser` returns `UNSUPPORTED_VERSION`, use
`generic_trace_parser` only for event types listed in
`references/generic-parser-coverage.md`. Mark unsupported events as omitted,
and do not claim full trace coverage.

Fallback 必须是经过设计和测试的备用路径。


19. Fallback 优先级

多个备用路径可按质量排序:

1
2
3
4
5
6
7
8
9
Primary live API
↓ unavailable
Approved secondary API
↓ unavailable
Recent verified cache
↓ unavailable
Partial local analysis
↓ impossible
Ask / Stop

排序依据:

  • 正确性;
  • 数据新鲜度;
  • 安全性;
  • 授权范围;
  • 成本;
  • 延迟;
  • 用户目标。

不能只按“哪个还能调用”排序。


20. 透明 Fallback

最终结果应说明:

  • 主路径为什么不可用;
  • 启用了哪个替代方案;
  • 替代结果的时间和来源;
  • 覆盖、精度或能力损失;
  • 哪些结论因此不能成立;
  • 怎样获得完整结果。

示例:

1
2
3
实时指标接口在重试预算内持续超时。本报告改用 2026-10-07 02:00
生成的验证缓存,因此不包含 02:00 之后的数据。关于故障恢复时间的结论
无法确认,其余历史区间分析已通过同一 Schema 校验。

静默 Fallback 会让用户误认为结果来自主数据源。


21. Checkpoint 与 Resume

长循环应保存检查点,避免失败后从头重复。

21.1 检查点内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"run_id": "run_20261007_001",
"stage": "evidence_collection",
"iteration": 3,
"completed_items": ["claim-1", "claim-2"],
"pending_items": ["claim-3"],
"cursor": "page-token-8",
"artifacts": {
"evidence_matrix": "artifacts/evidence.json"
},
"side_effects": [],
"remaining_budget": {
"iterations": 2,
"tool_calls": 5
}
}

21.2 Resume 前验证

  • 检查点版本兼容;
  • 输入未改变;
  • 中间产物完整;
  • cursor 仍有效;
  • 外部状态未使计划失效;
  • 原授权仍适用。

21.3 只继续未完成工作

OpenAI 官方恢复指导建议在已有 Session 中请求继续未完成部分,而不是让 Agent 重复整个 Turn。


22. Partial Success:循环中的部分完成

批量任务可能是:

1
2
3
4
5
20 个文件
├── 17 complete
├── 1 retryable failure
├── 1 unsupported
└── 1 waiting for user input

不要用单个布尔值表示整体状态。

1
2
3
4
5
6
7
{
"status": "partial_success",
"completed": 17,
"retryable_failed": 1,
"unsupported": 1,
"waiting_for_input": 1
}

恢复时只处理未完成集合,并对已经完成的副作用去重。


23. 修复、重试、Fallback、询问、停止的决策树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Failure
│
├── Invalid input?
│ ├── safely fixable → fix → validate → retry
│ └── user information needed → ask
│
├── Auth / permission / budget?
│ └── stop automatic retry → report required action
│
├── Transient?
│ ├── side effect confirmed absent / idempotent
│ │ └── bounded backoff retry
│ └── side effect unknown and non-idempotent
│ └── inspect or ask; do not blind retry
│
├── Primary path unavailable?
│ ├── approved fallback exists → fallback → validate → disclose
│ └── no approved fallback → stop
│
└── Semantic validation failure?
├── targeted repair possible → fix loop
├── acceptable degradation → disclose and deliver partial result
└── otherwise → stop

24. 一份完整的 SKILL.md 模板

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
35
36
37
38
39
40
41
42
43
44
45
46
47
## Loop policy

For every loop, define:
- initial state;
- per-iteration action;
- progress measure;
- success condition;
- iteration, time, tool-call, and cost limits;
- no-progress condition;
- checkpoint and exit behavior.

Never use an unbounded “repeat until successful” instruction.

## Retry policy

- Classify the error before retrying.
- Retry only: `rate_limited`, `timeout`, `service_unavailable`.
- Honor `Retry-After`.
- Use exponential backoff with jitter.
- Maximum attempts: 3.
- Stop if the error changes.
- Account for retries already performed by the SDK.
- Before retrying a write, confirm its outcome or guarantee idempotency.

## Fallback policy

Primary: [path A]

Use fallback [path B] only when:
- [explicit trigger]; and
- [fallback preconditions].

Differences:
- [freshness / coverage / precision / side-effect difference].

After fallback:
- run [validation];
- label the result as fallback-derived;
- disclose limitations;
- stop if [fallback failure condition].

## Recovery

- Resume from the latest validated checkpoint.
- Revalidate external state and authorization.
- Execute only unfinished work.
- Rerun affected postconditions and final checks.

25. 完整示例:Performance Analysis Skill

25.1 证据收集循环

1
2
3
4
5
6
7
8
9
10
For each unresolved root-cause question:
1. Select one missing evidence type.
2. Query the corresponding read-only tool.
3. Normalize and deduplicate results.
4. Update the evidence matrix.

Stop successfully when every high-priority hypothesis is supported, contradicted,
or explicitly marked unknown.

Stop without success after four rounds, 12 tool calls, or two no-progress rounds.

25.2 Tool Retry

1
2
3
4
5
6
7
8
On rate limit, overload, or transient timeout:
- inspect whether the query or action already completed;
- honor Retry-After;
- retry at most twice;
- stop if the error code changes.

Do not retry invalid trace IDs, unsupported formats, permission errors, or empty
results using the same unchanged request.

25.3 Parser Fallback

1
2
3
4
5
Use `scripts/parse_trace.py` as primary.

If it returns `UNSUPPORTED_TRACE_VERSION`, use
`scripts/parse_trace_generic.py` only when the trace contains the documented
common event subset. Record omitted event types and reduce coverage confidence.

25.4 Report Fix Loop

1
2
3
4
5
6
7
8
Run `scripts/validate_report.py`.

If validation fails:
1. Fix only the reported violations.
2. Rerun the complete validator.
3. Stop after three failed validation rounds or when the same error repeats.

Never deliver a report labeled complete when mandatory validation still fails.

26. 可观测性

每轮循环和重试应记录:

  • run_id;
  • 阶段;
  • iteration / attempt;
  • 输入摘要;
  • 错误码;
  • 进度指标;
  • 等待时间;
  • 剩余预算;
  • Fallback 原因;
  • 副作用状态;
  • 退出原因。

示例:

1
2
3
4
5
6
7
8
9
10
{
"event": "retry_scheduled",
"run_id": "run_42",
"step": "metric_query",
"attempt": 2,
"error_code": "rate_limited",
"delay_seconds": 30,
"remaining_attempts": 1,
"side_effect_status": "none"
}

记录 request ID 便于定位持续性错误,但不要记录凭据和不必要的敏感数据。


27. 如何测试循环

27.1 成功退出

检查完成条件满足后是否立即退出,不再产生额外调用。

27.2 预算退出

目标始终不能满足时,是否在最大轮数、时间或成本处停止。

27.3 无进展退出

连续返回重复结果时,是否检测到没有新信息。

27.4 状态前进

分页 cursor、待处理集合和验证错误数量是否按预期变化。

27.5 恢复

在第 N 轮中断后,是否从检查点继续,而不是从头重复。

27.6 重复检测

是否正确去重来源、对象和副作用。


28. 如何测试 Retry 与 Fallback

28.1 错误分类

  • 400 输入错误不应退避重试;
  • 401/403 不应自动重试;
  • 临时 429 应遵守等待提示;
  • 额度型 429 不应持续重试;
  • 5xx 和超时进入有限重试;
  • 未知错误安全停止。

28.2 重试预算

  • 最大次数精确生效;
  • 总时长截止生效;
  • 错误变化立即停止;
  • SDK 与 Skill 重试没有意外相乘。

28.3 副作用

  • 服务端成功但响应丢失;
  • 回读显示已创建;
  • 同一幂等键重复调用;
  • 状态未知且操作非幂等。

28.4 Fallback

  • 主路径临时失败但重试后恢复,不应过早 Fallback;
  • 主路径确定性不支持,应直接走批准的 Fallback;
  • Fallback 覆盖不足时应降级置信度;
  • Fallback 失败时应停止;
  • 最终输出必须披露替代路径。

28.5 恢复后验证

无论 Retry 或 Fallback 返回成功,都必须重新执行对应 Postcondition 和 Final Check。


29. 常见错误

29.1 无限循环

1
repeat until successful

没有预算和停止条件。

29.2 目标条件主观

1
search until it looks complete

无法测试。

29.3 所有错误统一重试

权限、输入和额度问题不会因等待自动消失。

29.4 超时后直接重做写操作

可能制造重复副作用。

29.5 忽略 SDK 自带重试

导致实际调用次数远高于 Skill 声明。

29.6 Fallback 没有明确触发条件

模型可能过早放弃主路径或随意换工具。

29.7 静默 Fallback

用户无法判断数据新鲜度、精度和来源变化。

29.8 Fallback 不做验证

备用路径也可能产生错误或不兼容结果。

29.9 恢复后重新执行已完成工作

浪费资源,并可能重复外部动作。

29.10 把部分成功压成成功或失败

前者隐瞒缺口,后者丢弃已经验证的成果。

29.11 错误变化后仍沿用原重试循环

恢复策略已经失效,需要重新分类。

29.12 达到预算后强行给出确定结论

预算耗尽只说明必须停止,不代表证据已经充分。


30. 博客总结

Loop、Retry 和 Fallback 分别解决不同问题:

1
2
3
4
5
6
7
8
Loop
→ 多轮执行以达到完成条件

Retry
→ 临时失败后重试同一逻辑操作

Fallback
→ 主路径不可用时采用经过批准的替代路径

OpenAI 官方错误恢复文档强调:重试临时失败前要检查保存状态和已完成副作用,遵守 Retry-After,并设置尝试次数或截止时间。Anthropic 官方文档则明确了工具 Agent Loop 的停止原因、结构化错误反馈、指数退避以及 SDK 已有重试行为。

请记住:

  • 每个循环都有初始状态、进度指标、成功条件和终止条件;
  • 预算耗尽不等于成功;
  • 只有可能变化的错误才适合重试;
  • 重试前先检查副作用;
  • 非幂等写操作不能盲目重做;
  • Fallback 是设计好的替代路径,不是随便换工具;
  • Fallback 的质量损失必须透明;
  • Resume 只继续未完成工作;
  • Retry 或 Fallback 后必须重新验证。

31. 学完检查题

  1. Loop、Retry 和 Fallback 的区别是什么?
  2. Loop Contract 包含哪七个元素?
  3. 目标、预算和无进展终止条件分别解决什么问题?
  4. 为什么 until good enough 不是可靠终止条件?
  5. 哪些错误通常可以重试?
  6. 为什么 429 不能一律按短期限流处理?
  7. Retry Budget 至少包含哪些字段?
  8. 为什么需要指数退避和 Jitter?
  9. 超时后为什么不能直接重复写操作?
  10. Idempotency Key 应该在每次重试时变化吗?
  11. Fallback 与 Degradation 有何区别?
  12. Fallback Contract 应包含什么?
  13. Checkpoint 恢复前要重新检查什么?
  14. 为什么恢复成功后仍要重新执行 Final Check?

32. Skill 专项复盘

32.1 这个逻辑应该写在 SKILL.md 还是 reference?

循环主干、停止条件、重试预算、Fallback 触发和失败出口写入 SKILL.md;平台错误码表和大型兼容矩阵可放 reference。

32.2 这个步骤应该交给 LLM 还是 script?

错误分类中的固定规则、预算计数、退避和去重应由代码保障;LLM 可以评估语义证据是否充分、生成修复方案和解释降级影响。

32.3 这个能力应该是 Skill 还是 Tool?

Retry 和 Fallback 的业务策略属于 Skill;Tool 应返回结构化错误、幂等能力和操作状态。不要让 Tool 隐藏无限重试。

32.4 什么条件下应该触发这个 Skill?

Skill 仍由用户目标触发;Loop、Retry 和 Fallback 是 Skill 内部在执行状态、错误类别和证据缺口满足条件时启用的控制流。

32.5 如何证明这个 Skill 比没有 Skill 更好?

测量完成率、平均尝试次数、无进展循环率、重复副作用率、Fallback 正确率、透明披露率、恢复成功率和成本上限遵从率。


33. 本章实践

为一个证据研究 Skill 设计:

  1. 一个最多五轮的搜索循环;
  2. 一个“两轮无新增证据”终止条件;
  3. 一个按 URL 与 claim 去重的状态集合;
  4. 一个 3 次尝试、90 秒截止的 Retry Budget;
  5. 一组 retryable 与 non-retryable 错误;
  6. 一个遵守 Retry-After 的指数退避策略;
  7. 一个写操作超时后的状态确认路径;
  8. 一个主搜索服务到可信缓存的 Fallback Contract;
  9. 一个披露缓存时间和覆盖差异的输出模板;
  10. 一套包含死循环、错误变化、重复副作用和 Fallback 失败的测试。

下一章将严格按照大纲进入:

第 18 章:多个 Skill 如何组合与调用。


官方参考资料


Agent Skill 原理与工程实践(十七):循环、重试、Fallback 怎么设计
https://cj0510.github.io/2026/10/07/AI/Skill/17-循环重试Fallback怎么设计/
作者
CJ1018
发布于
2026年10月7日
许可协议
CC BY-NC-SA 4.0