For the complete documentation index, see llms.txt. This page is also available as Markdown.

群聊消息

用于通过 Live APIs 运行群聊房间的管理员客户端收发消息的参考,包括字段、错误和轮次结果。

这些消息只存在于一个使用以下方式创建的房间中 group_chat: true。它们通过该房间的 LiveKit 数据通道传输,并与文档中记录的消息一起传输于 客户端到服务器的消息 和 服务器到客户端的消息 页面上。只有房间中的人类参与者可以发送 group-address;本页称该参与者为 主持人。当使用以下方式创建时,一个房间可以容纳不止一名人类 max_num_participants ,超过其默认的 1;额外的人类按中所述加入 使用多角色会话。封装约定遵循 消息术语表,但有两个不同:群聊命令还携带一个顶层的 label 和 id,并且 turn-complete 到达时没有顶层的 label 字段开始的类型。

群聊房间仅对已启用该功能的账户可用。

你发送的命令

group-address

将房间定向给一个回合。只有主持人可以发送它,而且只能通过 LiveKit 数据通道发送。

{
  "label": "rtvi-ai",
  "type": "group-address",
  "id": "turn-0001",
  "data": {
    "room_session_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
    "mode": "all",
    "expected_route_epoch": 0,
    "text": "请每个角色用一句话介绍自己。"
  }
}
字段
输入
必填
描述

label

字符串

否

常规 RTVI 标签, "rtvi-ai"。服务器会忽略它;发送它只是为了与其他客户端消息保持一致。

id

字符串

是

命令 id,1–128 个字符。在该房间内你发送的每个命令中必须唯一; group-address, interaction-target,并且 character-roster-update 共享同一个 id 空间。

data.room_session_id

UUID

是

房间,来自 /connect 响应。

data.mode

字符串

是

定向模式: "all", "tagged",或者 "open"。请参见下方表格。

data.target_membership_ids

UUID[]

"tagged" 仅限

至少一个在线 membership_id,且不含重复。若为 "all" 和 "open" 则省略它——使用任一模式发送的列表都会被忽略,而该回合仍会定向到房间中的每个实例。

data.expected_route_epoch

整数

是

你持有的最新 route_epoch ,来自 /connect 或来自 extras.route_epoch 上一次 group-address, interaction-target,或者 character-roster-update 响应的结果。移除当前活动实例会提升该纪元。

data.text

字符串

是

主持人的消息。

定向模式

mode

被指向的人

必须回复

"all"

房间中的每个角色实例。

是。拒绝会被报告为失败。

"tagged"

仅限列在中的实例 target_membership_ids.

是。拒绝会被报告为失败。

"open"

房间中的每个角色实例。

否。实例可以拒绝,此时会被报告为已通过。

服务器响应额外字段

服务器对每个 group-address 都只返回一个 server-response 携带 event_type: "group-address"。对于它接受的命令,该响应会在所有被定向的实例完成后到达;被拒绝的命令会立即以 status: "error"进行回复。一个回合还会产生 server-response 你未发送的消息,其中带有 event_type "context-update" 或 "user_text_message",每个被定向实例可能各一条;忽略任何 server-response 其 event_type 不是你自己的命令之一的消息。对于 status: "success", extras 携带:

字段
输入
描述

command_id

字符串

该 id 从请求中回显。

room_session_id

UUID

该房间。

mode

字符串

本次回合使用的定向模式。

route_epoch

整数

房间当前的纪元。将此值作为 expected_route_epoch 发送到下一条命令中。

target_membership_ids

UUID[]

本次回合定向到的实例。

answered_membership_ids

UUID[]

产生回复的实例。

passed_membership_ids

UUID[]

拒绝的实例。只有一个 "open" 回合会在这里产生条目。

failed_membership_ids

UUID[]

未产生回复的实例。超时会在这里报告。

summary.turn_id

字符串

回合标识符,等于 command_id.

summary.addressed

整数

被定向的实例数量。

summary.answered

整数

回复的实例数量。

summary.passed

整数

拒绝的实例数量。

summary.failed

整数

未回复的实例数量。

summary.cancelled

布尔值

存在于每个摘要中。取消无法触达,因此该值始终为 false.

summary.route_epoch

整数

回合开始时捕获的路由纪元。

status: "success" 表示回合已结束,而不是表示有人回复了。即使回合中每个实例都失败或超时,仍会返回 成功。请阅读 failed_membership_ids 以了解发生了什么。

在 status: "error", extras 携带 代码。房间本身抛出的错误—— stale_route_epoch, invalid_target_membership, duplicate_target_membership, empty_target_set 在一个 "all" 或 "open" 回合中, turn_in_progress, turn_wait_timeout,并且 command_id_conflict ——也携带 command_id, room_session_id, active_membership_id,并且 route_epoch。在命令到达房间之前就被拒绝的错误—— not_roster_room, not_group_chat_room, unauthorized_sender, invalid_command, wrong_room, invalid_route_epoch, empty_message, empty_target_set 在一个 "tagged" 回合中,以及 coordinator_unavailable ——只携带 代码 ,因此要把它们和你尚未完成的命令关联,而不是和 extras.command_id。失败的 group-address-part 帧会以 代码 和 command_id回复。意外的服务器端故障会以 status: "error" 和一个 消息 但没有 extras,因此请读取 extras.code 带有可选访问并回退到 消息.

错误代码

代码

当

该怎么做

not_roster_room

该房间是使用以下方式创建的 character_id来表示移除,而不是 characters.

使用以下方式创建该房间 characters.

not_group_chat_room

该房间是在没有 group_chat: true.

新建一个带有 group_chat: true.

unauthorized_sender

发送者不是该房间中的人类参与者。

从人类参与者的连接发送该命令。

invalid_command

在一个 group-address, id 缺失或超过 128 个字符时, data 不是对象,或者 mode 不是这三个值之一;或者一个 group-address-part 帧格式错误。

修正消息并用新的 id.

wrong_room

data.room_session_id 不是该房间。

使用 room_session_id 来自 /connect.

invalid_route_epoch

expected_route_epoch 不是整数。

发送整数。

stale_route_epoch

expected_route_epoch 与房间的纪元不匹配。

从 extras.route_epoch 从此响应中移除并用新的 id.

empty_message

文本 为空。

发送文本。

empty_target_set

"tagged" 是在没有目标的情况下发送的,或者 "all" / "open" 发送到了一个没有在线实例的房间。

至少列出一个 membership_id,或者等待某个实例变为就绪。

invalid_target_membership

目标不是该房间中的在线 membership_id ,或者不是 UUID。

使用 membership_id 中的值, /connect, bot-ready,或者 roster 响应。

duplicate_target_membership

相同的 id 在 target_membership_ids.

移除重复项。

turn_in_progress

由于有一个回合正在运行,你的命令被立即拒绝。

等待该 turn 的 server-response,然后再重新发送。

turn_wait_timeout

你的命令等待了正在运行的回合,但该回合在回合超时加上一个很短的余量内仍未结束,默认大约两分钟。

重新发送。

command_id_conflict

该 id 被以不同内容重复使用。

使用新的 id.

coordinator_unavailable

该房间已不再可服务。

创建一个新房间。

幂等性

重新发送相同的 id 且内容相同会被静默接受,不会产生第二个响应。不要等待第二个响应;请依赖第一个响应。重新发送相同的 id 则会被拒绝,并返回 command_id_conflict.

一次只进行一个回合

一个房间一次只运行一个回合。在回合运行时发送第二个 group-address 会被以 turn_in_progress 拒绝,并且不会被缓存,因此请在该回合的之后重试 server-response. interaction-target 和 character-roster-update 在回合期间也会以相同代码被拒绝。


group-address-part

携带一个 group-address 的帧,而该帧太大,无法一次发送完。LiveKit 数据通道拒绝超过 15,360 字节的消息。

字段
输入
必填
描述

label

字符串

否

常规 RTVI 标签, "rtvi-ai"。服务器会忽略它。

id

字符串

是

该 group-address 正在发送中的命令 id,1–128 个字符。每一帧都相同。

data.command_id

字符串

否

当存在时,它必须等于 id.

data.index

整数

是

此帧的从零开始的位置,来自 0 设置为 count - 1.

data.count

整数

是

帧的总数, 1 设置为 64。每一帧都相同。

data.payload

字符串

是

完整 JSON 的一个 base64 切片。 group-address JSON。

分块规则

  • 先把完整的 JSON 消息进行一次 base64 编码,然后将该字符串拆分到各个帧中;每个 group-address payload 都是其中的一段。 服务器按

  • 顺序拼接这些切片,并只解码一次。 index 。

  • 只有最后一段可以携带 = 填充。服务器在解码前会先拼接切片,因此除结尾之外任何地方出现填充都会导致整个命令失败。可以在任意位置拆分编码字符串;服务器会原样重建它。切勿分别对每一帧单独进行 base64 编码,因为那会把填充放在中间并导致整个命令失败。

  • 单个命令的 base64 载荷总计最多 1 MiB,约合 768 KiB 的 group-address JSON。

  • 格式错误或超大帧会使该命令失败,错误为 event_type: "group-address", status: "error",并且 code: "invalid_command"。不过有两种失败是静默的:如果某帧的 id 缺失或超过 128 个字符,则该帧会被丢弃,因为没有可用于关联回复的内容;如果一个命令在首帧后的 1 分钟内仍未完成,则这条部分送达的命令会被放弃。在这两种情况下,回合都不会结束,因此请在客户端侧超时,并及时发送一个命令的所有帧。

  • 重新组装后的消息会被按完全相同的方式处理,就像一个 group-address 随该 id.


你接收的消息

turn-complete

结束一个群聊回合并报告其结果。 turn-complete 报告整个群聊回合; bot-turn-completed 是按角色区分的,并且在群聊房间中保持不变。

字段
输入
描述

room_session_id

UUID

该房间。

command_id

字符串

该 id 的 group-address 开启该回合的。

mode

字符串

本次回合使用的定向模式。

addressed_membership_ids

UUID[]

本次回合定向到的实例。命名为 target_membership_ids 在 server-response extras。

answered_membership_ids

UUID[]

产生回复的实例。

passed_membership_ids

UUID[]

拒绝的实例。只有一个 "open" 回合会在这里产生条目。

failed_membership_ids

UUID[]

未产生回复的实例。未在回合超时内完成的实例会列在这里。

turn_id

字符串

回合标识符,等于 command_id.

addressed

整数

被定向的实例数量。

answered

整数

回复的实例数量。

passed

整数

拒绝的实例数量。

failed

整数

未回复的实例数量。

cancelled

布尔值

出现在每个 turn-complete中。取消无法触达,因此该值始终为 false.

route_epoch

整数

回合开始时捕获的路由纪元。

此消息的四个属性会影响客户端如何消费它:

  • turn-complete 没有顶层的 label,不同于大多数服务器消息。不要根据 label.

  • turn-complete 对传入消息进行过滤;每个回合最多发送一次,不论房间中有多少个角色实例。它通过某个实例的连接发布,且不会重试,因此请把 server-response 视为回合可靠结束。其 data 还可能携带发布该消息的实例的身份字段;忽略它们并读取列表。

  • turn-complete 可能会在实例最后一个 bot-llm-text delta 之前以及在 server-response之前到达。之后继续接受一小段宽限期内的回复文本——实际上 1 到 2 秒就足够。

  • route_epoch 这里指的是回合的快照,而不是下一次要发送的值。发送 extras.route_epoch 来自 server-response 作为下一个 expected_route_epoch.


按角色消息上的身份字段

在使用以下方式创建的房间中的服务器消息 characters 数组(每个群聊房间都是如此)携带六个身份字段,用来将它们与某个角色实例关联: room_session_id, membership_id, character_id, character_session_id, participant_identity,并且 is_initial。这些字段的位置取决于消息的形状。已经携带 data 对象的消息会在该对象内部接收它们。扁平消息会在为它们创建的 data 对象中接收它们,从而产生一个嵌套的 data.data 路径。

消息
身份字段的位置

bot-llm-text

data

bot-llm-started

data

bot-llm-stopped

data

bot-ready

data.about,映射在 data

character-status

data

character-removed

data

llm-no-response

嵌套的 data 对象

interaction-created

嵌套的 data 对象

server-response

嵌套的 data 对象;有用的字段保留在 extras

每个实例都会将其回复作为普通 bot-llm-text 消息流式发送。按 data.membership_id. bot-llm-stopped 来标识该回复。

不要也消费 bot-transcription;它重复了相同的回复文本。

一个拒绝 "open" 回合会用 llm-no-response 和 reason: "abstain"来宣布它。由于该消息是扁平的,其身份字段位于一个嵌套的 data 对象下:

turn-complete 才是权威,而不是这条消息。如果实例在拒绝之前流式发送了任何可见文本,那么以回复为准,该实例会列在 answered_membership_ids中。实例也可能列在 passed_membership_ids 中而从未发送过 llm-no-response中。将 llm-no-response 视为提示,并根据 turn-complete 列表来确定结果。


群聊房间中的 bot-ready

bot-ready 是中所描述的消息 映射每个角色实例。在群聊房间中,它的 data.about 对象通常除了那里记录的字段外还会携带一个字段: :即要显示给该实例的名称。该字段尽力提供;若不存在,则回退到该 membership 的,用于显示该实例的名称。该字段只是尽力而为。若它缺失,则回退到该实例的 :即要显示给该实例的名称。该字段尽力提供;若不存在,则回退到该 membership 的 上的 /connect roster 条目,该条目携带的是角色的纯名称,不含下一步所述的房间唯一后缀,因此请自行消歧回退值。

显示名称在房间内会被设为唯一:名为 Ada 的第二个实例会被赋予显示名称 Ada (2)。一个 character-status 消息带有 status: "ready" 在其 data 对象中以平面形式携带相同字段。

相关页面

构建群聊使用多角色会话客户端到服务器消息服务器到客户端消息

最后更新于

这有帮助吗?