Zum Inhalt springen
Nibiru docsv0.9.2

Agent-Plugin

Ein ReAct-stiliges Werkzeugnutzungs-Agent. Erweitern Sie das Werkzeug, um ihm jede PHP-Fähigkeit zu geben, die Sie schreiben können.

Stable Reading time ~ 3 min Edit on GitHub

Das Agent-Plugin ermöglicht es Ihnen, einer LLM die Fähigkeit zu geben — SQL-Abfragen auszuführen, HTTP-Endpunkte anzusprechen, Dateien zu lesen oder alles andere zu tun, was Sie als PHP-Methode ausdrücken können. Es führt eine ReAct-artige Schleife durch: Denken → Werkzeug-Aufruf → Beobachten → Wiederholen → Antworten.

use Nibiru\Module\Ai\Ai;
use Nibiru\Module\Ai\Plugin\Tools\PdoQuery;
$ai = new Ai();
echo $ai->agent()
->withTools([new PdoQuery()])
->run('How many active users do we have?');
// → "We have 1,247 active users." (after the agent ran SELECT count(*)…)
user task
LLM gets system prompt with tool definitions
LLM emits ```tool {"tool":"pdo_query","args":{"sql":"SELECT…"}}```
Agent runs the tool, captures result
LLM gets observation, decides: more tools or final answer?
"FINAL: 1,247 active users."

Das Protokoll verwendet einen gepufferten JSON-Sentinel\“tool {…}```— den jeder Modell erzeugen kann. Es ist keine native Tool-Aufruf-API erforderlich, daher funktioniert es auf jedem Ollama-Modell out of the box. (Modelle, die eine native Tool-Aufruf-API unterstützen, können über einen Subclass eingesetzt werden, derparseToolCall()` überschreibt.)

Nibiru bietet drei Produkte an:

WerkzeugWas es macht
Tools\PdoQueryEinzelner schreibgeschützter SELECT-Befehl gegen die App-Datenbank. Blockiert INSERT/UPDATE/DELETE/DROP/TRUNCATE/ALTER. Gibt bis zu 50 Zeilen als JSON zurück.
Tools\HttpGetHolt eine HTTP/HTTPS-URL mit optionalen Headern. Gibt den Body zurück, abgeschnitten auf 8 KB.
Tools\FileReadLiest eine Projektdatei über einen relativen Pfad. Blockiert die ..-Reise. Gibt bis zu 8 KB zurück.
use Nibiru\Module\Ai\Plugin\Tools;
$agent = $ai->agent()->withTools([
new Tools\PdoQuery(),
new Tools\HttpGet(),
new Tools\FileRead(),
]);
// Multi-step task
echo $agent->run(
'Read application/controller/loginController.php and tell me '
. 'whether it implements rate limiting.'
);

Der Agent wird file_read mit dem Pfad aufrufen, die Quelle beobachten und basierend auf dem tatsächlichen Gesehenen antworten – nicht auf das, was es sich vorstellt.

Erweitern Sie Tool:

namespace App\AiTools;
use Nibiru\Module\Ai\Plugin\Tool;
class StripeRefund extends Tool
{
public function name(): string { return 'stripe_refund'; }
public function description(): string {
return 'Issue a Stripe refund for a charge ID.';
}
public function schema(): array {
return [
'charge_id' => [
'type' => 'string',
'description' => 'A Stripe charge ID, e.g. ch_3K…',
'required' => true,
],
'amount_cents' => [
'type' => 'integer',
'description' => 'Amount to refund in cents. Omit for full refund.',
'required' => false,
],
];
}
public function execute(array $args): mixed {
$stripe = new \Stripe\StripeClient(getenv('STRIPE_SECRET_KEY'));
$refund = $stripe->refunds->create(array_filter([
'charge' => $args['charge_id'],
'amount' => $args['amount_cents'] ?? null,
]));
return json_encode([
'refund_id' => $refund->id,
'status' => $refund->status,
'amount' => $refund->amount,
]);
}
}

Dann stecken Sie es ein:

$ai->agent()
->withTools([new \App\AiTools\StripeRefund(), new Tools\PdoQuery()])
->run('Refund order #4421 — they were charged twice.');

Der Agent wird pdo_query verwenden, um die Gebühr zu finden, und dann stripe_refund mit dieser Gebührs-ID aufrufen.

$agent = $ai->agent()->withTools([new Tools\PdoQuery()]);
$answer = $agent->run('How many products in the gold-plating category?');
foreach ($agent->trace() as $step) {
echo "Step {$step['step']}: action={$step['action']}\n obs={$step['observation']}\n";
}

Nützlich für das Debuggen, die Nachverfolgung von Abläufen oder zum Erstellen einer “Zeige dein Arbeitsvorgehen”-Benutzeroberfläche.

  • PdoQuery blocks writes. Wenn Sie Schreibzugriff benötigen, erstellen Sie eine subklasse mit erhöhten Rechten und einer Überwachungsnachverfolgung. Heben Sie die SELECT-nur-Einschränkung im eingebauten Tool nicht auf.
  • HttpGet allows any URL by default. Sperren Sie es über eine Zulassungsliste in [AI] http_allowed_hosts[] (geplant) oder erstellen Sie eine RestrictedHttpGet-Subklasse, die URLs filtert.
  • FileRead blocks ... Es ist auf den Anwendungsstamm beschränkt.
  • Max iterations. agent.max_iterations = 6 in der INI verhindert unkontrollierte Schleifen. Erhöhen Sie vorsichtig.
  • Tool timeout. agent.tool_timeout = 30 (Sekunden). Ein Tool, das hängt, wird die Anfrage nicht ewig blockieren.
  • Vergessen Sie withTools(). Ohne Werkzeuge ist der Agent nur ein regulärer Chat.
  • Lassen Sie dem Agenten Geheimnisse sehen. Legen Sie niemals API-Schlüssel, rohe Passwörter oder PII in die Antwort eines Tools — das Modell erhält den vollständigen String.
  • Lange Werkzeugausgaben. Jede Beobachtung wird an die Konversation angehängt. Ein Tool, das 50 KB ausgibt, erschöpft schnell den Kontext. Die eingebaute Tools haben eine Obergrenze von 8 KB; tun Sie das gleiche in Ihren benutzerdefinierten Tools.
  • Kein Werkzeugaufruf in der Antwort = endgültige Antwort. Wenn das Modell eine endgültige Antwort produziert, die aussehen wie einen Werkzeugaufruf, aber nicht validiert wird, behandelt der Agent es als endgültig. Seien Sie explizit im Prompt: “Geben Sie einen Werkzeugaufruf ODER eine endgültige Antwort aus, niemals beides.”