We use cookies essential for this site to function well. Please click to help us improve its usefulness with additional cookies. Learn about our use of cookies in our Privacy Policy & Cookies Policy.

Show details

How to Build an AI Pair Programmer with CrewAI?

8 min read

Introduction

As the need for efficient software development continues, artificial intelligence becomes a valuable colleague for programmers. AI-powered coding assistants are changing the game by making it easier for developers to write, debug, and optimize their code like pair programmers. In this article, we’ll learn how to build an AI pair programmer using CrewAI agents to simplify your coding tasks and boost your productivity in software development.

Overview

  • Grasp the basics of CrewAI and its role in assisting coding tasks.
  • Recognize key components—Agents, Tasks, Tools, and Crews—and their interactions.
  • Gain hands-on experience in setting up AI agents for code generation and review.
  • Learn to configure multiple AI agents to work together on coding tasks.
  • Develop skills to use CrewAI to evaluate and optimize code quality.

What Can an AI Pair Programmer Do?

Let’s explore a few use cases of what an AI pair programmer can do.

  1. Write code: We can generate the code for a given problem using an AI agent and review it with another agent.
  2. Improve existing code: If we write the code, our pair programmer can evaluate it based on the evaluation requirements.
  3. Optimize code: We can ask for any changes to the code to optimize it, such as adding comments, a doc string, etc.
  4. Debug code: Errors are inevitable in the code. But unlike rubber duck, our pair programmer can make suggestions.
  5. Write test cases: Let the AI agent write the test cases for every edge case. We can even use it for test-driven development. 

In this article, we will cover the first two tasks.

What is CrewAI?

CrewAI is a popular framework for building AI agents. It consists of key components such as Agents, Tasks, Tools, and Crews.

  • Agent: At its core, an agent uses a large language model (LLM) to generate outputs based on input prompts. It can call various tools, accept human input, and communicate with other agents to complete tasks.
  • Task: A task outlines what the agent will accomplish, specifying the description, the agent to use, and the tools that can be called upon.
  • Tool: Agents can utilize various tools to perform tasks like web searches, reading files, and executing code enhancing the capabilities of the AI Agent.
  • Crew: A crew is a group of agents collaborating to complete a set of tasks. Each crew defines how agents interact, share information, and delegate responsibilities.

Also Read: Building Collaborative AI Agents With CrewAI

Now, let’s build an agent to gain a better understanding!

What are the Prerequisites?

Before building an AI Pair Programmer with a CrewAI agent, ensure you have the API keys for LLMs.

Accessing an LLM via API

Start by generating an API key for the LLM you plan to use. Then, create a .env file to store this key securely. This will keep it private while making it easily accessible within your project.

Example of a .env File

Here’s an example of what a .env file looks like:

Libraries Required

We have used the following versions for the major libraries:

  • crewai – 0.66.0
  • crewai-tools – 0.12.1

Automating Code Creation with CrewAI

In this section, we will import the necessary libraries and define agents to generate and review code. This hands-on approach will help you understand how to utilize CrewAI effectively.

Import the Necessary Libraries

from dotenv import load_dotenv
load_dotenv('/.env')

from crewai import Agent, Task, Crew

Defining the Code Writer Agent

We can use one agent to generate the code and another agent to review the code.

code_writer_agent = Agent(role="Software Engineer",
                          goal='Write optimized code for a given task', 
                          backstory="""You are a software engineer who writes code for a given task.
                               The code should be optimized, and maintainable and include doc string, comments, etc.""",
                          llm='gpt-4o-mini',
                          verbose=True)

Explanation of Agent Parameters

  • role: Defines what the agent is and defines it based on the tasks we want the agent to complete.
  • Goal: Defines what the agent tries to achieve. The agent makes the decisions to achieve this goal.
  • backstory: Provides context to the role and goal of the agent. This can be used for better interaction with the agent as this is sent as the prompt to the LLM.
  • llm: LLM used in the agent. CrewAI uses LiteLLM to call the LLMs, so refer to its documentation for the available models.
  • verbose: we can set verbose=True to look at the input and output of the agent.

Defining the Code Writer Task

code_writer_task = Task(description='Write the code to solve the given problem in the {language} programming language.'
                        'Problem: {problem}',
                        expected_output='Well formatted code to solve the problem. Include type hinting',
                        agent=code_writer_agent)

Explanation of Task Parameters

  • description: write a clear and detailed statement of objectives for the task that needs to be completed. curly braces {} are used to indicate variables. In this case, we pass the ‘problem’ and ‘language’ values to the task.
  • expected_output: How the output of the task should look like. We can also get structured output using Pydantic classes.
  • agent: defines the agent that should be used to achieve this task.

Defining the Code Reviewer Agent and Task

Similarly, let’s define code_reviewer_agent and code_reviewer_task.

code_reviewer_agent = Agent(role="Senior Software Engineer",
                            goal='Make sure the code written is optimized and maintainable', 
                            backstory="""You are a Senior software engineer who reviews the code written for a given task.
                               You should check the code for readability, maintainability, and performance.""",
                            llm='gpt-4o-mini',
                            verbose=True)
                            
code_reviewer_task = Task(description="""A software engineer has written this code for the given problem 
                            in the {language} programming language.' Review the code critically and 
                            make any changes to the code if necessary. 
                            'Problem: {problem}""",
                          expected_output='Well formatted code after the review',
                          agent=code_reviewer_agent)

Building and Running the Crew

Now, we can build the crew and run it:

crew = Crew(agents=[code_writer_agent, code_reviewer_agent], 
            tasks=[code_writer_task, code_reviewer_task], 
            verbose=True)
            
result = crew.kickoff(inputs={'problem': 'create a game of tic-tac-toe', 'language': 'Python'})            

The sample output will be as follows:

Building and Running the Crew
Building and Running the Crew

Result

The result will have the following

result.dict().keys()
>>> dict_keys(['raw', 'pydantic', 'json_dict', 'tasks_output', 'token_usage'])

# we can also check token usage
result.dict()['token_usage']
>>> {'total_tokens': 2656,
 'prompt_tokens': 1425,
 'completion_tokens': 1231,
 'successful_requests': 3}
 
# we can print the final result
print(result.raw)

We can run the code generated by the Agent:

TIc Tac Toe

Automated Code Evaluation with Crew AI

After building the code generation and review agents, we will now evaluate an existing code file.

Gathering Requirements

First, we will gather evaluation requirements for a problem using an agent and then evaluate the code based on those requirements using another agent.

Using Tools for Enhanced Capabilities

We will use the FileReadTool to read files from the system. Tools enhance agent capabilities by enabling actions like reading files or searching the Internet.

We can assign tools to both tasks and agents. Tools assigned in Tasks will override tools in the agent.

Initialize Agent and Task for Requirement Gathering

code_requirements_agent = Agent(role="Data Scientist",
                          goal='provide are all things that should be required in the code to solve the given problem.', 
                          backstory="""You are a Data Scientist who decides what are all things required 
                          in the code to solve a given problem/task. The code will be written based on 
                          the requirements provided by you.""",
                          llm='gpt-4o-mini',
                          verbose=True)
                         
code_requirement_task = Task(description='Write the requirements for the given problem step-by-step.'
                        'Problem: {problem}',
                            expected_output='Well formatted text which specifies what is required to solve the problem.',
                            agent=code_requirements_agent,
                            human_input=True)                         

In the above task, we have assigned human_input to True. So, the agent asks for input from the user once it generates the requirements. We can ask it to make any changes if required.

Evaluating the Code

Now, do the same evaluation. Here, we use the tool to read the file. We also use GPT-4o for better output as the context size is larger.

from crewai_tools import DirectoryReadTool, FileReadTool
file_read_tool = FileReadTool('EDA.py')

code_evaluator_agent = Agent(role="Data Science Evaluator",
                            goal='Evaluate the given code file based on the requirements provided for a given problem', 
                            backstory="""You are a Data Science evaluator who reviews and evaluates the code.
                               You should check the code based on the requirements given to you""",
                            llm='gpt-4o',
                            verbose=True)
                            
code_evaluator_task = Task(description="""A code file is given to you. 
                            Evaluate the file based on the requirements given as the context.
                            Provide the only review and evaluation of the code as the output, not the code.
                            """,
                           expected_output='Detailed evaluation results of the code file based on the requirements.'
                           'Review the code file for each point of the requirements given to you'
                           'Provide evaluation results as text',
                           tools=[file_read_tool],
                           agent=code_evaluator_agent)                            

Building the Crew for Evaluation

Let us build the crew and define the problem to get the requirements for it.

crew = Crew(agents=[code_requirements_agent, code_evaluator_agent], 
            tasks=[code_requirement_task, code_evaluator_task], 
            verbose=True)
            
problem = """
Perform EDA on the NYC taxi trip duration dataset.
Here is the description of all the variables/features available in the dataset which will help you to perform EDA:

    id - a unique identifier for each trip
    vendor_id - a code indicating the provider associated with the trip record
    pickup_datetime - date and time when the meter was engaged
    dropoff_datetime - date and time when the meter was disengaged
    passenger_count - the number of passengers in the vehicle (driver entered value)
    pickup_longitude - the longitude where the meter was engaged
    pickup_latitude - the latitude where the meter was engaged
    dropoff_longitude - the longitude where the meter was disengaged
    dropoff_latitude - the latitude where the meter was disengaged
    store_and_fwd_flag - This flag indicates whether the trip record was held in vehicle memory before sending to the vendor because the vehicle did not have a connection to the server (Y=store and forward; N=not a store and forward trip)
    trip_duration - (target) duration of the trip in seconds

"""            

result = crew.kickoff(inputs={'problem': problem})

Output from Tasks

Here’s how the result will look like while asking for human input:

Output from Tasks

We can also get the output of any task as follows:

print(code_requirement_task.output.raw)

# final output
print(result.raw)

In this way, we can build versatile crews to make our own AI pair programmer.

Conclusion

CrewAI offers a powerful framework for enhancing software development by leveraging AI agents to automate code generation, review, and evaluation tasks. Developers can streamline their workflow and improve productivity by defining clear roles, goals, and tasks for each agent. Incorporating an AI Pair Programmer with CrewAI into your software development workflow can significantly enhance productivity and code quality.

CrewAI’s flexible framework allows for seamless collaboration between AI agents, ensuring your code is optimized, maintainable, and error-free. As AI technology evolves, leveraging tools like CrewAI for pair programming will become an essential strategy for developers to streamline their work and boost efficiency. With its versatile tools and collaborative features, CrewAI has the potential to revolutionize how we approach programming, making the process more efficient and effective.

Frequently Asked Questions

Q1. What is CrewAI and how does it help in software development?  

A. CrewAI is a framework that leverages AI agents. It can be used to assist developers with tasks like writing, reviewing, and evaluating code. It enhances productivity by automating repetitive tasks, allowing developers to focus on more complex aspects of development.

Q2. What are the key components of CrewAI?  

A. The core components of CrewAI include Agents, Tasks, Tools, and Crews. Agents perform actions based on their defined roles, Tasks specify the objectives, Tools extend the agents’ capabilities, and Crews allow multiple agents to collaborate on complex workflows.

Q3. How do I set up an AI agent in CrewAI to generate code?  

A. To set up an AI agent, you define its role (e.g., “Software Engineer”), goal (e.g., “Write optimized code”), and backstory for context, and specify the LLM (language model) to be used. You also create a corresponding Task that details the problem and expected output.

Q4. Can CrewAI agents work together on tasks?  

A. Yes, CrewAI agents can collaborate on tasks by being part of a “Crew.” Each agent in the crew can have a specific task, such as writing code or reviewing it, allowing for efficient teamwork among AI agents.

Q5. What tools can be used with CrewAI agents?  

A. CrewAI agents can use various tools to enhance their capabilities, such as reading files, conducting web searches, or running code. These tools can be assigned to agents and tasks, allowing for more dynamic and powerful workflows.

I am working as an Associate Data Scientist at Analytics Vidhya, a platform dedicated to building the Data Science ecosystem. My interests lie in the fields of Deep Learning and Natural Language Processing (NLP).