Some examples of calling AI tool API using python

πŸ”§ Production Example 1 β€” Basic Tool Calling (Weather API)

🧠 Use Case

User asks:

β€œWhat’s the weather in Delhi?”

LLM decides to call get_weather().


πŸ“¦ Step 1 β€” Define Tool Schema

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Fetch current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        }
    }
]


🧠 Step 2 β€” Define Backend Function

def get_weather(city: str) -> dict:
    # In production, call real weather API here
    return {
        "city": city,
        "temperature": "28Β°C",
        "condition": "Sunny"
    }


πŸš€ Step 3 β€” Call LLM with Tools Enabled

from openai import OpenAI
import json

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "user", "content": "What is the weather in Delhi?"}
    ],
    tools=tools,
    tool_choice="auto"
)


πŸ” Step 4 β€” Detect Tool Call

message = response.choices[0].message

if message.tool_calls:
    tool_call = message.tool_calls[0]
    function_name = tool_call.function.name
    arguments = json.loads(tool_call.function.arguments)

    # Secure validation
    if function_name == "get_weather" and "city" in arguments:
        result = get_weather(arguments["city"])


πŸ” Step 5 β€” Send Tool Result Back to Model

second_response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "user", "content": "What is the weather in Delhi?"},
        message,
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result)
        }
    ]
)

print(second_response.choices[0].message.content)


πŸ” Production Enhancements (Critical)

In real systems, always:

  • Validate arguments
  • Apply rate limits
  • Log tool usage
  • Restrict allowed tools per user role
  • Sanitize inputs

Never directly trust model-generated arguments.


πŸ” Production Example 2 β€” Database Query Tool

🧠 Use Case

User asks:

β€œShow last 5 orders for customer ID 1024.”


πŸ“¦ Tool Definition

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_recent_orders",
            "description": "Fetch recent orders for a customer",
            "parameters": {
                "type": "object",
                "properties": {
                    "customer_id": {"type": "integer"},
                    "limit": {"type": "integer"}
                },
                "required": ["customer_id"]
            }
        }
    }
]


🧠 Backend Implementation

def get_recent_orders(customer_id: int, limit: int = 5):
    # Replace with actual database query
    return [
        {"order_id": 501, "amount": 1200},
        {"order_id": 502, "amount": 850}
    ][:limit]


πŸ›‘οΈ Secure Execution Pattern

if function_name == "get_recent_orders":
    customer_id = int(arguments["customer_id"])
    limit = int(arguments.get("limit", 5))

    # Security check example
    if limit > 20:
        raise ValueError("Limit exceeds maximum allowed")

    result = get_recent_orders(customer_id, limit)


🧠 Production Example 3 β€” ReAct-Style Tool Loop

For multi-step reasoning:

messages = [
    {"role": "system", "content": "You are an enterprise AI assistant."},
    {"role": "user", "content": "Calculate tax for order 501 and provide summary."}
]

while True:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        tools=tools,
        tool_choice="auto"
    )

    message = response.choices[0].message

    if not message.tool_calls:
        print(message.content)
        break

    tool_call = message.tool_calls[0]
    function_name = tool_call.function.name
    arguments = json.loads(tool_call.function.arguments)

    # Execute tool securely
    result = execute_tool(function_name, arguments)

    messages.append(message)
    messages.append({
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": json.dumps(result)
    })

This creates:

Think β†’ Call Tool β†’ Observe β†’ Think β†’ Respond


πŸ—οΈ Enterprise Architecture Pattern

Production systems include:

  • Tool registry
  • Execution controller
  • Role-based access
  • Logging layer
  • Observability metrics
  • Retry logic
  • Failure handling

Never let the LLM directly execute code.

Always isolate execution layer.


πŸ›‘οΈ Security Best Practices

1️⃣ Strict Schema Validation

Use pydantic or JSON schema validation.

2️⃣ Input Sanitization

Prevent SQL injection or command injection.

3️⃣ Tool Permission Matrix

Not all users can access all tools.

4️⃣ Timeout & Fallback

Prevent hanging calls.

5️⃣ Audit Logging

Track every tool invocation.


πŸ“Š Why This Matters

Without tool calling:

  • LLM hallucinates data

With tool calling:

  • LLM retrieves real data
  • Backend enforces control
  • System becomes deterministic

This is the foundation of:

  • Enterprise AI copilots
  • Autonomous agents
  • AI workflow systems
  • RAG + Tools hybrid systems

🏁 Final Thought

Prompt Engineering controls output.

Tool Calling controls action.

Together, they create real-world AI systems.

Step by step AI

Leave a Comment