为什么这个示例很重要
传统的 AI 集成需要您管理复杂的基础设施:轮询响应、处理超时、管理连接状态以及构建自定义流式传输解决方案。ModelRiver 消除了所有这一切。
只需几行代码,您即可获得:
- 真正的端到端流式传输:从用户输入到 AI 响应,一切都通过 WebSockets 实时流动
- 零基础设施开销:无需构建或维护您自己的流式传输服务器
- 自动故障转移:当 AI 模型不可用时具有内置的供应商回退功能
- 结构化输出(Structured outputs):定义 JSON schema 并获得格式完美、类型安全的响应
- 事件驱动的回调:在 AI 处理和响应传递之间注入自定义逻辑
您将构建什么
一个全栈聊天机器人应用程序,具有:
| 功能特征 | 描述 |
|---|---|
| 实时聊天 UI | 具有即时消息传递功能的现代 React 界面 |
| 异步 AI 处理 | 通过 ModelRiver 的异步 API 进行非阻塞请求 |
| WebSocket 流式传输 | 使用 @modelriver/client SDK 进行实时响应传递 |
| 结构化响应 | 带有情感分析、置信度分数和待办事项的 AI 响应 |
| 自定义 ID 注入 | 在整个生命周期中使用您自己的 UUID 跟踪对话 |
架构概述
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│ React Frontend │────▶│ Node.js Server │────▶│ ModelRiver API ││ (Your App) │ │ (Your Backend) │ │ (AI Gateway) │└─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ AI Processing │ │ │ │ (Background) │ │ │ └─────────────────┘ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Webhook Event │◀─────────────┘ │ │ + ID Injection │ │ └─────────────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ Callback URL │ │ │ (to ModelRiver)│ │ └─────────────────┘ │ │ └───────────────────────┘ WebSocket Stream (Real-time Response)魔法所在:事件驱动的回调
这就是 ModelRiver 真正闪耀的地方。当您发送异步 AI 请求时:
- ModelRiver 处理您的请求并生成 AI 响应。
- 在传递到您的前端之前,ModelRiver 会向您的后端发送一个 webhook。
- 您的后端丰富了该响应(例如使用自定义 ID)、验证数据或触发其他操作。
- 您的后端回拨到 ModelRiver 并带有被丰富的数据负载。
- ModelRiver 将最终响应通过 WebSocket 流式传输给您的前端。
此模式支持传统 AI API 无法实现的用例:
- 用于数据库跟踪的自定义 ID 注入
- 响应验证和过滤
- 敏感内容的审批关卡
- 多步丰富管道
分步设置指南
按照以下步骤使聊天机器人在本地运行。本指南涵盖了从克隆代码到获得您的第一个 AI 响应的所有内容。
先决条件
- Node.js 16+
- 一个 ModelRiver 帐户(在此处创建一个)
步骤 1:克隆和安装
git clone https://github.com/modelriver/modelriver-chatbot-demo.gitcd modelriver-chatbot-demo # Install backend dependenciescd backend && npm install # Install frontend dependenciescd ../frontend && npm install步骤 2:设置 ModelRiver 控制台
2.1 创建项目
- 前往 console.modelriver.com
- 点击 New Project 并为其命名(例如
my-chatbot)
2.2 连接 AI 供应商(Provider)
- 导航到项目中的 Providers。
- 点击 Add Provider 并选择其中一个(例如 OpenAI,Anthropic)。
- 输入您供应商的 API 密钥并保存。
2.3 创建结构化输出(Structured output)
这定义了 AI 响应的 JSON 格式。导航到 Structured Outputs → Create Structure。
- 名称(Name):
chatbot_response - 示例数据(Sample data): 粘贴此响应示例:
1{2 "reply": "The AI's direct response",3 "summary": "Brief summary of the conversation",4 "sentiment": "positive | negative | neutral | mixed",5 "confidence": 0.95,6 "topics": ["topic1", "topic2"],7 "action_items": [8 { "task": "Description", "priority": "high | medium | low" }9 ]10}- 点击 Build schema from sample data:这将自动生成带有示例的类型化 JSON 模式(schema),以提高 AI 输出的准确性。
- 保存(Save)该结构。
2.4 创建工作流(Workflow)
导航到 Workflows → Create Workflow。
| 设置 | 值 |
|---|---|
| 名称(Name) | mr_chatbot_workflow(必须与代码中的默认值匹配) |
| 供应商(Provider) | 选择您所连接的供应商 |
| 模型(Model) | 选择一个模型(例如 gpt-5-mini,claude-haiku-4-5) |
| 结构化输出(Structured output) | 选择 chatbot_response |
| 事件名称(Event name) | new_chat(触发 webhook 回调) |
保存(Save)该工作流。
2.5 创建 API 密钥
导航到 API Keys → Create Key。
- 输入 密钥名称(key name)(例如
chatbot-dev)。 - 设置 过期时间(expiration)(如果是开发可以选 "永不(Never)",测试就选短一些的时间)。
- 点击 Create Key。
- 立即复制密钥:您将无法再次看到它。
2.6 为本地开发创建 Webhook
导航到 Webhooks → Create Webhook。
- 选择 Localhost (CLI) 作为 webhook 类型:这让 CLI 能够接收 webhook。
- 将 Secret 字段留空以自动生成一个,或输入您自己的字符串。
- 启用该 webhook 并点击 Create webhook。
- 复制此密钥(secret):这是您之后在
.env中设置WEBHOOK_SECRET时所需要的。
步骤 3:配置环境
使用步骤 2 中的值创建 backend/.env:
MODELRIVER_API_KEY=your_api_key_from_step_2.5PORT=4000BACKEND_PUBLIC_URL=http://localhost:4000WEBHOOK_SECRET=your_webhook_secret_from_step_2.6EVENT_NAME=new_chat重要提示: EVENT_NAME 必须与您的工作流中的事件名称相匹配。
步骤 4:设置本地 Webhook 转发
您的 localhost:4000 无法从外部互联网直接访问,因此 ModelRiver 无法直接发送 webhook。CLI 解决了这个问题。
安装并进行身份验证:
npm install -g @modelriver/climodelriver login开始监听:
modelriver forward您将会看到:
✓ Connected to ModelRiver✓ Forwarding webhooks → http://localhost:4000/webhook/modelriver关于安全性的注意事项: 在生产环境中,您应该验证 webhook 签名,以确保请求确实来自 ModelRiver。
步骤 5:运行应用程序
打开三个终端窗口(Tabs):
终端 1:CLI(已经在运行):
modelriver listen终端 2:后端(backend):
cd backend && npm start终端 3:前端(frontend):
cd frontend && npm run dev步骤 6:测试!
- 在您的浏览器中打开
http://localhost:3006。 - 输入一条消息并点击发送。
- 见证奇迹时刻:
- 您的消息被发送到您的后端系统。
- 后端向 ModelRiver 发出异步请求。
- ModelRiver 将请求交由 AI 处理并同时发送了一则 webhook。
- CLI 将收到的 webhook 转发到您本地的 localhost。
- 您的后端向响应中注入了相关数据(enriched response),随后予以回调触发。
- 前端最终通过 WebSocket 连接接收被编排完成后的结构化响应内容。
此时您应该会看到一条已经包含了情感分析识别结果、主题归类以及具体待办选项的一条格式化返回数据!
关键实现细节
发送 AI 请求(后端)
1// POST /chat endpoint2app.post('/chat', async (req, res) => {3 const { message, workflow = 'mr_chatbot_workflow' } = req.body;4 5 // Generate custom IDs for tracking6 const conversationId = uuidv4();7 const messageId = uuidv4();8 9 // Send async request to ModelRiver10 const response = await fetch(`${MODELRIVER_API_URL}/v1/ai/async`, {11 method: 'POST',12 headers: {13 'Authorization': `Bearer ${MODELRIVER_API_KEY}`,14 'Content-Type': 'application/json'15 },16 body: JSON.stringify({17 workflow,18 messages: [{ role: 'user', content: message }],19 delivery_method: 'websocket',20 webhook_url: `${BACKEND_PUBLIC_URL}/webhook/modelriver`,21 events: ['webhook_received'],22 metadata: { conversationId, messageId }23 })24 });25 26 // Return WebSocket connection details to frontend27 const data = await response.json();28 res.json({29 channel_id: data.channel_id,30 websocket_url: data.websocket_url,31 ws_token: data.ws_token32 });33});接收 AI 响应(前端)
1import { useModelRiver } from '@modelriver/client';2 3function ChatApp() {4 const { connect, message, status } = useModelRiver();5 6 const sendMessage = async (text) => {7 // Get WebSocket details from your backend8 const res = await fetch('/chat', {9 method: 'POST',10 body: JSON.stringify({ message: text })11 });12 const { websocket_url, ws_token, channel_id } = await res.json();13 14 // Connect to ModelRiver WebSocket15 connect({ websocket_url, ws_token, channel_id });16 };17 18 // message updates in real-time as AI responds19 return (20 <div>21 <div className="ai-response">{message}</div>22 <button onClick={() => sendMessage('Hello!')}>Send</button>23 </div>24 );25}处理 Webhook(后端)
1// Webhook 端点在 AI 响应到达前端之前接收它2app.post('/webhook/modelriver', async (req, res) => {3 const { channel_id, ai_response, callback_url } = req.body;4 5 // 取回您的自定义 ID6 const pending = pendingRequests.get(channel_id);7 8 // 使用您的自定义 ID 丰富响应9 const enrichedData = {10 id: pending.messageId,11 conversation_id: pending.conversationId,12 ...ai_response.data13 };14 15 // 将丰富(enriched)后的数据发回 ModelRiver16 await fetch(callback_url, {17 method: 'POST',18 headers: { 'Content-Type': 'application/json' },19 body: JSON.stringify(enrichedData)20 });21 22 res.status(200).json({ success: true });23});了解响应(Response)
当配置了结构化输出时(如步骤 2.3中所示),前端会自动渲染:
| 字段 | 显示方式 |
|---|---|
| Reply | 主要的 AI 响应(突出显示) |
| Sentiment | 视觉指示器(正面、中性、负面) |
| Confidence | 颜色编码的进度条 |
| Topics | 交互式标签按钮 |
| Action items | 带有颜色指示的优先级列表 |
API 参考(API reference)
后端端点
| 端点(Endpoint) | 方法 | 描述 |
|---|---|---|
/chat | POST | 发送聊天消息,返回 WebSocket 连接的详细信息 |
/webhook/modelriver | POST | 接收来自 ModelRiver 的 webhook |
/conversations/:id | GET | 获取对话历史记录 |
/health | GET | 健康检查端点 |
请求参数
1{2 "message": "User's message (required)",3 "workflow": "Workflow name (optional, default: mr_chatbot_workflow)",4 "conversationId": "Existing conversation ID (optional)"5}是什么让这与众不同
| 能力特征(Capability) | 传统做法 | 使用 ModelRiver |
|---|---|---|
| 实时流式传输 | 构建自定义 WebSocket 服务器 | SDK 处理一切事物 |
| 本地开发 | ngrok、localtunnel 等软件 | modelriver listen |
| 供应商故障转移 | 手动进行代码编写实现 | 自动化且内置的服务 |
| 响应验证 | 在前端进行后期人工处理 | 事件驱动的回调功能 |
| 结构化输出(Structured output) | 复杂的 Prompt 参数调校工程 | 定义 schema 并直接获取出具有预设格式内容的 JSON |
| 自定义 ID 跟踪 | 跨服务进行追踪比较困难 | 原生的元数据注入 |
下一步(Next steps)
既然现在您已经获得了一个正常运行的聊天机器人,请探索这些领域:
- 增加更多提供者:配置备用的供应商服务以提高可靠性。
- 确保您的 Webhooks 处于安全保护状态:用于生产环境所必须采取的保护措施。
- 自定义架构映射输出(schema):添加适应您用例的相关结构字段。
- 进一步去探索可观测性相关模块:从控制台系统展开查验监控的各项支持处理和动作。
- 更深度结合以及应用相关的 SDK:获得高级的 Hooks 定义及具体设置和引用的各项等内容相关操作。
资源(Resources)
- GitHub 端开源代码库(repository):整个应用系统完整的演示。
- CLI reference documentation(关于终端接口调用操作控制说明文档手则):包含所有的对支持环境终端操控使用等的所有详细等内容各操作控制参量等介绍汇总相关内容项。
- 有关对客户端支持对应的 Client SDK 开发库:包含相关并附带对在对应相关关于支持的对应使用的具有各种关联支持组件有关的。
- 关于支持处理应用各项涉及相关和执行情况的各 webhook 开发指引规范与对接要求(Webhooks guide):针对在与对接应对有关应对对处理对向和包含对于并涉及到关于应对对接事件应对相关对系统等等。
- Workflows(用来搭建操作的各有关对于事件任务流项支持的对应相关管线介绍的各种要求操作指引手则说明书等内容的相关了解查询):建立在支持和建立处理对于相关的流水任务作业管等各相关的。