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
The things that bite, sorted by stage-mortification potential. Read before rehearsing.
-parametersSymptom: agent runs but @V("topic") is null — no error, just wrong output.
Cause: reflection sees arg0/arg1 without -parameters.
Fix: add the compiler arg (see tools-memory-and-build.md). Verify: javap -p YourAgent.class shows real names.
Symptom: NoSuchMethodError on ChatModel/AiMessage at first invocation; compiles fine.
Cause: langchain4j-bom:1.15.0 aligns stable modules only; a mismatched agentic/mcp beta got pulled.
Fix: pin every beta explicitly at 1.15.0-beta25; ./gradlew dependencies | grep langchain4j should show a single langchain4j-core.
Symptom: demo hangs, the same tool is called repeatedly, token bill spikes.
Cause: no maxSequentialToolsInvocations set.
Fix: always set it (.maxSequentialToolsInvocations(10)).
MissingArgumentException: Missing argument: XCauses (most→least likely): incomplete Map passed to UntypedAgent.invoke; upstream outputKey ≠ downstream @V name; -parameters missing; a @V value renamed between versions.
Fix: log scope contents before invocation; add .errorHandler(ctx -> { fill missing keys; return ErrorRecoveryResult.retry(); }).
outputName vs current outputKeySymptom: deprecation/compile issue porting older examples.
Cause: the canonical name became outputKey (and typedOutputKey for Class<?>). Older web examples use .outputName(...).
Fix: rename outputName → outputKey everywhere, including declarative @SequenceAgent(outputName=…).
Symptom: node processes survive Ctrl-C; laptop warms up after a few rehearsals.
Cause: StdioMcpTransport spawns npx; a hard Ctrl-C can skip shutdown.
Fix: always register a shutdown hook calling mcpClient.close(). Between rehearsals: pkill -f "modelcontextprotocol/server".
ChatMemory on a parallelMapperBuilder sub-agentSymptom: IllegalStateException at runtime on fan-out-over-collection.
Cause: documented limitation — mapped sub-agents are stateless.
Fix: remove .chatMemory(...); share state via AgenticScope keys.
Symptom: expected token streaming, got a buffered response. Cause: streaming is end-to-end only when the streaming agent is last; intermediate ones are buffered. Fix: put the streaming agent last, or don't promise streaming through a multi-agent flow.
Symptom: no method to add a sub-agent after .build().
Cause: sub-agents are fixed at build time (confirmed limitation).
Fix: rebuild the supervisor (cheap), or use a custom Planner consulting a dynamic registry.
Symptom: works once, 429s on "run it again."
Cause: real rate limits; prompt-cache misses after the ~5-min TTL.
Fix: keep gpt-4o-mini ready as fallback; try/catch and swap on 429; .cacheSystemMessages(true) to cut input cost within the cache window.
These are the current/official shapes — earlier blog posts and some drafts get them wrong:
AgentListener callbacks take AgentRequest / AgentResponse (+ scope/tool callbacks), and inheritedBySubagents() defaults to false. Do not assume beforeAgentInvocation(AgentInvocation) or a true default.Planner is init / firstAction / nextAction returning Action via the call(...) / done() helpers — not a single nextAction constructing new Action.DoneAction().SCORED runs a scorer agent that ranks the planner's summary vs. the last agent's output; it is not "sub-agents return scores and the highest wins."NoSuchMethodError on core types → beta agentic vs. stable core mismatch; move them together.1.10.0 there is no AgentMonitor/AgentListener (weak observability). 1.13.0-beta23+ has persistable scope.scripts/check_versions.sh whenever in doubt; pin all agentic/mcp artifacts to the same beta.