Agents team, better prompts, WIP

This commit is contained in:
ajaysi
2024-05-12 19:13:02 +05:30
parent f9b9204349
commit 6a95b96973
13 changed files with 392 additions and 90 deletions

View File

@@ -17,7 +17,8 @@ print("Loading, required libraries..")
app = typer.Typer()
from lib.utils.alwrity_utils import blog_from_audio, blog_from_keyword, do_web_research, do_web_research, ai_news_writer
from lib.utils.alwrity_utils import write_story, essay_writer, blog_tools, competitor_analysis, image_to_text_writer, image_generator
from lib.utils.alwrity_utils import write_story, essay_writer, blog_tools
from lib.utils.alwrity_utils import content_planning, competitor_analysis, image_to_text_writer, image_generator
def prompt_for_time_range():
@@ -100,8 +101,8 @@ def content_planning_tools():
choices = [
("Do keyword Research", "Keywords web research - 🤓 Will read & earn my bread.."),
("Competitor Analysis", "Competitor Analysis - 🧐What's my neighbour doing.."),
("Blog Titles", "🥹🥹 Just give me Topic titles")
("Competitor Analysis", "Competitor Analysis - 🧐 What's my neighbour doing.."),
("Content Calender", "🥹🥹 Just give me content calender 🥹🥹")
]
mode = radiolist_dialog(title="Choose an option:", values=choices).run()
@@ -110,6 +111,8 @@ def content_planning_tools():
do_web_research()
elif mode == 'Competitor Analysis':
competitor_analysis()
elif mode == 'Content Calender':
content_planning()
def check_search_apis():

View File

@@ -45,7 +45,6 @@ from urllib.parse import quote_plus
from tqdm import tqdm
from tabulate import tabulate
from pytrends.request import TrendReq
from wordcloud import WordCloud
from loguru import logger
# Configure logger

View File

@@ -74,7 +74,8 @@ def do_tavily_ai_search(search_keywords):
logger.info(f"Doing Tavily AI search for: {search_keywords}")
t_results = get_tavilyai_results(search_keywords)
t_titles = tavily_extract_information(t_results, 'titles')
return(t_results, t_titles)
t_answer = tavily_extract_information(t_results, 'answer')
return(t_results, t_titles, t_answer)
except Exception as err:
logger.error(f"Failed to do Tavily AI Search: {err}")

View File

@@ -99,7 +99,7 @@ def get_tavilyai_results(keywords):
def print_result_table(output_data):
""" Pretty print the tavily AI serch result. """
""" Pretty print the tavily AI search result. """
# Prepare data for tabulate
table_data = []
for item in output_data.get("results"):

View File

@@ -16,25 +16,25 @@ from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
def write_blog_google_serp(search_keyword, search_results):
"""Combine the given online research and gpt blog content"""
prompt = f"""
You are Alwrity, the Creative Content writer, writing up fresh ideas and crafts them with care and uniqueness.
She makes complex topics simple to understand and writes in a friendly, conversational tone that connects with everyone.
She excels at creating a introductions that attract users, to read more.
As a SEO expert and content writer, I will provide you with my 'web research keywords' and its 'google search result'.
As expert Creative Content writer, writing up fresh ideas with care and uniqueness.
I will provide you with my 'web research keywords' and its 'google search result'.
Your goal is to create detailed SEO-optimized content and also include 5 FAQs.
Follow below guidelines:
1). Your blog content should compete against all blogs from search results.
2). Your FAQ should be based on 'People also ask' and 'Related Queries' from given search result.
Always include answers for each FAQ, use your knowledge and confirm with snippets given in search result.
3). Act as subject matter expert for given research keywords: {search_keyword}.
4). Your blog should be highly formatted in markdown style and highly readable.
5). Always write in the first person.
6). Inject Your Unique Voice and Style: Add personal insights, anecdotes, or experiences to infuse authenticity and humanize the content, making it engaging and authentic.
4). Conversational tone: Write like you're chatting with a friend, making the topic approachable and interesting.
5). Your blog should be highly formatted in markdown style and highly readable.
6). Friendly tone: Write like you're talking to a friend, not giving a lecture.
7). Simple explanations: No robotic jargon! Make AI writing easy to understand.
8). Personal touch: Share your own experiences and opinions to make it relatable.
9). Examples and stories: Bring the topic to life with real-world examples.
\n\nWeb Research Keyword: "{search_keyword}"
Google search Result: "{search_results}"
Here are some Google search results to spark your creativity: "{search_results}".
But don't just rehash them - use your own voice and insights!
"""
logger.info("Generating blog and FAQs from Google web search results.")
try:
@@ -43,3 +43,70 @@ def write_blog_google_serp(search_keyword, search_results):
except Exception as err:
logger.error(f"Exit: Failed to get response from LLM: {err}")
exit(1)
def improve_blog_intro(blog_content, blog_intro):
"""Combine the given online research and gpt blog content"""
prompt = f"""
As an expert Content editor, I will provide you with my 'blog content' and its new 'blog introduction'.
Your goal is to replace the old introduction with the given new introduction.
Do Not change any other section of the blog content.
You must respond with the complete blog content with replaced introduction.
Do not provide explanations for your response.
\n\nBlog Content: "{blog_content}"
Blog Introduction: "{blog_intro}".
"""
logger.info("Generating blog introduction from tavily answer.")
try:
response = llm_text_gen(prompt)
return response
except Exception as err:
logger.error(f"Exit: Failed to get response from LLM: {err}")
exit(1)
def blog_with_keywords(blog, keywords):
"""Combine the given online research and gpt blog content"""
prompt = f"""
As an expert digital content writer, specializing in content optimization and SEO.
I will provide you with my 'blog content' and 'list of keywords' on the same topic.
Your task is to write an original blog, utilizing given keywords and blog content.
Your blog should be highly detailed and well formatted.
You are Sarah, the Creative Content writer, writing up fresh ideas and crafts them with care.
She makes complex topics easy to understand and writes in a friendly tone that connects with everyone.
She excels at simplifying complex topics and communicates with charisma, making technical jargon come alive for her audience.
Blog content: '{blog}'
list of keywords: '{keywords}'
"""
try:
response = llm_text_gen(prompt)
return response
except Exception as err:
logger.error(f"blog_with_keywords: Failed to get response from LLM: {err}")
raise err
def blog_with_research(report, blog):
"""Combine the given online research and gpt blog content"""
prompt = f"""
You are Alwrity, the Creative Content writer, writing up fresh ideas and crafts them with care and uniqueness.
She makes complex topics simple to understand and writes in a friendly, conversational tone that connects with everyone.
She excels at simplifying complex topics and writes in the first person, for her audience.
I will provide you with a latest 'research report' and a outdated 'blog content' on the same topic.
Your task is to update the given blog content, using the new research report, as context.
\n\nResearch report: '{report}'
\n\nBlog content: '{blog}'
"""
try:
response = llm_text_gen(prompt)
return response
except Exception as err:
logger.error(f"blog_with_research: Failed to get response from LLM: {err}")
raise err

View File

@@ -1,36 +0,0 @@
import os
import sys
from loguru import logger
logger.remove()
logger.add(sys.stdout,
colorize=True,
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
)
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
def blog_with_keywords(blog, keywords):
"""Combine the given online research and gpt blog content"""
prompt = f"""
As an expert digital content writer, specializing in content optimization and SEO.
I will provide you with my 'blog content' and 'list of keywords' on the same topic.
Your task is to write an original blog, utilizing given keywords and blog content.
Your blog should be highly detailed and well formatted.
You are Sarah, the Creative Content writer, writing up fresh ideas and crafts them with care.
She makes complex topics easy to understand and writes in a friendly tone that connects with everyone.
She excels at simplifying complex topics and communicates with charisma, making technical jargon come alive for her audience.
Blog content: '{blog}'
list of keywords: '{keywords}'
"""
try:
response = llm_text_gen(prompt)
return response
except Exception as err:
logger.error(f"blog_with_keywords: Failed to get response from LLM: {err}")
raise err

View File

@@ -1,33 +0,0 @@
import os
import sys
from loguru import logger
logger.remove()
logger.add(sys.stdout,
colorize=True,
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}"
)
# Intenral libraries
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
def blog_with_research(report, blog):
"""Combine the given online research and gpt blog content"""
prompt = f"""
You are Alwrity, the Creative Content writer, writing up fresh ideas and crafts them with care and uniqueness.
She makes complex topics simple to understand and writes in a friendly, conversational tone that connects with everyone.
She excels at simplifying complex topics and writes in the first person, for her audience.
I will provide you with a latest 'research report' and a outdated 'blog content' on the same topic.
Your task is to update the given blog content, using the new research report, as context.
\n\nResearch report: '{report}'
\n\nBlog content: '{blog}'
"""
try:
response = llm_text_gen(prompt)
return response
except Exception as err:
logger.error(f"blog_with_research: Failed to get response from LLM: {err}")
raise err

View File

@@ -15,9 +15,7 @@ logger.add(sys.stdout,
from ..ai_web_researcher.gpt_online_researcher import do_google_serp_search,\
do_tavily_ai_search, do_metaphor_ai_research, do_google_pytrends_analysis
from .blog_from_google_serp import write_blog_google_serp
from .combine_research_and_blog import blog_with_research
from .combine_blog_and_keywords import blog_with_keywords
from .blog_from_google_serp import write_blog_google_serp, improve_blog_intro, blog_with_keywords, blog_with_research
from ..ai_web_researcher.you_web_reseacher import get_rag_results, search_ydc_index
from ..blog_metadata.get_blog_metadata import blog_metadata
from ..blog_postprocessing.save_blog_to_file import save_blog_to_file
@@ -49,7 +47,8 @@ def write_blog_from_keywords(search_keywords, url=None):
# Commenting it out for blog writing, using Tavily for other forms of writing.
# Do Tavily AI research to augument the above blog.
try:
tavily_search_result, t_titles = do_tavily_ai_search(search_keywords)
tavily_search_result, t_titles, t_answer = do_tavily_ai_search(search_keywords)
blog_markdown_str = improve_blog_intro(blog_markdown_str, t_answer)
example_blog_titles.append(t_titles)
blog_markdown_str = blog_with_research(blog_markdown_str, tavily_search_result)
logger.info(f"######### Blog content after Tavily AI research: ######### \n\n{blog_markdown_str}\n\n")
@@ -71,6 +70,7 @@ def write_blog_from_keywords(search_keywords, url=None):
pytrends_search_result = do_google_pytrends_analysis(search_keywords)
logger.info(f"Google Trends keywords to use in the blog: {pytrends_search_result}\n")
blog_markdown_str = blog_with_keywords(blog_markdown_str, pytrends_search_result)
blog_markdown_str = improve_blog_intro(blog_markdown_str, t_answer)
except Exception as err:
logger.error(f"Failed to do Google Trends Analysis:{err}")
logger.info(f"########### Blog Content After Google Trends Analysis:######### \n {blog_markdown_str}\n\n")

View File

@@ -15,7 +15,7 @@ logger.add(sys.stdout,
from .write_blogs_from_youtube_videos import youtube_to_blog
from ...ai_web_researcher.gpt_online_researcher import do_google_serp_search
from ...ai_writers.combine_research_and_blog import blog_with_research
from ..blog_from_google_serp import blog_with_research
from ...blog_metadata.get_blog_metadata import blog_metadata
from ...blog_postprocessing.save_blog_to_file import save_blog_to_file

View File

@@ -0,0 +1,33 @@
* **Trending:** How Open-Source AI is Changing the Future of Content Creation
* **Seasonal:** 5 Ways Open-Source AI Can Help You Write More Engaging Holiday Content
* **Trending:** The Best Open-Source AI Writing Tools for Every Need
* **Seasonal:** Open-Source AI Writing: A Threat to Human Writers or a Valuable Tool?
* **Trending:** The Ethics of Open-Source AI Writing: What You Need to Know
* **Seasonal:** How to Use Open-Source AI to Write Festive Social Media Posts
* **Evergreen:** Open-Source AI Writing: The Good, the Bad, and the Ugly
* **Trending:** How Open-Source AI Can Help You Write More Effective Blog Posts
* **Seasonal:** Open-Source AI Writing: How to Create Holiday-Themed Website Content
* **Evergreen:** How to Use Open-Source AI to Write Better Social Media Content
* **Trending:** The Best Open-Source AI Writing Tools for Bloggers
* **Seasonal:** How to Use Open-Source AI to Write Holiday-Themed Email Marketing Campaigns
* **Seasonal:** Open Source AI Writers for Holiday Content Creation
* **Evergreen:** How to Write Great Content with Open Source AI Writers: A Step-by-Step Guide
* **Trending:** The Role of Open Source AI Writers in SEO
* **Seasonal:** Open Source AI Writers for Black Friday and Cyber Monday
* **Trending:** Open Source AI Writers and the Future of Content Consumption
* **Trending:** Open Source AI Writers and the Rise of Personalized Content
* **Trending:** Open Source AI Writers and the Future of Content Strategy
* **Seasonal:** Open Source AI Writers for Back-to-School Content
* **Trending:** Open Source AI Writers and the Rise of AI-Generated Art
* How AI Writers Can Help You Create High-Quality Blog Posts
* The Role of AI Writers in the Future of Content Creation
* AI Writers vs. Human Writers: Which Is Better for Your Content?
* The Dos and Don'ts of Using AI Writers
| 5 | AI writing tool news | News about AI writing tools | The Latest News about AI Writing Tools |
| 6 | AI writing tool resources | Resources for AI writing tools | The Best Resources for AI Writing Tools |
| 6 | AI writing tool community | Community for AI writing tools | The Best Community for AI Writing Tools |
| 6 | AI writing tool support | Support for AI writing tools | The Best Support for AI Writing Tools |
| 7 | AI writing tool training | Training for AI writing tools | The Best Training for AI Writing Tools |
| 7 | AI writing tool certification | Certification for AI writing tools | The Best Certification for AI Writing Tools |
| 7 | AI writing tool courses | Courses for AI writing tools | The Best Courses for AI Writing Tools |
| 8 | AI writing tool workshops | Workshops for AI writing tools | The Best Workshops for AI Writing Tools |

View File

@@ -0,0 +1,230 @@
import os
from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool
from langchain_google_genai import ChatGoogleGenerativeAI
from crewai_tools import ScrapeWebsiteTool, tool
from crewai_tools import FileReadTool
from ..ai_web_researcher.google_trends_researcher import do_google_trends_analysis
def setup_environment():
os.environ["OPENAI_MODEL_NAME"] = 'gpt-3.5-turbo' # Adjust based on given model
def create_agents(search_keywords):
# Tools for the agents.
search_tool = SerperDevTool()
# To enable scrapping any website it finds during it's execution
#scrape_tool = ScrapeWebsiteTool()
# To read results from a file.
# Initialize the tool to read any files the agents knows or lean the path for
# file_read_tool = FileReadTool()
# Initialize the tool with a specific file path, so the agent can only read the content of the specified file
file_read_tool = FileReadTool(file_path=os.getenv('SEARCH_SAVE_FILE'))
# The manager keeps an eye on the content already planned to give new ideas.
# TBD: Accept the user website urls and populate the file with sitemap.xml
manager_read_tool = FileReadTool(file_path="content_already_planned.txt")
# Load the google gemini api key
google_api_key = os.getenv("GEMINI_API_KEY")
# Set gemini pro as llm
llm = ChatGoogleGenerativeAI(
model="gemini-pro", verbose=True, temperature=0.7, google_api_key=google_api_key
)
content_researcher = Agent(
role = 'Senior Web Research Analyst (Content Strategy): Aisha Sharma',
goal = f"""
Recommend unique blog titles for "{search_keywords}" keywords.
Provide researched titles to be used for content calender & planning.""",
backstory = f"""
Your Focus: Content Opportunity Analysis & Keyword Research ({search_keywords}).
Your Skills:
1). Web Research & Content Gap Identification (Expert).
2). SEO Best Practices, Keyword Research & content planning expert (Advanced).
3). Analyzes search trends and competitor content.
Mission:
1). Fuel company's content strategy with data-driven insights to attract and educate online readers.
2). Identifies high-volume, low-competition keywords relevant to {search_keywords}.
Responsibilities:
1). Recommend high-value content opportunities through in-depth web research and competitor analysis.
2). Do competitor analysis for {search_keywords} for content calender & planning.
""",
tools = [search_tool],
memory = True, # Enable memory
verbose = True,
max_rpm = None, # No limit on requests per minute
max_iter = 10, # Default value for maximum iterations
allow_delegation = False,
llm = llm
)
content_planner = Agent(
role = 'Senior Content Strategist & planner - Ted XingPi',
goal = f"""
Craft a series of content titles around {search_keywords} that can be expanded into 2 month-long series.
Do not repeat the blog titles, always consult the previously written blog titles from the file(content_already_planned.txt).
Set the """,
backstory = """You are Ted XingPi, with Experience of 15 years.
Your Skills:
1). Content Opportunity Analysis & Content calender planning (Expert).
2). AI Applications for Content Marketing (Highly Knowledgeable).
3). Content Strategy Development & planning.
4). Analyze keyword research for content opportunities.
Your Responsibilties:
1). Identify content topics and keywords for {search_keywords}.
2). Create content calender that showcases the value proposition around {search_keywords}.
3). Collaborate with team to identify content gaps and trending topics, relevant to given keywords.
4). Develop content calender with a focus on organic marketing to attract online customers.
5). The content calender should include, Head Term Keyword, Long-Tail Keyword and Blog Post Title.
""",
memory = True, # Enable memory
verbose = True,
tools = [manager_read_tool],
max_rpm = None, # No limit on requests per minute
max_iter = 15, # Default value for maximum iterations
allow_delegation = False,
llm = llm
)
google_trends_researcher = Agent(
role = 'Content Marketing & Google Trends Specialist - Sarah Qureshi.',
goal = f"""Use Google Trends to suggest AI writing keywords & titles, optimized for {search_keywords}.
All the required google trends data is present in the file({os.getenv('SEARCH_SAVE_FILE')}).""",
backstory = f"""You are Sarah Qureshi, with 10 years as a content writer and planner.
Your Skills:
1). Proven experience in using Google Trends for keyword research.
2). Strong understanding of SEO best practices.
3). Reading files and understanding long table with data.
4). Ability to communicate complex data insights in a clear and concise way.
Your Personality:
1). Enjoys breaking down complex topics into clear and concise information.
2). Strong communicator with a knack for explaining technical concepts in an engaging way.
Your responsibilties:
1). Collaborate on content strategy, provide keyword, titles recommendations and integrate them into the content calendar.
2). Recommend high-volume, low-competition keywords, titles with strong user intent.
3). Recommend, Rising search queries related to {search_keywords}.
5). Recommend keywords, blog titles for preparing/planning the content calender.
""",
memory = True, # Enable memory
tools = [file_read_tool],
verbose = True,
max_rpm = None, # No limit on requests per minute
max_iter = 15, # Default value for maximum iterations
allow_delegation = False,
llm = llm
)
content_marketing_manager = Agent(
role="Content Marketing Manager - Diksha Yuj",
goal=f"""Create highly detailed 2 month-long content calender, focused around keywords: {search_keywords}.
Important to ensure the keywords and titles are not already written on, consult the file(content_already_planned.txt).""",
backstory="""
Content Marketing Manager: Diksha Yuj
Experience: Digital Marketing Veteran (15+ years)
Mission: Supercharge organic growth of the company, with content marketing.
Responsibilities:
1). Ensures that content titles are not repeated & No keyword cannabilization.
2). Maintains and consults a file for all previous written titles.
3). Develops a content calendar aligned and optimized around {search_keywords}.
4). Keenly follows & learns the research and communication of other team members.
5). The content calender should include, Head Term Keyword, Long-Tail Keyword and Blog Post Title.
""",
memory=True, # Enable memory
verbose=True,
tools = [manager_read_tool],
max_rpm=None, # No limit on requests per minute
max_iter=10, # Default value for maximum iterations
allow_delegation=False,
llm=llm
)
return [content_researcher, google_trends_researcher, content_planner, content_marketing_manager]
def create_tasks(agents, search_keywords):
research_task = Task(
description=f"""Conduct a analysis on the following: "{search_keywords}". Suggest blog titles for content calender.
Set the input parameter as : search_query""",
expected_output=f"""Analyze keywords {search_keywords} to provide content ideas for content calender.""",
agent=agents[0] # Assign to the researcher agent
)
google_trends_task = Task(
description=f"""Conduct Google Trends analysis, on keywords: {search_keywords}, from the file({os.getenv('SEARCH_SAVE_FILE')}).
Suggest blog titles for content calender. Recommend high-volume, low-competition keywords with strong user intent.
Set the input parameter file_path to {os.getenv('SEARCH_SAVE_FILE')}""",
expected_output=f"Recommend content ideas, blog titles to be included in the content calender.",
agent=agents[1] # Assign to the researcher agent
)
planner_task = Task(
description=f"""Develop a content calendar for {search_keywords} that includes evergreen, trending, and seasonal post ideas.""",
expected_output=f"""
A Highly detailed content calender that positions {search_keywords} as a must-read for industry insiders and newcomers alike.
Prioritize keywords relevant to user needs and search intent, leveraging Google Trends insights.
Employ a balance of head terms (broad topics) and long-tail keywords (specific phrases) for optimal reach and targeting.
New content should target unique keywords to avoid competition with existing content.
Focus on specific aspects within a theme to differentiate semantically similar keywords for {search_keywords}.
Use context & insights from Aisha Sharma & Sarah Qureshi.
Set the input parameter file_path to content_already_planned.txt""",
#human_input=True,
agent=agents[2] # Assign to the outliner agent
)
marketing_manager_task = Task(
description=f"""Make sure the content calender is optimised for keywords: '{search_keywords}'.
Make sure the titles are unique, semantically unique and mitigate keyword cannabilization.
Use context & insights from Aisha Sharma & Sarah Qureshi.
Set the input parameter file_path to content_already_planned.txt
""",
expected_output=f"""Final content calender for the next 2 months. Targeting 5 articles per week.
Make sure to present the content calender in tabular format. Include details of how to use the content calender.""",
agent=agents[3] # Assign to the reviewer agent
)
return [research_task, google_trends_task, planner_task, marketing_manager_task]
def execute_tasks(agents, tasks):
crew = Crew(
agents=agents,
tasks=tasks,
verbose=2, # You can set it to 1 or 2 for different logging levels
#process=Process.sequential,
#memory=True,
language="en"
)
result = crew.kickoff()
return result
def ai_agents_writers(search_keywords):
do_google_trends_analysis(search_keywords)
#setup_environment()
agents = create_agents(search_keywords)
tasks = create_tasks(agents, search_keywords)
result = execute_tasks(agents, tasks)
print("########## Final Output Result ############")
print(result)

View File

@@ -0,0 +1,12 @@
crewai[tools]
langchain-google-genai
scikit-learn
scipy
matplotlib
pandas
plotly
lxml_html_clean
tabulate
pytrends
loguru
requests_html

View File

@@ -19,6 +19,8 @@ from lib.ai_writers.ai_agents_crew_writer import ai_agents_writers
from lib.gpt_providers.text_generation.ai_story_writer import ai_story_generator
from lib.gpt_providers.text_generation.ai_essay_writer import ai_essay_generator
from lib.gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
from lib.content_planning_calender.content_planning_agents_alwrity_crew import ai_agents_writers
def blog_from_audio():
@@ -219,6 +221,30 @@ def write_story():
exit(1)
def content_planning():
""" Agents team to create a content calender """
while True:
print("________________________________________________________________")
content_keywords = input_dialog(
title='Enter Main Domain Keywords of your business:',
text='Better keywords will generate better blog titles, content calender, Play with keywords & combine into single calender:',
).run()
# If the user cancels, exit the loop
if content_keywords is None:
break
if content_keywords and len(content_keywords.split()) >= 2:
break
else:
message_dialog(
title='Error',
text='🚫 Single keywords are just too vague. Try again.'
).run()
try:
ai_agents_writers(content_keywords)
except Exception as err:
print(f"Failed to genrate content calender: {err}")
def essay_writer():
# Define essay types and education levels