跳到主要内容

在小程序中调用

微信小程序可以通过 wx.cloud.extend.AI 调用云开发 Agent,支持流式输出。

先确认你的 Agent 使用的协议

Agent 的通信协议由创建时的模板决定:控制台「接入 & 调试」页端点以 /acp 结尾的(cloudbase-agent 模板),使用 ACP 协议;自建 HTTP Agent 使用 AG-UI 协议。下文示例按协议分节。

前置条件

  • 小程序基础库 3.15.1+
  • 已创建云开发环境
  • 已创建 Agent

初始化

// app.js
App({
onLaunch() {
wx.cloud.init({
env: 'your-env-id',
});
}
});

调用 ACP 协议 Agent(cloudbase-agent 模板)

请求体写 ACP 协议 的 JSON-RPC 格式,从 eventStream 解析 session/update 事件:

async function sendMessage(message) {
const res = await wx.cloud.extend.AI.bot.sendMessage({
data: {
// botId 必填,标识调用的 Agent
botId: 'your-agent-id',
jsonrpc: '2.0',
id: 1,
method: 'session/prompt',
params: {
prompt: [{ type: 'text', text: message }],
// 多轮会话:把上一轮事件中返回的 sessionId 传回即可延续上下文
// sessionId: 'your-session-id',
},
}
});

let response = '';
for await (const event of res.eventStream) {
if (event.data === '[DONE]') break;
const frame = JSON.parse(event.data);
const update = frame?.params?.update;
if (update?.sessionUpdate === 'agent_message_chunk') {
response += update.content.text; // 正文增量
}
}
return response;
}

sendMessage('你好');

调用 AG-UI 协议 Agent(自建 HTTP Agent)

基础调用

function generateId() {
const timestamp = Date.now().toString().slice(-4);
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
return timestamp + random;
}

async function sendMessage(message) {
const res = await wx.cloud.extend.AI.bot.sendMessage({
data: {
// botId 必填,标识调用的 Agent
botId: 'your-agent-id',
// 入参结构参考前后端通信协议:
// https://docs.cloudbase.net/ai/agent/http-agent-protocol
threadId: 'thread_id_' + generateId(),
runId: 'run_id_' + generateId(),
messages: [
{ id: String(Date.now()), role: 'user', content: message }
],
tools: [],
context: [],
state: {},
forwardedProps: {},
}
});

// 流式接收响应
let response = '';
for await (const event of res.eventStream) {
// 需要手动解析 event.data
const data = JSON.parse(event.data);
// 根据事件类型输出,响应事件参考文档:
// https://docs.cloudbase.net/ai/agent/http-agent-protocol#%E5%93%8D%E5%BA%94%E4%BA%8B%E4%BB%B6
switch (data.type) {
case 'TEXT_MESSAGE_CONTENT':
response += data.delta;
console.log(data.delta); // 实时输出
break;

case 'RUN_ERROR':
console.error('运行出错:', data.message);
break;

case 'RUN_FINISHED':
// 运行结束
break;
}
}

return response;
}

sendMessage('你好');

完整示例

// pages/chat/chat.js

function generateId() {
const timestamp = Date.now().toString().slice(-4);
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
return timestamp + random;
}

Page({
data: {
messages: [],
inputValue: '',
loading: false,
},

onInput(e) {
this.setData({ inputValue: e.detail.value });
},

async sendMessage() {
const { inputValue, messages } = this.data;
if (!inputValue.trim() || this.data.loading) return;

this.setData({
messages: [...messages, { role: 'user', content: inputValue }],
inputValue: '',
loading: true,
});

try {
const res = await wx.cloud.extend.AI.bot.sendMessage({
data: {
botId: 'your-agent-id',
threadId: 'thread_id_' + generateId(),
runId: 'run_id_' + generateId(),
messages: [
{ id: String(Date.now()), role: 'user', content: inputValue }
],
tools: [],
context: [],
state: {},
forwardedProps: {},
}
});

// 添加空的助手消息
this.setData({
messages: [...this.data.messages, { role: 'assistant', content: '' }],
});

// 流式接收响应
let fullText = '';
for await (const event of res.eventStream) {
const data = JSON.parse(event.data);
if (data.type === 'TEXT_MESSAGE_CONTENT') {
fullText += data.delta;
const updatedMessages = [...this.data.messages];
updatedMessages[updatedMessages.length - 1].content = fullText;
this.setData({ messages: updatedMessages });
}
}
} catch (error) {
console.error('发送消息失败:', error);
wx.showToast({ title: '发送失败', icon: 'none' });
} finally {
this.setData({ loading: false });
}
},
});

相关文档