Files
story/docs/elder-agent-flow.md
T
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

80 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 老人专属智能体与设备聊天接口
服务地址:`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 表示当前火山账户的平台智能体,不表示跨账户公开共享;业务层依然是一位老人一个智能体。