自定义框架适配器
为什么需要自定义框架适配器
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 等不同的编程范式
创建适配器需要处理以下四个核心问题:
- 实例管理:正确创建和管理
AIChat/AIAgent实例 - 状态同步:将 AI 状态变化同步到框架的响应式系统
- 生命周期:在组件创建时初始化,销毁时释放资源
- 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) |
| 生命周期 | 同 | 同 |
| 核心 API | chat() / stop() | send() / stop() / setTools() |
参考官方适配器实现:@tencent/ssv-ai-sdk-react、@tencent/ssv-ai-sdk-vue、@tencent/ssv-ai-sdk-vue2、@tencent/ssv-ai-sdk-miniprogram。
@ssv-lab