There are many architectures for agentic systems, and Verified Multi-Agent Orchestration (VMAO) is one of them: an architecture that makes it possible to turn a natural-language request into a strict sequential execution plan. The system first decides what is worth investigating, splits the work into branches, executes independent parts in parallel, assembles the picture, and checks whether there is enough confidence for the final answer. If the picture is weak, the next loop receives the context of the previous attempt.
In this demo, the same flow is shown through an incident investigation scenario. A user comes with a symptom: checkout-service has an increase in 5xx responses, along with a time window, a possible dependency, and a suspicion of degradation. The harness first chooses the traces worth checking: metrics, logs, traces, deployment, config. From this, the work graph is formed.
A plain text list of steps does not always map well onto a runtime: it is hard to see which parts can run at the same time and which must run sequentially. A graph gives a stricter contract. Some branches start immediately, others wait for results. Data flows explicitly: metric results can go into period comparison, log results into signature detection, and terminal branches converge into a shared analysis.
The demo scope is intentionally compressed. Synthetic data gives a repeatable scenario, and local agents remove integration noise. The mechanics themselves remain the main focus: the model proposes a plan, the runtime checks its shape, the graph executes independent branches, and the result passes through a quality gate. A production version would add real data sources, sandboxing, access controls, observability, and stronger verification. LangGraph4j was used to implement the graph: a Java clone of LangGraph that allows building graphs with asynchronous nodes and conditional transitions.
An important aspect is budget pressure at every level of execution. The system does not treat the reasoning loop as an unlimited resource: the overall budget spans planning, graph execution, sub-agent calls, verification, and replanning. Planning consumes model usage, execution limits the number of agent calls and wall-clock time, parallel branches compete for the same shared budget, and a new cycle is allowed only if enough resources remain for a useful refinement. In this way, orchestration continuously monitors how much additional work it can still afford.
The outer graph shows the whole cycle well:
return new StateGraph<>(Lg4jRunState.SCHEMA, Lg4jRunState::new)
.addNode("plan", node_async(state -> planNode.plan(state, budget)))
.addNode("validate", node_async(validateNode::validate))
.addNode("execute", node_async(state -> executionNode.execute(state, budget)))
.addNode("build_report", node_async(reportNode::build))
.addNode("verify", node_async(verificationNode::verify))
.addNode("decide_replan", node_async(state -> replanDecisionNode.decide(state, budget)))
.addNode("finish", node_async(finishNode::finish))
.addEdge(START, "plan")
.addEdge("plan", "validate")
.addEdge("validate", "execute")
.addEdge("execute", "build_report")
.addEdge("build_report", "verify")
.addEdge("verify", "decide_replan")
.addConditionalEdges("decide_replan",
edge_async(state -> state.needsReplan() ? "replan" : "finish"),
Map.of("replan", "plan", "finish", "finish"))
.addEdge("finish", END);
The plan graph is executed using the classic Kahn’s algorithm together with lightweight virtual threads. Each node maintains a counter of unfinished dependencies. Nodes with no dependencies are immediately added to the ready queue. The executor starts as many tasks from this queue as allowed by maxConcurrency. Whenever a node completes, its result is added to the shared execution state, and the dependency counters of its downstream nodes are decremented. If a dependent node’s counter reaches zero, that node becomes ready to run.
var nodesById = Lg4jPlanDag.nodesById(plan);
var dependents = dependents(plan);
var remainingDeps = remainingDeps(plan);
var ready = readyNodes(plan, remainingDeps);
while (!ready.isEmpty() || running > 0) {
while (running < maxConcurrency && !ready.isEmpty()) {
var node = ready.remove();
var state = execution.state();
completions.submit(() -> new NodeUpdate(
node.getId(),
executeNode(budget, agentInvocationExecutor, node, state)));
running++;
}
var completed = take(completions);
running--;
execution.apply(completed.update());
for (var dependentId : dependents.getOrDefault(completed.nodeId(), List.of())) {
if (remainingDeps.merge(dependentId, -1, Integer::sum) == 0) {
ready.add(nodesById.get(dependentId));
}
}
}
execution.apply(analyzeEvidence(plan, budget, agentInvocationExecutor, execution.state()));
The scheduler handles fan-out and fan-in naturally: a completed node can unblock several downstream nodes, while a node with multiple dependencies waits for all of them. Independent branches run in parallel, limited by the max concurrency setting. Final evidence analysis starts only after all nodes have finished.
Result verification in the demo is intentionally simplified. In a real system, its depth would be much greater: for example, it would include analysis of intermediate results, contradiction checks, and so on. The architecture already has a dedicated place for it. If verification passes, the report is formed. If the report is weak, the new attempt receives the context of the previous one, and the next plan is built with that experience.
Ultimately, this is simply an attempt to show a VMAO-style process:
- planning
- validation
- parallel execution of multiple sub-agents
- evaluation and formation of either the result or a new signal
The value of the demo, in my view, is that this flow is visible without extra noise.
Repository: https://github.com/lbobylev/harness-demo
Inspired by: VERIFIED MULTI-AGENT ORCHESTRATION: A PLAN-
EXECUTE-VERIFY-REPLAN FRAMEWORK FOR COM-
PLEX QUERY RESOLUTION

Top comments (4)
Interesting use case, I’m wondering if with langgraph4j usage we can achieve same result in more robuste and reproducible way
btw, I really love what you are doing with LangGraph4j
@bsorrentino dev.to/lbobylev/building-an-agenti... fyi
@bsorrentino With LangGraph, it is undoubtedly easier to implement a state machine.
It also provides support for parallel execution of graph branches. This is an illustration of the approach for a team that is learning Spring AI — an attempt to implement similar functionality using the tools currently available in the framework. It is not intended to be an optimal solution for production development. The goal is only to demonstrate some of the patterns and underlying mechanics.