<?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: Sunil Prakash</title>
    <description>The latest articles on DEV Community by Sunil Prakash (@sunilprakash).</description>
    <link>https://dev.to/sunilprakash</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%2F3838537%2F32569555-b587-4112-9fc0-0ea4a37e9fa4.png</url>
      <title>DEV Community: Sunil Prakash</title>
      <link>https://dev.to/sunilprakash</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sunilprakash"/>
    <language>en</language>
    <item>
      <title>The State of Memory in Java AI Agents (April 2026)</title>
      <dc:creator>Sunil Prakash</dc:creator>
      <pubDate>Tue, 07 Apr 2026 17:12:08 +0000</pubDate>
      <link>https://dev.to/sunilprakash/the-state-of-memory-in-java-ai-agents-april-2026-13c6</link>
      <guid>https://dev.to/sunilprakash/the-state-of-memory-in-java-ai-agents-april-2026-13c6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was originally published on &lt;a href="https://jamjet.dev/blog/state-of-memory-java-ai-agents/" rel="noopener noreferrer"&gt;jamjet.dev&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If you're building AI agents in Java today, your options for persistent memory range from "store the last 20 chat messages in Postgres" to "run a Python service in a sidecar container and call it over HTTP." There is no Java-native equivalent to Mem0, Zep, or Letta — the libraries Python developers reach for when they need real memory.&lt;/p&gt;

&lt;p&gt;This post is a tour of every option a Java developer has in April 2026, why most of them stop at chat history, what "real memory" should actually mean, and one library we shipped to fill the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scenario every Java AI developer recognises
&lt;/h2&gt;

&lt;p&gt;You're building an AI agent in Spring Boot. Maybe it's a customer support copilot, maybe it's a coding assistant, maybe it's a research agent. You wire up Spring AI or LangChain4j, write a few tools, and the first conversation works.&lt;/p&gt;

&lt;p&gt;Then your user comes back the next day. The agent doesn't remember them. It doesn't remember they're allergic to peanuts. It doesn't remember they're working on the Acme migration. It doesn't remember they prefer verbose explanations. Every conversation starts from zero.&lt;/p&gt;

&lt;p&gt;You search for "Java AI agent memory" and end up with three kinds of results:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tutorials on how to store chat messages in Postgres&lt;/li&gt;
&lt;li&gt;Marketing pages for Mem0 and Zep — Python only&lt;/li&gt;
&lt;li&gt;GitHub issues asking why there's no Java SDK&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Memory" means three different things
&lt;/h2&gt;

&lt;p&gt;Before we tour the libraries, we need to be precise. There are at least three different things people mean when they say "agent memory":&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Conversation history.&lt;/strong&gt; The last N messages of the current session. Solved problem — every framework ships this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. State checkpointing.&lt;/strong&gt; Snapshots of agent execution state for resume and replay. Solved by LangGraph, Koog persistence, Temporal-style runtimes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Long-term knowledge memory.&lt;/strong&gt; Facts about the user, their preferences, their projects, their history — extracted from conversations, stored durably, retrievable across sessions, and de-conflicted when they change. This is what Mem0 and Zep do. &lt;strong&gt;It is not solved on the JVM.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rest of this post is about the third one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What real memory needs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fact extraction.&lt;/strong&gt; An LLM reads a conversation and pulls out discrete, atomic facts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conflict detection.&lt;/strong&gt; When a new fact contradicts an old one, the system invalidates the old fact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid retrieval.&lt;/strong&gt; Vector + keyword + graph walk fused together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal reasoning.&lt;/strong&gt; Facts have validity windows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token-budgeted context assembly.&lt;/strong&gt; Pick which facts go in the prompt and respect the budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decay and consolidation.&lt;/strong&gt; Stale facts fade, frequent facts get promoted, duplicates merge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tour: every option Java developers have today
&lt;/h2&gt;

&lt;h3&gt;
  
  
  LangChain4j ChatMemory
&lt;/h3&gt;

&lt;p&gt;Most popular JVM AI framework. Ships &lt;code&gt;ChatMemory&lt;/code&gt; interface with &lt;code&gt;MessageWindowChatMemory&lt;/code&gt; and &lt;code&gt;TokenWindowChatMemory&lt;/code&gt;. Persistence via developer-implemented &lt;code&gt;ChatMemoryStore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What it does: stores message objects, respects token/count limits. What it does not do: extract facts, deduplicate, retrieve semantically, reason about time. The docs are explicit — &lt;code&gt;ChatMemory&lt;/code&gt; is a container abstraction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spring AI ChatMemory
&lt;/h3&gt;

&lt;p&gt;Shipped GA in 2025 with broad backend support: JDBC, Cassandra, Mongo, Neo4j, Cosmos DB. Three advisors plug it into &lt;code&gt;ChatClient&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;VectorStoreChatMemoryAdvisor&lt;/code&gt; is the closest thing to "semantic memory" — it indexes raw messages in your VectorStore. But it indexes raw messages, not extracted facts. No entity model, no relationship graph, no conflict detection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google ADK for Java
&lt;/h3&gt;

&lt;p&gt;Ships 1.0.0 with two memory implementations: &lt;code&gt;InMemoryMemoryService&lt;/code&gt; (keyword matching only) and &lt;code&gt;VertexAiMemoryBankService&lt;/code&gt; (Vertex AI only). Memory Bank is excellent but Google Cloud-locked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Koog (JetBrains)
&lt;/h3&gt;

&lt;p&gt;Kotlin-first framework with &lt;code&gt;AgentMemory&lt;/code&gt; storing facts by &lt;code&gt;Concept&lt;/code&gt;, &lt;code&gt;Subject&lt;/code&gt;, &lt;code&gt;Scope&lt;/code&gt;. Closest competitor on the "facts about subjects" axis.&lt;/p&gt;

&lt;p&gt;Two caveats: Java consumption is awkward, and GitHub issue JetBrains/koog#1001 documents that AgentMemory floods prompts as facts accumulate — no token budgeting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embabel
&lt;/h3&gt;

&lt;p&gt;Rod Johnson's JVM agent framework. Uses a blackboard pattern — shared state per agent run.&lt;/p&gt;

&lt;p&gt;Per the maintainers: &lt;em&gt;"in Embabel it's not about conversational memory so much as domain objects that are stored in the blackboard during the flow."&lt;/em&gt; Long-term memory is an explicit non-goal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mem0 Java SDK (the one that doesn't exist)
&lt;/h3&gt;

&lt;p&gt;The top Google result is &lt;code&gt;me.pgthinker:mem0-client-java&lt;/code&gt;, a community wrapper at version 0.1.3, last updated nine months ago, with 9 GitHub stars. It's a thin REST client requiring a Python Mem0 server alongside your JVM app.&lt;/p&gt;

&lt;p&gt;No official Mem0 Java client exists. Python and Node.js only.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zep Java SDK (also doesn't exist)
&lt;/h3&gt;

&lt;p&gt;Zep's official clients are Python, TypeScript, and Go. No Java SDK.&lt;/p&gt;

&lt;h3&gt;
  
  
  DIY (what most teams actually do)
&lt;/h3&gt;

&lt;p&gt;When Java teams need real memory today, they assemble:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Postgres + pgvector (or Qdrant) for embeddings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;JdbcChatMemoryRepository&lt;/code&gt; for messages&lt;/li&gt;
&lt;li&gt;Custom advisor that calls an LLM to extract facts&lt;/li&gt;
&lt;li&gt;Custom retrieval layer combining vector and keyword search&lt;/li&gt;
&lt;li&gt;Nightly cron job for decay and dedup&lt;/li&gt;
&lt;li&gt;Custom token-budgeting in the prompt builder&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Roughly 1,500–3,000 lines of bespoke Java per team. Quietly diverges between projects. Rarely gets temporal reasoning right. Almost never gets consolidation right.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern
&lt;/h2&gt;

&lt;p&gt;Every Java memory option lives in one of two boxes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chat history persistence&lt;/strong&gt; (LangChain4j, Spring AI core, Embabel)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State checkpointing&lt;/strong&gt; (LangGraph4j, Koog persistence)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing in between. No JVM-native library that does fact extraction + conflict resolution + temporal graph + hybrid retrieval + consolidation in one dependency.&lt;/p&gt;

&lt;p&gt;The Python ecosystem has had Mem0 since 2024 and Zep/Graphiti since early 2025. The Java ecosystem is roughly 18 months behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built
&lt;/h2&gt;

&lt;p&gt;I run &lt;a href="https://jamjet.dev" rel="noopener noreferrer"&gt;JamJet&lt;/a&gt;. As we built our agent runtime, the memory gap kept showing up. So we built a memory layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engram&lt;/strong&gt; is a durable memory system that does the things on the list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fact extraction from conversation messages via LLM&lt;/li&gt;
&lt;li&gt;Conflict detection — vector similarity threshold plus LLM resolution&lt;/li&gt;
&lt;li&gt;Hybrid retrieval — vector + SQLite FTS5 keyword + graph walk&lt;/li&gt;
&lt;li&gt;Temporal knowledge graph with validity windows&lt;/li&gt;
&lt;li&gt;Token-budgeted context assembly with three output formats&lt;/li&gt;
&lt;li&gt;5-operation consolidation engine: &lt;strong&gt;decay&lt;/strong&gt;, &lt;strong&gt;promote&lt;/strong&gt;, &lt;strong&gt;dedup&lt;/strong&gt;, &lt;strong&gt;summarize&lt;/strong&gt;, &lt;strong&gt;reflect&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;MCP server option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Runs against SQLite by default. No Postgres, no Qdrant, no Neo4j, no Python sidecar.&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;dev.jamjet.engram.EngramClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;dev.jamjet.engram.EngramConfig&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;memory&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;EngramClient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EngramConfig&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;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&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="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;"role"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;      &lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"I'm allergic to peanuts and live in Austin"&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;"role"&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="s"&gt;"content"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Got it, I'll remember that."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="s"&gt;"alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&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;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"what should I cook for dinner"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"system_prompt"&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="n"&gt;context&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;"text"&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;Maven Central:&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;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;dev.jamjet&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;jamjet-sdk&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;0.4.3&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;Apache 2.0. Rust runtime published as &lt;code&gt;jamjet-engram&lt;/code&gt; on crates.io.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do (yet)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No Spring Boot auto-configuration yet (starter on roadmap)&lt;/li&gt;
&lt;li&gt;No JDBC backend (SQLite-first, Postgres in 0.5.x)&lt;/li&gt;
&lt;li&gt;No managed cloud option&lt;/li&gt;
&lt;li&gt;No published LongMemEval / DMR scores yet (benchmarks running, not going to cherry-pick)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&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;dev.jamjet&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;jamjet-sdk&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;0.4.3&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;Or run it as an MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;jamjet-engram-server
engram serve &lt;span class="nt"&gt;--db&lt;/span&gt; memory.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/jamjet-labs/jamjet" rel="noopener noreferrer"&gt;github.com/jamjet-labs/jamjet&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you've been quietly rolling your own memory layer in Java, I'd love to hear what you ended up with. Reach out via GitHub issues or the comments below.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>java</category>
      <category>rust</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Introducing Agentic AI for Serious Engineers: A Free Practical Book + Code Repo</title>
      <dc:creator>Sunil Prakash</dc:creator>
      <pubDate>Fri, 27 Mar 2026 04:33:12 +0000</pubDate>
      <link>https://dev.to/sunilprakash/introducing-agentic-ai-for-serious-engineers-a-free-practical-book-code-repo-64g</link>
      <guid>https://dev.to/sunilprakash/introducing-agentic-ai-for-serious-engineers-a-free-practical-book-code-repo-64g</guid>
      <description>&lt;p&gt;Agentic AI is moving fast.&lt;/p&gt;

&lt;p&gt;There are new frameworks, new demos, new orchestration patterns, and new opinions almost every week. That is exciting, but it also creates a problem for engineers trying to build real systems.&lt;/p&gt;

&lt;p&gt;A lot of the material online is either too abstract, too framework-specific, too hype-heavy, or too focused on demo magic instead of production reality.&lt;/p&gt;

&lt;p&gt;I wanted something different.&lt;/p&gt;

&lt;p&gt;So I started writing &lt;strong&gt;Agentic AI for Serious Engineers&lt;/strong&gt; - a free practical book and code repo for engineers who want to build agent systems that are not just impressive in a demo, but usable, testable, observable, and trustworthy in real environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I wrote it
&lt;/h2&gt;

&lt;p&gt;I kept running into the same gap.&lt;/p&gt;

&lt;p&gt;There is plenty of excitement around agents, but much less practical material on questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What actually makes a system agentic?&lt;/li&gt;
&lt;li&gt;When should you use an agent instead of a workflow?&lt;/li&gt;
&lt;li&gt;How should tools be designed so they are safe and reliable to call?&lt;/li&gt;
&lt;li&gt;What does good context design look like?&lt;/li&gt;
&lt;li&gt;How do you evaluate an agent system beyond “it seemed to work”?&lt;/li&gt;
&lt;li&gt;Where should human approval sit in the architecture?&lt;/li&gt;
&lt;li&gt;How do you think about reliability, security, and observability from the start?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are the questions this book tries to answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;This book is for engineers and architects building real AI systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;backend engineers&lt;/li&gt;
&lt;li&gt;platform engineers&lt;/li&gt;
&lt;li&gt;staff+ engineers&lt;/li&gt;
&lt;li&gt;software architects&lt;/li&gt;
&lt;li&gt;technical leads&lt;/li&gt;
&lt;li&gt;data engineers working on production AI applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It assumes you already understand software systems.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; assume you already know how to design agent systems well.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes it different
&lt;/h2&gt;

&lt;p&gt;This project is intentionally practical.&lt;/p&gt;

&lt;p&gt;It is not a catalog of trendy frameworks.&lt;br&gt;
It is not a collection of magical claims.&lt;br&gt;
It is not “plug in this library and everything works.”&lt;/p&gt;

&lt;p&gt;Instead, it focuses on the engineering questions that matter when systems move closer to production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool contracts&lt;/li&gt;
&lt;li&gt;control flow&lt;/li&gt;
&lt;li&gt;context boundaries&lt;/li&gt;
&lt;li&gt;evaluation&lt;/li&gt;
&lt;li&gt;approval gates&lt;/li&gt;
&lt;li&gt;reliability&lt;/li&gt;
&lt;li&gt;hardening&lt;/li&gt;
&lt;li&gt;traceability&lt;/li&gt;
&lt;li&gt;operating tradeoffs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not just to help someone build an agent.&lt;/p&gt;

&lt;p&gt;The goal is to help them build one with better judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s inside
&lt;/h2&gt;

&lt;p&gt;The repo currently includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;7 chapters&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2 threaded end-to-end projects&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;per-chapter code&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tests and eval-oriented structure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;diagrams, principles, and roadmap&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;a free online version of the book&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of the topics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what “agentic” actually means&lt;/li&gt;
&lt;li&gt;tools, context, and the agent loop&lt;/li&gt;
&lt;li&gt;workflow-first design&lt;/li&gt;
&lt;li&gt;multi-agent systems&lt;/li&gt;
&lt;li&gt;human-in-the-loop architecture&lt;/li&gt;
&lt;li&gt;evaluating and hardening agents&lt;/li&gt;
&lt;li&gt;when not to use agents&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The kind of engineer I wrote this for
&lt;/h2&gt;

&lt;p&gt;I wrote this for the engineer who looks at agentic AI and thinks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is interesting.&lt;br&gt;&lt;br&gt;
But how do I build it in a way I can actually trust?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the center of gravity of the book.&lt;/p&gt;

&lt;p&gt;Not anti-agent.&lt;br&gt;&lt;br&gt;
Not pro-hype.&lt;br&gt;&lt;br&gt;
Just serious about engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read it free
&lt;/h2&gt;

&lt;p&gt;You can read the book and explore the code here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[&lt;a href="https://github.com/sunilp/agentic-ai" rel="noopener noreferrer"&gt;https://github.com/sunilp/agentic-ai&lt;/a&gt;]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you end up reading it, I’d genuinely love feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what feels most useful&lt;/li&gt;
&lt;li&gt;what is still unclear&lt;/li&gt;
&lt;li&gt;what you’d want covered more deeply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m continuing to improve it, and I’d love for it to become a genuinely useful resource for engineers building the next generation of AI systems.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>softwareengineering</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Your AI CLI Writes Code. Mine Tells You What It'll Break.</title>
      <dc:creator>Sunil Prakash</dc:creator>
      <pubDate>Sun, 22 Mar 2026 15:18:05 +0000</pubDate>
      <link>https://dev.to/sunilprakash/your-ai-cli-writes-code-mine-tells-you-what-itll-break-296l</link>
      <guid>https://dev.to/sunilprakash/your-ai-cli-writes-code-mine-tells-you-what-itll-break-296l</guid>
      <description>&lt;p&gt;AI CLI tools are everywhere right now. Claude Code, Gemini CLI, GitHub Copilot in the terminal — they'll write your code, refactor your modules, even run your tests.&lt;/p&gt;

&lt;p&gt;But ask any of them: &lt;strong&gt;"If I rename this function, what breaks?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They'll scan the files they can see, make their best guess, and probably miss the SQL view that reads the column you're about to change. Or the Java batch job that calls your Python function through a stored procedure. Or the dbt model downstream of the table your migration is about to alter.&lt;/p&gt;

&lt;p&gt;That's not a knock on AI. It's just not what LLMs are built for. Dependency analysis needs &lt;strong&gt;deterministic static analysis&lt;/strong&gt;, not probabilistic text generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap in every AI CLI
&lt;/h2&gt;

&lt;p&gt;Here's what I noticed building with these tools: they're incredible at &lt;em&gt;writing&lt;/em&gt; code but terrible at &lt;em&gt;understanding what already depends on it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ask Claude Code to "add retry logic to the HTTP client" — brilliant. Ask it "what will break if I change the response shape of &lt;code&gt;getUser&lt;/code&gt;" — it'll read a few files and give you a confident answer that misses half the callers.&lt;/p&gt;

&lt;p&gt;That's because LLMs work with whatever fits in context. Your codebase has thousands of files. The SQL stored procedure that calls your function through &lt;code&gt;EXEC&lt;/code&gt; isn't in the context window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static analysis that crosses language boundaries
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://jam.sunilprakash.com" rel="noopener noreferrer"&gt;Jam&lt;/a&gt; to fill this gap. It's a developer CLI with 40+ commands, but the one that keeps saving me is &lt;code&gt;jam trace --impact&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It uses tree-sitter to parse your entire workspace — TypeScript, Python, Java, and SQL — builds a SQLite index of every function, every call site, every import, and every SQL column reference. Then gives you a deterministic answer:&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="nv"&gt;$ &lt;/span&gt;jam trace updateBalance &lt;span class="nt"&gt;--impact&lt;/span&gt;

Impact Analysis &lt;span class="k"&gt;for &lt;/span&gt;updateBalance
───────────────────────────────────
Direct callers:
  PaymentService.processRefund&lt;span class="o"&gt;()&lt;/span&gt;  &lt;span class="o"&gt;[&lt;/span&gt;Java]
  BATCH_NIGHTLY_RECONCILE         &lt;span class="o"&gt;[&lt;/span&gt;SQL]

Column dependents:
  VIEW v_customer_summary   &lt;span class="o"&gt;(&lt;/span&gt;reads customer.balance&lt;span class="o"&gt;)&lt;/span&gt;
  PROC_MONTHLY_STATEMENT    &lt;span class="o"&gt;(&lt;/span&gt;reads customer.balance&lt;span class="o"&gt;)&lt;/span&gt;

Risk: HIGH — 2 callers across 2 languages, 2 column dependents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No hallucination. No "I think these files might be affected." Two callers in two languages, two column dependents, risk level HIGH. Deterministic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why LLMs can't do this (yet)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context window limits&lt;/strong&gt; — Your 200-file Java project with SQL migrations doesn't fit in any context window. Static analysis indexes everything.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-language boundaries&lt;/strong&gt; — A Java class running &lt;code&gt;EXEC update_user&lt;/code&gt; is calling a SQL stored procedure. LLMs see a string. Tree-sitter sees a cross-language call.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Column-level tracking&lt;/strong&gt; — When a SQL view reads &lt;code&gt;customer.balance&lt;/code&gt;, and your function writes to &lt;code&gt;customer.balance&lt;/code&gt;, that's a dependency. No LLM tracks this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Determinism&lt;/strong&gt; — Ask an LLM the same question twice, get different answers. Ask &lt;code&gt;jam trace&lt;/code&gt; twice, get the same graph. For impact analysis, you need guarantees, not guesses.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Not replacing AI — complementing it
&lt;/h2&gt;

&lt;p&gt;Jam isn't anti-AI. It literally has AI built in — &lt;code&gt;jam ask&lt;/code&gt;, &lt;code&gt;jam go&lt;/code&gt; (agentic execution), &lt;code&gt;jam commit&lt;/code&gt; (AI-powered commit messages), &lt;code&gt;jam review&lt;/code&gt;. It works with Ollama, Copilot, OpenAI, Anthropic, and Groq.&lt;/p&gt;

&lt;p&gt;But for the question "what breaks if I change this?" — AI is the wrong tool. You wouldn't ask ChatGPT to run your test suite. You shouldn't ask it to trace your dependency graph either.&lt;/p&gt;

&lt;p&gt;The best workflow: use Claude Code or Gemini CLI to &lt;em&gt;write&lt;/em&gt; the change, then use &lt;code&gt;jam trace --impact&lt;/code&gt; to &lt;em&gt;verify&lt;/em&gt; the blast radius before you ship.&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="c"&gt;# Trace any symbol's callers and callees&lt;/span&gt;
jam trace createProvider &lt;span class="nt"&gt;--depth&lt;/span&gt; 5

&lt;span class="c"&gt;# Get the full impact report&lt;/span&gt;
jam trace updateBalance &lt;span class="nt"&gt;--impact&lt;/span&gt;

&lt;span class="c"&gt;# Output as Mermaid diagram for docs&lt;/span&gt;
jam trace handleRequest &lt;span class="nt"&gt;--mermaid&lt;/span&gt;

&lt;span class="c"&gt;# JSON for CI/automation&lt;/span&gt;
jam trace processPayment &lt;span class="nt"&gt;--impact&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tree-sitter parsing&lt;/strong&gt; — Builds ASTs for TypeScript, Python, Java, SQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Symbol extraction&lt;/strong&gt; — Functions, classes, methods, imports, call sites&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-language detection&lt;/strong&gt; — Java &lt;code&gt;EXEC&lt;/code&gt;/&lt;code&gt;CALL&lt;/code&gt; → SQL procedures. SQL column refs in SELECT/UPDATE/INSERT/DELETE&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite index&lt;/strong&gt; — Local database, fast graph queries, incremental updates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impact analysis&lt;/strong&gt; — Walks the graph upstream, finds column dependents, calculates risk&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The index rebuilds in seconds. No cloud. No API calls. Pure local static analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @sunilp-org/jam-cli
jam trace &amp;lt;any-function-name&amp;gt;
jam trace &amp;lt;any-function-name&amp;gt; &lt;span class="nt"&gt;--impact&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key needed for trace — it's pure static analysis. The AI features (ask, go, commit, review) auto-detect your provider.&lt;/p&gt;

&lt;p&gt;978 tests. MIT licensed. Works everywhere Node runs.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/sunilp/jam-cli" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://jam.sunilprakash.com" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://www.npmjs.com/package/@sunilp-org/jam-cli" rel="noopener noreferrer"&gt;npm&lt;/a&gt; | &lt;a href="https://marketplace.visualstudio.com/items?itemName=sunilp.jam-cli-vscode" rel="noopener noreferrer"&gt;VSCode Extension&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>developertools</category>
      <category>productivity</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
