Skip to content
On this page

自定义框架适配器

为什么需要自定义框架适配器

AI SDK 采用了分层架构设计,核心功能集中在 @tencent/ssv-ai-sdk-shared 包中,通过 AIChat(Stream)和 AIAgent(Agent)类提供统一的 AI 能力。然而,不同的前端框架(React、Vue、Angular 等)都有各自独特的:

  • 响应式系统:React 的 state/hooks、Vue 的 reactive、Angular 的 RxJS 等
  • 生命周期管理:组件挂载、更新、销毁的时机和方式不同
  • API 风格:Hook 函数、Class 组件、Options API 等不同的编程范式

创建适配器需要处理以下四个核心问题:

  1. 实例管理:正确创建和管理 AIChat / AIAgent 实例
  2. 状态同步:将 AI 状态变化同步到框架的响应式系统
  3. 生命周期:在组件创建时初始化,销毁时释放资源
  4. API 封装:提供符合框架习惯的接口

Stream 适配器实现示例(React)

基于 AIChat 创建 React Hook 适配器:

typescript
import { useState, useEffect, useRef, useCallback } from 'react';
import { AIChat, AIEvents, BrowserAdapter } from '@tencent/ssv-ai-sdk-shared';
import type { ChatOptions, ChatParams, ChatState, Message, FileItem } from '@tencent/ssv-ai-sdk-shared';

interface ChatResult extends ChatState {
  chat: (params: ChatParams) => Promise<void>;
  stop: () => void;
  setInput: (value: string) => void;
  setFiles: (files: FileItem[]) => void;
  setMessages: (messages: Message[]) => void;
  setOptions: (options: Partial<ChatOptions>) => void;
  on: (event: string, callback: (...args: any[]) => void) => void;
  off: (event: string, callback: (...args: any[]) => void) => void;
}

export function useChat(options: ChatOptions): ChatResult {
  // 2. 状态同步:使用 React 的 useState 管理 AI 状态
  const [state, setState] = useState<ChatState>({
    messages: [],
    error: null,
    status: 'idle',
    input: '',
    files: [],
    assistantStatus: 'idle',
  });

  // 1. 实例管理:使用 useRef 保持实例引用
  const aiRef = useRef<AIChat | null>(null);

  // 3. 生命周期:组件挂载时初始化,卸载时清理
  useEffect(() => {
    aiRef.current = new AIChat({
      adapter: new BrowserAdapter(),
      ...options,
    });

    // 2. 状态同步:监听状态变化并同步到 React state
    aiRef.current.on(AIEvents.STATE_CHANGE, (newState: ChatState) => {
      setState(newState);
    });

    return () => {
      aiRef.current?.dispose();
    };
  }, []);

  // 4. API 封装:提供符合 React Hook 习惯的方法
  const chat = useCallback(async (params: ChatParams) => {
    await aiRef.current?.chat(params);
  }, []);

  const stop = useCallback(() => aiRef.current?.stop(), []);
  const setInput = useCallback((v: string) => aiRef.current?.setInput(v), []);
  const setFiles = useCallback((f: FileItem[]) => aiRef.current?.setFiles(f), []);
  const setMessages = useCallback((m: Message[]) => aiRef.current?.updateMessages(m), []);
  const setOptions = useCallback((o: Partial<ChatOptions>) => aiRef.current?.setOptions(o), []);
  const on = useCallback((event: string, cb: (...args: any[]) => void) => aiRef.current?.on(event, cb), []);
  const off = useCallback((event: string, cb: (...args: any[]) => void) => aiRef.current?.off(event, cb), []);

  return { ...state, chat, stop, setInput, setFiles, setMessages, setOptions, on, off };
}

Agent 适配器实现示例(React)

基于 AIAgent 创建 React Hook 适配器,需额外同步 agentState

typescript
import { useState, useEffect, useRef, useCallback } from 'react';
import { AIAgent, AIEvents, BrowserAdapter } from '@tencent/ssv-ai-sdk-shared';
import type {
  AgentOptions,
  AgentChatState,
  SendParams,
  Message,
  ExecutableTool,
} from '@tencent/ssv-ai-sdk-shared';

interface AgentResult extends AgentChatState {
  send: (params?: SendParams) => Promise<void>;
  stop: () => void;
  setMessages: (messages: Message[]) => void;
  setAgentState: (path: string, value: any) => void;
  setTools: (tools: ExecutableTool[]) => void;
  resetAgent: () => void;
  on: (event: string, callback: (...args: any[]) => void) => void;
  off: (event: string, callback: (...args: any[]) => void) => void;
}

export function useAgent(options: AgentOptions): AgentResult {
  // 2. 状态同步:Agent 状态需额外包含 agentState
  const [state, setState] = useState<AgentChatState>({
    messages: [],
    error: null,
    status: 'idle',
    assistantStatus: 'idle',
    agentState: {},
  });

  const agentRef = useRef<AIAgent | null>(null);

  // 3. 生命周期
  useEffect(() => {
    agentRef.current = new AIAgent({
      adapter: new BrowserAdapter(),
      ...options,
    });

    // 2. 状态同步:监听包含 agentState 的完整状态
    agentRef.current.on(AIEvents.STATE_CHANGE, (newState: AgentChatState) => {
      setState(newState);
    });

    return () => {
      agentRef.current?.dispose();
    };
  }, []);

  // 4. API 封装
  const send = useCallback(async (params: SendParams = {}) => {
    await agentRef.current?.send(params);
  }, []);

  const stop = useCallback(() => agentRef.current?.stop(), []);
  const setMessages = useCallback((m: Message[]) => agentRef.current?.setMessages(m), []);
  const setAgentState = useCallback((path: string, value: any) => agentRef.current?.setAgentState(path, value), []);
  const setTools = useCallback((tools: ExecutableTool[]) => agentRef.current?.setTools(tools), []);
  const resetAgent = useCallback(() => agentRef.current?.resetAgent(), []);
  const on = useCallback((event: string, cb: (...args: any[]) => void) => agentRef.current?.on(event, cb), []);
  const off = useCallback((event: string, cb: (...args: any[]) => void) => agentRef.current?.off(event, cb), []);

  return { ...state, send, stop, setMessages, setAgentState, setTools, resetAgent, on, off };
}

总结

步骤Stream(AIChat)Agent(AIAgent)
实例管理new AIChat({ adapter, ...options })new AIAgent({ adapter, ...options })
状态同步ChatState(无 agentState)AgentChatState(含 agentState)
生命周期
核心 APIchat() / stop()send() / stop() / setTools()

参考官方适配器实现:@tencent/ssv-ai-sdk-react@tencent/ssv-ai-sdk-vue@tencent/ssv-ai-sdk-vue2@tencent/ssv-ai-sdk-miniprogram

Released under the MIT License.