A team is running three specialized agents concurrently: one that triages GitHub issues, one that assigns labels, and one that drafts responses. All three agents read from and write to a shared state store containing the current issue queue. Two of the agents occasionally make conflicting updates to the same issue record simultaneously. Which approach best prevents conflicting and stale context in this shared state architecture?
Select an answer to reveal the explanation.
Short Explanation
Shared state between concurrent agents is like three people editing the same shared spreadsheet without change tracking—someone's work gets overwritten without either of them knowing. You need optimistic locking with version tokens so a write only succeeds if it still matches the version the agent read; otherwise it gets a conflict and must re-read before retrying.
Full Explanation
Concurrent agent systems that share a mutable state store are vulnerable to two related problems: conflicting writes, where two agents update the same record simultaneously and one overwrites the other's changes, and stale reads, where an agent acts on data that has already been changed by another agent. Both problems produce incorrect or inconsistent behavior.
The full-state reload approach is incorrect. Reloading the full shared state before every operation would create enormous read amplification; three agents each reloading the entire issue queue before every action would flood the state store with unnecessary reads. More importantly, this does not actually prevent conflicts: two agents could both load the state at the same moment, compute their respective updates, and then both write, with the second write silently overwriting the first.
The single sequential agent approach is incorrect. Merging three specialized agents into a single sequential agent eliminates the concurrency problem by removing concurrency entirely. While this would prevent conflicts, it sacrifices the performance and specialization benefits of a multi-agent design. It is an architectural regression, not a solution. For genuinely concurrent workloads, sequential execution is often unacceptably slow.
The message-queue polling approach is incorrect. The 60-second polling interval introduces significant stale context risk. An agent that reads issue state and then waits up to 60 seconds before acting on it could be operating on severely outdated information. While a message queue for serializing writes has merit, the polling interval described would make the system unacceptably laggy and stale.
The optimistic locking approach is correct. Optimistic locking is the standard pattern for preventing conflicting writes in concurrent systems without the overhead of pessimistic locks. Each record carries a version token. Agents read a record and note its version. When writing, they include the version they read; the store only commits the write if the version still matches the current version. If another agent wrote first, the version will have incremented, the conflict is detected, and the second agent must re-read and recompute before retrying. This is lightweight, scalable, and safe.