ESC
开源 1 分钟阅读

chatbot-template:基于Next.js、AI SDK、shadcn/ui构建的极简聊天机器人模板

shadcn/ui团队发布了一个极简聊天机器人模板,基于Next.js、AI SDK、shadcn/ui及Vercel AI Gateway构建,支持流式聊天、工具调用、网络搜索和人工介入问卷,可一键部署到Vercel,无需额外配置。

来源:GitHub

chatbot-template

一个极简聊天机器人模板,基于Next.js、AI SDK、shadcn/ui、shadcn/react、shadcn/typeset以及Vercel AI Gateway构建。

GitHub stars GitHub forks License

特性

  • 流式聊天,支持Markdown渲染和shadcn/typeset
  • 工具调用示例
  • 通过各提供商内置搜索工具进行网络搜索
  • 人在回路的问卷功能。模型可以提出澄清问题,使用shadcn问卷组件作答

部署

Deploy with Vercel

就这么简单——无需配置。Vercel部署通过OIDC自动认证到AI Gateway,用量计入你团队的AI Gateway额度。

本地开发

pnpm install

然后为应用提供网关凭证,可以从已关联的Vercel项目拉取OIDC令牌:

vercel link
vercel env pull

或在Vercel控制台(AI Gateway → API Keys)创建API密钥,并添加到.env.local:

cp .env.example .env.local
# 然后设置 AI_GATEWAY_API_KEY=...

启动开发服务器:

pnpm dev

配置

环境变量必填描述
AI_GATEWAY_API_KEY仅本地开发AI Gateway API密钥。Vercel部署时无需(使用OIDC)。

模型列表位于lib/models.ts——第一个条目为默认模型。

安全

/api/chat路由为公开且未鉴权——每个请求都会消耗你的AI Gateway额度。作为个人演示没问题,但在面向真实流量之前,你应该:

该路由已经校验请求体、将模型限制为lib/models.ts、限制输出令牌和步骤数,并在客户端断开时中止生成——但这些只限制单个请求,不限制整体流量。

工作原理

  • app/api/chat/route.ts使用streamText流式响应
  • components/chat.tsx使用useChat和shadcn聊天原语渲染对话。
  • tools/定义工具——每个工具一个文件(文件名即模型面对的工具名),在tools/index.ts中组合:包括服务端执行的GitHub仓库查询、交互式ask_user问卷,以及提供商原生的网络搜索。

工具部件

助手消息是一组带类型的部件列表。components/chat-message.tsx根据part.type进行切换,并将每个部件委托给components/parts/中的对应组件:

部件类型组件渲染内容
texttext-part.tsx通过react-markdown和shadcn/typeset渲染Markdown。
tool-github_repogithub-repo-part.tsx查询运行时显示旋转指示器,然后显示带链接的统计行(星标、分支、语言)。
tool-web_searchweb-search-part.tsx搜索运行时显示“正在搜索网络…”状态,每次搜索后显示一条持久的“已搜索网络”行。
tool-ask_userask-user-part.tsx已回答的问题内联显示。待处理问题在question-card.tsx中渲染,固定在滚动器底部。
source-urlsources-part.tsx网络搜索引用,在消息流式结束后去重到“已搜索N个网站”抽屉中。

工具部件随着流的推进经历多个状态——input-streaming → input-available → output-available(或output-error)——每个组件根据part.state显示进度、结果和失败。

添加自定义工具

  1. 创建tools/<name>.ts(文件名即模型面对的工具名),导出包含description、inputSchema和execute函数的tool()(对于用户在界面中回答的工具,如ask_user,可省略execute),然后在tools/index.ts中注册。
  2. 在components/parts/中添加部件组件,并在chat-message.tsx中添加case "tool-<name>"。

消息类型通过InferUITools从工具定义中推断,因此part.input和part.output在部件组件中具有完整类型——重命名字段会产生构建错误,而不是静默的undefined。

添加组件

npx shadcn@latest add button

许可证

MIT——见LICENSE。