Namespace Extension(命名空间扩展)
用 Provider 名字作为 key,将各 Provider 专有数据挂载在统一结构的命名空间下,实现零冲突的开放式扩展,无需修改核心接口。
定义
Namespace Extension(命名空间扩展)是一种接口扩展策略:核心接口预留一个 providerMetadata 或类似字段,每个 Provider 把自己专有的数据挂在以自己命名的 key 下,调用方通过命名空间前缀区分来源。
vercel/ai 中的实现
typescript
// LanguageModelV4GenerateResult
providerMetadata?: {
[provider: string]: Record<string, JSONValue>;
openai?: {
acceptedPredictionTokens?: number;
rejectedPredictionTokens?: number;
logprobs?: ...;
};
anthropic?: { ... };
}
OpenAI 的 acceptedPredictionTokens(预测缓存命中数)只在 OpenAI 实现里有意义,通过 providerMetadata.openai.* 透传到框架层,不污染标准 LanguageModelV4GenerateResult 接口。
设计价值
- 零冲突:每个 Provider 的数据在独立命名空间,不同 Provider 的同名字段不会互相覆盖
- 开放扩展:新 Provider 无需修改核心类型定义,直接在自己的命名空间下添加字段
- 向后兼容:
providerMetadata整体是 optional,不用 Provider 不受影响
与 Plugin System 的区别
Plugin System 通常需要注册中心和生命周期管理。Namespace Extension 是更轻量的模式——不需要注册,约定 key 即可,TypeScript 的 index signature 提供类型安全的开放式扩展点。
典型用途
- 框架核心接口需要支持 Provider 专有能力扩展
- 各 Provider 的专有字段数量不确定,且互不相关
- 调用方需要可选地访问 Provider 特定数据