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

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

Download DeepSeek R1 Model Locally free | AI RAG with LlamaIndex, Local Embedding and Ollama

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

Create Chat bot application using Python, Streamlit and Gemini AI

Restore the lost focus of Auto post back controls in asp.net update Panel control