Appearance
模型失败、Fallback 与确定性测试
1. 为什么这组知识要一起学
理解 Harness 如何与模型交互:输入如何表示、输出如何结构化、不同 Provider 如何抽象,以及一次调用如何被测试和复现。
这几个知识点处在同一条工程链上。如果只记单个名词,很容易在真实系统里把责任放错层:例如让模型管理程序事实、让数据库 transaction 承担外部 API 原子性,或把一个 provider SDK 的行为误认为 Agent 的通用规律。
2. Mental Model
Model Layer 是 Harness 与模型厂商之间的 anti-corruption layer:内部只依赖稳定语义,provider 差异通过 capability 与 adapter 暴露。
text
Domain Request → ModelRequest → Provider Adapter → Provider API/Stream → Normalized Items → Validation → Runtime3. 核心机制
Model Error Taxonomy
模型层错误至少分 transport、rate-limit、timeout、context overflow、invalid output、provider unavailable 与 semantic failure。只有部分错误适合自动重试。
Model Routing / Fallback
路由应根据 task class、质量阈值、延迟和成本选择模型,并通过 eval 验证。简单按 token 长度路由通常不足以代表任务难度。
Fake Model / Deterministic Runtime Testing
Scripted/Fake Model 用预设 output item 驱动真实 Runtime,可以稳定测试工具、handoff、retry、session 与 streaming;真实模型行为则留给 integration/eval。
4. 最小实现 / 伪代码
下面代码只表达边界和生命周期,不要求照抄到项目中:
python
class ModelClient(Protocol):
async def generate(self, request: ModelRequest) -> ModelResponse: ...
class ScriptedModel:
def __init__(self, outputs): self.outputs = iter(outputs)
async def generate(self, request): return next(self.outputs)真正实现时应把 I/O、状态持久化、错误翻译和策略注入拆成可测试组件,而不是把示例扩成一个巨型函数。
5. 在 Shadow Harness 中怎么落地
定义 ModelClient、ModelRequest、ModelResponse、Usage、OutputItem、Capabilities 与 ScriptedModel;业务层不直接传 provider SDK object。
建议为本章涉及的行为留下明确的 domain object、interface 和 trace event;只要一个关键行为只能通过读日志猜测,就说明 Runtime contract 仍不够清晰。
6. Production Engineering 检查项
- 结构合法不等于语义正确
- streaming 必须有终止/取消语义
- 记录 provider/model/settings 进 Run Manifest
- 按错误类别决定 retry/fallback
7. Failure Modes
7.1 SDK 类型泄漏到全项目
当出现「SDK 类型泄漏到全项目」时,对照 normalized request/response、capability matrix、provider raw response 与 schema/domain validation 分层定位。 这类问题通常需要修改 contract、policy、state 或 adapter,而不是只追加 Prompt。
7.2 过度抽象成最低公分母
当出现「过度抽象成最低公分母」时,对照 normalized request/response、capability matrix、provider raw response 与 schema/domain validation 分层定位。 这类问题通常需要修改 contract、policy、state 或 adapter,而不是只追加 Prompt。
7.3 把 JSON 可解析当作 schema 合法
当出现「把 JSON 可解析当作 schema 合法」时,对照 normalized request/response、capability matrix、provider raw response 与 schema/domain validation 分层定位。 这类问题通常需要修改 contract、policy、state 或 adapter,而不是只追加 Prompt。
7.4 真实模型参与 Runtime 单元测试导致不稳定
当出现「真实模型参与 Runtime 单元测试导致不稳定」时,对照 normalized request/response、capability matrix、provider raw response 与 schema/domain validation 分层定位。 这类问题通常需要修改 contract、policy、state 或 adapter,而不是只追加 Prompt。
8. Trade-offs
直接 SDK 最快但耦合高;完全统一抽象会损失特性;Common Contract + Capability Detection 通常更平衡。
设计记录最好明确:当前约束是什么、备选方案有哪些、为什么现在选这个、未来什么条件出现时需要重构。 这样 ADR 才能随着模型和基础设施变化被重新审视。
9. Experiment / Evaluation
用 ScriptedModel 固定输出,覆盖 final/tool-call/invalid-schema/rate-limit/stream-cancel 场景;再用 integration test 验证真实 provider。
实验应固定数据集、版本和环境,至少记录 success、latency、token/cost、attempt/step 数以及失败类型;涉及随机模型时需要重复运行而不是只看一次结果。
10. 常见问题
基础:Model Error Taxonomy 最容易被误解的点是什么?
模型层错误至少分 transport、rate-limit、timeout、context overflow、invalid output、provider unavailable 与 semantic failure。只有部分错误适合自动重试。
机制:这些能力在一次 Run 的哪个生命周期阶段生效?
沿着 Domain Request → ModelRequest → Provider Adapter → Provider API/Stream → Normalized Items → Validation → Runtime 找位置,并明确它的输入、输出、持久化事实和失败传播。
工程:如果这一层失败,应该由谁恢复?
先区分 transient failure、invalid input、permission、semantic failure 与 irreversible side effect。恢复策略属于拥有该状态与副作用的 Runtime/adapter,而不是交给模型自由决定。
设计:规模扩大 10 倍后,哪个假设最先失效?
优先检查 context/token、并发/连接池、catalog 大小、持久化吞吐、trace 体积、身份与租户隔离。不要默认“多加机器”能解决语义和一致性问题。
11. Sources
- OpenAI Agents SDK — Models
- OpenAI Agents SDK — Running agents
- OpenAI Agents SDK — Testing
- OpenAI Agents SDK — Results
12. 本文结论
掌握本文的标准不是能背定义,而是能画出数据流、写出最小 contract、解释失败恢复,并用测试或 benchmark 证明设计没有只停留在概念层。