Skip to content

编程式控制

AI 小鲸 v2.0 通过 Vue 的模板引用(template ref)机制,暴露了丰富的编程式 API,允许你从外部代码精确控制聊天组件的行为。

非 Vue 宿主

若页面没有 Vue 运行时(React、纯 HTML 等),请使用 v2.1.4-beta.8+Standalone 子入口:通过 mountAIBlueking / mountChatBot 返回的 expose 调用与下文 ref API 相同的方法(如 showsendMessage)。

ChatBot 模板引用

获取引用

vue
<template>
  <ChatBot ref="chatBotRef" url="/api/v1/agent/chat" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ChatBot } from '@blueking/ai-blueking';
import type { ChatBotExpose } from '@blueking/ai-blueking';

const chatBotRef = ref<ChatBotExpose>();
</script>

可用方法

sendMessage - 发送消息

typescript
// 发送纯文本消息
chatBotRef.value?.sendMessage('帮我写一个 Python 排序函数');

// 发送带属性的消息
chatBotRef.value?.sendMessage('解释这段代码', {
  property: {
    extra: {
      cite: '被引用的代码内容...',
    },
  },
});

stopGeneration - 停止生成

typescript
// 停止当前正在进行的 AI 回复
chatBotRef.value?.stopGeneration();

switchSession - 切换会话

typescript
// 切换到指定会话(异步操作)
await chatBotRef.value?.switchSession('session-code-123');

setCiteText - 设置引用文本

typescript
// 在输入框中设置引用文本
chatBotRef.value?.setCiteText('这段文本将作为引用上下文发送');

focusInput - 聚焦输入框

typescript
// 让输入框获得焦点
chatBotRef.value?.focusInput();

完整示例

vue
<template>
  <div class="app">
    <div class="toolbar">
      <button @click="sendQuickMessage">快速提问</button>
      <button @click="stopReply" :disabled="!isGenerating">停止</button>
      <button @click="focusChat">聚焦输入</button>
    </div>
    <ChatBot ref="chatBotRef" url="/api/v1/agent/chat" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { ChatBot } from '@blueking/ai-blueking';
import type { ChatBotExpose } from '@blueking/ai-blueking';

const chatBotRef = ref<ChatBotExpose>();

const isGenerating = computed(() => chatBotRef.value?.isGenerating.value ?? false);

const sendQuickMessage = () => {
  chatBotRef.value?.sendMessage('你好,请介绍一下你自己');
};

const stopReply = () => {
  chatBotRef.value?.stopGeneration();
};

const focusChat = () => {
  chatBotRef.value?.focusInput();
};
</script>

AIBlueking 模板引用

AIBlueking 作为带窗口管理的高层组件,暴露了额外的窗口控制方法。

获取引用

vue
<template>
  <AIBlueking ref="aiBluekingRef" url="/api/v1/agent/chat" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { AIBlueking } from '@blueking/ai-blueking';
import type { AIBluekingExpose } from '@blueking/ai-blueking';

const aiBluekingRef = ref<AIBluekingExpose>();
</script>

可用方法

show - 显示窗口

show() 返回 Promise<void>。面板会立即显示;Promise 在会话初始化完成后 resolve:

  • 始终等待 sessionListgetSessions)加载完成
  • loadRecentSessionOnMounttrue(默认)时,还会等待最近会话选定或创建完成
  • 传入 sessionCode 时,在就绪后再切换到该会话

初始化失败时 Promise reject,并触发 @sdk-errorapiName: 'init')。

typescript
// 推荐:等待会话就绪后再执行业务逻辑
try {
  await aiBluekingRef.value?.show();

  const helper = aiBluekingRef.value?.getChatHelper();
  console.log('会话列表:', helper?.session.list.value);
  console.log('当前会话:', helper?.session.current.value);
} catch (error) {
  console.error('小鲸初始化失败:', error);
}

// 显示并切换到指定会话(切换发生在就绪之后)
await aiBluekingRef.value?.show('session-code-123');

与事件的区别

不需要额外监听 sessions-loaded 等内部事件来判断「能否读 session」。对集成方而言,await show() 即表示可安全访问 getChatHelper()?.session

hide - 隐藏窗口

typescript
// 隐藏窗口
aiBluekingRef.value?.hide();

sendMessage - 发送消息

typescript
// 发送消息(如果窗口未显示会自动显示)
aiBluekingRef.value?.sendMessage('你好');

addNewSession - 新建会话

typescript
// 创建一个新的会话
aiBluekingRef.value?.addNewSession();

updatePosition - 更新窗口位置

typescript
// 设置窗口左上角坐标 (x, y)
aiBluekingRef.value?.updatePosition(100, 200);

updateSize - 更新窗口大小

typescript
// 设置窗口宽高 (width, height)
aiBluekingRef.value?.updateSize(600, 800);

完整示例

vue
<template>
  <div class="app">
    <!-- 悬浮按钮 -->
    <button class="float-btn" @click="toggleChat">
      <span v-if="!isVisible">💬</span>
      <span v-else>✕</span>
    </button>

    <!-- AI 助手窗口 -->
    <AIBlueking
      ref="aiBluekingRef"
      url="/api/v1/agent/chat"
      @close="isVisible = false"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { AIBlueking } from '@blueking/ai-blueking';
import type { AIBluekingExpose } from '@blueking/ai-blueking';

const aiBluekingRef = ref<AIBluekingExpose>();
const isVisible = ref(false);

const toggleChat = async () => {
  if (isVisible.value) {
    aiBluekingRef.value?.hide();
    isVisible.value = false;
  } else {
    isVisible.value = true;
    try {
      await aiBluekingRef.value?.show();
    } catch {
      isVisible.value = false;
    }
  }
};
</script>

响应式状态监听

通过模板引用,你可以监听组件内部的响应式状态变化。

ChatBot 状态

typescript
import { watch } from 'vue';

// 监听消息列表变化
watch(
  () => chatBotRef.value?.messages.value,
  (messages) => {
    if (messages) {
      console.log('当前消息数量:', messages.length);
      // 可用于同步外部状态
      externalMessageCount.value = messages.length;
    }
  },
  { deep: true }
);

// 监听生成状态
watch(
  () => chatBotRef.value?.isGenerating.value,
  (generating) => {
    if (generating) {
      console.log('AI 正在回复...');
      disableOtherInputs();
    } else {
      console.log('AI 回复完毕');
      enableOtherInputs();
    }
  }
);

获取 ChatHelper 进行高级操作

对于更高级的场景,可以通过 getChatHelper 直接获取底层 chatHelper 实例:

typescript
// 获取 chatHelper 实例
const helper = chatBotRef.value?.getChatHelper();

if (helper) {
  // 直接访问 agent 模块
  const agentInfo = helper.agent.getAgentInfo();

  // 直接访问 session 模块
  const sessions = helper.session.getSessionList();
  const currentSession = helper.session.getCurrentSession();

  // 直接访问 message 模块
  const messages = helper.message.getMessages();
}

外部集成模式

在复杂的应用中,你可能需要在 ChatBot 初始化完成后获取其内部能力,用于跨组件集成。

监听 Agent 加载完成

vue
<template>
  <ChatBot
    ref="chatBotRef"
    url="/api/v1/agent/chat"
    @agent-info-loaded="onAgentLoaded"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ChatBot } from '@blueking/ai-blueking';
import type { ChatBotExpose } from '@blueking/ai-blueking';

const chatBotRef = ref<ChatBotExpose>();

const onAgentLoaded = (agentInfo: any) => {
  console.log('Agent 加载完成:', agentInfo.name);

  // 获取 chatHelper 进行高级操作
  const helper = chatBotRef.value?.getChatHelper();

  if (helper) {
    // 使用底层 SDK 进行自定义操作
    setupCustomIntegration(helper);
  }
};

function setupCustomIntegration(helper: any) {
  // 示例:监听所有消息变化,同步到外部系统
  watch(
    () => helper.message.getMessages(),
    (messages) => {
      syncToExternalSystem(messages);
    },
    { deep: true }
  );
}
</script>

跨组件通信

typescript
// store/chat.ts - 使用 Pinia 或其他状态管理
import { defineStore } from 'pinia';

export const useChatStore = defineStore('chat', () => {
  const chatBotRef = ref<ChatBotExpose | null>(null);

  // 注册 ChatBot 引用
  function registerChatBot(ref: ChatBotExpose) {
    chatBotRef.value = ref;
  }

  // 任何组件都可以调用的方法
  function sendMessage(content: string) {
    chatBotRef.value?.sendMessage(content);
  }

  function stopGeneration() {
    chatBotRef.value?.stopGeneration();
  }

  return { registerChatBot, sendMessage, stopGeneration };
});
vue
<!-- 页面 A:注册 ChatBot -->
<template>
  <ChatBot ref="chatBotRef" url="/api/v1/agent/chat" />
</template>

<script setup lang="ts">
import { onMounted } from 'vue';
import { useChatStore } from '@/store/chat';

const chatBotRef = ref<ChatBotExpose>();
const chatStore = useChatStore();

onMounted(() => {
  if (chatBotRef.value) {
    chatStore.registerChatBot(chatBotRef.value);
  }
});
</script>
vue
<!-- 页面 B:远程控制 ChatBot -->
<template>
  <button @click="askAI">向 AI 提问</button>
</template>

<script setup lang="ts">
import { useChatStore } from '@/store/chat';

const chatStore = useChatStore();

const askAI = () => {
  chatStore.sendMessage('请帮我分析这个数据');
};
</script>

All Rights Reserved. 腾讯蓝鲸 版权所有