第 15 期 | Agent 驱动的 DevOps:部署自动化
好的,作为技术教育专家,我将为您撰写这篇关于 Hermes Agent 在 DevOps 领域应用的深度教程。
副标题:让 Hermes 参与自动化构建、Docker 打包、测试发布流程,体验向"AI原生运维"范式的跳跃。
学习目标
在本期课程中,您将深入探索如何将 Hermes Agent 的能力从对话和信息处理扩展到实际的软件工程实践中。完成本教程后,您将能够:
- 理解 Agent-Driven DevOps 的核心思想:了解它与传统 CI/CD 工具(如 Jenkins, GitLab CI)的区别与优势。
- 创建强大的 DevOps Skill:编写一个能够执行本地 Shell 命令的 Hermes Skill,作为连接 Agent 与服务器操作的桥梁。
- 实现完整的自动化部署流程:通过 Git Webhook 触发,让 Hermes Agent 自动完成拉取代码、构建 Docker 镜像、停止旧容器、启动新容器的完整 CI/CD (Continuous Integration/Continuous Deployment) 流程。
- 构建闭环反馈系统:在部署任务完成后,让 Hermes Agent 主动通过消息网关(如 Telegram)向您汇报结果,实现无人值守的自动化运维。
核心概念讲解
1. 什么是 Agent 驱动的 DevOps (Agent-Driven DevOps)?
传统的 DevOps 自动化依赖于预定义的、结构化的配置文件(如 .gitlab-ci.yml, Jenkinsfile)。这些工具强大但通常缺乏灵活性和上下文感知能力。它们的执行逻辑是固定的,遇到非预期情况时,往往需要人工介入排查日志。
Agent-Driven DevOps 是一种新的范式,它将大型语言模型(LLM)驱动的 Agent 置于 DevOps 流程的核心。其关键特点包括:
- 自然语言交互:除了自动化触发,你还可以通过自然语言向 Agent下达指令,如“部署主分支到预发环境”、“回滚上一个版本”、“检查生产环境服务状态”。
- 上下文感知与决策:Agent 能够理解上下文。例如,当一个部署任务失败时,它不仅能报告错误,还能根据错误日志(通过 Skill 读取)尝试分析原因,甚至提出解决方案。
- 动态工作流编排:Agent 可以根据情况动态调整工作流。例如,如果测试阶段发现高危漏洞,它可以自动暂停部署流程,并立即通知安全团队,而不是僵化地继续执行下一步。
- 集成与协同:Hermes Agent 可以作为一个智能中枢,连接代码仓库 (GitHub)、项目管理工具 (Jira)、监控系统 (Prometheus) 和通信平台 (Telegram, Slack),实现跨系统的信息整合与任务协同。
在本教程中,我们将实现 Agent-Driven DevOps 的第一步:将 Hermes Agent 打造为一个由 Git 事件驱动的、能够执行部署任务的智能运维机器人。
2. Hermes Agent 在 DevOps 中的角色
在这个自动化流程中,Hermes Agent 扮演着“智能编排器”和“执行者”的角色。
- 监听器 (Listener):通过 Webhook 接口,实时监听来自外部系统(如 GitHub)的事件。
- 决策者 (Decision Maker):接收到事件后,Agent 的大脑(LLM)根据其内置的 Prompt 和可用的 Skills,决定应该执行哪个工具(Tool/Function)。
- 执行者 (Executor):通过专门为 DevOps 设计的 Skill,调用底层的 Shell 脚本或命令来完成实际工作,如
git pull,docker build,docker run等。 - 报告者 (Reporter):任务执行完毕后,通过消息网关将结果(成功或失败)反馈给用户,形成一个完整的闭环。
3. 关键技术组件
- Skill (
execute_shell_command): 这是我们实现 DevOps 自动化的核心武器。我们将创建一个 Skill,它包含一个可以安全执行 Shell 命令的工具。这是 Agent 与操作系统交互的唯一通道。 - Webhook: Webhook 是一种反向 API,允许外部服务在特定事件发生时,主动向 Hermes Agent 发送一个 HTTP POST 请求。在本例中,GitHub 在我们
git push代码时,会向 Hermes 的 Webhook URL 推送一个包含提交信息的 JSON 数据包。 - Shell 脚本 (
deploy.sh): 将复杂的部署逻辑封装在一个独立的 Shell 脚本中是一种最佳实践。这使得 Hermes 的 Skill 职责单一(只负责调用脚本),同时也让部署逻辑更易于维护和在其他地方复用。
💻 实战演示
我们将以一个简单的 Python Flask 应用为例,构建一个完整的自动化部署流水线。当开发者向 GitHub 仓库推送代码时,Hermes Agent 将自动将其部署到服务器上。
Step 1: 准备项目环境
首先,我们需要一个待部署的应用。我们创建一个简单的 Flask Web 应用,并为其编写 Dockerfile 和部署脚本。
1. 创建项目目录
在您的服务器上,创建一个项目目录。
mkdir hermes-devops-demo
cd hermes-devops-demo
2. 创建 Flask 应用 (app.py)
这是一个最简单的 "Hello World" 应用。
# app.py
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello():
# 我们将通过环境变量来验证部署是否更新
version = os.environ.get('APP_VERSION', 'v1.0.0')
return f"Hello from Hermes DevOps Demo! Version: {version}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
3. 创建依赖文件 (requirements.txt)
Flask==2.2.2
4. 创建 Dockerfile
这个文件定义了如何将我们的应用打包成一个 Docker 镜像。
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
5. 创建部署脚本 (deploy.sh)
这是整个自动化流程的核心执行逻辑。该脚本负责停止并移除旧的容器,然后使用最新的代码构建并运行新的容器。
#!/bin/bash
# deploy.sh
# 确保脚本在任何命令失败时退出
set -e
# --- 配置变量 ---
# Docker 镜像名称
IMAGE_NAME="hermes-demo-app"
# 容器名称
CONTAINER_NAME="hermes-demo-container"
# 应用端口
APP_PORT=5000
# 项目路径 (确保这是脚本所在的绝对路径)
PROJECT_PATH=$(pwd)
# 获取当前的 Git Commit Hash 作为版本号
GIT_COMMIT_HASH=$(git rev-parse --short HEAD)
echo "====== [ HERMES DEVOPS ] ======"
echo "Starting deployment for commit: $GIT_COMMIT_HASH"
echo "Project path: $PROJECT_PATH"
# --- 1. 拉取最新代码 ---
echo "--> Step 1: Pulling latest code from git..."
git pull origin main
# --- 2. 构建 Docker 镜像 ---
echo "--> Step 2: Building Docker image: $IMAGE_NAME:$GIT_COMMIT_HASH..."
docker build -t $IMAGE_NAME:$GIT_COMMIT_HASH -t $IMAGE_NAME:latest .
# --- 3. 停止并移除旧容器 ---
# 使用 docker ps -q 来检查容器是否存在,如果存在则停止并删除
if [ "$(docker ps -q -f name=$CONTAINER_NAME)" ]; then
echo "--> Step 3: Stopping and removing old container..."
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
fi
# --- 4. 启动新容器 ---
echo "--> Step 4: Starting new container..."
docker run -d \
--name $CONTAINER_NAME \
-p $APP_PORT:5000 \
-e APP_VERSION=$GIT_COMMIT_HASH \
--restart always \
$IMAGE_NAME:latest
echo "====== [ DEPLOYMENT SUCCESS ] ======"
echo "Application deployed successfully!"
echo "Access it at: http://<your_server_ip>:$APP_PORT"
# 将部署结果返回给调用者(Hermes Skill)
echo "Deployment of version $GIT_COMMIT_HASH completed."
重要: 赋予脚本执行权限。
chmod +x deploy.sh
6. 初始化 Git 仓库并推送到 GitHub
git init
git add .
git commit -m "Initial commit for DevOps demo"
# 在 GitHub 上创建一个新的空仓库,然后执行以下命令
git remote add origin <your_github_repo_url.git>
git branch -M main
git push -u origin main
至此,我们的应用代码和部署脚本已经准备就绪。
Step 2: 创建 DevOps Skill
现在,我们为 Hermes Agent 创建一个 Skill,让它能够调用我们刚刚编写的 deploy.sh 脚本。
- 进入 Hermes Agent 的
skills目录,创建一个新的 Skill 文件devops_skill.py。 - 编辑
devops_skill.py文件,内容如下:
# skills/devops_skill.py
import subprocess
import os
from hermes_agent.skills.skill import Skill
class DevOpsSkill(Skill):
def __init__(self, agent):
super().__init__(agent)
# 你的项目部署脚本所在的绝对路径
self.project_path = "/path/to/your/hermes-devops-demo"
def get_tools(self):
return [self.deploy_project]
def deploy_project(self, project_name: str, branch: str) -> str:
"""
Deploys a specified project by executing its deployment script.
This tool should be triggered by a webhook from a Git repository.
It executes the deploy.sh script within the project's directory.
:param project_name: The name of the project to deploy, e.g., 'hermes-devops-demo'.
:param branch: The branch that was pushed, e.g., 'main'.
:return: A string containing the output of the deployment script.
"""
# 安全检查:只允许部署主分支
if branch != 'main':
return f"Deployment skipped. Only pushes to the 'main' branch trigger deployment. Received push to '{branch}'."
if project_name != 'hermes-devops-demo':
return f"Deployment skipped. Unknown project name: '{project_name}'."
script_path = os.path.join(self.project_path, "deploy.sh")
if not os.path.exists(script_path):
error_msg = f"Error: Deployment script not found at {script_path}"
self.agent.logger.error(error_msg)
return error_msg
try:
self.agent.logger.info(f"Executing deployment script for project '{project_name}' from branch '{branch}'...")
# 使用 subprocess 执行 shell 脚本
# cwd 参数确保脚本在正确的项目目录下执行
result = subprocess.run(
[script_path],
capture_output=True,
text=True,
check=True,
cwd=self.project_path
)
output = result.stdout
self.agent.logger.info(f"Deployment script executed successfully. Output:\n{output}")
# 部署成功后,发送通知
self.send_deployment_notification(status="✅ SUCCESS", details=output)
return f"Deployment successful. Log:\n{output}"
except subprocess.CalledProcessError as e:
error_output = e.stderr
self.agent.logger.error(f"Deployment script failed. Error:\n{error_output}")
# 部署失败后,发送通知
self.send_deployment_notification(status="❌ FAILED", details=error_output)
return f"Deployment failed. Error:\n{error_output}"
def send_deployment_notification(self, status: str, details: str):
"""通过消息网关发送部署状态通知"""
if not self.agent.message_gateway:
self.agent.logger.warning("Message gateway not configured. Skipping notification.")
return
# 假设你已经配置好了 Telegram (或其它) 网关
# 从配置中获取管理员的用户ID
admin_user_id = self.agent.config.get('admin_user_id')
if not admin_user_id:
self.agent.logger.warning("Admin user ID not set in config. Skipping notification.")
return
commit_hash = details.split("commit: ")[1].split("\n")[0] if "commit: " in details else "N/A"
message = (
f"**Hermes DevOps Notification**\n\n"
f"**Status**: {status}\n"
f"**Project**: hermes-devops-demo\n"
f"**Commit**: `{commit_hash}`\n\n"
f"**Details**:\n```\n{details[-1000:]}\n```" # 只发送最后1000个字符的日志
)
# 发送消息给管理员
self.agent.message_gateway.send_message(message, admin_user_id)
self.agent.logger.info(f"Sent deployment notification to admin user {admin_user_id}.")
3. 注册 Skill
打开 Hermes Agent 的 config.yml 文件,在 skills 部分添加我们的新 Skill。
# config.yml
skills:
- name: devops_skill.DevOpsSkill
enabled: true
# ... 其他配置
同时,为了让通知功能生效,请确保你已经配置了消息网关(如 Telegram,参考第05期课程),并在 config.yml 中添加管理员的用户ID。
# config.yml
# ...
message_gateways:
telegram:
enabled: true
api_token: "your_telegram_bot_token"
# 添加一个新的配置项
admin_user_id: "your_telegram_user_id"
Step 3: 配置 Webhook 接入
现在,我们需要告诉 GitHub,当有代码 push 事件时,请通知我们的 Hermes Agent。
获取 Hermes Webhook URL: Hermes Agent 的 Webhook URL 格式为:
http://<your_hermes_server_ip>:<port>/v1/webhook/{webhook_id}。webhook_id:你可以在config.yml中自定义,或者使用默认的。我们在此处定义一个新的。api_key:用于验证请求的来源,也在config.yml中设置。
在
config.yml中添加webhook配置:# config.yml server: host: "0.0.0.0" port: 8888 api_key: "a_very_secret_api_key" # 请使用一个强密码 webhooks: # 为我们的 DevOps 流程定义一个专用的 webhook - id: "github-devops-trigger" # 当此 webhook 被触发时,Agent 会执行此指令 # 我们利用 LLM 的能力,将 webhook 的 JSON 内容作为上下文,让它调用正确的工具 prompt: > The following JSON payload was received from a GitHub webhook for the 'hermes-devops-demo' repository. The 'ref' field indicates the branch that was pushed. Based on this information, call the deploy_project tool with the correct project name and branch. Do not ask for confirmation, just execute the tool. Webhook Payload: {payload}根据此配置,我们的 Webhook URL 是:
http://<your_hermes_server_ip>:8888/v1/webhook/github-devops-trigger。在 GitHub 中配置 Webhook:
- 打开你的 GitHub 仓库页面,进入
Settings->Webhooks。 - 点击
Add webhook。 - Payload URL: 填入你的 Hermes Webhook URL。
- Content type: 选择
application/json。 - Secret: 填入你在
config.yml中设置的api_key。 - Which events would you like to trigger this webhook?: 选择
Just the push event。 - 确保
Active复选框被勾选,然后点击Add webhook。
- 打开你的 GitHub 仓库页面,进入
(这是一个示意图,请根据实际界面操作)
Step 4: 触发与验证
一切准备就绪!现在我们来触发整个流程。
重启 Hermes Agent 以加载新的 Skill 和配置。
# 在 Hermes Agent 的根目录 python main.py观察启动日志,确保
DevOpsSkill已成功加载。修改代码并推送: 在本地克隆的
hermes-devops-demo项目中,对app.py做一个小的修改。# app.py (修改后) @app.route('/') def hello(): version = os.environ.get('APP_VERSION', 'v1.0.0') # 添加一句新的问候 return f"Hello from Hermes DevOps Demo! Version: {version}. Deployment was automated!"提交并推送代码:
git add app.py git commit -m "feat: Update greeting message to test auto-deployment" git push origin main观察 Hermes Agent 日志: 在
git push命令成功后,你应该会立刻在 Hermes Agent 的控制台看到类似以下的日志:INFO:hermes_agent.services.http_server:Received webhook request for ID: github-devops-trigger INFO:hermes_agent.agent:Received instruction from webhook 'github-devops-trigger'. Processing... INFO:hermes_agent.models.provider:Calling tool: deploy_project with args: {'project_name': 'hermes-devops-demo', 'branch': 'main'} INFO:skills.devops_skill:Executing deployment script for project 'hermes-devops-demo' from branch 'main'... # ... deploy.sh 脚本的输出 ... INFO:skills.devops_skill:Deployment script executed successfully. Output: ====== [ HERMES DEVOPS ] ====== ... ====== [ DEPLOYMENT SUCCESS ] ====== ... INFO:skills.devops_skill:Sent deployment notification to admin user 123456789.验证部署结果:
- 在服务器上运行
docker ps,你会看到一个新的容器正在运行,它的启动时间就是刚刚。 - 使用
curl或浏览器访问你的应用:curl http://localhost:5000。 - 你应该能看到更新后的内容,并且版本号是新的 Git Commit Hash。
$ curl http://localhost:5000 Hello from Hermes DevOps Demo! Version: a1b2c3d. Deployment was automated!- 在服务器上运行
检查通知: 打开你的 Telegram,你应该会收到来自 Hermes Bot 的一条消息,详细报告了部署成功的信息和日志。
涉及命令
- 项目设置:
mkdir,cd,git init,git add,git commit,git remote add,git push - 权限管理:
chmod +x deploy.sh - Docker:
docker build,docker ps,docker stop,docker rm,docker run - 验证:
curl http://localhost:5000
要点回顾
- Agent-Driven DevOps 的核心是智能与交互:我们利用 LLM 的理解能力,通过一个通用的 Prompt 来解析 Webhook 内容并调用正确的工具,这比写死的
if-else逻辑更具扩展性。 - 职责分离是关键:复杂的部署逻辑应封装在独立的 Shell 脚本 (
deploy.sh) 中,而 Hermes Skill 只负责触发、监控和报告。这种解耦使得两部分都易于维护。 - Webhook 是连接外部世界的桥梁:通过配置 Webhook,Hermes Agent 能够响应外部系统的事件,从而实现事件驱动的自动化。
- 安全是第一要务:在 Skill 中执行 Shell 命令具有潜在风险。务必对输入参数进行严格校验(如我们检查了
branch和project_name),并确保执行的脚本来自可信的源。在生产环境中,应考虑使用更安全的执行沙箱。 - 闭环反馈至关重要:自动化流程的最后一步永远是报告。通过消息网关发送通知,可以让我们在不登录服务器的情况下,实时掌握系统状态,真正实现“无人值守”。
通过本期课程,您已经成功地将 Hermes Agent 集成到了一个现代化的 DevOps 工作流中。这仅仅是一个开始,您可以基于此框架进行扩展,例如:
- 增加测试阶段:在部署前自动运行单元测试。
- 支持多环境部署:通过解析分支名(如
develop,release/*)来决定部署到哪个环境。 - 增加人工审批环节:在部署到生产环境前,Agent 在群组里发起一个投票,等待管理员确认后才继续。
欢迎继续探索 Hermes Agent 的无限可能,向着真正的 "AI-Native Ops" 迈进!