# @chat-adapter/web 中文文档

规范地址：https://npmcn.com/package/%40chat-adapter/web/

版本：4\.44\.0
npm 元数据更新时间：2026-11-02T14:56:12.230Z
中文译文更新时间：2026-11-09T11:25:53.199Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40chat-adapter/web
原文对照：https://npmcn.com/package/%40chat-adapter/web/?lang=original
项目主页：https://chat-sdk.dev/adapters/official/web
源码仓库：https://github.com/vercel/chat

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：53 kB，11 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：2 个
- peer 依赖：ai ^6 \|\| ^7，vue ^3，react ^19，svelte ^5，@ai-sdk/vue ^3 \|\| ^4，@ai-sdk/react ^3 \|\| ^4，@ai-sdk/svelte ^4 \|\| ^5
- 首次发布：2026-05-07T21:11:05.777Z
- 最新版本发布：2026-11-02T14:56:11.770Z
- 近 30 天下载量：81011（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：20（近 12 个月 20 个）

## 中文简介

Chat SDK的网络适配器——浏览器在AI SDK或AG-UI(TanStack AI)流协议上的聊天UI

## 安装

```sh
npm install @chat-adapter/web
```

也可以使用：`pnpm add @chat-adapter/web`、`yarn add @chat-adapter/web`、`bun add @chat-adapter/web`

## README

[![Web adapter for Chat SDK](https://chat-sdk.dev/en/adapters/official/web/og)](https://chat-sdk.dev/adapters/official/web)

# @chat-adapter/web (英语)

> npm 软件包 : [`@chat-adapter/web`](https://www.npmjs.com/package/@chat-adapter/web)

[![Agent Stack](https://img.shields.io/badge/Agent%20Stack-000?style=flat-square&logo=vercel&logoColor=FFF&labelColor=000&color=000)](https://vercel.com/kb/agent-stack) [![MIT License](https://img.shields.io/badge/License-MIT-000?style=flat-square&logo=opensourceinitiative&logoColor=white&labelColor=000&color=000)](https://npmcn.com/package/LICENSE)

网络适配器 [聊天SDK](https://chat-sdk.dev/)。让一个聊天-sdk bot与Slack, Teams, Discord 等同时为浏览器聊天UI服务——相同 `bot.onDirectMessage(...)` 每个平台的操作员起火.

适配器说 [AI SDK UI 消息流协议](https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol) 默认情况下,因此React,Vue,和Svelte AI SDK客户端对服务器端点工作. 设定 `protocol: "ag-ui"` 说话 [乌干达](https://docs.ag-ui.com/concepts/events) 相反,因为 [谭斯塔克AI](https://npmcn.com/package/%40chat-adapter/web/#readme-tanstack-ai) 和其他AG-UI客户端。 服务器对两个客户端SDK都没有运行时间依赖.

联合国 [聊天-sdk.dev/适应者/官方/网络](https://chat-sdk.dev/adapters/official/web) 指南: [vercel.com/kb/chat-sdk (英语)](https://vercel.com/kb/chat-sdk)

## 安装

```bash
pnpm add @chat-adapter/web
```

然后安装匹配您的用户界面的客户端软件包 :

| 客户端 | 软件包 | 从 | `protocol` |
| --- | --- | --- | --- |
| AI SDK + React / Next.js (英语) | `ai`, (中文(简体) ), `@ai-sdk/react` | `@chat-adapter/web/react` | `"ai-sdk"` (默认) |
| AI SDK + Vue / 努克特 | `ai`, (中文(简体) ), `@ai-sdk/vue` | `@chat-adapter/web/vue` | `"ai-sdk"` (默认) |
| AI SDK + Svelte / Svelte Kit 软件 | `ai`, (中文(简体) ), `@ai-sdk/svelte` | `@chat-adapter/web/svelte` | `"ai-sdk"` (默认) |
| 谭斯塔克AI | `@tanstack/ai-react` (或另一个 TanStack AI 框架包) | `@tanstack/ai-react` | `"ag-ui"` |

## 带CLI的脚手架

要使用Web适配器预选的新浏览器聊天程序 :

```bash
npx create-chat-sdk@latest my-bot --adapter web memory
```

访问 [适配器目录](https://chat-sdk.dev/adapters) 见其他官方和供应商官方适配器.

## 快开始

### 服务器

```typescript
// lib/bot.ts
import { Chat } from "chat";
import { createWebAdapter } from "@chat-adapter/web";
import { createMemoryState } from "@chat-adapter/state-memory";

export const bot = new Chat({
  userName: "mybot",
  adapters: {
    web: createWebAdapter({
      userName: "mybot",
      getUser: (req) => ({ id: getUserIdFromCookie(req) }),
    }),
  },
  state: createMemoryState(),
});

bot.onDirectMessage(async (thread, message) => {
  await thread.post(`You said: ${message.text}`);
});
```

```typescript
// app/api/chat/route.ts
import { after } from "next/server";
import { bot } from "@/lib/bot";

export async function POST(request: Request): Promise<Response> {
  return bot.webhooks.web(request, {
    waitUntil: (task) => after(() => task),
  });
}
```

### 客户端

#### 反应

```tsx
// app/chat/page.tsx
"use client";
import { useChat } from "@chat-adapter/web/react";

export default function ChatPage() {
  const { messages, sendMessage, status, stop } = useChat();
  // Render with `ai-elements` (<Conversation>, <Message>, <PromptInput>)
  // or your own components — `messages`, `sendMessage`, `status` are the
  // standard `@ai-sdk/react` API.
}
```

#### 阴道

```vue
<!-- components/Chat.vue -->
<script setup lang="ts">
import { useChat } from "@chat-adapter/web/vue";

const chat = useChat({ api: "/api/chat" });
</script>

<template>
  <div v-for="msg in chat.messages" :key="msg.id">
    <template
      v-for="(part, index) in msg.parts"
      :key="`${msg.id}-${part.type}-${index}`"
    >
      <p v-if="part.type === 'text'">{{ part.text }}</p>
    </template>
  </div>
</template>
```

#### 丝绒

```svelte
<!-- Chat.svelte -->
<script lang="ts">
  import { useChat } from "@chat-adapter/web/svelte";

  const chat = useChat({ api: "/api/chat" });
</script>

{#each chat.messages as msg (msg.id)}
  {#each msg.parts as part, index (`${msg.id}-${part.type}-${index}`)}
    {#if part.type === "text"}<p>{part.text}</p>{/if}
  {/each}
{/each}
```

#### 谭斯塔克AI

设定 `protocol: "ag-ui"` 在适配器上,然后点 TanStack AI的 `useChat` 在路线上 `fetchServerSentEvents`数字 :

```typescript
createWebAdapter({
  userName: "mybot",
  getUser: (req) => ({ id: getUserIdFromCookie(req) }),
  protocol: "ag-ui",
});
```

```tsx
// app/chat/page.tsx
"use client";
import { fetchServerSentEvents, useChat } from "@tanstack/ai-react";

export default function ChatPage() {
  const { messages, sendMessage, isLoading, stop } = useChat({
    connection: fetchServerSentEvents("/api/chat"),
    threadId: "support-1",
  });
  // Text parts carry their text in `part.content`.
}
```

`threadId` 成为聊天- sdk 线条 id 中的对话 id 。 每个 `thread.post` 调用作为自己的助理消息到达,处理器错误以一个 `RUN_ERROR` 活动.

## 认证

`getUser` 这是 **安全边界** 用于网络适配器。 与Slack/Teams不同的是,平台在每一个webhook上签名,web请求直接来自浏览器——您必须亲自识别呼叫者. 正在返回 `null` 导致适配器以 HTTP 401 响应,没有处理器运行.

插入您的应用程序已经使用的内容 :

```typescript
// NextAuth
createWebAdapter({
  userName: "mybot",
  getUser: async (req) => {
    const session = await getServerSession(authOptions);
    if (!session?.user) return null;
    return { id: session.user.id, name: session.user.name };
  },
});

// Clerk
createWebAdapter({
  userName: "mybot",
  getUser: async (req) => {
    const { userId, sessionClaims } = await auth();
    if (!userId) return null;
    return { id: userId, name: sessionClaims?.name as string | undefined };
  },
});

// Custom session cookie
createWebAdapter({
  userName: "mybot",
  getUser: async (req) => {
    const sessionId = req.headers.get("cookie")?.match(/session=([^;]+)/)?.[1];
    if (!sessionId) return null;
    const user = await db.users.findBySession(sessionId);
    return user ? { id: user.id, name: user.name } : null;
  },
});
```

若为 `getUser` 扔出,适配器返回401并记录出错。 在错误消息中不要包括敏感数据——它没有被浮出客户端,而是被登录.

> 决心 `user.id` 嵌入到聊天- sdk 线索 id (参见 [线索](https://npmcn.com/package/%40chat-adapter/web/#readme-threading) 页:1 包含的用户代号 `:` 与 HTTP 400 一同被拒绝,因为他们会破坏往返 `decodeThreadId`。如果您的认证提供者以冒号(例如. `provider:sub` 要求) `getUser` ——以基数64-编码为例.

## 线索

默认情况下,每个 `useChat` 一个聊天- sdk 线索的对话地图 :

```
web:{user.id}:{conversationId}
```

`conversationId` 这是 `id` 字段 AI SDK 的使用 Chat 在其请求正文中发送,或 `threadId` 字段为 `protocol: "ag-ui"`。如果客户提供(`useChat({ id: "support-chat" })`),它通过再装入来再使用;否则每个请求都会生成新鲜的ID. 一个不是字符串的对话ID,或者包含 `:`,用HTTP 400拒绝.

`channel.messages` 财务报告和审定财务报表 `thread.messages` 在网络上是等同的——频道 id 是线索 id. 这样可以避免交会出血 `persistMessageHistory` 被启用,而同一用户有多个使用Chat 对话框打开.

覆盖( 例如, 每个用户一个线程, 不分对话) :

```typescript
createWebAdapter({
  userName: "mybot",
  getUser: (req) => /* ... */,
  threadIdFor: ({ user }) => `web:${user.id}:default`,
});
```

编码/解码辅助器在适配器上被曝光:

```typescript
adapter.encodeThreadId({ userId: "u1", conversationId: "abc" });
// → "web:u1:abc"
adapter.decodeThreadId("web:u1:abc");
// → { userId: "u1", conversationId: "abc" }
```

## 流线

`thread.post` 接受一个 `AsyncIterable<string | StreamChunk>` 并直接将 Dertas 泵入SSE 响应机体——没有编辑回路,没有限制速率. Handlers可以使用任何模型库. 例如,用AI SDK的 `streamText`数字 :

```typescript
import { streamText } from "ai";
// Bring your own model from any AI SDK provider
// (@ai-sdk/openai, @ai-sdk/anthropic, @ai-sdk/google, ...).

bot.onDirectMessage(async (thread, message) => {
  const result = streamText({
    model: myModel,
    prompt: message.text,
  });
  await thread.post(result.textStream);
});
```

适配者的荣誉 `request.signal`,所以打电话 `stop()` 从客户端的短路中取出服务器上的转发器. `task_update` 财务报告和审定财务报表 `plan_update` `StreamChunk`电线上没有原生的v1代表,被悄悄地抛出.

## 信件持续性

`persistMessageHistory` 默认为 **`true`**。Web没有平台侧历史 API,所以是聊天 sdk 处理器通过前一个回合查看的唯一方法 `thread.messages` 编号 : `channel.messages` 是通过配置的状态适配器消息历史缓存。 准备吧 `false` 只有在您的操作者不需要前轮 :

```typescript
createWebAdapter({
  userName: "mybot",
  getUser: (req) => /* ... */,
  persistMessageHistory: false,
});
```

客户端在每个请求上重新发送整个对话,但适配器不从中读取历史. 浏览器控制请求主体 `messages[]` 数组,因此适配器只消耗最新的用户消息,并从中去除工具部件. 最后一个条目必须是用户消息;一个以助手或工具消息结尾的正文,如客户端工具结果被HTTP 400拒绝. 再次发送相同的用户消息( S)`regenerate()` 或重新装入)再次运行处理器,而不是作为重复被丢弃,历史保存了更早的回覆并存储了重复的信件第二次.

`message.raw` 输入 `WebMessage`部分字段 `type` 为: `unknown`与 `"ai-sdk"` 形状匹配 AI SDK `UIMessage`这样你就可以投出 `message.raw as UIMessage`。 。 。 .

## 框架帮助者

`@chat-adapter/web/react` 输出薄薄的包装 `@ai-sdk/react`是因为 `useChat` 预配置为 `DefaultChatTransport`数字 :

```tsx
import { useChat } from "@chat-adapter/web/react";

const { messages, sendMessage, status, stop, regenerate } = useChat({
  api: "/api/chat",        // default
  threadId: "support-1",   // becomes useChat's `id` and the request body's `id`
});
```

| 选项 | 说明 |
| --- | --- |
| `api` | Web适配器路由的API端点. 默认为 `/api/chat`。 。 。 . |
| `threadId` | 聊天- sdk 线程 id — 请求体的表面 `id` 这样服务器就可以获得聊天-sdk线程 id. 大力推荐. 倒计时 `id` 从 `ChatInit`。 。 。 . |
| `experimental_throttle` | Throttle在ms中等待聊天消息和数据更新. |
| `resume` | 是否恢复当前聊天生成流 . |
| 退缩 | 所有其他选项都通过 `@ai-sdk/react`是因为 `useChat`。 。 。 . |

用于高级配置(海关运输、响应拦截器等) `@ai-sdk/react`是因为 `useChat` 直接——包装上没有什么神奇.

`@chat-adapter/web/vue` 出口a `useChat` 返回 Vue 反应的工厂 `Chat` 实例 `@ai-sdk/vue`数字 :

```vue
<script setup lang="ts">
import { useChat } from "@chat-adapter/web/vue";

const chat = useChat({ api: "/api/chat", threadId: "support-1" });
</script>

<template>
  <div v-for="msg in chat.messages" :key="msg.id">
    <template
      v-for="(part, index) in msg.parts"
      :key="`${msg.id}-${part.type}-${index}`"
    >
      <p v-if="part.type === 'text'">{{ part.text }}</p>
    </template>
  </div>
</template>
```

`@chat-adapter/web/svelte` 出口a `useChat` 返回 Svelte 反应的工厂 `Chat` 实例 `@ai-sdk/svelte`数字 :

```svelte
<script lang="ts">
  import { useChat } from "@chat-adapter/web/svelte";

  const chat = useChat({ api: "/api/chat", threadId: "support-1" });
</script>

{#each chat.messages as msg (msg.id)}
  {#each msg.parts as part, index (`${msg.id}-${part.type}-${index}`)}
    {#if part.type === "text"}<p>{part.text}</p>{/if}
  {/each}
{/each}
```

与反应助手不同,Vue和Svelte返回 `Chat` 直接出现。 访问 `chat.messages`, (中文(简体) ), `chat.sendMessage()`, (中文(简体) ), `chat.status`,以及 `chat.stop()` 而不是去结构化.

## 配置

| 选项 | 需求 | 说明 |
| --- | --- | --- |
| `userName` | 对 | Bot用户名. 聊天 sdk 要求的提及检测( S)`@username`)并种子助理消息的机器人身份. |
| `getUser` | 对 | `(request: Request) => WebUser | null | Promise<WebUser | null>`。从输入的 HTTP 请求中解析用户。 正在返回 `null` 生产出 HTTP 401. |
| `protocol` | 没有 | `"ai-sdk"` (违约)或 `"ag-ui"`. 请求和流式答复的无线电协议。 使用 `"ag-ui"` 给TanStack AI和其他AG-UI客户端. |
| `persistMessageHistory` | 没有 | 在配置的状态适配器中坚持发送消息历史 。 默认 : `true`。 。 。 . |
| `threadIdFor` | 没有 | 从已解析的用户和使用Chat 对话 id 中获取聊天- sdk 线索 id 。 默认 : `web:{user.id}:{conversationId}`。 。 。 . |
| `logger` | 没有 | 锁定实例( 默认为 `ConsoleLogger("info")`) (中文(简体) ). |

## 特征

### 通讯

| 特性 | 支助 |
| --- | --- |
| 邮件 | 对 |
| 编辑信件 | 没有(每个助理转弯都是新鲜的回音) |
| 删除信件 | 没有 |
| 文件上传 | 否(推迟到v2) |
| 流线 | 原生( SSE: AI SDK UI 消息流或 AG- UI) |
| 已排定的消息 | 没有 |

### 丰富内容

| 特性 | 支助 |
| --- | --- |
| 卡片格式 | 只在v1(卡/JSX被推迟到v2)中下标 |
| 按钮 | 没有 |
| 表格 | 是(全球增长机制降标) |
| 模块 | 没有 |

### 对话

| 特性 | 支助 |
| --- | --- |
| 提及 | N/A(每个网络消息路由作为管理器) |
| 添加反应 | 没有 |
| 删除反应 | 没有 |
| 打字指标 | 不适用(使用Chat生成a) `status` (来自SSE反应本身) |
| 模式 | 对.. `isDM: true` 每个线程 |

### 信件历史

| 特性 | 支助 |
| --- | --- |
| 获取信件 | Via 状态适配器缓存( 无平台 API) |
| 获取单个消息 | 没有 |
| 获取线索信息 | 是(合成) |
| 获取频道消息 | 通过状态适配器缓存 |
| 列表线索 | 没有 |
| 后频道消息 | 没有 |

## v1 范围

**在:** 文本 + 标记下, 本地流线, DM 风格的路由, 持续的信息历史, 中止通过 `request.signal`。 。 。 .

**退出( 推迟至 v2 ):** 卡/JSX渲染,反应,模式,文件上传,编辑/删除,多塔布主动推.

## 解决问题

### 每个请求返回401

-   `getUser` 正在返回 `null` 或掷出. 在其中添加一个日志以确认请求实际包含您期望的会话 .
-   饼干没有被转发——检查一下 `useChat` 被挂载在与 `/api/chat` (或您的运输通过证书).

### 每个请求返回 400 “无效用户 ID ”

-   身份证归来 `getUser` 包含一个 `:` 字符,将损坏线条编号的回转。 将内部的标识规范化 `getUser` (例如, `id.replace(/:/g, "_")` 或基础64-编码它.

### `useChat` 在每次渲染时重现状态

-   别走 `id: undefined` 改为 `useChat`\- 内部的包裹守卫 - 但是如果你打电话 `@ai-sdk/react`是因为 `useChat` 直接删除 `id` 而不是通过 `undefined`。 。 。 .

### `thread.messages` 为空

-   `persistMessageHistory` 实值 `false` 没有任何平台-侧面的历史可以倒退。 准备吧 `true` (默认). 适配器从不通过请求体 `messages[]` 因此,状态适配器是先前转弯的唯一来源.

### 请求退回 400 “信件的最后一项必须是用户信件”

-   适配器只处理新用户转动. 客户端工具结果和自动重新提交(例如, `useChat`是因为 `sendAutomaticallyWhen`)发送一个以助手或工具消息结尾的正文,不支持.

## AI 编码代理

如果您使用OpenAI Codex, Claude Code, 或 Cursor 等AI编码代理, 在写入代码前安装 Chat SDK 技能, 使其了解 SDK API, 适配器模式, 以及项目常规 .

```bash
npx skills add vercel/chat
```

技术参考文献 `node_modules/chat/docs`,加上已发布的软件包中的适配器指南和启动模板.

您也可以安装 [Vercel 插件](https://vercel.com/docs/agent-resources/vercel-plugin) 包括Chat SDK技术与专家代理、代理斜线指令

```bash
npx plugins add vercel/vercel-plugin
```

插件是可选的;单是技能就足以用Chat SDK来构建.

关于可代理阅读的文件,见 [聊天- sdk.dev/llms.txt](https://chat-sdk.dev/llms.txt) (页数索引)或 [聊天- sdk.dev/llms- full.txt](https://chat-sdk.dev/llms-full.txt) (全文).

## 许可证

麻省理工学院

## 常见问题

### @chat-adapter/web 是什么？

Chat SDK的网络适配器——浏览器在AI SDK或AG-UI\(TanStack AI\)流协议上的聊天UI

### 如何安装 @chat-adapter/web？

在项目目录运行 npm install @chat-adapter/web，或使用 pnpm add / yarn add / bun add。

### @chat-adapter/web 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @chat-adapter/web 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @chat-adapter/web 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @chat-adapter/web 可以商用吗？

@chat-adapter/web 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @chat-adapter/web 的下载量有多少？

根据 npm 官方下载统计，@chat-adapter/web 在 2026/10/10 – 2026/11/08 这 30 天内被下载 81,011 次，日均约 2,700 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @chat-adapter/web 还在维护吗？

最新版本 4\.44\.0 发布于 2026/11/02（6 天前）；至今共发布 20 个版本，其中过去 12 个月发布了 20 个；首次发布于 2026/05/08。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

