公约
每个模块都遵循的共同规则:导入、结果元数据、传输契约、幂等与 BYOK。
导入模式
Python 暴露三个命名空间——ai、infra 与 account:
python
from infrai import infra, ai, account
infra.activate() # one-time onboarding (Python only)
ai.chat("hello") # ai.* namespace
infra.email.send(to="x@y.com", subject="Hi", body="...") # infra.* namespace
account.balance() # account.* namespaceTypeScript 使用单一客户端,其命名空间与模块一一对应:
typescript
import { InfraiClient } from "@infrai/sdk";
const client = new InfraiClient({ apiKey: process.env.INFRAI_API_KEY! });
await client.ai.chat({ messages: "hello" });
await client.email.send({ to: "x@y.com", subject: "Hi", text: "..." });
await client.account.balance();结果元数据
每次调用都会返回数据及一个元数据块,让 agent 无需再请求供应商即可读取成本与延迟。
python
result = ai.chat("Hello")
if result["_metadata"]:
print(result["_metadata"]["cost_usd"], result["_metadata"]["request_id"])cost_usd· 本次调用的美元成本,可与账单逐条对账。latency_ms· 端到端延迟(毫秒)。vendor· 实际服务本次调用的上游供应商。cache_hit· 响应是否来自缓存。request_id· 全局唯一 id(UUID v7),用于支持与对账。
传输契约
每个 SDK 都遵循相同的传输契约。若你直接调用 HTTP API,请遵循下列约定:
| 认证 | Authorization: Bearer <infrai_project_key> |
| 请求体 | 规范化 JSON:键排序、无空格、结尾换行、UTF-8。 |
| 幂等头 | Idempotency-Key |
| 请求 id | metadata.request_id (UUID v7) |
幂等
幂等让重试安全——在去重窗口内,同一 key 永不重复扣费、不重复创建资源。
- 读取(GET)调用默认幂等——无需传 key。
- 产生费用的调用会在服务端派生 key;推荐你主动传入。
- 资源创建类调用必须显式传入 idempotency_key。
python
# Cost-incurring calls: pass a key so retries never double-charge
infra.email.send(
to="customer@x.com",
subject="Order #123 confirmed",
body="...",
idempotency_key=f"order-confirmed-{order_id}",
)
# Resource creation requires a key
account.keys.create(label="prod", idempotency_key="bootstrap-prod-key-v1")当你在产生费用的调用中省略 key 时,服务端会确定性地派生一个:
text
idempotency_key = sha256(account_id + request_id + capability + content_hash)默认去重窗口为 24 小时(最短 1 小时,最长 7 天)。窗口内重复请求会返回原始结果且不再扣费。
BYOK(自带密钥)
注册你自己的供应商凭证,让调用通过你的密钥而非共享池分发。
python
# Register your own vendor key; calls dispatch through it
account.byok.register(
provider="openai",
alias="prod-gpt4o",
credentials={"api_key": "sk-..."},
idempotency_key="byok-openai-prod-v1",
)
account.byok.list()
account.byok.test(id="byok_01HX...")
account.byok.revoke(id="byok_01HX...")凭证只写不读:API 永不返回明文密钥,只返回一个可供你辨认的短指纹。