概述
提供云开发 AI 接入能力,快速接入大模型和 Agent。
基础使用示例
Publishable Key 可前往 云开发平台/API Key 配置 中生成
类型声明
function ai(): AI;
返回值
返回新创建的 AI 实例。
import cloudbase from "@cloudbase/js-sdk";
// 初始化
const app = cloudbase.init({
env: "your-env-id", // 替换为您的环境ID
region: "ap-shanghai", // 地域,默认为上海
accessKey: "", // 填入生成的 Publishable Key
});
// 如果填入了 accessKey,则不需要此步骤
await app.auth.signInAnonymously();
const ai = app.ai();
// 基础文本生成示例
async function generateText() {
const model = ai.createModel("hunyuan-exp");
const result = await model.generateText({
model: "hunyuan-lite",
messages: [{ role: "user", content: "你好,请你介绍一下李白" }],
});
console.log("生成的文本:", result.text);
console.log("消耗的token:", result.usage);
}
// 流式文本生成示例
async function streamText() {
const model = ai.createModel("hunyuan-exp");
const result = await model.streamText({
model: "hunyuan-lite",
messages: [{ role: "user", content: "1+1等于多少" }],
});
for await (let chunk of result.textStream) {
console.log("收到文本块:", chunk);
}
}
// Agent 对话示例
async function chatWithAgent() {
const res = await ai.bot.sendMessage({
botId: "botId-xxx",
msg: "你好,请介绍一下你自己",
history: [],
});
for await (let text of res.textStream) {
console.log("Agent 回复:", text);
}
}
AI
用于创建 AI 模型的类。
createModel
function createModel(model: string): ChatModel;
创建指定的 AI 模型。
- 创建一个新的 AI 模型实例
- 返回一个实现了 ChatModel 抽象类的模型实例
- 该实例提供 AI 生成文本相关能力
参数
模型标识符,如 'hunyuan-exp'、'hunyuan-lite' 等
返回
实现了 ChatModel 抽象类的模型实例,提供 AI 生成文本相关能力
示例
// 创建混元体验版模型
const model = ai.createModel("hunyuan-exp");
// 创建混元轻量版模型
const liteModel = ai.createModel("hunyuan-lite");
// 创建多个模型实例用于不同场景
const expModel = ai.createModel("hunyuan-exp"); // 体验版,功能完整
const liteModel = ai.createModel("hunyuan-lite"); // 轻量版,响应快速
const proModel = ai.createModel("hunyuan-pro"); // 专业版,性能更强
// 根据需求选择不同模型
async function generateWithModel(scenario: string, content: string) {
let selectedModel;
switch (scenario) {
case "creative":
selectedModel = expModel;
break;
case "quick":
selectedModel = liteModel;
break;
case "professional":
selectedModel = proModel;
break;
default:
selectedModel = liteModel;
}
const result = await selectedModel.generateText({
model: scenario,
messages: [{ role: "user", content: content }],
});
return result.text;
}
bot
挂载了 Bot 类的实例,上面集合了一系列与 Agent 交互的方法。具体可参考 Bot 类 的详细文档。
使用示例
const agentList = await ai.bot.list({ pageNumber: 1, pageSize: 10 });
registerFunctionTool
function registerFunctionTool(functionTool: FunctionTool): void;
注册函数工具。在进行大模型调用时,可以告知大模型可用的函数工具,当大模型的响应被解析为工具调用时,会自动调用对应的函数工具。
参数
要注册的函数工具定义
返回
无返回值
示例
// 定义获取天气的工具
const getWeatherTool = {
name: "get_weather",
description: "返回某个城市的天气信息。调用示例:get_weather({city: '北京'})",
fn: ({ city }) => `${city}的天气是:秋高气爽!!!`,
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "要查询的城市",
},
},
required: ["city"],
},
};
// 注册工具
ai.registerFunctionTool(getWeatherTool);
// 使用工具进行对话
const model = ai.createModel("hunyuan-exp");
const result = await model.generateText({
model: "hunyuan-turbo",
tools: [getWeatherTool],
messages: [
{
role: "user",
content: "请告诉我北京的天气状况",
},
],
});
console.log(result.text);
// 多工具集成系统
class ToolIntegrationSystem {
private registeredTools: Map<string, FunctionTool> = new Map();
// 注册多个工具
registerTools(tools: FunctionTool[]): void {
tools.forEach((tool) => {
ai.registerFunctionTool(tool);
this.registeredTools.set(tool.name, tool);
console.log(`✓ 工具注册成功: ${tool.name}`);
});
}
// 获取所有可用工具
getAvailableTools(): FunctionTool[] {
return Array.from(this.registeredTools.values());
}
// 智能对话助手
async smartAssistant(question: string): Promise<string> {
const model = ai.createModel("hunyuan-exp");
const result = await model.generateText({
model: "hunyuan-turbo",
tools: this.getAvailableTools(),
messages: [
{
role: "user",
content: question,
},
],
});
return result.text;
}
// 工具使用统计
getToolUsageStats(): Map<string, number> {
const stats = new Map<string, number>();
// 在实际应用中,这里可以记录工具调用次数
return stats;
}
}
// 定义多个工具
const tools = [
{
name: "get_weather",
description: "获取城市天气信息",
fn: ({ city }) => `${city}的天气:晴,25℃`,
parameters: {
type: "object",
properties: { city: { type: "string", description: "城市名称" } },
required: ["city"],
},
},
{
name: "calculate",
description: "执行数学计算",
fn: ({ expression }) => `计算结果:${eval(expression)}`,
parameters: {
type: "object",
properties: { expression: { type: "string", description: "数学表达式" } },
required: ["expression"],
},
},
{
name: "search_info",
description: "搜索信息",
fn: ({ keyword }) => `搜索结果:关于${keyword}的信息`,
parameters: {
type: "object",
properties: { keyword: { type: "string", description: "搜索关键词" } },
required: ["keyword"],
},
},
];
// 使用示例
const toolSystem = new ToolIntegrationSystem();
toolSystem.registerTools(tools);
// 智能对话
const answer = await toolSystem.smartAssistant(
"计算一下 15*8+20 的结果,并告诉我北京的天气"
);
console.log("助手回答:", answer);
// 动态工具管理系统
class DynamicToolManager {
private toolRegistry: Map<string, FunctionTool> = new Map();
// 动态注册工具
registerTool(tool: FunctionTool): void {
ai.registerFunctionTool(tool);
this.toolRegistry.set(tool.name, tool);
console.log(`工具注册: ${tool.name}`);
}
// 动态卸载工具
unregisterTool(toolName: string): boolean {
if (this.toolRegistry.has(toolName)) {
this.toolRegistry.delete(toolName);
console.log(`工具卸载: ${toolName}`);
return true;
}
return false;
}
// 根据上下文动态选择工具
async contextualAssistant(
context: string,
question: string
): Promise<string> {
const relevantTools = this.selectRelevantTools(context, question);
const model = ai.createModel("hunyuan-exp");
const result = await model.generateText({
model: "hunyuan-turbo",
tools: relevantTools,
messages: [
{
role: "system",
content: `当前上下文:${context}`,
},
{
role: "user",
content: question,
},
],
});
return result.text;
}
// 根据上下文选择相关工具
private selectRelevantTools(
context: string,
question: string
): FunctionTool[] {
const tools = Array.from(this.toolRegistry.values());
// 简单的关键词匹配算法
const keywords = [...context.split(" "), ...question.split(" ")];
return tools.filter((tool) => {
return keywords.some((keyword) =>
tool.description.toLowerCase().includes(keyword.toLowerCase())
);
});
}
// 热更新工具
updateTool(toolName: string, updatedTool: FunctionTool): boolean {
if (this.toolRegistry.has(toolName)) {
this.unregisterTool(toolName);
this.registerTool(updatedTool);
console.log(`工具更新: ${toolName}`);
return true;
}
return false;
}
// 获取工具列表
listTools(): string[] {
return Array.from(this.toolRegistry.keys());
}
}
// 使用示例
const toolManager = new DynamicToolManager();
// 注册初始工具
toolManager.registerTool({
name: "weather",
description: "获取天气信息",
fn: ({ city }) => `${city}天气:晴`,
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
});
// 动态添加新工具
toolManager.registerTool({
name: "translate",
description: "翻译文本",
fn: ({ text, to }) => `${text} 翻译为 ${to}:示例翻译结果`,
parameters: {
type: "object",
properties: {
text: { type: "string" },
to: { type: "string" },
},
required: ["text", "to"],
},
});
// 上下文感知对话
const answer = await toolManager.contextualAssistant(
"天气和翻译相关的问题",
"把'你好'翻译成英语,并告诉我上海的天气"
);
console.log("智能回答:", answer);
// 查看可用工具
console.log("可用工具:", toolManager.listTools());
ChatModel
这个抽象类描述了 AI 生文模型类提供的接口。
generateText
function generateText(data: BaseChatModelInput): Promise<{
rawResponses: Array<unknown>;
text: string;
messages: Array<ChatModelMessage>;
usage: Usage;
error?: unknown;
}>;
调用大模型生成文本。
- 向大模型发送消息并获取生成的文本响应
- 支持完整的对话上下文管理
- 返回详细的调用信息和 token 消耗统计
参数
大模型输入参数,包含模型配置和消息内容
返回
大模型生成文本的响应结果
示例
const model = ai.createModel("hunyuan-exp");
const result = await model.generateText({
model: "hunyuan-lite",
messages: [{ role: "user", content: "你好,请你介绍一下李白" }],
});
console.log("生成的文本:", result.text);
console.log("消耗的token:", result.usage);
const model = ai.createModel("hunyuan-exp");
// 多轮对话示例
const messages = [
{ role: "user", content: "你好,我想了解中国古代文学" },
{
role: "assistant",
content:
"中国古代文学源远流长,从诗经楚辞到唐诗宋词,都有着丰富的文化内涵。",
},
{ role: "user", content: "那你能介绍一下唐诗的特点吗?" },
];
const result = await model.generateText({
model: "hunyuan-lite",
messages: messages,
temperature: 0.7,
topP: 0.9,
});
console.log("唐诗介绍:", result.text);
// 注册天气查询工具
ai.registerFunctionTool({
name: "get_weather",
description: "查询城市天气信息",
fn: ({ city }) => `${city}的天气是:晴朗,25℃`,
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "要查询的城市名称",
},
},
required: ["city"],
},
});
const model = ai.createModel("hunyuan-exp");
const result = await model.generateText({
model: "hunyuan-lite",
messages: [{ role: "user", content: "请告诉我北京的天气状况" }],
tools: [getWeatherTool],
toolChoice: "auto",
});
console.log("大模型响应:", result.text);
streamText
function streamText(data: BaseChatModelInput): Promise<StreamTextResult>;
以流式调用大模型生成文本。
- 流式调用时,生成的文本及其他响应数据会通过 SSE 返回,该接口的返回值对 SSE 做了不同程度的封装,开发者能根据实际需求获取到文本流和完整数据流。
- 以流式方式调用大模型生成文本,支持实时获取增量内容
参数
大模型输入参数,包含模型配置和消息内容
返回
流式文本生成的结果,包含文本流和数据流
示例
const model = ai.createModel("hunyuan-exp");
const result = await model.streamText({
model: "hunyuan-lite",
messages: [{ role: "user", content: "你好,请你介绍一下李白" }],
});
// 获取文本流
for await (let chunk of result.textStream) {
console.log("收到文本块:", chunk);
}
// 1
// 加
// 1
// 的结果
// 是
// 2
// 。
// 获取数据流
for await (let data of result.dataStream) {
console.log("收到数据块:", data);
}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// {created: 1723013866, id: "a95a54b5c5d2144eb700e60d0dfa5c98", model: "hunyuan-lite", version: "202404011000", choices: Array(1), …}
// 在网页中实时显示流式内容
async function displayStreamingText(question: string) {
const model = ai.createModel("hunyuan-exp");
const result = await model.streamText({
model: "hunyuan-lite",
messages: [{ role: "user", content: question }],
});
const outputElement = document.getElementById("output");
outputElement.innerHTML = "";
for await (let chunk of result.textStream) {
outputElement.innerHTML += chunk;
// 滚动到最新内容
outputElement.scrollTop = outputElement.scrollHeight;
}
}
// 使用示例
displayStreamingText("请详细介绍一下唐诗的发展历程");
// 监控流式生成进度
async function monitorStreamProgress(question: string) {
const model = ai.createModel("hunyuan-exp");
const result = await model.streamText({
model: "hunyuan-lite",
messages: [{ role: "user", content: question }],
});
let totalChunks = 0;
let startTime = Date.now();
for await (let chunk of result.textStream) {
totalChunks++;
console.log(`第${totalChunks}个文本块: ${chunk}`);
}
const endTime = Date.now();
console.log(
`生成完成,共${totalChunks}个文本块,耗时${endTime - startTime}ms`
);
// 获取完整消息和token统计
const messages = await result.messages;
const usage = await result.usage;
console.log("完整对话:", messages);
console.log("Token消耗:", usage);
}
Bot
用于与 Agent 交互的类。
get
function get(props: { botId: string }): Promise<BotInfo>;
获取某个 Agent 的信息。
- 根据 Agent ID 获取详细的 Agent 信息
- 返回 Agent 的基本配置、欢迎语、头像等完整信息
参数
获取 Agent 信息的参数
返回
Agent 的详细信息
示例
const res = await ai.bot.get({ botId: "botId-xxx" });
console.log("Agent 信息:", res);
// 应用启动时加载 Agent 配置
async function initializeAgent(botId: string) {
try {
const agentInfo = await ai.bot.get({ botId });
// 设置应用界面
document.title = `${agentInfo.name} - AI助手`;
// 显示欢迎信息
const welcomeElement = document.getElementById("welcome");
welcomeElement.innerHTML = `
<div class="agent-header">
<img src="${agentInfo.avatar}" alt="${agentInfo.name}" class="avatar" />
<h2>${agentInfo.name}</h2>
<p>${agentInfo.introduction}</p>
</div>
`;
// 设置聊天背景
if (agentInfo.background) {
document.body.style.backgroundImage = `url(${agentInfo.background})`;
}
return agentInfo;
} catch (error) {
console.error("加载 Agent 配置失败:", error);
throw error;
}
}
// 使用示例
initializeAgent("bot-27973647");
// 管理多个 Agent 的配置
class AgentManager {
private agents: Map<string, BotInfo> = new Map();
async loadAgent(botId: string) {
if (this.agents.has(botId)) {
return this.agents.get(botId);
}
const agentInfo = await ai.bot.get({ botId });
this.agents.set(botId, agentInfo);
return agentInfo;
}
getAgentList() {
return Array.from(this.agents.values());
}
async switchAgent(botId: string) {
const agentInfo = await this.loadAgent(botId);
// 更新界面显示
this.updateUI(agentInfo);
return agentInfo;
}
private updateUI(agentInfo: BotInfo) {
// 更新界面元素
console.log("切换到 Agent:", agentInfo.name);
}
}
// 使用示例
const agentManager = new AgentManager();
await agentManager.loadAgent("bot-27973647");
await agentManager.loadAgent("bot-27973648");
list
function list(props: {
name: string;
introduction: string;
information: string;
enable: boolean;
pageSize: number;
pageNumber: number;
}): Promise<AgentListResult>;
批量获取多个 Agent 的信息。
- 查询和筛选可用的 Agent 列表
- 支持分页查询和条件筛选
- 返回 Agent 的基本信息和配置详情
- 适用于构建 Agent 选择器、Agent 管理界面等应用
参数
查询 Agent 列表的参数
返回
Agent 列表查询结果
示例
const agentList = await ai.bot.list({
pageNumber: 1,
pageSize: 10,
name: "",
enable: true,
information: "",
introduction: "",
});
console.log("Agent 总数:", agentList.total);
console.log("Agent 列表:", agentList.botList);
// 根据条件筛选 Agent
async function searchAgents(keyword: string, page: number = 1) {
const result = await ai.bot.list({
pageNumber: page,
pageSize: 20,
name: keyword,
enable: true,
information: keyword,
introduction: keyword,
});
console.log(`找到 ${result.total} 个匹配的 Agent`);
result.botList.forEach((agent) => {
console.log(`- ${agent.name}: ${agent.introduction}`);
});
return result;
}
// 使用示例
await searchAgents("翻译"); // 搜索翻译相关的 Agent
await searchAgents("客服", 2); // 搜索客服相关的 Agent,第二页
// 构建 Agent 选择器界面
class AgentSelector {
private currentPage: number = 1;
private pageSize: number = 12;
async loadAgents(keyword: string = "") {
const result = await ai.bot.list({
pageNumber: this.currentPage,
pageSize: this.pageSize,
name: keyword,
enable: true,
information: keyword,
introduction: keyword,
});
this.displayAgents(result.botList);
this.updatePagination(result.total);
return result;
}
private displayAgents(agents: any[]) {
const container = document.getElementById("agent-list");
container.innerHTML = "";
agents.forEach((agent) => {
const agentCard = document.createElement("div");
agentCard.className = "agent-card";
agentCard.innerHTML = `
<img src="${agent.avatar}" alt="${agent.name}" class="agent-avatar" />
<div class="agent-info">
<h3>${agent.name}</h3>
<p>${agent.introduction}</p>
<button onclick="selectAgent('${agent.botId}')">选择</button>
</div>
`;
container.appendChild(agentCard);
});
}
private updatePagination(total: number) {
const pagination = document.getElementById("pagination");
const totalPages = Math.ceil(total / this.pageSize);
pagination.innerHTML = `
<button onclick="prevPage()" ${
this.currentPage <= 1 ? "disabled" : ""
}>上一页</button>
<span>第 ${this.currentPage} 页,共 ${totalPages} 页</span>
<button onclick="nextPage()" ${
this.currentPage >= totalPages ? "disabled" : ""
}>下一页</button>
`;
}
async nextPage() {
this.currentPage++;
await this.loadAgents();
}
async prevPage() {
if (this.currentPage > 1) {
this.currentPage--;
await this.loadAgents();
}
}
selectAgent(botId: string) {
console.log("选择的 Agent ID:", botId);
// 开始与选中的 Agent 对话
this.startChat(botId);
}
private startChat(botId: string) {
// 实现与 Agent 开始对话的逻辑
console.log("开始与 Agent 对话:", botId);
}
}
// 使用示例
const selector = new AgentSelector();
await selector.loadAgents(); // 加载第一页 Agent
// 搜索特定类型的 Agent
await selector.loadAgents("写作助手");
sendMessage
function sendMessage(props: {
botId: string;
msg: string;
history: Array<{
role: string;
content: string;
}>;
}): Promise<StreamResult>;
与 Agent 进行对话。
- 响应会通过 SSE 返回,该接口的返回值对 SSE 做了不同程度的封装,开发者能根据实际需求获取到文本流和完整数据流。
- 支持多轮对话上下文管理
- 返回流式响应,支持实时获取 Agent 回复
- 适用于构建聊天机器人、智能助手等应用
参数
发送消息的参数
返回
流式对话结果,包含文本流和数据流
示例
const res = await ai.bot.sendMessage({
botId: "botId-xxx",
history: [{ content: "你是李白。", role: "user" }],
msg: "你好",
});
// 获取文本流
for await (let text of res.textStream) {
console.log("Agent 回复:", text);
}
// 获取数据流
for await (let data of res.dataStream) {
console.log("详细数据:", data);
}
// 多轮对话示例
class ChatSession {
private history: Array<{ role: string; content: string }> = [];
async sendMessage(botId: string, message: string) {
const res = await ai.bot.sendMessage({
botId: botId,
history: this.history,
msg: message,
});
let fullResponse = "";
// 实时显示回复
for await (let chunk of res.textStream) {
fullResponse += chunk;
this.updateDisplay(fullResponse);
}
// 记录对话历史
this.history.push({ role: "user", content: message });
this.history.push({ role: "assistant", content: fullResponse });
return fullResponse;
}
private updateDisplay(text: string) {
const chatArea = document.getElementById("chat-area");
chatArea.innerHTML = text;
chatArea.scrollTop = chatArea.scrollHeight;
}
clearHistory() {
this.history = [];
}
getHistory() {
return this.history;
}
}
// 使用示例
const chatSession = new ChatSession();
await chatSession.sendMessage("botId-xxx", "你好,请介绍一下你自己");
await chatSession.sendMessage("botId-xxx", "你能帮我写一首诗吗?");
// 构建实时聊天应用
class ChatApp {
private botId: string;
private conversationId: string;
constructor(botId: string) {
this.botId = botId;
this.setupEventListeners();
}
private setupEventListeners() {
const sendBtn = document.getElementById("send-btn");
const input = document.getElementById("message-input") as HTMLInputElement;
sendBtn.addEventListener("click", () => {
this.sendMessage(input.value);
input.value = "";
});
input.addEventListener("keypress", (e) => {
if (e.key === "Enter") {
this.sendMessage(input.value);
input.value = "";
}
});
}
async sendMessage(message: string) {
if (!message.trim()) return;
// 显示用户消息
this.displayMessage("user", message);
try {
const res = await ai.bot.sendMessage({
botId: this.botId,
history: this.getChatHistory(),
msg: message,
});
// 显示流式回复
const assistantDiv = this.displayMessage("assistant", "");
for await (let chunk of res.textStream) {
assistantDiv.innerHTML += chunk;
assistantDiv.scrollIntoView({ behavior: "smooth" });
}
} catch (error) {
this.displayMessage("error", "发送消息失败: " + error.message);
}
}
private displayMessage(role: string, content: string): HTMLDivElement {
const chatContainer = document.getElementById("chat-container");
const messageDiv = document.createElement("div");
messageDiv.className = `message ${role}`;
messageDiv.innerHTML = content;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
return messageDiv;
}
private getChatHistory() {
const messages = document.querySelectorAll(".message");
const history = [];
for (let message of messages) {
const role = message.classList.contains("user") ? "user" : "assistant";
const content = message.innerHTML;
history.push({ role, content });
}
return history;
}
}
// 使用示例
const chatApp = new ChatApp("botId-xxx");
getChatRecords
function getChatRecords(props: {
botId: string;
sort: string;
pageSize: number;
pageNumber: number;
}): Promise<ChatRecordsResult>;
获取聊天记录。
- 获取指定 Agent 的历史聊天记录
- 支持分页查询和排序
- 返回完整的对话历史信息
- 适用于构建聊天历史查看功能
参数
获取聊天记录的参数
返回
聊天记录查询结果
示例
const records = await ai.bot.getChatRecords({
botId: "botId-xxx",
pageNumber: 1,
pageSize: 10,
sort: "asc",
});
console.log("总记录数:", records.total);
console.log("记录列表:", records.recordList);
// 分页查询聊天记录
class ChatHistoryManager {
private botId: string;
private currentPage: number = 1;
private pageSize: number = 20;
constructor(botId: string) {
this.botId = botId;
}
async loadPage(pageNumber: number) {
const records = await ai.bot.getChatRecords({
botId: this.botId,
pageNumber: pageNumber,
pageSize: this.pageSize,
sort: "desc", // 按时间倒序排列
});
this.currentPage = pageNumber;
return records;
}
async nextPage() {
return this.loadPage(this.currentPage + 1);
}
async previousPage() {
if (this.currentPage > 1) {
return this.loadPage(this.currentPage - 1);
}
return null;
}
getTotalPages(totalRecords: number) {
return Math.ceil(totalRecords / this.pageSize);
}
}
// 使用示例
const historyManager = new ChatHistoryManager("botId-xxx");
const firstPage = await historyManager.loadPage(1);
console.log("第1页记录:", firstPage.recordList);
const secondPage = await historyManager.nextPage();
console.log("第2页记录:", secondPage.recordList);
// 构建聊天历史查看界面
class ChatHistoryViewer {
private botId: string;
constructor(botId: string) {
this.botId = botId;
this.setupUI();
}
private setupUI() {
const historyContainer = document.getElementById("history-container");
const prevBtn = document.getElementById("prev-btn");
const nextBtn = document.getElementById("next-btn");
const pageInfo = document.getElementById("page-info");
prevBtn.addEventListener("click", () => this.previousPage());
nextBtn.addEventListener("click", () => this.nextPage());
}
async loadHistory(pageNumber: number = 1) {
const records = await ai.bot.getChatRecords({
botId: this.botId,
pageNumber: pageNumber,
pageSize: 10,
sort: "desc",
});
this.displayRecords(records.recordList);
this.updatePageInfo(pageNumber, records.total);
}
private displayRecords(records: any[]) {
const container = document.getElementById("records-container");
container.innerHTML = "";
records.forEach((record) => {
const recordDiv = document.createElement("div");
recordDiv.className = "chat-record";
recordDiv.innerHTML = `
<div class="record-header">
<span class="role">${record.role}</span>
<span class="time">${record.createTime}</span>
</div>
<div class="content">${record.content}</div>
`;
container.appendChild(recordDiv);
});
}
private updatePageInfo(currentPage: number, total: number) {
const pageInfo = document.getElementById("page-info");
const totalPages = Math.ceil(total / 10);
pageInfo.textContent = `第${currentPage}页,共${totalPages}页,总计${total}条记录`;
}
async nextPage() {
const currentPage = parseInt(
document.getElementById("page-info").textContent.match(/第(\d+)页/)[1]
);
await this.loadHistory(currentPage + 1);
}
async previousPage() {
const currentPage = parseInt(
document.getElementById("page-info").textContent.match(/第(\d+)页/)[1]
);
if (currentPage > 1) {
await this.loadHistory(currentPage - 1);
}
}
}
// 使用示例
const historyViewer = new ChatHistoryViewer("botId-xxx");
await historyViewer.loadHistory(1);
sendFeedback
function sendFeedback(props: {
userFeedback: IUserFeedback;
botId: string;
}): Promise<void>;
发送对某条聊天记录的反馈信息。
- 对指定的聊天记录进行评价和反馈
- 支持评分、评论、标签等多种反馈方式
- 帮助改进 Agent 的回答质量
- 适用于构建用户反馈系统
参数
发送反馈的参数
返回
无返回值
示例
const res = await ai.bot.sendFeedback({
userFeedback: {
botId: "botId-xxx",
recordId: "recordId-xxx",
comment: "非常棒",
rating: 5,
tags: ["优美"],
aiAnswer: "落英缤纷",
input: "来个成语",
type: "upvote",
},
botId: "botId-xxx",
});
console.log("反馈发送成功");
// 构建用户反馈系统
class FeedbackSystem {
private botId: string;
constructor(botId: string) {
this.botId = botId;
this.setupFeedbackUI();
}
private setupFeedbackUI() {
const feedbackButtons = document.querySelectorAll(".feedback-btn");
feedbackButtons.forEach((button) => {
button.addEventListener("click", (e) => {
const recordId = e.target.dataset.recordId;
const type = e.target.dataset.type; // upvote 或 downvote
this.showFeedbackDialog(recordId, type);
});
});
}
private showFeedbackDialog(recordId: string, type: string) {
const dialog = document.getElementById("feedback-dialog");
const submitBtn = document.getElementById("submit-feedback");
const ratingInput = document.getElementById("rating") as HTMLInputElement;
const commentInput = document.getElementById(
"comment"
) as HTMLTextAreaElement;
const tagsInput = document.getElementById("tags") as HTMLInputElement;
dialog.style.display = "block";
submitBtn.onclick = async () => {
await this.submitFeedback(recordId, type, {
rating: parseInt(ratingInput.value),
comment: commentInput.value,
tags: tagsInput.value.split(",").map((tag) => tag.trim()),
});
dialog.style.display = "none";
};
}
async submitFeedback(
recordId: string,
type: string,
feedback: {
rating: number;
comment: string;
tags: string[];
}
) {
try {
await ai.bot.sendFeedback({
userFeedback: {
botId: this.botId,
recordId: recordId,
comment: feedback.comment,
rating: feedback.rating,
tags: feedback.tags,
aiAnswer: this.getCurrentAnswer(),
input: this.getCurrentQuestion(),
type: type,
},
botId: this.botId,
});
this.showSuccessMessage("感谢您的反馈!");
} catch (error) {
this.showErrorMessage("反馈发送失败: " + error.message);
}
}
private getCurrentAnswer(): string {
// 获取当前对话的回答内容
const answerElement = document.querySelector(
".assistant-message:last-child"
);
return answerElement?.textContent || "";
}
private getCurrentQuestion(): string {
// 获取当前对话的问题内容
const questionElement = document.querySelector(".user-message:last-child");
return questionElement?.textContent || "";
}
private showSuccessMessage(message: string) {
const notification = document.createElement("div");
notification.className = "notification success";
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => notification.remove(), 3000);
}
private showErrorMessage(message: string) {
const notification = document.createElement("div");
notification.className = "notification error";
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => notification.remove(), 5000);
}
}
// 使用示例
const feedbackSystem = new FeedbackSystem("botId-xxx");
// 批量处理用户反馈
class BatchFeedbackProcessor {
private botId: string;
private feedbackQueue: Array<{
recordId: string;
type: string;
rating: number;
comment: string;
tags: string[];
}> = [];
constructor(botId: string) {
this.botId = botId;
this.startProcessing();
}
addFeedback(
recordId: string,
type: string,
rating: number,
comment: string,
tags: string[]
) {
this.feedbackQueue.push({ recordId, type, rating, comment, tags });
}
private async startProcessing() {
setInterval(async () => {
if (this.feedbackQueue.length > 0) {
await this.processBatch();
}
}, 5000); // 每5秒处理一次
}
private async processBatch() {
const batch = this.feedbackQueue.splice(0, 10); // 每次处理最多10个反馈
const promises = batch.map((feedback) => {
return ai.bot.sendFeedback({
userFeedback: {
botId: this.botId,
recordId: feedback.recordId,
comment: feedback.comment,
rating: feedback.rating,
tags: feedback.tags,
aiAnswer: "", // 需要根据实际情况获取
input: "", // 需要根据实际情况获取
type: feedback.type,
},
botId: this.botId,
});
});
try {
await Promise.all(promises);
console.log(`成功处理 ${batch.length} 个反馈`);
} catch (error) {
console.error("批量处理反馈失败:", error);
// 将失败的反馈重新加入队列
this.feedbackQueue.unshift(...batch);
}
}
getQueueSize() {
return this.feedbackQueue.length;
}
}
// 使用示例
const feedbackProcessor = new BatchFeedbackProcessor("botId-xxx");
// 添加多个反馈
feedbackProcessor.addFeedback("record-1", "upvote", 5, "回答很棒", [
"准确",
"详细",
]);
feedbackProcessor.addFeedback("record-2", "downvote", 2, "回答不够准确", [
"不准确",
]);
console.log("当前队列大小:", feedbackProcessor.getQueueSize());
getFeedback
function getFeedback(props: {
botId: string;
type: string;
sender: string;
senderFilter: string;
minRating: number;
maxRating: number;
from: number;
to: number;
pageSize: number;
pageNumber: number;
}): Promise<FeedbackResult>;
获取已存在的反馈信息。
- 查询指定 Agent 的用户反馈记录
- 支持多种过滤条件:时间范围、评分范围、用户过滤等
- 返回分页的反馈结果和统计信息
- 适用于构建反馈分析和管理系统
参数
查询反馈信息的参数
返回
反馈查询结果
示例
const res = await ai.bot.getFeedback({
botId: "botId-xxx",
from: 0,
to: 0,
maxRating: 4,
minRating: 3,
pageNumber: 1,
pageSize: 10,
sender: "user-a",
senderFilter: "include",
type: "upvote",
});
console.log("反馈总数:", res.total);
console.log("反馈列表:", res.feedbackList);
// 构建反馈分析系统
class FeedbackAnalyzer {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async analyzeFeedback(timeRange: { from: number; to: number }) {
const feedback = await ai.bot.getFeedback({
botId: this.botId,
from: timeRange.from,
to: timeRange.to,
minRating: 1,
maxRating: 5,
pageNumber: 1,
pageSize: 1000, // 获取足够多的数据进行分析
sender: "",
senderFilter: "include",
type: "",
});
return this.generateReport(feedback.feedbackList);
}
private generateReport(feedbackList: any[]) {
const report = {
total: feedbackList.length,
upvotes: feedbackList.filter((f) => f.type === "upvote").length,
downvotes: feedbackList.filter((f) => f.type === "downvote").length,
averageRating: this.calculateAverageRating(feedbackList),
commonTags: this.getCommonTags(feedbackList),
ratingDistribution: this.getRatingDistribution(feedbackList),
topComments: this.getTopComments(feedbackList),
};
return report;
}
private calculateAverageRating(feedbackList: any[]): number {
const ratings = feedbackList.map((f) => f.rating).filter((r) => r > 0);
return ratings.length > 0
? ratings.reduce((a, b) => a + b, 0) / ratings.length
: 0;
}
private getCommonTags(feedbackList: any[]): string[] {
const tagCounts = new Map<string, number>();
feedbackList.forEach((feedback) => {
feedback.tags?.forEach((tag) => {
tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
});
});
return Array.from(tagCounts.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 10)
.map((entry) => entry[0]);
}
private getRatingDistribution(feedbackList: any[]): Record<number, number> {
const distribution = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 };
feedbackList.forEach((feedback) => {
if (feedback.rating >= 1 && feedback.rating <= 5) {
distribution[feedback.rating]++;
}
});
return distribution;
}
private getTopComments(feedbackList: any[]): any[] {
return feedbackList
.filter((f) => f.comment && f.comment.length > 0)
.sort((a, b) => b.rating - a.rating)
.slice(0, 5);
}
}
// 使用示例
const analyzer = new FeedbackAnalyzer("botId-xxx");
const report = await analyzer.analyzeFeedback({
from: Date.now() - 7 * 24 * 60 * 60 * 1000, // 最近7天
to: Date.now(),
});
console.log("反馈分析报告:", report);
// 构建反馈管理界面
class FeedbackManager {
private botId: string;
constructor(botId: string) {
this.botId = botId;
this.setupUI();
}
private setupUI() {
const filterForm = document.getElementById("feedback-filter-form");
const resultsContainer = document.getElementById("feedback-results");
const exportBtn = document.getElementById("export-feedback");
filterForm.addEventListener("submit", (e) => {
e.preventDefault();
this.loadFeedback(this.getFilterValues());
});
exportBtn.addEventListener("click", () => {
this.exportFeedback();
});
}
private getFilterValues() {
const formData = new FormData(
document.getElementById("feedback-filter-form")
);
return {
type: formData.get("type") as string,
minRating: parseInt(formData.get("minRating") as string),
maxRating: parseInt(formData.get("maxRating") as string),
from: this.parseDate(formData.get("fromDate") as string),
to: this.parseDate(formData.get("toDate") as string),
pageNumber: 1,
pageSize: 50,
};
}
private parseDate(dateString: string): number {
return dateString ? new Date(dateString).getTime() : 0;
}
async loadFeedback(filters: any) {
try {
const res = await ai.bot.getFeedback({
botId: this.botId,
...filters,
sender: "",
senderFilter: "include",
});
this.displayResults(res.feedbackList, res.total);
} catch (error) {
this.showError("加载反馈失败: " + error.message);
}
}
private displayResults(feedbackList: any[], total: number) {
const container = document.getElementById("feedback-results");
container.innerHTML = "";
const summary = document.createElement("div");
summary.className = "feedback-summary";
summary.innerHTML = `共找到 ${total} 条反馈记录`;
container.appendChild(summary);
feedbackList.forEach((feedback) => {
const feedbackCard = this.createFeedbackCard(feedback);
container.appendChild(feedbackCard);
});
}
private createFeedbackCard(feedback: any): HTMLDivElement {
const card = document.createElement("div");
card.className = `feedback-card ${feedback.type}`;
card.innerHTML = `
<div class="feedback-header">
<span class="type ${feedback.type}">${
feedback.type === "upvote" ? "👍" : "👎"
}</span>
<span class="rating">评分: ${feedback.rating}/5</span>
<span class="time">${new Date(
feedback.createTime
).toLocaleString()}</span>
</div>
<div class="feedback-content">
<div class="question"><strong>问题:</strong> ${feedback.input}</div>
<div class="answer"><strong>回答:</strong> ${feedback.aiAnswer}</div>
<div class="comment"><strong>评论:</strong> ${feedback.comment}</div>
<div class="tags"><strong>标签:</strong> ${
feedback.tags?.join(", ") || "无"
}</div>
</div>
`;
return card;
}
private async exportFeedback() {
const res = await ai.bot.getFeedback({
botId: this.botId,
from: 0,
to: Date.now(),
minRating: 1,
maxRating: 5,
pageNumber: 1,
pageSize: 10000,
sender: "",
senderFilter: "include",
type: "",
});
const csv = this.convertToCSV(res.feedbackList);
this.downloadCSV(csv, `feedback_${this.botId}_${Date.now()}.csv`);
}
private convertToCSV(feedbackList: any[]): string {
const headers = ["类型", "评分", "问题", "回答", "评论", "标签", "时间"];
const rows = feedbackList.map((f) => [
f.type,
f.rating,
f.input,
f.aiAnswer,
f.comment,
f.tags?.join(";"),
new Date(f.createTime).toLocaleString(),
]);
return [headers, ...rows]
.map((row) => row.map((cell) => `"${cell}"`).join(","))
.join("\n");
}
private downloadCSV(csv: string, filename: string) {
const blob = new Blob([csv], { type: "text/csv" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
private showError(message: string) {
const errorDiv = document.createElement("div");
errorDiv.className = "error-message";
errorDiv.textContent = message;
document.getElementById("feedback-results").appendChild(errorDiv);
}
}
// 使用示例
const feedbackManager = new FeedbackManager("botId-xxx");
uploadFiles
function uploadFiles(props: {
botId: string;
fileList: Array<{
fileId: string;
fileName: string;
type: "file";
}>;
}): Promise<void>;
将云存储中的文件上传至 Agent,用于进行文档聊天。
- 支持将云存储中的文件上传到指定的 Agent
- 上传后的文件可用于文档聊天功能
- 支持批量上传多个文件
- 适用于构建文档问答、文件分析等应用场景
参数
文件上传参数
返回
无返回值
示例
// 上传单个文件到指定 Agent
await ai.bot.uploadFiles({
botId: "botId-xxx",
fileList: [
{
fileId: "cloud://document.docx",
fileName: "document.docx",
type: "file",
},
],
});
console.log("文件上传成功");
// 批量上传多个文件
async function uploadAndChat(
botId: string,
files: Array<{ fileId: string; fileName: string }>
) {
// 上传文件
await ai.bot.uploadFiles({
botId: botId,
fileList: files.map((file) => ({
...file,
type: "file" as const,
})),
});
console.log("文件上传完成,开始文档聊天");
// 基于上传的文件进行聊天
const res = await ai.bot.sendMessage({
botId: botId,
msg: "请分析这些文档的主要内容",
files: files.map((f) => f.fileId),
});
// 流式输出回答
for await (let text of res.textStream) {
console.log(text);
}
}
// 使用示例
await uploadAndChat("your-bot-id", [
{ fileId: "cloud://report.pdf", fileName: "季度报告.pdf" },
{ fileId: "cloud://data.xlsx", fileName: "数据表格.xlsx" },
]);
// 构建文档问答系统
class DocumentQASystem {
private botId: string;
private uploadedFiles: string[] = [];
constructor(botId: string) {
this.botId = botId;
}
async uploadDocuments(files: Array<{ fileId: string; fileName: string }>) {
await ai.bot.uploadFiles({
botId: this.botId,
fileList: files.map((file) => ({
...file,
type: "file" as const,
})),
});
this.uploadedFiles.push(...files.map((f) => f.fileId));
console.log(`已上传 ${files.length} 个文件`);
}
async askQuestion(question: string): Promise<string> {
const res = await ai.bot.sendMessage({
botId: this.botId,
msg: question,
files: this.uploadedFiles,
});
let fullAnswer = "";
for await (let text of res.textStream) {
fullAnswer += text;
}
return fullAnswer;
}
async interactiveChat() {
console.log("文档问答系统已启动,输入 'exit' 退出");
while (true) {
const question = await this.getUserInput("请输入问题: ");
if (question.toLowerCase() === "exit") {
console.log("再见!");
break;
}
console.log("思考中...");
const answer = await this.askQuestion(question);
console.log("回答:", answer);
console.log("---");
}
}
private getUserInput(prompt: string): Promise<string> {
return new Promise((resolve) => {
// 在实际应用中,这里可以是浏览器输入框或命令行输入
const input = prompt;
resolve(input);
});
}
}
// 使用示例
const qaSystem = new DocumentQASystem("doc-bot-id");
// 上传文档
await qaSystem.uploadDocuments([
{ fileId: "cloud://manual.pdf", fileName: "产品手册.pdf" },
{ fileId: "cloud://faq.docx", fileName: "常见问题.docx" },
]);
// 开始交互式问答
await qaSystem.interactiveChat();
getRecommendQuestions
function getRecommendQuestions(props: {
botId: string;
name: string;
introduction: string;
agentSetting: string;
msg: string;
history: Array<{
role: string;
content: string;
}>;
}): Promise<StreamResult>;
获取推荐的问题,基于对话上下文智能生成相关问题建议。
- 根据当前对话内容和历史记录智能推荐相关问题
- 支持流式返回,实时获取推荐问题
- 适用于构建智能对话助手、聊天机器人等应用
- 帮助用户发现更多相关话题,提升对话体验
参数
获取推荐问题的参数
返回
流式返回的推荐问题结果
示例
// 获取推荐问题
const res = await ai.bot.getRecommendQuestions({
botId: "botId-xxx",
name: "智能助手",
introduction: "我是一个智能对话助手",
agentSetting: "专业、友好的AI助手",
msg: "你好,我想了解人工智能",
history: [
{ content: "你是谁啊", role: "user" },
{ content: "我是一个智能助手,可以帮助你解答各种问题", role: "assistant" },
],
});
// 流式获取推荐问题
for await (let question of res.textStream) {
console.log("推荐问题:", question);
}
// 构建智能对话助手,自动推荐相关问题
class SmartChatAssistant {
private botId: string;
private conversationHistory: Array<{ role: string; content: string }> = [];
constructor(botId: string) {
this.botId = botId;
}
async sendMessage(message: string): Promise<string> {
// 添加用户消息到历史记录
this.conversationHistory.push({ role: "user", content: message });
// 发送消息并获取回答
const response = await ai.bot.sendMessage({
botId: this.botId,
msg: message,
history: this.conversationHistory,
});
let assistantReply = "";
for await (let text of response.textStream) {
assistantReply += text;
}
// 添加助手回答到历史记录
this.conversationHistory.push({
role: "assistant",
content: assistantReply,
});
return assistantReply;
}
async getRecommendedQuestions(): Promise<string[]> {
if (this.conversationHistory.length === 0) {
return [];
}
const latestMessage =
this.conversationHistory[this.conversationHistory.length - 1].content;
const res = await ai.bot.getRecommendQuestions({
botId: this.botId,
name: "智能助手",
introduction: "智能对话助手",
agentSetting: "",
msg: latestMessage,
history: this.conversationHistory,
});
const questions: string[] = [];
for await (let question of res.textStream) {
questions.push(question);
}
return questions;
}
async interactiveChat() {
console.log(
"智能助手已启动,输入 'exit' 退出,输入 'suggest' 获取推荐问题"
);
while (true) {
const userInput = await this.getUserInput("请输入: ");
if (userInput.toLowerCase() === "exit") {
console.log("再见!");
break;
}
if (userInput.toLowerCase() === "suggest") {
console.log("正在为您推荐相关问题...");
const questions = await this.getRecommendedQuestions();
console.log("推荐问题:");
questions.forEach((q, i) => console.log(`${i + 1}. ${q}`));
continue;
}
console.log("思考中...");
const reply = await this.sendMessage(userInput);
console.log("助手回答:", reply);
// 自动推荐相关问题
console.log("\n您可能还想了解:");
const questions = await this.getRecommendedQuestions();
questions.slice(0, 3).forEach((q, i) => console.log(`${i + 1}. ${q}`));
console.log("---");
}
}
private getUserInput(prompt: string): Promise<string> {
return new Promise((resolve) => {
// 实际应用中这里可以是浏览器输入框
const input = prompt;
resolve(input);
});
}
}
// 使用示例
const assistant = new SmartChatAssistant("smart-bot-id");
await assistant.interactiveChat();
// 电商客服场景下的推荐问题应用
class EcommerceCustomerService {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async handleCustomerQuery(
query: string
): Promise<{ answer: string; suggestions: string[] }> {
const response = await ai.bot.sendMessage({
botId: this.botId,
msg: query,
history: [],
});
let answer = "";
for await (let text of response.textStream) {
answer += text;
}
// 获取相关推荐问题
const recommendRes = await ai.bot.getRecommendQuestions({
botId: this.botId,
name: "电商客服",
introduction: "专业的电商客服助手",
agentSetting: "专注于解答电商相关问题",
msg: query,
history: [
{ role: "user", content: query },
{ role: "assistant", content: answer },
],
});
const suggestions: string[] = [];
for await (let suggestion of recommendRes.textStream) {
suggestions.push(suggestion);
}
return { answer, suggestions };
}
// 处理常见电商场景
async handleProductInquiry(productName: string) {
const query = `我想了解 ${productName} 这个产品`;
const result = await this.handleCustomerQuery(query);
console.log("客服回答:", result.answer);
console.log("\n您可能还想了解:");
result.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
return result;
}
async handleOrderInquiry(orderId: string) {
const query = `查询订单 ${orderId} 的状态`;
const result = await this.handleCustomerQuery(query);
console.log("订单状态:", result.answer);
console.log("\n相关服务:");
result.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
return result;
}
}
// 使用示例
const customerService = new EcommerceCustomerService("ecommerce-bot-id");
// 处理产品咨询
await customerService.handleProductInquiry("iPhone 15");
// 处理订单查询
await customerService.handleOrderInquiry("ORD20231226001");
createConversation
function createConversation(props: {
botId: string;
title?: string;
}): Promise<IConversation>;
创建与 Agent 的新对话,建立独立的对话会话。
- 为指定的 Agent 创建新的对话会话
- 支持自定义对话标题,便于管理和识别
- 每个对话会话独立存储对话历史
- 适用于多用户、多场景的对话管理需求
参数
创建对话的参数
返回
创建的对话信息
示例
// 创建新的对话会话
const conversation = await ai.bot.createConversation({
botId: "botId-xxx",
title: "技术咨询对话",
});
console.log("对话创建成功:", conversation.conversationId);
console.log("对话标题:", conversation.title);
// 多用户对话管理系统
class ConversationManager {
private botId: string;
private userConversations: Map<string, string> = new Map(); // userId -> conversationId
constructor(botId: string) {
this.botId = botId;
}
async createUserConversation(
userId: string,
title?: string
): Promise<string> {
const conversation = await ai.bot.createConversation({
botId: this.botId,
title: title || `${userId}的对话`,
});
this.userConversations.set(userId, conversation.conversationId);
console.log(`为用户 ${userId} 创建对话: ${conversation.conversationId}`);
return conversation.conversationId;
}
async getUserConversation(userId: string): Promise<string | null> {
return this.userConversations.get(userId) || null;
}
async sendMessageToUser(userId: string, message: string): Promise<string> {
let conversationId = await this.getUserConversation(userId);
if (!conversationId) {
conversationId = await this.createUserConversation(userId);
}
const response = await ai.bot.sendMessage({
botId: this.botId,
msg: message,
conversationId: conversationId,
});
let reply = "";
for await (let text of response.textStream) {
reply += text;
}
return reply;
}
async getConversationHistory(userId: string) {
const conversationId = await this.getUserConversation(userId);
if (!conversationId) {
return [];
}
const conversation = await ai.bot.getConversation({
botId: this.botId,
conversationId: conversationId,
});
return conversation.history || [];
}
}
// 使用示例
const manager = new ConversationManager("support-bot-id");
// 为用户创建对话
await manager.createUserConversation("user123", "技术支持对话");
// 发送消息
const reply = await manager.sendMessageToUser("user123", "我的账户有问题");
console.log("助手回复:", reply);
// 获取对话历史
const history = await manager.getConversationHistory("user123");
console.log("对话历史:", history);
// 多主题对话管理系统
class MultiTopicConversationManager {
private botId: string;
private topicConversations: Map<string, string> = new Map(); // topic -> conversationId
constructor(botId: string) {
this.botId = botId;
}
async createTopicConversation(topic: string): Promise<string> {
const conversation = await ai.bot.createConversation({
botId: this.botId,
title: `关于${topic}的讨论`,
});
this.topicConversations.set(topic, conversation.conversationId);
console.log(`创建主题对话: ${topic} -> ${conversation.conversationId}`);
return conversation.conversationId;
}
async switchTopic(topic: string, message: string): Promise<string> {
let conversationId = this.topicConversations.get(topic);
if (!conversationId) {
conversationId = await this.createTopicConversation(topic);
}
const response = await ai.bot.sendMessage({
botId: this.botId,
msg: message,
conversationId: conversationId,
});
let reply = "";
for await (let text of response.textStream) {
reply += text;
}
return reply;
}
async getTopicSummary(topic: string): Promise<string> {
const conversationId = this.topicConversations.get(topic);
if (!conversationId) {
return "该主题暂无对话记录";
}
const conversation = await ai.bot.getConversation({
botId: this.botId,
conversationId: conversationId,
});
const history = conversation.history || [];
const messageCount = history.length;
const lastMessage =
history.length > 0 ? history[history.length - 1].content : "无";
return `主题: ${topic}\n对话数量: ${messageCount}\n最后消息: ${lastMessage}`;
}
listTopics(): string[] {
return Array.from(this.topicConversations.keys());
}
}
// 使用示例
const topicManager = new MultiTopicConversationManager("multi-topic-bot-id");
// 在不同主题间切换对话
const techReply = await topicManager.switchTopic(
"技术问题",
"如何解决这个bug?"
);
console.log("技术问题回复:", techReply);
const businessReply = await topicManager.switchTopic(
"商务合作",
"我们想谈合作"
);
console.log("商务合作回复:", businessReply);
// 回到技术问题继续对话
const techReply2 = await topicManager.switchTopic(
"技术问题",
"还有其他解决方案吗?"
);
console.log("技术问题继续:", techReply2);
// 查看主题摘要
console.log("所有主题:", topicManager.listTopics());
const summary = await topicManager.getTopicSummary("技术问题");
console.log("技术问题摘要:\n", summary);
getConversation
function getConversation(props: {
botId: string;
pageSize?: number;
pageNumber?: number;
isDefault?: boolean;
}): Promise<ConversationListResult>;
获取 Agent 的对话列表,支持分页查询和条件筛选。
- 查询指定 Agent 的所有对话记录
- 支持分页查询,便于管理大量对话
- 可筛选默认对话或所有对话
- 适用于对话管理、历史记录查看等场景
参数
获取对话列表的参数
返回
对话列表查询结果
示例
// 获取对话列表
const result = await ai.bot.getConversation({
botId: "botId-xxx",
pageSize: 10,
pageNumber: 1,
isDefault: false,
});
console.log(`共有 ${result.total} 个对话`);
result.conversations.forEach((conversation, index) => {
console.log(
`${index + 1}. ${conversation.title} (${conversation.messageCount} 条消息)`
);
});
// 对话管理系统
class ConversationManagementSystem {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async getAllConversations(): Promise<IConversation[]> {
let allConversations: IConversation[] = [];
let pageNumber = 1;
const pageSize = 50;
while (true) {
const result = await ai.bot.getConversation({
botId: this.botId,
pageSize: pageSize,
pageNumber: pageNumber,
isDefault: false,
});
allConversations = allConversations.concat(result.conversations);
if (result.conversations.length < pageSize) {
break;
}
pageNumber++;
}
return allConversations;
}
async searchConversations(keyword: string): Promise<IConversation[]> {
const allConversations = await this.getAllConversations();
return allConversations.filter((conversation) =>
conversation.title.toLowerCase().includes(keyword.toLowerCase())
);
}
async getRecentConversations(days: number = 7): Promise<IConversation[]> {
const allConversations = await this.getAllConversations();
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - days);
return allConversations.filter((conversation) => {
const updateTime = new Date(conversation.updateTime);
return updateTime >= cutoffDate;
});
}
async getConversationStats(): Promise<{
total: number;
recent: number;
averageMessages: number;
}> {
const allConversations = await this.getAllConversations();
const recentConversations = await this.getRecentConversations(7);
const totalMessages = allConversations.reduce(
(sum, conv) => sum + conv.messageCount,
0
);
const averageMessages =
allConversations.length > 0 ? totalMessages / allConversations.length : 0;
return {
total: allConversations.length,
recent: recentConversations.length,
averageMessages: Math.round(averageMessages),
};
}
async exportConversationList(): Promise<string> {
const allConversations = await this.getAllConversations();
const csv = [
"对话ID,标题,创建时间,最后更新时间,消息数量",
...allConversations.map(
(conv) =>
`${conv.conversationId},"${conv.title}",${conv.createTime},${conv.updateTime},${conv.messageCount}`
),
].join("\n");
return csv;
}
}
// 使用示例
const manager = new ConversationManagementSystem("management-bot-id");
// 获取对话统计
const stats = await manager.getConversationStats();
console.log(`总对话数: ${stats.total}`);
console.log(`最近7天对话数: ${stats.recent}`);
console.log(`平均消息数: ${stats.averageMessages}`);
// 搜索对话
const searchResults = await manager.searchConversations("技术");
console.log(`找到 ${searchResults.length} 个技术相关对话`);
// 导出对话列表
const csvData = await manager.exportConversationList();
console.log("对话列表导出完成");
// 批量对话分析工具
class ConversationAnalyzer {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async analyzeConversationPatterns(): Promise<{
timeDistribution: { hour: number; count: number }[];
messageLengthStats: { avgLength: number; maxLength: number };
topicDistribution: Map<string, number>;
}> {
const allConversations = await this.getAllConversations();
// 时间分布分析
const timeDistribution = Array.from({ length: 24 }, (_, hour) => ({
hour,
count: allConversations.filter((conv) => {
const hour = new Date(conv.createTime).getHours();
return hour === hour;
}).length,
}));
// 消息长度统计
const messageLengths = allConversations.map((conv) => conv.messageCount);
const avgLength =
messageLengths.reduce((sum, len) => sum + len, 0) / messageLengths.length;
const maxLength = Math.max(...messageLengths);
// 主题分布分析(基于标题关键词)
const topicDistribution = new Map<string, number>();
const topics = ["技术", "商务", "客服", "产品", "其他"];
topics.forEach((topic) => {
const count = allConversations.filter((conv) =>
conv.title.includes(topic)
).length;
topicDistribution.set(topic, count);
});
return {
timeDistribution,
messageLengthStats: { avgLength, maxLength },
topicDistribution,
};
}
async getConversationTrends(): Promise<{
dailyTrends: { date: string; count: number }[];
weeklyTrends: { week: string; count: number }[];
}> {
const allConversations = await this.getAllConversations();
// 按日期分组
const dailyCounts = new Map<string, number>();
allConversations.forEach((conv) => {
const date = new Date(conv.createTime).toISOString().split("T")[0];
dailyCounts.set(date, (dailyCounts.get(date) || 0) + 1);
});
const dailyTrends = Array.from(dailyCounts.entries())
.map(([date, count]) => ({
date,
count,
}))
.sort((a, b) => a.date.localeCompare(b.date));
// 按周分组
const weeklyCounts = new Map<string, number>();
allConversations.forEach((conv) => {
const date = new Date(conv.createTime);
const weekStart = new Date(date);
weekStart.setDate(date.getDate() - date.getDay());
const weekKey = weekStart.toISOString().split("T")[0];
weeklyCounts.set(weekKey, (weeklyCounts.get(weekKey) || 0) + 1);
});
const weeklyTrends = Array.from(weeklyCounts.entries())
.map(([week, count]) => ({
week,
count,
}))
.sort((a, b) => a.week.localeCompare(b.week));
return { dailyTrends, weeklyTrends };
}
private async getAllConversations(): Promise<IConversation[]> {
let allConversations: IConversation[] = [];
let pageNumber = 1;
const pageSize = 100;
while (true) {
const result = await ai.bot.getConversation({
botId: this.botId,
pageSize: pageSize,
pageNumber: pageNumber,
isDefault: false,
});
allConversations = allConversations.concat(result.conversations);
if (result.conversations.length < pageSize) {
break;
}
pageNumber++;
}
return allConversations;
}
}
// 使用示例
const analyzer = new ConversationAnalyzer("analytics-bot-id");
// 分析对话模式
const patterns = await analyzer.analyzeConversationPatterns();
console.log("对话时间分布:", patterns.timeDistribution);
console.log("消息长度统计:", patterns.messageLengthStats);
console.log("主题分布:", patterns.topicDistribution);
// 获取对话趋势
const trends = await analyzer.getConversationTrends();
console.log("每日趋势:", trends.dailyTrends);
console.log("每周趋势:", trends.weeklyTrends);
deleteConversation
function deleteConversation(props: {
botId: string;
conversationId: string;
}): Promise<void>;
删除指定的对话会话,清理对话历史记录。
- 永久删除指定的对话会话
- 清理对话中的所有消息记录
- 释放存储空间,优化系统性能
- 适用于对话管理、数据清理等场景
参数
删除对话的参数
返回
删除操作完成,无返回值
示例
// 删除指定的对话
await ai.bot.deleteConversation({
botId: "botId-xxx",
conversationId: "conv-123",
});
console.log("对话删除成功");
// 批量对话清理工具
class ConversationCleaner {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async deleteOldConversations(daysThreshold: number = 30): Promise<number> {
const allConversations = await this.getAllConversations();
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysThreshold);
const oldConversations = allConversations.filter((conversation) => {
const updateTime = new Date(conversation.updateTime);
return updateTime < cutoffDate;
});
console.log(
`找到 ${oldConversations.length} 个超过 ${daysThreshold} 天的旧对话`
);
// 批量删除旧对话
let deletedCount = 0;
for (const conversation of oldConversations) {
try {
await ai.bot.deleteConversation({
botId: this.botId,
conversationId: conversation.conversationId,
});
deletedCount++;
console.log(`已删除对话: ${conversation.title}`);
} catch (error) {
console.error(`删除对话失败: ${conversation.title}`, error);
}
}
console.log(`成功删除 ${deletedCount} 个旧对话`);
return deletedCount;
}
async deleteEmptyConversations(): Promise<number> {
const allConversations = await this.getAllConversations();
const emptyConversations = allConversations.filter(
(conversation) => conversation.messageCount === 0
);
console.log(`找到 ${emptyConversations.length} 个空对话`);
let deletedCount = 0;
for (const conversation of emptyConversations) {
try {
await ai.bot.deleteConversation({
botId: this.botId,
conversationId: conversation.conversationId,
});
deletedCount++;
} catch (error) {
console.error(`删除空对话失败: ${conversation.title}`, error);
}
}
console.log(`成功删除 ${deletedCount} 个空对话`);
return deletedCount;
}
async deleteConversationsByTitle(keyword: string): Promise<number> {
const allConversations = await this.getAllConversations();
const matchingConversations = allConversations.filter((conversation) =>
conversation.title.toLowerCase().includes(keyword.toLowerCase())
);
console.log(
`找到 ${matchingConversations.length} 个包含"${keyword}"的对话`
);
let deletedCount = 0;
for (const conversation of matchingConversations) {
try {
await ai.bot.deleteConversation({
botId: this.botId,
conversationId: conversation.conversationId,
});
deletedCount++;
console.log(`已删除: ${conversation.title}`);
} catch (error) {
console.error(`删除对话失败: ${conversation.title}`, error);
}
}
return deletedCount;
}
private async getAllConversations(): Promise<IConversation[]> {
let allConversations: IConversation[] = [];
let pageNumber = 1;
const pageSize = 100;
while (true) {
const result = await ai.bot.getConversation({
botId: this.botId,
pageSize: pageSize,
pageNumber: pageNumber,
isDefault: false,
});
allConversations = allConversations.concat(result.conversations);
if (result.conversations.length < pageSize) {
break;
}
pageNumber++;
}
return allConversations;
}
}
// 使用示例
const cleaner = new ConversationCleaner("cleanup-bot-id");
// 删除30天前的旧对话
const oldDeleted = await cleaner.deleteOldConversations(30);
console.log(`清理了 ${oldDeleted} 个旧对话`);
// 删除空对话
const emptyDeleted = await cleaner.deleteEmptyConversations();
console.log(`清理了 ${emptyDeleted} 个空对话`);
// 删除包含特定关键词的对话
const keywordDeleted = await cleaner.deleteConversationsByTitle("测试");
console.log(`清理了 ${keywordDeleted} 个测试对话`);
// 用户数据管理系统
class UserDataManager {
private botId: string;
private userConversations: Map<string, string[]> = new Map(); // userId -> conversationIds
constructor(botId: string) {
this.botId = botId;
}
async deleteUserConversations(userId: string): Promise<number> {
const userConversationIds = this.userConversations.get(userId) || [];
console.log(`为用户 ${userId} 删除 ${userConversationIds.length} 个对话`);
let deletedCount = 0;
for (const conversationId of userConversationIds) {
try {
await ai.bot.deleteConversation({
botId: this.botId,
conversationId: conversationId,
});
deletedCount++;
console.log(`已删除对话: ${conversationId}`);
} catch (error) {
console.error(`删除对话失败: ${conversationId}`, error);
}
}
// 从内存中移除用户对话记录
this.userConversations.delete(userId);
console.log(`用户 ${userId} 的数据清理完成,删除了 ${deletedCount} 个对话`);
return deletedCount;
}
async deleteAllUserData(): Promise<number> {
const allUserIds = Array.from(this.userConversations.keys());
let totalDeleted = 0;
console.log(`开始清理 ${allUserIds.length} 个用户的数据`);
for (const userId of allUserIds) {
const deletedCount = await this.deleteUserConversations(userId);
totalDeleted += deletedCount;
}
console.log(`总共清理了 ${totalDeleted} 个对话`);
return totalDeleted;
}
async deleteUserDataByCondition(
condition: (userId: string, conversationIds: string[]) => boolean
): Promise<number> {
const usersToDelete: string[] = [];
for (const [userId, conversationIds] of this.userConversations.entries()) {
if (condition(userId, conversationIds)) {
usersToDelete.push(userId);
}
}
console.log(`找到 ${usersToDelete.length} 个符合条件的用户`);
let totalDeleted = 0;
for (const userId of usersToDelete) {
const deletedCount = await this.deleteUserConversations(userId);
totalDeleted += deletedCount;
}
return totalDeleted;
}
// 添加用户对话记录
addUserConversation(userId: string, conversationId: string) {
if (!this.userConversations.has(userId)) {
this.userConversations.set(userId, []);
}
this.userConversations.get(userId)!.push(conversationId);
}
// 获取用户对话统计
getUserStats(): { totalUsers: number; totalConversations: number } {
let totalConversations = 0;
for (const conversationIds of this.userConversations.values()) {
totalConversations += conversationIds.length;
}
return {
totalUsers: this.userConversations.size,
totalConversations: totalConversations,
};
}
}
// 使用示例
const dataManager = new UserDataManager("data-management-bot-id");
// 添加用户对话记录
dataManager.addUserConversation("user1", "conv-123");
dataManager.addUserConversation("user1", "conv-456");
dataManager.addUserConversation("user2", "conv-789");
// 查看统计
const stats = dataManager.getUserStats();
console.log(`用户数: ${stats.totalUsers}, 对话数: ${stats.totalConversations}`);
// 删除特定用户数据
const deletedCount = await dataManager.deleteUserConversations("user1");
console.log(`删除了用户1的 ${deletedCount} 个对话`);
// 条件删除:删除对话数超过阈值的用户
const conditionDeleted = await dataManager.deleteUserDataByCondition(
(userId, conversationIds) => conversationIds.length > 5
);
console.log(`删除了 ${conditionDeleted} 个对话数超过5的用户数据`);
speechToText
function speechToText(props: {
botId: string;
engSerViceType: string;
voiceFormat: string;
url: string;
isPreview?: boolean;
}): Promise<SpeechToTextResult>;
将语音文件转换为文字,支持多种音频格式和语言识别。
- 支持多种音频格式:MP3、WAV、AAC 等
- 支持多种语言识别引擎
- 可处理本地或远程音频文件
- 适用于语音助手、会议记录、语音笔记等场景
参数
语音转文字的参数
返回
语音识别结果
示例
// 将语音文件转换为文字
const result = await ai.bot.speechToText({
botId: "speech-bot-id",
engSerViceType: "16k_zh",
voiceFormat: "mp3",
url: "https://example.com/audio.mp3",
});
console.log("识别结果:", result.text);
console.log("置信度:", result.confidence);
console.log("音频时长:", result.duration, "秒");
console.log("识别语言:", result.language);
// 语音助手应用
class VoiceAssistant {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async processVoiceCommand(audioUrl: string): Promise<{
text: string;
response: string;
action?: string;
}> {
// 语音转文字
const speechResult = await ai.bot.speechToText({
botId: this.botId,
engSerViceType: "16k_zh",
voiceFormat: "mp3",
url: audioUrl,
});
console.log("语音识别结果:", speechResult.text);
// 根据识别结果生成回复
const response = await ai.bot.sendMessage({
botId: this.botId,
msg: speechResult.text,
});
let assistantReply = "";
for await (let text of response.textStream) {
assistantReply += text;
}
// 分析是否需要执行特定操作
const action = this.analyzeCommand(speechResult.text);
return {
text: speechResult.text,
response: assistantReply,
action: action,
};
}
async createVoiceNote(audioUrl: string, title?: string): Promise<string> {
const result = await ai.bot.speechToText({
botId: this.botId,
engSerViceType: "16k_zh",
voiceFormat: "mp3",
url: audioUrl,
});
const noteContent = `
语音笔记 - ${title || new Date().toLocaleString()}
音频时长: ${result.duration}秒
识别置信度: ${Math.round(result.confidence * 100)}%
内容:
${result.text}
`;
console.log("语音笔记创建成功:");
console.log(noteContent);
return noteContent;
}
async batchTranscribe(
audioFiles: Array<{ url: string; name: string }>
): Promise<Map<string, string>> {
const results = new Map<string, string>();
console.log(`开始批量转换 ${audioFiles.length} 个音频文件`);
for (const file of audioFiles) {
try {
const result = await ai.bot.speechToText({
botId: this.botId,
engSerViceType: "16k_zh",
voiceFormat: this.getFileFormat(file.url),
url: file.url,
});
results.set(file.name, result.text);
console.log(`✓ ${file.name}: 转换成功`);
} catch (error) {
console.error(`✗ ${file.name}: 转换失败`, error);
results.set(file.name, "转换失败");
}
}
console.log("批量转换完成");
return results;
}
private analyzeCommand(text: string): string | undefined {
const commands = {
天气: "weather",
时间: "time",
播放: "play",
停止: "stop",
搜索: "search",
};
for (const [keyword, action] of Object.entries(commands)) {
if (text.includes(keyword)) {
return action;
}
}
return undefined;
}
private getFileFormat(url: string): string {
const extension = url.split(".").pop()?.toLowerCase();
return extension === "wav" ? "wav" : "mp3";
}
}
// 使用示例
const voiceAssistant = new VoiceAssistant("voice-bot-id");
// 处理语音命令
const commandResult = await voiceAssistant.processVoiceCommand(
"voice-command.mp3"
);
console.log("语音命令:", commandResult.text);
console.log("助手回复:", commandResult.response);
if (commandResult.action) {
console.log("执行操作:", commandResult.action);
}
// 创建语音笔记
const note = await voiceAssistant.createVoiceNote(
"meeting-recording.mp3",
"会议记录"
);
// 批量转换音频文件
const audioFiles = [
{ url: "audio1.mp3", name: "采访录音1" },
{ url: "audio2.wav", name: "会议录音2" },
{ url: "audio3.mp3", name: "讲座录音3" },
];
const transcriptions = await voiceAssistant.batchTranscribe(audioFiles);
// 智能会议记录系统
class MeetingTranscriptionSystem {
private botId: string;
constructor(botId: string) {
this.botId = botId;
}
async transcribeMeeting(
audioUrl: string,
participants: string[] = []
): Promise<{
transcript: string;
summary: string;
actionItems: string[];
speakerAnalysis: Map<string, number>;
}> {
// 语音转文字
const speechResult = await ai.bot.speechToText({
botId: this.botId,
engSerViceType: "16k_zh",
voiceFormat: "mp3",
url: audioUrl,
});
console.log("会议录音转换完成,时长:", speechResult.duration, "秒");
// 生成会议摘要
const summaryPrompt = `请为以下会议内容生成摘要,提取关键决策和行动项:\n\n${speechResult.text}`;
const summaryResponse = await ai.bot.sendMessage({
botId: this.botId,
msg: summaryPrompt,
});
let summary = "";
for await (let text of summaryResponse.textStream) {
summary += text;
}
// 提取行动项
const actionPrompt = `从以下会议内容中提取具体的行动项和负责人:\n\n${speechResult.text}`;
const actionResponse = await ai.bot.sendMessage({
botId: this.botId,
msg: actionPrompt,
});
let actionText = "";
for await (let text of actionResponse.textStream) {
actionText += text;
}
const actionItems = actionText
.split("\n")
.filter((item) => item.trim().length > 0);
// 分析发言分布(简单版本)
const speakerAnalysis = this.analyzeSpeakerDistribution(
speechResult.text,
participants
);
return {
transcript: speechResult.text,
summary: summary,
actionItems: actionItems,
speakerAnalysis: speakerAnalysis,
};
}
async generateMeetingMinutes(
audioUrl: string,
meetingTitle: string,
participants: string[]
): Promise<string> {
const meetingData = await this.transcribeMeeting(audioUrl, participants);
const minutes = `
会议纪要
========
会议标题: ${meetingTitle}
会议时长: ${
meetingData.transcript.length > 0
? "约" + Math.ceil(meetingData.transcript.length / 200) + "分钟"
: "未知"
}
参会人员: ${participants.join(", ")}
会议摘要
--------
${meetingData.summary}
会议记录
--------
${meetingData.transcript}
行动项
------
${meetingData.actionItems
.map((item, index) => `${index + 1}. ${item}`)
.join("\n")}
发言统计
--------
${Array.from(meetingData.speakerAnalysis.entries())
.map(([speaker, count]) => `${speaker}: ${count} 次发言`)
.join("\n")}
`;
console.log("会议纪要生成完成");
return minutes;
}
private analyzeSpeakerDistribution(
transcript: string,
participants: string[]
): Map<string, number> {
const distribution = new Map<string, number>();
// 为每个参与者初始化计数
participants.forEach((participant) => {
distribution.set(participant, 0);
});
// 简单分析:统计参与者名字出现的次数
participants.forEach((participant) => {
const regex = new RegExp(participant, "gi");
const count = (transcript.match(regex) || []).length;
distribution.set(participant, count);
});
return distribution;
}
}
// 使用示例
const meetingSystem = new MeetingTranscriptionSystem("meeting-bot-id");
// 生成会议纪要
const minutes = await meetingSystem.generateMeetingMinutes(
"meeting-recording.mp3",
"季度规划会议",
["张三", "李四", "王五"]
);
console.log(minutes);
// 直接转录会议
const meetingData = await meetingSystem.transcribeMeeting("team-meeting.mp3");
console.log("会议摘要:", meetingData.summary);
console.log("行动项:", meetingData.actionItems);
textToSpeech
function textToSpeech(props: {
botId: string;
voiceType: number;
text: string;
isPreview?: boolean;
}): Promise<TextToSpeechResult>;
将文本转换为语音,支持多种语音类型和音色选择。
- 支持多种语音类型和音色选择
- 可调节语速、音调等参数
- 支持长文本分段转换
- 适用于语音播报、有声读物、语音助手等场景
参数
文字转语音的参数
返回
文字转语音的结果
示例
// 将文本转换为语音
const result = await ai.bot.textToSpeech({
botId: "tts-bot-id",
voiceType: 1, // 标准女声
text: "你好,我是AI语音助手,很高兴为您服务。",
});
console.log("语音合成完成:");
console.log("音频地址:", result.audioUrl);
console.log("音频时长:", result.duration, "秒");
console.log("文件格式:", result.format);
console.log("文件大小:", result.size, "字节");
// 智能语音助手
class VoiceAssistant {
private botId: string;
private voiceType: number;
constructor(botId: string, voiceType: number = 1) {
this.botId = botId;
this.voiceType = voiceType;
}
async speakText(text: string): Promise<string> {
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: this.voiceType,
text: text,
});
console.log(`语音合成完成: ${result.duration}秒`);
// 在实际应用中,这里可以播放音频
this.playAudio(result.audioUrl);
return result.audioUrl;
}
async createAudioBook(
chapters: Array<{ title: string; content: string }>
): Promise<Map<string, string>> {
const audioFiles = new Map<string, string>();
console.log(`开始制作有声读物,共 ${chapters.length} 章`);
for (const [index, chapter] of chapters.entries()) {
console.log(`正在合成第 ${index + 1} 章: ${chapter.title}`);
try {
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: this.voiceType,
text: chapter.content,
});
audioFiles.set(chapter.title, result.audioUrl);
console.log(`✓ 第 ${index + 1} 章合成完成,时长: ${result.duration}秒`);
} catch (error) {
console.error(`✗ 第 ${index + 1} 章合成失败`, error);
}
}
console.log("有声读物制作完成");
return audioFiles;
}
async generateInteractiveStory(
storyTitle: string,
storyContent: string[]
): Promise<{
audioFiles: string[];
totalDuration: number;
}> {
const audioFiles: string[] = [];
let totalDuration = 0;
console.log(`开始生成交互式故事: ${storyTitle}`);
for (const [index, paragraph] of storyContent.entries()) {
console.log(`合成第 ${index + 1} 段内容`);
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: this.voiceType,
text: paragraph,
});
audioFiles.push(result.audioUrl);
totalDuration += result.duration;
console.log(`✓ 第 ${index + 1} 段合成完成,时长: ${result.duration}秒`);
}
console.log(`故事生成完成,总时长: ${totalDuration}秒`);
return { audioFiles, totalDuration };
}
async createVoiceAnnouncement(
message: string,
repeat: number = 1
): Promise<string[]> {
const announcements: string[] = [];
console.log(`生成语音播报,重复 ${repeat} 次`);
for (let i = 0; i < repeat; i++) {
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: this.voiceType,
text: message,
});
announcements.push(result.audioUrl);
console.log(`✓ 第 ${i + 1} 次播报生成完成`);
}
return announcements;
}
private playAudio(audioUrl: string): void {
// 在实际应用中,这里可以实现音频播放逻辑
console.log("播放音频:", audioUrl);
// 示例:使用HTML5 Audio API播放
// const audio = new Audio(audioUrl);
// audio.play();
}
// 设置语音类型
setVoiceType(voiceType: number): void {
this.voiceType = voiceType;
console.log(`语音类型已设置为: ${voiceType}`);
}
// 获取支持的语音类型
getSupportedVoices(): Array<{ id: number; name: string }> {
return [
{ id: 1, name: "标准女声" },
{ id: 2, name: "标准男声" },
{ id: 3, name: "情感女声" },
{ id: 4, name: "情感男声" },
{ id: 5, name: "儿童声音" },
{ id: 6, name: "老年声音" },
];
}
}
// 使用示例
const voiceAssistant = new VoiceAssistant("voice-bot-id", 1);
// 简单语音播报
const audioUrl = await voiceAssistant.speakText("欢迎使用语音助手系统!");
// 制作有声读物
const chapters = [
{ title: "第一章", content: "这是一个故事的开头..." },
{ title: "第二章", content: "故事继续发展..." },
{ title: "第三章", content: "故事的高潮部分..." },
];
const audioBook = await voiceAssistant.createAudioBook(chapters);
// 生成交互式故事
const storyContent = [
"从前有一个小村庄...",
"村庄里住着一位聪明的老人...",
"老人教会了村民很多知识...",
];
const story = await voiceAssistant.generateInteractiveStory(
"智慧老人",
storyContent
);
// 创建语音播报
const announcements = await voiceAssistant.createVoiceAnnouncement(
"请注意,系统即将维护",
3
);
// 多语言语音合成系统
class MultiLanguageVoiceSystem {
private botId: string;
private languageVoices: Map<string, number> = new Map();
constructor(botId: string) {
this.botId = botId;
this.initializeLanguageVoices();
}
private initializeLanguageVoices(): void {
this.languageVoices.set("zh-CN", 1); // 中文-标准女声
this.languageVoices.set("en-US", 2); // 英文-标准男声
this.languageVoices.set("ja-JP", 3); // 日语-情感女声
this.languageVoices.set("ko-KR", 4); // 韩语-情感男声
this.languageVoices.set("fr-FR", 1); // 法语-标准女声
this.languageVoices.set("de-DE", 2); // 德语-标准男声
}
async synthesizeMultilingualText(
texts: Map<string, string>
): Promise<Map<string, string>> {
const results = new Map<string, string>();
console.log(`开始合成多语言文本,共 ${texts.size} 种语言`);
for (const [language, text] of texts.entries()) {
const voiceType = this.languageVoices.get(language) || 1;
console.log(`合成 ${language} 语言文本`);
try {
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: voiceType,
text: text,
});
results.set(language, result.audioUrl);
console.log(`✓ ${language} 语言合成完成,时长: ${result.duration}秒`);
} catch (error) {
console.error(`✗ ${language} 语言合成失败`, error);
results.set(language, "合成失败");
}
}
return results;
}
async createInternationalAnnouncement(
message: string
): Promise<Map<string, string>> {
const translations = await this.translateMessage(message);
return this.synthesizeMultilingualText(translations);
}
async generateLanguageLearningAudio(
language: string,
phrases: string[]
): Promise<Array<{ phrase: string; audioUrl: string }>> {
const learningAudios: Array<{ phrase: string; audioUrl: string }> = [];
const voiceType = this.languageVoices.get(language) || 1;
console.log(`生成 ${language} 语言学习音频,共 ${phrases.length} 个短语`);
for (const phrase of phrases) {
try {
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: voiceType,
text: phrase,
});
learningAudios.push({
phrase: phrase,
audioUrl: result.audioUrl,
});
console.log(`✓ 短语 "${phrase}" 音频生成完成`);
} catch (error) {
console.error(`✗ 短语 "${phrase}" 音频生成失败`, error);
}
}
return learningAudios;
}
async createTourGuideAudio(
language: string,
attractions: Array<{ name: string; description: string }>
): Promise<Map<string, string>> {
const guideAudios = new Map<string, string>();
const voiceType = this.languageVoices.get(language) || 1;
console.log(
`生成 ${language} 语言导游音频,共 ${attractions.length} 个景点`
);
for (const attraction of attractions) {
const description = `${attraction.name}:${attraction.description}`;
try {
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: voiceType,
text: description,
});
guideAudios.set(attraction.name, result.audioUrl);
console.log(`✓ 景点 "${attraction.name}" 导游音频生成完成`);
} catch (error) {
console.error(`✗ 景点 "${attraction.name}" 导游音频生成失败`, error);
}
}
return guideAudios;
}
private async translateMessage(
message: string
): Promise<Map<string, string>> {
// 在实际应用中,这里可以调用翻译API
const translations = new Map<string, string>();
translations.set("zh-CN", message); // 中文
translations.set("en-US", "Hello, this is an announcement."); // 英文
translations.set("ja-JP", "こんにちは、これはアナウンスです。"); // 日语
translations.set("ko-KR", "안녕하세요, 공지사항입니다."); // 韩语
return translations;
}
// 添加新的语言支持
addLanguageSupport(languageCode: string, voiceType: number): void {
this.languageVoices.set(languageCode, voiceType);
console.log(`添加语言支持: ${languageCode} -> 语音类型 ${voiceType}`);
}
// 获取支持的语言列表
getSupportedLanguages(): string[] {
return Array.from(this.languageVoices.keys());
}
}
// 使用示例
const multiLangSystem = new MultiLanguageVoiceSystem("multilang-bot-id");
// 多语言文本合成
const multilingualTexts = new Map([
["zh-CN", "欢迎使用多语言语音系统"],
["en-US", "Welcome to the multilingual voice system"],
["ja-JP", "多言語音声システムへようこそ"],
]);
const audioResults = await multiLangSystem.synthesizeMultilingualText(
multilingualTexts
);
// 国际公告播报
const announcements = await multiLangSystem.createInternationalAnnouncement(
"系统维护通知"
);
// 语言学习音频
const englishPhrases = ["Hello", "How are you?", "Thank you", "Goodbye"];
const learningAudios = await multiLangSystem.generateLanguageLearningAudio(
"en-US",
englishPhrases
);
// 导游音频
const attractions = [
{ name: "故宫", description: "中国古代宫殿建筑群,世界文化遗产" },
{ name: "长城", description: "中国古代军事防御工程,世界奇迹" },
];
const guideAudios = await multiLangSystem.createTourGuideAudio(
"zh-CN",
attractions
);
getTextToSpeechResult
function getTextToSpeechResult(props: {
botId: string;
taskId: string;
isPreview?: boolean;
}): Promise<TextToSpeechResult>;
获取文字转语音任务的结果,查询语音合成任务的完成状态和生成的音频文件。
- 查询异步语音合成任务的状态和结果
- 获取生成的音频文件信息
- 支持预览模式和正式模式
- 适用于批量语音合成、长文本处理等异步场景
参数
获取语音合成结果的参数
返回
语音合成任务结果
示例
// 查询语音合成任务结果
const result = await ai.bot.getTextToSpeechResult({
botId: "tts-bot-id",
taskId: "task-123456",
});
console.log("任务状态:", result.status);
console.log("任务进度:", result.progress, "%");
if (result.status === "completed") {
console.log("音频地址:", result.audioUrl);
console.log("音频时长:", result.duration, "秒");
console.log("文件格式:", result.format);
console.log("文件大小:", result.size, "字节");
} else if (result.status === "processing") {
console.log("任务仍在处理中,请稍后重试");
} else if (result.status === "failed") {
console.log("任务处理失败");
}
// 批量语音合成任务监控系统
class BatchTTSMonitor {
private botId: string;
private taskQueue: Map<string, { text: string; createTime: Date }> =
new Map();
constructor(botId: string) {
this.botId = botId;
}
// 添加任务到队列
addTask(taskId: string, text: string): void {
this.taskQueue.set(taskId, {
text: text,
createTime: new Date(),
});
console.log(`任务 ${taskId} 已添加到队列`);
}
// 监控任务进度
async monitorTaskProgress(
taskId: string,
maxWaitTime: number = 300
): Promise<TextToSpeechResult> {
const startTime = Date.now();
const checkInterval = 5000; // 5秒检查一次
console.log(`开始监控任务 ${taskId} 进度`);
while (true) {
const result = await ai.bot.getTextToSpeechResult({
botId: this.botId,
taskId: taskId,
});
console.log(
`任务 ${taskId} 状态: ${result.status}, 进度: ${result.progress}%`
);
if (result.status === "completed") {
console.log(`任务 ${taskId} 已完成,音频时长: ${result.duration}秒`);
this.taskQueue.delete(taskId);
return result;
}
if (result.status === "failed") {
console.error(`任务 ${taskId} 处理失败`);
this.taskQueue.delete(taskId);
throw new Error(`语音合成任务失败: ${taskId}`);
}
// 检查是否超时
if (Date.now() - startTime > maxWaitTime * 1000) {
console.error(`任务 ${taskId} 监控超时`);
throw new Error(`语音合成任务超时: ${taskId}`);
}
// 等待一段时间后重试
await this.sleep(checkInterval);
}
}
// 批量监控所有任务
async monitorAllTasks(): Promise<Map<string, TextToSpeechResult>> {
const results = new Map<string, TextToSpeechResult>();
const taskIds = Array.from(this.taskQueue.keys());
console.log(`开始监控 ${taskIds.length} 个任务`);
for (const taskId of taskIds) {
try {
const result = await this.monitorTaskProgress(taskId);
results.set(taskId, result);
} catch (error) {
console.error(`任务 ${taskId} 监控失败:`, error);
}
}
console.log(`任务监控完成,成功: ${results.size}/${taskIds.length}`);
return results;
}
// 获取任务统计信息
getTaskStats(): {
total: number;
completed: number;
processing: number;
failed: number;
} {
const stats = {
total: this.taskQueue.size,
completed: 0,
processing: 0,
failed: 0,
};
// 在实际应用中,这里可以根据任务状态进行统计
return stats;
}
// 清理已完成的任务
cleanupCompletedTasks(): void {
const completedTaskIds: string[] = [];
// 在实际应用中,这里可以清理已完成的任务记录
console.log(`清理了 ${completedTaskIds.length} 个已完成任务`);
}
private sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}
// 使用示例
const monitor = new BatchTTSMonitor("batch-tts-bot-id");
// 添加任务到监控队列
monitor.addTask("task-001", "这是第一个语音合成任务");
monitor.addTask("task-002", "这是第二个语音合成任务");
monitor.addTask("task-003", "这是第三个语音合成任务");
// 监控单个任务
const result = await monitor.monitorTaskProgress("task-001");
console.log("任务结果:", result.audioUrl);
// 批量监控所有任务
const allResults = await monitor.monitorAllTasks();
// 查看任务统计
const stats = monitor.getTaskStats();
console.log("任务统计:", stats);
// 长文本语音合成系统
class LongTextTTSProcessor {
private botId: string;
private voiceType: number;
constructor(botId: string, voiceType: number = 1) {
this.botId = botId;
this.voiceType = voiceType;
}
// 分段处理长文本
async processLongText(
longText: string,
maxSegmentLength: number = 500
): Promise<string[]> {
const segments = this.splitText(longText, maxSegmentLength);
const audioUrls: string[] = [];
console.log(`开始处理长文本,共 ${segments.length} 段`);
for (const [index, segment] of segments.entries()) {
console.log(`处理第 ${index + 1}/${segments.length} 段文本`);
try {
// 提交语音合成任务
const result = await ai.bot.textToSpeech({
botId: this.botId,
voiceType: this.voiceType,
text: segment,
});
// 等待任务完成
const finalResult = await this.waitForTaskCompletion(result.taskId);
audioUrls.push(finalResult.audioUrl);
console.log(
`✓ 第 ${index + 1} 段处理完成,时长: ${finalResult.duration}秒`
);
} catch (error) {
console.error(`✗ 第 ${index + 1} 段处理失败`, error);
}
}
console.log(`长文本处理完成,生成 ${audioUrls.length} 个音频文件`);
return audioUrls;
}
// 等待任务完成
private async waitForTaskCompletion(
taskId: string,
maxWaitTime: number = 600
): Promise<TextToSpeechResult> {
const startTime = Date.now();
const checkInterval = 3000; // 3秒检查一次
while (true) {
const result = await ai.bot.getTextToSpeechResult({
botId: this.botId,
taskId: taskId,
});
if (result.status === "completed") {
return result;
}
if (result.status === "failed") {
throw new Error(`语音合成任务失败: ${taskId}`);
}
// 检查超时
if (Date.now() - startTime > maxWaitTime * 1000) {
throw new Error(`语音合成任务超时: ${taskId}`);
}
console.log(`任务 ${taskId} 进度: ${result.progress}%`);
await this.sleep(checkInterval);
}
}
// 文本分段
private splitText(text: string, maxLength: number): string[] {
const segments: string[] = [];
let currentSegment = "";
const sentences = text.split(/[。!?.!?]/);
for (const sentence of sentences) {
const trimmedSentence = sentence.trim();
if (!trimmedSentence) continue;
if (currentSegment.length + trimmedSentence.length + 1 <= maxLength) {
currentSegment += (currentSegment ? "。" : "") + trimmedSentence;
} else {
if (currentSegment) {
segments.push(currentSegment + "。");
}
currentSegment = trimmedSentence;
}
}
if (currentSegment) {
segments.push(currentSegment + "。");
}
return segments;
}
// 合并音频文件(在实际应用中需要专门的音频处理工具)
async mergeAudioFiles(audioUrls: string[]): Promise<string> {
console.log(`开始合并 ${audioUrls.length} 个音频文件`);
// 在实际应用中,这里可以调用音频合并API
// 这里返回第一个音频URL作为示例
return audioUrls[0];
}
// 生成有声读物
async createAudioBook(
bookTitle: string,
chapters: string[]
): Promise<Map<string, string[]>> {
const bookAudios = new Map<string, string[]>();
console.log(`开始制作有声读物: ${bookTitle},共 ${chapters.length} 章`);
for (const [index, chapter] of chapters.entries()) {
console.log(`处理第 ${index + 1} 章`);
const chapterAudios = await this.processLongText(chapter);
bookAudios.set(`第${index + 1}章`, chapterAudios);
console.log(
`✓ 第 ${index + 1} 章处理完成,生成 ${chapterAudios.length} 个音频片段`
);
}
console.log(`有声读物制作完成: ${bookTitle}`);
return bookAudios;
}
private sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}
// 使用示例
const longTextProcessor = new LongTextTTSProcessor("longtext-bot-id", 1);
// 处理长文本
const longText = "这是一段很长的文本内容,需要被分成多个段落进行语音合成...";
const audioSegments = await longTextProcessor.processLongText(longText);
// 制作有声读物
const bookChapters = [
"第一章:故事的开端...",
"第二章:情节发展...",
"第三章:高潮部分...",
"第四章:结局...",
];
const audioBook = await longTextProcessor.createAudioBook(
"我的故事",
bookChapters
);
// 合并音频文件
const mergedAudio = await longTextProcessor.mergeAudioFiles(audioSegments);
console.log("合并后的音频:", mergedAudio);
完整类型定义
IBotCreateConversation
interface IBotCreateConversation {
botId: string;
title?: string;
}
IBotGetConversation
interface IBotGetConversation {
botId: string;
pageSize?: number;
pageNumber?: number;
isDefault?: boolean;
}
IBotDeleteConversation
interface IBotDeleteConversation {
botId: string;
conversationId: string;
}
IBotSpeechToText
interface IBotSpeechToText {
botId: string;
engSerViceType: string;
voiceFormat: string;
url: string;
isPreview?: boolean;
}
IBotTextToSpeech
interface IBotTextToSpeech {
botId: string;
voiceType: number;
text: string;
isPreview?: boolean;
}
IBotGetTextToSpeechResult
interface IBotGetTextToSpeechResult {
botId: string;
taskId: string;
isPreview?: boolean;
}
BaseChatModelInput
interface BaseChatModelInput {
model: string;
messages: Array<ChatModelMessage>;
temperature?: number;
topP?: number;
tools?: Array<FunctionTool>;
toolChoice?: "none" | "auto" | "custom";
maxSteps?: number;
onStepFinish?: (prop: IOnStepFinish) => unknown;
}
| BaseChatModelInput 属性名 | 类型 | 说明 |
|---|---|---|
| model | string | 模型名称。 |
| messages | Array<ChatModelMessage> | 消息列表。 |
| temperature | number | 采样温度,控制输出的随机性。 |
| topP | number | 温度采样,即模型考虑概率质量为 top_p 的标记的结果。 |
| tools | Array<FunctionTool> | 大模型可用的工具列表。 |
| toolChoice | string | 指定大模型选择工具的方式。 |
| maxSteps | number | 请求大模型的最大次数。 |
| onStepFinish | (prop: IOnStepFinish) => unknown | 当对大模型的一次请求完成时,出发的回调函数。 |
BotInfo
interface BotInfo {
botId: string;
name: string;
introduction: string;
agentSetting: string;
welcomeMessage: string;
avatar: string;
background: string;
tags: Array<string>;
isNeedRecommend: boolean;
knowledgeBase: Array<string>;
type: string;
initQuestions: Array<string>;
enable: true;
}
IUserFeedback
interface IUserFeedback {
recordId: string;
type: string;
botId: string;
comment: string;
rating: number;
tags: Array<string>;
input: string;
aiAnswer: string;
}
ChatModelMessage
type ChatModelMessage =
| UserMessage
| SystemMessage
| AssistantMessage
| ToolMessage;
UserMessage
type UserMessage = {
role: "user";
content: string;
};
SystemMessage
type SystemMessage = {
role: "system";
content: string;
};
AssistantMessage
type AssistantMessage = {
role: "assistant";
content?: string;
tool_calls?: Array<ToolCall>;
};
ToolMessage
type ToolMessage = {
role: "tool";
tool_call_id: string;
content: string;
};
ToolCall
export type ToolCall = {
id: string;
type: string;
function: { name: string; arguments: string };
};
FunctionTool
工具定义类型。
type FunctionTool = {
name: string;
description: string;
fn: CallableFunction;
parameters: object;
};
| FunctionTool 属性名 | 类型 | 说明 |
|---|---|---|
| name | string | 工具名称。 |
| description | string | 工具的描述。清楚的工具描述有助于大模型认识工具的用途。 |
| fn | CallableFunction | 工具的执行函数。当 AI SDK 解析出大模型的响应需要该工具调用时,会调用此函数,并将结果返回给大模型。 |
| parameters | object | 工具执行函数的入参。需要使用 JSON Schema 的格式定义入参。 |
IOnStepFinish
大模型响应后出发的回调函数的入参类型。
interface IOnStepFinish {
messages: Array<ChatModelMessage>;
text?: string;
toolCall?: ToolCall;
toolResult?: unknown;
finishReason?: string;
stepUsage?: Usage;
totalUsage?: Usage;
}
| IOnStepFinish 属性名 | 类型 | 说明 |
|---|---|---|
| messages | Array<ChatModelMessage> | 到当前步骤为止所有的消息列表。 |
| text | string | 当前响应的文本。 |
| toolCall | ToolCall | 当前响应调用的工具。 |
| toolResult | unknown | 对应的工具调用结果。 |
| finishReason | string | 大模型推理结束的原因。 |
| stepUsage | Usage | 当前步骤所花费的 token。 |
| totalUsage | Usage | 到当前步骤为止所花费的总 token。 |
Usage
type Usage = {
completion_tokens: number;
prompt_tokens: number;
total_tokens: number;
};
IConversation
Agent 会话。
interface IConversation {
id: string;
envId: string;
ownerUin: string;
userId: string;
conversationId: string;
title: string;
startTime: string; // date-time format
createTime: string;
updateTime: string;
}