Function Calling: The Key to Connecting AI with the Real World

Artificial Intelligence tutorial - IT technology blog
Artificial Intelligence tutorial - IT technology blog

When AI is Brilliant but Out of Touch with Reality

You’ve likely encountered this: asking ChatGPT for this morning’s Bitcoin price or Claude to check if a server is up. The response is usually a polite apology about outdated data, or worse, a convincingly hallucinated number.

In reality, LLMs (Large Language Models) are like super-brains locked in a glass box. They can write poetry or code at lightning speed but lack the “hands” to touch the real world. AI doesn’t know if it’s raining in Hanoi today, nor can it access your database to pull a sales report.

Through various automation projects, I’ve found this to be the biggest hurdle. If limited to just back-and-forth chatting, AI remains a high-end toy rather than a powerful collaborator.

Why is AI so Limited?

The root cause lies in training. Models like GPT-4 or Claude 3.5 Sonnet learn from massive but static datasets. Once training ends, their knowledge is frozen, turning AI into a “bookworm” that only knows the past.

The common solution is RAG (copy-pasting data into the prompt). However, this spikes token usage, and the AI still can’t take action. To enable AI to call APIs, delete DB records, or send emails, we need a mechanism for it to understand and control its surroundings. That’s where Function Calling (or Tool Use) shines.

The Solution: Turning AI into a Tool Operator

Currently, both OpenAI and Anthropic allow us to describe functions to the AI. Note that the AI doesn’t execute the code directly. Instead, it returns a JSON file containing the function name and arguments, and then our server executes the command.

1. Implementation with OpenAI API

With OpenAI, you define a list of tools in the request. Here’s how I integrated real-time weather lookups with only 1-2 seconds of latency:

import openai

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get real-time weather for a specific city",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "Example: Hanoi"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["location"]
            }
        }
    }
]

response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Is it raining in Hanoi today?"}],
    tools=tools,
    tool_choice="auto"
)

Instead of returning text, GPT will request a call to get_current_weather(location="Hanoi"). You simply fetch data from a real weather API and feed it back to the AI to synthesize the answer for the user.

2. Implementation with Claude API (Anthropic)

On the Claude side, this concept is called Tool Use. The syntax differs slightly, but the logic is identical. Claude 3.5 Sonnet is currently highly regarded for its precise parameter reasoning and minimal data confusion.

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=1024,
    tools=[
        {
            "name": "query_database",
            "description": "Query order from internal system",
            "input_schema": {
                "type": "object",
                "properties": {
                    "order_id": {"type": "string", "description": "Order ID format #ITFZ-xxx"}
                },
                "required": ["order_id"]
            }
        }
    ],
    messages=[{"role": "user", "content": "Check status for order #ITFZ-123"}]
)

Battle-Tested Tips: Keeping AI from “Hallucinating” During Function Calls

Using Function Calling isn’t hard, but making it production-stable is another story. Here are three “lessons learned the hard way” that I’ve gathered:

The Description is Key

Never write lazy descriptions like "get data". AI selects functions entirely based on this field. Be specific: “Use this function when a customer asks for shipping status. Input must be a code starting with ITFZ”. A good description can reduce incorrect function calls to under 5%.

Always Handle Tool Errors

If your API returns a 404 or 500 error, don’t just dump the raw error at the AI. Format it: “Error: Order not found, please ask the customer to double-check the code”. The AI will then respond more gracefully rather than relaying dry system logs.

Security First: The Critical Vulnerability

Never let AI autonomously execute destructive commands like DROP TABLE. AI can be prone to Prompt Injection attacks, leading it to call dangerous functions. I always follow the principle: AI only has read access. Any write/delete operations must require an admin to click “Confirm” on a dashboard.

Managing Token Costs

Every Tool you define consumes tokens in every request. Stuffing 50 tools in at once is expensive and confuses the AI. My tip is to categorize Tools into groups. Only load the “finance” toolset into the context when the user asks a finance-related question.

I hope these insights give you more confidence when building AI applications. Function Calling is the bridge that turns a basic chatbot into a true virtual assistant!

Share: