<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: bsorrentino</title>
    <description>The latest articles on Forem by bsorrentino (@bsorrentino).</description>
    <link>https://forem.com/bsorrentino</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53518%2Ff0ff1ba7-a659-49a7-92e4-4fac9e829916.png</url>
      <title>Forem: bsorrentino</title>
      <link>https://forem.com/bsorrentino</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bsorrentino"/>
    <language>en</language>
    <item>
      <title>Skill-Based Sub-Agents with LangGraph4j and Spring AI</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Mon, 04 May 2026 20:27:26 +0000</pubDate>
      <link>https://forem.com/bsorrentino/skill-based-sub-agents-with-langgraph4j-and-spring-ai-52b0</link>
      <guid>https://forem.com/bsorrentino/skill-based-sub-agents-with-langgraph4j-and-spring-ai-52b0</guid>
      <description>&lt;h2&gt;
  
  
  Combine Tools &amp;amp; Skill to create Agent
&lt;/h2&gt;

&lt;p&gt;Modern agentic systems usually expose two strong but separate abstractions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;, which give an LLM executable capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills&lt;/strong&gt;, which package reusable instructions for a narrow task&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article shows how to combine both ideas in &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; so that a skill is not just prompt text, but a fully operational &lt;strong&gt;sub-agent exposed as a tool&lt;/strong&gt;. The result is a practical pattern for building modular multi-agent systems in Java with &lt;strong&gt;&lt;a href="https://spring.io/projects/spring-ai" rel="noopener noreferrer"&gt;Spring AI&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt;&lt;/strong&gt;, while keeping each agent focused, reusable, and low in context cost.&lt;/p&gt;

&lt;p&gt;Starting from a standard ReACT agent, the approach implemented is quite simple.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load a &lt;code&gt;SKILL.md&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Read its front matter to define the tool contract ( name and argument description)&lt;/li&gt;
&lt;li&gt;Use the skill body as the sub-agent system prompt&lt;/li&gt;
&lt;li&gt;Restrict the sub-agent to only the tools declared by the skill&lt;/li&gt;
&lt;li&gt;Register the sub-agent in a parent ReAct agent as if it were a normal tool&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words, a skill becomes an &lt;em&gt;executable tool-backed agent&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Pattern Matters
&lt;/h2&gt;

&lt;p&gt;The standard ReAct pattern already gives an LLM a strong execution model: reason, choose a tool, inspect the result, and continue until the task is complete. That model is useful because the LLM does not need to commit to a fixed plan up front. It can adapt after every tool call.&lt;/p&gt;

&lt;p&gt;The next step is to let a tool itself be implemented by another agent.&lt;/p&gt;

&lt;p&gt;Once that happens, the parent agent is no longer forced to know every operational detail. It only needs to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which specialized capability exists&lt;/li&gt;
&lt;li&gt;when to invoke it&lt;/li&gt;
&lt;li&gt;what input to pass&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The specialized logic is delegated to a narrower agent with its own instructions and its own restricted toolset. This gives us a clean &lt;strong&gt;sub-agent architecture&lt;/strong&gt; without inventing a new orchestration primitive. We reuse the same tool-calling semantics that ReAct agents already understand well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Reusing Tool Semantics Is Powerful
&lt;/h2&gt;

&lt;p&gt;One of the most valuable properties of LLM-based agents is their ability to build and revise a tool execution plan while reasoning over intermediate results. ReAct made this practical by combining thought, action, and observation in a loop.&lt;/p&gt;

&lt;p&gt;When a tool call can transparently invoke another agent, we preserve that planning model instead of replacing it.&lt;/p&gt;

&lt;p&gt;The parent agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;decide that a specialized capability is needed&lt;/li&gt;
&lt;li&gt;provide only the task-relevant context&lt;/li&gt;
&lt;li&gt;wait for a result exactly as it would for a standard tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The child agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run its own reasoning loop&lt;/li&gt;
&lt;li&gt;invoke its own allowed tools&lt;/li&gt;
&lt;li&gt;return a compact outcome to the parent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives hierarchical coordination without exposing the full inner workflow to the parent prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimizing Context and Token Usage
&lt;/h2&gt;

&lt;p&gt;This pattern also improves context discipline.&lt;/p&gt;

&lt;p&gt;Without sub-agents, a single generalist agent often needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every tool definition&lt;/li&gt;
&lt;li&gt;all operating instructions for every domain&lt;/li&gt;
&lt;li&gt;every procedural rule in one large system prompt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That quickly becomes expensive and unreliable.&lt;/p&gt;

&lt;p&gt;With skill-based sub-agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the parent only sees high-level capabilities&lt;/li&gt;
&lt;li&gt;each child sees only the instructions relevant to its task&lt;/li&gt;
&lt;li&gt;each child receives only the tools it is allowed to use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This narrower context has practical benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer tokens sent to the model&lt;/li&gt;
&lt;li&gt;lower prompt interference between unrelated domains&lt;/li&gt;
&lt;li&gt;clearer tool choice&lt;/li&gt;
&lt;li&gt;better modularity as the system grows&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;allowed-tools&lt;/code&gt; skill property plays an important role here anabling tool filtering. It turns tool access into an explicit design decision instead of an accidental side effect of what happened to be registered globally.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reference implementation
&lt;/h2&gt;

&lt;p&gt;I've started implementation in the new &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; release stream &lt;code&gt;1.9&lt;/code&gt; currently in active development. The implementation is centered on [&lt;code&gt;SkilledReactSubAgent&lt;/code&gt;], which turns a markdown skill into both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a compiled LangGraph4j sub-graph&lt;/li&gt;
&lt;li&gt;a Spring AI tool (i.e. &lt;code&gt;ToolCallback&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means the same component can participate in the graph as an agent and present itself to the parent LLM as a callable tool.&lt;/p&gt;

&lt;p&gt;In particular the flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse the &lt;code&gt;SKILL.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Extract &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; from front matter&lt;/li&gt;
&lt;li&gt;Optionally filter tools using &lt;code&gt;allowed-tools&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use the markdown body as the sub-agent instructions&lt;/li&gt;
&lt;li&gt;Compile the agent&lt;/li&gt;
&lt;li&gt;Wrap it into a function tool whose input is a single &lt;code&gt;context&lt;/code&gt; field&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The important design choice is that the &lt;strong&gt;tool definition is derived from the skill metadata&lt;/strong&gt;, while the &lt;strong&gt;agent behavior is derived from the skill content&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Skill Format
&lt;/h3&gt;

&lt;p&gt;The supported skill format is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;agent name&amp;gt;&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|"&lt;/span&gt;
        &lt;span class="s"&gt;&amp;lt;multi line description&amp;gt;&lt;/span&gt;
&lt;span class="na"&gt;allowed-tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;list of tools&amp;gt;&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;skill&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  From Skill to Tool-Backed Agent
&lt;/h3&gt;

&lt;p&gt;The conversion happens in &lt;code&gt;SkilledReactSubAgent.Builder#build(...)&lt;/code&gt;. This is the crucial bridge where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the skill metadata defines the external API&lt;/li&gt;
&lt;li&gt;the skill body defines the internal operating behavior&lt;/li&gt;
&lt;li&gt;the allowed tools define the sub-agent execution boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting agent is then wrapped as a Spring AI function tool.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;From the parent agent point of view, this is just another tool. Internally, it is a complete ReAct-capable agent workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Purchase Assistant Agent
&lt;/h3&gt;

&lt;p&gt;This is an agent that allow to select a produdct from a reference marketplace and purchase it. Below the simplified component diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeiutlwe940j65rwdvyp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeiutlwe940j65rwdvyp.png" alt="diagram" width="778" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Marketplace Skill
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-marketplace&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;marketplace agent, ask for information about products. This is agent that provides the information on the product marketplace.&lt;/span&gt;
    &lt;span class="s"&gt;required data are:&lt;/span&gt;
    &lt;span class="s"&gt;* product name&lt;/span&gt;
&lt;span class="na"&gt;allowed-tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;searchByProduct&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## Retrieve product information&lt;/span&gt;
We need all information about about the product of interest in particular is mandatory to have
&lt;span class="p"&gt;*&lt;/span&gt; product name

with such information we have to invoke tool &lt;span class="sb"&gt;`searchByProduct`&lt;/span&gt; and return the result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Payment Skill
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent-payment&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;payment agent, this is the agent that provides payment service.&lt;/span&gt;
    &lt;span class="s"&gt;required data are:&lt;/span&gt;
    &lt;span class="s"&gt;* Product name&lt;/span&gt;
    &lt;span class="s"&gt;* Product price&lt;/span&gt;
    &lt;span class="s"&gt;* Product currency&lt;/span&gt;
    &lt;span class="s"&gt;* the International Bank Account Number (IBAN) - optional&lt;/span&gt;

&lt;span class="na"&gt;allowed-tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;submit-payment&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;retrieve-iban&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## submit a payment for purchasing a specific product&lt;/span&gt;
We need all information about purchasing to allow the payment
&lt;span class="p"&gt;
*&lt;/span&gt; Product name
&lt;span class="p"&gt;*&lt;/span&gt; Product price
&lt;span class="p"&gt;*&lt;/span&gt; Product price currency
&lt;span class="p"&gt;*&lt;/span&gt; International Bank Account Number (IBAN)

With such information you must invoke tool &lt;span class="sb"&gt;`submit-payment`&lt;/span&gt; and return the result of the payment transaction plus the IBAN.
If IBAN is not provided invoke tool &lt;span class="sb"&gt;`retrieve-iban`&lt;/span&gt; to retrieve the required IBAN.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observing the skills above they define three different concerns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: the tool name exposed to the parent agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt;: the tool description shown to the model&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allowed-tools&lt;/code&gt;: the only tools available inside the sub-agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything after the front matter becomes the sub-agent system prompt.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Again, this is a strong separation of concerns. The parent agent sees a concise tool contract, while the child agent receives richer operating instructions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Finally the code
&lt;/h2&gt;

&lt;p&gt;Below a representative code snippet that show how wires two skill-based sub-agents into a parent agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;subAgentMarketplace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SkilledReactSubAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Marketplace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compileConfig&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;SkillSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Paths&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"skills/agent-marketplace/"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;subAgentPayment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SkilledReactSubAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Payment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compileConfig&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;SkillSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Paths&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"skills/agent-payment/"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;purchaseAssistantAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentExecutorEx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subAgentMarketplace&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subAgentPayment&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compileConfig&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""
        search for product 'X'.
        If found proceed to payment with IBAN US82WEST1234567890123456 
        to purchase it
        """&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;purchaseAssistantAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; 
        &lt;span class="nc"&gt;GraphInput&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"messages"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;runnableConfig&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This composition is interesting because the purchase agent (the parent) does not need detailed knowledge of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how product lookup works&lt;/li&gt;
&lt;li&gt;how payment submission works&lt;/li&gt;
&lt;li&gt;when IBAN retrieval is required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those rules are delegated to the sub agents themselves.&lt;/p&gt;

&lt;p&gt;That is a simple but good example of behavioral encapsulation. The parent agent only decides to involve marketplace agent to retrieve product and after that to involve payment agent to purchase.&lt;/p&gt;

&lt;p&gt;This is a very basic but representative example, it is useful because it shows the intended layering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user gives a single business request&lt;/li&gt;
&lt;li&gt;the parent agent decomposes the work&lt;/li&gt;
&lt;li&gt;specialized sub-agents execute their own logic&lt;/li&gt;
&lt;li&gt;the final answer comes back through the normal tool-response path&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Interesting note that each sub agent, potentially, can relies on different LLM chat model so we can further optimize overall agent execution process&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below a more detailed componet diagram generated by &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7u6han2x5t14pgasky3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7u6han2x5t14pgasky3.png" alt="diagram" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this diagram it is quite clear that the sub agents are nothing but sub-graphs&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Advantages
&lt;/h2&gt;

&lt;p&gt;This approach has several practical advantages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reuse Existing Agent Patterns&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is no need to invent a separate orchestration protocol for sub-agents. A sub-agent is exposed as a tool, so the parent agent can use standard ReAct behavior without extra prompting complexity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Better Modularity&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each skill owns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;its tool-facing identity&lt;/li&gt;
&lt;li&gt;its internal instructions&lt;/li&gt;
&lt;li&gt;its allowed tool boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes the system easier to evolve than a single monolithic agent prompt.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Smaller and Cleaner Context&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The child agent receives only what it needs. This reduces token usage and lowers the risk that unrelated instructions distort tool choice or task execution.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Safer Capability Scoping&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By filtering tools from &lt;code&gt;allowed-tools&lt;/code&gt;, the framework prevents a child agent from accidentally seeing tools outside its intended domain.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Better Reusability&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A skill can be packaged, versioned, and reused across different parent agents. The same marketplace or payment skill can participate in many workflows as long as the tool contract remains stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tradeoffs and Implementation Considerations
&lt;/h2&gt;

&lt;p&gt;This pattern is strong, but it is not free of tradeoffs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The Parent Must Summarize Well&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because the child receives a single &lt;code&gt;context&lt;/code&gt; field, the parent agent needs to pass the relevant facts clearly. If critical information is omitted, the child may need extra recovery steps or may fail to act.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Tool Descriptions Matter More&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since the parent sees the child as a tool, the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; fields in the skill front matter become part of the routing surface for the LLM. Weak metadata will reduce invocation quality.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prompt Boundaries Need Discipline&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The skill body is effectively the child system prompt. If it is vague, contradictory, or overloaded, the benefits of modularity disappear. Skills need to stay focused.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Observability Is Important&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nested agents can make execution harder to inspect if tracing is weak. LangGraph4j's graph structure and step streaming help here, but production systems should still invest in logging and traceability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why LangGraph4j Fits This Well
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; is a good fit for this pattern because it already models agent workflows as explicit graphs and integrates naturally with Spring AI tool abstractions.&lt;/p&gt;

&lt;p&gt;That matters for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the sub-agent is not just prompt composition; it is a compiled graph with state and execution hooks&lt;/li&gt;
&lt;li&gt;the parent integration remains ergonomic because Spring AI already treats capabilities as tools&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; support interruptions in subgraph enabling &lt;strong&gt;Human In The Loop&lt;/strong&gt; also when involving sub agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the implementation is not forcing two incompatible ideas together. It is aligning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LangGraph4j graph execution&lt;/li&gt;
&lt;li&gt;Spring AI tool calling&lt;/li&gt;
&lt;li&gt;markdown-defined skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;into a single reusable agent-building pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Turning a skill into a sub-agent is a small change with a large impact.&lt;/p&gt;

&lt;p&gt;It lets us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;preserve the strengths of the ReAct loop&lt;/li&gt;
&lt;li&gt;delegate specialized behavior cleanly&lt;/li&gt;
&lt;li&gt;reduce context size&lt;/li&gt;
&lt;li&gt;constrain tool access per domain&lt;/li&gt;
&lt;li&gt;build multi-agent systems out of reusable skill modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea is implemented in a compact and pragmatic way: a &lt;code&gt;SKILL.md&lt;/code&gt; file becomes the source of both the sub-agent prompt and the tool contract exposed to the parent agent.&lt;/p&gt;

&lt;p&gt;For Java teams building agentic applications with Spring AI and LangGraph4j, this is a practical pattern for moving from a single large agent toward a modular multi-agent design without abandoning the tool semantics that current LLMs already handle well.&lt;/p&gt;

&lt;p&gt;The implementation is in progress on release &lt;code&gt;1.9-SNAPSHOT&lt;/code&gt; in develop branch of &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; repository but the first result are very promising.&lt;/p&gt;

&lt;p&gt;Hope this could help and encourage usage of &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; for your next Agentic Workflow. Checkout project, try it and let me know your feedback and... happy AI coding! 👋&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://bsorrentino.github.io/bsorrentino/ai/2026/04/28/LangGraph4j-SubAgent.html" rel="noopener noreferrer"&gt;https://bsorrentino.github.io&lt;/a&gt; on April 28, 2026.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agentskills</category>
      <category>langgraph4j</category>
      <category>springai</category>
    </item>
    <item>
      <title>Interesting reading for who are approaching use AI for developing at scale</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Mon, 30 Mar 2026 07:48:38 +0000</pubDate>
      <link>https://forem.com/bsorrentino/interesting-reading-for-who-are-approaching-use-ai-for-developing-at-scale-2okf</link>
      <guid>https://forem.com/bsorrentino/interesting-reading-for-who-are-approaching-use-ai-for-developing-at-scale-2okf</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/incomplete_developer/spec-driven-development-return-of-best-practices-44b0" class="crayons-story__hidden-navigation-link"&gt;Spec-Driven Development: Return of Best Practices&lt;/a&gt;
    &lt;div class="crayons-article__cover crayons-article__cover__image__feed"&gt;
      &lt;iframe src="https://www.youtube.com/embed/SYNSj-nwZyo" title="Spec-Driven Development: Return of Best Practices"&gt;&lt;/iframe&gt;
    &lt;/div&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/incomplete_developer" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1237870%2Fd4f4f10a-3000-409a-8c61-f712e1bb5b87.png" alt="incomplete_developer profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/incomplete_developer" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Incomplete Developer
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Incomplete Developer
                
              
              &lt;div id="story-author-preview-content-3409072" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/incomplete_developer" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1237870%2Fd4f4f10a-3000-409a-8c61-f712e1bb5b87.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Incomplete Developer&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/incomplete_developer/spec-driven-development-return-of-best-practices-44b0" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 26&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/incomplete_developer/spec-driven-development-return-of-best-practices-44b0" id="article-link-3409072"&gt;
          Spec-Driven Development: Return of Best Practices
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/specdrivendevelopment"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;specdrivendevelopment&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/vibecoding"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;vibecoding&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/incomplete_developer/spec-driven-development-return-of-best-practices-44b0" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/incomplete_developer/spec-driven-development-return-of-best-practices-44b0#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>specdrivendevelopment</category>
      <category>vibecoding</category>
      <category>ai</category>
    </item>
    <item>
      <title>Agent Definition Language (ADL): The Open Source Standard for Defining AI Agents 👀. Looks promising

https://www.nextmoca.com/blogs/agent-definition-language-adl-the-open-source-standard-for-defining-ai-agents</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Tue, 10 Feb 2026 09:28:44 +0000</pubDate>
      <link>https://forem.com/bsorrentino/agent-definition-language-adl-the-open-source-standard-for-defining-ai-agents-looks-ibd</link>
      <guid>https://forem.com/bsorrentino/agent-definition-language-adl-the-open-source-standard-for-defining-ai-agents-looks-ibd</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.nextmoca.com/blogs/agent-definition-language-adl-the-open-source-standard-for-defining-ai-agents" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fstatic1.squarespace.com%2Fstatic%2F68793d703bfc192900e52897%2Ft%2F69367d5c303f115f30ef293d%2F1765178760762%2FChatGPT%2BImage%2BDec%2B7%252C%2B2025%2Bat%2B10_59_56%2BPM.png%3Fformat%3D1500w" height="506" class="m-0" width="760"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.nextmoca.com/blogs/agent-definition-language-adl-the-open-source-standard-for-defining-ai-agents" rel="noopener noreferrer" class="c-link"&gt;
            Agent Definition Language (ADL): The Open Source Standard for Defining AI Agents — Next Moca 
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            GitHub Repository:     https://github.com/nextmoca/adl
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.squarespace-cdn.com%2Fcontent%2Fv1%2F68793d703bfc192900e52897%2F3868b990-79f4-4dc0-b01c-f46e74d833a2%2Ffavicon.ico%3Fformat%3D100w" width="100" height="100"&gt;
          nextmoca.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Observability matter</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Fri, 06 Feb 2026 17:47:43 +0000</pubDate>
      <link>https://forem.com/bsorrentino/observability-matter-24m3</link>
      <guid>https://forem.com/bsorrentino/observability-matter-24m3</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk" class="crayons-story__hidden-navigation-link"&gt;LangGraph4j Hooks and OpenTelemetry&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/bsorrentino" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53518%2Ff0ff1ba7-a659-49a7-92e4-4fac9e829916.png" alt="bsorrentino profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/bsorrentino" class="crayons-story__secondary fw-medium m:hidden"&gt;
              bsorrentino
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                bsorrentino
                
              
              &lt;div id="story-author-preview-content-3237947" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/bsorrentino" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53518%2Ff0ff1ba7-a659-49a7-92e4-4fac9e829916.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;bsorrentino&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 6&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk" id="article-link-3237947"&gt;
          LangGraph4j Hooks and OpenTelemetry
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/langgraph4j"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;langgraph4j&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/observability"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;observability&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opentelemetry"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opentelemetry&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>langgraph4j</category>
      <category>agents</category>
      <category>observability</category>
      <category>opentelemetry</category>
    </item>
    <item>
      <title>LangGraph4j Hooks and OpenTelemetry</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Fri, 06 Feb 2026 17:44:50 +0000</pubDate>
      <link>https://forem.com/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk</link>
      <guid>https://forem.com/bsorrentino/langgraph4j-hooks-and-opentelemetry-1egk</guid>
      <description>&lt;h2&gt;
  
  
  Why Observability Matters
&lt;/h2&gt;

&lt;p&gt;Agentic workflows are dynamic: nodes may run conditionally, in parallel, or be skipped entirely. When something fails, a simple stack trace is rarely enough. &lt;strong&gt;Observability&lt;/strong&gt; gives you a unified view of &lt;strong&gt;what&lt;/strong&gt; happened, &lt;strong&gt;where&lt;/strong&gt; it happened, and &lt;strong&gt;why&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In practice, observability helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand end-to-end execution flow.&lt;/li&gt;
&lt;li&gt;Detect performance bottlenecks early.&lt;/li&gt;
&lt;li&gt;Correlate errors with specific nodes, edges, and state transitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Telemetry Matters
&lt;/h2&gt;

&lt;p&gt;Observability is only possible if you collect high‑quality telemetry. Telemetry is the raw signal: &lt;strong&gt;traces&lt;/strong&gt;, &lt;strong&gt;logs&lt;/strong&gt;, and &lt;strong&gt;metrics&lt;/strong&gt;. Without it, probably,  you are debugging your system partially.&lt;/p&gt;

&lt;p&gt;In agent graphs, telemetry becomes even more important because state and control flow are distributed across steps. The same workflow can behave differently depending on state, configuration, or external tool results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The LangGraph4j hooks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://langgraph4j.github.io/langgraph4j/core/hooks/" rel="noopener noreferrer"&gt;LangGraph4j hooks&lt;/a&gt; are small, composable interceptors that sit around &lt;strong&gt;nodes&lt;/strong&gt; and &lt;strong&gt;conditional edges&lt;/strong&gt;. They let you run custom logic &lt;strong&gt;before&lt;/strong&gt;, &lt;strong&gt;after&lt;/strong&gt;, or &lt;strong&gt;wrapping&lt;/strong&gt; the core action, without modifying the node itself. &lt;br&gt;
Hooks can be registered globally (applies to all nodes/edges) or by ID (targeted to a specific node/edge), and their execution order is &lt;strong&gt;LIFO&lt;/strong&gt;(Last In First Out) for &lt;code&gt;BeforeCall&lt;/code&gt;/&lt;code&gt;AfterCall&lt;/code&gt;, &lt;strong&gt;FIFO&lt;/strong&gt;(First In First Out) for &lt;code&gt;WrapCall&lt;/code&gt;. &lt;br&gt;
This makes them a precise, low‑friction mechanism for cross‑cutting concerns like tracing, metrics, logging, or state inspection.&lt;/p&gt;
&lt;h2&gt;
  
  
  How Hooks Enable Observability
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://langgraph4j.github.io/langgraph4j/core/hooks/" rel="noopener noreferrer"&gt;Hooks&lt;/a&gt; provide lifecycle interception points around node and edge execution. This is the ideal place to add logging, metrics, or traces without contaminating business logic.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; you can intercept execution &lt;strong&gt;before&lt;/strong&gt;, &lt;strong&gt;after&lt;/strong&gt;, or &lt;strong&gt;around&lt;/strong&gt; node/edge calls. Here is a minimal example that measures node execution time and logs it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;MyState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SCHEMA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serializer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addWrapCallNodeHook&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;nodeId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// add Wrap call node hook&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;whenComplete&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentTimeMillis&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"node '{}' took {}ms"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nodeId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;});&lt;/span&gt;
    &lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addNode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"node1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action1&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addNode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"node2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action2&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;....&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern scales: you can plug in structured logs, metrics counters, or spans with the same hook mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenTelemetry in the Java Ecosystem
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://opentelemetry.io/docs/what-is-opentelemetry/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt; is the standard for observability across modern platforms. In Java it provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tracing&lt;/strong&gt; via spans&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt; via meters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs&lt;/strong&gt; via instrumentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You configure it once and export telemetry to a backend like &lt;strong&gt;&lt;a href="https://www.jaegertracing.io" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;Grafana&lt;/strong&gt;, or the &lt;strong&gt;OpenTelemetry Collector&lt;/strong&gt;. The key benefit here is &lt;strong&gt;portability&lt;/strong&gt;: you are not locked to a single vendor.&lt;/p&gt;

&lt;h2&gt;
  
  
  How LangGraph4j Hooks Enable OpenTelemetry
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; includes a dedicated module, &lt;code&gt;langgraph4j-opentelemetry&lt;/code&gt;, that provides hook implementations ready for tracing node and edge execution. Consider it as a reference implementation about &lt;strong&gt;how to integrate OpenTelemetry in LangGraph4j&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The module includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;OTELWrapCallTraceHook&lt;/code&gt;: creates spans for each node and edge call, adding config/state attributes and start/end events.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OTELWrapCallTraceSetParentHook&lt;/code&gt;: creates a parent span so node/edge spans are grouped inside a workflow scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A minimal integration looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;otelHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OTELWrapCallTraceHook&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;serializer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parentHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OTELWrapCallTraceSetParentHook&lt;/span&gt;&lt;span class="o"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MyWorkflow"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;groupName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stream"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;MyState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SCHEMA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serializer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addWrapCallNodeHook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;otelHook&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addWrapCallEdgeHook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;otelHook&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addWrapCallNodeHook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parentHook&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addWrapCallEdgeHook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parentHook&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addNode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"node1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action1&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addNode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"node2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action2&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addContitionalEdges&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"node2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edgeAction&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
            &lt;span class="nc"&gt;EdgeMappings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"node1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toEnd&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;        
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps node logic clean while producing rich, correlated traces for the entire workflow.&lt;/p&gt;

&lt;p&gt;Below an example of output in &lt;a href="https://www.jaegertracing.io" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt; tracing platform&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi3989g7rpnk6794wb5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi3989g7rpnk6794wb5d.png" alt="jaeger" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hooks are the foundation for observability in &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt;: they give you structured interception points without affect your main workflow code. OpenTelemetry builds on top of this by standardizing how telemetry is collected and exported in the Java ecosystem.&lt;br&gt;
Combined, they deliver production-grade visibility for complex agent workflows.&lt;br&gt;
Checkout project, try it and let me know your feedback and ... happy AI coding! 👋&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/what-is-opentelemetry/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://bsorrentino.github.io/bsorrentino/ai/2026/02/04/LangGraph4j-Hooks-and-OpenTelemertry.html" rel="noopener noreferrer"&gt;https://bsorrentino.github.io&lt;/a&gt; on February 4, 2026&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>langgraph4j</category>
      <category>agents</category>
      <category>observability</category>
      <category>opentelemetry</category>
    </item>
    <item>
      <title>I read this in a post: "AI agents are 5% models and 95% engineering glue." I completely agree, but I feel like it's not so clear among software engineers.
This helps us to understand that we need to focus on adding value around models.</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Sat, 31 Jan 2026 08:55:24 +0000</pubDate>
      <link>https://forem.com/bsorrentino/i-read-this-in-a-post-ai-agents-are-5-models-and-95-engineering-glue-i-completely-agree-but-23nl</link>
      <guid>https://forem.com/bsorrentino/i-read-this-in-a-post-ai-agents-are-5-models-and-95-engineering-glue-i-completely-agree-but-23nl</guid>
      <description></description>
      <category>ai</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Top GitHub Users By Public Contributions in Italy 

https://github.com/gayanvoice/top-github-users/blob/main/markdown/public_contributions/italy.md 

I'm at 26th place 👨‍💻 🚀😉</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Fri, 23 Jan 2026 15:04:34 +0000</pubDate>
      <link>https://forem.com/bsorrentino/top-github-users-by-public-contributions-in-italy-1o1i</link>
      <guid>https://forem.com/bsorrentino/top-github-users-by-public-contributions-in-italy-1o1i</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://github.com/gayanvoice/top-github-users/blob/main/markdown/public_contributions/italy.md" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frepository-images.githubusercontent.com%2F373383893%2F3812a400-d11b-11eb-8238-bd579de69457" height="640" class="m-0" width="1280"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://github.com/gayanvoice/top-github-users/blob/main/markdown/public_contributions/italy.md" rel="noopener noreferrer" class="c-link"&gt;
            top-github-users/markdown/public_contributions/italy.md at main · gayanvoice/top-github-users · GitHub
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Check your ranking in GitHub! Don't forget to star ⭐ this repository. - gayanvoice/top-github-users
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Ffavicons%2Ffavicon.svg" width="32" height="32"&gt;
          github.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>[Top GitHub Users By Public Contributions in Italy]
(https://github.com/gayanvoice/top-github-users/blob/main/markdown/public_contributions/italy.md)

I'm at 26th place 👨‍💻 🚀😉</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Fri, 23 Jan 2026 14:58:26 +0000</pubDate>
      <link>https://forem.com/bsorrentino/top-github-users-by-public-contributions-in-italy-1jp</link>
      <guid>https://forem.com/bsorrentino/top-github-users-by-public-contributions-in-italy-1jp</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://github.com/gayanvoice/top-github-users/blob/main/markdown/public_contributions/italy.md" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frepository-images.githubusercontent.com%2F373383893%2F3812a400-d11b-11eb-8238-bd579de69457" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://github.com/gayanvoice/top-github-users/blob/main/markdown/public_contributions/italy.md" rel="noopener noreferrer" class="c-link"&gt;
            top-github-users/markdown/public_contributions/italy.md at main · gayanvoice/top-github-users · GitHub
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Check your ranking in GitHub! Don't forget to star ⭐ this repository. - gayanvoice/top-github-users
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Ffavicons%2Ffavicon.svg"&gt;
          github.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




</description>
      <category>community</category>
      <category>github</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Exploring Javelit, the Java counterpart to Streamlit, for rapid prototyping and AI agents using LangGraph4j.</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Sat, 20 Dec 2025 20:42:38 +0000</pubDate>
      <link>https://forem.com/bsorrentino/exploring-javelit-the-java-counterpart-to-streamlit-for-rapid-prototyping-and-ai-agents-using-5gmi</link>
      <guid>https://forem.com/bsorrentino/exploring-javelit-the-java-counterpart-to-streamlit-for-rapid-prototyping-and-ai-agents-using-5gmi</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/bsorrentino/experimenting-with-javelit-the-streamlit-for-java-bll" class="crayons-story__hidden-navigation-link"&gt;Experimenting with Javelit - The Streamlit for Java&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/bsorrentino" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53518%2Ff0ff1ba7-a659-49a7-92e4-4fac9e829916.png" alt="bsorrentino profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/bsorrentino" class="crayons-story__secondary fw-medium m:hidden"&gt;
              bsorrentino
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                bsorrentino
                
              
              &lt;div id="story-author-preview-content-3117821" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/bsorrentino" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53518%2Ff0ff1ba7-a659-49a7-92e4-4fac9e829916.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;bsorrentino&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/bsorrentino/experimenting-with-javelit-the-streamlit-for-java-bll" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 20 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/bsorrentino/experimenting-with-javelit-the-streamlit-for-java-bll" id="article-link-3117821"&gt;
          Experimenting with Javelit - The Streamlit for Java
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ui"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ui&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ux"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ux&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javelit"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javelit&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/bsorrentino/experimenting-with-javelit-the-streamlit-for-java-bll#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>java</category>
      <category>ui</category>
      <category>ux</category>
      <category>javelit</category>
    </item>
    <item>
      <title>Experimenting with Javelit - The Streamlit for Java</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Sat, 20 Dec 2025 20:41:56 +0000</pubDate>
      <link>https://forem.com/bsorrentino/experimenting-with-javelit-the-streamlit-for-java-bll</link>
      <guid>https://forem.com/bsorrentino/experimenting-with-javelit-the-streamlit-for-java-bll</guid>
      <description>&lt;h2&gt;
  
  
  Starting from Python development ecosystem
&lt;/h2&gt;

&lt;p&gt;At the beginning of my journey with agentic applications, I started with the Python programming language, leveraging &lt;a href="https://docs.langchain.com/oss/python/langchain/overview" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt;/&lt;a href="https://docs.langchain.com/oss/python/langgraph/overview" rel="noopener noreferrer"&gt;LangGraph&lt;/a&gt;. For testing and documentation, I relied on the simple yet powerful &lt;a href="https://jupyter.org" rel="noopener noreferrer"&gt;Jupyter Notebooks&lt;/a&gt;. Simultaneously, for rapid prototyping, I adopted the amazing &lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt; framework, which empowered me to quickly develop functional applications with an effective UI and excellent UX. &lt;/p&gt;

&lt;h2&gt;
  
  
  Moving from Python ecosystem to the Java one
&lt;/h2&gt;

&lt;p&gt;When I started developing &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt;, I tried to replicate my Python development ecosystem in Java. So I've experimented with the Java Notebooks through the &lt;a href="https://github.com/padreati/rapaio-jupyter-kernel" rel="noopener noreferrer"&gt;rapaio-jupyter-kernel&lt;/a&gt; project, which allowed me to replicate the development experience I had with &lt;a href="https://jupyter.org" rel="noopener noreferrer"&gt;Jupyter Notebooks&lt;/a&gt; in Python quite well. For rapid prototyping, I relied almost entirely on &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt; framework, which is a fairly fast and enjoyable programming experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Javelit come to play 🚀
&lt;/h2&gt;

&lt;p&gt;Going on my efforts on &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; and continuously monitoring the most interesting and promising Java projects on GitHub, I discovered &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt;. This project intrigued me because of its reference to &lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt;, and after a review, I was amazed to realize that the dynamic programming model popularized by &lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt; had been adapted for Java by this initiative, which is cool.😎&lt;br&gt;
So I started to evaluate it as part of may java development ecosystem and below i'll share with you my experience about it.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Javelit 👀
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; is a tool to quickly build interactive app frontends in Java, particularly for data apps, but it’s not limited to them. It helps you quickly develop rapid prototypes, with a live-reload loop, so that you can quickly experiment and update the app instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Javelit’s architecture allows you to write apps the same way you write plain Java methods. Any time something must be updated on the screen, Javelit reruns your entire Java main method from top to bottom.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you have to think about it &lt;strong&gt;as if your entire UI code runs inside a continuous loop&lt;/strong&gt; that refreshes whenever something needs updating on the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; provides developers with a rich set of prebuilt &lt;a href="https://docs.javelit.io/develop/api-reference" rel="noopener noreferrer"&gt;components&lt;/a&gt; that make it easy to get started. &lt;/p&gt;

&lt;p&gt;Just to provide you an idea of the &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; approach below the inevitable "&lt;em&gt;Hello World&lt;/em&gt;" code snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// usr/bin/env jbang "$0" "$@" ; exit $?&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.javelit.core.Jt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;markdown&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
            ## My first official message
            Hello World!
            """&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, once &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; is &lt;a href="https://docs.javelit.io/get-started/installation/standalone#install-javelit" rel="noopener noreferrer"&gt;installed&lt;/a&gt;, you’d run it with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javelit run App.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use Javelit with LangGraph4j
&lt;/h2&gt;

&lt;p&gt;I've decided to use &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; to develop some examples of &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; usage and below, I show you how have used &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; to implement a demo app to run the &lt;strong&gt;LangGraph4j powered React Agent&lt;/strong&gt;. &lt;br&gt;
For simplicity I've reported only the meaningful code snippets, but for a complete code take a look to &lt;a href="https://github.com/langgraph4j/langgraph4j/blob/main/spring-ai/spring-ai-agent/src/test/java/JtAgentExecutorApp.java" rel="noopener noreferrer"&gt;&lt;code&gt;JtAgentExecutorApp.java&lt;/code&gt;&lt;/a&gt; for &lt;a href="https://spring.io/projects/spring-ai#overview" rel="noopener noreferrer"&gt;spring AI&lt;/a&gt; based implementation. &lt;/p&gt;

&lt;p&gt;As &lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt; in &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; entire application consist in just one &lt;code&gt;main()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JtAgentExecutorApp&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LangGraph4J React Agent"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// create a LangGraph4j Agent&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentExecutor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* instantiate the preferred ChatModel */&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toolsFromObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyTools&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="cm"&gt;/* Custom Tools */&lt;/span&gt;  &lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 

            &lt;span class="c1"&gt;// input: the user message&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;textArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user message:"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user message"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;labelVisibility&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JtComponent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LabelVisibility&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HIDDEN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// button: start agent processing &lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;button&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"start agent"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isBlank&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// if button pressed&lt;/span&gt;

                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;outputComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;expander&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Workflow Steps"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GraphInput&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"messages"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userMessage&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

                &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

                &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                    &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sessionState&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"streaming"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
                            #### %s
                            %s
                            """&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formatted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
                            &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Object:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;joining&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n\n"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
                    &lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputComponent&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;

                &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;elapsedTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;between&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startTime&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

                &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"finished in %ds%n"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formatted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elapsedTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toSeconds&lt;/span&gt;&lt;span class="o"&gt;())).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Jt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of the &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; app looks like: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chat model selection view&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0eje5auie6ujogfw56t7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0eje5auie6ujogfw56t7.png" alt="Chat model selection view" width="800" height="726"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Start agent view&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9bbp83jkrwr35vjqh9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9bbp83jkrwr35vjqh9a.png" alt="Start agent view" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Results view&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vz18hyzxbhxbdw74irx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vz18hyzxbhxbdw74irx.png" alt="Results view" width="800" height="799"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  👉 try yourself 👀 🚀 🤯
&lt;/h3&gt;

&lt;p&gt;If you want try yourself (after installed &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;javelit&lt;/a&gt;) run the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javelit run https://github.com/langgraph4j/langgraph4j/tree/main/spring-ai/spring-ai-agent/src/test/java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; brings the power of rapid prototyping and interactive web app development to the Java ecosystem, much like &lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt; does for Python. With its simple, loop-based programming model, developers can quickly build data-driven applications without needing extensive frontend knowledge, leveraging familiar Java syntax and the rich JVM ecosystem. The live-reload feature enables instant experimentation and iteration, making it ideal for prototyping AI agents, data visualizations, and interactive tools. By integrating seamlessly with libraries like &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; combined with both &lt;a href="https://spring.io/projects/spring-ai#overview" rel="noopener noreferrer"&gt;Spring AI&lt;/a&gt; and &lt;a href="https://docs.langchain4j.dev" rel="noopener noreferrer"&gt;LangChain4j&lt;/a&gt;, &lt;a href="https://javelit.io" rel="noopener noreferrer"&gt;Javelit&lt;/a&gt; empowers Java developers to create engaging user interfaces effortlessly, bridging the gap between backend logic and user-facing applications.&lt;br&gt;&lt;br&gt;
Checkout project, try it and let me know your feedback and ... happy coding! 👋&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://glaforge.dev/posts/2025/10/24/javelit-to-create-quick-interactive-app-frontends-in-java/" rel="noopener noreferrer"&gt;Javelit to create quick interactive app frontends in Java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://bsorrentino.github.io/bsorrentino/ai/2025/12/20/Experiment-Javelit-Streamlit-for-Java.html" rel="noopener noreferrer"&gt;https://bsorrentino.github.io&lt;/a&gt; on December 20, 2025.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>ui</category>
      <category>ux</category>
      <category>javelit</category>
    </item>
    <item>
      <title>Very interesting. I agree with sentence "prompts are becoming as important as code dependencies" so it will be important apply the dependencies management approach also for prompt management</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Fri, 12 Dec 2025 10:22:25 +0000</pubDate>
      <link>https://forem.com/bsorrentino/very-interesting-i-agree-with-sentence-prompts-are-becoming-as-important-as-code-dependencies-so-e30</link>
      <guid>https://forem.com/bsorrentino/very-interesting-i-agree-with-sentence-prompts-are-becoming-as-important-as-code-dependencies-so-e30</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/devdiaries" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F161574%2F66c19c0b-5ffa-4d1a-b555-e417464d81a0.jpg" alt="devdiaries"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/devdiaries/prpm-the-universal-package-manager-for-ai-prompts-36cf" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;PRPM - The Universal Package Manager for AI Prompts&lt;/h2&gt;
      &lt;h3&gt;Dev Diaries ・ Dec 9 '25&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#devchallenge&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#muxchallenge&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#showandtell&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#video&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>devchallenge</category>
      <category>muxchallenge</category>
      <category>showandtell</category>
      <category>video</category>
    </item>
    <item>
      <title>🧠🤖 LangGraph4j Deep Agents (Agent 2.0)</title>
      <dc:creator>bsorrentino</dc:creator>
      <pubDate>Fri, 17 Oct 2025 15:07:17 +0000</pubDate>
      <link>https://forem.com/bsorrentino/langgraph4j-deep-agents-agent-20-1d74</link>
      <guid>https://forem.com/bsorrentino/langgraph4j-deep-agents-agent-20-1d74</guid>
      <description>&lt;h2&gt;
  
  
  Why Deep Agents (Agent 2.0)?
&lt;/h2&gt;

&lt;p&gt;Classic agents often run a simple loop: &lt;strong&gt;think → call a tool → observe → repeat&lt;/strong&gt;. That’s great for quick, transactional queries, but it breaks down on multi-hour or multi-day tasks (hallucinations, loss of goal, looping, no recovery).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Deep Agents&lt;/strong&gt; try fix this by &lt;strong&gt;changing the architecture&lt;/strong&gt; (not just the prompt) based on the four pillars below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Planning&lt;/strong&gt; – The agent continuously maintains a plan (e.g., a TODO in Markdown) with clear statuses instead of hiding intent in a just chain-of-thought.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hierarchical Delegation (Sub-Agents)&lt;/strong&gt; – An &lt;strong&gt;Orchestrator&lt;/strong&gt; delegates to specialized agents (Researcher, Coder, Writer, …), each working in a clean context and returning synthesized results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent Memory&lt;/strong&gt; – Intermediate artifacts (notes, code, data) are written to external storage (filesystem, vector store, …) and referenced by path/query rather than stuffing everything into the context window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extreme Context Engineering&lt;/strong&gt; – Long, specific instructions define: when to plan vs. act, when to spawn sub-agents and the human-in-the-loop(HITL) rules.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Reference Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2dvh90fvinygxjcee78f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2dvh90fvinygxjcee78f.png" alt="Deep Agents Architecture" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Reference Implementation in Java using LangGraph4j
&lt;/h2&gt;

&lt;p&gt;Since the &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; is inpired by (more popular) &lt;a href="https://github.com/langchain-ai/langgraph" rel="noopener noreferrer"&gt;LangGraph&lt;/a&gt; python version, I've decided to adapt its python based &lt;a href="https://github.com/langchain-ai/deepagents" rel="noopener noreferrer"&gt;Deep Agents reference implementation&lt;/a&gt; to Java using &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; and &lt;a href="https://spring.io/projects/spring-ai" rel="noopener noreferrer"&gt;Spring AI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project is on &lt;a href="https://github.com/langgraph4j/langgraph4j-deepagents.git" rel="noopener noreferrer"&gt;Github&lt;/a&gt;. This repository demonstrates the four pillars of Deep Agents, it includes sample code that create a &lt;strong&gt;Deep Researcher Agent&lt;/strong&gt; that use &lt;a href="https://www.tavily.com" rel="noopener noreferrer"&gt;Tavily&lt;/a&gt; as web search engine and &lt;strong&gt;OpenAI gpt-4o-mini model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at a sequence diagram for a Deep Agent handling a complex request: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2oevotyyr15qno70auf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2oevotyyr15qno70auf.png" alt="sequence" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below a representative code snippet that implements the Deep Agents in the diagram&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a Research Sub Agent&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;researchSubagent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DeepAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SubAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"research-agent"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
        Used to research more in depth questions. Only give this researcher one topic at a time.
        Do not pass multiple sub questions to this researcher.
        Instead, you should break down a large topic into the necessary components, and then call multiple research agents in parallel, one for each sub question.
        """&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
        You are a dedicated researcher. Your job is to conduct research based on the users questions.
        Conduct thorough research and then reply to the user with a detailed answer to their question

        ........(to be continued).............. 
        """&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"internet_search"&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Create a Critique Sub Agent&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;critiqueSubAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;DeepAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SubAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"critique-agent"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Used to critique the final report. Give this agent some information about how you want it to critique the report."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
            You are a dedicated editor. You are being tasked to critique a report.

            You can find the report at `final_report.md`.

            You can find the question/topic for this report at `question.txt`.

            ........(to be continued).............. 
            """&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Create a Main Agent&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;deepAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DeepAgent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
        You are an expert researcher. Your job is to conduct thorough research, and then write a polished report.

        The first thing you should do is to write the original user question to `question.txt` so you have a record of it.

        Use the research-agent to conduct deep research. It will respond to your questions/topics with a detailed answer.

        When you think you enough information to write a final report, write it to `final_report.md`

        You can call the critique-agent to get a critique of the final report. After that (if needed) you can do more research and edit the `final_report.md`

        ........(to be continued).............. 

        """&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subAgents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;researchSubagent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;critiqueSubAgent&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;internetSearch&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;CompileConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;recursionLimit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""
                        What is langgraph4j project?
                        """&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;runnableConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RunnableConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"messages"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userMessage&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; 
                        &lt;span class="n"&gt;runnableConfig&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;peek&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="sh"&gt;"""
        ================================
        TODO
        ================================
        """&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;todos&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
                -----------
                %s
                -----------
                """&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="sh"&gt;"""
        ================================
        FILES
        ================================
        """&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
                file: '%s'
                -----------
                %s
                -----------
                """&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="sh"&gt;"""
        ================================
        FINAL RESULT
        ================================
        """&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"result: %s\n"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;lastMessage&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AssistantMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;AssistantMessage:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getText&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Deep Agents architecture is a try &lt;strong&gt;to move beyond one-loop “shallow” agents&lt;/strong&gt; to explicit planning hierarchical delegation, persistent memory, and rigorous context engineering. &lt;a href="https://github.com/langgraph4j/langgraph4j" rel="noopener noreferrer"&gt;LangGraph4j&lt;/a&gt; can help to experiment in Labs and deliver in production complex Agentic Workflow on top of JVM. &lt;br&gt;
Checkout project, try it and let me know your feedback and ... happy AI coding! 👋&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.langchain.com/deep-agents/" rel="noopener noreferrer"&gt;Deep Agents (LangChain Blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hwchase17/deepagents" rel="noopener noreferrer"&gt;Langchain Deepagents (Github)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.philschmid.de/agents-2.0-deep-agents" rel="noopener noreferrer"&gt;Agents 2.0: From Shallow to Deep Agents (Phil Schmid Blog)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Originally published at &lt;a href="https://bsorrentino.github.io/bsorrentino/ai/2025/10/17/langgraph4j-deepagents.html" rel="noopener noreferrer"&gt;https://bsorrentino.github.io&lt;/a&gt; on October 17, 2025.&lt;/p&gt;

</description>
      <category>langgraph4j</category>
      <category>ai</category>
      <category>agents</category>
      <category>springai</category>
    </item>
  </channel>
</rss>
