自定义框架适配器
为什么需要自定义框架适配器
AI SDK 采用了分层架构设计,核心功能集中在 @tencent/ssv-ai-sdk-shared
包中,通过 AIChat
类提供统一的 AI 聊天能力。然而,不同的前端框架(React、Vue、Angular 等)都有各自独特的:
- 响应式系统:React 的 state/hooks、Vue 的 reactive、Angular 的 RxJS 等
- 生命周期管理:组件挂载、更新、销毁的时机和方式不同
- API 风格:Hook 函数、Class 组件、Options API 等不同的编程范式
直接使用核心的 AIChat
类虽然可行,但无法与框架的响应式系统完美集成,开发者需要手动处理状态同步、生命周期管理等复杂问题。因此需要为不同框架创建适配器,将 AI SDK 的能力无缝集成到各个框架的开发体验中。
适配器连接 UI 框架需要做的几点
创建自定义框架适配器主要需要处理以下几个核心问题:
1. 创建和管理 AIChat 实例
在适当的时机初始化 AIChat
实例,选择合适的平台适配器(浏览器环境使用 BrowserAdapter
,小程序环境使用 MiniprogramAdapter
)。
2. 状态同步机制
将 AIChat
的状态变化同步到框架的响应式系统中,确保 UI 能够实时响应状态变化。通过监听 AIEvents.STATE_CHANGE
事件来实现。
3. 生命周期管理
在组件创建时初始化 AI 实例,在组件销毁时正确释放资源,避免内存泄漏。
4. API 封装
提供符合框架习惯的 API 接口,隐藏底层 AIChat
的复杂性,让开发者能够用熟悉的方式使用 AI 功能。
React 适配器实现示例
以下是一个完整的 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;
}
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. 创建和管理 AIChat 实例:使用 useRef 保持实例引用
const aiInstanceRef = useRef<AIChat | null>(null);
// 3. 生命周期管理:在组件挂载时初始化,卸载时清理
useEffect(() => {
// 创建 AIChat 实例,选择浏览器适配器
aiInstanceRef.current = new AIChat({
adapter: new BrowserAdapter(),
...options,
});
// 2. 状态同步机制:监听状态变化并同步到 React state
aiInstanceRef.current.on(AIEvents.STATE_CHANGE, (newState: ChatState) => {
setState(newState);
});
// 3. 生命周期管理:组件卸载时清理资源
return () => {
aiInstanceRef.current?.dispose();
};
}, []);
// 4. API 封装:提供符合 React Hook 习惯的方法
const chat = useCallback(async (params: ChatParams): Promise<void> => {
if (!aiInstanceRef.current) return;
await aiInstanceRef.current.chat(params);
}, []);
const stop = useCallback(() => {
aiInstanceRef.current?.stop();
}, []);
const setInput = useCallback((value: string) => {
aiInstanceRef.current?.setInput(value);
}, []);
const setFiles = useCallback((files: FileItem[]) => {
aiInstanceRef.current?.setFiles(files);
}, []);
const setMessages = useCallback((messages: Message[]) => {
aiInstanceRef.current?.updateMessages(messages);
}, []);
const setOptions = useCallback((options: Partial<ChatOptions>) => {
aiInstanceRef.current?.setOptions(options);
}, []);
// 4. API 封装:返回状态和操作方法的组合
return {
...state,
chat,
stop,
setInput,
setFiles,
setMessages,
setOptions,
};
}
使用示例
typescript
// 在 React 组件中使用自定义适配器
function ChatComponent() {
const chatResult = useChat({
api: {
apiUrl: 'https://your-api-endpoint.com',
headers: {
Authorization: 'Bearer your-token',
},
},
mode: 'stream',
});
const handleSendMessage = async () => {
await chatResult.chat({
messages: [
...chatResult.messages,
{ role: 'user', content: chatResult.input },
],
});
};
return (
<div>
<div>
{chatResult.messages.map((msg, index) => (
<div key={index}>{msg.content}</div>
))}
</div>
<input
value={chatResult.input}
onChange={(e) => chatResult.setInput(e.target.value)}
/>
<button onClick={handleSendMessage}>发送</button>
</div>
);
}
总结
通过以上四个核心步骤,你可以为任何前端框架创建自定义的 AI SDK 适配器:
- 实例管理:正确创建和管理
AIChat
实例 - 状态同步:将 AI 状态同步到框架的响应式系统
- 生命周期:处理组件的创建和销毁
- API 设计:提供符合框架习惯的接口
参考官方适配器实现:@tencent/ssv-ai-sdk-react
、@tencent/ssv-ai-sdk-vue
、@tencent/ssv-ai-sdk-vue2
、@tencent/ssv-ai-sdk-miniprogram
。