Aiops探索:基于Ansible的Dify版本运维智能体落地思路

我之前落地过Coze+Ansible的智能体,大家可以看案例-->Aiops探索:基于ansible的coze运维智能体终于成功了。而最近有个同学想做基于Dify的版本来找我帮忙,于是就有了今天这篇文章!

先说整体思路: Dify智能体会把我们的自然语言通过大模型转换为Dify工作流需要的必要参数,比如对哪个服务器做什么操作。这样Dify工作流就会去调用Asible的Dify插件,然后和Ansible控制台关联起来,最后Ansible再执行对应的Playbook去落地需求。

注意,此方案有一个投机取巧的点,就是将Dify服务器和Ansible控制节点合二为一了,这样就不用远程去调用,省去了很多麻烦。当然,这样做也有弊端,就是安全性会差一些。

看下落地细节吧,最关键的点在于如何在Dify制作访问Ansible的插件?Dify 的自定义插件是一个包含 yaml 配置文件和 python 代码的 zip 包。

1. 创建插件目录结构

在你的本地电脑上创建如下目录结构:

复制代码
my_ansible_tool/├── provider.yaml              # 插件元信息└── tools/    └── ansible_runner.yaml    # 工具定义    └── ansible_runner/        └── __init__.py        # 空文件,使其成为包        └── tool.py            # 核心逻辑代码
2. 编写 provider.yaml

这个文件定义了插件的作者、名称、图标等基本信息。​​​​​​​

复制代码
# my_ansible_tool/provider.yamlidentity:  author: Dify User  name: ansible_tool  label:    en_US: Ansible Tool    zh_Hans: Ansible 工具  description:    en_US: A tool to execute Ansible playbooks for server automation.    zh_Hans: 一个用于执行 Ansible Playbook 以实现服务器自动化的工具。  icon: icon.svg  tags:    - api    - devops
3. 编写 tools/ansible_runner.yaml

这个文件定义了工具本身,包括它的参数。这些参数将作为用户在 Dify 工作流中配置的输入项。​​​​​​​

复制代码
# my_ansible_tool/tools/ansible_runner.yamlidentity:  name: ansible_runner  author: Dify User  label:    en_US: Ansible Playbook Runner    zh_Hans: Ansible Playbook 执行器  description:    en_US: Executes a specified Ansible playbook against an inventory.    zh_Hans: 在指定的主机清单上执行一个 Ansible Playbook。  icon: icon.svgparameters:  - name: playbook_path    type: string    required: true    label:      en_US: Playbook Path      zh_Hans: Playbook 路径    human_description:      en_US: The absolute path to the Ansible playbook file inside the Dify container (e.g., /data/ansible/ping.yml).      zh_Hans: Dify 容器内 Ansible playbook 文件的绝对路径 (例如: /data/ansible/ping.yml)。    llm_description: The absolute path to the ansible playbook file to be executed.    form: llm  - name: inventory_path    type: string    required: true    label:      en_US: Inventory Path      zh_Hans: 主机清单路径    human_description:      en_US: The absolute path to the Ansible inventory file inside the Dify container (e.g., /data/ansible/hosts.ini).      zh_Hans: Dify 容器内 Ansible 主机清单文件的绝对路径 (例如: /data/ansible/hosts.ini)。    llm_description: The absolute path to the ansible inventory file.    form: llm  - name: extra_vars    type: string    required: false    label:      en_US: Extra Variables      zh_Hans: 额外变量    human_description:      en_US: Optional. A JSON string of extra variables to pass to the playbook.      zh_Hans: 可选。一个 JSON 格式的字符串,用于向 Playbook 传递额外变量。    llm_description: A JSON string of extra variables for the ansible playbook.    form: llm
4. 编写核心代码 tools/ansible_runner/tool.py

这是插件的核心,负责接收参数并执行 ansible-playbook 命令。​​​​​​​

复制代码
# my_ansible_tool/tools/ansible_runner/tool.pyimport jsonimport subprocessfrom typing import Any, Dict, Listfrom dify_plugin import Tool
class AnsibleRunnerTool(Tool):    def _run_ansible_command(self, command: List[str]) -> Dict[str, Any]:        """        Executes the ansible-playbook command and returns its output.        """        try:            # 使用 subprocess.run 执行命令,更安全且能捕获输出            result = subprocess.run(                command,                capture_output=True,                text=True,                check=False, # 不检查返回码,我们自己处理                encoding='utf-8',                errors='replace'            )
            output = {                "returncode": result.returncode,                "stdout": result.stdout,                "stderr": result.stderr,            }
            # 将输出格式化为 JSON 字符串,方便 Dify 解析和展示            return json.dumps(output, indent=2, ensure_ascii=False)
        except FileNotFoundError:            return json.dumps({"error": "ansible-playbook command not found. Is Ansible installed and in PATH?"}, ensure_ascii=False)        except Exception as e:            return json.dumps({"error": f"An unexpected error occurred: {str(e)}"}, ensure_ascii=False)
    def invoke(self, user_id: str, tool_parameters: Dict[str, Any]) -> str:        """        The main entry point for the tool invocation.        """        playbook_path = tool_parameters.get('playbook_path')        inventory_path = tool_parameters.get('inventory_path')        extra_vars_str = tool_parameters.get('extra_vars')
        if not playbook_path or not inventory_path:            return self.create_text_message("Error: Playbook path and inventory path are required.")
        # 构建基础命令        command = [            'ansible-playbook',            '-i', inventory_path,            playbook_path        ]
        # 如果提供了额外变量,添加到命令中        if extra_vars_str:            try:                # 验证 extra_vars 是否为有效的 JSON                json.loads(extra_vars_str)                command.extend(['--extra-vars', extra_vars_str])            except json.JSONDecodeError:                return self.create_text_message(f"Error: Invalid JSON format for extra_vars: {extra_vars_str}")
        # 执行命令并获取结果        result_json = self._run_ansible_command(command)
        # 将结果返回给 Dify        return self.create_text_message(result_json)

将这些文件打包为zip格式压缩包,直接在Dify控制台,通过"自定义工具"导入。有了此工具,就可以设计工作流了。

1)创建工作流:在 Dify 中创建一个新的空白工作流。

2)添加开始节点:设置一个输入变量,例如 task_description,让用户描述他们想做什么。

3)添加 LLM 节点:

  • 连接"开始"节点。

  • "系统提示词" 中,明确告诉 AI 它的角色和可用的工具。例如:

    你是一个专业的运维助手。你可以使用 'Ansible_Playbook_Runner' 工具来执行服务器管理任务。
    你知道以下预定义的 Playbook:1. '/data/ansible/ping.yml': 用于检查服务器连通性。2. '/data/ansible/install_nginx.yml': 用于在 webservers 组的服务器上安装 Nginx。
    主机清单文件位于 '/data/ansible/hosts.ini'。
    根据用户的请求,选择合适的 Playbook 和主机清单来调用工具。如果用户请求的任务没有对应的 Playbook,请告知用户。

  • "模型" 中选择一个合适的模型。

  • 在 "工具" 中,启用你刚刚上传的 "Ansible Tool"。

4)添加结束节点:连接 LLM 节点,用于输出最终结果。

对了,忘记提醒大家,不要忘记编写你自己的playbook,放到Dify服务器也就是Ansible控制节点上。真正干活儿的是这些playbook。你想做啥,就写啥playbook吧。上面的"系统提示词"中也提到了,留给大家自由发挥吧。

注意:我目前就是提供一个落地思路,具体细节还需你好好调教调教!

相关推荐
TG_yunshuguoji5 小时前
亚马逊云渠道商:如何通过配置自动替换构建故障自愈的云架构?
运维·服务器·架构·云计算·aws
期待着20135 小时前
StarRocks 集群安装部署文档
linux·服务器
2301_772093566 小时前
高并发webserver_interview
运维·服务器·数据库·后端·网络协议·mysql·wireshark
haimin03716 小时前
ubuntu 20.04 安装xrdp远程桌面访问
linux·运维·ubuntu
TG:@yunlaoda360 云老大6 小时前
阿里云国际站GPU:怎么通过通过VNC连接实例?
服务器·阿里云·云计算
乌托邦的逃亡者6 小时前
Linux系统中配置history命令显示时间、IP、账号和操作命令
linux·运维·安全
Archy_Wang_17 小时前
Elasticsearch8.4.1升级Elasticsearch9.1.5
运维·elasticsearch·jenkins
集智飞行7 小时前
docker login方法
运维·docker·容器
liulilittle7 小时前
LwIP协议栈MPA多进程架构
服务器·开发语言·网络·c++·架构·lwip·通信