更新时间:2026-03-18 GMT+08:00
分享

基于函数创建插件

在AgentArts智能体开发平台中,当官方插件市场无法满足特定业务需求时,开发者需要自主创建插件。根据实现机制与运行形态的不同,自定义插件主要分为“API类型插件”和“函数类型插件”两种形态。API型插件介绍及创建请参考基于API创建插件

前提条件

函数形式插件

函数类型插件是指直接在AgentArts智能体开发平台中编写并运行的一段代码脚本(Python3.9或Node.js14.18脚本),它不依赖外部服务器,而是利用平台提供的算力即时执行。

典型适用场景:

  • 精确计算:利息计算、日期推算(下周三是几号)、单位换算。
  • 逻辑校验:身份证/手机号正则校验、JSON格式修复。
  • 数据清洗:数据进行去重、排序、过滤。

不适用场景:大规模数据存储、重型计算(如视频渲染)、复杂的持久化状态管理。

插件调用链路:

  1. 用户输入:修复这段JSON:{'name': '张三', age: 25,}。
  2. Agent分析:Agent识别用户意图为“JSON修复”,命中代码插件fix_json_format。
  3. 参数生成:模型提取用户提供的原始文本,生成入参:{ "raw_text": "{'name': '张三', age: 25,}" }。
  4. 沙箱启动:Agent启动一个隔离的Python运行环境(Sandbox)。
  5. 代码执行:加载用户编写的修复逻辑,代码尝试解析并重新序列化数据,确保输出符合标准JSON规范。
  6. 返回结果:代码运行结束,返回结构化结果:{ "is_valid": true, "formatted_json": "{\"name\": \"张三\", \"age\": 25}" }。
  7. 最终回复:模型根据代码返回的结果,向用户输出:“已为您修复JSON格式,修复后的内容如下...”。

创建插件的流程

函数型插件是直接在平台提供的沙箱环境中的一段脚本代码,本文将直接通过具体示例进行演示,助您快速上手。

序号

流程环节

说明

1

创建插件

在函数插件中,“插件”仅作为管理和分类的容器,实现对同类工具的管理。

2

创建工具

创建工具

工具真正干活的实体。每一个工具都对应一个独立的函数实例。代码逻辑、依赖包、入参出参定义全部都在这里配置。

创建自定义依赖包(可选)

支持使用Python3.9或Node.js14.18创建工具代码。为了保持轻量和安全,平台只提供最基础的语言环境,即除了Python3.9、Node.js14.18本身自带的标准库外,其余依赖包均需要手动上传。

示例1

文本相似度计算插件,基于Python,不需上传依赖包。

示例2

网页HTML内容清洗插件(需上传依赖包),基于Python,需上传依赖包。

示例3

创建Python依赖包

附录1

Python编码规范

附录2

Node.js编码规范

示例1:文本相似度计算插件

该插件的主要作用是接收两个文本输入(text1和text2),并通过以下三种算法之一计算它们的相似程度(0.0到1.0之间):

  • Cosine(余弦相似度):默认算法。通过词频向量计算文本在语义/内容上的重合度。
  • Jaccard(杰卡德相似系数):计算两个文本中相同字符(token)在总字符中的占比,适合集合重合度计算。
  • Edit Distance(编辑距离):计算将一个文本变成另一个文本需要变动多少字符,适合检测拼写错误或短文本的字面差异。

同时配置了停用词表(DEFAULT_STOPWORDS)、预处理配置(PREPROCESS_CONFIG)、文本预处理(preprocess_text)单元。

  • 停用词表:定义了一组常见的无实际意义的词(如“的”、“了”、“是”等),用于过滤。
  • 预处理配置:转小写;去除标点符号(只保留汉字、字母、数字);去除停用词;切分粒度。
  • 文本预处理:清洗:将文本转为小写,并使用正则表达式;分词:将文本打散成字符列表;过滤:移除在停用词表中的字符。

文本相似度计算插件创建步骤如下:

  1. 登录AgentArts智能体开发平台,在左侧导航栏“个人空间”区域,选择目标空间。
  2. 在左侧导航栏中选择“开发中心 > 组件库”,在“插件”页签,单击页面右上角“创建插件”。
  3. 选择“函数类型”类型的插件,然后根据以下步骤配置插件信息。

    表1 基本信息

    参数

    说明

    示例

    插件类型

    根据实现机制与运行形态的不同,插件分为“API类型”和“函数类型”两种形态。

    函数类型

    插件图标

    单击默认图标按钮,可上传本地图片作为插件的自定义图标。

    支持jpg、jpeg、png格式,不超过200KB。

    系统默认图标

    名称

    用于标识当前插件,在“组件库 > 插件”页面会展示该名称。

    命名规则:按照插件的实际功能命名,有助于Agent进行插件的精准识别和调度。

    命名要求:可以包含中文、英文、数字、下划线;

    长度限制:2~64个字符。

    文本相似度计算

    描述

    描述当前插件的类型、功能和适用场景。

    需要按照插件的实际功能填写描述,有助于Agent进行插件的精准识别和调度。

    使用Python内置库(re/math/difflib)计算两段文本的相似度(适配Agent意图匹配、问答匹配、文本查重等场景)。

  4. 配置完单击“确定”。

    平台会自动跳转至工具信息页面,请参考后续步骤创建工具,在创建工具阶段会配置代码脚本、输入、输出参数等信息。

  5. 在“工具信息”页面,单击“创建工具”,在“添加工具”弹窗单击“新建函数”。

    图1 添加函数

  6. 填写函数名称与描述,执行语言选择“Python3.9”。

    表2 函数基本信息

    参数

    填写示例

    名称

    Text_similarity_calculation

    描述

    使用Python内置库(re/math/difflib)计算两段文本的相似度(适配Agent意图匹配、问答匹配、文本查重等场景)。

    执行语言

    Python3.9

  7. 单击“编辑源码”,复制如下代码脚本。

    图2 编辑源码
    # -*- coding:utf-8 -*-
    import re
    import math
    import difflib
    
    
    # ===================== 全局配置 =====================
    DEFAULT_STOPWORDS = {
        "的", "了", "是", "我", "你", "他", "她", "它", "们", "在", "有", "就",
        "不", "和", "也", "都", "这", "那", "此", "彼", "之", "于", "及", "与",
        "哦", "啊", "呢", "吧", "吗", "哈", "哎", "哼", "嗨", "喂", "嗯", "一个",
        "一些", "一点", "一般", "一样", "怎么", "怎么样", "哪里", "什么", "多少"
    }
    DEFAULT_ALGORITHM = "cosine"
    PREPROCESS_CONFIG = {
        "lowercase": True,
        "remove_punctuation": True,
        "remove_stopwords": True,
        "split_granularity": "char"
    }
    
    
    # ===================== 文本处理工具函数 =====================
    def preprocess_text(text: str, config: dict = None) -> list:
        if text is None:
            text = ""
        config = config or PREPROCESS_CONFIG
        text = str(text).strip()
    
    
        if config.get("lowercase", True):
            text = text.lower()
        if config.get("remove_punctuation", True):
            text = re.sub(r"[^\u4e00-\u9fa5a-zA-Z0-9\s]", "", text)
        if config.get("split_granularity", "char") == "char":
            tokens = list(text)
        else:
            tokens = text.split()
        if config.get("remove_stopwords", True):
            tokens = [t for t in tokens if t and t not in DEFAULT_STOPWORDS]
        return tokens
    
    
    def cosine_similarity(vec1: list, vec2: list) -> float:
        if not vec1 or not vec2:
            return 0.0
        dot_product = sum(v1 * v2 for v1, v2 in zip(vec1, vec2))
        norm1 = math.sqrt(sum(v * v for v in vec1))
        norm2 = math.sqrt(sum(v * v for v in vec2))
        if norm1 == 0 or norm2 == 0:
            return 0.0
        return round(dot_product / (norm1 * norm2), 4)
    
    
    def jaccard_similarity(tokens1: list, tokens2: list) -> float:
        set1 = set(tokens1)
        set2 = set(tokens2)
        intersection = len(set1 & set2)
        union = len(set1 | set2)
        return round(intersection / union, 4) if union != 0 else 0.0
    
    
    def edit_distance_similarity(text1: str, text2: str) -> float:
        text1 = str(text1).strip() if text1 is not None else ""
        text2 = str(text2).strip() if text2 is not None else ""
        return round(difflib.SequenceMatcher(None, text1, text2).ratio(), 4)
    
    
    # ===================== 平台入口函数 =====================
    def main(args: dict) -> dict:
        """
        平台标准入口函数,函数名不可修改
        :param args: 输入参数字典,包含 text1、text2、algorithm
        :return: 输出参数字典,包含相似度计算结果
        """
        try:
            # 1. 获取输入参数
            text1 = str(args.get('text1', '')).strip()
            text2 = str(args.get('text2', '')).strip()
            algorithm = str(args.get('algorithm', DEFAULT_ALGORITHM)).strip().lower()
    
    
            # 2. 非空校验
            if not text1 or not text2:
                return {
                    "similarity": "0.0",
                    "status": "failed",
                    "used_algorithm": "",
                    "confidence": "0.0",
                    "error_msg": "text1 和 text2 不能为空,请检查输入参数"
                }
    
    
            # 3. 计算相似度
            if algorithm == "jaccard":
                tokens1 = preprocess_text(text1)
                tokens2 = preprocess_text(text2)
                similarity = jaccard_similarity(tokens1, tokens2)
                used_algorithm = "jaccard"
            elif algorithm == "edit_distance":
                similarity = edit_distance_similarity(text1, text2)
                used_algorithm = "edit_distance"
            else:
                tokens1 = preprocess_text(text1)
                tokens2 = preprocess_text(text2)
                vocab = {token: idx for idx, token in enumerate(set(tokens1 + tokens2))}
                vec1 = [tokens1.count(token) for token in vocab]
                vec2 = [tokens2.count(token) for token in vocab]
                similarity = cosine_similarity(vec1, vec2)
                used_algorithm = "cosine"
    
    
            # 4. 返回成功结果
            return {
                "similarity": str(similarity),
                "status": "success",
                "used_algorithm": used_algorithm,
                "confidence": str(similarity),
                "error_msg": ""
            }
    
    
        except Exception as e:
            # 5. 返回错误结果
            return {
                "similarity": "0.0",
                "status": "failed",
                "used_algorithm": "",
                "confidence": "0.0",
                "error_msg": f"计算失败:{str(e)}"
            }

  8. 设置函数的输入、输出参数。

    输入参数为两个待识别的文本,分别为text1、text2。

    输出参数在本次示例代码中,定义在body参数中,因此需要新增一个body参数。返回的JSON体会包含similarity(相似度数值)。

    图3 输入参数
    图4 输出参数

  9. 代码配置完成后,单击“确定”完成工具的创建。
  10. 在“工具列表”页面,单击“调试”按钮,输入参数值,单击“开始调测”检查调测结果。

    在本示例中,输入text1、text2文本后,返回的body体中已经包含similarity(相似度数值)
    图5 工具调试

  11. 调试成功后,工具状态随之变为“成功”,此时可单击右上角“发布”,发布插件。

    只有经过发布的插件可以给智能体使用。

示例2:网页HTML内容清洗插件

该插件的主要作用是解析和清洗网页HTML内容,该插件主要实现了以下功能。

  • 标签过滤:强制移除script(JS脚本),style (CSS样式),meta,iframe (广告/视频),svg等非文本标签。
  • 注释移除:删除HTML注释(往往包含无用信息)。
  • 安全机制:代码中有一个逻辑if len(tag.get_text()) < 200。只有当这些区域字数很少时才删除。防止误删了被错误标记为class="content-sidebar" 的正文长文。

由于不同的网页HTML内容与样式千差万别,本示例仅作为简单的功能演示使用。正式场景中,一般会对HTML网页样式订制专属的清洗策略。

网页HTML内容清洗插件创建步骤如下:

  1. 登录AgentArts智能体开发平台,在左侧导航栏“个人空间”区域,选择目标空间。
  2. 在左侧导航栏中选择“开发中心 > 组件库”,在“插件”页签,单击页面右上角“创建插件”。
  3. 选择“函数类型”类型的插件,然后根据以下步骤配置插件信息。

    表3 基本信息

    参数

    说明

    示例

    插件类型

    根据实现机制与运行形态的不同,插件分为“API类型”和“函数类型”两种形态。

    函数类型

    插件图标

    单击默认图标按钮,可上传本地图片作为插件的自定义图标。

    支持jpg、jpeg、png格式,不超过200KB。

    系统默认图标

    名称

    用于标识当前插件,在“组件库 > 插件”页面会展示该名称。

    命名规则:按照插件的实际功能命名,有助于Agent进行插件的精准识别和调度。

    命名要求:可以包含中文、英文、数字、下划线;

    长度限制:2~64个字符。

    网页HTML内容清洗

    描述

    描述当前插件的类型、功能和适用场景。

    需要按照插件的实际功能填写描述,有助于Agent进行插件的精准识别和调度。

    解析网页HTML源码,支持智能清洗并提取正文文本。它能自动过滤脚本、样式及广告噪音,将杂乱代码转换为结构化数据。

  4. 配置完单击“确定”。

    平台会自动跳转至工具信息页面,请参考后续步骤创建工具,在创建工具阶段会配置代码脚本、输入、输出参数等信息。

  5. 在“工具信息”页面,单击“创建工具”,在“添加工具”弹窗单击“新建函数”。

    图6 新建函数

  6. 填写函数名称与描述,执行语言选择“Python3.9”。

    表4 函数基本信息

    参数

    填写示例

    名称

    WebHtmlParser

    描述

    解析网页HTML源码,支持智能清洗并提取正文文本。它能自动过滤脚本、样式及广告噪音,将杂乱代码转换为结构化数据。

    执行语言

    Python3.9

  7. 单击“编辑源码”,复制如下代码脚本。

    图7 编辑源码

    本示例中会使用Python的beautifulsoup4依赖包,打包上传方法请参见示例3:创建Python依赖包

    # -*- coding:utf-8 -*-
    import json
    import re
    # 依赖包:beautifulsoup4 (需打包上传)
    from bs4 import BeautifulSoup, Comment
    
    
    # ===================== 业务逻辑工具函数 =====================
    def clean_text(soup):
        """
        深度清洗 HTML,提取纯净文本
        """
        for tag in soup(["script", "style", "meta", "head", "input", "iframe", "noscript", "svg", "link"]):
            tag.extract()
    
    
        for comment in soup.find_all(text=lambda text: isinstance(text, Comment)):
            comment.extract()
    
    
        for tag in soup.find_all(class_=re.compile(r'(nav|footer|header|sidebar|menu|copyright)', re.I)):
            if len(tag.get_text()) < 200:
                tag.extract()
    
    
        text = soup.get_text(separator='\n')
    
    
        lines = []
        for line in text.splitlines():
            clean_line = line.strip()
            if clean_line:
                lines.append(clean_line)
    
    
        return '\n'.join(lines)
    
    
    def extract_links(soup, base_url=""):
        links = []
        seen = set()
        for a in soup.find_all('a', href=True):
            href = a['href'].strip()
            text = a.get_text(strip=True)
            if not href or href.startswith(('javascript:', '#', 'mailto:', 'tel:')):
                continue
            if base_url and not href.startswith(('http', '//')):
                base_url = base_url.rstrip('/')
                if href.startswith('/'):
                    href = base_url + href
                else:
                    href = base_url + '/' + href
    
    
            key = (text, href)
            if text and key not in seen:
                links.append({"text": text, "url": href})
                seen.add(key)
        return links
    
    
    def extract_images(soup, base_url=""):
        images = []
        seen = set()
        for img in soup.find_all('img', src=True):
            src = img['src'].strip()
            alt = img.get('alt', '').strip()
            if base_url and src and not src.startswith(('http', '//', 'data:')):
                base_url = base_url.rstrip('/')
                if src.startswith('/'):
                    src = base_url + src
                else:
                    src = base_url + '/' + src
    
    
            if src and src not in seen:
                images.append({"alt": alt, "src": src})
                seen.add(src)
        return images
    
    
    # ===================== 平台入口函数 =====================
    def main(args: dict) -> dict:
        """
        HTML 内容解析插件入口函数
        :param args: 输入参数字典,包含 content、mode、base_url
        :return: 输出参数字典,包含解析结果
        """
        try:
            # 1. 直接从 args 获取输入参数
            html_content = str(args.get('content', '') or args.get('html', '')).strip()
            mode = str(args.get('mode', 'text')).strip().lower()
            base_url = str(args.get('base_url', '')).strip()
    
    
            # 2. 非空校验
            if not html_content:
                return {
                    "status": "failed",
                    "mode": mode,
                    "result": {},
                    "error_msg": "未检测到 content 参数,请检查输入"
                }
    
    
            # 3. 业务处理
            soup = BeautifulSoup(html_content, 'html.parser')
            data = {}
    
    
            if mode == "links":
                data["links"] = extract_links(soup, base_url)
                data["count"] = len(data["links"])
            elif mode == "images":
                data["images"] = extract_images(soup, base_url)
                data["count"] = len(data["images"])
            elif mode == "summary":
                title = soup.title.string if soup.title else ""
                desc = ""
                meta = soup.find('meta', attrs={'name': 'description'}) or soup.find('meta', attrs={'property': 'og:description'})
                if meta:
                    desc = meta.get('content', '')
                full_text = clean_text(soup)
                data["title"] = title.strip()
                data["description"] = desc.strip()
                data["summary_text"] = full_text[:800] + "..." if len(full_text) > 800 else full_text
            else:
                cleaned = clean_text(soup)
                data["cleaned_text"] = cleaned
                data["length"] = len(cleaned)
    
    
            # 4. 直接返回字典
            return {
                "status": "success",
                "mode": mode,
                "result": data,
                "error_msg": ""
            }
    
    
        except Exception as e:
            return {
                "status": "failed",
                "mode": "",
                "result": {},
                "error_msg": f"处理失败:{str(e)}"
            }

  8. 设置函数的输入、输出参数。

    输入参数为content,类型为string,表示待提取的网页文本。

    输出参数在本次示例代码中,定义在body参数中,因此需要新增一个body参数。返回的JSON体会包含清洗后的内容。

    图8 输入参数
    图9 输出参数

  9. 添加Python依赖包,本示例中会使用Python的beautifulsoup4依赖包,打包上传方法请参见示例3:创建Python依赖包

    图10 添加依赖包

  10. 将获取的依赖包上传至平台后,单击“确定”完成工具的创建。

示例3:创建Python依赖包

除了Python3.9、Node.js14.18本身自带的标准库外,其余依赖包均需要手动上传。

本小节结合示例2:网页HTML内容清洗插件作为演示,介绍制作Python的beautifulsoup4依赖包。

  1. 准备一台Huawei Cloud EulerOS 2.0环境的服务器。

    制作函数依赖包推荐在Huawei Cloud EulerOS 2.0环境中进行。 使用其他系统打包可能会因为底层依赖库的原因,运行出问题,比如找不到动态链接库。

    本示例中创建一台EulerOS镜像的弹性云服务器进行后续操作的演示(创建一台按需计费、最低规格1u1g、EulerOS镜像的服务器,使用完成即可删除释放)。

  2. 创建完成后,远程登录至该服务器(可使用弹性云服务器默认的CloudShell方式登录)。
  3. 依次执行以下命令,下载Python的beautifulsoup4依赖包,并将其压缩为zip包。

    # 1. 创建临时目录,用于存放beautifulsoup4依赖包,该依赖包缩写为bs4,创建相同名称的目录
    mkdir -p /tmp/bs4
    # 2. 安装依赖(自动包含soupsieve)
    pip install beautifulsoup4 --root /tmp/bs4
    # 进入临时目录
    cd /tmp/bs4
    # 查找 site-packages 路径(Linux 下通用命令)
    find . -name "site-packages"
    # 示例输出:./usr/local/lib/python3.9/site-packages
    # 进入找到的 site-packages 目录(替换为上面步骤中查询的实际路径)
    cd ./usr/local/lib/python3.9/site-packages
    # -r:递归打包(包含 bs4、soupsieve 等所有文件);-q:静默模式
    # 将包生成到 /tmp 目录,方便后续下载
    zip -rq /tmp/bs4.zip *
    

  4. 打包完成后即可在tmp路径下查询到bs4.zip文件,下载该依赖包。

    图11 下载依赖包

  5. 返回插件的“添加工具”页面,单击“添加依赖包”。选择“私有依赖包”,按照页面提示前往FunctionGraph创建依赖包。

    图12 添加依赖包

  6. 在FunctionGraph页面,单击“创建依赖包”。在创建依赖包页面填写依赖包名称、选择运行时为Python 3.9,并选择ZIP上传方式。

    插件支持Python3.9、Node.js14.18版本的代码,因此运行时也需要选择对应的版本。ZIP上传方式较为便捷,推荐使用。创建依赖包后会自动生成对应的版本号。

    图13 创建依赖包

  7. 返回插件的“添加工具”页面,选择所需的依赖包。

    图14 添加依赖包

Python编码规范

本小节主要说明平台支持的Python函数的结构、参数定义及开发规范。开发者需基于此模板编写业务逻辑,实现插件的具体功能。

  • 简单场景代码示例:

    示例代码:

    def main(args: dict) -> dict:
        """
        运行代码节点会调用此函数,请勿对下面的函数名做修改
        :param args: 输入固定为args字典类型,kv为输入参数键值对
        :return: 输出参数为字典类型,kv为输出参数键值对
        """
        ret = {
            "key0": args.get('input', 'default'),
            "key1": "hi"
        }
        return ret

    通过固定的main函数触发代码执行,输入参数 args 是一个字典(dict),包含在界面上配置的所有输入参数,通过args.get('参数名', '默认值')读取。返回值必须与界面上配置的输出参数名称完全一致。

  • 复杂场景代码示例:

    示例代码:

    # -*- coding:utf-8 -*-
    import json
    import base64
    """
    公共函数使用方法示例
    import common
    headers = {}
    body = ""
    data = common.httpRequest("http://localhost:3300/test", headers, body, "POST")
    if data.get("code") < 300:
        return data.get("body")
    return "error: " + data.get("error")
    接口返回res = {"headers": {},
                  "body": string,
                  "code": number,
                  "error": string}
    """
    """"
    mssiAuthData参数样例
    {
         "header":{}, // 连接器认证header参数
         "path": {}, // 连接器认证path参数
         "query":{}, // 连接器认证query参数
         "body":{}, // 连接器认证body参数
         "host":"https://demo.com // API主机地址
    }
    """
    def extractRequestParam(rawValue, encoded, defaultValue):
        if encoded and rawValue:
            rawValue = str(base64.b64decode(rawValue), "utf-8")
        return json.loads(rawValue) if rawValue else defaultValue
    ## 请勿对下面的函数名做修改
    def handler(event, context):
        """
        函数是方法的入口
        :param event: 执行事件(event), 包含用户定义的函数参数以及所选择的的连接器认证相关参数
        :param context: Runtime提供的函数执行上下文
        :return:
        """
        isBase64Encoded = event.get('isBase64Encoded', False)
        inputData = extractRequestParam(event.get('body'), isBase64Encoded, {})  # 用户定义的函数参数数据
        mssiAuthData = extractRequestParam(event.get('mssiAuthData'), isBase64Encoded, {})  # 连接器认证数据
        mssiAuthData["securityToken"] = context.getToken()
        dataExtendConfig = extractRequestParam(event.get('dataExtendConfig'), isBase64Encoded, {})  # 流步骤扩展参数
        result = {}
        return json.dumps(result)

    代码主要包含三个部分:

    • 公共库引用说明:代码顶部的注释展示了如何使用平台内置的common库发起HTTP请求。
    • 辅助工具函数:extractRequestParam用于处理参数的解包与格式转换。
    • 主入口函数:handler(event, context)是插件执行的核心,包含业务逻辑。

    主入口函数:

    def handler(event, context):
        # ...
    • 约束:请勿修改函数名handler。平台通过此名称定位并执行函数。
    • 参数:
      • event (Dict):包含本次调用的所有输入数据。
      • context (Object):运行时上下文对象,提供系统级能力。

    输入参数:

    event对象中包含了经过Base64编码的原始数据。模板代码通过extractRequestParam函数自动完成了解码和JSON反序列化,开发者可直接使用以下变量:

    表5 变量说明

    变量名

    含义

    用途

    inputData

    用户业务参数

    对应插件定义中用户填写的入参(如查询关键词、日期等)。

    mssiAuthData

    连接器鉴权数据

    包含调用第三方API所需的host,header等鉴权信息(由平台连接器配置自动注入)。

    dataExtendConfig

    扩展配置

    流程步骤中的高级配置参数(通常用于低代码编排场景)。

    代码示例
    # 获取用户输入的 "city" 参数
    city_name = inputData.get("city", "city_name")
    
    # 获取连接器配置的主机地址
    api_host = mssiAuthData.get("host")

    上下文与安全凭证:

    context提供与运行环境交互的能力。

    context.getToken():获取当前执行环境的安全令牌(Security Token)。

    用法:模板代码已自动将Token注入到mssiAuthData["securityToken"]中,通常用于身份验证。

    发起网络请求:

    平台预置了common模块用于处理网络请求。请勿使用Python原生requests库,建议使用common.httpRequest以确保兼容性和安全性。

    入参:

    • url (str):请求完整地址。
    • headers (dict):请求头。
    • body (str/json):请求体。
    • method (str):请求方法("GET", "POST", etc.)。

    返回值(data) 结构:

    {
        "code": 200,          # HTTP 状态码
        "body": "...",        # 响应体字符串
        "headers": {...},     # 响应头
        "error": "..."        # 错误信息(如有)
    }

    返回值规范:

    函数最终必须返回一个JSON格式的字符串。

    代码示例
    result = {
        "status": "success",
        "message": "查询成功",
        "data": { "temperature": 25 }
    }
    return json.dumps(result, ensure_ascii=False)

Node.js编码规范

本小节主要说明平台支持的Node.js函数的结构、参数定义及开发规范。开发者需基于此模板编写业务逻辑,实现插件的具体功能。

  • 简单场景代码示例:
    示例代码:
    /**
     * 运行代码节点会调用此函数,请勿对下面的函数名做修改
     * @param {Object} args - 输入固定为args对象类型,kv为输入参数键值对
     * @returns {Promise<Object>} 输出参数为Promise包裹的对象类型,kv为输出参数键值对
       */
       exports.main = async (args) => {
       const ret = {
           "key0": args?.input ?? 'default',
           "key1": "hi"
       };
       return ret;
       }

    平台通过固定的exports.main异步函数触发代码执行。输入参数args是一个对象(Object),包含在界面上配置的所有输入参数,通过可选链操作符?.和空值合并操作符??读取(如args?.input ?? 'default')。返回值必须与界面上配置的输出参数名称完全一致。

  • 复杂场景代码示例:
    示例代码:
    /**
     * common是平台提供的公共函数,包括方法有post和get请求
     *
     * const common = require("./common.js");
     * const headers = {};
     * const body = "";
     * 示例1:异步调用
     * common.httpRequest("http://localhost:8080/test", headers, body, "POST").then((data) => {
     *      if(data.code < 300){
     *         return data.body;
     *      }
     *      return {};
     * });
     *
     * 示例2:同步调用
     * const data = await common.httpRequest("http://localhost:8080/test", headers, body, "POST");
     * if(data.code < 300){
     *     return data.body;
     * }
     * return {};
     * 接口返回 data = {
     *                "headers": {},
     *               "body": string,
     *               "code": number,
     *               "error": string
     *               }
     */
    /**
     *
     * mssiAuthData参数样例
     * {
     *      "header":{}, // 连接器认证header参数
     *      "path": {}, // 连接器认证path参数
     *      "query":{}, // 连接器认证query参数
     *      "body":{}, // 连接器认证body参数
     *      "host":"https://demo.com // API主机地址
     * }
     *
     */
    function extractEventData(event, name) {
        let data = event[name]
        if (event.isBase64Encoded && data) {
            data = new Buffer(data, 'base64').toString()
        }
        return data ? JSON.parse(data) : {}
    }
    /**
     * 函数是方法的入口
     * @param {*} event  执行事件(event), 包含用户定义的函数参数以及所选择的的连接器认证相关参数
     * @param {*} context  Runtime提供的函数执行上下文
     * @returns
     */
    exports.handler = async function (event, context) {
        const inputData = extractEventData(event, 'body') // 用户定义的函数参数数据
        const mssiAuthData = extractEventData(event, 'mssiAuthData') // 连接器认证数据
        mssiAuthData.securityToken = context.getToken()
        const dataExtendConfig = extractEventData(event, 'dataExtendConfig')  // 流步骤扩展参数
        let result = "{}";
        return result;
    }

    代码采用CommonJS规范,主要包含以下部分:

    • 依赖引入:通过require("./common.js") 引入平台内置的HTTP请求库。
    • 辅助工具:extractEventData函数用于自动处理Base64解码与JSON反序列化,开发者通常无需修改此函数。
    • 主入口:exports.handler是异步函数入口,承载核心业务逻辑。

    主入口函数:

    exports.handler = async function (event, context) {
        // 业务逻辑区域
    }
    • 约束:必须保留exports.handler命名。
    • 特性:函数被定义为async,您可以在函数体内使用await语法来处理异步操作(如网络请求)。

    输入参数:

    代码模板通过extractEventData帮助您从event中提取并格式化了以下关键对象,您可以直接在handler中使用:

    表6 变量说明

    变量名

    类型

    含义

    用途

    inputData

    Object

    用户业务参数

    对应插件定义中用户填写的入参。

    mssiAuthData

    Object

    连接器鉴权数据

    包含调用第三方API所需的host, header, query等鉴权配置信息。

    dataExtendConfig

    Object

    扩展配置

    流程编排中的高级配置参数。

    代码示例
    // 获取用户输入的参数 "keyword"
    const keyword = inputData.keyword || "default";
    
    // 获取连接器配置的主机地址
    const apiHost = mssiAuthData.host;

    上下文与安全凭证

    context对象提供运行时的系统能力。

    • context.getToken():获取当前执行环境的安全令牌(Security Token)。
    • 自动注入:模板代码已执行mssiAuthData.securityToken = context.getToken(),将令牌自动合并到鉴权数据中,方便后续调用使用。

    发起网络请求:

    平台提供了common模块用于发送HTTP请求。为了代码的可读性和维护性,强烈建议使用await方式(同步写法)进行调用。

    接口定义
    const common = require("./common.js");
    // ...
    const response = await common.httpRequest(url, headers, body, method);
    响应结构
    {
        "code": 200,          // HTTP 状态码 (Number)
        "body": "...",        // 响应体 (String),通常需要 JSON.parse 解析
        "headers": {},        // 响应头 (Object)
        "error": "..."        // 错误描述 (String)
    }

相关文档