网页
综合
更新时间 2026-11-13 17:23:16
Parallel voting and adaptive model selection: smarter agentic AI on a budget - Quarkus
自动蜘蛛
quarkus.io
正文约 5999 字
Blog Parallel voting and adaptive model selection: smarter agentic AI on a budget
In a previous article we discussed why no single agentic pattern can cover all use cases, and introduced a generic Planner abstraction that allows users to define their own orchestration strategies and combine them with the ones provided by LangChain4j out-of-the-box. For instance, there we demonstrated how a goal-oriented pattern could be extended with a reflection loop to iteratively refine a piece of generated content.
Among other things, that example highlighted that having an agent evaluate its own output and loop until it reaches a quality threshold is a powerful technique. But this fundamental pattern also comes with a limitation: relying on a single evaluator can make the system fragile or less reliable. To overcome this issue, what if, instead of one judge, we could assemble a panel?
The voting pattern, introduced in LangChain4j 1.15.0, addresses this by dispatching the same input to multiple evaluator agents in parallel, collecting their individual assessments, and then aggregating them into a single consolidated result. This is not a simple majority vote on a boolean decision: the aggregation strategy is fully customizable, allowing the system to combine structured results in whatever way makes sense for the task at hand.
To put this into practice, let’s build a story evaluation system, also using the quarkus-langchain4j-agentic extension version 1.10.0. The pipeline works as follows: a creative writer generates a short story on a given topic, and then a panel of three critics, each specialized in a different aspect, evaluates the story in parallel. Their scores and suggestions are aggregated into a single critique, which is fed back to an editor agent that rewrites the story. This review loop repeats until the aggregated score crosses a quality threshold or a maximum number of iterations is reached. We will implement this example leveraging the fully declarative style made available by the quarkus-langchain4j extension.
First, let’s define the basic data types and the individual agents. Each agent is a simple Java interface with a single method having an @Agent annotation describing its role and an @UserMessage containing its prompt. In particular the @Agent annotation’s outputKey attribute specifies the key under which the agent’s output will be stored in the AgenticScope, making it available for other agents to use.
All these agents return a common CritiqueResult record to represent scores and suggestions, while the final output of the system is a ScoredStory that combines the story with its aggregated critique.
The creative writer generates a short story from a topic:
The three critics evaluate different aspects of the story: style, originality, and engagement. They all follow the same structure, differing only in their prompt:
The OriginalityCritic and EngagementCritic are analogous, each focusing on their respective dimension and producing their own CritiqueResult with outputKey values of "originalityCritique" and "engagementCritique".
Finally, the story editor rewrites the story based on the aggregated critique:
The key component that makes this pattern work is the VotingPlanner. It implements the Planner interface and orchestrates the parallel execution of all critic subagents, then aggregates their results using a configurable VotingStrategy.
The planner’s logic is straightforward: on the first action it dispatches all subagents at once in parallel by returning call(subagents). As each critic completes, nextAction is called: it collects the result and returns noOp() until all critics have finished, at which point it aggregates the votes and returns done(result).
The VotingStrategy is a functional interface that takes the collection of all critic outputs and reduces them to a single result:
For our story evaluation use case, the aggregation strategy averages the scores and concatenates the suggestions from all critics:
The LangChain4j API makes it easy to wire these agents into a coherent agentic system. First of all, we can configure the three critic agents as subagents of the voting agentic pattern, using the critiquesAggregator defined above to combine their results:
Then we can put the resulting votingCritics planner together with the story editor into a review loop that iteratively refines the story until it reaches a certain quality threshold:
Finally, we can chain the CreativeWriter agent, that generates the initial story, with the review loop in a sequence, and define an output method to assemble the final ScoredStory result:
The resulting system composes three different agentic patterns, a sequence, a loop, and a custom voting planner, into a single pipeline that can be injected at any point in your Quarkus application.
and then can be called with one line:
Making the StoryEvaluator interface extend the MonitoredAgent interface allows us to visualize both the system topology and the execution history of a sample run, using the new LangChain4j view available in the Quarkus Dev-UI. The LangChain4j monitoring dashboard automatically detects the nested structure of the agentic system, showing how the different patterns are composed together.
Giving a look at the topology of this agentic system clearly shows how the three patterns are nested: at the top, a sequential planner first invokes the CreativeWriter and then enters the review loop. Inside the loop, the VotingPlanner fans out to the three critics in parallel, collects and aggregates their results, and then the StoryEditor rewrites the story. The loop continues until the average score reaches 8.5 or five iterations have been completed.
We can try to put this agentic system at work, for instance asking it to generare a story on the topic of "a lonely robot finding friendship" and see how it iteratively refines the story based on the critics' feedback, finally producing a result like this:
The execution history of this sample run
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。