...

/

The AI Research Assistant: Agent Assembly and Orchestration

The AI Research Assistant: Agent Assembly and Orchestration

Assemble the individual RAG and API tools into a single, cohesive ReActAgent to create a fully functional application.

We'll cover the following...

In our last lesson, we methodically built and tested each of the three tools for our AI research assistant. We now have a reliable RAG tool for our local documents and two functional API tools for arXiv and Wikipedia. Our toolbox is complete.

In this lesson, we will finally assemble these components into a single, cohesive system. We will instantiate our ReActAgent, provide it with its brain (the LLM) and its capabilities (our custom tools), and then interact with it for the first time. This is where we will witness our agent’s intelligence in action as it orchestrates its tools to solve complex problems.

The orchestration layer

Our main.py file will serve as the entry point and orchestration layer for our application. Its responsibility is to initialize all the necessary components (the LLM and the tools) and assemble them into the final ReActAgent, which will handle user queries.

We will now work exclusively in our main.py file. The first step is to import all the necessary components: the agent class, the LLM, and the tool objects and functions that we created in Lesson 6.

We add the following import statements to the top of our main.py file:

# main.py
import os
import asyncio
from dotenv import load_dotenv
# Import our agent and LLM
from llama_index.core.agent import ReActAgent
from llama_index.llms.groq import Groq
# Import our custom tools from the /tools directory
from tools.rag_tool import get_rag_tool
from tools.api_tools import arxiv_tool, definition_tool
print("Successfully imported all necessary modules.")
Main application imports. We bring in the core ReActAgent class, the Groq LLM, and our custom-built tools from their respective modules

With our workspace prepared and our components imported, we are now ready to initialize and assemble our agent.

Now that we have imported all the necessary components, the next step is to write the main logic that initializes our tools, configures the agent, and starts the interactive session. This is where the components we built in Lesson 6 are finally brought together.

We will encapsulate our main logic within a main() function to keep our script organized.

We add the following code to your main.py file, underneath the import statements. This code brings all the components together to set up and initialize our ReActAgent.

# main.py (continued)
def main():
# Load environment variables from the .env file
load_dotenv()
print("Environment variables loaded.")
# --- 1. Initialize the LLM ---
# We use the Groq LLM for its fast inference speed.
llm = Groq(model="llama-3.1-8b-instant", api_key="{{GROQ_API_KEY}}")
# --- 2. Initialize the Tools ---
print("Initializing tools...")
# We call the factory function from our rag_tool.py module.
rag_tool = get_rag_tool()
# The API tools are already initialized in api_tools.py, so we can use them directly.
all_tools = [rag_tool, arxiv_tool, definition_tool]
print("✅ Tools initialized.")
# --- 3. Create the Agent ---
print("Initializing the ReAct Agent...")
agent = ReActAgent.from_tools(
tools=all_tools,
llm=llm,
verbose=True # CRITICAL for learning and debugging!
)
print("✅ Agent is ready. You can start asking questions.")
# --- 4. Create an Interactive Loop (to be added in the next section) ---
if __name__ == "__main__":
main()
This code sets up the LLM, gathers our pre-built tools into a list, and uses them to instantiate the ReActAgent
  • Line 2: We define the main() function, which encapsulates the core setup logic for our application.

  • Line 4: load_dotenv() reads the .env file and loads the GROQ_API_KEY as an environment variable.

  • Line 9: We initialize the Groq LLM instance, specifying the model (llama-3.1-8b-instant) and passing the API key loaded from the environment variables. This LLM will serve as the agent’s “brain.”

  • Line 14: We call the get_rag_tool() factory function that we imported from tools/rag_tool.py. This executes the code in that file and returns our fully configured RAG tool object.

  • Line 17: We create a Python list called all_tools. This list holds all the tool objects that our agent should have access to. We include our rag_tool (from the previous line) and the arxiv_tool and definition_tool that were imported directly from tools/api_tools.py. This modular approach makes it easy to add or remove capabilities later by just modifying this list.

  • Lines 22-26: This is the agent assembly step ...