| name | runbookhermes-aiops-agent |
| description | Hermes-native AIOps agent for evidence-driven incident response, approval-gated remediation, and runbook learning |
| triggers | ["set up runbookhermes for incident response","configure aiops agent with hermes","create incident response workflow with runbookhermes","integrate observability tools for automated remediation","build approval-gated remediation pipeline","generate runbook skills from incident data","deploy hermes agent for production incidents","configure evidence-driven root cause analysis"] |
RunbookHermes AIOps Agent Skill
Skill by ara.so — Hermes Skills collection.
RunbookHermes is a Hermes-native AIOps agent that specializes in incident response workflows. It extends Hermes Agent's runtime with evidence collection from observability tools (Prometheus, Loki, Jaeger), approval-gated remediation, checkpoint/rollback capabilities, and automatic runbook skill generation from resolved incidents.
What RunbookHermes Does
- Evidence-driven incident analysis: Collects metrics, logs, traces, and deployment history
- Approval-gated remediation: Requires human approval before risky actions
- Runbook learning: Converts successful incident resolutions into reusable skills
- Multi-channel intake: Accepts incidents from Web UI, Alertmanager, Feishu, WeCom, API
- EvidenceStack context engine: Compresses observability data for model reasoning
- IncidentMemory: Remembers service profiles, incident patterns, team preferences
Installation
Prerequisites
- Python 3.10+
- Hermes Agent (included as
agent/ subdirectory)
- Docker and Docker Compose (for local payment demo environment)
Clone and Install
git clone https://github.com/Tommy-yw/RunbookHermes.git
cd RunbookHermes
pip install -r requirements.txt
poetry install
Environment Configuration
Create .env file in project root:
OPENAI_API_KEY=${OPENAI_API_KEY}
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o
PROMETHEUS_URL=http://localhost:9090
LOKI_URL=http://localhost:3100
JAEGER_URL=http://localhost:16686
DEPLOY_BACKEND_TYPE=local_json
DEPLOY_HISTORY_PATH=./data/payment_demo/deploy_history.json
EXECUTION_BACKEND_TYPE=local_reference
EXECUTION_CONFIG_PATH=./data/payment_demo/execution_config.json
FEISHU_APP_ID=${FEISHU_APP_ID}
FEISHU_APP_SECRET=${FEISHU_APP_SECRET}
WECOM_CORP_ID=${WECOM_CORP_ID}
WECOM_AGENT_SECRET=${WECOM_AGENT_SECRET}
RUNBOOK_API_HOST=0.0.0.0
RUNBOOK_API_PORT=8000
Start Local Payment Demo Environment
cd demo/payment_system
docker-compose up -d
cd ../..
curl http://localhost:8001/health
curl http://localhost:8002/health
curl http://localhost:8003/health
Start RunbookHermes API Server
python -m apps.runbook_api.main
uvicorn apps.runbook_api.main:app --host 0.0.0.0 --port 8000 --reload
Access Web Console at http://localhost:8000
Core Concepts
1. Hermes Profile Integration
RunbookHermes runs as a Hermes Agent profile located at profiles/runbook-hermes/:
name: runbook-hermes
version: 1.0.0
description: AIOps agent for incident response
persona: incident_responder
tools:
- runbook-hermes
context_engine: evidence_stack
memory_provider: incident_memory
2. Evidence Collection Tools
The runbook-hermes tool plugin provides incident-response capabilities:
from plugins.runbook_hermes.tools import query_metrics
evidence = query_metrics(
service="payment-service",
metric_type="http_5xx_rate",
time_window="5m"
)
Available tools in the plugin:
query_metrics - Prometheus metrics collection
query_logs - Loki log search
query_traces - Jaeger trace analysis
get_deploy_history - Recent deployment records
create_checkpoint - Save system state before remediation
request_approval - Gate risky actions
execute_rollback - Controlled rollback execution
verify_recovery - Post-remediation health check
3. EvidenceStack Context Engine
Compresses observability data for model consumption:
from plugins.context_engine.evidence_stack.engine import EvidenceStackEngine
engine = EvidenceStackEngine()
engine.add_evidence({
"type": "metric",
"service": "payment-service",
"signal": "http_503_rate_spike",
"value": "45 req/s",
"severity": "critical"
})
context = engine.get_context()
4. IncidentMemory Provider
Stores operational knowledge:
from plugins.memory.incident_memory.provider import IncidentMemoryProvider
memory = IncidentMemoryProvider()
memory.save_service_profile("payment-service", {
"critical_metrics": ["http_5xx_rate", "p95_latency"],
"dependencies": ["coupon-service", "order-service"],
"rollback_safe": True
})
similar = memory.recall_similar_incidents(
service="payment-service",
symptom="http_503_spike"
)
Creating and Managing Incidents
Via Web Console
Navigate to http://localhost:8000/incidents/create and fill the form:
- Service name
- Severity (critical, high, medium, low)
- Description
- Alert data (optional)
Via API
import requests
response = requests.post("http://localhost:8000/api/incidents", json={
"service": "payment-service",
"severity": "critical",
"description": "HTTP 503 rate spike detected",
"alert": {
"metric": "http_5xx_rate",
"value": 45.2,
"threshold": 5.0
},
"metadata": {
"source": "alertmanager",
"runbook_url": "https://wiki.example.com/payment-503"
}
})
incident_id = response.json()["incident_id"]
Via Hermes CLI
hermes run \
--profile runbook-hermes \
--input "Payment service showing HTTP 503 errors at 45 req/s" \
--context '{"service": "payment-service", "severity": "critical"}'
Via Alertmanager Webhook
Configure Alertmanager to send webhooks:
receivers:
- name: runbook-hermes
webhook_configs:
- url: http://localhost:8000/gateway/alertmanager
send_resolved: true
Approval Workflow
RunbookHermes gates risky actions behind approval:
from runbook_hermes.approval import ApprovalManager
approval_mgr = ApprovalManager()
approval_id = approval_mgr.request_approval(
incident_id="inc_001",
action_type="rollback",
target_service="payment-service",
target_version="v1.2.3",
risk_level="high",
reason="Rollback to last known good version due to 503 spike",
checkpoint_id="chk_001"
)
status = approval_mgr.get_status(approval_id)
if status == "approved":
execute_rollback(service="payment-service", version="v1.2.3")
Approve via Web Console
Navigate to http://localhost:8000/approvals to review and approve/reject pending actions.
Approve via API
requests.post(f"http://localhost:8000/api/approvals/{approval_id}/approve", json={
"operator": "alice",
"comment": "Approved after verifying checkpoint"
})
Checkpoint and Rollback
Create Checkpoint Before Remediation
from runbook_hermes.checkpoint import CheckpointManager
checkpoint_mgr = CheckpointManager()
checkpoint = checkpoint_mgr.create(
incident_id="inc_001",
service="payment-service",
snapshot_type="deployment",
metadata={
"current_version": "v1.2.4",
"replica_count": 3,
"config_hash": "abc123"
}
)
Execute Rollback
from runbook_hermes.remediation import RemediationExecutor
executor = RemediationExecutor()
result = executor.rollback(
service="payment-service",
target_version="v1.2.3",
checkpoint_id=checkpoint.id,
dry_run=False
)
recovery_status = executor.verify_recovery(
service="payment-service",
expected_metrics={"http_5xx_rate": "<5"}
)
Runbook Skill Generation
After resolving an incident, generate a reusable skill:
from runbook_hermes.skills import SkillGenerator
generator = SkillGenerator()
skill = generator.generate_from_incident(
incident_id="inc_001",
skill_name="payment-http-503-rollback",
trigger_conditions=["payment service 503 spike", "payment 5xx rate > 40"],
steps=[
"collect_evidence",
"verify_deploy_change",
"create_checkpoint",
"request_approval",
"rollback_deployment",
"verify_recovery"
]
)
skill.save("skills/runbooks/payment-http-503-rollback.yaml")
Generated skill format:
name: payment-http-503-rollback
version: 1.0.0
triggers:
- payment service 503 spike
- payment 5xx rate > 40
steps:
- name: collect_evidence
tool: query_metrics
params:
service: payment-service
metric: http_5xx_rate
- name: verify_deploy_change
tool: get_deploy_history
params:
service: payment-service
limit: 5
- name: create_checkpoint
tool: create_checkpoint
- name: request_approval
tool: request_approval
risk_level: high
- name: rollback_deployment
tool: execute_rollback
Observability Integration
Prometheus Metrics
from integrations.observability.prometheus_adapter import PrometheusAdapter
prom = PrometheusAdapter(base_url="http://localhost:9090")
result = prom.query_range(
query='rate(http_requests_total{status=~"5..", service="payment-service"}[5m])',
start="-15m",
end="now",
step="30s"
)
if result.has_spike(threshold=5.0):
evidence = {
"type": "metric",
"signal": "http_5xx_spike",
"max_value": result.max_value(),
"timestamp": result.max_timestamp()
}
Loki Logs
from integrations.observability.loki_adapter import LokiAdapter
loki = LokiAdapter(base_url="http://localhost:3100")
logs = loki.query_range(
query='{service="payment-service"} |= "error" | json',
start="-15m",
limit=100
)
error_patterns = logs.extract_patterns(min_frequency=5)
Jaeger Traces
from integrations.observability.jaeger_adapter import JaegerAdapter
jaeger = JaegerAdapter(base_url="http://localhost:16686")
traces = jaeger.search_traces(
service="payment-service",
start="-15m",
min_duration="500ms",
limit=20
)
for trace in traces.with_errors():
root_cause_span = trace.find_slowest_span()
Running Hermes Agent with RunbookHermes Profile
Direct CLI Invocation
hermes run \
--profile runbook-hermes \
--input "Payment service p95 latency is 2.5s, normal is 200ms" \
--verbose
hermes run \
--profile runbook-hermes \
--input "Check payment service deployment history" \
--tools query_metrics,get_deploy_history
Programmatic Invocation
from agent.runtime import HermesRuntime
from agent.config import AgentConfig
config = AgentConfig(
profile="runbook-hermes",
tools=["runbook-hermes"],
context_engine="evidence_stack",
memory_provider="incident_memory"
)
runtime = HermesRuntime(config)
response = runtime.run(
input_text="Investigate payment-service HTTP 503 spike",
context={
"service": "payment-service",
"incident_id": "inc_001",
"severity": "critical"
}
)
print(response.final_answer)
print(response.evidence_chain)
print(response.recommended_actions)
Common Patterns
Pattern 1: Full Incident Response Workflow
from runbook_hermes.workflow import IncidentResponseWorkflow
workflow = IncidentResponseWorkflow()
result = workflow.execute(
service="payment-service",
symptom="http_503_spike",
severity="critical",
auto_approve=False
)
print(f"Root cause: {result.root_cause}")
print(f"Remediation: {result.remediation_action}")
print(f"Status: {result.status}")
Pattern 2: Evidence-Driven Diagnosis
from runbook_hermes.diagnosis import EvidenceDiagnosis
diagnosis = EvidenceDiagnosis(service="payment-service")
diagnosis.collect_metrics(time_window="15m")
diagnosis.collect_logs(time_window="15m", error_only=True)
diagnosis.collect_traces(time_window="15m", min_duration="500ms")
diagnosis.collect_deploy_history(limit=10)
root_cause = diagnosis.analyze()
print(f"Most likely cause: {root_cause.hypothesis}")
print(f"Confidence: {root_cause.confidence}")
print(f"Supporting evidence: {root_cause.evidence_ids}")
Pattern 3: Safe Remediation with Approval
from runbook_hermes.remediation import SafeRemediation
remediation = SafeRemediation(incident_id="inc_001")
plan = remediation.plan_rollback(
service="payment-service",
target_version="v1.2.3"
)
checkpoint = remediation.create_checkpoint()
approval = remediation.request_approval(
action=plan,
checkpoint=checkpoint,
timeout_minutes=30
)
if approval.is_approved():
dry_run_result = remediation.execute(dry_run=True)
if dry_run_result.success:
result = remediation.execute(dry_run=False)
if remediation.verify_recovery():
print("Remediation successful")
else:
remediation.restore_checkpoint(checkpoint.id)
Pattern 4: Multi-Service Impact Analysis
from runbook_hermes.topology import ServiceTopology
topology = ServiceTopology()
graph = topology.build_graph(
root_service="payment-service",
depth=2
)
impact = topology.analyze_impact(
failing_service="payment-service",
failure_type="http_503"
)
print(f"Directly impacted: {impact.direct}")
print(f"Indirectly impacted: {impact.indirect}")
print(f"Suggested investigation order: {impact.priority_list}")
Configuration Reference
RunbookHermes Config File
Create config/runbook_hermes.yaml:
incident:
auto_create_from_alert: true
default_severity: high
evidence_collection_timeout: 300
evidence:
metrics:
enabled: true
time_window: 15m
retention_days: 30
logs:
enabled: true
max_lines: 1000
error_patterns_only: false
traces:
enabled: true
sample_limit: 100
min_duration: 200ms
approval:
required_for:
- rollback
- restart
- config_change
- scale_down
auto_approve_on_critical: false
approval_timeout_minutes: 30
require_checkpoint: true
remediation:
dry_run_first: true
verify_recovery:
Tool Configuration
tools:
query_metrics:
timeout: 30
max_results: 1000
query_logs:
timeout: 60
max_lines: 5000
query_traces:
timeout: 45
max_traces: 200
execute_rollback:
require_approval: true
require_checkpoint: true
dry_run_first: true
Troubleshooting
Issue: Evidence collection returns empty results
Cause: Observability backends not reachable or no data in time window
Solution:
from integrations.observability.health import check_backends
health = check_backends()
print(f"Prometheus: {health['prometheus']}")
print(f"Loki: {health['loki']}")
print(f"Jaeger: {health['jaeger']}")
evidence = query_metrics(
service="payment-service",
time_window="1h"
)
Issue: Approval requests timeout
Cause: No operator reviewing approvals in time
Solution:
approval:
approval_timeout_minutes: 60
fallback_to_auto_reject: false
notification:
on_approval_request:
- type: feishu
webhook_url: ${FEISHU_APPROVAL_WEBHOOK}
Issue: Runbook skills not generating
Cause: Incident not marked as resolved or missing evidence
Solution:
from runbook_hermes.incident import IncidentManager
mgr = IncidentManager()
mgr.mark_resolved(
incident_id="inc_001",
resolution="Rolled back to v1.2.3",
root_cause="Bad deployment v1.2.4"
)
from runbook_hermes.skills import SkillGenerator
generator = SkillGenerator()
skill = generator.generate_from_incident("inc_001")
skill.save()
Issue: Model-assisted summaries failing
Cause: Model API key not configured or endpoint unreachable
Solution:
echo $OPENAI_API_KEY
echo $OPENAI_BASE_URL
curl $OPENAI_BASE_URL/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
model:
enabled: false
Issue: Hermes profile not found
Cause: Profile directory not in Hermes search path
Solution:
export HERMES_PROFILE_PATH="./profiles/runbook-hermes:$HERMES_PROFILE_PATH"
cp -r profiles/runbook-hermes ~/.hermes/profiles/
Debug Mode
Enable verbose logging:
import logging
logging.basicConfig(level=logging.DEBUG)
export RUNBOOK_HERMES_LOG_LEVEL=DEBUG
hermes run \
--profile runbook-hermes \
--input "Debug payment service issue" \
--debug \
--trace-tools
Advanced Usage
Custom Tool Integration
Add domain-specific tools:
from agent.tools import Tool, ToolParameter
class CheckDatabaseConnectionTool(Tool):
name = "check_database_connection"
description = "Verify database connectivity and connection pool status"
parameters = [
ToolParameter(name="service", type="string", required=True),
ToolParameter(name="db_name", type="string", required=True)
]
def execute(self, service: str, db_name: str) -> dict:
return {
"status": "healthy",
"active_connections": 25,
"max_connections": 100
}
from plugins.runbook_hermes.registry import register_tool
register_tool(CheckDatabaseConnectionTool())
Custom Evidence Type
from runbook_hermes.evidence import EvidenceCollector
class CostEvidenceCollector(EvidenceCollector):
def collect(self, service: str, time_window: str) -> dict:
return {
"type": "cost_spike",
"service": service,
"cost_increase_pct": 150,
"period": time_window
}
from runbook_hermes.evidence import register_collector
register_collector("cost", CostEvidenceCollector())
This skill enables AI coding agents to help developers deploy, configure, and operate RunbookHermes for production incident response with Hermes Agent integration.