文档

订单状态与物流助手

处理订单类咨询(状态、延迟、变更),并快速草拟有用的回复。

本指南将一步步教你如何把 订单状态与物流助手 模板接入你自己的应用。无需任何 AI 经验,你只需要复制代码,而不是编写 AI 逻辑。

它做什么

处理订单类咨询(状态、延迟、变更),并快速草拟有用的回复。

模板自带 2 个工作流2 个响应格式,它们已经可以协同工作:

  • 工作流:order_triage_workfloworder_reply_workflow
  • 响应格式:order_triage_responseorder_reply_response

想走完全无代码的路径? 直接跳到 第 6 步:无代码方案

你将构建什么

  • 一个后端端点,用客户请求启动 订单状态与物流助手 工作流。
  • 一个实时聊天界面,在生成过程中流式展示 AI 回复。
  • 一个Webhook 接收器,接收流水线事件并把结果发回给客户。

步骤 1:下载并导入模板

  1. 打开 订单状态与物流助手 模板页面,点击下载 JSON
  2. 在 ModelRiver 项目中点击导入,粘贴或上传文件,确认预览后完成导入。所有内容以原子方式创建,不会覆盖任何已有数据。
  3. 了解更多:导入与导出指南

步骤 2:连接 AI 提供商

该模板运行在 OpenAI 和 Anthropic 上。导入前请先在项目的「提供商」部分完成连接。如果你使用其他提供商,也可以在导入后修改任意工作流。

步骤 3:添加后端端点

你的后端通过调用 ModelRiver API 来启动工作流,需要项目 API 密钥(在「项目设置 → API 密钥」中创建)。响应中包含一次性 ws_token,你的前端用它来流式接收回复。

// Express.js - POST /api/ai/chatimport express from 'express';const app = express();app.use(express.json()); app.post('/api/ai/chat', async (req, res) => {  const response = await fetch('https://api.modelriver.com/v1/ai/async', {    method: 'POST',    headers: {      'Authorization': `Bearer ${process.env.MR_API_KEY}`,      'Content-Type': 'application/json',    },    body: JSON.stringify({      workflow: 'order_triage_workflow',      messages: [{ role: 'user', content: req.body.message }],      inputs: { customer_id: req.body.customer_id },    }),  });  const data = await response.json();  // Return the one-time ws_token so the frontend can stream the reply.  res.json({ ws_token: data.ws_token, channel_id: data.channel_id });}); app.listen(3000);

也可以使用 CLI 在本地运行这个端点:modelriver listen 会把 ModelRiver 的 Webhook 转发到你的 localhost。

步骤 4:在前端流式接收回复

使用 ModelRiver 客户端 SDK 连接数据流。用后端返回的 ws_token 调用 connect() 后,AI 回复会实时到达,无需轮询。

import { useState } from 'react';import { useModelRiver } from '@modelriver/client/react'; export function TemplateChat() {  const [input, setInput] = useState('');  const { connect, response, error, status } = useModelRiver({    baseUrl: 'wss://api.modelriver.com/socket',    persist: true,  });   const handleSend = async () => {    // 1. Your backend starts the order_triage_workflow workflow and returns a one-time ws_token.    const res = await fetch('/api/ai/chat', {      method: 'POST',      headers: { 'Content-Type': 'application/json' },      body: JSON.stringify({ message: input }),    });    const { ws_token, channel_id } = await res.json();     // 2. Connect to ModelRiver's stream. The reply arrives in real time.    connect({ wsToken: ws_token, channelId: channel_id });    setInput('');  };   return (    <div>      <input value={input} onChange={(e) => setInput(e.target.value)}             disabled={status === 'loading'} placeholder="Type your request..." />      <button onClick={handleSend} disabled={!input || status === 'loading'}>Send</button>      {status === 'loading' && <p>Working on it...</p>}      {response && (        <div>          <p>{response.content}</p>          {response.data && <pre>{JSON.stringify(response.data, null, 2)}</pre>}        </div>      )}      {error && <p>{error}</p>}    </div>  );}

npm install @modelriver/client 安装 SDK。同一个 ws_token 可用于 React、Vue、原生 JS 和 Svelte。

步骤 5:在后端接收管道事件

AI 步骤完成后,ModelRiver 会把 task.ai_generated 事件投递到你项目中配置的 Webhook 地址。你的后端可以补充自己的数据(你的政策、订单详情或数据库查询),然后调用事件中的 callback_url,最终回复就会流式发送给客户。

签名通过 mr-signature 请求头校验(使用你的 Webhook 密钥对原始请求体计算 HMAC-SHA256)。

// Express.js - POST /webhooks/modelriverimport express from 'express';import crypto from 'node:crypto'; const app = express();app.use(express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } })); app.post('/webhooks/modelriver', async (req, res) => {  // 1. Verify the HMAC signature. Reject missing, non-string, or  // length-mismatched signatures before comparing bytes.  const signature = req.headers['mr-signature'];  const secret = process.env.MR_WEBHOOK_SECRET;  const expected = crypto    .createHmac('sha256', secret)    .update(req.rawBody)    .digest('hex');  if (    typeof signature !== 'string' ||    signature.length !== expected.length ||    !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))  ) {    return res.status(401).send('Invalid signature');  }   const event = req.body;   // 2. The AI step finished. Enrich it with your own data (order, policy, ...).  const enriched = { ...event.ai_response, checked_at: new Date().toISOString() };  await saveEvent(event.channel_id, enriched); // your database   // 3. Send the enriched result back so the reply streams to the customer.  if (event.callback_url && event.callback_required) {    await fetch(event.callback_url, {      method: 'POST',      headers: {        'Authorization': `Bearer ${process.env.MR_API_KEY}`,        'Content-Type': 'application/json',      },      body: JSON.stringify({ data: enriched }),    });  }   res.status(200).send('ok');}); app.listen(3000);

步骤 6:无代码方案

不想自己运行服务器?这些平台可以直接接收流水线事件、存储数据并回调,无需管理任何基础设施。

// Supabase Edge Function - webhooks/modelriver// Deploy with: supabase functions deploy webhooks-modelriverimport { serve } from 'https://deno.land/[email protected]/http/server.ts';import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'; const supabase = createClient(  Deno.env.get('SUPABASE_URL')!,  Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!); async function verifySignature(raw: string, signature: string | null): Promise<boolean> {  if (!signature) return false;  const key = await crypto.subtle.importKey(    'raw',    new TextEncoder().encode(Deno.env.get('MR_WEBHOOK_SECRET')!),    { name: 'HMAC', hash: 'SHA-256' },    false,    ['sign']  );  const digest = new Uint8Array(    await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(raw))  );  const expected = [...digest]    .map((byte) => byte.toString(16).padStart(2, '0'))    .join('');  if (signature.length !== expected.length) return false;  const a = new TextEncoder().encode(signature);  const b = new TextEncoder().encode(expected);  let diff = 0;  for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];  return diff === 0;} serve(async (req) => {  // 1. Verify the HMAC signature over the raw body before parsing the event.  const raw = await req.text();  if (!(await verifySignature(raw, req.headers.get('mr-signature')))) {    return new Response('Invalid signature', { status: 401 });  }  const event = JSON.parse(raw);   // 2. Store the AI step result in Postgres.  const { error } = await supabase.from('ai_content').insert({    channel_id: event.channel_id,    payload: event.ai_response,    status: 'ai_generated',  });  if (error) return new Response(error.message, { status: 500 });   // 3. Send the result back so the reply streams to the customer.  if (event.callback_url && event.callback_required) {    await fetch(event.callback_url, {      method: 'POST',      headers: {        Authorization: `Bearer ${Deno.env.get('MR_API_KEY')}`,        'Content-Type': 'application/json',      },      body: JSON.stringify({ data: event.ai_response }),    });  }   return new Response('ok');});

端到端测试

  1. 启动你的后端(或部署无代码函数),并在项目中配置 MR_API_KEYMR_WEBHOOK_SECRET 和 Webhook 地址。
  2. 打开前端,输入一条测试请求并点击发送
  3. 确认回复实时到达,并且后端收到了 task.ai_generated 事件。

后续步骤