Atoms多模型同时调用同步异步切换方式
通过Jotai原子组合实现多模型切换与同步/异步模式一键切换:modelSelectorAtom调度三模型配置,activeModelCallAtom动态路由,syncResponseAtom提供同步模板填充,executeModelCallAtom触发异步流式请求,displayResponseAtom根据modeAtom自动适配渲染模式。

你需要在同一个 React 组件中,让多个 Jotai 原子分别触发不同模型(如 OpenAI、Claude、本地 Ollama)的调用,并能随时在同步渲染(如预设 prompt 模板填充)和异步请求(如 real-time streaming)之间切换。
创建可切换行为的原子组
先定义一个基础原子存储当前选中的模型标识符,它将作为后续所有派生原子的调度开关:
const modelSelectorAtom = atom('openai');
再创建三个独立原子,每个对应一个模型的调用逻辑。注意:它们不直接执行请求,只封装调用意图与参数结构——真正的执行由消费端决定。
const openaiCallAtom = atom((get) => ({ model: 'gpt-4o', messages: get(chatHistoryAtom) }));
const claudeCallAtom = atom((get) => ({ model: 'claude-3-haiku-20240307', messages: get(chatHistoryAtom), max_tokens: 512 }));
const ollamaCallAtom = atom((get) => ({ model: 'llama3.2', messages: get(chatHistoryAtom), options: { temperature: 0.7 } }));
按模型标识动态路由到对应原子
使用一个只读派生原子,根据 modelSelectorAtom 的值返回对应模型的调用配置:
const activeModelCallAtom = atom((get) => {
const selector = get(modelSelectorAtom);
switch (selector) {
case 'openai': return get(openaiCallAtom);
case 'claude': return get(claudeCallAtom);
case 'ollama': return get(ollamaCallAtom);
default: return get(openaiCallAtom);
}
});
这个原子本身不触发网络请求,只是做配置组装。它确保下游无论何时读取,拿到的都是当前选中模型的最新参数快照。
同步模式:用 atomWithDefault 预填充响应
方法一:为每个模型准备一个“模拟响应原子”,用于开发调试或离线 fallback:
const mockOpenaiResponseAtom = atomWithDefault(() => '我已收到您的消息,正在思考中...');
方法二:构建一个带默认值的派生原子,在无异步执行时返回静态内容:
const syncResponseAtom = atom((get) => {
const config = get(activeModelCallAtom);
return `【${config.model}】已加载模板:${JSON.stringify(config.messages.slice(-1)[0]?.content || '')}`;
});
【注意:syncResponseAtom 不依赖任何异步状态,因此绝不会触发 Suspense 或 loading 状态】
异步模式:用 write-only atom 触发真实请求
第一步:定义一个可写原子,接收配置并返回 Promise:
const executeModelCallAtom = atom(null, (get, set, config) => {
const controller = new AbortController();
set(abortControllerAtom, controller);
fetch('/api/chat', { method: 'POST', body: JSON.stringify(config), signal: controller.signal })
.then(r => r.json())
.then(data => set(modelResponseAtom, data))
.catch(err => { if (err.name !== 'AbortError') set(errorAtom, err.message) });
});
第二步:在组件中调用它,传入 activeModelCallAtom 的当前值:
const [_, execute] = useAtom(executeModelCallAtom);
useEffect(() => { execute(get(activeModelCallAtom)); }, [activeModelCallAtom]);
第三步:用 useAtomValue 监听 modelResponseAtom 获取结果,或用 useAtom 处理 errorAtom 显示错误。
一键切换同步/异步行为
① 创建控制开关原子:
const modeAtom = atom<'sync' | 'async'>('sync');
② 定义一个响应读取原子,让它能自动适配模式:
const displayResponseAtom = atom((get) => {
const mode = get(modeAtom);
if (mode === 'sync') return get(syncResponseAtom);
return get(modelResponseAtom) || '等待响应...';
});
③ 在用户界面(UI)中设置一个切换按钮:
④ 最终消费:
const response = useAtomValue(displayResponseAtom);
-
- 元宵节猜灯谜的祝福短信
- 角色扮演 |
-
- 关于柯南的沙雕网名有哪些
- 角色扮演 | 1
- 网名
-
- 最新中性名字男女通用网名有哪些
- 角色扮演 | 1
- 网名
-
- 关于蓝色说唱的网名有哪些
- 角色扮演 | 1
- 网名
-
- 我好喜欢你是什么梗?
- 角色扮演 |