Μετάβαση στο περιεχόμενο

Neuron Μνήμη + μηχανή καταστάσεων ελέγχου

Αυτό το μοτίβο είναι χρήσιμο όταν ένας agent πρέπει να διατηρεί το ιστορικό συνομιλίας σε επαναλαμβανόμενους γύρους ανθρώπινου ελέγχου, ενώ τον συνολικό κύκλο ζωής εξακολουθεί να συντονίζει το Queuety.

Το Queuety διαχειρίζεται τη μηχανή καταστάσεων ελέγχου, ενώ το Neuron διαχειρίζεται τη μνήμη του agent για το νήμα σύνταξης.

Γιατί βοηθά εδώ η μνήμη Neuron

Αν ένας αξιολογητής απορρίψει ένα προσχέδιο και ζητήσει αλλαγές, η επόμενη κλήση του agent δεν θα πρέπει να χρειάζεται να ανασυνθέσει όλο το περιβάλλον από την αρχή.

Το Neuron του SQLChatHistory ταιριάζει σε αυτήν την περίπτωση, επειδή ο agent μπορεί να συνεχίσει στο ίδιο νήμα συνομιλίας, ενώ το Queuety δρομολογεί τις αποφάσεις του αξιολογητή και τους γύρους αναθεώρησης.

Ο agent Neuron με ιστορικό που βασίζεται στο SQL

PHP
namespace App\Neuron;

use NeuronAI\Agent\Agent;
use NeuronAI\Chat\History\ChatHistoryInterface;
use NeuronAI\Chat\History\SQLChatHistory;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;
use NeuronAI\SystemPrompt;

final class EditorAgent extends Agent
{
    public function __construct(
        private readonly string $threadId,
        private readonly \PDO $pdo,
    ) {}

    protected function provider(): AIProviderInterface
    {
        return new Anthropic(
            key: $_ENV['ANTHROPIC_API_KEY'],
            model: $_ENV['ANTHROPIC_MODEL'],
        );
    }

    protected function chatHistory(): ChatHistoryInterface
    {
        return new SQLChatHistory(
            thread_id: $this->threadId,
            pdo: $this->pdo,
            table: 'neuron_chat_history',
            contextWindow: 50000,
        );
    }

    public function instructions(): string
    {
        return (string) new SystemPrompt(
            background: [
                'You are an editorial agent for long-form product briefs.',
                'Apply reviewer notes without losing the original intent.',
            ],
        );
    }
}

Συντάξτε μία φορά και αναθεωρήστε διατηρώντας το ίδιο νήμα μνήμης

PHP
namespace App\StateMachines\Actions;

use App\Neuron\EditorAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Contracts\StateAction;

final class DraftBriefAction implements StateAction
{
    public function handle(array $state, ?string $event = null, array $event_payload = [], array $payload = []): array|string
    {
        // Queuety creates actions with `new DraftBriefAction()`, so build dependencies here.
        $pdo = new \PDO($_ENV['NEURON_DB_DSN'], $_ENV['NEURON_DB_USER'], $_ENV['NEURON_DB_PASSWORD']);

        $threadId = $state['neuron_thread_id'] ?? sprintf(
            'brief:%d:editor',
            $state['brief_id'],
        );

        $prompt = "Write the first draft for brief {$state['brief_id']}.";

        if ('reject' === $event) {
            $prompt = sprintf(
                'Revise the draft using these review notes: %s',
                $event_payload['reason'] ?? 'Tighten the draft and address reviewer concerns.',
            );
        }

        $agent = new EditorAgent($threadId, $pdo);
        $message = $agent->chat(
            new UserMessage($prompt)
        )->getMessage();

        return [
            'neuron_thread_id' => $threadId,
            'draft_markdown' => $message->getContent(),
            'review_round' => (int) ($state['review_round'] ?? 0) + 1,
            '_event' => 'draft_ready',
        ];
    }
}

Η μηχανή καταστάσεων Queuety

PHP
use Queuety\Enums\StateMachineStatus;
use Queuety\Queuety;

$machine_id = Queuety::machine('brief_review_session')
    ->version('brief-review-session.v1')
    ->state('drafting')
    ->action(DraftBriefAction::class)
    ->on('draft_ready', 'awaiting_review')
    ->state('awaiting_review')
    ->on('approve', 'completed')
    ->on('reject', 'drafting')
    ->state('completed', StateMachineStatus::Completed)
    ->dispatch([
        'brief_id' => 42,
    ]);

// Later, once the draft action has finished and the machine waits in `awaiting_review`:
Queuety::machine_event(
    $machine_id,
    'reject',
    [ 'reason' => 'Tighten the introduction and add pricing context.' ]
);

Queuety::machine_event(
    $machine_id,
    'approve',
    [ 'reviewer' => 'editor@example.com' ]
);

Το πρώτο πέρασμα εισέρχεται στο drafting, εκτελεί την ενέργεια που βρίσκεται στην ουρά και μεταβαίνει στο awaiting_review.

Αν ο αξιολογητής απορρίψει το προσχέδιο, η μηχανή επιστρέφει στο drafting. Καθώς το ωφέλιμο φορτίο του συμβάντος reject περνά στο DraftBriefAction, το επόμενο προσχέδιο μπορεί να αξιοποιήσει τις σημειώσεις του αξιολογητή χωρίς να χάσει το αρχικό ιστορικό νήματος Neuron.

Γιατί αυτό είναι πιο καθαρό από την επανάληψη μιας ροής εργασιών

Αυτό το πρόβλημα αφορά τον κύκλο ζωής. Ένα προσχέδιο περιμένει ανθρώπινο έλεγχο, ο αξιολογητής μπορεί να το εγκρίνει ή να το απορρίψει, η απόρριψη επαναφέρει τη συνεδρία στη σύνταξη και η έγκριση ολοκληρώνει τη συνεδρία. Αυτό αντιστοιχεί πιο άμεσα σε μια μηχανή καταστάσεων παρά σε μια γραμμική ροή εργασιών με βρόχο επιστροφής.

Η κατάσταση της ροής εργασιών εξακολουθεί να είναι ιδανική για στοιχεία συντονισμού, όπως ο αριθμός γύρων ελέγχου, τα αναγνωριστικά τεχνουργημάτων και ροών εργασιών, καθώς και οι αποφάσεις δρομολόγησης. Η μνήμη Neuron είναι καταλληλότερη για το ιστορικό συνομιλίας, όπως προηγούμενες προτροπές, επαναληπτικές αναθεωρήσεις και απαντήσεις μοντέλου που πρέπει να παραμείνουν μέρος του νήματος σύνταξης.

Με τη χρήση και των δύο, κάθε σύστημα αναλαμβάνει την εργασία για την οποία είναι καταλληλότερο.

Πότε να διατηρήσετε τη ροή ως ροή εργασιών

Προτιμήστε μια ροή εργασιών όταν η διαδικασία ελέγχου έχει σαφή όρια και εστιάζει στην εκτέλεση, για παράδειγμα:

Δημιουργήστε ένα προσχέδιο, περιμένετε μία έγκριση και δημοσιεύστε το.

Προτιμήστε μια μηχανή καταστάσεων όταν η συνεδρία ενδέχεται να επισκεφθεί τις ίδιες καταστάσεις αρκετές φορές και εξωτερικά συμβάντα καθορίζουν τον κύκλο ζωής.