RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /How-to
  5. /How to Use OpenAI Function Calling with Tools
HOW-TO · RAG

How to Use OpenAI Function Calling with Tools

intermediate·20 min·By Eruo Fredoline
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES

OpenAI API key or local model with tool support, Python 3.10+

What this does

Function calling lets the LLM request execution of external tools by outputting structured JSON. The application executes the tool and feeds the result back to the model for a final answer.

Steps

  • Define tool schemas. Each tool requires a JSON Schema description of its parameters.
import json
from openai import OpenAI

client = OpenAI(api_key="sk-...", base_url="http://localhost:11434/v1")  # Ollama also works

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "The city name"
                    }
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "Evaluate a math expression",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "Math expression like '2+2'"
                    }
                },
                "required": ["expression"]
            }
        }
    }
]
  • Send a request with tools. The model may return a tool_calls response.
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "What's 15*7 and the weather in Paris?"}],
    tools=tools,
    tool_choice="auto"
)

message = response.choices[0].message
print(message.tool_calls)
  • Execute tool calls and return results. Map function names to local implementations.
def get_weather(city: str) -> str:
    return f"Weather in {city}: 22°C, sunny"

def calculate(expression: str) -> str:
    return str(eval(expression))

if message.tool_calls:
    messages = [{"role": "user", "content": "What's 15*7 and the weather in Paris?"}]
    messages.append(message)

    for tc in message.tool_calls:
        func = globals()[tc.function.name]
        args = json.loads(tc.function.arguments)
        result = func(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": tc.id,
            "content": result
        })

    # Send back to model for final answer
    final = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
    print(final.choices[0].message.content)
  • Force a specific tool with tool_choice. Use {"type": "function", "function": {"name": "calculate"}} to force.

Verification

python -c "
from openai import OpenAI
c = OpenAI(api_key='sk-test', base_url='http://localhost:11434/v1')
r = c.chat.completions.create(model='llama3.2', messages=[{'role':'user','content':'say hi'}], tools=[{'type':'function','function':{'name':'test','parameters':{'type':'object','properties':{'x':{'type':'string'}},'required':['x']}}}])
print(r.choices[0].finish_reason)
# Expected: stop or tool_calls
"

Common failures

  • Tool choice ignored by local models. Some models don't respect tool_choice: "required". Fall back to parsing function calls from text.
  • JSON schema too complex. Deeply nested $ref or allOf schemas cause parsing failures. Use flat properties with type and description.
  • Missing tool_call_id. The tool response must include the exact id from the model's request. A mismatch causes the model to ignore the response.
  • Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
  • Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.

Related guides

  • How to Define JSON Schema for Tool Calling
  • How to Handle Function Call Errors and Retries
← All how-to guidesCourses →