Hermes Agent Tutorial Part 6: Building a Complete AI Workflow — Automated Daily Tech News Digest
In Parts 1 through 3 of this series, we covered installation and configuration, multi-role systems and skill management, and cron jobs with automated workflows. In this sixth installment, we bring everything together into a single, production-ready project: an automated daily tech news digest system that scrapes headlines, analyzes them through multiple expert lenses, generates a structured report, and delivers it to your team chat every morning.
This is not a toy example. By the end of this guide, you will have a fully functional automation pipeline that demonstrates how Hermes Agent’s roles, skills, scheduler, and delivery channels work in concert to solve real-world problems.
Table of Contents
- Project Overview
- Architecture and Data Flow
- Prerequisites
- Step 1: Configure the Environment
- Step 2: Build the News Fetcher Skill
- Step 3: Define the Expert Roles
- Step 4: Create the Analysis Pipeline
- Step 5: Schedule the Cron Job
- Step 6: Configure Delivery Channels
- Step 7: Testing and Validation
- Full Project Files
- Extending the Project
- Conclusion
Project Overview
The goal is simple: every weekday at 8:00 AM, the agent fetches the latest technology news from multiple RSS feeds and APIs, runs the headlines through two specialized experts — an AI Expert and an Investment Expert — synthesizes their analyses into a unified markdown report, and pushes the result to a Feishu group chat (with Slack as a fallback).
What You Will Learn
- How to build a custom skill that fetches and normalizes external data
- How to define specialized roles with domain-specific prompts and tool access
- How to orchestrate multi-role collaboration within a single automated task
- How to schedule and manage a complex cron job with skills and delivery channels
- How to test, debug, and monitor a production-ready automation pipeline
Architecture and Data Flow
The system follows a four-stage pipeline:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 1. FETCH │────▶│ 2. ANALYZE │────▶│ 3. SYNTHESIZE │────▶│ 4. DELIVER │
│ News Headlines │ │ Multi-Expert │ │ Merge Reports │ │ Feishu/Slack │
└─────────────────┘ └──────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
RSS/API fetcher AI Expert Report generator Feishu bot
Skill: news-fetch Investment Expert Skill: report-merge Slack webhook
Stage 1 — Fetch: A custom news-fetch skill retrieves headlines from configured sources and stores them as a normalized JSON file.
Stage 2 — Analyze: Two expert roles independently analyze the headlines. The AI Expert focuses on technical significance, research impact, and engineering implications. The Investment Expert focuses on market signals, funding events, and competitive dynamics.
Stage 3 — Synthesize: A synthesis role merges both analyses into a single coherent report with executive summary, detailed findings, and actionable takeaways.
Stage 4 — Deliver: The final report is formatted as markdown and sent to the configured Feishu group (or Slack channel) with proper threading and tagging.
Prerequisites
Before starting, ensure you have:
- Hermes Agent installed and configured (see Part 1)
- A valid API key for your LLM provider (OpenAI, Anthropic, or local inference)
- Feishu bot credentials (webhook URL or bot token) or a Slack webhook URL
- Python 3.10+ with
requests,feedparser, andbeautifulsoup4installed - Network access to tech news RSS feeds (TechCrunch, Ars Technica, The Verge, etc.)
Install the Python dependencies:
pip install requests feedparser beautifulsoup4
Step 1: Configure the Environment
Create a dedicated workspace for this project. This keeps all files isolated and version-controllable.
mkdir -p ~/.hermes/projects/news-digest/{skills,roles,data,logs}
export NEWS_DIGEST_DIR="$HOME/.hermes/projects/news-digest"
Update your main ~/.hermes/config.yaml to include the project workspace and enable the required toolsets:
# ~/.hermes/config.yaml
agent:
name: "news-digest-agent"
role: "orchestrator"
log_level: "info"
workspace: "~/.hermes/projects/news-digest"
llm:
provider: "openai"
model: "gpt-4o"
api_key: "${OPENAI_API_KEY}"
temperature: 0.5
max_tokens: 4096
timeout_seconds: 120
skills:
directory: "~/.hermes/skills"
auto_load: true
allowed:
- "news-fetch"
- "report-merge"
- "web-scraping"
toolsets:
- "web"
- "filesystem"
- "feishu"
- "slack"
scheduler:
enabled: true
timezone: "UTC"
jobs_file: "~/.hermes/jobs.yaml"
mcp:
enabled: true
servers:
- name: "filesystem"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "~/.hermes/projects/news-digest/data"]
logging:
directory: "~/.hermes/projects/news-digest/logs"
max_files: 30
format: "json"
Validate the configuration:
hermes config validate
Step 2: Build the News Fetcher Skill
The news-fetch skill is responsible for collecting headlines from multiple sources, deduplicating them, and writing a normalized JSON file for downstream analysis.
Skill Directory Structure
mkdir -p ~/.hermes/skills/news-fetch
Skill Manifest
Create ~/.hermes/skills/news-fetch/skill.yaml:
name: "news-fetch"
version: "1.0.0"
description: "Fetches and normalizes tech news headlines from RSS feeds and APIs"
author: "your-name"
roles:
- "orchestrator"
- "ai"
- "investment"
dependencies: []
tools:
- "terminal"
- "file_manager"
entrypoint: "fetch.py"
auto_activate: false
context_budget: 400
Skill Implementation
Create ~/.hermes/skills/news-fetch/fetch.py:
#!/usr/bin/env python3
"""
news-fetch skill: Collects tech news from RSS feeds and writes normalized JSON.
"""
import json
import sys
import hashlib
from datetime import datetime, timezone
from pathlib import Path
import feedparser
import requests
from bs4 import BeautifulSoup
# Configurable source list
SOURCES = {
"techcrunch": "https://techcrunch.com/feed/",
"ars-technica": "https://feeds.arstechnica.com/arstechnica/index",
"the-verge": "https://www.theverge.com/rss/index.xml",
"wired": "https://www.wired.com/feed/rss",
}
OUTPUT_DIR = Path.home() / ".hermes" / "projects" / "news-digest" / "data"
MAX_HEADLINES_PER_SOURCE = 10
def fetch_rss(url: str, source_name: str) -> list[dict]:
"""Fetch and parse an RSS feed, returning normalized headline dicts."""
headlines = []
try:
feed = feedparser.parse(url)
for entry in feed.entries[:MAX_HEADLINES_PER_SOURCE]:
title = entry.get("title", "").strip()
link = entry.get("link", "").strip()
published = entry.get("published", "")
summary = entry.get("summary", "")
# Clean HTML from summary
summary_text = BeautifulSoup(summary, "html.parser").get_text(separator=" ", strip=True)
# Generate a stable ID from title + source
item_id = hashlib.sha256(f"{source_name}:{title}".encode()).hexdigest()[:16]
headlines.append({
"id": item_id,
"source": source_name,
"title": title,
"url": link,
"published": published,
"summary": summary_text[:500],
"fetched_at": datetime.now(timezone.utc).isoformat(),
})
except Exception as exc:
print(f"[ERROR] Failed to fetch {source_name}: {exc}", file=sys.stderr)
return headlines
def fetch_all() -> list[dict]:
"""Fetch headlines from all configured sources and deduplicate."""
all_headlines = []
seen_ids = set()
for source_name, url in SOURCES.items():
print(f"[INFO] Fetching {source_name}...")
for item in fetch_rss(url, source_name):
if item["id"] not in seen_ids:
seen_ids.add(item["id"])
all_headlines.append(item)
# Sort by fetch time (newest first)
all_headlines.sort(key=lambda x: x["fetched_at"], reverse=True)
return all_headlines
def save_headlines(headlines: list[dict]) -> Path:
"""Persist headlines to a timestamped JSON file."""
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
filepath = OUTPUT_DIR / f"headlines_{timestamp}.json"
with open(filepath, "w", encoding="utf-8") as f:
json.dump({
"meta": {
"generated_at": datetime.now(timezone.utc).isoformat(),
"source_count": len(SOURCES),
"headline_count": len(headlines),
},
"headlines": headlines,
}, f, indent=2, ensure_ascii=False)
print(f"[INFO] Saved {len(headlines)} headlines to {filepath}")
return filepath
if __name__ == "__main__":
headlines = fetch_all()
if not headlines:
print("[WARN] No headlines fetched. Check network connectivity and source URLs.", file=sys.stderr)
sys.exit(1)
out_path = save_headlines(headlines)
print(out_path)
Make the script executable:
chmod +x ~/.hermes/skills/news-fetch/fetch.py
Test the skill manually:
python3 ~/.hermes/skills/news-fetch/fetch.py
You should see output similar to:
[INFO] Fetching techcrunch...
[INFO] Fetching ars-technica...
[INFO] Fetching the-verge...
[INFO] Fetching wired...
[INFO] Saved 32 headlines to /root/.hermes/projects/news-digest/data/headlines_20260620_080000.json
Step 3: Define the Expert Roles
We need three roles for this pipeline: the AI Expert, the Investment Expert, and an Orchestrator that manages the synthesis.
AI Expert Role
Create ~/.hermes/roles/ai-expert.yaml:
name: "ai-expert"
description: "Expert in artificial intelligence, machine learning, and software engineering trends"
system_prompt: |
You are a senior AI researcher and engineer with deep expertise in machine learning,
large language models, computer vision, robotics, and MLOps.
When analyzing tech news headlines:
1. Identify which stories have genuine technical significance versus hype
2. Assess the maturity of any mentioned technologies (research, prototype, production)
3. Note implications for practitioners: new tools, deprecated approaches, emerging standards
4. Highlight any open-source releases, benchmark results, or reproducible claims
5. Flag potential misinformation or exaggerated claims
Format your analysis as structured markdown with these sections:
- **Key Technical Stories** (ranked by significance)
- **Emerging Trends** (patterns across multiple headlines)
- **Practitioner Impact** (what engineers should know)
- **Skeptic's Corner** (claims that need verification)
default_skills:
- "news-fetch"
- "web-scraping"
tool_preferences:
terminal: true
file_manager: true
web: true
context_window:
preferred: 16000
min: 8000
Investment Expert Role
Create ~/.hermes/roles/investment-expert.yaml:
name: "investment-expert"
description: "Expert in technology investing, market analysis, and startup evaluation"
system_prompt: |
You are a technology-focused venture capitalist with 15 years of experience
evaluating startups, market trends, and competitive dynamics.
When analyzing tech news headlines:
1. Identify funding rounds, acquisitions, and IPO signals
2. Assess market positioning and competitive threats
3. Evaluate business model viability and unit economics mentions
4. Note regulatory risks or tailwinds
5. Highlight contrarian opportunities or overvalued sectors
Format your analysis as structured markdown with these sections:
- **Funding & M&A Activity** (deals, valuations, investors)
- **Market Signals** (trends that affect valuations)
- **Competitive Dynamics** (winners, losers, shifts)
- **Investment Thesis Updates** (how today's news changes your view)
- **Risk Alerts** (regulatory, macro, or sector-specific risks)
default_skills:
- "news-fetch"
- "web-scraping"
tool_preferences:
terminal: true
file_manager: true
web: true
context_window:
preferred: 16000
min: 8000
Orchestrator Role
Create ~/.hermes/roles/orchestrator.yaml:
name: "orchestrator"
description: "Coordinates multi-expert analysis and synthesizes unified reports"
system_prompt: |
You are a project orchestrator responsible for coordinating multiple domain experts
and producing unified, actionable reports.
Your workflow:
1. Read the raw headline data
2. Delegate technical analysis to the AI Expert
3. Delegate market analysis to the Investment Expert
4. Synthesize both analyses into a single coherent report
5. Ensure the final output is concise, well-structured, and suitable for busy executives
The final report must include:
- **Executive Summary** (3-4 bullet points, under 100 words total)
- **AI Expert Findings** (summarized, not verbatim)
- **Investment Expert Findings** (summarized, not verbatim)
- **Cross-Domain Insights** (where technical and market analysis intersect)
- **Recommended Actions** (specific, time-bounded recommendations)
Tone: professional, concise, no fluff. Use markdown formatting for readability.
default_skills:
- "news-fetch"
- "report-merge"
tool_preferences:
terminal: true
file_manager: true
context_window:
preferred: 32000
min: 16000
Step 4: Create the Analysis Pipeline
The analysis pipeline is a single cron job that uses the orchestrator role to drive the entire process. The orchestrator’s prompt instructs it to invoke the news-fetch skill, delegate analysis to the two experts, and synthesize the final report.
The Report Merge Skill
Create a lightweight skill to help with report formatting:
mkdir -p ~/.hermes/skills/report-merge
cat > ~/.hermes/skills/report-merge/skill.yaml << 'EOF'
name: "report-merge"
version: "1.0.0"
description: "Merges multiple analysis sections into a unified markdown report"
author: "your-name"
roles:
- "orchestrator"
entrypoint: "merge.py"
auto_activate: false
EOF
cat > ~/.hermes/skills/report-merge/merge.py << 'EOF'
#!/usr/bin/env python3
import sys
from datetime import datetime, timezone
def merge_report(sections: list[str], title: str = "Daily Tech Digest") -> str:
header = f"# {title}\n\n**Generated:** {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}\n\n---\n\n"
body = "\n\n---\n\n".join(sections)
footer = "\n\n---\n\n*This report was generated automatically by Hermes Agent.*"
return header + body + footer
if __name__ == "__main__":
# Read sections from stdin, separated by double newlines
raw = sys.stdin.read()
sections = [s.strip() for s in raw.split("\n\n---\n\n") if s.strip()]
print(merge_report(sections))
EOF
chmod +x ~/.hermes/skills/report-merge/merge.py
Step 5: Schedule the Cron Job
Now we define the master cron job that runs the entire pipeline. Create or edit ~/.hermes/jobs.yaml:
jobs:
- name: "daily-tech-news-digest"
schedule: "0 8 * * 1-5"
role: "orchestrator"
enabled: true
task: |
Run the daily tech news digest pipeline:
1. Execute the news-fetch skill to collect today's headlines.
Save the output JSON path.
2. Read the headlines file and present the top 20 stories to the AI Expert.
Ask for a structured technical analysis.
3. Present the same headlines to the Investment Expert.
Ask for a structured market and investment analysis.
4. Use the report-merge skill to combine both analyses into a single
markdown document with an executive summary.
5. Save the final report to ~/.hermes/projects/news-digest/data/daily_report.md
6. Deliver the report via Feishu to the configured group chat.
If Feishu fails, fallback to Slack.
skills:
- "news-fetch"
- "report-merge"
toolsets:
- "web"
- "filesystem"
- "feishu"
- "slack"
delivery:
channel: "feishu"
target: "${FEISHU_GROUP_CHAT_ID}"
format: "markdown"
fallback_delivery:
channel: "slack"
target: "${SLACK_WEBHOOK_URL}"
format: "markdown"
timeout_seconds: 300
retries: 2
The schedule: "0 8 * * 1-5" ensures the job runs at 8:00 AM UTC, Monday through Friday only. Adjust the timezone or hour based on your team’s location.
Reload the scheduler to pick up the new job:
hermes scheduler reload
Verify the job is registered:
hermes scheduler list
Step 6: Configure Delivery Channels
Feishu (Lark) Setup
- Open your Feishu group chat and add a custom bot.
- Copy the webhook URL and extract the chat ID, or use a bot app with API credentials.
- Export the credentials in your shell profile:
export FEISHU_APP_ID="cli_xxxxxxxxxxxxxxxx"
export FEISHU_APP_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export FEISHU_GROUP_CHAT_ID="oc_xxxxxxxxxxxxxxxx"
Slack Setup (Fallback)
- Create an incoming webhook in your Slack workspace.
- Export the URL:
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
Testing Delivery
Before relying on the cron schedule, test delivery manually:
hermes run --task "Send a test message to Feishu saying 'Hermes Agent delivery test successful'" --role orchestrator
If the test message appears in your chat, the delivery channel is correctly configured.
Step 7: Testing and Validation
Manual Pipeline Test
Run the entire pipeline on demand to verify each stage:
hermes run --task "Run the daily tech news digest pipeline end-to-end" --role orchestrator
Watch the logs for errors:
tail -f ~/.hermes/projects/news-digest/logs/agent.log
Validate Each Stage
Stage 1 — Fetch: Confirm headlines_*.json is created in ~/.hermes/projects/news-digest/data/.
Stage 2 — Analysis: Check that the agent invokes both the AI Expert and Investment Expert roles. You should see context switches in the logs.
Stage 3 — Synthesis: Verify daily_report.md is generated and contains all required sections.
Stage 4 — Delivery: Confirm the report appears in your Feishu group with proper markdown rendering.
Common Issues and Fixes
| Issue | Cause | Fix |
|---|---|---|
| No headlines fetched | Network blocked or RSS changed | Verify URLs with curl, update SOURCES in fetch.py |
| Role switch fails | Role YAML syntax error | Run hermes config validate and check indentation |
| Feishu message not sent | Missing credentials | Verify FEISHU_APP_ID and FEISHU_APP_SECRET are exported |
| Report too long | LLM output exceeds token limit | Reduce MAX_HEADLINES_PER_SOURCE or summarize before synthesis |
| Scheduler not firing | Scheduler daemon not running | Start with hermes scheduler start --daemon |
Full Project Files
For convenience, here is a consolidated view of every file created in this project.
~/.hermes/config.yaml
agent:
name: "news-digest-agent"
role: "orchestrator"
log_level: "info"
workspace: "~/.hermes/projects/news-digest"
llm:
provider: "openai"
model: "gpt-4o"
api_key: "${OPENAI_API_KEY}"
temperature: 0.5
max_tokens: 4096
timeout_seconds: 120
skills:
directory: "~/.hermes/skills"
auto_load: true
allowed:
- "news-fetch"
- "report-merge"
- "web-scraping"
toolsets:
- "web"
- "filesystem"
- "feishu"
- "slack"
scheduler:
enabled: true
timezone: "UTC"
jobs_file: "~/.hermes/jobs.yaml"
mcp:
enabled: true
servers:
- name: "filesystem"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "~/.hermes/projects/news-digest/data"]
logging:
directory: "~/.hermes/projects/news-digest/logs"
max_files: 30
format: "json"
~/.hermes/skills/news-fetch/skill.yaml
name: "news-fetch"
version: "1.0.0"
description: "Fetches and normalizes tech news headlines from RSS feeds and APIs"
author: "your-name"
roles:
- "orchestrator"
- "ai"
- "investment"
dependencies: []
tools:
- "terminal"
- "file_manager"
entrypoint: "fetch.py"
auto_activate: false
context_budget: 400
~/.hermes/skills/news-fetch/fetch.py
See the full implementation in Step 2.
~/.hermes/skills/report-merge/skill.yaml
name: "report-merge"
version: "1.0.0"
description: "Merges multiple analysis sections into a unified markdown report"
author: "your-name"
roles:
- "orchestrator"
entrypoint: "merge.py"
auto_activate: false
~/.hermes/roles/ai-expert.yaml
See the full implementation in Step 3.
~/.hermes/roles/investment-expert.yaml
See the full implementation in Step 3.
~/.hermes/roles/orchestrator.yaml
See the full implementation in Step 3.
~/.hermes/jobs.yaml
See the full implementation in Step 5.
Extending the Project
Once the basic pipeline is stable, consider these enhancements:
Add More News Sources
Extend SOURCES in fetch.py to include industry-specific feeds (AI research, biotech, climate tech). You can also add API-based sources like NewsAPI or Hacker News.
Add a Third Expert
Create a Policy Expert role that analyzes regulatory implications. This is valuable for teams in regulated industries.
Add Sentiment Analysis
Use a lightweight NLP model to score headline sentiment and include a sentiment trend chart in the report.
Archive and Search
Store historical reports in a vector database and add a /search command to the Feishu bot that answers questions like “What did we say about OpenAI last month?”
Multi-Language Support
Add a translation skill that generates localized versions of the report for global teams.
Interactive Follow-Up
Configure the Feishu bot to accept replies. When a user asks “Tell me more about story #3,” the agent fetches the full article and provides a deep-dive analysis.
Conclusion
This project demonstrates how Hermes Agent transforms from a conversational assistant into a fully autonomous operations partner. By combining:
- Custom skills for data acquisition (
news-fetch) - Specialized roles for domain expertise (
ai-expert,investment-expert) - Orchestration for synthesis (
orchestrator) - Cron scheduling for reliable automation
- Multi-channel delivery for team integration
…you have built a system that would traditionally require multiple separate tools, scripts, and services. Yet everything lives within a single, version-controllable Hermes Agent configuration.
The true power of this approach is composability. Each component — the fetcher, the experts, the merger, the scheduler — is independently testable and reusable. Tomorrow, you could repurpose the news-fetch skill for a competitive intelligence pipeline. You could redeploy the investment-expert role for startup due diligence. You could schedule the orchestrator to run weekly instead of daily. The architecture scales with your needs.
In the next part of this series, we will explore error handling and observability — how to make your production workflows resilient, debuggable, and auditable at scale.
Stay automated!