Condividi tramite


Flussi di lavoro di Microsoft Agent Framework - Isolamento dello stato

Nelle applicazioni reali, la gestione corretta dello stato è fondamentale quando si gestiscono più attività o richieste. Senza un adeguato isolamento, lo stato condiviso tra diverse esecuzioni del flusso di lavoro può causare comportamenti imprevisti, corruzione dei dati e condizioni di gara. Questo articolo illustra come garantire l'isolamento dello stato all'interno dei flussi di lavoro di Microsoft Agent Framework, fornendo informazioni dettagliate sulle procedure consigliate e sui problemi comuni.

Generatori di flussi di lavoro modificabili e flussi di lavoro non modificabili

I flussi di lavoro vengono creati dai generatori di flussi di lavoro. I generatori di flussi di lavoro sono in genere considerati modificabili, in cui è possibile aggiungere, modificare l'executor di avvio o altre configurazioni dopo la creazione del generatore o anche dopo la compilazione di un flusso di lavoro. D'altra parte, i flussi di lavoro non sono modificabili in quanto una volta compilato un flusso di lavoro, non può essere modificato (nessuna API pubblica per modificare un flusso di lavoro).

Questa distinzione è importante perché influisce sul modo in cui lo stato viene gestito tra diverse esecuzioni del flusso di lavoro. Non è consigliabile riutilizzare una singola istanza del flusso di lavoro per più attività o richieste, perché ciò può causare la condivisione dello stato non intenzionale. È invece consigliabile creare una nuova istanza del flusso di lavoro utilizzando il costruttore per ogni attività o richiesta, per garantire l'isolamento dello stato e una corretta sicurezza nell'uso dei thread.

Verifica dell'isolamento dello stato nei generatori di flussi di lavoro

Quando un'istanza dell'executor viene passata direttamente a un generatore di flussi di lavoro, tale istanza dell'executor viene condivisa tra tutte le istanze del flusso di lavoro create dal generatore. Ciò può causare problemi se l'istanza dell'executor contiene lo stato che non deve essere condiviso tra più esecuzioni del flusso di lavoro. Per garantire un corretto isolamento dello stato e la sicurezza dei thread, è consigliabile utilizzare funzioni factory che creano una nuova istanza di executor per ogni istanza del flusso di lavoro.

Prossimamente...

Esempio non thread-safe:

executor_a = CustomExecutorA()
executor_b = CustomExecutorB()

workflow_builder = WorkflowBuilder()
# executor_a and executor_b are passed directly to the workflow builder
workflow_builder.add_edge(executor_a, executor_b)
workflow_builder.set_start_executor(executor_b)

# All workflow instances created from the builder will share the same executor instances
workflow_a = workflow_builder.build()
workflow_b = workflow_builder.build()

Esempio di sicurezza dei thread:

workflow_builder = WorkflowBuilder()
# Register executor factory functions with the workflow builder
workflow_builder.register_executor(factory_func=CustomExecutorA, name="executor_a")
workflow_builder.register_executor(factory_func=CustomExecutorB, name="executor_b")
# Add edges using registered factory function names
workflow_builder.add_edge("executor_a", "executor_b")
workflow_builder.set_start_executor("executor_b")

# Each workflow instance created from the builder will have its own executor instances
workflow_a = workflow_builder.build()
workflow_b = workflow_builder.build()

Suggerimento

Per garantire l'isolamento dello stato e la thread safety appropriati, assicurarsi anche che le istanze dell'executor create dalle funzioni factory non condividano lo stato modificabile.

Gestione stato agente

Il contesto dell'agente viene gestito tramite thread dell'agente. Per impostazione predefinita, ogni agente in un flusso di lavoro otterrà il proprio thread, a meno che l'agente non sia gestito da un executor personalizzato. Per altre informazioni, vedere Uso degli agenti.

I thread dell'agente vengono mantenuti tra le esecuzioni del flusso di lavoro. Ciò significa che se un agente viene richiamato nella prima esecuzione di un flusso di lavoro, il contenuto generato dall'agente sarà disponibile nelle esecuzioni successive della stessa istanza del flusso di lavoro. Sebbene ciò possa essere utile per mantenere la continuità all'interno di una singola attività, può anche causare la condivisione dello stato imprevisto se la stessa istanza del flusso di lavoro viene riutilizzata per diverse attività o richieste. Per assicurarsi che ogni attività abbia uno stato isolato dell'agente, usare le funzioni di fabbrica degli agenti nel costruttore del flusso di lavoro per creare un'istanza distinta del flusso di lavoro per ciascuna attività o richiesta.

Prossimamente...

Esempio non thread-safe:

writer_agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(
    instructions=(
        "You are an excellent content writer. You create new content and edit contents based on the feedback."
    ),
    name="writer_agent",
)
reviewer_agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(
    instructions=(
        "You are an excellent content reviewer."
        "Provide actionable feedback to the writer about the provided content."
        "Provide the feedback in the most concise manner possible."
    ),
    name="reviewer_agent",
)

builder = WorkflowBuilder()
# writer_agent and reviewer_agent are passed directly to the workflow builder
builder.add_edge(writer_agent, reviewer_agent)
builder.set_start_executor(writer_agent)

# All workflow instances created from the builder will share the same agent
# instances and agent threads
workflow = builder.build()

Esempio thread-safe:

def create_writer_agent() -> ChatAgent:
    """Factory function to create a Writer agent."""
    return AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(
        instructions=(
            "You are an excellent content writer. You create new content and edit contents based on the feedback."
        ),
        name="writer_agent",
    )

def create_reviewer_agent() -> ChatAgent:
    """Factory function to create a Reviewer agent."""
    return AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(
        instructions=(
            "You are an excellent content reviewer."
            "Provide actionable feedback to the writer about the provided content."
            "Provide the feedback in the most concise manner possible."
        ),
        name="reviewer_agent",
    )

builder = WorkflowBuilder()
# Register agent factory functions with the workflow builder
builder.register_agent(factory_func=create_writer_agent, name="writer_agent")
builder.register_agent(factory_func=create_reviewer_agent, name="reviewer_agent")
# Add edges using registered factory function names
builder.add_edge("writer_agent", "reviewer_agent")
builder.set_start_executor("writer_agent")

# Each workflow instance created from the builder will have its own agent
# instances and agent threads
workflow = builder.build()

Conclusione

L'isolamento dello stato nei flussi di lavoro di Microsoft Agent Framework può essere gestito in modo efficace usando funzioni factory con generatori di flussi di lavoro per creare nuove istanze di executor e agenti. Creando nuove istanze del flusso di lavoro per ogni attività o richiesta, è possibile mantenere l'isolamento dello stato appropriato ed evitare la condivisione dello stato imprevista tra diverse esecuzioni del flusso di lavoro.

Passaggi successivi