文档

读取并扩展对话

会话记忆中的对话保存在 ModelRiver 中。你可以在后端读取它们、添加人工接管的消息,或将其重置。

工作流启用会话记忆后,每次携带 session_id 发送的轮次都会保存在 ModelRiver 中(见端点中的会话记忆)。会话 API 让你的后端读取这些对话并向其中追加轮次,因此你无需自己再保存一份聊天记录。

典型用途:

  • 在你的应用中展示用户过去的对话。
  • 将对话转交给人工客服:把用户的消息和客服的回复保存在同一个会话中,这样 AI 重新接手时能看到客服说过的话。
  • 通过实时更新,在你的应用或客服后台中即时显示新的轮次。
  • 删除会话以重置对话。

所有端点都使用与 /v1/ai 相同的项目 API 密钥(Authorization: Bearer mr_live_…),并且只能看到该密钥所属项目中的会话。其他项目的会话,或不是 UUID 的 id,都会返回 404 {"error": "Session not found"}。


列出会话

HTTP
1GET /v1/sessions?workflow=support_bot&limit=20&page=1
参数默认值说明
workflow全部只返回该名称工作流的会话
limit20每页数量,最多 100
page1页码,从 1 开始

会话按最近活动时间倒序排列。

JSON
1{
2 "data": [
3 {
4 "id": "9f8c2c1e-5b8a-4d0e-9a51-2f6f0f1d7a10",
5 "workflow": "support_bot",
6 "message_count": 6,
7 "last_activity_at": "2026-10-25T09:14:03.512Z",
8 "inserted_at": "2026-10-25T08:58:41.007Z",
9 "last_message": {
10 "role": "assistant",
11 "content": "Your refund was issued today.",
12 "at": "2026-10-25T09:14:03.498Z"
13 }
14 }
15 ],
16 "page": 1,
17 "limit": 20
18}

message_count 统计已保存的轮次:每条 AI 回复和每条追加的消息各计一次。最新轮次没有可读文本时,last_message 为 null。


读取会话

HTTP
1GET /v1/sessions/:id
JSON
1{
2 "id": "9f8c2c1e-5b8a-4d0e-9a51-2f6f0f1d7a10",
3 "workflow": "support_bot",
4 "inserted_at": "2026-10-25T08:58:41.007Z",
5 "last_activity_at": "2026-10-25T09:14:03.512Z",
6 "messages": [
7 {
8 "id": "4b1d…:user",
9 "role": "user",
10 "author": "user",
11 "author_name": null,
12 "content": "I was charged twice for order 1234",
13 "created_at": "2026-10-25T08:58:40.112Z"
14 },
15 {
16 "id": "4b1d…:assistant",
17 "role": "assistant",
18 "author": "ai",
19 "author_name": null,
20 "content": "Sorry about that. Let me connect you with our billing team.",
21 "created_at": "2026-10-25T08:58:41.007Z"
22 },
23 {
24 "id": "7e02…:assistant",
25 "role": "assistant",
26 "author": "agent",
27 "author_name": "Dana",
28 "content": "Hi, I'm Dana. I've refunded the duplicate charge.",
29 "created_at": "2026-10-25T09:14:03.498Z"
30 }
31 ],
32 "truncated": false
33}

消息按时间正序排列(最早的在前)。

字段说明
id稳定的消息 id,请将其视为不透明字符串。
roleuser 或 assistant
authoruser、ai(模型回复)或 agent(通过此 API 追加的人工回复)
author_name追加消息时传入的 author_name,否则为 null
created_at该轮次的保存时间
truncated当会话超过此处返回的最近 100 个轮次时为 true

只返回对话本身。系统提示词、注入的会话记忆以及 ModelRiver 内置的安全指令都不会返回,失败请求的回复也不会返回。轮次会按照你所在套餐的日志保留期限保存。


追加消息

在会话中保存一个轮次,不调用模型。不会产生费用,也不计入请求次数。

HTTP
1POST /v1/sessions/:id/messages
2Content-Type: application/json
3 
4{ "role": "assistant", "content": "Hi, I'm Dana. I've refunded the duplicate charge.", "author_name": "Dana" }
字段必填说明
role✅user 保存一条用户消息;assistant 保存一条人工客服的回复(author: "agent")
content✅非空文本,最多 100,000 个字符
author_name❌显示名称,最多 200 个字符

响应 201:

JSON
1{
2 "id": "7e02…:assistant",
3 "role": "assistant",
4 "author": "agent",
5 "author_name": "Dana",
6 "content": "Hi, I'm Dana. I've refunded the duplicate charge.",
7 "created_at": "2026-10-25T09:14:03.498Z"
8}

追加的轮次会成为会话记忆的一部分。下一次携带该 session_id 的 /v1/ai 请求会把这些用户消息和客服回复当作之前的对话,AI 可以从客服停下的地方继续。

缺少字段或字段无效时返回 400 和 error 信息。如果项目已停止保存请求正文,追加同样会返回 400,因为会话内容无法保存。


实时更新

无需轮询即可实时跟踪会话:新的轮次、你的应用发送的事件以及删除操作,都会通过与异步响应流式传输相同的 WebSocket 送达。

  1. 你的后端为该会话申请一个一次性令牌:

    HTTP
    1POST /v1/sessions/:id/subscribe
    JSON
    1{
    2 "session_id": "4b1d…",
    3 "ws_token": "Qm9i…",
    4 "websocket_url": "wss://api.modelriver.com/socket",
    5 "websocket_channel": "session:7c2e…:4b1d…",
    6 "expires_in": 300
    7}
  2. 你的前端使用 ws_token 加入 websocket_channel。客户端 SDK 会完成这一步,并在每次重新连接时向你的后端申请新令牌:

    TYPESCRIPT
    1import { subscribeToSession } from '@modelriver/client';
    2 
    3const subscription = subscribeToSession({
    4 // Your backend route that calls POST /v1/sessions/:id/subscribe
    5 getSubscription: () => fetch(`/api/chat/${chatId}/live`, { method: 'POST' }).then((r) => r.json()),
    6 onMessage: (message) => addToChat(message),
    7 onSignal: (signal) => { if (signal.name === 'agent.joined') showAgent(signal.data); },
    8 onDeleted: () => closeChat(),
    9});
    10 
    11// Later
    12subscription.close();

令牌只能使用一次,只对该会话有效,未使用时五分钟后过期。连接会在一小时后关闭,SDK 会用新令牌重新连接。由于该频道会传输对话内容,请只为有权查看该对话的用户申请令牌。

事件

事件载荷触发时机
message与“读取会话”中格式相同的一条消息,外加 session_id会话中的一次 /v1/ai 请求成功(先是用户消息,然后是回复),或有轮次被追加
signal{ "session_id", "name", "data", "sent_at" }你的后端发送了信号
deleted{ "session_id" }会话被删除

失败的请求和测试模式运行不会推送。消息 id 与 GET /v1/sessions/:id 返回的一致,因此客户端可以把实时消息合并到之前加载的历史中而不会重复。客户端断开期间发送的事件不会补发:重新连接后,请再次读取会话以补齐内容(SDK 的 onLive 回调会告诉你时机)。

发送信号

信号用于告知订阅者那些不属于对话轮次的事情,例如“客服已加入”“对话已关闭”或“对方正在输入”。信号只会发送给当前已连接的订阅者,且从不保存,因此不会出现在对话记录或会话记忆中。

HTTP
1POST /v1/sessions/:id/signals
2Content-Type: application/json
3 
4{ "name": "agent.joined", "data": { "name": "Dana" } }
字段必填说明
name✅1–64 个字符:小写字母、数字以及 _ . : -
data❌任意 JSON,最大 4 KB

响应 202:{ "status": "sent" }。


删除会话

HTTP
1DELETE /v1/sessions/:id
JSON
1{ "message": "success", "status": "deleted" }

删除会话会移除其 id 和记忆,并向其实时订阅者发送 deleted,效果与在控制台的日志 → 会话中删除相同。请求日志会保留以供审计。下一次 /v1/ai 请求不带 session_id 即可开始新的对话。在受保护的项目中,删除会返回 403 project_protected;请改由组织所有者或管理员在控制台中删除该会话。


后续步骤