助理调用说明
1.认证打通
1.1.快速接入
适用目标客户:私有化客户接入
信任三方传递的用户信息,保存并且组装上下文。

1.2.标准三方
适用目标客户:百度云、飞书、钉钉、企微等
使用第三方的登录页面,登录成功之后返回IDP登录校验并获取用户信息

流程说明
- 通过超级助理登录页面选择登录方式。
- 点击跳转到对应的登录页面地址并携带 超级助手登录地址作为跳转地址 eg:百度云登录地址 https://login.bce.baidu.com/?redirect=https://superhelper.bce.baidu.com/api/idp/v1/authentication/login?state=IAM&u=https://superhelper.bce.baidu.com/helper/web/dashboard
参数说明:
| 参数 | 说明 | 
|---|---|
| api/idp/v1/authentication/login | IDP登录地址 | 
| state | 登录来源 | 
| u | 登录成功之后跳转地址(非必须) | 
   
- IDP服务处理,根据state判断登录来源,获取对应认证code或token访问对应认证地址获取用户信息。 本地存储用户信息并生成验证cookie:login_auth_type,方便后续的每次请求拦截认证校验
2.「助理」使用方式
2.1 OpenApi 使用步骤
2.1.1 访问凭证获取
通过ak/sk获取超级助理颁发的访问凭证tenant_access_token

接口说明
GET https://{host}/api/idp/v1/accessToken/get
请求参数
| 字段 | 说明 | 
|---|---|
| ak | 应用颁发KEY | 
| sk | 应用颁发Secret Key | 
返回参数
1{
2    "success": true,
3    "code": 200,
4    "msg": "ok",
5    "data": "ePMbrL87v8PNcB4UPixxx......xxxNpEGHqTk498QYS7qFiKVz1=="
6}2.2.2 API调用
接口说明:
GET https://{host}/open/api/aiChat/conversation
请求参数
RequestHeader
| 字段 | 必要 | 说明 | 
|---|---|---|
| Authorization | Y | 'Bearer {tenant_access_token}' 请求头中添加应用凭证 | 
| Accept | N | text/event-stream | 
RequestParam
| 字段 | 必要 | 说明 | 
|---|---|---|
| content | Y | 用户输入的问题 | 
| userId | N | 当前使用者的用户ID | 
| userName | N | 当前使用者的用户名称 | 
userId和userName有助于业务逻辑中对当前使用者提供更好的处理
响应结果
响应结果示例
1event:ack
2data:{"msgType":"","userInfo":{"userId":"0","avatar":""},"msgId":"1791352321427951616","questionId":"","conversationId":"","docKey":"","orderId":7013,"actionType":"","timestamp":0,"contents":null,"vertical":"","verticalGroup":"","debugInfo":"aichat-server_cp3fcue25l5mmnu34di0","reqDebug":null,"logId":""}
3
4event:loading
5data:{"msgType":"intent","userInfo":{"userId":"","avatar":""},"msgId":"","questionId":"","conversationId":"","docKey":"","orderId":0,"actionType":"","timestamp":0,"contents":"","vertical":"","verticalGroup":"","debugInfo":"aichat-server_cp3fcue25l5mmnu34di0","reqDebug":null,"logId":""}
6
7event:loading
8data:{"msgType":"identifying","userInfo":{"userId":"","avatar":""},"msgId":"","questionId":"","conversationId":"","docKey":"","orderId":0,"actionType":"","timestamp":0,"contents":"","vertical":"","verticalGroup":"","debugInfo":"aichat-server_cp3fcue25l5mmnu34di0","reqDebug":null,"logId":""}
9
10event:loading
11data:{"msgType":"generating","userInfo":{"userId":"","avatar":""},"msgId":"","questionId":"","conversationId":"","docKey":"","orderId":0,"actionType":"","timestamp":0,"contents":"正在生成回答","vertical":"verticalPublic","verticalGroup":"verticalPublic","debugInfo":"aichat-server_cp3fcue25l5mmnu34di0","reqDebug":null,"logId":""}
12
13event:message
14data:{"msgType":"aigc","userInfo":{"userId":"assistant","avatar":""},"msgId":"1791352321440534528","questionId":"1791352321427951616","conversationId":"","docKey":"","orderId":0,"actionType":"","timestamp":1715926650262,"contents":[{"type":"vertical-title","contents":{"text":"基于「千帆千亿问答」回答","pluginName":"千帆千亿问答","pluginVersion":""}}],"vertical":"verticalPublic","verticalGroup":"verticalPublic","debugInfo":"logId=aichat-server_cp3fcue25l5mmnu34di0","reqDebug":null,"logId":""}
15
16data:{"msgType":"aigc","userInfo":{"userId":"assistant","avatar":""},"msgId":"1791352321440534528","questionId":"1791352321427951616","conversationId":"","docKey":"","orderId":0,"actionType":"","timestamp":1715926650263,"contents":[{"type":"ai-markdown","contents":{"text":"你好"}}],"vertical":"verticalPublic","verticalGroup":"verticalPublic","debugInfo":"logId=aichat-server_cp3fcue25l5mmnu34di0","reqDebug":null,"logId":""}
17
18event:finish
19data:end响应结果说明
- event 消息类型:
| event 类型 | 说明 | 
|---|---|
| ack | 开始发送消息 | 
| loading | 消息加载中 | 
| message | 需要渲染的消息 | 
| finish | 发送消息完成 | 
- data 消息体:
| 字段 | 说明 | 
|---|---|
| contents | 消息内容 | 
| msgType | 消息类型 | 
| msgId | 消息ID | 
| conversationId | 会话ID | 
| timestamp | 时间 | 
- contents 消息内容:
| 字段 | 说明 | 
|---|---|
| type | 需要渲染的消息类型 | 
| contents | 需要渲染的消息内容 | 
- 
前端支持渲染的消息类型 - 通用类型
 
| 类型 | 说明 | 渲染效果样例 | 
|---|---|---|
| vertical-title | 插件标题 |  | 
| para | 纯文本,段落 | |
| text | 纯文本,文字 | |
| ai-text | 纯文本,仅支持链接识别 |  | 
| ai-markdown | markdown 类型的内容,支持链接识别能力,支持表格 / 代码 / 列表 / 引用 等能力 | |
| image-group | 图片组,端内支持点击放大效果 | |
| link | 一段简单的文本链接,支持加一个 icon | |
| reference | 参考资源,较为常用 |  | 
| file | 文件解读场景,仅发送场景展现 | |
| workflow-card | 工作卡,较为常用 |  | 
| query-recommend | query 推荐 | 
1- 智能助理消息类型| 类型 | 说明 | 渲染效果样例 | 
|---|---|---|
| status_info | 消息标题 |  | 
| answer_summary | 消息-总结 |  | 
| answer_clarify | 消息-列表 |  | 
| answer_finalAnswer | 消息-文本 | |
| thinking | denbug 信息-思考 |  | 
| action | denbug 信息 | |
| action_input | denbug 信息 | |
| observation | denbug 信息 |  | 
2.2.3 获取AK、SK、OpenApiUrl
进入【管理后台】 ---> 点击【助理管理】---> 点击要使用的Agent(默认应用)查看详情 ---> 获取AK、SK、Agent访问地址
 

2.2.4 消息类型在前端的渲染
接口返回的消息格式遵循与前端约定的协议,不同的type对应不同的渲染方式,使用时可根据业务灵活实现 返回类型主要分两类
markdown类型
1.添加渲染引起依赖包 "@baidu/markdown-typed-render-engine": "1.0.6-assistant.1"
该包现只支持React,暂不支持Vue
注意:@baidu/markdown-typed-render-engine渲染包属于厂内包,如果需要可以咨询售前同学提供
如果只是需要渲染简单markdown数据也可使用markdown-it来渲染
2.使用markdown渲染引擎
1import MarkdownRenderEngine from '@baidu/markdown-typed-render-engine';
2import '@baidu/markdown-typed-render-engine/dist/index.css';
3
4// 渲染markdown类型数据
5<MarkdownRenderEngine
6    className={styles.markdown} // markdown渲染组件样式
7    value={text} // 待渲染的markdown类型数据
8    typed={
9        isLastMarkdownString: status === 'finish',
10        renderLength: 3, // 每次渲染的长度
11        autoInit: true,
12        full: true,
13    }
14    render={{
15        chartV1: true, // 开启 chartV1 图表自动渲染,默认关闭
16    }}
17/>工作卡(workflow)类型
工作卡渲染方式:
1.引入对应的flow.js脚本
1  <script src="https://{host}/super-help/api/v1/engine-pre/js-rcv/flow.js?sceneId=knowledge"></script>2.拿到消息中的关键模版信息
1 const {cardInfo, teplateInfo} = message;3.调用挂载在window上的渲染方法
1          const renderData = {
2            cardInfo,
3            templateInfo,
4            dom: document.getElementById('renderCardWrapper'), //作为容器的dom节点
5            uuid: uuid(), //唯一的uuid,用来标记区分不同的工作卡
6            type: 'inline',
7            callback:(success: boolean)=>{} //可选参数,渲染后执行的回调,成功执行callback(true),失败callback(false)
8        }
9        window.flow.linkRecognize.renderCardByData(renderData);3.JSSDK接入
3.1 SDK安装
1.直接浏览器标签引入
1  <script src="https://superhelper-online.bj.bcebos.com/jssdk/js/SuperHelper.iife.js"></script>3.2 SDK使用
3.2.1 登录
SDK使用之前需要先进行登录,登录采用AK/SK的校验方式,此方式会从后端获得临时token,用于用户后续对话的鉴权。
1const {login, Renderer} = window.SuperHelper;
2// other codes...
3// 第三方逻辑,已获取到用于登录的token和tenantId
4login({
5    ak: ak,
6    sk: sk,
7    // 指定登录域名,可选
8    host: 'https://superhelper.bce.baidu.com'
9}).then(() => {
10    // 登录完成后可以进行后面超级助理的渲染
11    render()
12})3.2.2 渲染
登录之后便可以进行超级助理界面的渲染。使用Renderer类提供的render方法来渲染整个界面,包含悬浮窗和侧边栏。
1function render() {
2    const renderer = new Renderer({
3        // 指定超级助理页面地址,可选
4        aiChatHost: 'https://superhelper.bce.baidu.com',
5    });
6    renderer.render();
7    // other...
8}此时会在右侧渲染出一个悬浮窗,Renderer同时提供了showFlowWindow()和hideFlowWindow()来控制悬浮窗的显隐。 点击悬浮窗会展示侧边栏,同样Renderer提供了showSideBar()和hideSidebar() 方法来控制侧边栏的显隐。
3.2.3 事件
超级助理的相关事件都是通过Renderer的实例来进行监听和触发的,SuperHelper提供了一个RENDERER_EVENT对象,方便获取相关事件的type名称,所有支持的事件名都会维护到这个对象上。
1const {RENDERER_EVENT} = window.SuperHelper;
2render.addEventListener(RENDERER_EVENT.sideBarDisplay, isShow => {
3    console.log('sideBarDisplay', isShow);
4});
5render.addEventListener(RENDERER_EVENT.chatReply,  message => {
6    // message返回为格式详见下方聊天消息结果的获取
7    console.log('aichatMessage', message);
8});目前支持的事件:
1const RENDERER_EVENT = {
2    // 界面渲染完成
3    mounted: 'mounted',
4    // 界面销毁完成
5    destroyed: 'destroyed',
6    // 聊天消息回复
7    chatReply: 'chatReply',
8    // 侧边栏显隐事件
9    sideBarDisplay: 'sideBarDisplay',
10};3.2.4 聊天消息的结果获取
通过监听聊天返回事件可以拿到超级助理的返回结果,包含所使用插件、消息内容等。 如提问“888”的返回结果:
1{
2    'content': '888',
3    'result': [
4        {'text': '基于「文心一言插件」回答', 'pluginName': '文心一言插件', 'pluginVersion': ''},
5        {
6            'text': '“888”在网络用语中通常表示一种祝福或祈愿的用语,尤其在中国网络文化中,它被广泛使用。这个数字的发音与“发发发”非常相似,因此它被视为一种寓意吉祥、财运亨通的数字。\n\n在中国的传统文化中,数字8是一个非常吉祥的数字,代表着好运、成功和发财。因此,“888”在网络用语中也被视为一个幸运数字,可以带来好运和幸福。\n\n此外,“888”在某些情况下也可以表示一种告别或分手的意味,但这种用法相对较少。\n\n总之,“888”在中国网络用语中通常是一种祝福或祈愿的用语,代表着吉祥、好运和财富。',
7        },
8    ],
9};4.H5接入
4.1 生成签名(Server端)
企业Server端根据签名算法生成sign,通过接口下发给前端的方式,供前端调用H5页面

4.1.1 企业自定义签名
通过使用SK对 AK + params进行hmac_sha256 运算签名
- 使用有序map整合 ak + params
- 对map按照key进行字典排序,并将map转为 key=value&xxx 格式的字符串
- 使用SK对需要加密的字符串进行加密
params参数
| 字段 | 说明 | 必填 | 
|---|---|---|
| userId | 用户ID(客户系统) | Y | 
| userName | 用户名称 | Y | 
| tenantId | 租户ID(超级助理下发) | Y | 
| tenantName | 租户名称(超级助理下发) | N | 
租户ID查看(tenantId)
JAVA代码示例
1import org.apache.commons.codec.digest.HmacAlgorithms;
2import org.apache.commons.codec.digest.HmacUtils;
3
4Map<String, String> params = // 用户数据
5String ak = "" // 真实的AK
6String sk = "" // 真实的SK
7
8
9LinkedHashMap<String, String> signParams = new LinkedHashMap<>();
10params.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach((entry) -> {
11    signParams.put(entry.getKey(), entry.getValue());
12});
13signParams.put("ak", ak);
14String data = signParams.entrySet().stream()
15        .map(entry -> entry.getKey() + "=" + entry.getValue())
16        .collect(Collectors.joining("&"));
17String sign = hmacSha256(sk, data)
18
19
20 private static String hmacSha256(String key, String data){
21    HmacUtils hmacUtils = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, key);
22    return hmacUtils.hmacHex(data);
23}4.2 页面嵌入
4.2.1 获取参数
前端需要提前根据当前用户的登录态,向企业系统server端获取userInfo、ak、signature等信息
1// 用户信息格式,有当前企业系统获取的当前用户信息
2const userInfo = {
3    userId,
4    userName,
5    tenantId,
6    tenantName,    // tenantName非必传,可为''
7}
8
9// 应用的ak
10const ak = 'xxxxx';
11
12// 从server获取当前用户的签名(根据4.1签名算法生成)
13const signature: any = await getSignature(); 4.2.2 创建iframe
location.origin 为当前环境的请求地址 eg:https://superhelper.bce.baidu.com
1参考例子:
2const host = location.origin + '/public/agents/web?isJiliFlag=1';
3const iframe = document.createElement('iframe') as HTMLIFrameElement;
4iframe.src = host;
5if (iframe) {
6    iframe.style.width = "100vw";
7    iframe.style.height =  window.innerHeight+'px';
8    iframe.style.border = 'none';
9    iframeContainerRef.current.appendChild(iframe); // iframeContainerRef.current属于React的ref语法,目的是为了将创建的iframe添加到所需的元素中
10    iframeRef.current = iframe; // iframeRef.current属于React的ref语法,目的是为了后续对iframe元素对象方便获取和赋值
11}4.2.3 监听 postmessage
1 window.addEventListener('message', func); // 建议在创建iframe之前执行,关注时机
2const func = (event) => {
3    const data = event.data;
4    if (data?.type === 'GET_TOKEN') {
5        const time = new Date(new Date().getTime() + 60 * 60 * 1000).toISOString();
6        iframeRef.current?.contentWindow?.postMessage(
7            {
8                type: 'SET_TOKEN',   // 固定填充
9                href: location.href, // 当前嵌入的主页面的地址,比如百度网站嵌入超级助理,则为 https://www.baidu.com/?query=test 
10                requestId: data.requestId, // 固定填充
11                data: {
12                    userInfo, // 用户信息,与签名传传入的userInfo一致
13                    expireTime: time, // 超时时间
14                    sign: signature,  // 服务端下发的签名(4.1.1步骤)
15                    ak: ak,           // 应用ak
16                    isJSSDK: true,    // 固定填充
17                },
18            },
19            host  // 超级助理的页面地址(企业嵌入地址)。固定填充:https://superhelper.bce.baidu.com/public/agents/web
20        );
21    }
22}例子:
1// 响应函数参考: 
2window.addEventListener('message', func); // 建议在创建iframe之前执行,关注时机
3const func = (event) => {
4    const data = event.data;
5    if (data?.type === 'GET_TOKEN') {
6        const time = new Date(new Date().getTime() + 60 * 60 * 1000).toISOString();
7        iframeRef.current?.contentWindow?.postMessage(
8            {
9                type: 'SET_TOKEN',
10                href: "https://superhelper.bce.baidu.com/openweb/cloudMeet",
11                requestId: 'xxxx',
12                data: {
13                    userInfo: {
14                        tenantId: "xxxxxx"
15                        tenantName: "xxx"
16                        userId: "xxx"
17                        userName: "huicheng_mine"
18                    },
19                    expireTime: "2024-06-12T13:50:21.013Z",
20                    sign: 'xxxxx',
21                    ak: 'xxxxx',
22                    isJSSDK: true,
23                },
24            },
25            location.origin + '/public/agents/web''
26        );
27    }
28}FAQ
1. H5页面签名校验失败 请检查签名信息里面必须包含正确的ak和params(params为前端传入的用户信息,签名和前端传入的参数必须一致)。
2. 访问超级助理页面出现跨域问题(CORS)
 当前超级助理默认开启了跨域(Cross-origin resource sharin)控制,如需内嵌请联系管理员或者发送邮件信息(superhelper_rd@baidu.com)开启白名单。
当前超级助理默认开启了跨域(Cross-origin resource sharin)控制,如需内嵌请联系管理员或者发送邮件信息(superhelper_rd@baidu.com)开启白名单。

