You need to enable JavaScript to run this app.
导航
推荐接口(predict)
最近更新时间:2025.02.10 16:45:01首次发布时间:2022.04.13 17:53:21

调用个性化推荐接口,传入用户id以及相关的上下文信息等,可以获得推荐结果列表。

请求方法

HTTPS POST

Path

《URL相关名词解释》
/predict/api/${application_id}/default

请求头

公共请求头部分详见《公共请求头说明》
接口额外请求头:

参数

说明

示例

是否必传

Enable-Spm-Route

用于告知推荐服务是否开启SPM路由。开启了之后推荐服务会根据请求携带的SPM将请求路由到绑定的栏位处理逻辑中。开启SPM路由的时候需要确保请求中的SPM是有效的SPM,且已经绑定了栏位。否则服务端会返回错误。

true

说明

如果您使用推荐平台,调用 Predict 接口时,必须将请求头 Enable-Spm-Route 设置为 true

请求体

参数

参数
类型
是否必传
描述
user
object
用户信息。
context
object
上下文信息。
candidateItems
object list
跳过召回等特殊场景需要上传候选集。
parentItem
object
相关推荐场景需要上传。
filterItems
object list
需要过滤的物品列表。
size
int
接口返回物品个数(优先级高于栏位配置返回数量)

说明

在线请求使用 filter 参数前,必须在平台上配置动态筛选。有关动态筛选配置的详情,请参阅 通过动态筛选,实现用户个性化筛选

示例

{
    "user":{
        "uid":"uid1",
        "device":{
            "deviceId":"device_id",
            "platform":"ios"
        },
        "age":"30",
        "gender":"male",
        "province":"GuangDong",
        "city":"ShenZhen",
        "country":"China"
    },
    "context":{
        "spm":"A$##$B$##$C",
        "feature":{
            "stringFeature":{
                "key":"value"
            },
            "intFeature":{
                "key":2
            },
            "floatFeature":{
                "key":3.5
            },
            "doubleFeature":{
                "key":3.51231
            },
            "stringArrayFeature":{
                "key":{
                    "values":[
                        "values1",
                        "values2"
                    ]
                }
            },
            "intArrayFeature":{
                "key":{
                    "values":[
                        1,
                        2
                    ]
                }
            },
            "floatArrayFeature":{
                "key":{
                    "values":[
                        1.1,
                        2.2
                    ]
                }
            },
            "doubleArrayFeature":{
                "key":{
                    "values":[
                        1.11111,
                        2.22222
                    ]
                }
            }
        },
        "filter":{
            "stringFilter":{
                "key":"value"
            },
            "intFilter":{
                "key":2
            },
            "floatFilter":{
                "key":3.5
            },
            "doubleFilter":{
                "key":3.51231
            },
            "stringArrayFilter":{
                "key":{
                    "values":[
                        "value1",
                        "value2"
                    ]
                }
            },
            "intArrayFilter":{
                "key":{
                    "values":[
                        1,
                        2
                    ]
                }
            },
            "floatArrayFilter":{
                "key":{
                    "values":[
                        1.1,
                        2.2
                    ]
                }
            },
            "doubleArrayFilter":{
                "key":{
                    "values":[
                        1.11111,
                        2.22222
                    ]
                }
            }
        },
        "extra":{
            "key1":"value1",
            "key2":"value2"
        }
    },
    "candidateItems":[
        {
            "id":"item_id1"
        },
        {
            "id":"item_id2"
        }
    ],
    "parentItem":{
        "id":"item_id3"
    },
    "filterItems":[
        {
            "id":"item_id4"
        },
        {
            "id":"item_id5"
        }
    ],
    "size":10
}

返回体

参数

参数
类型
描述
code
int32
不等同于http status,用于排查业务错误。200代表正常。非200代表错误。
message
string
状态信息,默认"OK",遇到错误会返回错误信息。
value
object
request_id
string
推荐请求的requestId。
success
bool
success字段存在,且等于true的时候,请求才是成功的。含义比code更简单直接一些。

示例

{
    "code":200,
    "message":"OK",
    "value":{
        "items":[
            {
                "id":"12345789",
                "rank":1,
                "transData":"jJGJveDUifbABAMoBDHRlc3RfZ2FubGluMQ==",
                "extra":{
                    "score":"0.67912"
                }
            },
            {
                "id":"56479201",
                "rank":2,
                "transData":"25vbGl0aBUa4MW/jhjkdsa+kljlkjdsa==",
                "extra":{
                    "score":"0.45213"
                }
            },
            {
                "id":"12340987",
                "rank":3,
                "transData":"dsjkahiunfmn1231/dsafkl+23123adaasd==",
                "extra":{
                    "score":"0.33768"
                }
            }
        ]
    },
    "request_id":"sfbnbm-123sam-dsajkh",
    "success":true
}

代码示例

import com.alibaba.fastjson2.JSON;
import okhttp3.*;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class Main {

    final static String token = "xxx"; // 替换为实际的token
    final static String tenantId = "xxx"; // 替换为实际的租户id
    final static String applicationId = "xxx"; // 替换为实际的应用id
    final static String predictUrl = "https://api.byteair.volces.com/predict/api/" + applicationId + "/default";

    public static void main(String[] args) {
        predict();
    }

    public static void predict() {
        String tenantTs = Integer.toString((int) (System.currentTimeMillis() / 1000)); // 当前时间戳
        String tenantNonce = UUID.randomUUID().toString().substring(0, 8); // 随机字符串
        byte[] httpBody = JSON.toJSONBytes(new HashMap<>() {{ // 示例用http body.真实请求请替换成实际使用的body.
            put("user", new HashMap<>() {{
                put("uid", "123");
            }});
            put("context", new HashMap<>() {{
                put("spm", "1$##$2$##$3");
            }});
        }});
        String sign = calSignature(token, tenantId, tenantTs, tenantNonce, httpBody);
        Headers.Builder builder = createHeader(tenantTs, tenantNonce, sign);
        builder.set("Enable-Spm-Route", "true");
        System.out.println(builder.build().toString());
        System.out.println(new String(httpBody));
        Request request = new Request.Builder()
                .url(predictUrl)
                .headers(builder.build())
                .post(RequestBody.create(httpBody))
                .build();

        OkHttpClient client = new OkHttpClient();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("action=predict`phase=failure");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String body = response.body().string();
                System.out.println(body);
            }
        });
    }

    //根据token、tenant_id、tenantTs、tenantNonce、httpBody计算signature
    public static String calSignature(String token, String tenant_id, String tenantTs, String tenantNonce, byte[] httpBody) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            // 按照token、httpBody、tenant_id、ts、nonce的顺序拼接
            // 本身为字符串的字段,需要使用utf-8方式编码成字节数组
            // httpBody本身为bytes类型,因此无需编码
            digest.update(token.getBytes(StandardCharsets.UTF_8));
            digest.update(httpBody);
            digest.update(tenant_id.getBytes(StandardCharsets.UTF_8));
            digest.update(tenantTs.getBytes(StandardCharsets.UTF_8));
            digest.update(tenantNonce.getBytes(StandardCharsets.UTF_8));
            // 将得到sha256使用16进制字符串表示
            return bytes2Hex(digest.digest());
        } catch (NoSuchAlgorithmException ignored) {
            return "";
        }
    }

    public static String bytes2Hex(byte[] bts) {
        StringBuilder des = new StringBuilder();
        String hex;
        for (byte bt : bts) {
            // 剔除负数强转成int后补上的"ffffff"
            hex = (Integer.toHexString(bt & 0xff));
            // 始终用两个16进制代表一个byte,不够的在前面补“0”
            if (hex.length() == 1) {
                des.append("0");
            }
            des.append(hex);
        }
        return des.toString();
    }

    private static Headers.Builder createHeader(String tenantTs, String nonce, String signature) {
        Headers.Builder builder = new Headers.Builder();
        builder.add("Tenant-Id", tenantId);
        builder.add("Tenant-Ts", tenantTs);
        builder.add("Tenant-Nonce", nonce);
        builder.add("Tenant-Signature", signature);
        builder.add("Request-Id", String.valueOf(UUID.randomUUID()));
        builder.add("Content-Type", "application/json");
        return builder;
    }
}