Tool-Aufrufe sind, wenn einem LLM erlaubt wird, bestimmte Funktionen auszulösen (wie „meine Dateien durchsuchen“, „einen Taschenrechner ausführen“ oder „eine API aufrufen“), indem es eine strukturierte Anfrage sendet, anstatt die Antwort im Text zu erraten. Sie verwenden Tool-Aufrufe, weil sie die Ausgaben zuverlässiger und aktueller machen, und sie dem Modell erlauben reale Aktionen durchzuführen (Systeme abzufragen, Fakten zu verifizieren, Schemata durchzusetzen) statt zu halluzinieren.
In diesem Tutorial lernen Sie, wie Sie lokale LLMs über Tool Calling mit Beispielen für Mathematik, Geschichten, Python-Code und Terminalfunktionen verwenden. Die Inferenz erfolgt lokal über llama.cpp, llama-server und OpenAI-Endpunkte.
Unsere Anleitung sollte für nahezu jedes Modell einschließlich:
Unser erster Schritt ist, das neueste zu erhalten llama.cpp auf GitHub hier. Sie können auch den unten stehenden Build-Anweisungen folgen. Ändern Sie -DGGML_CUDA=ON zu -DGGML_CUDA=OFF wenn Sie keine GPU haben oder nur CPU-Inferenz wünschen.
In einem neuen Terminal (bei Verwendung von tmux: STRG+B+D) erstellen wir einige Tools wie das Addieren von 2 Zahlen, das Ausführen von Python-Code, das Ausführen von Linux-Funktionen und vieles mehr:
Dann verwenden wir die unten stehenden Funktionen (kopieren, einfügen und ausführen), die Funktionsaufrufe automatisch parsen und den OpenAI-Endpunkt für jedes Modell aufrufen:
In diesem Beispiel verwenden wir Devstral 2. Beim Wechseln eines Modells stellen Sie sicher, dass Sie die korrekten Sampling-Parameter verwenden. Sie können alle in unseren Anleitungen hier.
Nun zeigen wir mehrere Methoden zur Ausführung von Tool-Calling für viele verschiedene Anwendungsfälle unten:
Eine Geschichte schreiben:
Mathematische Operationen:
Generierten Python-Code ausführen
Beliebige Terminalbefehle ausführen
🌠 Qwen3-Coder-Next Tool Calling
In einem neuen Terminal erstellen wir einige Tools wie das Addieren von 2 Zahlen, das Ausführen von Python-Code, das Ausführen von Linux-Funktionen und vieles mehr:
Anschließend verwenden wir die untenstehenden Funktionen, die die Funktionsaufrufe automatisch parsen und den OpenAI-Endpunkt für jedes LLM aufrufen:
Nun zeigen wir mehrere Methoden zur Ausführung von Tool-Calling für viele verschiedene Anwendungsfälle unten:
Generierten Python-Code ausführen
Beliebige Terminalbefehle ausführen
Wir bestätigen, dass die Datei erstellt wurde — und das wurde sie!
⚡ GLM-4.7-Flash + GLM 4.7 Aufrufe
Wir laden zuerst herunter GLM-4.7 oder GLM-4.7-Flash via etwas Python-Code und starten es dann über llama-server in einem separaten Terminal (z. B. mit tmux). In diesem Beispiel laden wir das große GLM-4.7-Modell herunter:
Wenn Sie es erfolgreich ausgeführt haben, sollten Sie Folgendes sehen:
Starten Sie es nun über llama-server in einem neuen Terminal. Verwenden Sie tmux, wenn Sie möchten:
Und Sie werden erhalten:
Nun in einem neuen Terminal und beim Ausführen von Python-Code: Zur Erinnerung, führen Sie aus Tool Calling Guide Wir verwenden GLM 4.7s optimale Parameter temperature = 0.7 und top_p = 1.0
Tool-Aufruf für mathematische Operationen für GLM 4.7
Tool-Aufruf zum Ausführen generierten Python-Codes für GLM 4.7
📙 Devstral 2 Tool Calling
Wir laden zuerst herunter Devstral 2 via etwas Python-Code und starten es dann über llama-server in einem separaten Terminal (z. B. mit tmux):
Wenn Sie es erfolgreich ausgeführt haben, sollten Sie Folgendes sehen:
Starten Sie es nun über llama-server in einem neuen Terminal. Verwenden Sie tmux, wenn Sie möchten:
Sie werden Folgendes sehen, wenn es erfolgreich war:
Wir rufen das Modell dann mit der folgenden Nachricht und mit Devstrals vorgeschlagenen Parametern von temperature = 0.15 auf. Zur Erinnerung auszuführen Tool Calling Guide
import json, subprocess, random
from typing import Any
def add_number(a: float | str, b: float | str) -> float:
return float(a) + float(b)
def multiply_number(a: float | str, b: float | str) -> float:
return float(a) * float(b)
def substract_number(a: float | str, b: float | str) -> float:
return float(a) - float(b)
def write_a_story() -> str:
return random.choice([
"Vor langer Zeit in einer weit, weit entfernten Galaxie...",
"Es gab zwei Freunde, die Faultiere und Code liebten...",
"Die Welt ging zu Ende, weil jedes Faultier übermenschliche Intelligenz entwickelte...",
"Unbekannt einem Freund, hatte der andere versehentlich ein Programm geschrieben, um Faultiere zu entwickeln...",
])
def terminal(command: str) -> str:
if "rm" in command or "sudo" in command or "dd" in command or "chmod" in command:
msg = "Kann die Befehle 'rm, sudo, dd, chmod' nicht ausführen, da sie gefährlich sind"
print(msg); return msg
print(f"Führe Terminalbefehl `{command}` aus")
try:
return str(subprocess.run(command, capture_output = True, text = True, shell = True, check = True).stdout)
except subprocess.CalledProcessError as e:
return f"Befehl fehlgeschlagen: {e.stderr}"
def python(code: str) -> str:
data = {}
exec(code, data)
del data["__builtins__"]
return str(data)
MAP_FN = {
"add_number": add_number,
"multiply_number": multiply_number,
"substract_number": substract_number,
"write_a_story": write_a_story,
"terminal": terminal,
"python": python,
}
tools = [
{
"type": "function",
"function": {
"name": "add_number",
"description": "Addiere zwei Zahlen.",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "string",
"description": "Die erste Zahl.",
},
"b": {
"type": "string",
"description": "Die zweite Zahl.",
},
},
"required": ["a", "b"],
},
},
},
{
"type": "function",
"function": {
"name": "multiply_number",
"description": "Multipliziert zwei Zahlen.",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "string",
"description": "Die erste Zahl.",
},
"b": {
"type": "string",
"description": "Die zweite Zahl.",
},
},
"required": ["a", "b"],
},
},
},
{
"type": "function",
"function": {
"name": "substract_number",
"description": "Subtrahiert zwei Zahlen.",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "string",
"description": "Die erste Zahl.",
},
"b": {
"type": "string",
"description": "Die zweite Zahl.",
},
},
"required": ["a", "b"],
},
},
},
{
"type": "function",
"function": {
"name": "write_a_story",
"description": "Schreibt eine zufällige Geschichte.",
"parameters": {
"type": "object",
"properties": {},
"required": [],
},
},
},
{
"type": "function",
"function": {
"name": "terminal",
"description": "Führt Operationen vom Terminal aus.",
"parameters": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "Der Befehl, den Sie ausführen möchten, z. B. `ls`, `rm`, ...",
},
},
"required": ["command"],
},
},
},
{
"type": "function",
"function": {
"name": "python",
"description": "Ruft einen Python-Interpreter mit etwas Python-Code auf, der ausgeführt wird.",
"parameters": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Der auszuführende Python-Code",
},
},
"required": ["code"],
},
},
},
]
from openai import OpenAI
def unsloth_inference(
messages,
temperature = 0.7,
top_p = 0.95,
top_k = 40,
min_p = 0.01,
repetition_penalty = 1.0,
):
messages = messages.copy()
openai_client = OpenAI(
base_url = "http://127.0.0.1:8001/v1",
api_key = "sk-no-key-required",
)
model_name = next(iter(openai_client.models.list())).id
print(f"Verwende Modell = {model_name}")
has_tool_calls = True
original_messages_len = len(messages)
while has_tool_calls:
print(f"Aktuelle Nachrichten = {messages}")
response = openai_client.chat.completions.create(
model = model_name,
messages = messages,
temperature = temperature,
top_p = top_p,
tools = tools if tools else None,
tool_choice = "auto" if tools else None,
extra_body = {"top_k": top_k, "min_p": min_p, "repetition_penalty" :repetition_penalty,}
)
tool_calls = response.choices[0].message.tool_calls or []
content = response.choices[0].message.content or ""
tool_calls_dict = [tc.to_dict() for tc in tool_calls] if tool_calls else tool_calls
messages.append({"role": "assistant", "tool_calls": tool_calls_dict, "content": content,})
for tool_call in tool_calls:
fx, args, _id = tool_call.function.name, tool_call.function.arguments, tool_call.id
out = MAP_FN[fx](**json.loads(args))
messages.append({"role": "tool", "tool_call_id": _id, "name": fx, "content": str(out),})
else:
has_tool_calls = False
return messages
messages = [{
"role": "user",
"content": [{"type": "text", "text": "Könnten Sie mir eine Geschichte schreiben ?"}],
}]
unsloth_inference(messages, temperature = 0.15, top_p = 1.0, top_k = -1, min_p = 0.00)
messages = [{
"role": "user",
"content": [{"type": "text", "text": "What is today's date plus 3 days?"}],
}]
unsloth_inference(messages, temperature = 0.15, top_p = 1.0, top_k = -1, min_p = 0.00)
messages = [{
"role": "user",
"content": [{"type": "text", "text": "Create a Fibonacci function in Python and find fib(20)."}],
}]
unsloth_inference(messages, temperature = 0.15, top_p = 1.0, top_k = -1, min_p = 0.00)
messages = [{
"role": "user",
"content": [{"type": "text", "text": "Schreibe 'I'm a happy Sloth' in eine Datei und gib sie mir danach wieder aus."}],
}]
messages = unsloth_inference(messages, temperature = 0.15, top_p = 1.0, top_k = -1, min_p = 0.00)
import json, subprocess, random
from typing import Any
def add_number(a: float | str, b: float | str) -> float:
return float(a) + float(b)
def multiply_number(a: float | str, b: float | str) -> float:
return float(a) * float(b)
def substract_number(a: float | str, b: float | str) -> float:
return float(a) - float(b)
def write_a_story() -> str:
return random.choice([
"Vor langer Zeit in einer weit, weit entfernten Galaxie...",
"Es gab zwei Freunde, die Faultiere und Code liebten...",
"Die Welt ging zu Ende, weil jedes Faultier übermenschliche Intelligenz entwickelte...",
"Unbekannt einem Freund, hatte der andere versehentlich ein Programm geschrieben, um Faultiere zu entwickeln...",
])
def terminal(command: str) -> str:
if "rm" in command or "sudo" in command or "dd" in command or "chmod" in command:
msg = "Kann die Befehle 'rm, sudo, dd, chmod' nicht ausführen, da sie gefährlich sind"
print(msg); return msg
print(f"Führe Terminalbefehl `{command}` aus")
try:
return str(subprocess.run(command, capture_output = True, text = True, shell = True, check = True).stdout)
except subprocess.CalledProcessError as e:
return f"Befehl fehlgeschlagen: {e.stderr}"
def python(code: str) -> str:
data = {}
exec(code, data)
del data["__builtins__"]
return str(data)
MAP_FN = {
"add_number": add_number,
"multiply_number": multiply_number,
"substract_number": substract_number,
"write_a_story": write_a_story,
"terminal": terminal,
"python": python,
}
tools = [
{
"type": "function",
"function": {
"name": "add_number",
"description": "Addiere zwei Zahlen.",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "string",
"description": "Die erste Zahl.",
},
"b": {
"type": "string",
"description": "Die zweite Zahl.",
},
},
"required": ["a", "b"],
},
},
},
{
"type": "function",
"function": {
"name": "multiply_number",
"description": "Multipliziert zwei Zahlen.",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "string",
"description": "Die erste Zahl.",
},
"b": {
"type": "string",
"description": "Die zweite Zahl.",
},
},
"required": ["a", "b"],
},
},
},
{
"type": "function",
"function": {
"name": "substract_number",
"description": "Subtrahiert zwei Zahlen.",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "string",
"description": "Die erste Zahl.",
},
"b": {
"type": "string",
"description": "Die zweite Zahl.",
},
},
"required": ["a", "b"],
},
},
},
{
"type": "function",
"function": {
"name": "write_a_story",
"description": "Schreibt eine zufällige Geschichte.",
"parameters": {
"type": "object",
"properties": {},
"required": [],
},
},
},
{
"type": "function",
"function": {
"name": "terminal",
"description": "Führt Operationen vom Terminal aus.",
"parameters": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "Der Befehl, den Sie ausführen möchten, z. B. `ls`, `rm`, ...",
},
},
"required": ["command"],
},
},
},
{
"type": "function",
"function": {
"name": "python",
"description": "Ruft einen Python-Interpreter mit etwas Python-Code auf, der ausgeführt wird.",
"parameters": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Der auszuführende Python-Code",
},
},
"required": ["code"],
},
},
},
]
from openai import OpenAI
def unsloth_inference(
messages,
temperature = 1.0,
top_p = 0.95,
top_k = 40,
min_p = 0.01,
repetition_penalty = 1.0,
):
messages = messages.copy()
openai_client = OpenAI(
base_url = "http://127.0.0.1:8001/v1",
api_key = "sk-no-key-required",
)
model_name = next(iter(openai_client.models.list())).id
print(f"Verwende Modell = {model_name}")
has_tool_calls = True
original_messages_len = len(messages)
while has_tool_calls:
print(f"Aktuelle Nachrichten = {messages}")
response = openai_client.chat.completions.create(
model = model_name,
messages = messages,
temperature = temperature,
top_p = top_p,
tools = tools if tools else None,
tool_choice = "auto" if tools else None,
extra_body = {"top_k": top_k, "min_p": min_p, "repetition_penalty" :repetition_penalty,}
)
tool_calls = response.choices[0].message.tool_calls or []
content = response.choices[0].message.content or ""
tool_calls_dict = [tc.to_dict() for tc in tool_calls] if tool_calls else tool_calls
messages.append({"role": "assistant", "tool_calls": tool_calls_dict, "content": content,})
for tool_call in tool_calls:
fx, args, _id = tool_call.function.name, tool_call.function.arguments, tool_call.id
out = MAP_FN[fx](**json.loads(args))
messages.append({"role": "tool", "tool_call_id": _id, "name": fx, "content": str(out),})
else:
has_tool_calls = False
return messages
messages = [{
"role": "user",
"content": [{"type": "text", "text": "Create a Fibonacci function in Python and find fib(20)."}],
}]
unsloth_inference(messages, temperature = 1.0, top_p = 0.95, top_k = 40, min_p = 0.00)
messages = [{
"role": "user",
"content": [{"type": "text", "text": "Schreibe 'I'm a happy Sloth' in eine Datei und gib sie mir danach wieder aus."}],
}]
messages = unsloth_inference(messages, temperature = 1.0, top_p = 1.0, top_k = 40, min_p = 0.00)
# !pip install huggingface_hub hf_transfer
import os
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
from huggingface_hub import snapshot_download
snapshot_download(
repo_id = "unsloth/GLM-4.7-GGUF",
local_dir = "unsloth/GLM-4.7-GGUF",
allow_patterns = ["*UD-Q2_K_XL*",], # Für Q2_K_XL
)