3
基于AppBuilder自定义组件开发大模型应用
AI原生应用开发/技术交流
5月29日16496看过
☞ 如果您在大模型落地过程中遇到任何问题,可以提交工单咨询:https://console.bce.baidu.com/ticket/#/ticket/create?productId=279
☞ 同时,大模型技术专家可为您提供效果调优、应用定制和技术培训等付费专属服务:https://cloud.baidu.com/product/llmservice.html
AppBuilder简介:
如果大家不了解AppBuilder的话,可以先到这里了解一下:https://cloud.baidu.com/doc/AppBuilder/s/6lq7s8lli
一句话简介:千帆AppBuilder(以下简称AppBuilder)是基于大模型搭建AI原生应用的工作台,提供RAG、Agent、GBI等应用框架,文档问答、表格问答、对话、创作等应用组件,以及文生图、语音等传统AI组件,目标是帮助开发者降低AI原生应用开发门槛。
AppBuilder 提供了很多预定义的组件,能够快速实现部分功能,便于我们结合大模型来实现业务功能。
自定义组件介绍:
但有些场景下,我们有一些较为复杂的场景或者自己的服务想要接入大模型,这时我们就可以使用自定义组件的功能来快速地实现服务接入。本文我们就以百度地图接口为例,展示如何使用自定义组件来方便的实现我们的业务功能。
自定义组件提供了 5 类节点,分别是大模型、知识库、API、分支器和代码节点,我们先简单介绍下:
大模型节点:调用大语言模型,根据输入参数和提示词生成回复。
知识库节点:知识库节点支持根据输入的 query,在选定的知识库中检索相关片段并召回,返回切片列表。你可以上传文件并建立知识库,在知识库节点中勾选想要使用的知识库进行检索。
API 节点:调用指定的 API 接口,获取接口返回信息
分支器节点:连接两个下游节点,根据判断调节来判断触发哪个下游节点
代码节点:可以自己编写 python 代码,来实现自定义的处理功能
实际应用案例:
我们以下面这个场景为例,基于自定义组件开发一个实际的应用。
场景:
借助AppBuilder,实现通过自然语言与百度地图POI(Point of Interest)接口交互,进行各类信息的查询。如:我在百度大厦,周围有啥好吃的?
百度地图接口:
百度地图提供了丰富的接口查询功能,本次我们主要用到的是百度地图的圆形区域检索功能,该接口可以通过设置圆心和半径,检索圆形区域内的地点信息。
工作流设计:
根据地图接口文档可知,完成查询需要的主要字段包括:圆心位置、搜索半径、搜索类型,其中圆心位置需要以经纬度的形式来输入,所以我们首先还要获取圆心的经纬度坐标,这个功能圆形区域检索接口也是支持的,所以我们需要调用两次地图的接口。
综上,我们初步得到了以下工作流:
接下来,我们开始逐一配置工作流的节点。
首先我们要定义整个工作流的入参,如address表示地点信息,city表示城市,range表示搜索半径,type表示查询的位置点的类型:
然后模型就会根据参数描述,通过用户输入的问题提取出相关的入参,如我们示例的问题是『我在百度大厦,周围有啥好吃的?』,通过大模型提取,得到的入参即为:
{"address": "百度大厦","city": "北京","range": "1000","type": "餐饮"}
其中,『百度大厦』是我们提供的,『北京』是大模型通过『百度大厦』这个信息查询并自动补全的城市信息(并不是所有地名都能够唯一的定位到一个城市,所以这里有时候还需要用户手动输入),1000是查询范围,我们可以在模型的prompt中设置一个默认值,『餐饮』是大模型基于用户的问题『有啥好吃的』推理出的。
下一步,我们需要把address和city传给『经纬度接口』,来获取圆心位置的经纬度信息。我们按照接口要求,填写接口的url、method、鉴权字段等信息:
请求参数中,我们需要把工作流传入的字段引入到接口中,query字段我们引用入参address,region字段我们引用city,output我们静态指定为『json』:
返回中,我们根据返回接口,定义好json的结构:
最后在API调试页面手动填入下参数,运行一下,如果能请求成功就可以点击保存,这个API节点就配置成功了:
接下来,我们将经纬度查询节点获取到的圆心的坐标信息,加上开始节点传入的type、city、range信息一起传给圆形区域查询节点,来做周边信息查询, API的配置方法与上面相同:
这里我们发现,圆形区域信息查询接口的入参中,对经纬度参数的要求是一个字符串,因此不能直接拿经纬度接口的返回作为入参,因此这里我们在两个接口间插入一个代码模块,写一个小功能来处理下经纬度信息,让其满足接口的要求:
AppBuilder的代码模块中,入参会包含在params对象中,如我们引用了前一个节点的result参数,params的内容就是:
{"result": xxxx}
这里我们需要将经纬度模块查询到的坐标,从一个json对象转化为一个字符串,对应代码模块:
# 定义一个 main 函数,传入 params 参数。params 中包含了节点配置的输入变量。# 需要定义一个字典作为输出变量# 运行环境 Python3;预置 Package:NumPydef main(params):if 'result' in params.keys():location = params['result'][0]# 创建一个字典作为输出变量output_object ={# 引用节点定义的 location 变量"location": "%s,%s" %(location.get('lat'), location.get('lng'))}else:output_object ={}return output_object
现在我们在圆形区域查询接口中引用代码节点处理后的location信息,配置API节点的步骤同上,测试后接口就可以正常调用了:
到这里,我们的自定义组件的基本功能就都实现了,我们可以基于这个组件再做些优化,如对接口的结果做些预处理,以便后面大模型能更好的展示;或者增加一些分支器,来判断不同返回结果下的不同处理方案等。
当整个工作流的处理节点都配置完成后,最后我们要设置最终的返回格式,当前自定义组件支持两种返回模式:
1、直接返回对应的参数
2、按照自定义模板的内容返回
本示例中,我们希望在展示结果时通过markdown来展示,所以我们直接按照参数形式返回即可。
全部配置完后,我们就可以点下面的调试按钮,对整个自定义组件的工作流做调试了
可以看到工作流整体运行成功,返回了预期的结果,然后就可以点击右上角的发布按钮,将组件发布出去了
接来下我们来到Appbuidler的应用界面,新建应用,在组件列表中添加我们刚刚发布的组件:
应用配置
有了自定义组件,接下来就是编写角色指令来实现自然语言与组件的交互了,角色指令中需要注意一些细节,角色指令中我们跟大模型强调了在执行任务之前需要先确认好的位置信息,因为这个对于我们调用地图接口是必选的入参。同时,我们在角色指令中需要定义工具能力以及agent如何使用这个工具。另外我们在要求与限制中也需要对意图识别,专注度,结果数量和格式要求做好定义,确保提供稳定的输入输出体验。
这里我们放出这个应用的角色指令供大家参考:
# 角色任务作为周边信息查询助手,你的首要任务是获取用户所在的城市和具体位置。请确保在开始查询周边设施信息之前,先询问用户的相关位置信息。接下来,你需要根据用户输入的城市和具体位置,利用POI检索工具来查找周边设施的信息。你的任务是为用户提供准确、简洁、实时的周边设施信息。# 工具能力1. 地图POI检索工具熟练掌握并使用地图POI检索工具,根据用户的位置信息,检索周边设施的名称、位置、评价、电话、人均消费、距离、特色以及营业时间等信息。# 要求与限制1. 询问用户位置在提供任何查询服务之前,必须先确认用户的所在城市和具体位置2. 意图识别根据用户的问题,判断用户是否需要查询周边信息以及最符合用户需求的周边设施的类型3. 历史会话充分利用历史会话判断用户的所在地及城市、要查询的信息、路线的起点和终点等信息4. 专注于任务你的任务是提供周边设施信息,不要回答其他问题5. 搜索范围默认搜索周边3000米半径内的信息,如没有符合要求的信息,则引导用户扩大搜索范围6. 结果数量默认展示3个搜索结果项,用户可以要求展示更多,最多不超过10个7. 地图POI检索结果展示:如果结果数量大于3,默认只展示前3条结果;地图POI检索结果必须严格按照以下markdown格式展示## **[{{name}}]({{url}})**![照片]({{photo}})**地址**: {{address}}**电话**: {{tel}}**平均评价**: {{rating}}**平均消费**: {{price}}**距离**: {{distance}}**营业时间**: {{hour}}
到这里,我们的周边查询助手应用就实现了,我们可以用他来查询各类信息了,我们通过markdown的形式展示结果,可以实现超链接跳转及图片的展示:
我们把体验应用发布到了应用市场中,欢迎大家体验:
如果大家对于大模型应用构建有任何问题或者需要咨询,欢迎随时留言反馈。
评论