How to Implement LLM Function Calling in Python

LLM function calling is a two-step loop: ask the model to pick a tool (it replies with JSON), then your code parses that choice and runs the matching function. The model decides; your code does the work. Here's how to wire it end to end.

AI Engineeraillmfunction-calling

Why let the LLM choose a tool?

Language models are poor at arithmetic and have no live data - but they are good at understanding intent. Function calling uses that: you describe a set of tools, the model replies with a structured tool choice, and your code executes it deterministically. No hallucinated math, no stale answers.

The model is the router. Your functions are the workers.

The shape of the loop

# 1. Ask the model - it replies with a JSON tool choice
# 2. Parse {"tool": "calculator", "input": "47*9"}
# 3. Look up the tool function and call it
# 4. Return the result (not the model's text)

A minimal Flask implementation

import json
import requests
from flask import Flask, request, jsonify

app = Flask(__name__)
LLM_URL = "http://llm-service:8080/v1/chat/completions"

def _calc(expr):
    return eval(expr, {"__builtins__": {}}, {})

TOOLS = {
    "calculator": _calc,
}

def ask_llm(message: str) -> str:
    body = {
        "model": "the-model",
        "messages": [
            {
                "role": "system",
                "content": 'Choose a tool. Reply ONLY with JSON: {"tool": "calculator", "input": "<expr>"}',
            },
            {"role": "user", "content": message},
        ],
        "temperature": 0,
    }
    r = requests.post(LLM_URL, json=body, timeout=60)
    r.raise_for_status()
    return r.json()["choices"][0]["message"]["content"]

@app.post("/api/ask")
def ask():
    message = (request.get_json(silent=True) or {}).get("message", "")
    raw = ask_llm(message)

    try:
        choice = json.loads(raw)
        tool_name = choice["tool"]
        tool_input = choice["input"]
    except Exception:
        return jsonify(error="could not parse a tool choice", raw=raw), 502

    if tool_name not in TOOLS:
        return jsonify(error=f"unknown tool: {tool_name}"), 400

    result = TOOLS[tool_name](tool_input)
    return jsonify(tool=tool_name, result=result)

The endpoint returns {"tool": "calculator", "result": 423} - not the model's raw text.

Three things that matter in production

Extending to multiple tools

Add more entries to TOOLS and describe all of them in the system prompt. The model picks one per turn. For multi-step agent loops, feed the tool result back into the conversation as a new message and ask the model again - repeat until it stops calling tools.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

What is LLM function calling?

Function calling is a pattern where you prompt the LLM to reply with a structured JSON tool choice (e.g. which function to call and with what input) instead of freeform text. Your code then parses that choice and calls the real function, returning the result.

How do I parse the tool choice from the LLM response?

Prompt the model to return only raw JSON, then use json.loads on the response content. Extract the 'tool' and 'input' keys, validate that the tool is in your allowlist, and call the matching function.

Should I use eval() to run LLM-requested tool inputs?

Only with a restricted builtins dict (eval(expr, {'__builtins__': {}}, {})) for simple math expressions in a sandboxed environment. In production, parse the input explicitly and dispatch to vetted functions - never eval untrusted strings.

What is the difference between an LLM agent and function calling?

Function calling is one capability: the model returns structured JSON asking to call a tool, and your code runs it. An agent is a loop that uses function calling repeatedly - call, observe, decide - until a task is done. Function calling is a building block of agents.

Keep learning

Restore a Broken LLM API IntegrationAI/ML projectHarden an LLM Pipeline Against API FailuresAI/ML projectParse JSON From an LLM (Strip Markdown Fences)AI/ML projectAI/ML roadmapStep by step to hiredAI/ML interview questionsSTAR answersAll AI/ML projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →