Tool als Config-Datei anlegen
Der empfohlene Weg für produktive Tools — versioniert, review-bar, testbar.
Für alles, was produktiv laufen soll, sind Config-Dateien der richtige Ort. Sie landen in Git, lassen sich im Review prüfen und können Helfer-Funktionen nutzen.
Ordnerstruktur
In deinem Workspace:
tools/
├── dropbox/
│ ├── uploads/
│ │ └── uploadFile.php
│ └── listing/
│ └── listFiles.php
├── jtl/
│ └── orders/
│ └── getOrder.php
└── knowledge/
└── getKnowledge.php
Die Gruppierung nach API und Kategorie ist Konvention. Du darfst sie brechen, wenn du willst — der Loader scannt rekursiv, die Ordnernamen sind nur für dich.
Datei-Template
Jede .php-Datei gibt ein Array zurück, das einen oder mehrere Tools definiert. Der Schlüssel tools.<toolName> ist dabei zwingend.
<?php
return [
'tools' => [
'getInvoice' => [
'description' => 'Rechnung per ID abrufen.',
'parameters' => [
'type' => 'object',
'properties' => [
'id' => [
'type' => 'string',
'description' => 'Rechnungs-ID wie in JTL angezeigt.',
],
],
'required' => ['id'],
],
'api' => 'jtl',
'method' => 'GET',
'path' => '/invoices/{id}',
'mapping' => [
'id' => 'invoice_id',
'total' => 'amounts.gross',
'customer' => 'customer.name',
],
],
],
];
Mit Preprocess und Postprocess
<?php
return [
'tools' => [
'getInvoice' => [
// ... wie oben ...
'preprocess' => function (array $args, $ctx): array {
$args['id'] = strtoupper($args['id']);
return $args;
},
'postprocess' => function (array $result, array $args, $ctx): array {
$result['totalWithTax'] = round($result['total'] * 1.19, 2);
return $result;
},
],
],
];
Handler-only
Ohne API, reine PHP-Logik:
<?php
return [
'tools' => [
'calculateTax' => [
'description' => 'Netto-Betrag mit MwSt. berechnen.',
'parameters' => [
'type' => 'object',
'properties' => [
'net' => ['type' => 'number'],
'rate' => ['type' => 'number', 'description' => 'z. B. 0.19'],
],
'required' => ['net', 'rate'],
],
'handler' => function (array $results, array $args, array $ctx): array {
$gross = $args['net'] * (1 + $args['rate']);
return [
'net' => $args['net'],
'tax' => round($gross - $args['net'], 2),
'gross' => round($gross, 2),
];
},
],
],
];
Mehrere Tools pro Datei
Möglich, aber: eine Datei pro Tool hält Diffs klein und Namen eindeutig. Nur gruppieren, wenn Tools sehr eng zusammengehören und z. B. dieselbe Helferfunktion teilen.
Test-Fixture
Für schnelle lokale Tests kannst du einem Tool ein Args-Fixture mitgeben:
'args_fixture' => ['id' => 'INV-2026-001'],
Damit läuft:
tm test-tool getInvoice
ohne dass du die Args manuell eintippen musst — das Fixture wird automatisch verwendet.
Shared Tools
Tools, die über mehrere Workspaces hinweg sinnvoll sind (z. B. getKnowledge), leben in einem geteilten Bereich. Du referenzierst sie mit extends:
return [
'tools' => [
'getKnowledge' => [
'extends' => 'getKnowledge',
'description' => 'Durchsucht unsere Produkt-Wissensbasis.',
'args_fixture' => ['query' => 'Tomaten'],
],
],
];
Das zieht die Basis-Definition aus dem Shared-Bereich und erlaubt dir, einzelne Felder zu überschreiben.
Nach dem Anlegen
- Konfig wird beim nächsten Request automatisch neu geladen (Dev).
- In Production: je nach Setup ggf.
bin/cake cache clear_alloder Deploy nötig. - Das Tool ist erst sichtbar, wenn es in der
tools-Liste eines Chats oder Assistants steht.