Observed since 21 Oct, 10:07 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Relay-only model access SDK for AI Center applications (invocation binding, allowlist, stable errors)
Python 应用接入 AI Center 模型网关的最小 SDK。
Relay-only 合同(ADR-0015,2026-09-29 修订):应用不直连 LiteLLM,也不手工拼装归因。 部署时平台注入三元组环境变量,应用把模型请求发到平台 Relay,归因(spend logs metadata)由平台在转发时注入,ModelCall/Token/费用由 AI Center 对账生成。
| 环境变量 | 含义 |
|---|---|
AI_CENTER_MODEL_GATEWAY_URL_TEMPLATE | 含 {invocation_id} 占位符的 Relay 端点模板 |
AI_CENTER_RUNTIME_CREDENTIAL | per-Deployment 运行时凭据(随部署轮换) |
AI_CENTER_MODEL_OPERATIONS | 允许的 operation 白名单(逗号分隔;缺省一律拒绝) |
从仓库根目录执行(当前无需发布 PyPI):
uv pip install ./packages/ai-center-runtime
from ai_center_runtime import (
PlatformModelClient, PlatformModelError,
bind_invocation, model_access_mode,
)
# 1) 部署受理时把平台 Invocation 绑定到当前任务上下文(如异步 Job)。
binding = bind_invocation(platform_invocation_id)
try:
if model_access_mode() != "relay":
raise RuntimeError("平台模型访问未配置 Relay;direct 仅限本地开发")
# 2) 客户端读取三元组环境变量;白名单外的 operation 在发请求前失败。
with PlatformModelClient() as models:
answer = models.chat_completion(
[{"role": "user", "content": "你好"}],
model="deepseek-flash",
json_mode=True,
)
print(answer["choices"][0]["message"]["content"])
vectors = models.text_embeddings(["一段文本"], model="text-embedding")
finally:
binding.restore()
要点:
FastAPI 一行接入(可选依赖):同步接口不需要手写"读 header + bind + try/finally restore"——用依赖注入器,请求进入自动绑定、响应后自动解绑:
from fastapi import Depends
from ai_center_runtime import model_invocation, PlatformModelClient
@app.post("/extract")
async def extract(req: ExtractRequest, _b=Depends(model_invocation())):
# 本 handler 内的 Relay 调用自动携带 Invocation
with PlatformModelClient() as models:
return models.chat_completion([...], model="deepseek-flash")
安装:pip install 'ai-center-runtime[fastapi]'。缺
x-ai-center-invocation-id 头时返回 422;model_invocation(required=False)
放行无 Invocation 请求(调用点 fail-closed 不变)。
mode 三态,绝不回退:model_access_mode() 返回 relay / direct /
unconfigured;direct 只有应用显式设置 AI_CENTER_LLM_MODE=direct(本地开发)
时成立,平台从不注入它。
fail closed:白名单缺失或 operation 越界抛 MODEL_CAPABILITY_UNAVAILABLE;
未绑定 Invocation 抛 MODEL_INVOCATION_MISSING。构造
PlatformModelClient() 本身就是模式检查(未配置时构造即失败),无需再手写
mode 判断。
稳定错误:PlatformModelError.reason ∈ MODEL_CAPABILITY_UNAVAILABLE /
MODEL_INVOCATION_MISSING / MODEL_ACCESS_EXPIRED(异步窗口过期)/
MODEL_TIMEOUT / MODEL_UPSTREAM_ERROR;status 携带 HTTP 状态。
logical_call_id:默认按 {invocation_id}:{scope}:{sha256[:24]} 生成并经
x-request-id 透传;同一逻辑调用的重试应显式传同一个 logical_call_id。
OpenAI 兼容生态:relay_connection() 返回 {"base_url", "api_key"},
可直接喂给 openai.OpenAI(...)、llama_index OpenAI(...) 等。
InvocationContext / ModelClient 是直连 LiteLLM 时代的合同:平台已不再注入
LITELLM_BASE_URL / LITELLM_API_KEY,新应用禁止使用;它们仅为尚未迁移的
历史应用保留,迁移路径是把 InvocationContext.from_headers(...) +
ModelClient.from_runtime_context(...) 替换为 bind_invocation(...) +
PlatformModelClient(...)。
PlatformModelClient,
异步应用(FastAPI 路由、async Worker)用 AsyncPlatformModelClient,
两者接口语义一致。x-ai-center-* header。PYTHONPATH=packages/ai-center-runtime/src uv run --project packages/ai-center-runtime \
python -m unittest discover -s packages/ai-center-runtime/tests
协议测试通过 httpx MockTransport 校验三元组解析、模板物化、白名单 fail-closed、
错误映射与绑定隔离,不需要真实平台。真实链路探针见 scripts/smoke_relay.py。
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.0 | 8 Oct 2026 | 3 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 10:07 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:6d56012d70cba9de30bca2fae4a829e31b5cf204068790898c61fca9389cdd41