Engineering · · 4 min read
Two agents finished their parts. Why did one result disappear?
Separate parallel computation from shared writes, and choose merge rules that preserve every required result.
Two agents research different parts of an account. Both finish, but the final brief includes only the second result because both wrote to the same findings field. More parallel workers speed the task up until someone redoes the missing content.
A LangGraph supervisor discussion asks whether agents can work in parallel. The engineering question is which state they can change independently and how the parent combines it.
Identify shared writes before parallelizing#
Map each child task's outputs. If both children write the same scalar field, the system needs a conflict rule; if each produces an independent artifact, the parent validates and assembles references.
LangGraph's Graph API documentation describes state reducers and parallel graph execution. A reducer defines how updates combine and does not decide whether the combined business result is correct: appending two contradictory conclusions keeps both strings and leaves the contradiction.
Give independent work separate child outputs. In an account brief, support research produces support findings, billing research produces billing findings, and the parent owns the final summary and any customer-facing write.
Work through a lost result#
In a state object with summary, sources, and status, where the support and billing children each write a summary and source list, last-write-wins loses one child's work. An append merge keeps the text but duplicates source entries and produces two incompatible status values.
Give each child a stable task identifier and a result schema: source references, findings, unresolved questions, and completion state. Store results under child identities and let a parent step decide what belongs in the final brief.
The parent does not infer child completion from a nonempty result, because a child can save partial findings before failing. Keep progress and terminal completion distinct, so a half-finished search never becomes a completed section.
| Shared value | Better ownership pattern |
|---|---|
| Independent findings | Separate result per child |
| Unique source references | Deduplicate by stable source identity |
| Final recommendation | One parent decision after review |
| External customer update | One authorized writer |
| Task completion state | Parent derives it from required child states |
Protect the external object too#
Separate graph state does not stop two agents from updating the same ticket or document: if both read version seven and write different changes, one erases the other's update.
Use the target system's version precondition or compare-and-set when it has one. Otherwise assign one writer per object and let other agents submit proposed changes. Independent reads and unrelated writes continue.
On a version conflict, fetch the current object and compare intended changes instead of blindly retrying the old object. A field-level update can merge, and two different owner assignments need a decision.
The sub-agent identity guide addresses delegated authority. State ownership is separate: an agent with legitimate access can still overwrite another legitimate agent's work.
Make retries safe for the merge#
A child can finish, lose its acknowledgement, and deliver the same result again; an append-only reducer without identity checks duplicates it. Keep a stable child result identity and define whether a later delivery replaces, duplicates, or conflicts with the earlier one.
If the child revises its answer, use a result version, since the revision is not another independent finding. Keep the prior version as history and mark the current one for the parent.
Test out-of-order completion, duplicate delivery, a child failure after partial output, and a conflicting external update. The final artifact contains each required contribution once, with unresolved conflicts visible.
Keep the useful speedup#
Parallel work pays off when children progress independently, so do not serialize the whole workflow for one single-owner field. Split the shared mutation from the research, run independent reads together, and join the results deterministically.
The parent then consumes stable child outputs and never guesses which update won a race. Put output ownership and merge rules in the application contract, and use action evidence to inspect the resulting calls. The action lifecycle separates accepted work from completed results. Save the lost-result fixture so each added agent adds throughput.