Skip to content

Instantly share code, notes, and snippets.

@whimo
Last active April 1, 2025 12:33
Show Gist options
  • Save whimo/dfd14a7b13899b1409f5c67cc45d01fd to your computer and use it in GitHub Desktop.
Save whimo/dfd14a7b13899b1409f5c67cc45d01fd to your computer and use it in GitHub Desktop.
Blog with images using Ray, batched
import os
import ray
from dotenv import load_dotenv
from langchain_community.tools import DuckDuckGoSearchRun
from ray.dag.input_node import InputNode
from motleycrew.agents.crewai import CrewAIMotleyAgent
from motleycrew.agents.langchain import ReActToolCallingMotleyAgent
from motleycrew.common import configure_logging
from motleycrew.tools.image.dall_e import DallEImageGeneratorTool
configure_logging(verbose=True)
load_dotenv()
@ray.remote
def produce_blog_post(topic: str):
configure_logging(verbose=True)
search_tool = DuckDuckGoSearchRun()
researcher = CrewAIMotleyAgent(
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in various fields, doing web search if necessary",
backstory="""You work at a leading tech think tank.
Your expertise lies in identifying emerging trends.
You have a knack for dissecting complex data and presenting actionable insights.""",
verbose=True,
tools=[search_tool],
)
writer = ReActToolCallingMotleyAgent(
name="AI writer agent",
tools=[researcher],
verbose=True,
)
prompt = f"""You are an experienced blog writer.
Conduct a comprehensive analysis of the latest advancements in {topic} in 2024.
Identify key trends, breakthrough technologies, and potential industry impacts.
Using the insights provided by a thorough research, develop an engaging blog post
that highlights the most significant advancements in {topic}.
Your post should be informative yet accessible, catering to a domain-savvy audience.
Make it sound cool, avoid complex words so it doesn't sound like AI.
Create a blog post of at least 4 paragraphs, in markdown format."""
blog_post = writer.invoke({"prompt": prompt})
return blog_post
@ray.remote
def create_illustrations(blog_post: str):
configure_logging(verbose=True)
image_generator_tool = DallEImageGeneratorTool(
os.path.realpath("./images"),
model="dall-e-3",
refine_prompt_with_llm=True,
size="1024x1024",
style="vivid",
)
illustrator = ReActToolCallingMotleyAgent(
name="Illustrator",
description="Create beautiful and insightful illustrations for a blog post",
tools=[image_generator_tool],
)
prompt = f"""Create beautiful and insightful illustrations to accompany the provided blog post on AI advancements.
The blog post will be provided to you in markdown format.
Make sure to use the illustration tool provided to you, once per illustration, and embed the URL provided by
the tool into the blog post.
Create between 2 and 3 illustrations, neither more nor less
Only return the full text of the blog post with embedded URLs, no backticks, no other text.
Only use slashes as path separators, never backslashes.
The blog post is:
{blog_post}"""
illustrated_blog_post = illustrator.invoke({"prompt": prompt})
return illustrated_blog_post
with InputNode() as topic:
blog_post_ref = produce_blog_post.bind(topic=topic) # Create writing node
illustrated_blog_post_ref = create_illustrations.bind(
blog_post=blog_post_ref
) # Create illustration node
topics = ["AI", "neuroscience", "astrophysics"]
blog_post_refs = [illustrated_blog_post_ref.execute(topic) for topic in topics] # Does not block
print("Dispatched posts creation")
blog_posts = ray.get(blog_post_refs) # Wait for all the posts
for topic, blog_post in zip(topics, blog_posts):
print(f"Blog post for {topic}:\n")
print(blog_post)
print("\n\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment