Build and demo Java AI agent systems with langchain4j-agentic: workflow patterns, supervisor, custom Planner strategies (incl. the flagship typed-verdict / CriticResult-style critic pattern), plus MCP tools, A2A remote agents, build setup, and conference-demo storylines. Pinned to 1.15.0 / 1.15.0-beta25.
84
89%
Does it follow best practices?
Impact
100%
4.76xAverage score across 2 eval scenarios
Passed
No known issues
Apply these when writing code with the langchain4j-agentic module.
scripts/check_versions.sh): core 1.15.0 (GA), langchain4j-agentic / -agentic-a2a / -agentic-patterns / -mcp 1.15.0-beta25.langchain4j-bom aligns stable modules only — it does not manage the beta agentic/mcp artifacts. Pin each beta independently; mixing a transitive beta with BOM-managed core causes NoSuchMethodError at runtime.langchain4j-agentic-patterns, not the core agentic module.-parameters (Gradle options.compilerArgs.add("-parameters") / Maven <parameters>true</parameters>). Without it, @V("name") binds null silently — no error, wrong output..maxSequentialToolsInvocations(int) is mandatory on any tool-using agent (default 10) to prevent runaway tool loops.@Tool/@P from langchain4j-core; there is no agentic-specific tool annotation. Use .tools(...) for static tools, .toolProviders(...) for dynamic/MCP tools.mcpClient.close() when using stdio MCP transport.CriticResult — your own type, generic or concrete) over a stringly-typed score so branch decisions are compile-checked.@Agent a meaningful description — it is what the supervisor and pure-agentic planners read to decide when to use the agent.@Agent(name=...), the builder .name(...), or the method name by default). Names must be unique within an agentic system.-parameters so @V can be omitted, or annotate every argument with @V("..."). Do not rely on parameter names without -parameters.outputKey of one agent and the @V argument names of the next must match exactly. A typo silently produces a MissingArgumentException at runtime.outputKey across agents (e.g. "story") is the idiomatic way to refine a value through a chain — but it overwrites. Use distinct keys when you need both values later.TypedKey + @K over string keys to get compile-time safety and avoid casts when reading state.parallelMapper sub-agents must not use ChatMemory (the framework throws if they do), since the same agent runs repeatedly on different items.maxIterations to bound a loopBuilder. Combine with an exitCondition.exitCondition is checked after every sub-agent invocation to minimize calls. Use testExitAtLoopEnd(true) only when all sub-agents must run each iteration.Executor for parallelBuilder/parallelMapperBuilder in production rather than relying on the default cached thread pool.async(true) agents run off the calling thread; the scope blocks on their result only when a later agent needs it. AgentListener callbacks run on the invocation thread — keep them non-blocking.TokenStream only streams to the caller when it is the last agent invoked; otherwise it behaves asynchronously and is fully consumed before the next agent runs.errorHandler returning ErrorRecoveryResult.retry() / .result(...) / .throwException() to recover from missing arguments or tool/agent failures instead of letting the whole system fail.AgentMonitor (or extend MonitoredAgent) and generate an HTML report with HtmlReportGenerator to inspect the invocation tree, timings, and token usage.responseStrategy deliberately: LAST (default) returns the last agent's output, SUMMARY returns the planner's summary, SCORED lets a scorer agent pick. Use supervisorContext to inject policies/constraints.