Expert-Level Workflow: From Requirements to Deployment – A Complete Project实战
TL;DR: This final installment of our Hermes Agent series walks you through building a production-ready microservice from scratch—spanning requirements analysis, multi-agent collaboration, automated testing, CI/CD pipeline integration, and deployment to a Kubernetes cluster. You’ll learn how to orchestrate Hermes Agent’s full ecosystem, including MCP tools, cron jobs, and skill reuse, to deliver a complete project in under 4 hours.
🎯 Introduction: Why This Matters
After five parts of building Hermes Agent expertise, you now understand:
- Part 1: Installation and basic workflows
- Part 2: Multi-role collaboration between AI, developers, and domain experts
- Part 3: Skill system design and reuse
- Part 4: Cron-based automation for content pipelines
- Part 5: MCP protocol integration for tool extension
But theory without practice is just philosophy. Today, we bridge the gap between individual features and production-grade project delivery. You’ll learn how Hermes Agent transforms from a helpful assistant into a full-stack development orchestrator that can:
- Analyze ambiguous requirements and generate structured specifications
- Coordinate multiple specialized agents (architect, backend, frontend, DevOps)
- Execute automated testing with real-time feedback loops
- Deploy to Kubernetes with zero-downtime strategies
- Monitor and alert on production metrics
Learning Objectives:
- Design multi-phase workflows that handle real-world project complexity
- Implement Hermes Agent’s
workflow_chainingfeature for pipeline orchestration - Configure MCP-based integration with AWS, GitHub, and Slack APIs
- Build a reusable “project scaffold” skill that accelerates future development
📋 Project Overview: The “SmartAlert” Microservice
We’ll build SmartAlert—a real-time incident management service that:
- Ingests alerts from multiple sources (Prometheus, Datadog, custom APIs)
- Deduplicates and enriches alerts using AI classification
- Routes alerts to appropriate teams via Slack, PagerDuty, or email
- Provides a dashboard for historical analysis
Technical Stack:
- Backend: Go 1.22 (performance-critical), PostgreSQL 16, Redis 7
- Frontend: React 18 with TypeScript, Vite, Tailwind CSS
- Infrastructure: Docker, Kubernetes (EKS), Terraform, Helm
- CI/CD: GitHub Actions + ArgoCD
Why this project? It demonstrates every major Hermes Agent capability:
- Multi-agent collaboration (architect + developer + SRE)
- MCP integration (Slack, PagerDuty, AWS)
- Cron-based health checks and report generation
- Skill reuse (we’ll create a reusable
microservice-scaffoldskill)
🏗️ Phase 1: Requirements Analysis with Multi-Agent Collaboration
1.1 Initial Prompt Engineering
Create a new project in Hermes Agent:
hermes project init smartalert --template expert-workflow
This generates the following directory structure:
smartalert/
├── .hermes/
│ ├── config.yaml
│ ├── skills/
│ └── workflows/
├── requirements/
├── design/
├── src/
└── deployments/
Now, let’s define our multi-agent workflow. Create workflows/requirements-analysis.yaml:
name: "smartalert-requirements-analysis"
version: "1.0.0"
description: "Multi-agent requirements analysis for SmartAlert"
agents:
- role: "product_manager"
model: "gpt-4o"
system_prompt: |
You are a senior product manager specializing in incident management.
Focus on user stories, acceptance criteria, and business value.
Output structured requirements in YAML format.
- role: "system_architect"
model: "claude-3-opus"
system_prompt: |
You are a systems architect with 15 years of experience in distributed systems.
Focus on scalability, fault tolerance, and technology choices.
Output architecture decisions and trade-off analyses.
- role: "security_engineer"
model: "gpt-4o"
system_prompt: |
You are a security engineer specializing in cloud-native applications.
Focus on authentication, authorization, data encryption, and compliance.
Output threat models and security requirements.
workflow:
steps:
- name: "gather_requirements"
agent: "product_manager"
prompt: |
Analyze the following high-level requirements and produce:
1. 10-15 detailed user stories with acceptance criteria
2. Priority matrix (P0-P3)
3. Non-functional requirements (performance, availability, etc.)
High-level requirements:
{{user_input}}
output: "requirements/initial_requirements.yaml"
- name: "review_architecture"
agent: "system_architect"
depends_on: ["gather_requirements"]
prompt: |
Review the requirements from step 1 and produce:
1. System architecture diagram (C4 model - level 2)
2. Technology stack recommendations with justification
3. API specification (OpenAPI 3.0)
4. Data model (ER diagram)
Consider:
- 99.99% availability requirement
- 10,000 alerts/second peak throughput
- Multi-region deployment
output: "design/architecture.yaml"
- name: "security_review"
agent: "security_engineer"
depends_on: ["review_architecture"]
prompt: |
Perform a security review of the architecture from step 2:
1. Threat model using STRIDE methodology
2. Required security controls
3. Compliance requirements (SOC2, GDPR)
4. Penetration testing scope
output: "design/security_requirements.yaml"
- name: "consolidate"
agent: "product_manager"
depends_on: ["security_review"]
prompt: |
Consolidate all outputs into a single, coherent requirements document.
Resolve any conflicts between architecture and security requirements.
Output as a structured markdown document with:
- Executive summary
- Technical requirements
- Security requirements
- Implementation phases (Phase 1: MVP, Phase 2: Scale, Phase 3: Enterprise)
output: "requirements/consolidated_requirements.md"
1.2 Executing the Workflow
Run the workflow with our initial prompt:
hermes workflow run smartalert-requirements-analysis \
--param user_input="Build a real-time alert management system that ingests alerts from Prometheus and Datadog, deduplicates them using AI, routes to Slack/PagerDuty, and provides a dashboard. Must handle 10k alerts/sec with 99.99% uptime."
The workflow executes sequentially, with each agent building on the previous output. After ~15 minutes, you’ll have:
requirements/initial_requirements.yaml: 12 user stories with acceptance criteriadesign/architecture.yaml: C4 model diagrams, OpenAPI spec, data modeldesign/security_requirements.yaml: 23 security requirements with STRIDE analysisrequirements/consolidated_requirements.md: Comprehensive 40-page requirements document
1.3 Key Insight: Agent Handoff Protocol
Notice the depends_on field. Hermes Agent implements a structured handoff protocol:
- Each agent receives the complete output of its dependencies
- Agents can request clarification via the
askfunction - Conflicts are flagged in the consolidation step
This prevents the common problem of agents contradicting each other or working from stale information.
🔧 Phase 2: Scaffolding the Project with Custom Skills
2.1 Creating the Microservice Scaffold Skill
Based on the architecture from Phase 1, let’s create a reusable skill. Create skills/microservice-scaffold.yaml:
name: "microservice-scaffold"
version: "2.0.0"
description: "Generates production-ready microservice boilerplate with Go, React, and Kubernetes"
parameters:
service_name:
type: string
description: "Name of the microservice"
required: true
go_module_path:
type: string
description: "Go module path (e.g., github.com/company/smartalert)"
required: true
database:
type: string
enum: ["postgresql", "mysql", "none"]
default: "postgresql"
include_frontend:
type: boolean
default: true
include_k8s:
type: boolean
default: true
steps:
- name: "generate_backend"
action: "file_template"
template: |
// {{service_name}}/cmd/server/main.go
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"{{go_module_path}}/internal/api"
"{{go_module_path}}/internal/config"
"{{go_module_path}}/internal/database"
"{{go_module_path}}/internal/logger"
)
func main() {
cfg := config.Load()
log := logger.New(cfg.LogLevel)
db, err := database.Connect(cfg.DatabaseURL)
if err != nil {
log.Fatal("failed to connect to database", "error", err)
}
defer db.Close()
router := api.NewRouter(db, log)
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: router,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
// Graceful shutdown
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal("server failed", "error", err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
srv.Shutdown(ctx)
}
output: "{{service_name}}/cmd/server/main.go"
- name: "generate_dockerfile"
action: "file_template"
template: |
# {{service_name}}/Dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server ./cmd/server
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
output: "{{service_name}}/Dockerfile"
- name: "generate_helm_chart"
action: "file_template"
condition: "{{include_k8s}}"
template: |
# {{service_name}}/deployments/helm/values.yaml
replicaCount: 3
image:
repository: "{{service_name}}"
tag: latest
pullPolicy: Always
service:
type: ClusterIP
port: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80
probes:
liveness:
path: /healthz
initialDelaySeconds: 10
periodSeconds: 10
readiness:
path: /readyz
initialDelaySeconds: 5
periodSeconds: 5
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: {{service_name}}.example.com
paths:
- /api
output: "{{service_name}}/deployments/helm/values.yaml"
2.2 Applying the Skill
Execute the skill with our project parameters:
hermes skill run microservice-scaffold \
--param service_name="smartalert" \
--param go_module_path="github.com/smartotics/smartalert" \
--param database="postgresql" \
--param include_frontend=true \
--param include_k8s=true
This generates 47 files in under 30 seconds, including:
- Go backend with graceful shutdown, structured logging, and health checks
- React frontend with Vite, TypeScript, and Tailwind CSS
- Docker multi-stage builds
- Helm chart with HPA, probes, and ingress
- GitHub Actions CI/CD pipeline
- Terraform infrastructure code
2.3 Expert Tip: Skill Composition
Skills can call other skills. For example, our microservice-scaffold skill could call an api-generator skill to create OpenAPI-compliant endpoints. This composability is what makes Hermes Agent’s skill system powerful for enterprise use.
🚀 Phase 3: Implementing Core Business Logic with MCP Integration
3.1 Connecting External Services via MCP
Create mcp/slack-integration.yaml:
name: "slack-integration"
version: "1.0.0"
provider: "slack"
auth:
type: "oauth2"
client_id: "${SLACK_CLIENT_ID}"
client_secret: "${SLACK_CLIENT_SECRET}"
scopes:
- "chat:write"
- "channels:read"
- "users:read"
tools:
- name: "send_alert"
description: "Send an alert message to a Slack channel"
input_schema:
type: object
properties:
channel:
type: string
description: "Slack channel ID or name"
message:
type: string
description: "Alert message content"
severity:
type: string
enum: ["critical", "warning", "info"]
required: ["channel", "message"]
handler: |
async function handler(args) {
const blocks = [];
if (args.severity === "critical") {
blocks.push({
type: "header",
text: { type: "plain_text", text: "🚨 CRITICAL ALERT" }
});
}
blocks.push({
type: "section",
text: { type: "mrkdwn", text: args.message }
});
const response = await fetch("https://slack.com/api/chat.postMessage", {
method: "POST",
headers: {
"Authorization": `Bearer ${this.accessToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
channel: args.channel,
blocks: blocks,
text: args.message // fallback
})
});
return response.json();
}
Similarly, create MCP integrations for:
- PagerDuty: Trigger incidents, acknowledge, resolve
- Prometheus: Query metrics, check alert rules
- Datadog: Fetch monitors, post events
- AWS SNS: Send notifications to multiple channels
3.2 The Alert Processing Pipeline
Now, let’s build the core workflow that ties everything together. Create workflows/alert-pipeline.yaml:
name: "smartalert-pipeline"
version: "1.0.0"
description: "End-to-end alert processing pipeline"
triggers:
- type: "webhook"
path: "/api/v1/alerts"
methods: ["POST"]
authentication:
type: "api_key"
header: "X-API-Key"
- type: "cron"
schedule: "*/5 * * * *"
description: "Health check every 5 minutes"
workflow:
steps:
- name: "ingest_alert"
action: "process_webhook"
input:
source: "{{trigger.source}}"
payload: "{{trigger.payload}}"
output: "alert"
- name: "deduplicate"
action: "ai_deduplicate"
depends_on: ["ingest_alert"]
input:
alert: "{{steps.ingest_alert.output}}"
cache: "redis://{{REDIS_HOST}}:6379/0"
window: "5m"
output: "dedup_result"
condition: "{{steps.ingest_alert.output.severity != 'info'}}"
- name: "enrich_alert"
action: "ai_enrich"
depends_on: ["deduplicate"]
input:
alert: "{{steps.deduplicate.output.alert}}"
context:
- type: "prometheus"
query: "up{job='{{alert.service}}'}"
- type: "datadog"
query: "avg:system.cpu.user{service:{{alert.service}}}"
output: "enriched_alert"
- name: "classify_severity"
action: "ai_classify"
depends_on: ["enrich_alert"]
input:
alert: "{{steps.enrich_alert.output}}"
model: "gpt-4o-mini"
prompt: |
Classify this alert's severity based on:
- Historical patterns
- Current system metrics
- Business impact
Alert: {{alert}}
Output one of: "critical", "warning", "info"
output: "classification"
- name: "route_alert"
action: "mcp_route"
depends_on: ["classify_severity"]
input:
alert: "{{steps.enrich_alert.output}}"
severity: "{{steps.classify_severity.output}}"
routing_rules:
- severity: "critical"
channels:
- type: "pagerduty"
urgency: "high"
- type: "slack"
channel: "#incidents-critical"
- type: "sns"
topic: "arn:aws:sns:us-east-1:123456789012:critical-alerts"
- severity: "warning"
channels:
- type: "slack"
channel: "#incidents-warning"
- type: "email"
to: "[email protected]"
- severity: "info"
channels:
- type: "slack"
channel: "#incidents-info"
output: "routing_result"
- name: "store_alert"
action: "database_insert"
depends_on: ["route_alert"]
input:
connection: "postgresql://{{DB_USER}}:{{DB_PASS}}@{{DB_HOST}}:5432/smartalert"
table: "alerts"
data:
id: "{{steps.ingest_alert.output.id}}"
source: "{{steps.ingest_alert.output.source}}"
severity: "{{steps.classify_severity.output}}"
enriched_data: "{{steps.enrich_alert.output}}"
routing_result: "{{steps.route_alert.output}}"
created_at: "{{now()}}"
3.3 Real-Time Monitoring Dashboard
The frontend workflow generates a React dashboard with:
// src/components/AlertDashboard.tsx
import { useEffect, useState } from 'react';
import { LineChart, BarChart } from 'recharts';
import { useHermesStream } from '@hermes/react-sdk';
interface AlertMetrics {
total: number;
critical: number;
warning: number;
info: number;
avgResponseTime: number;
}
export function AlertDashboard() {
const [metrics, setMetrics] = useState<AlertMetrics>({
total: 0, critical: 0, warning: 0, info: 0, avgResponseTime: 0
});
// Real-time subscription via Hermes Agent's SSE endpoint
const { data, error } = useHermesStream('/api/v1/metrics/stream', {
onMessage: (msg) => {
setMetrics(prev => ({
...prev,
...msg.data
}));
}
});
return (
<div className="grid grid-cols-4 gap-4 p-6">
<MetricCard title="Total Alerts" value={metrics.total} color="blue" />
<MetricCard title="Critical" value={metrics.critical} color="red" />
<MetricCard title="Warning" value={metrics.warning} color="yellow" />
<MetricCard title="Avg Response" value={`${metrics.avgResponseTime}ms`} color="green" />
<div className="col-span-4">
<LineChart width={800} height={400} data={alertHistory}>
<Line type="monotone" dataKey="count" stroke="#8884d8" />
</LineChart>
</div>
</div>
);
}
🧪 Phase 4: Automated Testing with Hermes Agent
4.1 Test Generation Workflow
Create workflows/test-generation.yaml:
name: "generate-tests"
version: "1.0.0"
description: "Automatically generate unit, integration, and e2e tests"
steps:
- name: "analyze_code"
action: "code_analysis"
input:
path: "./src"
coverage_threshold: 80
output: "analysis"
- name: "generate_unit_tests"
action: "ai_generate_tests"
depends_on: ["analyze_code"]
input:
files: "{{steps.analyze_code.output.untested_functions}}"
framework: "testing" # Go standard testing
coverage_goal: 90
output: "unit_tests"
- name: "generate_integration_tests"
action: "ai_generate_tests"
depends_on: ["generate_unit_tests"]
input:
type: "integration"
services:
- "postgresql"
- "redis"
- "prometheus"
scenarios:
- "alert_ingestion_and_routing"
- "deduplication_within_window"
- "multi_source_correlation"
output: "integration_tests"
- name: "run_tests"
action: "execute"
depends_on: ["generate_integration_tests"]
input:
command: |
cd /workspace/smartalert
go test ./... -v -count=1 -race -coverprofile=coverage.out
go tool cover -html=coverage.out -o coverage.html
output: "test_results"
- name: "fix_failures"
action: "ai_fix_tests"
depends_on: ["run_tests"]
input:
test_results: "{{steps.run_tests.output}}"
max_attempts: 3
condition: "{{steps.run_tests.output.exit_code != 0}}"
4.2 Running the Test Suite
hermes workflow run generate-tests --watch
Hermes Agent will:
- Analyze your codebase and identify untested functions
- Generate test cases with proper mocking and assertions
- Run tests and capture failures
- Attempt to fix failing tests (up to 3 iterations)
- Generate a coverage report
Example output:
✓ Generated 47 unit tests for 23 functions
✓ Generated 12 integration tests covering 5 scenarios
✓ All tests passing (100% pass rate)
✓ Code coverage: 87.3% (target: 80%)
🚢 Phase 5: CI/CD Pipeline and Deployment
5.1 GitHub Actions Workflow
Create .github/workflows/deploy.yaml:
name: "SmartAlert CI/CD Pipeline"
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Run Hermes Agent Tests
uses: hermes-agent/action@v2
with:
workflow: "generate-tests"
api-key: ${{ secrets.HERMES_API_KEY }}
- name: Build Docker Image
run: docker build -t smartalert:${{ github.sha }} .
- name: Security Scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'smartalert:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
aws-region: us-east-1
- name: Push to ECR
run: |
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
docker tag smartalert:${{ github.sha }} 123456789012.dkr.ecr.us-east-1.amazonaws.com/smartalert:${{ github.sha }}
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/smartalert:${{ github.sha }}
- name: Deploy to EKS
run: |
aws eks update-kubeconfig --name smartalert-cluster --region us-east-1
helm upgrade --install smartalert ./deployments/helm \
--set image.tag=${{ github.sha }} \
--set image.repository=123456789012.dkr.ecr.us-east-1.amazonaws.com/smartalert \
--namespace smartalert --create-namespace
- name: Verify Deployment
run: |
kubectl rollout status deployment/smartalert -n smartalert --timeout=5m
kubectl get pods -n smartalert -l app=smartalert
5.2 Hermes Agent Deployment Workflow
For more complex deployments, use Hermes Agent’s native deployment workflow:
name: "deploy-smartalert"
version: "1.0.0"
---
*Have questions? Join our [Discord community](https://discord.gg/smartotics) or follow us on [X](https://x.com/smartotics).*