An autonomous AI content engine that researches trending technology, writes SEO-optimized articles, generates cover art, and publishes to Blogger and Facebook β every day, with zero human input.
This is one production pipeline, implemented two ways β a rare side-by-side study of the same real workload as a monolith and as a distributed multi-agent system. Both ship complete, tested, and deploy to Cloud Run with full CI/CD. You can run either locally in minutes and read the exact same business logic expressed in two architectural styles.
It's a working reference for the questions every agent team eventually asks:
- When is a single
SequentialAgentenough, and when do you split into services? - How does shared session state differ from passing JSON across an A2A boundary?
- How do you wire agent-to-agent auth, agent cards, and orchestration correctly?
The answer lives in code you can run, not slides.
Every day, automatically, the agent:
| # | Stage | How |
|---|---|---|
| 1 | Discovers a timely Google Cloud topic | Parallel scan of 4 feeds + Google News, deduped against post history |
| 2 | Writes a 1,000β2,000 word SEO article | Gemini 2.5 Flash with a validated BlogDraft schema |
| 3 | Generates a cover image | Imagen 4 β Cloud Storage |
| 4 | Publishes to Blogger | Blogger API v3, content-safety gated |
| 5 | Cross-posts to Facebook | Caption + link card, Graph API |
| 6 | Requests indexing | Google Indexing API ping for fast recrawl |
Live example: a daily-updated tech blog, fully operated by this agent.
Five sub-agents run in sequence inside a single Python process. Data flows through shared session state β no network hops, no serialization. One Docker image, one Cloud Run Job, one thing to monitor. This is the deployed default and the right choice for a fixed daily job.
Stack: ADK SequentialAgent + ParallelAgent Β· MCP (3 stdio servers) Β· Gemini 2.5 Flash Β· Imagen 4 Β· Blogger v3 Β· Facebook Graph Β· GCS Β· Indexing API.
The same five stages, regrouped into three independent specialist services coordinated by an orchestrator. Each specialist is its own Cloud Run Service that publishes an Agent Card and speaks the A2A protocol. The orchestrator is an LlmAgent whose only tool is send_message(agent_name, task) β it keeps control across all three delegations, feeding each result into the next call (the "agent-as-a-tool" pattern, not sub-agent transfer).
Stack: ADK LlmAgent + to_a2a + AgentCard + RemoteAgentConnections Β· A2A JSON-RPC Β· the same MCP servers, models, and APIs.
monolith/ |
a2a/ |
|
|---|---|---|
| Shape | 1 SequentialAgent, 5 sub-agents |
Orchestrator + 3 specialist services |
| Data between stages | Shared session state | JSON over the A2A network boundary |
| Deployables | 1 Cloud Run Job | 3 Cloud Run Services + 1 Job |
| CI/CD trigger | Auto on push to monolith/** |
Manual by default; auto-on-push opt-in |
| Service-to-service auth | N/A (one process) | Google ID token (USE_CLOUD_RUN_AUTH) |
| Scale-to-zero | Job exits when done | Services idle at zero between runs |
| Idle cost | ~$0 | ~$0 |
| Operational complexity | Low | Higher (4 services, cards, auth) |
| Best for | A fixed daily autonomous job | Reusable agents, dynamic routing, teams |
Both architectures reuse the exact same integration and tool code:
feed_server.pyβ GCP blog, release notes, training, Google News (MCP)blogger_server.pyβlist_recent_posts(dedup) +publish_post(MCP)facebook_server.pyβpost_to_pagewith caption sanitize + retry (MCP)imagen_tool.pyβ Imagen 4 cover image β GCSindexing_tool.pyβ Google Indexing API pingBlogDraftβ Pydantic schema validating the writer's outputpolicy_gateβ content-safety callback on every publish action- 12 GCP secrets β same Secret Manager names, injected into whichever runs
git clone https://github.com/faridmitri/DigitalCreatorAgent.git
cd DigitalCreatorAgent
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activatecd monolith
pip install -r requirements.txt
cp .env.example .env # fill in the 12 values
python run_agent.py # β publishes for real β run when readycd a2a
pip install -r requirements.txt
cp .env.example .env # same 12 values; keep USE_CLOUD_RUN_AUTH=false
# Terminals 1β3, one per specialist service:
uvicorn agents.researcher_agent.agent:a2a_app --host 127.0.0.1 --port 8001
uvicorn agents.writer_agent.agent:a2a_app --host 127.0.0.1 --port 8002
uvicorn agents.publisher_agent.agent:a2a_app --host 127.0.0.1 --port 8003
# Terminal 4 β drive the pipeline:
python -m orchestrator.runRun the offline test suites any time (no network, no publishing):
cd monolith && pytest tests/ -q
cd a2a && pytest tests/ -qBoth architectures ship with complete GitHub Actions CI/CD. See PLAYBOOK.MD for one-time GCP setup (APIs, Artifact Registry, the 12 secrets, Workload Identity Federation, IAM roles).
deploy-monolith.yml fires on every push to main touching monolith/**: it builds the image, pushes to Artifact Registry, and creates/updates the Cloud Run Job.
git add monolith/ && git commit -m "your change" && git push origin maindeploy-a2a.yml is workflow_dispatch-only by default β it never fires on push, so a routine push only ever deploys the monolith.
- GitHub β Actions β "Deploy A2A to Cloud Run"
- Run workflow β type
deployto confirm.
It builds all four images, deploys the three Services (--no-allow-unauthenticated, scale-to-zero), grants the orchestrator roles/run.invoker on each, and deploys the orchestrator Job with USE_CLOUD_RUN_AUTH=true.
Want A2A to auto-deploy too? Uncomment the
push:block at the top ofdeploy-a2a.yml(the file documents exactly what to change). If both workflows auto-deploy and both jobs are scheduled, the blog publishes twice daily β enable intentionally.
| Workflow | Trigger | Deploys |
|---|---|---|
deploy-monolith.yml |
Auto β push to main, paths monolith/** |
Cloud Run Job |
deploy-a2a.yml |
Manual β workflow_dispatch (auto-on-push opt-in) |
3 Cloud Run Services + 1 Job |
The three specialist services deploy --no-allow-unauthenticated. The orchestrator calls them with a Google ID token whose audience is each service's URL, handled automatically by _GoogleIdTokenAuth in orchestrator/remote_agent_connection.py when USE_CLOUD_RUN_AUTH=true (set by CI on the orchestrator job). Locally the flag defaults to false β plain HTTP, no tokens.
DigitalCreatorAgent/
βββ README.MD β you are here
βββ PLAYBOOK.MD β step-by-step: local run, GCP setup, deploy
βββ img/ β architecture + log screenshots
βββ .github/workflows/
β βββ deploy-monolith.yml β auto on push (monolith/**)
β βββ deploy-a2a.yml β manual; auto-on-push opt-in
β
βββ monolith/ β THE DEPLOYED SYSTEM
β βββ trend_agent/ β ADK agent package (5 sub-agents, MCP, tools)
β βββ run_agent.py β entrypoint
β βββ Dockerfile Β· requirements.txt Β· tests/ Β· .env.example
β
βββ a2a/ β DISTRIBUTED REFERENCE Β· ALSO DEPLOYABLE
βββ orchestrator/ β LlmAgent + send_message tool + auth
βββ agents/
β βββ researcher_agent/ β parallel discovery + finalizer
β βββ writer_agent/ β BlogDraft schema + SEO writer
β βββ publisher_agent/ β image β blogger β facebook β indexing
βββ common/ β shared prompts, MCP servers, tools, callbacks
βββ tests/ Β· .env.example Β· requirements.txt
| Monolith | A2A |
|---|---|
![]() |
![]() |
PLAYBOOK.MDβ every command: run locally, one-time GCP setup, deploy each architecture, schedule the daily job, and troubleshoot.
Built with Google ADK Β· Gemini 2.5 Β· Imagen 4 Β· MCP Β· A2A Β· Cloud Run Β· Secret Manager Β· Artifact Registry Β· Blogger v3 Β· Facebook Graph Β· Google Indexing API



