Appearance
TanStack AI 是面向 React、Solid、Preact 等前端框架的 AI 集成库,通过 @tanstack/ai-openrouter 包接入 OpenRouter。核心用法:openRouterText("model-id") 创建 adapter,传给 chat() 发起流式对话。进阶功能包括:modelOptions.models 配置备用模型列表、provider.sort 按延迟/吞吐/价格排序、provider.data_collection: "deny" 开启数据隐私模式、toolDefinition() + toolDefinition.server() 定义服务端工具调用,以及 toServerSentEventsResponse() 输出 SSE 流。
TanStack AI 是 TanStack 团队开发的前端 AI 集成库,支持 React、Solid、Preact。通过 @tanstack/ai-openrouter 包可以接入 OpenRouter 访问 300+ 模型。
安装
bash
npm install @tanstack/ai @tanstack/ai-openrouter基本用法
typescript
import { chat } from "@tanstack/ai";
import { openRouterText } from "@tanstack/ai-openrouter";
const stream = chat({
adapter: openRouterText("openai/gpt-4o"),
messages: [{ role: "user", content: "Hello!" }],
});配置选项
typescript
import { createOpenRouter, type OpenRouterConfig } from "@tanstack/ai-openrouter";
const config: OpenRouterConfig = {
apiKey: process.env.OPENROUTER_API_KEY!,
baseURL: "https://openrouter.ai/api/v1", // 可选
httpReferer: "https://your-app.com", // 可选,用于排名统计
xTitle: "Your App Name", // 可选,用于排名统计
};
const adapter = createOpenRouter(config.apiKey, config);服务端 SSE 流式响应
typescript
import { chat, toServerSentEventsResponse } from "@tanstack/ai";
import { openRouterText } from "@tanstack/ai-openrouter";
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = chat({
adapter: openRouterText("openai/gpt-4o"),
messages,
});
return toServerSentEventsResponse(stream);
}Tool Calling
使用 toolDefinition() 定义工具,toolDefinition.server() 实现服务端处理逻辑:
typescript
import { chat, toolDefinition } from "@tanstack/ai";
import { openRouterText } from "@tanstack/ai-openrouter";
import { z } from "zod";
const getWeatherDef = toolDefinition({
name: "get_weather",
description: "Get the current weather",
inputSchema: z.object({
location: z.string(),
}),
});
const getWeather = getWeatherDef.server(async ({ location }) => {
return { temperature: 72, conditions: "sunny" };
});
const stream = chat({
adapter: openRouterText("openai/gpt-4o"),
messages: [{ role: "user", content: "What's the weather in NYC?" }],
tools: [getWeather],
});Provider 路由功能
通过 modelOptions 参数控制 OpenRouter 的路由行为:
备用模型
主模型不可用时自动降级:
typescript
const stream = chat({
adapter: openRouterText("openai/gpt-4o"),
messages: [{ role: "user", content: "Hello!" }],
modelOptions: {
models: ["anthropic/claude-sonnet-4.5", "google/gemini-flash-1.5"],
route: "fallback",
},
});Provider 排序
按吞吐量、延迟或价格排序:
typescript
modelOptions: {
provider: {
sort: "throughput", // 或 "latency" | "price"
},
},Provider 指定顺序
typescript
modelOptions: {
provider: {
order: ["anthropic", "amazon-bedrock", "google-vertex"],
allow_fallbacks: true,
},
},Provider 过滤
只使用或排除特定 Provider:
typescript
modelOptions: {
provider: {
only: ["together", "fireworks"],
ignore: ["azure"],
quantizations: ["fp16", "bf16"],
},
},数据隐私控制
使用 Zero Data Retention(ZDR)Provider,防止数据被用于训练:
typescript
modelOptions: {
provider: {
data_collection: "deny",
zdr: true,
},
},成本上限
设置每次请求的最高价格(美元/百万 token):
typescript
modelOptions: {
provider: {
max_price: {
prompt: 0.5, // 输入 token 价格上限
completion: 2, // 输出 token 价格上限
},
},
},更多文档
常见问题
Q: TanStack AI 的 openRouterText() 只支持文本模型吗?
A: 目前 @tanstack/ai-openrouter 包主要面向文本生成场景。如果需要支持视觉(vision)或音频等多模态模型,可以查看 TanStack AI 文档 中是否有对应的 adapter 类型。
Q: modelOptions.route: "fallback" 和 provider.order 有什么区别?
A: route: "fallback" 配合 models 数组定义的是模型级别的降级(主模型不可用时换另一个模型);provider.order 定义的是 Provider 级别的优先顺序(同一个模型在不同 Provider 中的调用顺序)。两者可以组合使用。
Q: TanStack AI 适合用在纯客户端(浏览器直接调用)吗?
A: 不推荐。在浏览器端直接调用 OpenRouter API 会暴露 API key。推荐架构是在服务端创建 /api/chat 路由,服务端持有 API key 并通过 toServerSentEventsResponse() 将流式响应返回给前端。