Neuron Strömningssteg
Det här exemplet visar en tydlig uppdelning. Neuron strömmar agentsvaret del för del, medan Queuety sparar varje del beständigt genom StreamingStep. Det innebär att UI kan få ett utkast i realtid samtidigt som arbetsflödet överlever krascher eller omförsök av arbetare.
När det här mönstret är användbart
Använd det när ett utkast eller svar är så långt att du vill strömma det i realtid, när du vill behålla delvis utdata om arbetaren kraschar och när den slutliga artefakten fortfarande ska hamna i arbetsflödestillståndet efter att strömningen är klar.
Neuron-agenten
namespace App\Neuron;
use NeuronAI\Agent\Agent;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\OpenAI\Responses\OpenAIResponses;
use NeuronAI\SystemPrompt;
final class DraftMemoAgent extends Agent
{
protected function provider(): AIProviderInterface
{
return new OpenAIResponses(
key: $_ENV['OPENAI_API_KEY'],
model: $_ENV['OPENAI_MODEL'],
);
}
public function instructions(): string
{
return (string) new SystemPrompt(
background: [
'You write crisp internal strategy memos.',
'Prefer short sections and operationally useful language.',
],
);
}
}
Queuety-strömningssteget
namespace App\Workflow\Steps;
use App\Neuron\DraftMemoAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Contracts\StreamingStep;
use Queuety\Heartbeat;
final class StreamMemoDraftStep implements StreamingStep
{
public function stream(array $state, array $existing_chunks = []): \Generator
{
if (! empty($existing_chunks)) {
return;
}
$handler = (new DraftMemoAgent())->stream(
new UserMessage(sprintf(
"Write a strategy memo about %s for account %d.",
$state['topic'],
$state['account_id'],
))
);
foreach ($handler->events() as $i => $chunk) {
Heartbeat::beat(['chunks' => $i + 1]);
// This example assumes the agent has no tools attached, so
// Neuron will stream text/reasoning chunks only.
yield $chunk->content;
}
}
public function on_complete(array $chunks, array $state): array
{
return [
'draft_markdown' => implode('', $chunks),
];
}
public function config(): array
{
return [
'max_attempts' => 3,
];
}
}
Använd det i ett arbetsflöde
use Queuety\Queuety;
Queuety::workflow('memo_drafting')
->then(BuildDraftBriefStep::class)
->then(StreamMemoDraftStep::class)
->then(StoreMemoStep::class)
->dispatch([
'account_id' => 10,
'topic' => 'pricing changes for enterprise accounts',
]);
Varför använda Queuety i stället för enbart strömadaptrarna för Neuron
Neurons strömadaptrar är användbara för frontend-protokoll och transportlager. Queuety tillför något annat: varje genererad del sparas, omförsök kan fortsätta med de tidigare sparade delarna, det färdiga utkastet förs tillbaka till arbetsflödestillståndet och strömningen blir ett beständigt steg i en större orkestrering.
Det gör det här mönstret lämpligt när strömningen ingår i en flerstegsprocess för verksamheten, inte bara i en begäran/svar-UI.
En sak att tänka på
Om din Neuron-agent använder verktyg under strömningen ska du hantera strömmens delar uttryckligen. Neurons aktuella dokumentation om strömning beskriver TextChunk, ReasoningChunk, ToolCallChunk och ToolResultChunk. För ett bakgrundsarbetsflöde för textutkast är det oftast enklast att låta agenten bara strömma text.