链接复制成功!
在华为云Astro轻应用中调用流式报文接口实现智能助手聊天对话
应用场景
开发者使用华为云Astro轻应用开发标准页面时,如果需要通过智能助手组件或其他组件对接外部大模型接口,可以直接在脚本或自定义连接器中配置对大模型接口的调用,支持以流式报文的形式获取大模型接口的返回值。最终在组件中,可实时接收接口返回信息,用户无需等待接口完成全部数据传输即可查看返回数据。
流式报文是指在数据传输过程中,数据不是一次性全部传输完毕,而是以流的形式逐步传输。
本实践将为您介绍,如何在脚本中调用大数据模型接口,实现在应用中接入大数据模型能力,开发AI应用。
方案优势
通过对大模型接口流式报文的支持,增强了智能助手等AI对话组件中调用大模型接口的页面会话体验。用户能够实时获得大模型接口的输出,实现流畅的AI对话。
约束与限制
限制类别 | 具体限制 |
|---|---|
脚本中参数限制 | 通过脚本直接调用SSE协议的URL时,需要传入参数“isStream:true”,否则不会走流式的处理逻辑。 |
连接器配置中动作的限制 | 动作中的返回类型必须设置为text/event-stream,否则自定义连接器的执行逻辑不会走流式的处理逻辑。 |
开放接口中参数的限制 | 如果使用开放接口调用SSE协议的脚本,需要将接口信息中的API类型配置为STREAM(默认是REST),同时URL的前缀应该为/service-stream(会根据api类型自动显示),否则不会走流式的处理逻辑,接口执行会报错。 |
步骤一:在华为云Astro轻应用中对接大模型接口
在华为云Astro轻应用中,提供了脚本和自定义连接器两种方式来对接大模型接口,请根据具体需求和实际情况进行选择。
通过脚本对接大模型接口
- 创建一个低代码应用。
- 参考授权用户使用华为云Astro轻应用并购买实例中操作,申请华为云Astro轻应用免费试用或购买商业实例。
- 实例购买后,在华为云Astro轻应用服务控制台的“主页”中,单击“进入首页”,进入应用开发页面。
- 在“应用”中,单击“新建低代码应用”或单击
,进入新建低代码应用页面。 首次创建应用时,请根据界面提示创建一个命名空间。命名空间一旦创建,不能修改和删除,创建前请确认好相关信息。建议使用公司或团队的缩写作为命名空间。
- 在新建低代码应用页面,应用类型选择“标准应用”,单击“确定”。
- 输入应用的标签和名称,单击“新建”,即可进入应用设计器。 图2 创建一个空白应用

- 在应用设计器中,选择“逻辑”,单击脚本后的“+”。
- 新建一个空白的脚本,名称设置为“streamScript”,单击“添加”。图3 创建脚本

- 在脚本编辑器中,输入示例代码。
本示例代码主要实现的功能包括:创建一个客户端,通过POST方法和GET方法调用相应的接口,使后台以处理流式报文的方式处理接口返回的数据。其中,https://example.com为待调用大模型接口的地址。

通过脚本直接调用SSE协议的URL时,传入参数“isStream”必须设置为“true”,否则不会走流式的处理逻辑。
import * as context from 'context'; import * as http from 'http'; /* * The input parameter is defined by `@action.param()`. */ export class Input { @action.param({ type: "String", required: true, description: "the operation type" }) inputParam: string; } /* * The output parameter is defined by `@action.param()`. */ export class Output { } /* * Define the main service class. * * - The service entry function is defined by `@action.method()`. * - All dependent objects should be defined via `@useObject([])` (for objects) or `@useBo([])` (for business objects). */ export class CallSseUrl { @action.method({ input: "Input", output: "Output", description: "do a operation" }) run(input: Input): Output { let output = new Output(); let cli = http.newClient() let resp = cli.post("https://example.com", { isStream: true, data: { "message": input.inputParam }, headers: { "Content-Type": "application/json" } }) return output; } } - 单击脚本编辑器上方的
,保存脚本。 - 调试脚本验证脚本是否符合预期。
- 在脚本编辑器上方单击
,进入脚本调试页面。 - 在“输入参数”页签中,输入如下示例。 图4 设置输入参数

{ "inputParam": "我想创建一个差旅管理应用" } - 单击
,执行脚本。 在“输出参数”中,输出如下流式内容,表明脚本输出正常。
图5 脚本输出内容
好的!为您**智能规划**了"**差旅管理**"应用的构建计划如下: 1. 创建一个名为"**差旅管理**"的低代码应用; 2. 添加模型对象"**差旅管理**",包含字段: - **出发城市**(下拉选择) - **目的城市**(下拉选择) - **出发时间**(日期) - **结束时间**(日期) - **出差目的**(文本) 3. 为"**差旅管理**"模型生成一个标准的**增删改查界面**; 4. 配置一条脚本逻辑:"**提交申请后,自动流转到审批人进行审核**"。 请问您是否确认该构建计划? 您可以输入: - "**确认**",我将开始执行; - 或输入**修改意见**,例如"增加一个报销单模型"或"把交通工具改为文本字段"。
- 在脚本编辑器上方单击
- 脚本校验符合预期后,单击脚本编辑器上方的
,启用脚本。
通过连接器对接大模型接口
- 创建一个低代码应用。
- 参考授权用户使用华为云Astro轻应用并购买实例中操作,申请华为云Astro轻应用免费试用或购买商业实例。
- 实例购买后,在华为云Astro轻应用服务控制台的“主页”中,单击“进入首页”,进入应用开发页面。
- 在“应用”中,单击“新建低代码应用”或单击
,进入新建低代码应用页面。 首次创建应用时,请根据界面提示创建一个命名空间。命名空间一旦创建,不能修改和删除,创建前请确认好相关信息。建议使用公司或团队的缩写作为命名空间。
- 在新建低代码应用页面,应用类型选择“标准应用”,单击“确定”。
- 输入应用的标签和名称,单击“新建”,即可进入应用设计器。 图6 创建一个空白应用

- 创建自定义连接器。
- 在应用设计器中,选择“集成”,单击“连接器”下的“连接器实例”。
- 在“类型”中,选择“自定义连接器”,进入自定义连接器页面。
- 单击“+”,配置连接器信息,单击“保存”。 图7 创建自定义连接器

- 为自定义连接器添加动作。
- 在“动作”页签中,单击“新建”。
- 设置动作的基本信息,单击“下一步”。 图8 设置基本信息

表6 动作基本信息参数说明 参数
说明
示例
标签
新建动作的标签名,用于在页面显示。
取值范围:1~64个字符。
streamaction
名称
新建动作的名称,名称是动作在系统中的唯一标识。命名要求如下:
streamaction
URL
待调用大模型接口的URL地址。
https://example.com
方法
选择请求的方法,可以设置为POST或GET。
POST
内容类型
输入内容的类型取决于第三方支持的具体种类,该类型在HTTP标准协议中定义。
application/json
返回类型
选择接口的返回类型,支持“application/json”和“text/event-stream”两种类型。
- application/json:选择该类型时,系统将忽略第三方实际返回的“Content-Type”,采用第三方配置的“Content-Type”来解析返回内容。
- text/event-stream:选择该类型时,将以处理流式报文的方式处理接口返回值,需要确保第三方接口的返回值为流式报文,且响应体中的“Content-Type”为“text/event-stream”。
text/event-stream
注意:“返回类型”必须设置为“text/event-stream”,否则自定义连接器的执行逻辑不会走流式的处理逻辑。
- 本示例无需设置消息头入参,请单击
删除第一行参数,再单击“下一步”。 - 设置输入参数,单击“下一步”。 图9 输入参数配置页面

表7仅介绍本实践中使用到的参数,其他参数解释请参见使用自定义连接器调用第三方接口。
- 本示例无需设置输出参数,请单击
删除第一行参数,再单击“保存”。 - 返回动作页签,单击该动作所在行的
,启用该动作。 图10 动作已启用
- 在“认证信息”页签,单击“新建”,为连接器添加认证信息。图11 添加认证信息

- 验证连接器调用流式报文接口。
- 创建脚本或服务编排,调用自定义连接器。
- 方式一:创建一个脚本,在脚本中调用自定义连接器。
- 参考通过脚本对接大模型接口中操作,创建一个空白脚本,在脚本编辑器中输入如下示例代码。其中,“命名空间__streamconnector”为2中创建连接器的名称,“命名空间__streamaction”为3中为连接器添加的动作,“命名空间__streamAuth”为4中为连接器添加的认证信息。
import * as context from 'context'; import * as connector from 'connector'; /* * The input parameter is defined by `@action.param()`. */ export class Input { @action.param({ type: "String", required: true, description: "the operation type" }) inputParam: string; } /* * The output parameter is defined by `@action.param()`. */ export class Output { } /* * Define the main service class. * * - The service entry function is defined by `@action.method()`. * - All dependent objects should be defined via `@useObject([])` (for objects) or `@useBo([])` (for business objects). */ export class CallCustomConnector{ @action.method({ input: "Input", output: "Output", description: "do a operation" }) run(input: Input): Output { let output = new Output(); // 页面上自己创建的自定义连接器的调用方法,第一个参数是创建的自定义连接器名称,第二个参数是认证信息名称 let client2 = connector.newClient("命名空间__streamconnector", "命名空间_streamAuth"); let input2 = { "message": input.inputParam, "stream": true }; // 第一个入参是动作名称, 第二个参数是入参 let resp2 = client2.invoke("命名空间__streamaction", input2); context.getHttp().response.setBody(resp2.data) return output; } }
- 单击脚本编辑器上方的
,保存脚本。 - 在脚本编辑器上方单击
,调试脚本,调试方法请参考通过脚本对接大模型接口。 - 脚本校验符合预期后,单击脚本编辑器上方的
,启用脚本。
- 参考通过脚本对接大模型接口中操作,创建一个空白脚本,在脚本编辑器中输入如下示例代码。其中,“命名空间__streamconnector”为2中创建连接器的名称,“命名空间__streamaction”为3中为连接器添加的动作,“命名空间__streamAuth”为4中为连接器添加的认证信息。
- 方式二:创建一个服务编排,在服务编排调用自定义连接器。
- 在应用设计器中,选择“逻辑”,单击“编排”后的“+”。
- 输入服务编排的名称和标签,单击“添加”,进入服务编排页面。 图15 创建服务编排

表9 添加服务编排参数说明 参数
说明
示例
标签
新建服务编排的标签名,用于在界面展示,创建后可修改。
取值范围:1~64个字符。
流式编排
名称
服务编排在系统中的唯一标识,创建后不支持修改。系统会自动在名称前添加“{命名空间}__”streamFlow,当其他功能调用服务编排时,调用的是服务编排的名称,而不是标签。
命名要求如下:
streamFlow
- 在“连接器 > 自定义”中,拖拽4中连接器的认证信息到画布中。 在服务编排中,如果包含多个图元,建议将流式自定义连接器图元置于服务编排的最后位置。若不将其置于最后,将无法获取到该图元之后其他图元的输出参数。图16 拖拽连接器到画布中

- 单击
,进入全局上下文页面。 - 单击“变量”后的
,新建message变量,类型为“文本”。 图17 新建message变量
- 选中自定义连接器图元,单击
,选择创建的动作。 图18 选择动作
- 在“输入参数”中单击“新增行”,“目标”选择message,将6.e中创建的变量拖拽到“源”中。 图19 设置输入参数

- 连接图元指定逻辑关系,即从开始图元连向连接器图元。 图20 连接图元

- 单击页面上方的
,保存服务编排。 - 单击页面上方的
,启用服务编排。
- 方式一:创建一个脚本,在脚本中调用自定义连接器。
步骤二:调用流式报文接口实现智能对话
创建一个标准页面,并拖入一个智能助手组件,通过脚本调用流式报文接口实现智能对话。
- 在应用设计器的左侧导航栏中,选择“界面”。
- 单击页面后的“+”,创建一个空白页面的标准页面。图21 设置标准页面基本信息

- 在“基本组件 > 智能化”中,拖拽“智能助手”组件到右侧画布中。图22 添加智能助手组件

- 为组件绑定模型。
- 为智能助手组件添加事件。
通过为组件绑定事件,确保智能助手能够根据用户的输入内容,做出不同的响应或执行特定的操作。
- 选中智能助手组件,在“事件”页签,单击“发送事件”后的“+”。
- 在自定义动作中,输入如下示例,单击“创建”。
const _component = context.$component.current; // 获取界面聊天框输入的信息 const messages = _component.getMessages(); // 判断接口返回值是否为JSON,流式接口的返回值不是可解析的JSON格式,需要特殊处理,所以这里填false const isJson = false; // 通过脚本名,传入脚本入参,执行脚本。这里的messages是所有界面聊天框已输入信息的集合,最后一位为最新发送的消息 var _script = context.script('命名空间__streamScript').run({ inputParam: messages[messages.length -1].content }, isJson).then(async resp => { // 创建一个可读流 const reader = resp.body.getReader(); const decoder = new TextDecoder(); // 循环调用流式接口的返回值 while (true) { const { done, value } = await reader.read(); // 流式接口的返回值,每次返回都会有done字段判断流是否发送结束 if (done) { // 当前组件 var _component = context.$component.current; _component.closeLoading(); return; } const chunk = decoder.decode(value); const data = chunk.split('\n').filter(n => n).map(item => { try { // 流式接口的返回值,会以data:xxx的格式返回,输出到页面时,需要将data:去除 return JSON.parse(item.replaceAll('data:', '')).content; } }) data.forEach(item => { $model.ref('message').setData(item) }) } })其中,“命名空间__streamScript”为通过脚本对接大模型接口中创建脚本的名称,“message”为4.b中创建模型的名称。
如果6中使用的是通过服务编排调用自定义连接器的方式,此处请输入如下事件代码。其中,“streamFlow”为6.b中创建服务编排的名称,“message”为6.e中新建的变量。
const _component = context.$component.current; // 获取界面聊天框输入的信息 const messages = _component.getMessages(); // 判断接口返回值是否为JSON,流式接口的返回值不是可解析的JSON格式,需要特殊处理,所以这里填false // 初始化Flow var _flow = context.flow(" {{ flowName }}"); // 适用于一次调用,Flow即完成的场景 // 运行Flow _flow.run({ inputParam: messages[messages.length - 1].content }).then(function (resp) { // 创建一个可读流 const reader = resp.body.getReader(); const decoder = new TextDecoder(); // 循环调用流式接口的返回值 while (true) { const { done, value } = await reader.read(); // 流式接口的返回值,每次返回都会有done字段判断流是否发送结束 if (done) { // 当前组件 var _component = context.$component.current; _component.closeLoading(); return; } const chunk = decoder.decode(value); const data = chunk.split('\n').filter(n => n).map(item => { try { // 流式接口的返回值,会以data:xxx的格式返回,输出到页面时,需要将data:去除 return JSON.parse(item.replaceAll('data:', '')).content; } }) data.forEach(item => { $model.ref('message').setData(item) }) } })
- 设计完成后,单击页面上方的
,保存标准页面。
步骤三:验证智能助手是否流式输出
- 在已创建的标准页面中,单击
,进入预览页面。图27 标准页面预览页面
- 在智能助手的聊天框中,输入文字,例如“我想创建一个差旅管理应用”,单击“发送”。智能助手返回如下流式结果,表明智能助手组件对接外部大模型接口成功。图28 智能助手响应效果











