Eve AI is a production-grade, fully automated technical blog generator. It leverages advanced LLMs (via OpenRouter), LangGraph for workflow orchestration, and Gemini image models for diagram generation. The system is engineered for reliability, extensibility, and high-quality technical content creation with minimal human intervention.
- Automated Blog Generation: From a single topic prompt, Eve AI produces a multi-section, well-structured technical blog post.
- Research Integration: Optionally performs web research using Tavily, deduplicates sources, and grounds content in up-to-date evidence.
- Section Planning: Uses LLMs to create actionable outlines with goals, bullets, and word targets for each section.
- Parallelized Writing: Each section is written independently, allowing for scalable and fast content generation.
- Image Planning & Generation: Decides where technical diagrams are needed, generates prompts, and uses Gemini via OpenRouter to create and insert images.
- LangGraph Orchestration: All steps are managed as a robust, stateful graph, enabling modularity, error handling, and extensibility.
- Rate Limiting & Concurrency Control: Built-in mechanisms to avoid API abuse and ensure smooth operation.
- Comprehensive Logging: Rotating logs for debugging and auditability.
- CLI & API Ready: Usable as a command-line tool or as a Python module.
The core workflow is modeled as a directed acyclic graph (DAG) using LangGraph:
START
|
[router] --(needs_research?)--> [research]
| |
+-----------------------------+ |
| v
[orchestrator]
|
[fanout]
|
[worker] (parallel for each section)
|
[reducer subgraph]
|
END
[merge_content] -> [decide_images] -> [generate_and_place_images]
- merge_content: Merges all section markdown into a single document.
- decide_images: Uses an LLM to decide where images/diagrams are needed and generates prompts/placeholders.
- generate_and_place_images: Calls OpenRouter Gemini to generate images, saves them, and replaces placeholders with markdown image links.
- router_node: Decides if research is needed and generates search queries.
- research_node: Uses Tavily to fetch and deduplicate relevant web evidence.
- orchestrator_node: Plans the blog structure (sections, goals, bullets, word counts).
- fanout: Splits the plan into independent section-writing tasks.
- worker_node: Writes each section using the plan and evidence.
- merge_content: Merges all sections into a single markdown document.
- decide_images: Determines where images are needed and what they should depict.
- generate_and_place_images: Generates images using OpenRouter Gemini and inserts them into the markdown.
- Uses a custom
RateLimiterclass with a semaphore and minimum interval between API calls. - Prevents API overload and ensures compliance with OpenRouter and Tavily rate limits.
- All nodes are wrapped with try/except and log errors with stack traces.
- Graceful fallback for image generation: if an image fails, a markdown block with the error and prompt is inserted.
- Rotating file and console logging via Python's
loggingandRotatingFileHandler. - Logs all major events, errors, and API interactions.
- All secrets and API keys are loaded from
.env(never committed to git). - Model names, limits, and timeouts are configurable via the
Configclass.
- Uses OpenRouter's Gemini image models (
google/gemini-3-pro-image-previeworgoogle/gemini-2.5-flash-image-preview). - Handles all OpenRouter response formats (base64, URL, nested structures).
- Images are saved to the
images/directory and referenced in the markdown.
- All data structures (tasks, plans, evidence, images) are validated with Pydantic models.
- Ensures strict contract between LLM outputs and downstream processing.
- Run from the command line:
python backend.py "Your blog topic here" - Options for log level and date override.
eve_AI/
├── backend.py # Main backend and CLI
├── app.py # Streamlit or web UI (optional)
├── .env # API keys (not committed)
├── .gitignore # Excludes .env, venv, __pycache__, images, logs, etc.
├── images/ # Generated images
├── logs/ # Log files
├── experiments/ # Notebooks and research
└── README.md # This file
-
Clone the repo and install dependencies
git clone https://github.com/yourusername/eve_AI.git cd eve_AI pip install -r requirements.txt -
Set up your
.envfileOPEN_ROUTER_API_KEY=your-openrouter-key TAVILY_API_KEY=your-tavily-key -
Run the generator
python backend.py "How async tools impact Python development" -
Output
- Markdown blog file in the project root.
- Images in the
images/directory. - Logs in
blog_generator.log.
- Add new nodes: Just define a function and add it to the LangGraph.
- Change models: Update the
Configclass. - Tune prompts: Edit the system prompt strings for each node.
- Swap image model: Change
config.image_modelto any OpenRouter-supported image model.
- Never commit
.envor API keys. - All generated content and logs are excluded from git via
.gitignore. - Handles API errors and rate limits gracefully.
- LangGraph
- LangChain
- OpenRouter
- Tavily
- Pydantic
- Python-dotenv
- Requests
- Streamlit (optional, for UI)
- Markdown blog:
mastering_async_tools_in_python_a_complete_tutorial_and_their_impact_on_modern_development.md - Images:
images/async_sync_execution_comparison.pngimages/asyncio_performance_security.pngimages/async_tools_impact_python_ecosystem.png
MIT License
- Your Name
- Contributions welcome!
- Inspired by the LangGraph and OpenRouter communities.
- Thanks to all open-source contributors.