使用coze开发一个阿里云主机维护的智能体

image

 

image

 

在 Coze 平台创建阿里云运维智能体,核心是通过自然语言处理触发工作流,进而调用插件执行阿里云实例的真实操作。结合控制台界面,整体的创建流程与具体操作步骤如下:

一、 创建智能体与基础配置

  1. 进入平台并创建:登录 Coze 平台(coze.cn),进入空间(如 space/738212...),点击创建智能体(Bot)。
  2. 配置模型:在中间的“编排”面板,进入“模型设置”,选择大模型(如截图中选择的“豆包 1.5 Pro 32k”)。
  3. 编写人设与逻辑:在左侧“人设与回复逻辑”面板,定义智能体的角色和规则。
    • 角色设定:设定为“阿里云运维智能体”。
    • 技能配置:编写技能提示词,要求模型判断用户输入。若为非操作行为则引导,若为操作实例行为(如关机)则直接运行指定插件或工作流(如 aming_aliyun_ops)。
    • 限制条件:限制仅处理阿里云实例相关话题,拒绝无关内容。

二、 配置知识库与记忆(可选)

在中间“编排”面板向下滚动至“知识”和“记忆”区域:

  • 知识库:可添加阿里云 API 文档到“文本”知识库,或配置“表格/照片”,开启“自动调用”辅助模型理解。
  • 记忆变量:配置变量用于保存用户特征或常用的实例 ID,使交互更个性化。

三、 创建工作流(核心步骤)

在“编排”面板点击“工作流”旁的 + 号,创建并命名工作流(如 aming_aliyun_ops)。进入全屏工作流画布,按以下逻辑编排节点:

  1. 开始节点:
    • 配置输入变量(如 input),用于接收用户的原始自然语言指令。
  2. 大模型参数提取节点(并行配置):
    • 添加两个大模型节点(如“大模型”和“大模型_1”)。
    • 输入:均绑定开始节点的 input。
    • 输出与模型:分别配置输出变量为 instanceid(实例ID)和 action(操作动作),模型同样选择豆包 1.5 Pro 32k。
  3. 插件调用节点:
    • 添加插件节点(如 manager_instance)。
    • 输入映射:将上游大模型提取的 instanceid 和 action 映射到插件的输入参数中,同时填入阿里云的 access_key_id 和 access_key_secret。
    • 输出:插件节点会自动生成返回字段,如 request_id、success、error、message。
  4. 结束节点:
    • 配置输出变量,绑定插件节点的输出(如 success、error、message)。
    • 输出类型选择“返回文本”,将插件执行结果透传给智能体。

四、 绑定技能与发布

  1. 绑定工作流/插件:回到智能体编排主界面,在“技能”->“工作流”下确认已添加并启用该工作流(或在提示词中直接指定调用对应插件)。
  2. 预览与调试:
    • 在右侧“预览与调试”面板,输入测试指令(如“帮我关闭实例 i-n4a45z6713j1evi3tau0”)。
    • 观察调试信息:确认模型是否正确解析意图、工作流是否被正确触发、插件是否返回了请求 ID(如截图中的 652E4500-6BAA...)。
  3. 修复与优化:根据调试结果(如字段显示为空等异常),回头调整结束节点的变量映射、大模型节点的 JSON 输出格式或优化人设提示词。
  4. 发布智能体:调试无误后,点击右上角的“发布”按钮,使智能体生效供用户使用。

💡 补充注意事项

  • 权限配置:使用阿里云操作插件前,需确保提供的 AccessKey 具备对应的 ECS 操作权限(如 ecs:StopInstance)。
  • 参数提取稳定性:在工作流的大模型节点中,建议在提示词里强制要求模型以严格 JSON 格式输出提取的参数,避免因自然语言冗余导致下游插件接收参数失败。 

在 Coze 里,插件是“能力/工具”,工作流是“调用这些工具的流程图”。两者不是替代关系,而是“零件+装配线”的关系:插件负责真正打外部 API,工作流负责决定什么时候打、传什么参数、拿到结果后怎么处理。

一、整体关联模型

  • 插件(Plugin)=工具集合,每个工具是一个可调用 API(如阿里云 ECS 关机、天气查询、网页解析)。插件自己定义输入参数、输出字段、鉴权方式,平台不让在工作流里改它的结构。
  • 工作流(Workflow)=低代码节点画布。可以在画布里放“插件节点”,把一个插件的某个工具当成一步来跑;也可以放大模型节点、代码节点、选择器/条件、子工作流等,把多个插件串起来。
  • 智能体(Bot)=入口。智能体可以直接挂插件,也可以挂工作流;命中工作流后再由工作流内部调插件。

简单对应你前面阿里云那个例子:

开始(用户自然语言)→ 大模型节点(抽 instanceid/action)→ 插件节点(manager_instance/关机工具)→ 结束(透传 success、error、request_id)。

二、两种“关联”方式,行为完全不同

1. 智能体直接挂插件(LLM 自主调用)

  • 在智能体编排页“插件”区添加,模型根据人设+用户 Query 自动判断是否调用。
  • 参数由模型从对话里抽:比如“关 i-xxx”→模型抽 instanceid、action=stop;缺必填项会主动追问。
  • 优点:省事、适合单点能力(查天气、搜网页、翻译)。
  • 缺点:非确定性,参数提取不稳,多步/强格式场景容易跑偏。一次对话单次插件调用限制更明显,多插件串联要用工作流。

2. 工作流里放插件节点(引擎确定性调用)

  • 工作流画布“添加节点→插件”,选插件和具体工具。
  • 必填入参手动映射:可填固定值,或引用上游节点输出(开始变量、大模型输出、代码节点输出等)。
  • 插件输出按工具定义来,后续节点直接引用;可在插件节点输出区“查看示例”确认字段名。
  • 异常配置若设“返回设定内容/执行异常流程”,节点会额外给 isSuccess、errorBody,方便后面判断分支。
  • 优点:参数可控、步骤固定、可加条件/重试/格式化,适合“关机/重启/批量运维”这类任务。

你之前遇到“操作是否成功/错误信息为空”,本质就是工作流结束节点没把插件真实输出字段映射出来,或者插件异常分支没接住——属于第 2 种关联下的映射问题。

三、参数怎么从工作流流到插件再回来

  1. 开始节点定义变量(如 input)。
  2. 大模型/代码节点产出结构化参数(如 instanceid、action),输出变量名自己定。
  3. 插件节点→选工具→入参绑定:
    • instanceid ← 大模型节点.instanceid
    • action ← 大模型节点.action
    • AK/SK 可固定值,也可从开始/变量/资源库注入(别写死在前端提示词里)。
  4. 插件运行后输出(如 success、message、request_id、error),在下游引用。
  5. 结束节点把插件输出拼成文本,或走选择器:success=true 回“已关机+request_id”,false 回“失败+error”。

插件节点输入/输出结构按工具定义走,不能自己加字段;要做二次加工就用代码节点或大模型的下一节点。

四、工作流里还能怎么和插件组合

  • 大模型节点→插件:先抽取参数再调 API(你阿里云场景标准做法)。
  • 插件→大模型节点:先调插件拿原始数据,再让模型总结(如拉日志→总结)。
  • 插件→选择器→不同插件:按结果分支调不同工具(如检测实例状态=running 才关机,否则回提示)。
  • 工作流节点嵌套工作流:把“阿里云关机”封装成子工作流,主工作流按“工单审核→关机→通知”调用。
  • 大模型节点内部挂技能:大模型节点也能挂插件/工作流/知识库,等于在流程某一步再嵌一个自动调用子智能体。

五、怎么选(直接结论)

  • 单点、参数都在用户一句话里、不强求格式 → 智能体直接挂插件。
  • 要抽参→调 API→判断成功/失败→固定回执、批量、带审批/条件 → 放工作流,插件当节点用。
  • 阿里云运维这种“口头指令转真实资源操作”必须用工作流:参数提取用大模型节点、执行用插件节点、回传用结束节点,别让模型自由调插件,避免误关机或字段丢失。

如果你愿意,可以把 manager_instance 插件的入参/出参字段贴出来,我按“开始变量→大模型 JSON 输出→插件映射→结束回传”直接给一套字段对照。

image

 

image

 

image

 

image

 

在 Coze 平台通过 IDE 创建阿里云自定义插件,并将大模型智能体与该插件联动的完整流程及具体操作步骤如下:

一、 资源库新建插件(基础配置)

  1. 进入资源库:登录 Coze 平台,在左侧导航栏点击“资源库”。
  2. 新建插件:点击页面右上角的“+ 资源”或“新建”,选择“插件”。
  3. 填写基本信息:
    • 插件名称:输入清晰易懂的名称(如 aming_aliyun),便于大模型搜索和调用。
    • 插件描述:详细说明插件的主要功能和使用场景(如“阿里云的api插件”)。
    • 插件工具创建方式:选择“云侧插件 - 在 Coze IDE 中创建”(即字幕中提到的“选第二个 云侧插件”)。
    • IDE 运行时:选择 Python3。
  4. 确认创建:点击“确认”,系统会自动跳转进入 Coze IDE 集成开发环境。

二、 Coze IDE 插件开发(核心编码)

进入 IDE 后,开始具体工具(Tool)的开发(以截图中的 get_instance 为例):

  1. 创建工具:
    • 在 IDE 左侧工具列表区域,点击“+”号添加新工具。
    • 填写工具名称(如 get_instance)和工具介绍(如“查询实例信息”),名称建议采用蛇形命名法。
  2. 安装依赖包:
    • 在 IDE 左侧的“依赖包”面板点击“+”号。
    • 搜索并安装代码所需的三方库。截图中安装了阿里云官方 SDK(如 aliyun-python-sdk-ecs、alibabacloud-ecs201405 等)。
    • 注意:安装完成后需点击面板顶部的“刷新”按钮,让 IDE 识别新依赖。
  3. 编写业务逻辑代码:
    • 点击“代码”标签页进入编辑器。
    • Coze IDE 默认提供了一个代码模板,核心要求是必须导出名为 handler 的函数。
    • 参数获取:通过 args.input.xxx 获取传入的参数(如截图中获取的 region_id)。
    • 日志记录:通过 args.logger.info/error() 打印日志,便于调试。
    • 外部调用:导入阿里云 SDK 客户端,组装请求(如 DescribeInstancesRequest)并调用 API。
    • 结构化返回:return 返回一个字典。截图中规范地返回了 instances(数据)、success(布尔值)和 error(错误信息)字段,并对服务异常(ServerException)和参数异常(ClientException)做了捕获处理。
  4. 配置元数据(Metadata):
    • 点击“元数据”标签页。
    • 输入参数:添加代码中需要用到的参数(如 region_id),类型选字符串。参数名必须与代码中 args.input.xxx 的 xxx 完全一致。
    • 输出参数:添加代码中 return 返回的字段(如 instances、success、error),类型和名称需严格对应。
    • 依赖关联:在元数据页面向下滑动到“依赖配置”,勾选刚才安装的阿里云 SDK 依赖,点击保存。

三、 测试与发布

  1. 测试代码:在 IDE 右侧或上方的测试面板中,模拟输入测试数据(如 {"region_id": "cn-hangzhou"}),点击“运行”。观察输出结果是否符合预期,并检查日志。
  2. 发布插件:测试通过后,点击页面右上角的“发布”按钮。发布后插件状态会变为“已上线/已发布”,此时它才可以被智能体或工作流调用。

四、 关联智能体与工作流(联动使用)

发布插件后,回到之前配置的智能体(aming_aliyun_ops)中:

  1. 绑定插件/工作流:在智能体编排页面的“技能”->“工作流”或“插件”区域,添加刚刚发布的 aming_aliyun 插件(或其包含的工作流)。
  2. 更新提示词:在人设与回复逻辑中,明确指示大模型:“如果是操作阿里云实例的行为,直接运行插件/工作流 aming_aliyun_ops”。
  3. 预览调试:在右侧调试窗口输入“帮我关闭实例 i-xxx”,大模型会提取参数,触发工作流,工作流中的插件节点会执行真实的阿里云关机 API,并返回请求 ID。

💡 开发避坑提示:

  • 元数据一致性:元数据里定义的输入输出参数名,必须与 Python 代码里 args.input 获取的名字以及 return 字典里的 key 完全一致(大小写敏感),否则会报错。
  • 依赖刷新与关联:安装依赖后必须刷新,并且要在元数据中勾选关联该依赖,否则运行时会提示“找不到模块”。
  • Handler 函数:切勿删除或修改模板自带的 handler 函数入口,这是 Coze 识别工具执行的唯一入口。 

这段代码是 Coze 云侧插件(IDE 插件)​ 中用于 查询阿里云 ECS 实例列表​ 的工具函数,本质是一个 “阿里云 ECS 查询接口 → Coze 工具”的适配器。

下面我按 执行流程 + 关键代码逐行解释 + 在 Coze 中的作用​ 给你讲清楚。


一、这段代码是干什么的?(一句话版)

这段代码让 Coze 智能体通过调用阿里云 ECS OpenAPI,查询指定地域下的所有云服务器实例,并把结果以结构化 JSON 返回给工作流。


二、整体执行流程(逻辑链路)

用户/工作流
  ↓(输入 region_id、AK、SK)
Coze 插件 handler()
  ↓
初始化 AcsClient(阿里云 SDK 客户端)
  ↓
构造 DescribeInstancesRequest
  ↓
调用阿里云 ECS API
  ↓
解析 JSON 响应
  ↓
返回 instances / success / error

三、逐段代码详解

1️⃣ 导入依赖(SDK + Coze 运行时)

from runtime import Args
from typings.get_instance.get_instance import Input, Output
from aliyunsdkcore.client import AcsClient
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkcore.acs_exception.exceptions import ServerException, ClientException
import json
 

模块

作用

runtime.Args

Coze 插件运行时参数容器

Input / Output

插件元数据中声明的输入/输出结构

AcsClient

阿里云 Python SDK 的核心客户端

DescribeInstancesRequest

ECS 查询实例列表的 API 请求对象

ServerException / ClientException

阿里云服务端/客户端异常

json

解析阿里云返回的 JSON

✅ 这是标准阿里云老版 SDK + Coze 插件模板写法


2️⃣ 插件入口函数 handler

def handler(args: Args[Input]) -> Output:

这是 Coze 插件强制要求的入口函数名。

  • args.input:工作流/智能体传入的参数
  • args.logger:Coze 注入的日志对象
  • Input / Output:与 插件元数据(Metadata)​ 强绑定

📌 LLM 能否正确调用这个工具,完全依赖 Metadata 中的 input/output 定义


3️⃣ 获取输入参数

region_id = args.input.region_id
access_key_id = args.input.access_key_id
access_key_secret = args.input.access_key_secret

从 Coze 工作流中读取:

 

参数

含义

region_id

阿里云地域(如 cn-hangzhou)

access_key_id

RAM 账号 AK

access_key_secret

RAM 账号 SK

🚨 安全警告:

生产环境 不应该​ 让工作流直接传 AK/SK,应由插件内部从环境变量读取。


4️⃣ 记录日志

args.logger.info(f"Querying ECS instances in region: {region_id}")
  • 日志会出现在 Coze 插件调试面板
  • 用于排查:是否真的调用了插件、region 是否正确

5️⃣ 初始化阿里云客户端

client = AcsClient(
    access_key_id,
    access_key_secret,
    region_id
)

这一步等价于:

export ALIYUN_ACCESS_KEY_ID=xxx
export ALIYUN_ACCESS_KEY_SECRET=xxx
aliyun ecs DescribeInstances --region cn-hangzhou

AcsClient 负责:

  • 签名
  • HTTPS 请求
  • 鉴权

6️⃣ 构造 API 请求

request = DescribeInstancesRequest()
request.set_accept_format('json')
  • 使用的是 ECS 2014-05-26 旧版 API
  • 对应阿里云官方接口:
    👉 DescribeInstances

set_accept_format('json') 表示:

✅ 返回结果是 JSON,而不是 XML


7️⃣ 发送请求并解析响应

response = client.do_action_with_exception(request)
response_str = response.decode('utf-8')
response_data = json.loads(response_str)

执行顺序:

  1. do_action_with_exception 发送 HTTPS 请求
  2. 返回的是 bytes
  3. 转成字符串
  4. 解析成 Python dict

8️⃣ 提取实例列表

instances = response_data.get('Instances', {}).get('Instance', [])

阿里云返回的 JSON 结构类似:

{
  "Instances": {
    "Instance": [
      {
        "InstanceId": "i-xxx",
        "Status": "Running",
        "RegionId": "cn-hangzhou"
      }
    ]
  }
}

✅ 这里把真正的实例数组提取出来,方便工作流使用。


9️⃣ 返回成功结果(Coze 标准输出)

return {
    "instances": instances,
    "success": True,
    "error": None
}

这个返回值 必须和 Metadata 中的 Output 字段完全一致,否则 Coze 工作流会报错。


🔟 异常处理(非常关键)

阿里云服务端错误

except ServerException as e:

例如:

  • AK 无权限
  • 实例不存在
  • 余额不足

客户端参数错误

except ClientException as e:

例如:

  • region 写错
  • 参数缺失

兜底异常

except Exception as e:

防止插件崩溃,保证 Coze 工作流始终能拿到返回结果。


四、在 Coze 工作流中是怎么用的?

工作流节点示例

  1. 开始节点
    • 用户输入:查一下杭州的 ECS
  2. 大模型参数提取
    • 提取:region_id = cn-hangzhou
  3. 插件节点
    • 调用 get_instance
    • 传入:
      • region_id
      • access_key_id
      • access_key_secret
  4. 代码 / 结束节点
    • 使用:
      instances = 插件节点.instances
      success = 插件节点.success
      error = 插件节点.error

五、这段代码在“Ansible + Coze”体系里的定位

结合你前面的问题,它的角色是:

Coze 智能体
  ↓
插件 get_instance
  ↓
阿里云 ECS API
  ↓
拿到实例列表
  ↓
传给 Ansible / Flask API
  ↓
真正执行运维操作

✅ 它是“发现资产”的第一步​

✅ Ansible 是“执行操作”的第二步


六、生产环境优化建议(重要)

  1. AK/SK 不要从工作流传入
    access_key_id = os.getenv("ALIYUN_AK_ID")
    access_key_secret = os.getenv("ALIYUN_AK_SECRET")
  2. 分页支持
    • DescribeInstances 默认只返回 10 条
    • 需要 PageSize + PageNumber
  3. 只返回必要字段
    • 减少 token 消耗(InstanceId、Status、IP)
  4. 返回 request_id
    • 方便阿里云工单排查

七、一句话总结

这段代码是 Coze 插件里一个标准的“阿里云 ECS 实例查询工具”,负责把自然语言请求翻译成阿里云 API 调用,并把结果结构化返回给智能体工作流。

如果你愿意,我可以下一步帮你:

  • ✅ 改成 分页查询
  • ✅ 改成 只返回实例 ID + 状态
  • ✅ 和 Ansible Flask API​ 串联成一个完整运维工作流
  • ✅ 改成 环境变量 AK/SK 的安全版本

from runtime import Args
from typings.get_instance.get_instance import Input, Output
from aliyunsdkcore.client import AcsClient
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkcore.acs_exception.exceptions import ServerException, ClientException
import json

"""
Each file needs to export a function named `handler`. This function is the entrance to the Tool.
Parameters:
args: parameters of the entry function.
args.input - input parameters, you can get test input value by args.input.xxx.
args.logger - logger instance used to print logs, injected by runtime.
Remember to fill in input/output in Metadata, it helps LLM to recognize and use tool.
Return:
The return data of the function, which should match the declared output parameters.
"""

def handler(args: Args[Input]) -> Output:
    # 获取输入参数
    region_id = args.input.region_id
    access_key_id = args.input.access_key_id
    access_key_secret = args.input.access_key_secret
    
    # 记录日志
    args.logger.info(f"Querying ECS instances in region: {region_id}")
    
    try:
        # 初始化阿里云客户端
        client = AcsClient(
            access_key_id,
            access_key_secret,
            region_id
        )
        
        # 创建请求
        request = DescribeInstancesRequest()
        request.set_accept_format('json')
        
        # 发送请求
        response = client.do_action_with_exception(request)
        response_str = response.decode('utf-8')
        
        # 解析响应
        response_data = json.loads(response_str)
        instances = response_data.get('Instances', {}).get('Instance', [])
        
        # 记录成功日志
        args.logger.info(f"Successfully retrieved {len(instances)} instances")
        
        # 返回结果
        return {
            "instances": instances,
            "success": True,
            "error": None
        }
        
    except ServerException as e:
        error_msg = f"阿里云服务错误: {e.get_error_msg()} (错误码: {e.get_error_code()})"
        args.logger.error(error_msg)
        return {
            "instances": [],
            "success": False,
            "error": error_msg
        }
        
    except ClientException as e:
        error_msg = f"请求参数错误: {e.get_error_msg()} (错误码: {e.get_error_code()})"
        args.logger.error(error_msg)
        return {
            "instances": [],
            "success": False,
            "error": error_msg
        }
        
    except Exception as e:
        error_msg = f"未知错误: {str(e)}"
        args.logger.error(error_msg)
        return {
            "instances": [],
            "success": False,
            "error": error_msg
        }

posted on 2026-09-18 10:32  luzhouxiaoshuai  阅读(18)  评论(0)    收藏  举报

导航