构建一款完整的 AI 驱动研究助手,能够抓取网站并在网上搜索来回答问题。助手会自动判断何时使用网页抓取或搜索工具来收集信息,并基于汇总的数据提供全面的答案。
你将构建的内容#
一个 AI 聊天界面,用户可以就任意主题提问。AI 助手会自动判断何时使用网页爬取或搜索工具收集信息,并基于所获取的数据提供全面答案。
前置条件#
- 已安装 Node.js 18 或更高版本
- 来自 platform.openai.com 的 OpenAI API 密钥
- 来自 firecrawl.dev 的 Firecrawl API 密钥
- 具备 React 和 Next.js 的基础知识
创建新的 Next.js 项目
先创建一个全新的 Next.js 应用,并进入项目目录:
在出现提示时,选择以下选项:
- TypeScript:是
- ESLint:是
- Tailwind CSS:是
- App Router:是
- 使用
src/目录:否 - 导入别名:是 (@/*)
安装依赖项
安装 AI SDK 包#
AI SDK 是一个 TypeScript 工具包,提供统一的 API,便于与不同的 LLM 服务提供商对接:
这些软件包提供:
ai:包含流式传输、工具调用和响应处理的核心 SDK@ai-sdk/react:用于构建聊天界面的 React Hooks (如useChat)zod:用于工具输入的架构校验
在 ai-sdk.dev/docs 了解更多。
安装 AI Elements#
AI Elements 提供用于 AI 应用的预构建 UI 组件。运行以下命令以生成所有必需的组件脚手架:
这会在你的项目中初始化 AI Elements,包括会话组件、消息展示、提示输入和工具调用可视化。
文档:ai-sdk.dev/elements/overview。
安装 OpenAI Provider#
安装 OpenAI Provider 以连接到 OpenAI 的模型:
构建前端聊天界面
在 app/page.tsx 创建主页面,并从下方的 Code 标签页复制代码。这将是用户与 AI 助手交互的聊天界面。
了解前端#
前端使用 AI Elements 组件提供完整的聊天界面:
核心功能:
- 会话显示:
Conversation组件会自动处理消息的滚动与呈现 - 消息渲染:每个消息片段会根据其类型 (文本、推理、工具调用) 进行渲染
- 工具可视化:工具调用以可折叠的部分展示其输入和输出
- 交互控件:用户可切换网页搜索、选择模型并附加文件
- 消息 actions:为 assistant 消息提供复制与重试的 actions
添加 Markdown 渲染功能
为确保 LLM 输出的 Markdown 正确渲染,请在你的 app/globals.css 文件中添加以下 import:
这将导入在消息回复中渲染 Markdown 内容所需的样式。
构建基础型 API 路由
在 app/api/chat/route.ts 中创建聊天 API 端点。该路由将处理传入消息,并以流式方式返回来自 AI 的响应。
这个基础路由:
- 接收来自前端的消息
- 使用用户选择的 OpenAI 模型
- 将响应以流式方式返回给客户端
- 尚未包含工具——我们稍后会添加
配置环境变量
在项目根目录下创建一个 .env.local 文件:
添加你的 OpenAI API 密钥:
OPENAI_API_KEY 是 AI 模型正常运行所必需的。
测试基础聊天
现在你可以在未集成 Firecrawl 的情况下测试 AI SDK 聊天机器人。启动开发服务器:
在浏览器中打开 localhost:3000 并测试基础聊天功能。助手应能回复消息,但暂不具备网页抓取或搜索能力。
添加 Firecrawl 工具
现在,让我们使用 Firecrawl 为助手增强网页抓取和搜索功能。
安装 Firecrawl SDK#
Firecrawl 通过抓取和搜索,将网站转换为适用于 LLM 的 formats:
创建工具文件#
创建一个 lib 文件夹,并在其中添加一个 tools.ts 文件:
添加以下代码以定义网页抓取与搜索工具:
了解这些工具#
Scrape Website 工具:
- 接收一个 URL 作为输入 (由 Zod 架构验证)
- 使用 Firecrawl 的
scrape方法以 Markdown 获取页面内容 - 仅提取主要内容以减少 token 消耗
- 返回抓取的内容供 AI 分析
Search Web 工具:
- 接收带可选筛选条件的搜索查询
- 使用 Firecrawl 的
search方法查找相关网页 - 支持位置、时间范围、内容类别等高级筛选
- 返回包含标题、URL 和描述的结构化结果
了解更多关于工具的信息:ai-sdk.dev/docs/foundations/tools。
使用 Firecrawl 工具更新 API 路径
现在更新你的 app/api/chat/route.ts,把我们刚创建的 Firecrawl 工具加入进去。
查看完整的 app/api/chat/route.ts 代码
与基础路由相比的关键改动:
- 从 AI SDK 引入
stepCountIs - 从
@/lib/tools引入 Firecrawl 工具 - 添加包含
scrapeWebsite和searchWeb的tools对象 - 添加
stopWhen: stepCountIs(5)以限制执行步数 - 启用网页搜索时将
toolChoice设为 "auto",否则为 "none"
了解更多关于 streamText:ai-sdk.dev/docs/reference/ai-sdk-core/stream-text。
添加你的 Firecrawl API 密钥
测试完整应用程序
重启开发服务器:
打开 localhost:3000 测试增强版助手:
- 切换“Search”按钮以启用网页搜索
- 提问:“What are the latest features from firecrawl.dev?”
- 观察 AI 调用
searchWeb或scrapeWebsite工具 - 在 UI 中查看工具执行的输入与输出
- 阅读基于抓取数据的 AI 分析
工作机制#
消息流#
- 用户发送消息:用户输入问题并点击提交
- 前端发送请求:
useChat携带所选模型和网页搜索设置,将消息发送到/api/chat - 后端处理消息:API 路由接收消息并调用
streamText - AI 选择工具:模型分析问题并决定是否使用
scrapeWebsite或searchWeb(仅在启用网页搜索时) - 工具执行:若调用了工具,Firecrawl 将执行网页抓取或搜索
- AI 生成响应:模型分析工具结果并生成自然语言响应
- 前端展示结果:UI 实时显示工具调用与最终响应
工具调用流程#
AI SDK 的工具调用系统(ai-sdk.dev/docs/foundations/tools)工作方式如下:
- 模型接收用户消息和可用的工具描述
- 如果模型判断需要使用工具,则生成带参数的工具调用
- SDK 使用这些参数执行工具函数
- 将工具结果返回给模型
- 模型基于结果生成最终响应
以上过程会在一次 streamText 调用中自动完成,并将结果实时流式传输到前端。
核心功能#
模型选择#
该应用支持多种 OpenAI 模型:
- GPT-5 Mini(Thinking):OpenAI 的新近模型,具备更强的推理能力
- GPT-4o Mini:速度快、成本友好的模型
用户可以通过下拉菜单在不同模型之间切换。
Web Search 开关#
Search 按钮用于控制 AI 是否可以使用 Firecrawl 工具:
- 启用:AI 可按需调用
scrapeWebsite和searchWeb工具 - 禁用:AI 仅基于其训练知识作答
这让用户可以掌控何时使用网页数据,而非依赖模型的内置知识。
自定义方案思路#
添加更多工具#
使用其他工具扩展助手:
- 查询公司内部数据的数据库
- 集成 CRM 以获取客户信息
- 发送电子邮件
- 生成文档
每个工具遵循相同模式:使用 Zod 定义模式(schema),实现 execute 函数,并将其注册到 tools 对象中。
更换 AI 模型#
将 OpenAI 切换为其他供应商:
AI SDK 通过同一套 API 支持 20 多家提供商。了解更多:ai-sdk.dev/docs/foundations/providers-and-models。
自定义 UI#
AI Elements 组件基于 shadcn/ui 构建,因此你可以:
- 在组件文件中调整组件样式
- 为现有组件添加新的变体
- 创建符合设计系统的自定义组件
最佳实践#
-
使用合适的工具:优先用
searchWeb搜索相关页面,单页用scrapeWebsite,或交由 AI 决定 -
监控 API 使用:跟踪你的 Firecrawl 与 OpenAI API 使用量,以避免意外开销
-
优雅处理错误:工具内置错误处理,但建议补充面向用户的错误提示
-
优化性能:使用流式输出提供即时反馈,并考虑缓存高频访问的内容
-
设置合理的限制:通过
stopWhen: stepCountIs(5)避免过多工具调用与成本失控

