
# 智能交互第三方LLM回调接口
#### 功能介绍
MetaStudio智能交互服务支持开发者自定义数字人大脑（即第三方LLM）。当用户与数字人对话时，将触发调用该接口，由该接口返回问题对应的答案文本内容。
#### 签名计算方法
第三方LLM自定义接口，使用HMACSHA256签名模式，需要在URL中追加参数"secret"和"time_stamp"。
取值方式为：secret=hmac_sha256(URI(llm_url) + timestamp, appKey)\&time_stamp=hex(timestamp)。
字段含义如下所示：
- llm_url：为[创建智能交互数字人](https://support.huaweicloud.com/usermanual-metastudio/metastudio_05_0111.html)中"第三方语言模型地址"参数的取值，即第三方LLM自定义接口地址。
- appKey：为[创建智能交互数字人](https://support.huaweicloud.com/usermanual-metastudio/metastudio_05_0111.html)中"APPKEY"参数的取值。
代码示例，如下所示：
```
URI uri = URI.create(llm_url);
long currentTimeMillis = System.currentTimeMillis();
String input = uri.toString() + currentTimeMillis;
String secret = Hmacsha256.doFinal(input, appKey);
String timeStamp = Long.toHexString(currentTimeMillis);
```
针对代码示例的具体案例，如下所示：
```
String appKey = System.getenv("APP_KEY");
URI uri = URI.create("https://metastudio-llm/digital-human/chat");
long currentTimeMillis = 1744612873350L;
String input = uri.toString() + currentTimeMillis; // input = https://metastudio-llm/digital-human/chat1744612873350
String secret = Hmacsha256.doFinal(input, appKey); // secret = a02fc32111795dc6f760e6bd15bb0cbc9a35921dc5dc86e57eea56ae644d793e
String timeStamp = Long.toHexString(currentTimeMillis); // timeStamp = 1963307d486
// 最终请求为 https://metastudio-llm/digital-human/chat?secret=a02fc32111795dc6f760e6bd15bb0cbc9a35921dc5dc86e57eea56ae644d793e&time_stamp=1963307d486
```
#### URI
POST llm_url
表1Query参数 
| 参数         | 是否必选 | 参数类型   | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|:---|:---|:---|:---|
| secret     | 是    | String | 签名信息。 取值为：secret=hmac_sha256(URI(llm_url) + timestamp, appKey)。 字段含义如下所示： - llm_url：为[创建智能交互数字人](https://support.huaweicloud.com/usermanual-metastudio/metastudio_05_0111.html)中"第三方语言模型地址"参数的取值，即第三方LLM自定义接口地址。  - appKey：为[创建智能交互数字人](https://support.huaweicloud.com/usermanual-metastudio/metastudio_05_0111.html)中"APPKEY"参数的取值。   |
| time_stamp | 是    | String | 时间戳。16进制格式，单位为毫秒。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   
#### 请求参数
表2请求Body参数 
| 参数           | 是否必选 | 参数类型                                                                 | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
|:---|:---|:---|:---|
| messages     | 是    | Array of [Message] objects | 多轮对话问答对。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| app_id       | 是    | String                                                               | 第三方语言模型的应用ID。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| user         | 是    | String                                                               | 用户唯一标识。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| session_id   | 是    | String                                                               | 当前对话的唯一标识，用于关联对话上下文内容。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| is_stream    | 否    | Boolean                                                              | 答案是否采用流式响应方式。默认值：false。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| extend_param | 否    | [ExtendParam] object       | 让回调接口的extend_param携带如下字段的方法： - 如果需要携带client_id、city和extra_json_param，则通过下述方法： - [Web SDK启动交互任务](https://support.huaweicloud.com/api-metastudio/metastudio_08_0010.html#section4)：通过Web SDK方式创建任务。  - [启动数字人智能交互任务](https://support.huaweicloud.com/api-metastudio/StartSmartChatJob.html)：通过API方式创建任务    - 如果需要携带question_param，则使用Web SDK接口[sendTextQuestion](https://support.huaweicloud.com/api-metastudio/metastudio_08_0010.html#section14)设置questionParam参数。   |
   
 表3Message 
| 参数      | 是否必选 | 参数类型   | 描述                                                            |
|:---|:---|:---|:---|
| content | 是    | String | 对话内容。 取值最小长度1，最大长度4096。 |
   
 表4ExtendParam 
| 参数               | 是否必选 | 参数类型   | 描述      |
|:---|:---|:---|:---|
| client_id        | 否    | String | 客户端ID。  |
| city             | 否    | String | 城市。     |
| extra_json_param | 否    | String | 自定义参数。  |
| question_param   | 否    | String | 文本提问参数。 |
   
#### 响应参数
**状态码： 200**
表5非流式响应Header参数 
| 参数           | 参数类型   | 描述                                |
|:---|:---|:---|
| Content-Type | String | 取值：application/json;charset=UTF-8 |
   
表6流式响应Header参数 
| 参数           | 参数类型   | 描述                                 |
|:---|:---|:---|
| Content-Type | String | 取值：text/event-stream;charset=UTF-8 |
   
请求参数"is_stream"取值为"false"时，响应Body体中的参数说明，如[表7]所示。
 表7非流式响应Body体参数说明 
| 参数      | 参数类型                                                                  | 描述         |
|:---|:---|:---|
| id      | String                                                                | 每个响应的唯一标识。 |
| created | Integer                                                               | 响应生成时间。    |
| choices | Array of [ChatChoice] objects | 生成的文本列表。   |
   
 表8ChatChoice 
| 参数      | 是否必选 | 参数类型                                                   | 描述                   |
|:---|:---|:---|:---|
| message | 是    | [表9] objects | 生成文本的内容。             |
| index   | 是    | Integer                                                | 生成文本在列表中的索引值，从0开始计算。 |
   
 表9MessageItem 
| 参数           | 是否必选 | 参数类型   | 描述                                                                                                                                |
|:---|:---|:---|:---|
| content      | 是    | String | 对话内容。 取值最小长度1，最大长度4096。                                                                      |
| extend_param | 否    | String | 支持模型返回定义的扩展消息，将会在[semanticRecognized事件](https://support.huaweicloud.com/api-metastudio/metastudio_08_0011.html#section8)的字段中返回消息。 |
   
请求参数"is_stream"取值为"true"时，响应Body体中的参数说明，如[表10]所示。
 表10流式响应Body体参数说明 
| 参数   | 参数类型   | 描述                                                                                                                                                                                                    |
|:---|:---|:---|
| data | String | 请求参数"is_stream"取值为"true"时，第三方语言模型生成的消息，以SSE流式形式返回给MetaStudio智能交互服务。即生成内容通过增量方式逐个发送，每个data字段均包含一部分生成的内容，直至所有data返回完成后，响应结束。 流式响应结束的标识为：结尾必须使用"data:\[DONE\]"作为结束符。 |
   
**状态码： 400**
表11响应Body参数 
| 参数         | 参数类型   | 描述    |
|:---|:---|:---|
| error_code | String | 错误码。  |
| error_msg  | String | 错误描述。 |
   
#### 请求示例
问答请求支持如下二种方式：
- 单轮非流式问答请求
  代码示例，如下所示：
  ```
  {
      "messages": [{
          "content": "请介绍下长江"
      }],
      "app_id": "5ca7fxxxxxxe40a0a01bcxxxxxx88307",
      "user": "f6befxxxxxx24a6dbaaxxxxxxc576475",
      "session_id": "b1cb4bxxxxxx4de793129f76xxxxxx68",
      "is_stream": false,
      "extend_param": {
          "client_id": "xxx",
          "city": "北京市",
          "extra_json_param": "{\"param1\":\"value1\",\"param2\":\"value2\"}"
      }
  }
  ```
  
- 多轮流式问答请求
  代码示例，如下所示：
  ```
  {
      "messages": [{
          "content": "请介绍下长江" //第一轮问题
      }, {
          "content": "长江是中国的一条主要河流，也是世界上最长的河流之一。长江的源头在青藏高原的唐古拉山，全长约6300公里，流经中国的11个省份，最终在上海注入东海。" //第一轮答案
      }, {
          "content": "请列举5个途径的省份" //第二轮问题
      }, {
          "content": "以下是长江途径的5个省份:\n\n1.青海省\n2.四川省\n3.云南省\n4.湖南省\n5.江西省" //第二轮答案
      }, {
          "content": "长江中有哪些鱼类" //第三轮问题
      }],
      "app_id": "5ca7fxxxxxxe40a0a01bcxxxxxx88307",
      "user": "f6befxxxxxx24a6dbaaxxxxxxc576475",
      "session_id": "b1cb4bxxxxxx4de793129f76xxxxxx68",
      "is_stream": true,
      "extend_param": {
          "client_id": "xxx",
          "city": "北京市",
          "extra_json_param": "{\"param1\":\"value1\",\"param2\":\"value2\"}"
      }
  }
  ```
  
 
#### 响应示例
**状态码：200**
对应问答请求支持的二种方式，响应消息需要选择相同的方式，分别如下所示：
- 单轮非流式问答响应消息
  示例代码，如下所示：
  ```
  {
      "id": "2f8e891225d486190c8bea91207e9aa1",
      "created": 20230512084843,
      "choices": [{
          "index": 0,
          "message": {
              "content": "长江是中国的一条主要河流，也是世界上最长的河流之一。长江的源头在青藏高原的唐古拉山，全长约6300公里，流经中国的11个省份，最终在上海注入东海。",
      "extend_param": "xxxxxxxx"
          }
      }]
  }
  ```
  
- 多轮流式问答响应消息
  示例代码，如下所示：
  ```
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646748, "choices": [{"message": {"content": "长江"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646766, "choices": [{"message": {"content": "是", "extend_param": "xxxxx"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646785, "choices": [{"message": {"content": "中国"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646822, "choices": [{"message": {"content": "最长"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646841, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646878, "choices": [{"message": {"content": "河流，"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646915, "choices": [{"message": {"content": "流经"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646952, "choices": [{"message": {"content": "多个"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394646989, "choices": [{"message": {"content": "省份，"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647008, "choices": [{"message": {"content": "拥有"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647026, "choices": [{"message": {"content": "丰富"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647044, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647063, "choices": [{"message": {"content": "鱼类"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647081, "choices": [{"message": {"content": "资源"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647100, "choices": [{"message": {"content": "。"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647118, "choices": [{"message": {"content": "以下"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647136, "choices": [{"message": {"content": "是"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647154, "choices": [{"message": {"content": "长江"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647173, "choices": [{"message": {"content": "常见"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647191, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647209, "choices": [{"message": {"content": "一些"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647246, "choices": [{"message": {"content": "鱼类:\n"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647265, "choices": [{"message": {"content": "\n"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647302, "choices": [{"message": {"content": "1."}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647321, "choices": [{"message": {"content": "**"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647357, "choices": [{"message": {"content": "中华鲟"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647394, "choices": [{"message": {"content": "**: "}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647412, "choices": [{"message": {"content": "这是"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647431, "choices": [{"message": {"content": "一种"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647449, "choices": [{"message": {"content": "古老"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647468, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647523, "choices": [{"message": {"content": "鲟科"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647560, "choices": [{"message": {"content": "鱼类，"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647579, "choices": [{"message": {"content": "也"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647597, "choices": [{"message": {"content": "是"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647616, "choices": [{"message": {"content": "世界"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647635, "choices": [{"message": {"content": "上"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647653, "choices": [{"message": {"content": "最"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647672, "choices": [{"message": {"content": "古老"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647690, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647709, "choices": [{"message": {"content": "鱼类"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647728, "choices": [{"message": {"content": "之一"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647747, "choices": [{"message": {"content": "。"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647765, "choices": [{"message": {"content": "\n"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647804, "choices": [{"message": {"content": "2."}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647822, "choices": [{"message": {"content": "**"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647878, "choices": [{"message": {"content": "鲢鱼"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647914, "choices": [{"message": {"content": "**: "}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647932, "choices": [{"message": {"content": "也"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394647951, "choices": [{"message": {"content": "称"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648005, "choices": [{"message": {"content": "白鲢，"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648024, "choices": [{"message": {"content": "是"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648042, "choices": [{"message": {"content": "一种"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648060, "choices": [{"message": {"content": "常见"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648079, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648115, "choices": [{"message": {"content": "淡水鱼"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648133, "choices": [{"message": {"content": "类"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648152, "choices": [{"message": {"content": "。"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648170, "choices": [{"message": {"content": "\n"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648206, "choices": [{"message": {"content": "3."}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648225, "choices": [{"message": {"content": "**"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648316, "choices": [{"message": {"content": "鳙鱼"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648362, "choices": [{"message": {"content": "**: "}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648380, "choices": [{"message": {"content": "也"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648398, "choices": [{"message": {"content": "称"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648471, "choices": [{"message": {"content": "胖头鱼，"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648489, "choices": [{"message": {"content": "是"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648508, "choices": [{"message": {"content": "一种"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648527, "choices": [{"message": {"content": "重要"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648545, "choices": [{"message": {"content": "的"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648564, "choices": [{"message": {"content": "食用"}}]}
  data:{"id": "5b7eb95f59e54981b3aa58998c888c4b", "created": 1705394648582, "choices": [{"message": {"content": "鱼类"}}]}
  data:[DONE]
  ```
  
  
**状态码： 400**
```
{
  "error_code" : "xxxxxxxx",
  "error_msg" : "Invalid parameter"
}
```
#### 状态码
| 状态码 | 描述                 |
|:---|:---|
| 200 | 处理成功返回。            |
| 400 | 请求传参异常，包含错误码及对应描述。 |
   
#### 错误码
请参见[错误码](https://support.huaweicloud.com/api-metastudio/ErrorCode.html)。
