mcpField
A
ai-model-web

ai-model-web

github.com/tencentcloudbase开发79916 次安装今天更新
代码仓库

关于 ai-model-web

面向使用 CloudBase 的 Web 开发者,指导通过 @cloudbase/js-sdk 在浏览器中调用 AI 模型并流式呈现结果。它还规定了调用前的资源包资格和模型组就绪检查。

主要功能

  1. 01从浏览器调用 AI 模型
  2. 02流式生成文本响应
  3. 03检查 Token Credits 资格
  4. 04核验并启用模型组与模型

适用场景

  1. 01为 Web 应用添加文本生成
  2. 02在页面中流式显示模型输出
  3. 03调用 Hunyuan、DeepSeek 或 GLM

MCP 相关

该技能要求生成 SDK 代码前使用 MCP 工具检查环境、Token Credits 资源包和模型组状态;必要时通过工具启用模型。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tencentcloudbase/skills --skill ai-model-web

安装后在 Claude Code 中输入/ai-model-web确认已加载。

附带文件LICENSE.md

详细介绍

同级技能(仅限本地)

同级 CloudBase 技能与此技能一同发布。请使用 ../auth-tool-cloudbase/SKILL.md 这样的本地相对路径。

如果此环境中缺少引用的同级技能文件,请让用户安装完整的 CloudBase 插件(或缺失的技能)。不要通过 HTTP 将远程技能或协议 Markdown 获取到 Agent 上下文中。

何时使用此技能

当需要通过 @cloudbase/js-sdk 在浏览器/Web 应用中调用 AI 模型时,请使用此技能。

🧭 Web 的默认运行平面。 只要用户的请求涉及页面、Web 应用、前端、React/Vue/Next/Nuxt、仪表盘 UI,或“为我的 H5 添加 AI”,此技能就是默认路由目标。不要先建议使用 Node.js / 云函数 / CloudRun 代理;@cloudbase/js-sdk 可以直接从浏览器调用模型。只有当用户明确要求后端/服务端调用、图像生成,或确实需要服务端密钥或长时间运行的工作时,才切换到 ai-model-nodejs。此判断与用户选择的具体模型无关——模型名称(deepseek-*、glm-*、hunyuan-*、kimi-* 等)只影响 model 字段,不影响路由平面。

在以下情况下使用:

  • 将 AI 文本生成集成到前端 Web 应用中
  • 流式传输 AI 响应,以提供更好的用户体验
  • 从浏览器调用 Hunyuan / DeepSeek / GLM / Kimi / MiniMax 模型

以下情况不要使用:

  • Node.js 后端或云函数 → 使用 ai-model-nodejs 技能
  • 微信小程序 → 使用 ai-model-wechat 技能
  • 图像生成 → 使用 ai-model-nodejs 技能(仅限 Node SDK)
  • 不支持 CloudBase SDK 的运行时(原生应用、Python、Go 等)→ 使用 http-api-cloudbase 技能(现在包含可直接进行 HTTP 调用的 ai_model OpenAPI 规范;不要构建自定义 HTTP 代理)

⛔ 停止 — ai.createModel(...) 参数不是供应商/模型名称

编写任何 createModel(...) 代码行之前,请先阅读此内容。Agent 为此 SDK 生成代码时,最常见的错误就是臆造该参数。合法形式恰好有四种,其他任何形式都是错误。

✅ 合法的 ai.createModel(...) 参数使用时机
"cloudbase"新项目使用的主要托管组(由 TokenHub 支持,包含多个供应商的模型池)。供应商和具体模型应填写在 generateText / streamText 的 model 字段中,例如 { model: "deepseek-v4-flash" }。默认不会启用任何模型——请务必先检查 DescribeAIModels;如果目标模型不存在,请先使用 UpdateAIModel 启用该模型,再调用 SDK。
"hunyuan-v3"即将退役的旧版套餐组。 仅提供 hy3,平台不会再向其中添加新模型。现有代码仍可正常运行——新代码应使用 cloudbase + { model: "hy3" }。
"hunyuan-exp"仅当 DescribeAIModels 明确返回此环境的旧版内置组时使用。其原始默认模型 hunyuan-2.0-instruct-20251111 已下线(2026-05-31)——切勿使用此 ID。
"custom-<your-name>"通过 CreateAIModel 注册的用户自定义 GroupName。必须以 custom- 开头(例如 custom-kimi、custom-openai-compat)。
❌ 不要编写以下任何内容——它们全都不正确
ai.createModel("deepseek")                 // wrong — that's a vendor, not a GroupName
ai.createModel("deepseek-v4-flash")        // wrong — that's a model name, goes in the `model` field
ai.createModel("hunyuan")                  // wrong — vendor family, not a GroupName
ai.createModel("hunyuan-2.0-instruct-20251111")  // wrong — model name
ai.createModel("glm") / ai.createModel("kimi") / ai.createModel("minimax")  // wrong — vendor names
ai.createModel("openai") / ai.createModel("moonshot")  // wrong — vendor names
ai.createModel("custom")                   // wrong — placeholder; use your real custom-<name>
ai.createModel(modelName)                  // wrong — do not reuse the variable that holds the model id
✅ 正确模式——GroupName 和 Model 是两个不同的字段
const model = ai.createModel("cloudbase");          // ← GroupName
await model.generateText({
  model: "deepseek-v4-flash",                       // ← concrete model id
  messages: [...]
});
决策流程(用户指定具体模型时)
  1. 用户说“使用 DeepSeek v3.2”/“使用 hunyuan instruct”/“使用 Kimi k2.6”/“使用 GLM-5”/……
  2. createModel("cloudbase") 保持不变。
  3. 将模型 ID 填入 model 字段:{ model: "deepseek-v3.2" }、{ model: "hy3" }、{ model: "kimi-k2.6" }、{ model: "glm-5" }、……
  4. 切勿假设模型已启用。 编写 SDK 调用前,请确认它存在于 DescribeAIModels({ GroupName: "cloudbase" }).Models[] 中。如果不存在,请调用 DescribeManagedAIModelList,确认平台支持的准确 Model 名称(区分大小写——不要猜拼写),然后通过 UpdateAIModel 并设置 Status: 1 启用它(请记住,Models 会整体替换,因此要重新传入所有已启用的模型以及新模型)。

如果你正准备输入 ai.createModel(,且括号内是供应商名称、模型名称或猜测值——请停下。它几乎肯定不属于上述四个合法值之一。


强制双步骤预检(任何 SDK 代码之前)

生成任何与 AI 相关的 SDK 代码之前,先运行双步骤预检:①资格确认,②分组就绪检查。直接输出 createModel(...) 并让用户自行排查运行时错误,代价要高得多。

步骤 0:获取环境 ID

调用 MCP 工具 queryEnv,参数为 action=info,并从响应中读取 EnvId。所有后续检查和购买链接都要使用此 EnvId。


预检 ① — 资格确认(Token Credits 资源包)

调用 MCP 工具:

callCloudApi(service="tcb", action="DescribeEnvPostpayPackage", params={ EnvId })

通过条件(必须全部满足):

  • envPostpayPackageInfoList 至少包含一项

  • 该项的 postpayPackageId 以 pkg_tcb_tokencredits_ 开头

  • 该项的 status 不在 [3, 4] 中(3 / 4 通常表示已过期/已禁用;以实时响应为准)

  • ❌ 未满足 → 停止编写代码,并向用户说明以下内容(将 {envId} 替换为实际 ID):

    当前环境没有有效的 Token Credits 资源包。请先购买,然后再调用任何 AI API: https://buy.cloud.tencent.com/lowcode?buyType=resPack&envId={envId}&resourceType=token

    完成后请告知我,我会重新检查资源包状态。

  • ✅ 已满足 → 继续进行预检 ②。

按照约定,参数名使用 PascalCase。如果调用返回 InvalidParameter,则回退为 camelCase(envId / envPostpayPackageInfoList),并以实时响应为准。对于小程序场景,还存在一个额外的成长计划分支——请切换到 ai-model-wechat 技能。


预检 ② — 分组就绪情况(DescribeAIModels → 如有需要则调用 UpdateAIModel)

仅符合资格还不够。暂时不要调用 createModel("cloudbase")。 首先确认目标 GroupName 在环境中存在且 Status=1,并且目标 Model 已包含在其 Models[] 中。

  1. 列出当前环境中已配置的分组:

    callCloudApi(service="tcb", action="DescribeAIModels", params={ EnvId })
    

    返回 AIModelGroups: AIModelGroup[],其中每个 AIModelGroup 都包含 GroupName、Type(builtin / custom)、Models: [{ Model, EnableMCP, Tags }]、Status(1 = 开启 / 2 = 关闭)、BaseUrl、Secret、Remark。主要托管 GroupName 为 cloudbase。

  2. 切勿假设模型已启用。 检查 cloudbase 分组的 AIModelGroups[?].Models[].Model。如果目标模型缺失(或者用户未指定模型时,你打算默认使用的模型,例如 deepseek-v4-flash),请跳转到第 4 步并启用它——暂时不要调用 createModel("cloudbase")。如果 cloudbase 分组本身不存在或其 Status=2,也请跳转到第 4 步。

  3. 用户请求的模型属于托管目录(例如 deepseek-v3.2、hy3、glm-5、kimi-k2.6、……):检查该 Model 是否已在 cloudbase 分组的 Models[] 中。如果不在,请跳转到第 4 步。不要猜测准确的模型 ID——请先通过 DescribeManagedAIModelList(第 4 步涵盖此操作)核实规范拼写。

  4. 启用 / 添加托管模型(务必先查看权威目录和价格):

    callCloudApi(service="tcb", action="DescribeManagedAIModelList", params={ EnvId })
    

    返回 ManagedAIModelGroup[],其中每个分组都列出 GroupName(例如 cloudbase)、Remark 和 Models: [{ Model, EnableMCP, ModelSpec{ContextLength, MaxInputToken, MaxOutputToken}, ModelChargingInfo[{Type, InputPrice, OutputPrice, InputOutputUnit, CachePrice}] }]。这是受支持模型名称和价格的唯一权威来源——不要凭记忆推断。调用 UpdateAIModel 时,请使用此处返回的准确 Model 字符串。 启用前还应向用户展示价格。

    然后启用模型(注意:Models 会完整替换现有列表——务必连同新模型一起重新提交已启用的模型):

    callCloudApi(service="tcb", action="UpdateAIModel", params={
      EnvId,
      GroupName: "cloudbase",
      Models: [
        // resend every model that DescribeAIModels already showed as enabled
        { Model: "<already-enabled model, e.g. deepseek-v4-flash>" },
        // append the newly-requested one, using the exact spelling from DescribeManagedAIModelList
        { Model: "<target model>" }
      ],
      Status: 1
    })
    
  5. 请求的模型不在托管目录中(未被 DescribeManagedAIModelList 找到)→ 跳转到下一节,自定义接入(托管目录之外的模型)。

所有 Action 均使用 service=tcb、Version=2018-06-08。参数使用 PascalCase(EnvId / GroupName / Models / Status)。只有在调用返回 InvalidParameter 时才回退到 camelCase。


可用的提供商和模型

ai.createModel(<GroupName>) 只接受以下四类合法值:

1. "cloudbase" — 主要托管分组(推荐)
  • GroupName: "cloudbase"、Type: "builtin"、Remark: "腾讯云开发"(Tencent CloudBase)
  • 由 Tencent Cloud TokenHub 提供支持,这是一个统一的托管池,涵盖多个供应商——Hunyuan(HY 2.0 Instruct、HY 2.0 Think、Hunyuan-role、Hy3 preview、……)、DeepSeek(DeepSeek-V4-Pro、DeepSeek-V4-Flash、Deepseek-v3.2、Deepseek-v3.1、Deepseek-r1-0528、Deepseek-v3-0324、……)、Zhipu GLM(GLM-5、GLM-5-Turbo、GLM-5.1、GLM-5V-Turbo)、Kimi(K2.5、K2.6)、MiniMax(M2.5、M2.7)等。模型列表会不断更新——不要在应用代码中硬编码具体 SKU;请在运行时查询。
  • 默认情况下不会启用任何模型。 务必先调用 DescribeAIModels,查看环境中实际启用的模型;如果缺少目标模型,请调用 DescribeManagedAIModelList 获取权威目录和价格,然后调用 UpdateAIModel(Status: 1、完整替换 Models)启用该模型,再调用 SDK。
  • 权威目录和价格:DescribeManagedAIModelList
  • 环境中已启用的模型集合:DescribeAIModels
2. "hunyuan-v3" — 旧版计划组(正在退役)
  • 仅包含 hy3;该组不会新增模型,正逐步淘汰。迁移目标为 cloudbase + { model: "hy3" }
  • 现有代码仍可使用——不要将 createModel("hunyuan-v3")“修正”为 createModel("hy3");hy3 是模型 ID,不是 GroupName
  • 主要与小程序成长计划环境有关(参见 ai-model-wechat)
3. "hunyuan-exp" — 较旧的内置旧版模型组(为兼容性保留)
  • 除非环境明确仍返回该组,否则不要在 Web 中使用(此类流程请切换到 ai-model-wechat 技能)
  • 其原始默认模型 hunyuan-2.0-instruct-20251111 已于 2026-05-31 下线——绝不要指定该模型 ID。该组目前仍提供的模型,必须通过 DescribeAIModels({ GroupName: "hunyuan-exp" }).Models[] 获取
4. 用户自定义 GroupName
  • 通过 CreateAIModel 接入(参见下一节)。自定义 GroupName 必须以 custom- 开头(例如 custom-kimi、custom-moonshot、custom-openai-compat)。此命名约定可防止未来与平台可能逐步引入的内置 / 厂商 GroupName(cloudbase、hunyuan-exp、deepseek、glm、kimi、minimax,……)发生冲突
  • 示例:createModel("custom-kimi")、createModel("custom-openai-compat")

绝不要猜测并写出 createModel("deepseek") 或 createModel("custom"),除非 DescribeAIModels 明确返回了对应的 GroupName(旧环境可能仍保留历史上的内置 deepseek / hunyuan-exp 模型组——为兼容性仍可使用,但新项目应始终使用 cloudbase)。


自定义接入(托管目录之外的模型)

当用户想要调用非托管模型(自托管、企业内部模型、第三方 OpenAI 兼容端点,……)时,不要阻止。请引导他们完成接入:

选项 1:控制台流程(推荐,由用户自行处理)

https://tcb.cloud.tencent.com/dev?envId={envId}#/ai

选项 2:以编程方式接入(CreateAIModel)
callCloudApi(service="tcb", action="CreateAIModel", params={
  EnvId: "<envId>",
  GroupName: "custom-<your-name>",  // MUST start with "custom-" (e.g. custom-kimi, custom-openai-compat); never start with "cloudbase"
  BaseUrl: "<OpenAI-compatible endpoint, e.g. https://api.moonshot.cn/v1>",
  Models: [
    { Model: "<model name, e.g. kimi-k2.5>", EnableMCP: true }
  ],
  Remark: "<optional remark>",
  Status: 1,
  Secret: { ApiKey: "<vendor api key supplied by the user>" }
})

接入后,使用 DescribeAIModels 确认模型组已就绪,然后在代码中调用 ai.createModel("<the GroupName you just registered>")。使用 UpdateAIModel 添加 / 移除模型、轮换密钥或更改 BaseUrl(请记住,Models 会被完整替换)。使用 DeleteAIModel 移除自定义模型组(内置模型组无法删除)。

自定义模型的费用由第三方提供商收取,不会从 Token Credits 资源包中扣除。字段大小写遵循当前接口契约——遇到 InvalidParameter 时请改用驼峰命名。


安装

npm install @cloudbase/js-sdk

初始化

⚠️ 不要将匿名登录用作默认方式。 新环境默认禁用匿名登录,已有的不活跃环境也已自动禁用。即使手动启用了匿名登录,匿名用户默认也没有调用 AI 模型的权限。AI 模型技能不规定特定的登录界面——请将相关工作交由相应技能处理:

  • 启用 / 配置登录提供方(手机短信、电子邮件、微信开放平台、用户名+密码、OAuth 等)→ 遵循 auth-tool-cloudbase 技能(通过 callCloudApi 配置后端)。
  • 在浏览器中构建实际的登录流程(登录表单、回调、会话守卫)→ 遵循 auth-web-cloudbase 技能(使用 @cloudbase/js-sdk 认证 API,例如 signInWithPassword、signInWithPhone、getSession)。

AI 功能不要回退到 signInAnonymously()——匿名用户无法调用 AI 模型。仅在用户明确提出要求并接受这一取舍时,才将匿名登录用于非 AI 的只读演示。

import cloudbase from "@cloudbase/js-sdk";

const app = cloudbase.init({
  env: "<YOUR_ENV_ID>",
  accessKey: import.meta.env.VITE_PUBLISHABLE_KEY  // auto-provision via queryAppAuth / manageAppAuth, write to .env.local (see auth-web-cloudbase prerequisites)
});

const auth = app.auth;

// CRITICAL: Use auth.getSession() to check login — NOT the deprecated getLoginState().
// getLoginState() returns uid even without real login (just accessKey), causing false positives.
// getSession() returns data.session === undefined when no real login exists.
// Anonymous users are DENIED AI model permissions — calling AI without real login will fail.
const { data: sessionData } = await auth.getSession();
if (!sessionData?.session || sessionData.session.user?.is_anonymous) {
  // No real login or anonymous session — route to sign-in page
  window.location.href = "/login";
  return;
}

const ai = app.ai();

重要说明:

  • 使用顶层导入进行同步初始化
  • accessKey 会导致 getLoginState() 返回误导性的认证数据——已弃用的 getLoginState() 即使在未实际登录时也会返回带有 uid 的对象,这会导致简单的 !!loginState 检查失效。请改用 auth.getSession():在不存在实际登录时,它会返回 data.session === undefined,因此 !!data.session 是可靠的认证门控条件。
  • 使用 AI 功能前,用户必须通过已验证的登录方式(手机、电子邮件、微信、用户名+密码、自定义方式)完成认证。匿名用户没有 AI 模型权限。具体流程由 auth-web-cloudbase 技能负责。
  • 从 CloudBase 控制台获取 accessKey

generateText() — 非流式

前提条件: 已通过两步预检(资格检查 + 分组就绪检查),并已确认目标模型存在于 DescribeAIModels({ GroupName: "cloudbase" }).Models[] 中——如果模型不存在,则此时应已通过 UpdateAIModel 启用。以下示例仅以 deepseek-v4-flash 作说明;请替换为用户实际要求的模型。

const model = ai.createModel("cloudbase");

const result = await model.generateText({
  model: "deepseek-v4-flash",  // must already be enabled in this env (DescribeAIModels → UpdateAIModel)
  messages: [{ role: "user", content: "Give me a one-paragraph intro to Li Bai." }],
});

console.log(result.text);           // generated text string
console.log(result.usage);          // { prompt_tokens, completion_tokens, total_tokens }
console.log(result.messages);       // full message history
console.log(result.rawResponses);   // raw model responses

streamText() — 流式

前提条件: 已通过两步预检。

const model = ai.createModel("cloudbase");

const res = await model.streamText({
  model: "deepseek-v4-flash",
  messages: [{ role: "user", content: "Give me a one-paragraph intro to Li Bai." }],
});

// Option 1: iterate the text stream (recommended)
for await (let text of res.textStream) {
  console.log(text);  // incremental text chunks
}

// Option 2: iterate the data stream for full response chunks
for await (let data of res.dataStream) {
  console.log(data);  // full response chunk with metadata
}

// Option 3: access final results
const messages = await res.messages;  // full message history
const usage = await res.usage;        // token usage

错误处理模式

const model = ai.createModel("cloudbase");

try {
  const result = await model.generateText({
    model: "deepseek-v4-flash",
    messages: [{ role: "user", content: "Generate a concise onboarding checklist." }],
  });

  console.log(result.text);
} catch (error) {
  console.error("Failed to call CloudBase AI from Web", error);
}

类型定义

interface BaseChatModelInput {
  model: string;                        // required: model name
  messages: Array<ChatModelMessage>;    // required: message array
  temperature?: number;                 // optional: sampling temperature
  topP?: number;                        // optional: nucleus sampling
}

type ChatModelMessage =
  | { role: "user"; content: string }
  | { role: "system"; content: string }
  | { role: "assistant"; content: string };

interface GenerateTextResult {
  text: string;                         // generated text
  messages: Array<ChatModelMessage>;    // full message history
  usage: Usage;                         // token usage
  rawResponses: Array<unknown>;         // raw model responses
  error?: unknown;                      // error if any
}

interface StreamTextResult {
  textStream: AsyncIterable<string>;    // incremental text stream
  dataStream: AsyncIterable<DataChunk>; // full data stream
  messages: Promise<ChatModelMessage[]>;// final message history
  usage: Promise<Usage>;                // final token usage
  error?: unknown;                      // error if any
}

interface Usage {
  prompt_tokens: number;
  completion_tokens: number;
  total_tokens: number;
}

最佳实践

  1. 首先执行两步预检——① 资格检查(通过 DescribeEnvPostpayPackage 检查 Token Credits 资源包)+ ② 分组就绪情况检查(通过 DescribeAIModels 检查已启用的模型,通过 DescribeManagedAIModelList 获取权威的受支持模型目录;如果缺少目标模型,则使用包含完整替换内容的 Models[] 和 Status: 1 调用 UpdateAIModel)。跳过预检会直接导致运行时出现“找不到模型”/“模型未启用”错误。
  2. 切勿假定任何模型已启用——无论是 deepseek-v4-flash、hunyuan-*,还是其他模型。务必先通过 DescribeAIModels 验证;如果缺少目标模型,请在 DescribeManagedAIModelList 中查找准确的 Model 字符串(不要猜拼写或自行编造供应商前缀),然后调用 UpdateAIModel 启用该模型。
  3. createModel 只接受四种值——"cloudbase"(主托管分组)、"hunyuan-v3"(旧版计划分组,仅限 hy3,正在淘汰)、"hunyuan-exp"(较早的内置分组),或通过 CreateAIModel 注册的用户自定义 GroupName(必须以 custom- 开头,例如 custom-kimi、custom-openai-compat)。切勿使用 createModel("deepseek")/createModel("kimi")/createModel("custom") 进行猜测。
  4. 不要编造 SDK 方法名或参数。 本 SKILL.md 是 @cloudbase/js-sdk AI 接口的权威参考——编写代码前,请在此处(或下文的“类型定义”部分)查阅方法签名。如果此处没有记录某个方法或字段,请停下来询问,或通过 MCP 工具检查实时契约。不要猜测。
  5. 启用新的托管模型前先展示价格——DescribeManagedAIModelList 会返回 ModelSpec(上下文长度、最大输入/输出 Token 数)和 ModelChargingInfo(输入/输出/缓存价格、计费单位)。调用 UpdateAIModel 前,请向用户展示价格。
  6. 长回复使用流式传输——提升用户感知到的响应速度和交互体验。
  7. 妥善处理错误——使用 try/catch 包装 AI 调用。
  8. 妥善保管 accessKey——使用可公开的密钥,切勿使用秘密密钥。
  9. 尽早初始化——在应用入口处设置 SDK,确保路由前身份验证和 AI 均已就绪。
  10. AI 功能不要使用匿名身份验证——新环境默认禁用匿名登录,且匿名用户没有 AI 模型权限。调用任何 AI API 前,必须要求用户完成已验证的登录(手机号、电子邮件、用户名和密码、微信或自定义方式)。将供应商配置交由 auth-tool-cloudbase 技能处理,将浏览器登录流程交由 auth-web-cloudbase 技能处理;AI 模型技能会检查 auth.getSession() 并验证 loginType,再决定是否允许调用。
  11. 区分“预检失败”和“模型调用失败”——前者表示用户需要购买资源包或调用 UpdateAIModel;后者表示提示词/参数/网络问题。针对这两种情况向用户提供不同的指导。
  12. TypeScript:不要使用 any 来掩盖 SDK 类型错误。 SDK 自带类型定义;如果出现错误,请使用 unknown 和类型保护进行收窄,为实际使用的数据结构编写精确的 interface,或在本地 .d.ts 中扩展类型。切勿使用 : any、as any、@ts-ignore 或 @ts-nocheck。请参阅 web-development 技能中的 Engineering 宪章。
  13. 声称完成前先自行验证。 运行 tsc --noEmit 和项目构建,然后用 agent-browser 打开页面并实际触发 AI 调用。确认:(a) 文本流已显示在 UI 中;(b) 没有新增控制台错误;(c) result.usage 非零。没有证据就说“应该可以运行”是不可接受的——请遵循 web-development/browser-testing.md。

评论

支持 Markdown