在线演示:https://tombcato.github.io/ai-selector/react/index.html
前言
如果你正在开发一个需要用户配置 AI 服务的应用(比如 AI 写作助手、智能客服、代码补全工具等),你可能会遇到这些问题:
- 🤯 需要对接多家 AI 厂商(OpenAI、Claude、Gemini、DeepSeek...),每家 API 格式都不一样
- 📜 需要维护一长串模型列表,还要时刻关注厂商更新
- 🎨 还要设计一套 UI 让用户方便地选择和配置
AI Selector 就是为解决这些问题而生的。
Smart Ticker文字替换特效实现:https://blog.csdn.net/tombcato/article/details/156424365

✨ 核心特性
| 特性 | 描述 |
|---|---|
| 🤖 20+ 厂商 | OpenAI, Claude, Gemini, DeepSeek, 通义, 智谱, Mistral... 开箱即用 |
| ⚡ 智能模型发现 | 自动调用厂商 API 获取最新模型列表,无需手动维护 |
| 📡 连接诊断 | 一键测试 API 连通性与延迟 |
| 🔐 AES 加密存储 | API Key 加密保存到 localStorage,非明文 |
| 🎨 开箱即用 UI | Tailwind CSS 设计系统,深色模式,中英双语 |
| 🔌 React + Vue | 双框架适配器,核心逻辑共享 |
| 🧩 Headless 模式 | 只用 useAIConfig Hook,完全自定义 UI |
| 🔄 零后端可选 | 支持前端直连(默认) / 后端代理 / 自定义 fetcher |
🚀 快速开始
安装
bash
# React
npm install @tombcato/ai-selector-react
# Vue
npm install @tombcato/ai-selector-vue
使用
tsx
// React
import { AIConfigForm } from '@tombcato/ai-selector-react';
import '@tombcato/ai-selector-react/style.css';
function App() {
return (
<AIConfigForm
proxyUrl="" // 空字符串 = 直连模式
language="zh" // 'zh' | 'en'
showPreview // 显示配置预览
onSave={(config) => {
console.log('用户保存的配置:', config);
// { providerId: 'openai', apiKey: 'sk-xxx', model: 'gpt-4o', ... }
}}
/>
);
}
就这么简单!用户可以:
- 选择 AI 厂商(20+ 内置选项)
- 输入 API Key
- 选择模型(自动从厂商 API 获取最新列表)
- 测试连接
- 保存配置
🎯 三种接入模式
1️⃣ 直连模式(零后端)
浏览器 ────────────► AI 厂商 API
- ✅ 零配置,开箱即用
- ⚠️ API Key 暴露在浏览器 Network 中
- ⚠️ 部分厂商可能阻止 CORS
适合:个人项目、内部工具、原型验证
2️⃣ 代理模式(推荐生产环境)
浏览器 ───► 后端代理 ───► AI 厂商 API
tsx
<AIConfigForm proxyUrl="https://your-backend/ai-proxy" />
- ✅ 隐藏 API Key
- ✅ 绕过 CORS 限制
- 📦 需要部署后端(项目内含 Python FastAPI 示例)
3️⃣ 自定义模式(完全控制)
tsx
<AIConfigForm
modelFetcher={async (params) => {
// 自己实现模型获取、连接测试逻辑
return await yourCustomFetch(params);
}}
/>
🔐 API Key 安全存储
默认使用 AES 加密 存储到 localStorage:
typescript
import {
createConfigStorage,
encryptedStorageAdapter // 默认,AES 加密
} from '@tombcato/ai-selector-core';
const storage = createConfigStorage();
const config = storage.load(); // 自动解密
storage.save(newConfig); // 自动加密
localStorage 中看到的是密文:
U2FsdGVkX1+abc123...
🧩 Headless 模式
如果你不想用内置 UI,可以只使用 useAIConfig Hook:
tsx
import { useAIConfig } from '@tombcato/ai-selector-react';
function MyCustomUI() {
const {
providerId, apiKey, model, models, providers, isValid,
setProviderId, setApiKey, selectModel, runTest, save,
} = useAIConfig({ proxyUrl: '' });
return (
<div>
<select value={providerId} onChange={e => setProviderId(e.target.value)}>
{providers.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
</select>
{/* 完全自定义的 UI */}
</div>
);
}
🛠️ 自定义 Provider
需要对接私有部署的模型?或者覆盖内置厂商的配置?
tsx
<AIConfigForm
config={{
mode: 'default', // 'default' | 'customOnly'
custom: {
// 覆盖内置配置
openai: {
name: 'Enterprise OpenAI',
baseUrl: 'https://gateway.company.com/openai/v1',
},
// 添加自定义厂商
'my-llm': {
name: 'Internal LLM',
baseUrl: 'http://localhost:8080/v1',
apiFormat: 'openai',
needsApiKey: false,
models: [{ id: 'llama-3-8b', name: 'Llama 3 8B' }]
}
}
}}
/>
📦 项目结构
ai-selector/
├── packages/
│ ├── core/ # 核心逻辑(框架无关)
│ ├── react/ # React 适配器
│ └── vue/ # Vue 适配器
└── backend/ # Python 代理示例 (FastAPI)
核心逻辑在 @tombcato/ai-selector-core 中,React 和 Vue 只是薄薄的 UI 封装。
🤝 贡献
欢迎提 Issue 和 PR!
GitHub: https://github.com/tombcato/ai-selector
如果这个项目对你有帮助,欢迎给个 ⭐ Star!
📜 License
MIT © 2026 AI Selector