Paso de transmisión Neuron
Este ejemplo muestra una separación clara. Neuron transmite la respuesta del agente fragmento a fragmento, mientras que Queuety conserva cada fragmento de forma duradera mediante StreamingStep. Así, UI puede recibir un borrador en directo mientras el flujo de trabajo sigue resistiendo fallos o reintentos del proceso de trabajo.
Cuándo resulta útil este patrón
Úsalo cuando un borrador o una respuesta sea lo bastante largo como para querer transmitirlo en directo, cuando no quieras perder la salida parcial si el proceso de trabajo se detiene y cuando el artefacto final deba guardarse en el estado del flujo de trabajo al terminar la transmisión.
El agente Neuron
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.',
],
);
}
}
El paso de transmisión Queuety
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,
];
}
}
Úsalo en un flujo de trabajo
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',
]);
Por qué usar Queuety en lugar de adaptadores de transmisión Neuron por sí solos
Los adaptadores de transmisión de Neuron son útiles para protocolos y transportes de la interfaz. Queuety aporta algo distinto: se guarda cada fragmento emitido, los reintentos pueden reanudarse con los fragmentos guardados previamente, el borrador completo se incorpora al estado del flujo de trabajo y la transmisión se convierte en un paso duradero dentro de una orquestación más amplia.
Este patrón resulta adecuado cuando la transmisión forma parte de un proceso empresarial de varios pasos, no solo de una UI de solicitud y respuesta.
Una salvedad
Si tu agente Neuron usa herramientas mientras transmite, gestiona explícitamente los tipos de fragmento transmitidos. La documentación actual de transmisión de Neuron describe TextChunk, ReasoningChunk, ToolCallChunk y ToolResultChunk. Para un flujo de redacción en segundo plano, lo más sencillo suele ser limitar el agente de transmisión a texto.