Files
范智鹏 d6b8a3c897 feat: AI 调用稳定性增强(可重试错误分类 + 指数退避 + 修复链路错误透传)
- providers/base.ts 引入 ApiRequestError 与 isRetryableError,按 429/5xx/超时/网络错误/401 分类
- chatWithRetry 升级为最多 3 次指数退避(1s/2s/4s),非重试错误立即上抛;新增 setRetryBaseDelayForTest 钩子
- aiFixEngine/customFixEngine 不再吞错,修复失败原因透传为 ai-error: <原因>
- 扩展 ai-empty-response/customFixEngine 测试覆盖重试与分类
2026-08-31 21:57:54 +08:00

65 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 调用稳定性增强(重试 + 统一兜底)设计
日期:2026-08-29
状态:已批准(Stage ④ 通过)
## 背景与目标
评审报告「稳定性与易用性 12/15」指出:缺少显式重试机制;未见对 AI 调用异常的统一兜底。现状核实:
- `chatWithRetry`src/ai/engine.ts)仅对 `EmptyContentError` 重试 1 次,网络错误/超时/429/5xx 均直接上抛
- `requestFix`src/fix/aiFixEngine.tscatch 后静默返回 null,用户看不到 AI 失败原因
- engine 主入口已有 `degraded + error` 兜底结构(`Promise.allSettled` + i18n 错误聚合),无需改动
- 多 AI 供应商切换已被评审认可为降级策略,无需改动
## 方案
### 1. 错误分类(src/ai/providers/base.ts
新增 `ApiRequestError`(携带 HTTP status+ `isRetryableError()`
| 错误 | 可重试 |
|---|---|
| EmptyContentError | 是 |
| HTTP 429 / 5xx | 是 |
| 超时(AbortError / DOMException name==='AbortError' | 是 |
| 网络错误(TypeError | 是 |
| 401、其他 4xx、JSON 解析错 | 否,立即失败 |
### 2. provider 统一结构化抛错
openai-compatible.ts / gemini.ts / claude.ts:非 2xx 响应抛 `ApiRequestError`(携带 status 与响应文本)。401 保留现有 i18n 消息语义,同样结构化、不可重试。
### 3. chatWithRetry 增强(src/ai/engine.ts
固定策略:最多 3 次重试、指数退避 1s/2s/4s、按分类决定重试或立即上抛。所有调用入口(engine 三入口 + fix 链路)自动受益。
### 4. fix 链路兜底透传(src/fix/aiFixEngine.ts
`requestFix` 不再吞错,将最终错误消息透传到 `FixResult.message`,复用 commands.ts 现有 `t('fix.aiFailed')` 通知管道。
### 5. 单元测试
扩展既有 `tests/ai-empty-response.test.ts`chatWithRetry 测试的既有归属,避免新建文件):mock provider 抛可重试/不可重试错误,验证重试次数、退避行为、立即失败路径、`isRetryableError` 分类。`tests/customFixEngine.test.ts` 一处测试名随行为语义更新。
### 实现修订(编码期同步)
- `src/fix/customFixEngine.ts` 存在与 aiFixEngine 相同的吞错模式(同一评审批评点),按同一模式修复:`requestFix` 不再吞错,`aiFixReviewIssue` 调用处 catch 后透传 `ai-error: <原因>``FixResult.message`
- 引擎内部导出 `setRetryBaseDelayForTest` 测试钩子,避免测试真实等待 1s/2s/4s 退避
## 验证链
`npm run lint``npm run compile``npm test`
## 涉及文件
- src/ai/providers/base.ts
- src/ai/providers/openai-compatible.ts
- src/ai/providers/gemini.ts
- src/ai/providers/claude.ts
- src/ai/engine.ts
- src/fix/aiFixEngine.ts
- src/fix/customFixEngine.ts
- tests/ai-empty-response.test.ts
- tests/customFixEngine.test.ts