Files
story/docs/device-registration-to-chat-api.md
Codex Local 0c2151ace9
ci / verify (push) Canceled after 0s
chore: checkpoint 第一版
2026-09-06 17:04:11 +08:00

29 KiB
Raw Permalink Blame History

设备注册到聊天记录上传接口文档

1. 设备请求平台时的请求头

运营后台和用户 App 调用 /api/v1/* 时使用:

Authorization: Bearer <用户访问令牌>

设备调用 /device/* 时使用以下 HMAC 请求头:

请求头 中文含义 计算方式
X-Device-Id 平台设备编号 平台登记设备时返回的 credential.device_id
X-Device-Timestamp 请求时间 当前 UTC 时间,RFC3339 格式,例如 2026-09-05T09:20:00Z
X-Device-Nonce 防重放随机数 每个请求重新生成,长度 16–128 字符,不得重复
X-Device-Content-SHA256 请求正文摘要 hex_lower(SHA256(rawBody));GET 使用空字节正文
X-Device-Signature 请求签名 base64url_no_padding(HMAC-SHA256(platformDeviceSecret, canonical))
Idempotency-Key 业务幂等键 仅指定接口需要;同一次请求重试必须保持不变,长度 16–128 字符
Content-Type 正文类型 有 JSON 正文时为 application/json

签名原文 canonical:

{大写HTTP方法}\n{请求路径和查询参数}\n{X-Device-Timestamp}\n{X-Device-Nonce}\n{X-Device-Content-SHA256}

计算示例:

body = UTF8('{"hardware_id":"echoear-a1b2c3"}')
bodySha256 = hex_lower(SHA256(body))
timestamp = "2026-09-05T09:20:00Z"
nonce = "d8b81b916ddd4f4584a80a82"

canonical =
"POST\n" +
"/device/v3/hardware-agent-credentials:provision\n" +
timestamp + "\n" +
nonce + "\n" +
bodySha256

signature = base64url_no_padding(
  HMAC-SHA256(platformDeviceSecret, UTF8(canonical))
)

注意:

  • 摘要必须针对实际发送的原始字节计算,签名后不能再次格式化 JSON。
  • 查询参数属于签名内容,例如 /device/v2/commands?limit=10。
  • GET 空正文 SHA-256 固定为 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855。
  • platformDeviceSecret 是平台注册时返回的设备密钥,不是火山 Product Secret,也不是火山 device_secret。
  • 平台统一响应:成功为 {"request_id":"...","data":...};失败为 {"request_id":"...","error":...}。

2. 完整流程

顺序 调用方 动作 接口/地址 结果
1 运营平台 登记设备 POST /api/v1/ops/devices 返回平台设备 ID、平台设备密钥和绑定码
2 用户 App 绑定设备 POST /api/v1/device-claims 状态变为 BOUND
3 设备 获取火山运行凭据 POST /device/v3/hardware-agent-credentials:provision 平台动态注册火山设备,消耗一个 License,状态变为 ACTIVE
4 设备 检查固件 GET /device/v2/bootstrap 得到 firmware_compatible
5 设备 获取设备配置 GET /device/v2/config 得到配置版本和运行时配置
6 设备 判断是否继续 firmware_compatible=false 时停止聊天并进入 OTA 流程 只有兼容固件可以继续
7 设备 创建对话会话 POST /device/v3/agent-sessions 获取 Bot ID、系统提示词、人设和授权记忆
8 设备 连接火山 火山 WebSocket + session.update 注入本次人设并建立 16 kHz PCM 对话
9 设备 上报会话开始 POST /device/v3/agent-sessions/{id}/events 平台会话变为 ACTIVE
10 设备 上传最终聊天文本 POST /device/v3/agent-sessions/{id}/turns:batch 用户和智能体最终文本入库
11 设备 上报会话结束 同一个 events 接口,session_ended 平台会话变为 COMPLETED

激活状态:

FACTORY → CLAIMABLE → BOUND → PROVISIONING → ACTIVE → LOST/REVOKED

设备重置流程:

停止语音 → 上传剩余聊天记录 → 上报session_ended → POST /device/v3/factory-reset
→ 平台解除绑定并暂停火山凭据 → 设备按local_actions清理 → 重启进入CLAIMABLE

3. 接口

3.1 登记设备

地址:

POST /api/v1/ops/devices

输入:

字段 类型 必填 中文含义
model string 是 设备型号
hardware_revision string 否 硬件版本
minimum_security_version string 否 最低安全版本
minimum_firmware_version string 否 最低固件版本
household_id UUID 否 直接绑定的家庭编号;走绑定码时不传
subject_id UUID 否 直接绑定的服务对象编号;走绑定码时不传
voice_runtime enum 是 传 volc_hardware_agent
hardware_agent_bot_id string 否 兼容字段;当前方案不传,由平台产品配置决定
hardware_agent_transport enum 否 low_load 或 high_quality;建议由平台配置
hardware_agent_minimum_sdk_version string 否 最低硬件智能体 SDK 版本
activation_state enum 是 FACTORY、CLAIMABLE 或 BOUND;一般传 CLAIMABLE

输出:

字段 类型 中文含义
device.id UUID 平台设备编号
device.status string 设备业务状态
device.activation_state enum 激活状态
device.activation_revision integer 激活状态版本
device.model string 设备型号
device.hardware_revision string/null 硬件版本
device.minimum_security_version string/null 最低安全版本
device.minimum_firmware_version string/null 最低固件版本
device.voice_runtime enum 语音运行时
device.version integer 设备记录版本
credential.device_id UUID 平台设备编号
credential.secret string 设备调用平台所用的 HMAC 密钥,仅明文返回一次
credential.key_version integer 平台设备密钥版本
credential.issued_at datetime 密钥签发时间
claim.claim_code string/null 一次性绑定码
claim.issued_at datetime/null 绑定码签发时间
claim.expires_at datetime/null 绑定码过期时间

示例:

POST /api/v1/ops/devices
Authorization: Bearer <ops-token>
Content-Type: application/json

{
  "model": "echoear-esp32s3",
  "hardware_revision": "v1.0",
  "minimum_firmware_version": "1.0.0",
  "voice_runtime": "volc_hardware_agent",
  "activation_state": "CLAIMABLE"
}
{
  "request_id": "req-register-001",
  "data": {
    "device": {
      "id": "10000000-0000-0000-0000-000000000512",
      "status": "registered",
      "activation_state": "CLAIMABLE",
      "activation_revision": 1,
      "model": "echoear-esp32s3",
      "voice_runtime": "volc_hardware_agent",
      "version": 1
    },
    "credential": {
      "device_id": "10000000-0000-0000-0000-000000000512",
      "secret": "<platform-device-secret>",
      "key_version": 1,
      "issued_at": "2026-09-05T09:00:00Z"
    },
    "claim": {
      "claim_code": "ABCD-EFGH-IJKL-MNOP",
      "issued_at": "2026-09-05T09:00:00Z",
      "expires_at": "2026-09-06T09:00:00Z"
    }
  }
}

3.2 用户绑定设备

地址:

POST /api/v1/device-claims

输入:

字段 类型 必填 中文含义
claim_code string 是 一次性绑定码,不能填写设备 UUID
household_id UUID 是 家庭编号
subject_id UUID 是 设备服务对象编号

输出:

字段 类型 中文含义
binding_id UUID 设备绑定关系编号
device_id UUID 平台设备编号
household_id UUID 家庭编号
subject_id UUID 服务对象编号
bound_at datetime 绑定时间

示例:

POST /api/v1/device-claims
Authorization: Bearer <user-token>
Content-Type: application/json

{
  "claim_code": "ABCD-EFGH-IJKL-MNOP",
  "household_id": "10000000-0000-0000-0000-000000000211",
  "subject_id": "10000000-0000-0000-0000-000000000411"
}
{
  "request_id": "req-bind-001",
  "data": {
    "binding_id": "10000000-0000-0000-0000-000000000611",
    "device_id": "10000000-0000-0000-0000-000000000512",
    "household_id": "10000000-0000-0000-0000-000000000211",
    "subject_id": "10000000-0000-0000-0000-000000000411",
    "bound_at": "2026-09-05T09:10:00Z"
  }
}

3.3 占用 License 并获取火山设备凭据

地址:

POST /device/v3/hardware-agent-credentials:provision

输入:

字段 位置 类型 必填 中文含义
Idempotency-Key Header string 是 凭据申请幂等键,16–128 字符
hardware_id Body string 是 不随固件升级变化的物理硬件标识

输出:

字段 类型 中文含义
instance_id string 火山硬件智能体实例编号
product_key string 火山产品标识
device_name string 火山设备名称
hardware_id string 已绑定的物理硬件标识
device_secret string 火山设备专属密钥,需要加密保存
credential_ref string 平台内部凭据引用
credential_version integer 火山设备凭据版本
credential_source enum platform_dynamic_registration 为新注册,platform_stored 为复用已有凭据
issued_at datetime 凭据签发时间

示例:

POST /device/v3/hardware-agent-credentials:provision
Idempotency-Key: provision-device-00000512-v1
Content-Type: application/json
<设备HMAC请求头>

{"hardware_id":"echoear-esp32s3-a1b2c3d4"}
{
  "request_id": "req-provision-001",
  "data": {
    "instance_id": "6a92945cc0c4689234aef656",
    "product_key": "6a9568047dd4b23eacab9b1a",
    "device_name": "dt-10000000000000000000000000000512",
    "hardware_id": "echoear-esp32s3-a1b2c3d4",
    "device_secret": "<volc-device-secret>",
    "credential_ref": "volc-device-secret://10000000-0000-0000-0000-000000000512",
    "credential_version": 1,
    "credential_source": "platform_dynamic_registration",
    "issued_at": "2026-09-05T09:12:00Z"
  }
}

3.4 设备恢复出厂

地址:

POST /device/v3/factory-reset

输入:

字段 类型 必填 中文含义
Header Idempotency-Key string 是 本次重置幂等键,16–128 字符;重试保持不变
reset_id UUID 是 本次重置唯一编号
reset_counter integer 是 设备安全存储中的单调递增重置次数
occurred_at datetime 是 设备确认重置的 UTC 时间;不得晚于请求时间 5 分钟
trigger enum 是 physical_long_press、device_menu 或 service_tool
firmware_version string 是 当前固件版本
pending_turn_count integer 是 未上传聊天记录数;必须为 0
active_conversation_id UUID 否 设备认为仍在运行的会话编号

输出:

字段 类型 中文含义
reset_id UUID 重置编号
device_id UUID 平台设备编号
activation_state enum 重置后固定为 CLAIMABLE
reset_counter integer 平台接受的重置次数
binding_removed boolean 是否关闭了原用户绑定
previous_binding_id UUID/null 原绑定关系编号
provider_credential_status enum 火山设备凭据状态,通常为 SUSPENDED
license_action enum 固定为 RETAINED,重置不释放火山 License
ended_conversation_count integer 平台强制结束的残留会话数
cancelled_command_count integer 平台取消的待执行命令数
config_revision integer 重置后的设备配置版本
claim.code string 新的一次性绑定码
claim.issued_at datetime 绑定码签发时间
claim.expires_at datetime 绑定码过期时间
local_actions string[] 设备收到成功响应后必须执行的本地清理动作
reset_at datetime 平台完成重置的时间

平台同时把旧用户侧的设备状态置为离线,并推送 device.binding.reset 事件。设备收到成功响应后,按 local_actions 清理本地火山凭据、用户上下文、会话与网络配置;设备平台身份和 HMAC 密钥不得删除。

示例:

POST /device/v3/factory-reset
Idempotency-Key: factory-reset-00000512-0001
Content-Type: application/json
<设备HMAC请求头>

{
  "reset_id": "10000000-0000-0000-0000-000000000901",
  "reset_counter": 1,
  "occurred_at": "2026-09-05T09:30:00Z",
  "trigger": "physical_long_press",
  "firmware_version": "1.1.0",
  "pending_turn_count": 0
}
{
  "request_id": "req-reset-001",
  "data": {
    "reset_id": "10000000-0000-0000-0000-000000000901",
    "device_id": "10000000-0000-0000-0000-000000000512",
    "activation_state": "CLAIMABLE",
    "reset_counter": 1,
    "binding_removed": true,
    "previous_binding_id": "10000000-0000-0000-0000-000000000611",
    "provider_credential_status": "SUSPENDED",
    "license_action": "RETAINED",
    "ended_conversation_count": 0,
    "cancelled_command_count": 0,
    "config_revision": 9,
    "claim": {
      "code": "QRST-UVWX-YZ23-4567",
      "issued_at": "2026-09-05T09:30:01Z",
      "expires_at": "2026-09-06T09:30:01Z"
    },
    "local_actions": [
      "clear_volc_credential",
      "clear_user_context",
      "clear_session_state",
      "clear_network_credentials",
      "reboot_to_claimable"
    ],
    "reset_at": "2026-09-05T09:30:01Z"
  }
}

设备必须保留平台 device_id、平台 HMAC secret 和 hardware_id;其余用户上下文、火山凭据、会话状态和网络配置按 local_actions 清除。

3.5 检查固件版本

地址:

GET /device/v2/bootstrap

输入:

字段 位置 类型 必填 中文含义
firmware_version Query string 是 当前固件版本
device_time Query datetime 是 设备 UTC 时间,RFC3339
board_rev Query string 否 硬件版本
rtc_sdk_version Query string 否 火山 SDK 版本
codec Query string 否 音频格式,例如 pcm16
sample_rate Query integer 否 音频采样率,当前为 16000
network Query string 否 网络类型,例如 wifi

输出:

字段 类型 中文含义
server_time datetime 平台 UTC 时间
clock_skew_ms integer 平台时间减设备时间的毫秒差
device.device_id UUID 平台设备编号
device.status string 设备业务状态
device.model string 设备型号
device.hardware_revision string/null 硬件版本
device.minimum_security_version string/null 最低安全版本
device.minimum_firmware_version string/null 最低固件版本
device.firmware_compatible boolean 当前固件是否允许继续聊天
device.config_revision integer 当前平台配置版本
device.binding.bound boolean 是否已绑定
device.binding.household_id UUID/null 家庭编号
device.binding.subject_id UUID/null 服务对象编号
device.binding.subject_name string/null 服务对象名称

示例:

GET /device/v2/bootstrap?firmware_version=1.0.0&board_rev=v1.0&rtc_sdk_version=1.1.0&codec=pcm16&sample_rate=16000&network=wifi&device_time=2026-09-05T09%3A15%3A00Z
<设备HMAC请求头>
{
  "request_id": "req-bootstrap-001",
  "data": {
    "server_time": "2026-09-05T09:15:01Z",
    "clock_skew_ms": 1000,
    "device": {
      "device_id": "10000000-0000-0000-0000-000000000512",
      "status": "registered",
      "model": "echoear-esp32s3",
      "minimum_firmware_version": "1.0.0",
      "firmware_compatible": true,
      "config_revision": 8,
      "binding": {
        "bound": true,
        "household_id": "10000000-0000-0000-0000-000000000211",
        "subject_id": "10000000-0000-0000-0000-000000000411",
        "subject_name": "测试用户"
      }
    }
  }
}

3.6 获取设备配置

地址:

GET /device/v2/config

输入:

字段 位置 类型 必填 中文含义
If-None-Match Header string 否 本地配置 ETag;未变化时返回 304

输出:

字段 类型 中文含义
Response Header ETag string 当前配置 ETag
device_id UUID 平台设备编号
revision integer 配置版本
desired_config object 平台期望设备应用的配置
desired_config.voice_runtime enum 语音运行时
desired_config.hardware_agent_transport enum 火山传输方式
desired_config.minimum_sdk_version string 最低 SDK 版本
reported_revision integer/null 设备此前报告的配置版本
binding object 当前绑定信息,字段与 bootstrap 相同

示例:

GET /device/v2/config
If-None-Match: "7"
<设备HMAC请求头>
{
  "request_id": "req-config-001",
  "data": {
    "device_id": "10000000-0000-0000-0000-000000000512",
    "revision": 8,
    "desired_config": {
      "voice_runtime": "volc_hardware_agent",
      "hardware_agent_transport": "low_load",
      "minimum_sdk_version": "1.1.0"
    },
    "reported_revision": 7,
    "binding": {
      "bound": true,
      "household_id": "10000000-0000-0000-0000-000000000211",
      "subject_id": "10000000-0000-0000-0000-000000000411"
    }
  }
}

3.7 创建会话并获取系统提示词

地址:

POST /device/v3/agent-sessions

输入:

字段 类型 必填 中文含义
Header Idempotency-Key string 是 创建会话幂等键,16–128 字符
device_time datetime 是 设备 UTC 时间
monotonic_ms integer 否 开机后的单调时钟毫秒数
capabilities.hardware_agent boolean 是 必须为 true
capabilities.sdk_version string 是 硬件智能体 SDK 版本
capabilities.transports string[] 是 支持的传输方式
capabilities.input_audio_format string 是 上行音频能力,当前为 pcm_s16le_16000_mono
capabilities.output_audio_format string 是 下行音频能力,当前为 pcm_s16le_16000_mono
capabilities.server_event_callback boolean 是 当前传 false
capabilities.transcript_upload boolean 是 必须为 true
capabilities.dynamic_session_config boolean 是 必须为 true
capabilities.credential_rotation boolean 是 必须为 true
capabilities.near_pcm_recording boolean 是 是否支持近端录音
capabilities.far_pcm_recording boolean 是 是否支持远端录音
network.type string 是 网络类型
network.rssi integer 否 Wi-Fi RSSI
requested_goal string 是 固定为 open_conversation
config_revision integer 是 /device/v2/config 返回的配置版本

输出:

字段 类型 中文含义
conversation_id UUID 平台会话编号
status string 正常为 SESSION_READY
runtime_type string volc_hardware_agent
runtime.provider string 服务商,当前为 volcengine
runtime.bot_id string 本次使用的 Bot ID
runtime.transport string 本次传输方式
runtime.provider_session_ref string 火山会话引用
runtime.session_nonce string 会话证明随机值
runtime.config_digest string 本次动态配置摘要
runtime.wait_for_session_update boolean 是否必须先应用动态人设
session_config.dialog_id string 本次对话标识
session_config.system_prompt string 系统提示词/核心人设
session_config.persona_tone string 人设语气和表达风格
session_config.authorized_context string 授权的用户背景、近期摘要和长期记忆
session_config.prompt_bundle_version string 提示词版本
session_config.tool_url URL/null 工具调用地址
session_config.tool_scope_token string/null 本次会话工具令牌
privacy.retention_mode string 数据保留模式
privacy.record_near boolean 是否允许近端录音
privacy.record_far boolean 是否允许远端录音
privacy.upload_allowed boolean 是否允许上传聊天记录
session.engine_mode string 会话引擎模式
session.heartbeat_interval_sec integer 会话状态上报间隔
session.allocation_expires_at datetime 会话分配过期时间

示例:

POST /device/v3/agent-sessions
Idempotency-Key: session-device-00000512-0001
Content-Type: application/json
<设备HMAC请求头>

{
  "device_time": "2026-09-05T09:20:00Z",
  "monotonic_ms": 812345,
  "capabilities": {
    "hardware_agent": true,
    "sdk_version": "1.1.0-echoear",
    "transports": ["low_load"],
    "input_audio_format": "pcm_s16le_16000_mono",
    "output_audio_format": "pcm_s16le_16000_mono",
    "server_event_callback": false,
    "transcript_upload": true,
    "dynamic_session_config": true,
    "credential_rotation": true,
    "near_pcm_recording": false,
    "far_pcm_recording": false
  },
  "network": {"type":"wifi","rssi":-52},
  "requested_goal": "open_conversation",
  "config_revision": 8
}
{
  "request_id": "req-session-001",
  "data": {
    "conversation_id": "10000000-0000-0000-0000-000000000801",
    "status": "SESSION_READY",
    "runtime_type": "volc_hardware_agent",
    "runtime": {
      "provider": "volcengine",
      "bot_id": "botM4gWQ9A9y",
      "transport": "low_load",
      "provider_session_ref": "provider-session-ref",
      "session_nonce": "<session-nonce>",
      "config_digest": "<config-digest>",
      "wait_for_session_update": true
    },
    "session_config": {
      "dialog_id": "dialog-00000801",
      "system_prompt": "你是面向长者的陪伴助手……",
      "persona_tone": "率真、自然",
      "authorized_context": "经授权的背景和记忆……",
      "prompt_bundle_version": "persona-v12"
    },
    "privacy": {
      "retention_mode": "transcript_only",
      "record_near": false,
      "record_far": false,
      "upload_allowed": true
    },
    "session": {
      "engine_mode": "hardware_agent",
      "heartbeat_interval_sec": 30,
      "allocation_expires_at": "2026-09-05T09:25:00Z"
    }
  }
}

3.8 连接火山并注入人设

地址:

wss://ai-gateway.vei.volces.com/v1/realtime?bot={bot_id}&wait_for_session_update=true

输入:

字段 位置 中文含义 来源/计算
bot Query Bot ID 创建会话返回的 runtime.bot_id
X-Auth-Type Header 鉴权类型 固定为 1
X-Product-Key Header 火山产品标识 provision 返回的 product_key
X-Device-Name Header 火山设备名称 provision 返回的 device_name
X-Random-Num Header 随机数 每次连接重新生成
X-Timestamp Header Unix 秒 当前时间
X-Instance-Id Header 火山实例编号 provision 返回的 instance_id
X-Hardware-Id Header 物理硬件标识 provision 使用的 hardware_id
X-Signature Header 火山鉴权签名 base64(HMAC-SHA256(device_secret, canonical))
session.update WebSocket JSON 动态会话配置 注入平台返回的人设和记忆

输出:

事件 中文含义
session.created / session.updated 火山会话创建/动态人设生效
conversation.item.input_audio_transcription.completed 用户最终识别文本
response.audio_transcript.done 智能体最终回复文本
音频数据 智能体返回的 PCM16 音频,按 16 kHz 单声道播放
error 事件 火山连接或会话失败

示例:

canonical = "auth_type=1&device_name={device_name}&random_num={random_num}&product_key={product_key}&timestamp={timestamp}&instance_id={instance_id}"
X-Signature = base64(HMAC-SHA256(device_secret, canonical))
{
  "event_id": "evt-session-update-001",
  "type": "session.update",
  "session": {
    "object": "realtime.session",
    "model": "",
    "input_audio_format": "pcm16",
    "output_audio_format": "pcm16",
    "config": {
      "ASRConfig": {"TurnDetectionMode": 0},
      "LLMConfig": {
        "SystemMessages": [
          "<system_prompt>\n表达风格:<persona_tone>\n授权上下文:<authorized_context>\n会话标识:<dialog_id>"
        ]
      }
    },
    "agent_config": {"EnableConversationStateCallback": false}
  }
}

3.9 上报会话事件

地址:

POST /device/v3/agent-sessions/{conversation_id}/events

输入:

字段 类型 必填 中文含义
Path conversation_id UUID 是 平台会话编号
event_id string 是 事件唯一编号
sequence_no integer 是 事件顺序号,从 1 开始递增
event_type enum 是 session_started、session_updated、session_ended 或 session_failed
occurred_at datetime 是 事件发生时间
provider_session_ref string 是 火山会话引用
session_nonce string 是 会话证明随机值
provider_connection_ref string 启动时必填 WebSocket 连接标识
bot_id string 启动时必填 实际连接的 Bot ID
transport string 启动时必填 实际传输方式
config_digest string 启动时必填 已应用的人设配置摘要
dynamic_config_applied boolean 启动时必填 必须为 true
error_code string 失败时填写 失败错误码

输出:

字段 类型 中文含义
conversation_id UUID 平台会话编号
status string 会话状态,开始后为 ACTIVE,正常结束后为 COMPLETED
action enum continue 或 stop_session
duplicate boolean 是否为重复事件
accepted_at datetime 平台接收时间

示例:

开始请求:

{
  "event_id": "device-event-start-001",
  "sequence_no": 1,
  "event_type": "session_started",
  "occurred_at": "2026-09-05T09:20:03Z",
  "provider_session_ref": "provider-session-ref",
  "session_nonce": "<session-nonce>",
  "provider_connection_ref": "ws-connection-001",
  "bot_id": "botM4gWQ9A9y",
  "transport": "low_load",
  "config_digest": "<config-digest>",
  "dynamic_config_applied": true
}

结束示例:

{
  "event_id": "device-event-end-001",
  "sequence_no": 2,
  "event_type": "session_ended",
  "occurred_at": "2026-09-05T09:25:00Z",
  "provider_session_ref": "provider-session-ref",
  "session_nonce": "<session-nonce>"
}

响应示例:

{
  "request_id": "req-event-001",
  "data": {
    "conversation_id": "10000000-0000-0000-0000-000000000801",
    "status": "ACTIVE",
    "action": "continue",
    "duplicate": false,
    "accepted_at": "2026-09-05T09:20:03Z"
  }
}

3.10 上传聊天记录

地址:

POST /device/v3/agent-sessions/{conversation_id}/turns:batch

输入:

字段 类型 必填 中文含义
Path conversation_id UUID 是 平台会话编号
Header Idempotency-Key string 是 本批记录幂等键,16–128 字符
turns array 是 最终聊天记录数组,每批 1–500 条
turns[].turn_key string 是 会话内唯一的轮次标识,最长 255 字符
turns[].sequence_no integer 是 对话顺序号,会话内唯一且大于 0
turns[].speaker enum 是 用户为 subject,智能体为 agent
turns[].start_at datetime 是 本轮开始时间
turns[].end_at datetime 是 本轮结束时间,不早于开始时间
turns[].final_text string 是 最终文本,最长 20000 字符
turns[].interrupted boolean 是 本轮是否被打断

输出:

字段 类型 中文含义
conversation_id UUID 平台会话编号
accepted_count integer 本次新写入的记录数
duplicate_count integer 本次幂等重复的记录数

示例:

POST /device/v3/agent-sessions/10000000-0000-0000-0000-000000000801/turns:batch
Idempotency-Key: turns-conversation-00000801-0001
Content-Type: application/json
<设备HMAC请求头>

{
  "turns": [
    {
      "turn_key": "user-final-001",
      "sequence_no": 1,
      "speaker": "subject",
      "start_at": "2026-09-05T09:20:10Z",
      "end_at": "2026-09-05T09:20:12Z",
      "final_text": "今天天气怎么样?",
      "interrupted": false
    },
    {
      "turn_key": "agent-final-001",
      "sequence_no": 2,
      "speaker": "agent",
      "start_at": "2026-09-05T09:20:12Z",
      "end_at": "2026-09-05T09:20:16Z",
      "final_text": "我来帮你看看。",
      "interrupted": false
    }
  ]
}
{
  "request_id": "req-turns-001",
  "data": {
    "conversation_id": "10000000-0000-0000-0000-000000000801",
    "accepted_count": 2,
    "duplicate_count": 0
  }
}