<?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>DEV Community: sekka</title>
    <description>The latest articles on DEV Community by sekka (@asekka).</description>
    <link>https://dev.to/asekka</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3953219%2Fe647da73-548b-4436-97ec-24d99ebf0d70.jpg</url>
      <title>DEV Community: sekka</title>
      <link>https://dev.to/asekka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/asekka"/>
    <language>en</language>
    <item>
      <title>How I stopped Claude Code from ignoring my conventions</title>
      <dc:creator>sekka</dc:creator>
      <pubDate>Wed, 03 Jun 2026 21:16:01 +0000</pubDate>
      <link>https://dev.to/asekka/how-i-stopped-claude-code-from-ignoring-my-conventions-2lc0</link>
      <guid>https://dev.to/asekka/how-i-stopped-claude-code-from-ignoring-my-conventions-2lc0</guid>
      <description>&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%2F2u15mimwb271ew7h6kdr.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%2F2u15mimwb271ew7h6kdr.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github repo: &lt;a href="https://github.com/datallmhub/claude-governance" rel="noopener noreferrer"&gt;https://github.com/datallmhub/claude-governance&lt;/a&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>devtools</category>
      <category>claude</category>
    </item>
    <item>
      <title>Adaptive execution for Java agents: reason-aware retries and budget-aware routing</title>
      <dc:creator>sekka</dc:creator>
      <pubDate>Wed, 27 May 2026 08:20:52 +0000</pubDate>
      <link>https://dev.to/asekka/adaptive-execution-for-java-agents-reason-aware-retries-and-budget-aware-routing-1elm</link>
      <guid>https://dev.to/asekka/adaptive-execution-for-java-agents-reason-aware-retries-and-budget-aware-routing-1elm</guid>
      <description>&lt;p&gt;If your LLM agent retries a &lt;code&gt;429&lt;/code&gt; fifty times overnight, retries a &lt;code&gt;400&lt;/code&gt; three times before giving up, and sends every request to your top-tier model until the run budget is gone, those aren't bugs in the model. They're missing two cheap policies your orchestration layer should be making for you.&lt;/p&gt;

&lt;p&gt;AgentFlow4J v0.7.0 (Java multi-agent orchestration on Spring AI) ships those two policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Reason-aware retries
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;RetryPolicy&lt;/code&gt; that counts attempts is blind to &lt;em&gt;why&lt;/em&gt; a call failed. v0.7.0 adds a &lt;code&gt;FailureClassifier&lt;/code&gt; that sorts every failure into one of three categories:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;What the graph does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TRANSIENT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retry. If the failure carries a &lt;code&gt;Retry-After&lt;/code&gt; hint, that delay is honoured instead of the computed backoff.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PERMANENT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stop immediately — no further attempts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OVER_BUDGET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stop and surface an &lt;code&gt;InterruptRequest&lt;/code&gt; so a human can approve more budget and resume.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;default&lt;/strong&gt; classifier already understands JDK I/O exceptions, Spring AI / Spring Web &lt;code&gt;5xx&lt;/code&gt; + &lt;code&gt;429&lt;/code&gt; (parsing &lt;code&gt;Retry-After&lt;/code&gt;) vs other &lt;code&gt;4xx&lt;/code&gt;, and &lt;code&gt;BudgetExceededException&lt;/code&gt;, all detected by class name, so &lt;code&gt;agentflow4j-graph&lt;/code&gt; keeps &lt;strong&gt;zero compile-time Spring dependency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Adding your own rules composes via &lt;code&gt;orElse&lt;/code&gt;:&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="nc"&gt;FailureClassifier&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cause&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&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;cause&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;QuotaExhaustedException&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FailureClassification&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;overBudget&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"monthly quota hit"&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;cause&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;InvalidPromptException&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FailureClassification&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;permanent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rejected by guardrail"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// unknown — defer to the default&lt;/span&gt;
&lt;span class="o"&gt;};&lt;/span&gt;

&lt;span class="nc"&gt;RetryPolicy&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RetryPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exponential&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&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;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withClassifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FailureClassifier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existing policies that only set the legacy &lt;code&gt;retryOn&lt;/code&gt; predicate keep their exact behaviour, the classifier falls back to it when it returns &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Budget-aware routing
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;BudgetPolicy&lt;/code&gt; already caps the cost of a run. v0.7.0 lets it shape &lt;em&gt;which model handles which request&lt;/em&gt;:&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="nc"&gt;BudgetPolicy&lt;/span&gt; &lt;span class="n"&gt;budget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BudgetPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hierarchical&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;BudgetLimits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;5.00&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;estimator&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Use "premium" while ≥ $1.00 remains, then "fallback".&lt;/span&gt;
&lt;span class="nc"&gt;RoutingStrategy&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RoutingStrategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;budgetAware&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;budget&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BudgetPolicy&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="na"&gt;RUN&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.00&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"premium"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"fallback"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;CoordinatorAgent&lt;/span&gt; &lt;span class="n"&gt;desk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CoordinatorAgent&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;executor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"premium"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;premiumAgent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fallback"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallbackAgent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;routingStrategy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the run budget has more than &lt;code&gt;$1.00&lt;/code&gt; remaining, the coordinator sends work to &lt;code&gt;premium&lt;/code&gt;. The moment less remains, it degrades to &lt;code&gt;fallback&lt;/code&gt;. Reading the live &lt;code&gt;BudgetPolicy.remaining(...)&lt;/code&gt; counter is free, no extra LLM call to "classify complexity."&lt;/p&gt;

&lt;p&gt;This is the one cost-aware routing lever that's both &lt;strong&gt;deterministic&lt;/strong&gt; and &lt;strong&gt;provably cheaper&lt;/strong&gt;: classifying complexity ex-ante with an LLM would itself cost a call (chicken-and-egg), and self-confidence routing doubles the cost. Reading counters is free.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 30-second runnable demo
&lt;/h2&gt;

&lt;p&gt;The cookbook ships a recipe that wires both features end-to-end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/datallmhub/agentflow4j-cookbook.git
&lt;span class="nb"&gt;cd &lt;/span&gt;agentflow4j-cookbook
mvn &lt;span class="nt"&gt;-pl&lt;/span&gt; 06-cost-aware-routing &lt;span class="nb"&gt;exec&lt;/span&gt;:java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key required, Ollama optional, the recipe falls back to a deterministic stub. You should see the first three tickets handled by &lt;code&gt;premium&lt;/code&gt;, then the squad switching cleanly to &lt;code&gt;fallback&lt;/code&gt; once remaining drops below &lt;code&gt;$2.00&lt;/code&gt;. The retry scene then shows a flaky node recovering on attempt 3 with &lt;code&gt;50ms → 98ms&lt;/code&gt; exponential+jitter backoffs, followed by a classification table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.datallmhub.agentflow4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;agentflow4j-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;v0.7.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Via JitPack: add &lt;code&gt;https://jitpack.io&lt;/code&gt; to your &lt;code&gt;&amp;lt;repositories&amp;gt;&lt;/code&gt; if you haven't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Recipe 06 source: &lt;a href="https://github.com/datallmhub/agentflow4j-cookbook/tree/main/06-cost-aware-routing" rel="noopener noreferrer"&gt;github.com/datallmhub/agentflow4j-cookbook/tree/main/06-cost-aware-routing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Resilience docs: &lt;a href="https://datallmhub.github.io/agentflow4j/resilience/" rel="noopener noreferrer"&gt;datallmhub.github.io/agentflow4j/resilience&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Release notes: &lt;a href="https://github.com/datallmhub/agentflow4j/releases/tag/v0.7.0" rel="noopener noreferrer"&gt;github.com/datallmhub/agentflow4j/releases/tag/v0.7.0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>Run your first AI agent in Java — for free, with Mistral</title>
      <dc:creator>sekka</dc:creator>
      <pubDate>Tue, 26 May 2026 21:04:54 +0000</pubDate>
      <link>https://dev.to/asekka/run-your-first-ai-agent-in-java-for-free-with-mistral-3dhj</link>
      <guid>https://dev.to/asekka/run-your-first-ai-agent-in-java-for-free-with-mistral-3dhj</guid>
      <description>&lt;p&gt;Every "build an AI agent" tutorial I find assumes two things: you write Python, and you have a paid OpenAI key. I write Java and I didn't want to pay just to experiment.&lt;/p&gt;

&lt;p&gt;So here's the version nobody writes: a &lt;strong&gt;real LLM-backed agent, on the JVM, for free&lt;/strong&gt; — using &lt;a href="https://mistral.ai/" rel="noopener noreferrer"&gt;Mistral&lt;/a&gt;'s free tier and &lt;a href="https://github.com/datallmhub/agentflow4j" rel="noopener noreferrer"&gt;AgentFlow4J&lt;/a&gt;, an open-source orchestration runtime on top of Spring AI. About ten minutes, start to finish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Create a Mistral account
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="https://console.mistral.ai/" rel="noopener noreferrer"&gt;console.mistral.ai&lt;/a&gt; and sign up (email, Google, or GitHub). You land on &lt;em&gt;La Plateforme&lt;/em&gt;, the developer console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Get a free API key
&lt;/h2&gt;

&lt;p&gt;Open &lt;a href="https://console.mistral.ai/api-keys/" rel="noopener noreferrer"&gt;API Keys&lt;/a&gt; → &lt;strong&gt;Create new key&lt;/strong&gt;, name it, copy it (you only see it once).&lt;/p&gt;

&lt;p&gt;Export it in your shell — never commit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MISTRAL_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"sk-...your-key..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;mistral-small&lt;/code&gt; is covered by the free tier, which is plenty for building and testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Add the dependencies
&lt;/h2&gt;

&lt;p&gt;AgentFlow4J ships via &lt;a href="https://jitpack.io/#datallmhub/agentflow4j" rel="noopener noreferrer"&gt;JitPack&lt;/a&gt;. Add it plus Spring AI's Mistral starter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;jitpack.io&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;https://jitpack.io&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.github.datallmhub.agentflow4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;agentflow4j-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;v0.7.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.ai&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-ai-starter-model-mistral-ai&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4 — Point Spring AI at Mistral
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# application.yml&lt;/span&gt;
&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ai&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;mistralai&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;api-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${MISTRAL_API_KEY}&lt;/span&gt;
      &lt;span class="na"&gt;chat&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mistral-small-latest&lt;/span&gt;
          &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5 — Write and run an agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;
&lt;span class="nc"&gt;CommandLineRunner&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt; &lt;span class="n"&gt;chatClientBuilder&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Agent&lt;/span&gt; &lt;span class="n"&gt;assistant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ExecutorAgent&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;"assistant"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatClientBuilder&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;systemPrompt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You are a concise, helpful assistant. Answer in one sentence."&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;AgentResult&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;assistant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;AgentContext&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;"What is backpressure in reactive streams?"&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="s"&gt;"\nMistral says: "&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;text&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\n"&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;Run with &lt;code&gt;MISTRAL_API_KEY&lt;/code&gt; set, and you get a real answer from Mistral — your first LLM agent in Java, for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a runtime, not just a ChatClient?
&lt;/h2&gt;

&lt;p&gt;A single call is easy. Real systems chain agents, pass state, retry, and need guardrails. That's what AgentFlow4J adds on top of Spring AI: graph orchestration, typed state, checkpoint/resume, and governance gates (budget caps, tool/state policies, human approval) — all idiomatic Java, no Python, no sidecar.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/datallmhub/agentflow4j-cookbook" rel="noopener noreferrer"&gt;cookbook&lt;/a&gt; has five runnable recipes (RAG, ticket triage, web research, Slack bot, batch processing) if you want to go further.&lt;/p&gt;




&lt;p&gt;It's open source (Apache 2.0). If you've been wanting to build agents without leaving the JVM, I'd genuinely love your feedback: &lt;a href="https://github.com/datallmhub/agentflow4j" rel="noopener noreferrer"&gt;github.com/datallmhub/agentflow4j&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>ai</category>
      <category>llm</category>
      <category>springboot</category>
    </item>
  </channel>
</rss>
