LLM Agents Under the Hood: I Built One with Google's Python SDK

 I built advanced LLM (Large Language Model) Agents from the ground up using Python and the Google Generative AI package. I won't just show you the code; I'll explain exactly how agents work under the hood, from reasoning and planning to tool execution. 

  This tutorial is perfect for a developer, data scientist, or AI enthusiast ready to move from simple prompt engineering to building truly Agentic AI applications.

 

 


 

PREREQUISITES:

  • Basic knowledge of Python. 
  • A Google AI Studio API Key (it's free!).
  •  pip install google-generativeai python-dotenv

 Create new file named "shopping_agent.py" and add below code inside the file. 

 def confirm_shopping_order(product, quantity,address) -> str:  
      """  
      Function-callable API for Confirm a shopping order.  
      params: dict with keys 'product', 'quantity', 'address', etc.  
      """  
      #API call to search product availability can be added here  
      prompt = (  
           "You are a shopping assistant. "  
           "Following is the List of products available : "       
           "| Product Id | Brand | Product Name | Price |"  
           "|------------|-------|--------------|-------|"  
 "| 012121 | Bata | Formal Leather Shoes | ₹2,499 |"  
 "| 012122 | Metro | Casual Loafers | ₹1,799 |"  
 "| 012123 | Paragon | Sports Sandals | ₹899 |"  
 "| 012124 | Liberty | Executive Formal Shoes | ₹3,499 |"  
 "| 012125 | Action | Running Shoes | ₹1,299 |"  
 "| 012126 | Woodland | Outdoor Trekking Shoes | ₹4,999 |"  
 "| 012127 | Relaxo | Everyday Flip Flops | ₹399 |"  
 "| 012128 | Red Tape | Casual Sneakers | ₹2,199 |"  
 "| 012129 | Campus | Sports Shoes | ₹1,599 |"  
 "| 012130 | Lancer | School Shoes | ₹799 |\r\n"        
           f"Quantity asked: {quantity}, "  
           f"Address to deliver: {address}. "  
           f"product to deliver: {product}. "  
           "If any information is missing, ask for it. Take product confirmation by user."  
      )  
      print(prompt)  
      return prompt  
 def place_shopping_order(productId,brand, product, quantity,address, price) -> str:  
      """  
      Function-callable API for placing a shopping order.  
      params: dict with keys 'productId','product','Brand', 'quantity', 'address', etc.  
      """  
      #API call to place order can be added here  
      prompt = (  
           "You are a shopping assistant. "  
           "Follwing Order is Placed: "  
           f"Product Id: {productId}, "  
           f"Brand: {brand}, "  
           f"Product: {product}, "  
           f"Quantity: {quantity}, "  
           f"Address: {address}. "  
           f"Price: {price} "  
           "If any more order to place, ask for it."  
      )  
      print(prompt)  
      return prompt  
 # Example function schema for tool registration  
 CONFIRM_SHOPPING_ORDER_SCHEMA = {   
      "name": "confirm_shopping_order",  
      "description": "confirm a shopping order before placing order for a user.",  
      "parameters": {  
           "type": "object",  
           "properties": {  
                "product": {"type": "string", "description": "Product to order"},  
                "quantity": {"type": "string", "description": "Quantity of the product"},  
                "address": {"type": "string", "description": "Delivery address"}  
           },  
           "required": ["product", "quantity", "address"]  
      }  
 }  
 # Example function schema for tool registration  
 PLACE_SHOPPING_ORDER_SCHEMA = {  
      "name": "place_shopping_order",  
      "description": "Place a shopping order for a user.",  
      "parameters": {  
           "type": "object",  
           "properties": {  
                "productId": {"type": "string", "description": "Product id to order"},  
                "brand": {"type": "string", "description": "Brand of the Product to order"},  
                "product": {"type": "string", "description": "Product to order"},  
                "quantity": {"type": "string", "description": "Quantity of the product"},  
                "price": {"type": "string", "description": "Price of the product"},  
                "address": {"type": "string", "description": "Delivery address"}  
           },  
           "required": ["product", "quantity", "address"]  
      }  
 }  

 Create new file named "train_ticket_agent.py" and add below code inside the file.  

 def book_train_ticket(from_location, to_location, date,passenger_name) -> str:  
      """  
      Function-callable API for booking train tickets.  
      params: 'from_location', 'to_location', 'date', 'passenger_name', etc.  
      """  
      prompt = (  
           "You are a train ticket booking assistant. "  
           "Book a train ticket with the following details: "  
           f"From: {from_location}, "  
           f"To: {to_location}, "  
           f"Date: {date}, "  
           f"Passenger: {passenger_name}. "  
           "If any information is missing, ask for it."  
      )  
      print(prompt)  
      return prompt  
 # Example function schema for tool registration  
 BOOK_TRAIN_TICKET_SCHEMA = {  
      "name": "book_train_ticket",  
      "description": "Book a train ticket for a user.",  
      "parameters": {  
           "type": "object",  
           "properties": {  
                "from_location": {"type": "string", "description": "Departure city or station"},  
                "to_location": {"type": "string", "description": "Arrival city or station"},  
                "date": {"type": "string", "description": "Date of travel"},  
                "passenger_name": {"type": "string", "description": "Name of the passenger"}  
           },  
           "required": ["from_location", "to_location", "date", "passenger_name"]  
      }  
 }  

 Create new file named "main.py" and add below code inside the file. 

 import sys  
 from pathlib import Path  
 # Ensure project root is on sys.path so "agents" package can be imported  
 _project_root = Path(__file__).resolve().parents[1]  
 if str(_project_root) not in sys.path:  
   sys.path.insert(0, str(_project_root))  
 import os  
 from dotenv import load_dotenv  
 import google.generativeai as genai  
 from agents.train_ticket_agent import book_train_ticket, BOOK_TRAIN_TICKET_SCHEMA   
 from agents.shopping_agent import confirm_shopping_order,place_shopping_order, PLACE_SHOPPING_ORDER_SCHEMA,CONFIRM_SHOPPING_ORDER_SCHEMA  
 from google.generativeai import types  
 def main():  
      load_dotenv()  
      api_key = os.getenv("GEMINI_API_KEY")  
      if not api_key:  
           print("Please set the GEMINI_API_KEY environment variable in your .env file.")  
           return  
      genai.configure(api_key=os.getenv("GEMINI_API_KEY"))  
      # Register agent functions as tools  
      tools = [genai.types.Tool(function_declarations=[  
           BOOK_TRAIN_TICKET_SCHEMA,  
           CONFIRM_SHOPPING_ORDER_SCHEMA,            
           PLACE_SHOPPING_ORDER_SCHEMA  
      ])]  
      systemPrompt = (     "You are an intelligent assistant that can help users with various tasks such as booking train tickets, "  
           "Confirming the shopping order first with user then place the shopping orders. Call appropriate tool as per provided tools metadata in proper order to smooth agent workflow. ")  
      model = genai.GenerativeModel(model_name='models/gemini-2.5-flash',tools=tools,system_instruction=systemPrompt)  
      print("Agentic App: LlamaIndex + Google Gemini (Function Calling)")  
      print("Type 'exit' to quit.")  
      contents=[]  
      while True:  
           user_input = input("\nEnter your request: ")  
           if user_input.lower() == 'exit':  
                break        
           if contents.__len__() > 10:  
                contents=contents[10:]                 
           if contents.__len__()==0:       
                contents = [ types.ContentDict(role="user", parts=[types.PartDict(text=user_input)])]        
           else:  
                contents.append(types.ContentDict(role="user", parts=[types.PartDict(text=user_input)]))       
           print(Call_model(contents,model))  
 def Call_model(user_input, model) -> str:  
           innerResult= ""  
           result = model.generate_content(user_input)   
           user_input.append(result.candidates[0].content)             
           if(result.parts.__str__().__contains__("function_call")):                 
                for fn in result.parts:  
                     function_call =fn.function_call                  
                     function_name = function_call.name  
                     function_args = function_call.args  
                     for tool in model._tools._tools:                            
                          for fnc in tool._function_declarations:                                
                               if fnc.name == function_name:  
                                    print(f"Calling function: {function_name} with args: {function_args}")  
                                    funResult = ""  
                                         # Call the appropriate function based on the function name  
                                    if function_name == "book_train_ticket":  
                                         funResult = book_train_ticket(**function_args)  
                                    elif function_name == "confirm_shopping_order":  
                                         funResult = confirm_shopping_order(**function_args)  
                                    elif function_name == "place_shopping_order":  
                                         funResult = place_shopping_order(**function_args)  
                                    else:  
                                         funResult = f"Unknown function: {function_name}"                                
                                    user_input.append(types.ContentDict(role="Model", parts=["tool `{function_name}` response : "+funResult]))  
                innerResult= Call_model(user_input,model)                 
           return innerResult if innerResult.__len__() > 0 else getOutputString(result,user_input)   
 def getOutputString(result,user_input) -> str:  
      finalOtupt=[]  
      if(result.candidates.__len__()>0):       
           for part in result.candidates[0].content.parts:  
                finalOtupt.append(part.text)  
           user_input.append(types.ContentDict(role="Model", parts=[types.PartDict(text=" ".join(finalOtupt))]))  
      return " ".join(finalOtupt)  
 if __name__ == "__main__":  
      main()  

  Create new file named ".env" and add below keys inside the file. 

 # .env file for Gemini API Key  
 GEMINI_API_KEY=Add your gemini key  

 Now Run the application by firing below command in terminal.

 python main.py  

 Below is the output of above application after executing the application. 

 agent output 1

 agent output 2

 Agent output 3

 

Comments

Popular posts from this blog

I have created an application to extract text from image using AI

Use Chroma DB vector database in RAG application using llama index & Deepseek R1 local model

Understanding the Singleton Design Pattern in C#

Create Chat bot application using Python, Streamlit and Gemini AI

Angular User Session Timeout example step by step