能力描述符
能力描述符在 CubePi 0.5 中引入。
本页介绍如何访问任意模型——大型 SaaS API、区域性端点、代码规划层级,或自托管的 vLLM 实例——而无需为每个厂商编写专属胶水代码。设计思路是循序渐进的:
- 默认零配置。 对于 Anthropic 和 OpenAI,只需创建 provider 和 model,本页的内容一概不需要。
- 对于非默认端点,以数据方式描述差异。
CapabilityDescriptor以声明式方式捕获差异——无需子类化,无需 fork。
CubePi 提供的是机制(CapabilityDescriptor 及其 wire 运行时),而非厂商目录。包含 base URL、认证、区域/代码规划端点、模型列表的现成 provider 列表属于产品数据,应由嵌入 CubePi 的应用自行维护(例如,cubebox 维护自己的 provider 目录)。如需接入特定厂商,请按下文所示,使用正确的 base_url + CapabilityDescriptor 构建 provider。
1. 简单场景——完全零配置
大多数用户无需关心能力描述符。内置 provider 已有合理的默认值:
import cubepi
from cubepi import Agent, Model
from cubepi.providers.anthropic import AnthropicProvider
agent = Agent(
provider=AnthropicProvider(), # reads ANTHROPIC_API_KEY
model=Model(id="claude-sonnet-4-6", provider="anthropic"),
)
await agent.prompt("Hello!")
这就是全部配置。不带 capability= 构建的 provider,其输出与 CubePi 0.4 完全一致——下文的机制仅在显式使用时才会生效。
2. 非默认端点——CapabilityDescriptor
当你需要使用 OpenAI 或 Anthropic 之外的模型——DeepSeek、Qwen、豆包、OpenRouter 路由、本地服务器——麻烦在于每家的 wire 方言不同(是用 max_tokens 还是 max_completion_tokens?如何开关推理?)。你不需要子类化 provider;只需将差异描述为一个 CapabilityDescriptor,连同正确的 base_url 和对应端点 wire 形状的 provider 类一起传入:
import os
from cubepi import CapabilityDescriptor
from cubepi.providers.openai import OpenAIProvider
provider = OpenAIProvider(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
capability=CapabilityDescriptor(
reasoning_off_payload={"extra_body": {"reasoning": {"exclude": True}}},
reasoning_on_payload={"extra_body": {"reasoning": {"exclude": False}}},
),
)
根据端点的 wire 方言选择 provider 类:
| Wire 方言 | Provider 类 |
|---|---|
anthropic-messages | AnthropicProvider |
openai-completions | OpenAIProvider |
openai-responses | OpenAIResponsesProvider |
每个字段对应一种 wire 行为,未设置的字段不产生任何影响——因此只需声明实际存在差异的部分。
max_tokens_field
"max_tokens"(默认)或 "max_completion_tokens"。部分 OpenAI 兼容服务器只接受其中一种拼写;此字段在请求发出前重命名该 key。效果: 选错会导致服务器忽略输出长度限制或返回 400。
temperature
TemperatureSpec 控制调用方传入的 temperature 如何处理:
from cubepi import TemperatureSpec
TemperatureSpec(mode="free", min=0.0, max=2.0, default=1.0) # clamp into [min, max]
TemperatureSpec(mode="fixed", fixed_value=1.0) # always overwrite
TemperatureSpec(mode="ignored") # drop the key
free—— 调用方的值被截断到[min, max]范围内;若未传入则不写入任何值。效果: 防止超出范围的值被后端拒绝。fixed—— 始终使用fixed_value。效果: 适用于只允许固定 temperature 的模型(如部分 o 系列推理模型)。ignored—— 完全去除该 key。效果: 适用于在推理时对任何temperature字段返回 400 的后端。
推理开关:reasoning_off_payload / reasoning_on_payload
关闭推理时,将 reasoning_off_payload 深度合并到请求中;开启时合并 reasoning_on_payload。效果: 这就是"开关推理"如何映射到厂商期望的字段:
CapabilityDescriptor(
reasoning_off_payload={"extra_body": {"enable_thinking": False}},
reasoning_on_payload={"extra_body": {"enable_thinking": True}},
)
合并会递归处理嵌套 dict;数组是原子的;冲突时 capability 值优先。
推理级别:reasoning_level(三种形状)
在开/关之外,CubePi 将 ThinkingLevel(off/minimal/low/medium/high/xhigh)映射到通过点路径 path 写入的具体 wire 值。kind 决定形状:
from cubepi import ReasoningLevelSpec
# int_budget — a token budget (Anthropic).
ReasoningLevelSpec(
path="thinking.budget_tokens", kind="int_budget",
level_budgets={"off": 0, "minimal": 1024, "low": 2048,
"medium": 8192, "high": 16384, "xhigh": 16384},
)
# effort — an effort string (OpenAI Responses).
ReasoningLevelSpec(
path="reasoning.effort", kind="effort",
level_to_effort={"minimal": "minimal", "low": "low",
"medium": "medium", "high": "high", "xhigh": "high"},
)
# enum — a vendor-specific state (Doubao's 3-state thinking).
ReasoningLevelSpec(
path="thinking.type", kind="enum",
level_to_enum={"off": "disabled", "low": "enabled", "high": "enabled"},
)
效果: 映射表中缺失的级别不会被写入,端点将保持该级别的自身默认值。
supports_tools / supports_images / supports_streaming
声明式标志,由宿主应用和前端读取(例如,用于置灰图片上传按钮)。provider 本身不依赖这些标志做行为控制。
共享端点上的按模型覆盖
一个网关(OpenRouter、LiteLLM、内部代理)通常同时服务推理型和非推理型模型。model_capability_overrides 将 model_id 映射到一个描述符,该描述符会替换该模型的基础描述符:
provider = OpenAIProvider(
api_key="…",
base_url="https://openrouter.ai/api/v1",
capability=base_cap, # default for unlisted models
model_capability_overrides={
"deepseek/deepseek-r1": reasoning_cap, # this model only
},
)
解析方式为对 model_id 精确匹配;未列出的模型回退到 capability。
参见
- OpenAI Provider —— OpenAI / OpenAI 兼容端点的具体配置。
- Anthropic Provider ——
int_budget推理形状的实际用法。 - 自定义 Provider —— 当端点甚至不是 OpenAI/Anthropic 形状时。
- API 参考 →
cubepi.providers。