单一模型家族:Qwen3.7-Plus
kira-agent 的所有 tier(lite / nova / ultra)都使用同一个模型 —— Alibaba Qwen3.7-Plus,直连 DashScope International(不走 Vercel AI Gateway)。
// src/ai/gateway.ts
const dashscope = createOpenAICompatible({
name: "dashscope",
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
apiKey: process.env.DASHSCOPE_INTL_API_KEY,
headers: {
"X-DashScope-DataInspection": '{"input":"disable","output":"disable"}',
},
transformRequestBody: (body) => ({ ...body, enable_thinking: true }),
});
export const QWEN_AGENT_MODEL_ID = "qwen3.7-plus";
export const qwenAgentModel = dashscope(QWEN_AGENT_MODEL_ID);
不是 grok / gpt-5 / xAI / OpenAI。lite、nova、ultra 三个 tier 全部解析到 qwenAgentModel(QWEN_AGENT_MODEL_ID = "qwen3.7-plus")。旧文档里”ultra=gpt-5.4 / lite=grok-4-1”的说法都已过时。
为什么直连 DashScope 而不走 Gateway
- 直连才能发
X-DashScope-DataInspection: {"input":"disable","output":"disable"} —— Vercel AI Gateway 不转发自定义 HTTP header,走 Gateway 无法关掉阿里云平台侧的内容审查。
enable_thinking: true 由 transformRequestBody 注入请求体(Qwen3 thinking 开关;qwen3.7-plus 默认开,这里显式置位与历史 Gateway 配置 alibaba.enableThinking 对齐)。
X-DashScope-DataInspection: disable 需要账号级权限,需在 staging 验证生效。
Tier 解析
// src/ai/agents/index.ts
export type KiraModel = "lite" | "nova" | "ultra";
export const DEFAULT_MODEL = QWEN_AGENT_MODEL_ID; // lite
const NOVA_MODEL = QWEN_AGENT_MODEL_ID;
const ULTRA_MODEL = QWEN_AGENT_MODEL_ID;
export function resolveBuildOptions(tier: KiraModel): BuildOptions {
if (tier === "ultra") return { modelName: ULTRA_MODEL, model: qwenAgentModel };
if (tier === "nova") return { modelName: NOVA_MODEL, model: qwenAgentModel };
return { modelName: DEFAULT_MODEL, model: qwenAgentModel };
}
| tier | 模型 | 备注 |
|---|
lite | qwen3.7-plus | 默认 |
nova | qwen3.7-plus | 仅 provider model id 相同;tier 本身仍区分(影响 video / image-edit 工具的 provider 选择,见下) |
ultra | qwen3.7-plus | 同上 |
三个 tier 的 LLM 完全相同,但 tier 仍会传给工具层影响 provider 路由 —— 例如 generateVideo 在 nova/ultra 用 WAN 2.7、lite 用 Seedance;imageEdit 在 ultra 走更高质量的 gpt-image-2 链路。详见 Tools。
Step Limit
agent loop 的硬上限是 10 步:
const STEP_LIMIT = 10;
// new ToolLoopAgent({ ..., stopWhen: stepCountIs(STEP_LIMIT) })
chat_completion.hit_step_cap(stepCount >= STEP_LIMIT)会上报,用来发现”撞到上限 / 卡住”的 run。
Plan 校验与降级
POST /task 拿到请求的 model(tier)后,先按用户 plan 做校验/降级,得到 effectiveModel:
// src/hono/agent/index.ts
const isMaxPlan = profile.plan?.startsWith("max"); // max / max_year
const isPremium = profile.plan?.startsWith("pro") || isMaxPlan; // pro / pro_year / max*
let effectiveModel: typeof model;
if (model === "ultra") {
effectiveModel = isMaxPlan ? "ultra" : "lite"; // ultra 仅 max plan,否则降 lite
} else {
effectiveModel = isPremium ? model : "lite"; // nova 需 pro+,否则降 lite
}
| Plan | 可用 tier |
|---|
free / basic / basic_year | lite |
pro / pro_year | lite、nova |
max / max_year | lite、nova、ultra |
规则:
ultra 仅当 plan 以 max 开头(max / max_year)才生效;否则降级为 lite。
nova 需 premium(plan 以 pro 或 max 开头);否则降级为 lite。
- 任何非 premium 用户最终都跑
lite。
plan 不足时静默降级到 lite,不报错。这意味着客户端请求的 tier 与实际运行的 tier 可能不同 —— 实际 tier(effectiveModel)体现在 PostHog chat_started / chat_completion 的 kira_model 字段。
Staff 覆盖
staff 用户(isStaffUser(userId))走 createStaffKiraAgent,可由 CMS 的 AgentModel 全局做 per-user LLM 覆盖。普通用户走同步、无 CMS fetch 的 createKiraAgent。覆盖后的真实 model id 体现在以同一 task_id 串联的 PostHog 事件上。
工具型 utility 模型(非 chat 主路径)
工具/handler 内部的一次性 generateObject / generateText(如 NSFW 判定、anime 判定)走另一个模型,不是 chat 主路径:
gemini-3.1-flash-lite,直连 Google Vertex(BYOK),location=global(区域 endpoint 对 gemini-3.1-* 返回 NOT_FOUND)。
- 通过
utilityObject / utilityText 调用,会发 PostHog sub_call 事件记 token。