Files
story/docs/elder-agent-flow.md
T

80 lines
5.1 KiB
Markdown
Raw Normal View History

# 老人专属智能体与设备聊天接口
服务地址:`https://82.157.201.114`。2026-09-15 起,新设备不需要平台开机登记或 SDK 初始化回执。
## 1. 创建老人及智能体
`POST /api/v1/households/{household_id}/subjects`
```json
{"preferred_name":"张奶奶","language":"zh-CN","timezone":"Asia/Shanghai","profile_data":{},"conversation_preferences":{}}
```
后端保存老人,调用火山 `AibotCreate`,使用服务器现有豆包 S2S 模板(Provider=volcano,OutputMode=0);再调用 `AibotBind` 把新智能体关联到现有硬件产品,否则设备会被火山返回 `LimitExceeded.DeviceRtcBotNotFound`。每位老人一个 bot_id,存入自己的 PostgreSQL `subject_voice_agent`,不保存在小程序缓存里。智能体模型配置及 S2S 应用信息不再随开聊接口发给设备。
返回的 `data` 包含原老人字段,以及:
```json
{"id":"老人UUID","voice_agent":{"bot_id":"bot...","status":"READY"}}
```
火山失败时老人仍保存成功,`voice_agent.status=FAILED` 并给出提示;在原老人上重试,不要再创建一个老人:
`POST /api/v1/subjects/{subject_id}/voice-agent`,不需要请求体。成功返回 `data:{bot_id,status:"READY"}`。查询老人、老人列表也返回智能体状态。
## 2. 绑定设备
沿用现有 BLE 配网和绑定接口。关系为 `设备 → 当前绑定的老人 → 老人的 bot_id`。换绑会自动使用新老人的智能体;解绑不删除老人、智能体或历史聊天。设备供应商注册凭据沿用,不需要为每个智能体重新注册硬件。
## 3. 设备开始聊天
`POST /api/v1/device/chat/start`
```json
{"device_id":"KP01-B43A451634A8","session_id":"本次聊天UUID"}
```
`session_id` 由设备为每次聊天生成;同一聊天重试使用相同值。不需要 boot_id、register、voice-runtime、activation-acks;保存绑定响应的 5 个火山字段后,在本地初始化 SDK 即可请求聊天。设备 HTTP 签名保留。旧固件携带合法 boot_id 仍兼容,但不再与开机登记比对。
成功返回:
```json
{"ok":true,"code":"OK","data":{"session_id":"本次聊天UUID","bot_id":"该老人的bot_id","params":{"PlatformTaskID":"本次聊天UUID","AgentConfig":{"WelcomeMessage":"你好,今天想聊些什么?","EnableConversationStateCallback":false,"ServerMessageURLForRTS":"https://121.41.46.238/callbacks/v1/volcengine/chat?session_id=本次聊天UUID","ServerMessageSignatureForRTS":"沿用已有回调字段"}},"lease_expires_at_ms":1790000000000,"expires_at_ms":1790003600000}}
```
设备把 `bot_id`、`params` 交给现有火山 SDK;SDK 直接连火山拿 RTC 房间并收发音频。无需再传 S2SConfig。后端在每次新聊天开始时,通过 AibotUpdate 给这个已有智能体设置本次回调地址及当前可用记忆;不是重新创建智能体。`AgentConfig` 也携带相同回调地址,让聊天记录准确找到本次 session_id。原固件每 10 秒重复 start 续期逻辑保留,续期不重复更新火山。同一老人同一时间只允许一通聊天。
未绑定:HTTP 409,`code=DEVICE_UNBOUND`,`message=绑定错误:设备没有绑定人员`。智能体未就绪:HTTP 409,`code=VOICE_AGENT_NOT_READY`。供应商 SDK 尚未注册完成:`DEVICE_NOT_READY`。
## 4. 火山回调聊天记录
`POST /callbacks/v1/volcengine/chat?session_id={session_id}`
由火山直接请求服务器,不经过设备或小程序:
```json
{"message":"火山字幕包的Base64","signature":"本次配置中的ServerMessageSignatureForRTS"}
```
`message` 解码后是原生 subtitle 数据(或带 subv 帧头的同一数据):
```json
{"type":"subtitle","data":[{"userId":"input","roundId":1,"sequence":1,"text":"今天心情不错","definite":true,"paragraph":true}]}
```
保存最终字幕到 `call_utterance`,按 session_id 关联本次老人、设备,重复回调去重,挂断后迟到的回调仍归原会话。成功返回 HTTP 200、文本 `ok`。这里配置的是 `AgentConfig.ServerMessageURLForRTS`,不是 Function calling 接收消息 URL。
## 5. 设备结束聊天
`POST /api/v1/device/chat/end`
```json
{"device_id":"KP01-B43A451634A8","session_id":"本次聊天UUID","reason":"hangup","sdk_stopped":true}
```
返回 `data:{session_id,ended:true}`。失败可重复发送;即使之后设备解绑,旧会话的结束通知仍可提交。其他 reason:`start_failed`、`disconnected`、`reboot`、`timeout`。
本次只改变智能体和聊天通路,不新增安全验证步骤。火山原生 MemoryConfig 暂不启用;现有记录存储、后台整理和已授权平台记忆继续使用。记忆改由后端直接配置到智能体,不经设备转发。
火山管理 API:`POST https://rtc.volcengineapi.com?Action=AibotCreate&Version=2025-08-01`。查询/重试使用同版本 AibotQuery、AibotUpdate、AibotBind。绑定产品的请求体为 `{"Id":"bot...","Binding":{"InstanceId":"现有实例ID","ProductKey":"现有产品Key"}}`。AccessType=public 表示当前火山账户的平台智能体,不表示跨账户公开共享;业务层依然是一位老人一个智能体。