# wx.cloud.extend.AI

> 支持端：小程序、云函数

微信小程序基础库版本 `3.15.1` 及以上，支持通过微信云开发的 `wx.cloud.extend.AI` 扩展接口调用 cloudbase 提供的 DeepSeek、混元、Kimi、GLM、Minimax 等最新模型。

## 初始化

在使用 AI 相关能力前，需要传入云开发环境进行初始化。

```javascript
wx.cloud.init({
  env: "<你的环境ID>",
});
```

初始化完毕后，即可通过 `wx.cloud.extend.AI` 使用扩展接口来调用 AI 相关能力。

## 大模型

### AI.createModel()

创建指定的 AI 模型。

#### 使用示例

传入模型提供商字符串：

```js
const model = wx.cloud.extend.AI.createModel("cloudbase");
```

传入 `ModelDefinition` 对象（基础库 `3.15.1` 及以上支持）：

```js
const model = wx.cloud.extend.AI.createModel({
  modelName: "custom-model",
  modelPath: "/v1/chat/completions",
  extractPath: "choices[0].delta.content",
  reasoningPath: "choices[0].delta.reasoning_content",
});
```

#### 类型声明

```js
function createModel(model: string | ModelDefinition): ChatModel;

interface ModelDefinition {
  modelName: string;
  modelPath: string;
  extractPath: string;
  reasoningPath?: string;
}
```

#### 参数

| 参数名 | 必填 | 类型 | 说明 |
| ------ | ---- | ---- | ---- |
| model | 是 | `string \| ModelDefinition` | 模型名称字符串或模型定义对象 |
| model.modelName | 是 | `string` | 模型名称 |
| model.modelPath | 是 | `string` | 模型请求路径 |
| model.extractPath | 是 | `string` | 文本内容提取路径 |
| model.reasoningPath | 否 | `string` | 推理内容提取路径 |

返回一个提供 AI 生成文本能力的对象。

### ChatModel.streamText()

以流式调用大模型生成文本。流式调用时，生成的文本及其他响应数据会通过 [SSE](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) 返回，该接口的返回值对 SSE 做了不同程度的封装，开发者能根据实际需求获取到文本流和完整数据流。

#### streamText 使用示例

```js
// 连接模型提供商
const provider = wx.cloud.extend.AI.createModel("cloudbase"); 
const res = await provider.streamText({
  data: {
    model: "hy3-preview",
    messages: [
      {
        role: "user",
        content: "hi"
      }
    ]
  }
});

for await (let str of res.textStream) {
  // 打印生成的文本
  console.log(str); 
}
for await (let event of res.eventStream) {
  // 打印每次返回的完整数据
  console.log(event); 

  // 当大模型结束传输时，通常会发一条 [DONE] 数据，在此之后即可停止循环
  if (event.data === "[DONE]") {
    break;
  }
}
```

#### streamText 类型声明

```js
function streamText(props: StreamTextInput): Promise<StreamTextResult>;

interface StreamTextResult {
  eventStream: EventStream;
  textStream: TextStream;
}

interface StreamTextInput {
  data: unknown;
  onEvent?: OnEvent;
  onText?: OnText;
  onFinish?: OnFinish;
}

interface OnEvent {
  (prop: { data: string }): unknown;
}

interface OnText {
  (text: string): unknown;
}

interface OnFinish {
  (text: string): unknown;
}

interface EventStream {
  [Symbol.asyncIterator](): AsyncIterator<{
    event?: unknown;
    id?: unknown;
    data: string;
  }>;
}

interface TextStream {
  [Symbol.asyncIterator](): AsyncIterator<string>;
}
```

#### 参数

| 参数名 | 必填 | 类型               | 示例                                                                                       | 说明                                                                                                                                                                                                                                                                                     |
| ------ | ---- | ------------------ | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| props.data   | 是   | `unknown` | `{model: "deepseek-v4-flash", messages: [{ role: "user", content: "你好，请你介绍一下李白" }]}` | 各家大模型的调用参数不同，请根据实际调用模型传入正确的参数。 |
| props.tools   | 否   | `object` | -- | 工具调用相关参数 |
| props.tools.autoExecute   | 否   | `boolean` | `true` | 是否自动调用工具，默认为 `true` |
| props.tools.maxStep   | 否   | `number` | `10` | 最大自动执行的次数，默认为 10 次 |
| props.tools.list   | 否   | `Array` | -- | 工具列表 |
| `props.tools.list[n].name`   | 是   | `string` | `"get_weather"` | 工具名称 |
| `props.tools.list[n].description`   | 否   | `string` | `返回某个城市的某天的温度信息。调用示例：get_weather({city: '北京',date: '03-19'})` | 工具描述 |
| `props.tools.list[n].fn`   | 是   | `function` | `({ city, date }) => city + "在" + date + "的温度是：" + (20 + (Math.random() * 10))` | 工具执行的回调函数 |
| `props.tools.list[n].parameters`   | 否   | `{"type":"object","properties":{"city":{"type":"string","description":"要查询的城市"},"date":{"type":"string","description":"要查询的日期"}},"required":["city","date"]}` | -- | 工具执行回调函数的入参 schema 定义 |
| props.tools.onToolEvent   | 否   | `function` | `console.warn` | 监听大模型执行 tool_call 的事件 |
| props.onText   | 否   | `(text: string) => unknown;` | `(text) => console.log(text)` | 接收到新文本返回时触发的回调函数，参数为增量的文本 |
| props.onEvent   | 否   | `(prop: { data: string }) => unknown;` | `({data}) => console.log(data)` | 接收到新事件返回时触发的回调函数，参数为事件，prop.data 为此次事件包含的数据 |
| props.onFinish   | 否   | `(text: string) => unknown;` | `(text) => console.log(text)` | 当本次调用完全结束时触发的回调函数，参数为本次调用返回的完整文本 |

#### 返回值

| StreamTextResult 属性名            | 类型                            | 说明                                                          |
| -------------- | ----------------------------- | ----------------------------------------------------------- |
| textStream | `AsyncIterable<string>`      | 以流式返回的大模型生成文本，可参考使用示例获取到生成的增量文本。                            |
| eventStream | `AsyncIterable<{data: string, event?: unknown, id?: unknown}>`      | 以流式返回的大模型响应数据，可参考使用示例获取到生成的增量数据。由于各家大模型响应值互有出入，请根据实际情况合理使用。 |

### ChatModel.generateText()

调用大模型生成文本。

#### 使用示例

```js
// 连接模型提供商
const provider = wx.cloud.extend.AI.createModel("cloudbase"); 
const res = await provider.generateText({
  model: "hy3-preview",
  messages: [{ role: "user", content: "你好" }],
});
console.log(res);
// {
//   "id": "27dae91f4e9a4777782c61f89acf8ea4",
//   "object": "chat.completion",
//   "created": 1737602298,
//   "model": "hy3-preview",
//   "system_fingerprint": "",
//   "choices": [
//     {
//       "index": 0,
//       "message": {
//         "role": "assistant",
//         "content": "你好！很高兴与你交流。请问有什么我可以帮助你的吗？无论是关于生活、工作、学习还是其他方面的问题，我都会尽力为你提供帮助。"
//       },
//       "finish_reason": "stop"
//     }
//   ],
//   "usage": {
//     "prompt_tokens": 3,
//     "completion_tokens": 33,
//     "total_tokens": 36
//   },
//   "note": "以上内容为AI生成，不代表开发者立场，请勿删除或修改本标记"
// }
console.log(res.choices[0].message.content);
// 你好！很高兴与你交流。请问有什么我可以帮助你的吗？无论是关于生活、工作、学习还是其他方面的问题，我都会尽力为你提供帮助。
```

#### 类型声明

```js
function generateText(data: unknown): Promise<unknown>;
```

#### 参数

| 参数名 | 必填 | 类型               | 示例                                                                                       | 说明                                                                                                                                                                                                                                                                                     |
| ------ | ---- | ------------------ | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data   | 是   | unknown | `{model: "deepseek-v4-flash", messages: [{ role: "user", content: "你好，请你介绍一下李白" }]}` | 各家大模型的调用参数不同，请根据实际调用模型传入正确的参数。 |

#### 返回值

该接口直接返回实际调用大模型的响应值，需要根据实际响应内容解析出需要的数据。参见上文使用示例。

## 图片生成

> 基础库 `3.17.4` 及以上支持

通过 `AI.createImageModel()` 创建图片模型实例，可调用 `generateImage()` 进行文生图或图生图。

> **模型下线预告：** `HY-Image-3.0-Plus-4090-Tob-v1.0`（文生图）与 `HY-Image-v3.0-I2I-ToB-v1.0.1`（图生图）将于 **2026 年 12 月 1 日 0 点**下线，下线后调用会报错。接替模型 `hy-image-v3.5-preview` 预计 **2026 年 11 月中旬**提供，调用方式与当前模型不同，具体改造点另行通知。请评估工作量并预留适配时间。详见[《关于混元生图 3.0 模型下线的通知》](https://docs.cloudbase.net/ai/ai-inspire-plan-image-3.0-offline)。

### AI.createImageModel()

创建指定的图片模型实例。

#### 使用示例

```js
const imageModel = wx.cloud.extend.AI.createImageModel("hunyuan-image");
```

#### 类型声明

```ts
function createImageModel(provider: string): ImageModel;
```

#### 参数

| 参数名 | 必填 | 类型 | 说明 |
| ------ | ---- | ---- | ---- |
| provider | 是 | `string` | 模型提供商名称，如 `"hunyuan-image"` |

返回一个提供图片生成能力的对象。

### ImageModel.generateImage()

调用图片模型生成图片（支持文生图与图生图）。

#### 使用示例

文生图：

```js
const imageModel = wx.cloud.extend.AI.createImageModel("hunyuan-image");
const res = await imageModel.generateImage({
  model: "HY-Image-3.0-Plus-4090-Tob-v1.0",
  prompt: "一只胖胖的橘猫坐在窗台上打盹，水彩风格，温暖色调",
  size: "1024x1024",
  revise: { value: true },
  timeout: 120000,
});

console.log(res.data[0].url);
console.log(res.data[0].revised_prompt);
```

图生图：

```js
const imageModel = wx.cloud.extend.AI.createImageModel("hunyuan-image");
const res = await imageModel.generateImage({
  model: "HY-Image-v3.0-I2I-ToB-v1.0.1",
  prompt: "将这张照片转换为油画风格",
  size: "1024x1024",
  revise: { value: true },
  image_urls: ["https://example.com/reference.jpg"], // 或传入 images: ["<base64>"]
  timeout: 120000,
});

console.log(res.data[0].url);
```

#### 类型声明

```ts
function generateImage(data: GenerateImageInput): Promise<GenerateImageOutput>;

interface GenerateImageInput {
  model: string;
  prompt: string;
  size?: string;
  revise?: { value: boolean };
  footnote?: string;
  image_urls?: string[];
  images?: string[];
  timeout?: number;
}

interface GenerateImageOutput {
  id: string;
  created: number;
  data: Array<{
    url: string;
    revised_prompt?: string;
  }>;
}
```

#### 参数

| 参数名 | 必填 | 类型 | 说明 |
| ------ | ---- | ---- | ---- |
| model | 是 | `string` | 模型名称。文生图使用 `"HY-Image-3.0-Plus-4090-Tob-v1.0"`，图生图使用 `"HY-Image-v3.0-I2I-ToB-v1.0.1"` |
| prompt | 是 | `string` | 图片描述文本，最多 500 字 |
| size | 否 | `string` | 图片尺寸，默认 `"1024x1024"`，可选值：`"1024x1024"`（1:1）、`"1280x720"`（16:9）、`"720x1280"`（9:16）。宽 × 高不能超过 1024 × 1024 像素，超出会返回 400 错误 |
| revise | 否 | `{ value: boolean }` | 是否开启 prompt 改写，开启后模型会自动优化提示词 |
| footnote | 否 | `string` | 水印文本，会替换输出图片右下角默认的「AI生成」标识 |
| image_urls | 否 | `string[]` | 图生图垫图图片地址列表，与 `images` 二选一；当模型为 `HY-Image-v3.0-I2I-ToB-v1.0.1` 时最多支持 1 张图（大小不超过 10MB，支持 jpg、jpeg、png 格式） |
| images | 否 | `string[]` | 图生图垫图 base64 列表，与 `image_urls` 二选一；当模型为 `HY-Image-v3.0-I2I-ToB-v1.0.1` 时最多支持 1 张图（大小不超过 10MB，支持 jpg、jpeg、png 格式）。传纯 base64 字符串，不要带 `data:image/jpeg;base64,` 前缀，否则会返回 400 错误（`image validate failed`） |
| timeout | 否 | `number` | 请求超时时间（单位 ms），如 `120000` |

#### 返回值

| 属性名 | 类型 | 说明 |
| ------ | ---- | ---- |
| id | `string` | 请求 ID |
| created | `number` | 创建时间戳，单位为秒 |
| data | `Array<{ url: string; revised_prompt?: string }>` | 生成的图片列表，每项包含生成的图片 `url` 以及改写后的提示词 `revised_prompt`。无论是否开启 `revise`，该字段都会返回；未发生改写时与输入的 `prompt` 相同 |

#### 关于 revised_prompt

`revised_prompt` 中包含模型输出的内联标记，`<think>` 内为推理过程，`<recaption>` 内为画面描述，末尾还会携带 `<boi>`、`<img_size_*>`、`<img_ratio_*>` 等尺寸标记。直接展示前需提取 `<recaption>` 的内容：

```js
function cleanRevisedPrompt(text) {
  if (!text) return "";

  let out = text.replace(/<think>[\s\S]*?<\/think>/gi, "");

  const recaption = out.match(/<recaption>([\s\S]*?)<\/recaption>/i);
  const answer = out.match(/<answer>([\s\S]*?)<\/answer>/i);
  if (recaption && recaption[1].trim()) out = recaption[1];
  else if (answer && answer[1].trim()) out = answer[1];

  return out
    .replace(/<\/?boi>/gi, "")
    .replace(/<img_size_\d+>/gi, "")
    .replace(/<img_ratio_\d+>/gi, "")
    .replace(/<\/?recaption>/gi, "")
    .replace(/<\/?answer>/gi, "")
    .trim();
}
```

## Agent

### AI.bot.sendMessage()

与 Agent 进行对话。

#### 请求参数说明

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `threadId` | string | 否 | 会话 ID，用于多轮对话 |
| `runId` | string | 否 | 本次运行 ID |
| `messages` | array | 是 | 消息列表 |
| `tools` | array | 否 | 前端工具定义 |
| `context` | array | 否 | 上下文信息 |
| `forwardedProps` | object | 否 | 透传参数 |

#### 消息格式

```typescript
interface Message {
  id: string;           // 消息 ID
  role: "user" | "assistant" | "system" | "tool";
  content: string;      // 消息内容
  name?: string;        // 工具名称（role 为 tool 时）
  toolCallId?: string;  // 工具调用 ID（role 为 tool 时）
}
```

#### 响应格式

响应采用 SSE 格式，每个事件以 `data:` 开头：

```json
data: {"type":"TEXT_MESSAGE_START","messageId":"msg-1"}

data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg-1","delta":"你好"}

data: {"type":"TEXT_MESSAGE_END","messageId":"msg-1"}

data: {"type":"RUN_FINISHED"}
```

#### 事件类型

| 事件类型 | 说明 |
|---------|------|
| `RUN_STARTED` | Agent 开始运行 |
| `RUN_FINISHED` | Agent 运行结束 |
| `RUN_ERROR` | Agent 运行出错 |
| `TEXT_MESSAGE_START` | 文本消息开始 |
| `TEXT_MESSAGE_CONTENT` | 文本消息内容（增量） |
| `TEXT_MESSAGE_END` | 文本消息结束 |
| `TOOL_CALL_START` | 工具调用开始 |
| `TOOL_CALL_ARGS` | 工具调用参数（增量） |
| `TOOL_CALL_END` | 工具调用结束 |
| `STATE_SNAPSHOT` | 状态快照 |
| `STATE_DELTA` | 状态增量更新 |
| `MESSAGES_SNAPSHOT` | 消息快照 |
| `STEP_STARTED` | 步骤开始 |
| `STEP_FINISHED` | 步骤结束 |

更多用法请参考 [云开发 Agent 文档](https://docs.cloudbase.net/ai/agent-development/protocol)。
