Back
advanced

Deploying agent systems

Common agent orchestration patterns

Compare sequential, parallel, routed, and review workflows while preserving clear contracts, budgets, and partial-failure behavior.

Lesson 60 of 67About 26 min with practice

Two searches can run independently, but the answer depends on their combined evidence. What should happen if one fails? Choose orchestration around those dependencies and preserve partial failure at the join.

Before you begin: Understand agents, tool results, shared state, and task budgets.

Orchestration is the control of who runs next, what state they receive, and what counts as completion. It can be ordinary application code, a workflow graph, or a framework's team abstraction. The useful pattern follows the task's dependencies.

Start with the dependency graph

Sequential work is appropriate when one result is needed by the next step. A writer cannot ground an answer in evidence that has not been retrieved. Parallel work helps when independent searches can proceed at the same time. Routing selects one path based on the request. Review loops revisit a result after a concrete check fails.

These patterns can be combined, but every added path creates more states to handle. Start with a direct implementation and add dynamic choices only where fixed control flow cannot express the task.

PatternA useful workshop example
SequentialRetrieve records, filter eligibility, explain results.
ParallelSearch two independent permitted collections.
RoutedSend a structured date question to a deterministic parser.
Review loopRevise a draft after a missing-citation check fails.

Which completed work is still useful after the question changes?

An orchestration plan should expose the dependencies between work products. A source extraction may remain valid when the final question changes, while a question-specific interpretation may need to run again. Keeping these stages separate can avoid expensive repeated work without reusing stale conclusions.

In the challenge, identify which worker outputs depend on source revision and which depend on the current question. Give reusable artifacts explicit identities and provenance. This turns caching and routing into reasoned decisions about dependencies rather than blanket reuse of every earlier result.

Example

Workers extract facts from five unchanged documents.

What changes

The final question changes from “what changed?” to “who is affected?”

Result

Source extraction may be reusable; question-specific analysis must be reconsidered.

Reuse depends on the inputs that determine each artifact, including source versions and task meaning.

Give every stage an output contract

A retriever returns source records and status. A filter returns eligible IDs and unresolved cases. A writer returns claims with citations. A validator returns specific failures.

Do not use “sounds finished” as a contract. Separate complete, partial, and failed results. Preserve unknown values so a later stage cannot silently turn them into confirmed facts.

The following Python 3 program illustrates a join after two independent workers. It uses only the standard library and performs no model calls.

python
# Runnable: Python 3, standard library.
results = [
    {"worker": "public", "status": "complete", "ids": ["pottery"]},
    {"worker": "members", "status": "failed", "ids": []},
]
evidence = sorted({item for result in results for item in result["ids"]})
missing = [result["worker"] for result in results if result["status"] != "complete"]
assert evidence == ["pottery"]
assert missing == ["members"]
print({"evidence": evidence, "incomplete_sources": missing})

The join preserves a failed branch instead of presenting the available record as an exhaustive search. A real application decides whether partial evidence is sufficient for the user's question.

Change the question, keep the worker results

The local join has a public result and a failed member-record search. For “Name one public workshop,” the available result may be sufficient. For “List every workshop I can attend,” the same evidence may be incomplete. Completion is relative to the user's required coverage.

Where should that decision live?

The coordinator evaluates the task contract against the collected statuses and evidence. Workers should report their own scope and outcome honestly; the writer should not infer exhaustive coverage from a nonempty list. Keep missing sources visible when producing a partial answer.

Add a late successful result from the failed branch after the coordinator has already returned. Decide whether the task can update, remains final, or requires a new attempt. Versioned artifacts and explicit final states make this behavior understandable instead of letting a background worker overwrite a completed answer silently.

Assign ownership of shared state

Let independent workers produce separate artifacts. Have one coordinator combine them using an explicit rule. Concurrently rewriting a single plan or answer can lose updates and hide disagreements.

An artifact should include its source, task ID, revision, and relevant scope. If two workers find conflicting workshop times, the coordinator applies the source-version rule or reports the conflict. It should not average the times or vote on them.

Give external side effects one owner. If both a coordinator and a worker can reserve the same seat, retries and recovery become harder to reason about.

Bound the whole workflow

A maximum of three review rounds is useful only if nested calls are also bounded. Share deadlines and usage budgets across workers. Cancel work that is no longer needed, and decide how to handle results arriving after cancellation.

Retries should match the failure. A temporary lookup outage may justify another attempt. Missing permission does not justify routing to an agent with broader access. A critic that repeats “needs improvement” without identifying a concrete defect should not cause an endless revision loop.

Practice choosing a pattern

The task compares public workshop schedules from two locations, then writes one answer. One location's service is unavailable. What should happen?

Compare your design

Run the two lookups independently, collect their statuses, and preserve the unavailable location as a gap. If the user needs a complete comparison, say that it is incomplete. If a partial answer is useful, label its coverage. Do not claim that the available location has the only suitable workshops.

Evaluate the orchestrated system against a simpler baseline using task success, evidence support, elapsed time, total usage, and recovery behavior. A more elaborate graph is useful only when it earns those costs.

The LangGraph workflows and agents guide and AutoGen team documentation describe concrete implementations of these patterns.

Practice with feedback

Lesson challenge

Change the question, keep the worker results

Five workers each summarise a document. The final question changes from "what changed this month" to "who is affected". All five re-run.

Start from the dependency graph and give every stage an output contract.

Check your understanding

Question 1 of 3
Why did they all re-run?
Score: 0/0

Your task

Redesign the pipeline so a changed question reuses the worker stage.

These notes stay on this page. Download them before leaving.

What to include

  • Worker output is independent of the final question
  • The cache key is content-based, not question-based
  • The re-run analysis names exactly which stage repeats
  • There is one owner for any shared structure
Compare with a worked answer

Here is one way to answer. Check how it uses the information in the task.

Dependency graph: 5 documents -> extract (parallel, one per document) -> merge -> answer. Only the last stage sees the question.

Stage contracts worker (extract): input is one document version. Output is a question- independent structured record: {doc_id, doc_version, changes: [{what, who, effective_date, quote, offsets}], entities: [...]}. It never sees the question, which is what makes it reusable. reducer (answer): input is the merged records plus the question. Output is {answer, claim_ids}. Cheap, one call.

What is cached, and on what key: each worker's output, keyed on sha256(doc_id + doc_version + extractor_prompt_sha + model_id). Content-based, so an unchanged document is never re-extracted, and a prompt change correctly invalidates everything. When the question changes: only the reducer re-runs. That is one call instead of six, about 0.9s instead of 14s. When a document changes, only that one worker re-runs and then the reducer.

Shared state and its single owner: the merged record set is built by the orchestrator alone. Workers return values and write nothing. Earlier we had workers appending to a shared list, and the output ordering varied between runs, which made the whole thing unreproducible and took an afternoon to diagnose. Whole-workflow bound: 60 seconds and 20 model calls total, with per-stage timeouts of 15s. On breach the workflow returns the records it did complete plus a list of documents not covered, rather than a confident answer over a partial set.

When you are signed in, opening the challenge carries your edited working notes into its draft in this browser. The challenge has its own completion record. Practising here does not award points or mark it complete.

, where tool contracts cross a service boundary.

Practise this lesson

Change the question, keep the worker results

Start from the dependency graph and give every stage an output contract.

About 12 min75 points3 checks and one applied task
Loading your lesson progress...