Code Assistant v2: Complex code analysis
Use AgentKit Tools and Custom Router to add agentic capabilities.
Overview
Our Code Assistant v1, relying on a RAG workflow, had limited capabilities linked to its lack of reasoning. The second version of our Code Assistant will introduce reasoning capabilities to adapt analysis based on the user’s input:
These agentic (reasoning) capabilities are introduced by the following AgentKit concepts:
- Tools: Enables Agents to interact with their environment (ex: file system or shared State).
- Router: Powers the flow of the conversation between Agents.
- Network: Add a shared State to share information between Agents.
Let’s learn these concepts in practice.
Setup
Similarly to the Code Assistant v1, perform the following steps to setup your project:
You are now set up, let’s implement the v2 of our Code Assistant.
Implementing our Code Assistant v2
Overview of the agentic workflow
Our Code Assistant v2 introduces reasoning to perform tailored recommendations based on a given code file: refactoring, documentation, etc.
To achieve this behavior, we will need to:
- Create a
code_assistant_agent
Agent that will load a given filename from disk and plan a workflow using the following available Agents:analysis_agent
that will analyze the code file and suggest improvementsdocumentation_agent
that will generate documentation for the code file
- Finally, create a
summarization_agent
Agent that will generate a summary of the suggestions made by other agents
Compared to our Code Assistant v1, this new version does not consist of simple retrieval and generations steps. Instead, it introduces more flexibility by enabling LLM models to plan actions and select tools to use.
Let’s see how to implement the Agents.
A Network of Agents
Our Code Assistant v2 is composed of 4 Agents collaborating together to analyze a given code file. Such collaboration is made possible by using a Network to orchestrate the Agents and share State between them.
Unlike the Code Assistant v1, the user prompt will be passed to the network instead of an individual Agent:
To successfully run, a Network
relies on:
- A Router to indicate which Agent should be run next
- A shared State, updated by the Agents’ LLM responses and tool calls
Let’s start by implementing our Agents and registering them into the Network.
Creating Agents with Tools
Attaching Tools to an Agent helps to:
- Enrich dynamically the Agent context with dynamic data
- Store the Agent results in the shared State
Learn more about Tools.
The Analysis and Documentation Agents
Our first two analysis Agents are straightforward:
Defining task specific LLM calls (Agents) is a great way to make the LLM reasoning more efficient and avoid unnecessary generations.
Our documentation_agent
and analysis_agent
are currently stateless and need to be connected to the Network by saving their suggestions into the shared State.
For this, we will create our first Tool using createTool
:
A Tool is a function that can be called by an Agent.
The name
, description
and parameters
are used by the Agent to understand what the Tool does and what it expects as input.
The handler
is the function that will be called when the Tool is used. save_suggestions
’s handler relies on the Network’s State kv
(key-value store) API to share information with other Agents.
Learn more about the createTool() API.
The save_suggestions
Tool is used by both documentation_agent
and analysis_agent
to save their suggestions into the shared State:
Our documentation_agent
and analysis_agent
are now connected to the Network and will save their suggestions into the shared State.
Let’s now create our code_assistant_agent
that will read the code file from disk and plan the workflow to run.
The Code Assistant Agent
Let’s jump into the action by looking at the full implementation of our code_assistant_agent
:
The highlighted lines emphasize three important parts of the code_assistant_agent
:
-
The
system
property can take a function receiving the current Network state as argument, enabling more flexibility in the Agent’s behavior- Here, the
system
function is used to generate a prompt for the LLM based on the available Agents in the Network, enabling the LLM to plan the workflow to run
- Here, the
-
The
code_assistant_agent
relies on two Tools to achieve its goal:read_file
to read the code file from disk and save it into the shared Stategenerate_plan
to generate a plan of agents to run and save it into the shared State
The pattern of dynamic system
prompt and tools are also used by the summarization_agent
to generate a summary of the suggestions made by other agents.
The Summarization Agent
The summarization_agent
is a good example on how the State can be used to store intermediate results and pass them to the next Agent:
- the
suggestions
are stored in the State by thedocumentation_agent
andanalysis_agent
- the
summarization_agent
will read thesuggestions
from the State and generate a summary - the summary is then stored in the State as the
summary
key
Our four Agents are now propely defined and connected to the Network’s State.
Let’s now configure our Network to run the Agents with a Router.
Assembling the Network
An AgentKit Network is defined by a set of Agents and an optional defaultModel
:
The defaultModel
will be applied to all Agents part of the Network.
A model can also be set on an individual Agent by setting the model
property.
Learn more about the Network Model configuration.
Our Code Assistant v2 is missing a final piece: the Router. Without a Router, the Network will not know which Agent to run next.
Implementing the Router
As stated in the workflow overview, our Code Assistant v2 is an agentic worflow composed of the following steps:
- The
code_assistant_agent
will read the code file from disk and generate a plan of agents to run - Depending on the plan, the Network will run the next Agent in the plan (ex:
analysis_agent
anddocumentation_agent
) - Finally, the
summarization_agent
will generate a summary of the suggestions made by other agents
AgentKit’s Router enables us to implement such dynamic workflow with code by providing a defaultRouter
function:
How does a Router work?
The Router is a function called by the Network when starting a new run and between each Agent call.
The provided Router function (defaultRouter
) receives a network
argument granting access to the Network’s state and Agents.
Learn more about the Router.
Let’s have a closer look at the Router implementation:
Our Code Assistant v2 iteration is now complete. Let’s run it!
Running the Code Assistant v2
First, go to your Anthropic dashboard and create a new API key.
Then, run the following command to execute our Code Assistant:
The following output should be displayed in your terminal:
Updating the files/example.ts
by applying the suggestions and running the Code Assistant again will yield a different planning with a different summary.
Try it out!
What we’ve learned so far
Let’s recap what we’ve learned so far:
- Agentic workflows, compared to RAG workflows, are more flexible and can be used to perform more complex tasks
- Combining multiple Agents improves the accuracy of the LLM reasoning and can save tokens
- AgentKit enables to combine multiple Agents into a Network, connected by a common State
- AgentKit’s Router enables to implement our workflow with code, keeping control over our reasoning planning
Next steps
This Code Assistant v2 shines by its analysis capabilities, but cannot be qualified as an AI Agent.
In the next version of our Code Assistant, we will transform it into a semi-autonomous AI Agent that can solve bugs and improve code of a small project.
Code Assistant v3: Autonomous Code Assistant
The final version update of our Code Assistant will transform it into a semi-autonomous AI Agent.