diff --git a/ai_news_generator/README.md b/ai_news_generator/README.md index 6bc3e25b6..545ebfc13 100644 --- a/ai_news_generator/README.md +++ b/ai_news_generator/README.md @@ -1,7 +1,7 @@ -# AI News generator +# AI News Generator -This project leverages CrewAI and Cohere's Command-R:7B model to build an AI news generator! +This project leverages CrewAI Flows and Cohere's Command-R:7B model to build an AI news generator with an agentic workflow! ## Installation and setup @@ -13,9 +13,27 @@ This project leverages CrewAI and Cohere's Command-R:7B model to build an AI new **Install Dependencies**: Ensure you have Python 3.11 or later installed. ```bash - pip install crewai crewai-tools + pip install crewai crewai-tools streamlit python-dotenv ``` +## Architecture + +This application uses CrewAI Flows to create an agentic workflow with two main phases: + +### Phase 1: Research Phase (@start) +- **Agent**: Senior Research Analyst +- **Task**: Conduct comprehensive research on the given topic +- **Tools**: SerperDev (web search) +- **Output**: Structured research brief with citations + +### Phase 2: Writing Phase (@listen) +- **Agent**: Content Writer +- **Task**: Transform research into engaging blog post +- **Input**: Research output from Phase 1 +- **Output**: Polished markdown blog post + +The flow ensures that the writing phase only begins after the research phase completes, creating a structured agentic workflow. + --- ## 📬 Stay Updated with Our Newsletter! diff --git a/ai_news_generator/__pycache__/app.cpython-311.pyc b/ai_news_generator/__pycache__/app.cpython-311.pyc new file mode 100644 index 000000000..89b083749 Binary files /dev/null and b/ai_news_generator/__pycache__/app.cpython-311.pyc differ diff --git a/ai_news_generator/app.py b/ai_news_generator/app.py index 7fc78e07d..1229c2a11 100644 --- a/ai_news_generator/app.py +++ b/ai_news_generator/app.py @@ -2,6 +2,7 @@ import streamlit as st from crewai import Agent, Task, Crew, LLM from crewai_tools import SerperDevTool +from crewai.flow.flow import Flow, listen, start from dotenv import load_dotenv # Load environment variables @@ -45,102 +46,131 @@ 5. Download the result as a markdown file """) -def generate_content(topic): - llm = LLM( - model="command-r", - temperature=0.7 - ) +class NewsGeneratorFlow(Flow): + def __init__(self, topic): + super().__init__() + self.topic = topic + self.llm = LLM( + model="command-r", + temperature=0.7 + ) + self.search_tool = SerperDevTool(n_results=10) - search_tool = SerperDevTool(n_results=10) - - # First Agent: Senior Research Analyst - senior_research_analyst = Agent( - role="Senior Research Analyst", - goal=f"Research, analyze, and synthesize comprehensive information on {topic} from reliable web sources", - backstory="You're an expert research analyst with advanced web research skills. " - "You excel at finding, analyzing, and synthesizing information from " - "across the internet using search tools. You're skilled at " - "distinguishing reliable sources from unreliable ones, " - "fact-checking, cross-referencing information, and " - "identifying key patterns and insights. You provide " - "well-organized research briefs with proper citations " - "and source verification. Your analysis includes both " - "raw data and interpreted insights, making complex " - "information accessible and actionable.", - allow_delegation=False, - verbose=True, - tools=[search_tool], - llm=llm - ) + @start() + def research_phase(self): + """Phase 1: Research and analyze information on the given topic""" + # Senior Research Analyst Agent + senior_research_analyst = Agent( + role="Senior Research Analyst", + goal=f"Research, analyze, and synthesize comprehensive information on {self.topic} from reliable web sources", + backstory="You're an expert research analyst with advanced web research skills. " + "You excel at finding, analyzing, and synthesizing information from " + "across the internet using search tools. You're skilled at " + "distinguishing reliable sources from unreliable ones, " + "fact-checking, cross-referencing information, and " + "identifying key patterns and insights. You provide " + "well-organized research briefs with proper citations " + "and source verification. Your analysis includes both " + "raw data and interpreted insights, making complex " + "information accessible and actionable.", + allow_delegation=False, + verbose=True, + tools=[self.search_tool], + llm=self.llm + ) - # Second Agent: Content Writer - content_writer = Agent( - role="Content Writer", - goal="Transform research findings into engaging blog posts while maintaining accuracy", - backstory="You're a skilled content writer specialized in creating " - "engaging, accessible content from technical research. " - "You work closely with the Senior Research Analyst and excel at maintaining the perfect " - "balance between informative and entertaining writing, " - "while ensuring all facts and citations from the research " - "are properly incorporated. You have a talent for making " - "complex topics approachable without oversimplifying them.", - allow_delegation=False, - verbose=True, - llm=llm - ) + # Research Task + research_task = Task( + description=(f""" + 1. Conduct comprehensive research on {self.topic} including: + - Recent developments and news + - Key industry trends and innovations + - Expert opinions and analyses + - Statistical data and market insights + 2. Evaluate source credibility and fact-check all information + 3. Organize findings into a structured research brief + 4. Include all relevant citations and sources + """), + expected_output="""A detailed research report containing: + - Executive summary of key findings + - Comprehensive analysis of current trends and developments + - List of verified facts and statistics + - All citations and links to original sources + - Clear categorization of main themes and patterns + Please format with clear sections and bullet points for easy reference.""", + agent=senior_research_analyst + ) - # Research Task - research_task = Task( - description=(""" - 1. Conduct comprehensive research on {topic} including: - - Recent developments and news - - Key industry trends and innovations - - Expert opinions and analyses - - Statistical data and market insights - 2. Evaluate source credibility and fact-check all information - 3. Organize findings into a structured research brief - 4. Include all relevant citations and sources - """), - expected_output="""A detailed research report containing: - - Executive summary of key findings - - Comprehensive analysis of current trends and developments - - List of verified facts and statistics - - All citations and links to original sources - - Clear categorization of main themes and patterns - Please format with clear sections and bullet points for easy reference.""", - agent=senior_research_analyst - ) + # Create and execute research crew + research_crew = Crew( + agents=[senior_research_analyst], + tasks=[research_task], + verbose=True + ) - # Writing Task - writing_task = Task( - description=(""" - Using the research brief provided, create an engaging blog post that: - 1. Transforms technical information into accessible content - 2. Maintains all factual accuracy and citations from the research - 3. Includes: - - Attention-grabbing introduction - - Well-structured body sections with clear headings - - Compelling conclusion - 4. Preserves all source citations in [Source: URL] format - 5. Includes a References section at the end - """), - expected_output="""A polished blog post in markdown format that: - - Engages readers while maintaining accuracy - - Contains properly structured sections - - Includes Inline citations hyperlinked to the original source url - - Presents information in an accessible yet informative way - - Follows proper markdown formatting, use H1 for the title and H3 for the sub-sections""", - agent=content_writer - ) + research_result = research_crew.kickoff(inputs={"topic": self.topic}) + return research_result - # Create Crew - crew = Crew( - agents=[senior_research_analyst, content_writer], - tasks=[research_task, writing_task], - verbose=True - ) + @listen(research_phase) + def writing_phase(self, research_output): + """Phase 2: Transform research into engaging blog post""" + # Content Writer Agent + content_writer = Agent( + role="Content Writer", + goal="Transform research findings into engaging blog posts while maintaining accuracy", + backstory="You're a skilled content writer specialized in creating " + "engaging, accessible content from technical research. " + "You work closely with the Senior Research Analyst and excel at maintaining the perfect " + "balance between informative and entertaining writing, " + "while ensuring all facts and citations from the research " + "are properly incorporated. You have a talent for making " + "complex topics approachable without oversimplifying them.", + allow_delegation=False, + verbose=True, + llm=self.llm + ) + + # Writing Task + writing_task = Task( + description=(f""" + Using the research brief provided about {self.topic}, create an engaging blog post that: + 1. Transforms technical information into accessible content + 2. Maintains all factual accuracy and citations from the research + 3. Includes: + - Attention-grabbing introduction + - Well-structured body sections with clear headings + - Compelling conclusion + 4. Preserves all source citations in [Source: URL] format + 5. Includes a References section at the end + + Research Brief: {research_output} + """), + expected_output="""A polished blog post in markdown format that: + - Engages readers while maintaining accuracy + - Contains properly structured sections + - Includes Inline citations hyperlinked to the original source url + - Presents information in an accessible yet informative way + - Follows proper markdown formatting, use H1 for the title and H3 for the sub-sections""", + agent=content_writer + ) + + # Create and execute writing crew + writing_crew = Crew( + agents=[content_writer], + tasks=[writing_task], + verbose=True + ) - return crew.kickoff(inputs={"topic": topic}) + writing_result = writing_crew.kickoff(inputs={ + "topic": self.topic, + "research_output": research_output + }) + return writing_result + +def generate_content(topic): + """Generate content using CrewAI Flow""" + flow = NewsGeneratorFlow(topic) + return flow.kickoff() # Main content area if generate_button: